Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Zigbee ZHA support with Arduino - ESP32-C6 (TZ-595) #228

Closed
ilker-aktuna opened this issue Jan 24, 2024 · 37 comments
Closed

Zigbee ZHA support with Arduino - ESP32-C6 (TZ-595) #228

ilker-aktuna opened this issue Jan 24, 2024 · 37 comments
Labels

Comments

@ilker-aktuna
Copy link

Question

I am trying to make a working zigbee end device using a ESP32-C6 Dev module and Arduino IDE.
I found the Arduino example from here:
https://github.com/P-R-O-C-H-Y/arduino-esp32/blob/Zigbee-examples/libraries/ESP32/examples/Zigbee/Zigbee_Light_Bulb/Zigbee_Light_Bulb.ino

But this did not try to join any network.
So I changed the "esp_zb_task" method with:

char modelid[] = {13, 'E', 'S', 'P', '3', '2', 'C', '6', '.', 'L', 'i', 'g', 'h', 't'};
char manufname[] = {9, 'E', 's', 'p', 'r', 'e', 's', 's', 'i', 'f'};

static void esp_zb_task(void *pvParameters)
{
    // initialize Zigbee stack with Zigbee end-device config 
    esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG();
    esp_zb_init(&zb_nwk_cfg);
    esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);

    // set the on-off light device config
    uint8_t test_attr, test_attr2;
 
    test_attr = 0;
    test_attr2 = 4;
    // basic cluster create with fully customized
    esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_BASIC);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_POWER_SOURCE_ID, &test_attr2);
    esp_zb_cluster_update_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr2);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, &manufname[0]);
    // identify cluster create with fully customized
    esp_zb_attribute_list_t *esp_zb_identify_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);
    esp_zb_identify_cluster_add_attr(esp_zb_identify_cluster, ESP_ZB_ZCL_ATTR_IDENTIFY_IDENTIFY_TIME_ID, &test_attr);
    // group cluster create with fully customized
    esp_zb_attribute_list_t *esp_zb_groups_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_GROUPS);
    esp_zb_groups_cluster_add_attr(esp_zb_groups_cluster, ESP_ZB_ZCL_ATTR_GROUPS_NAME_SUPPORT_ID, &test_attr);
    // scenes cluster create with standard cluster + customized
    esp_zb_attribute_list_t *esp_zb_scenes_cluster = esp_zb_scenes_cluster_create(NULL);
    esp_zb_cluster_update_attr(esp_zb_scenes_cluster, ESP_ZB_ZCL_ATTR_SCENES_NAME_SUPPORT_ID, &test_attr);
    // on-off cluster create with standard cluster config
    esp_zb_on_off_cluster_cfg_t on_off_cfg;
    on_off_cfg.on_off = ESP_ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE;
    esp_zb_attribute_list_t *esp_zb_on_off_cluster = esp_zb_on_off_cluster_create(&on_off_cfg);
    // create cluster lists for this endpoint
    esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
    esp_zb_cluster_list_add_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    // update basic cluster in the existed cluster list
    //esp_zb_cluster_list_update_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_identify_cluster(esp_zb_cluster_list, esp_zb_identify_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_groups_cluster(esp_zb_cluster_list, esp_zb_groups_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_scenes_cluster(esp_zb_cluster_list, esp_zb_scenes_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_on_off_cluster(esp_zb_cluster_list, esp_zb_on_off_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
    // add created endpoint (cluster_list) to endpoint list
    esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list, HA_ESP_LIGHT_ENDPOINT, ESP_ZB_AF_HA_PROFILE_ID, ESP_ZB_HA_ON_OFF_OUTPUT_DEVICE_ID);
    esp_zb_device_register(esp_zb_ep_list);
    esp_zb_core_action_handler_register(zb_action_handler);
    ESP_ERROR_CHECK(esp_zb_start(false));
    esp_zb_main_loop_iteration();
}

with this change , the device is trying a join on my hub. (Hubitat)
I can see the device being detected on hub but it is stuck at "initializing" phase.

I'm not sure why , log_i and log_e statements in the example code do not produce on serial monitor.
So I added some serial.println replacing them. These work and I see that the ESP_ZB_BDB_SIGNAL_STEERING is received , but I get these errors i after that:

Network steering was not successful (status: ESP_FAIL
ZDO signal: ZDO Device Unavailable

So what is missing in this code to join a hub ?

Also, why doesn't the log_i and log_e statements work for me ?

Additional context.

No response

@github-actions github-actions bot changed the title Zigbee ZHA support with Arduino - ESP32-C6 Zigbee ZHA support with Arduino - ESP32-C6 (TZ-595) Jan 24, 2024
@Greginkansas
Copy link

Its the hub the code joins to my setup with zigbee2mqtt just fine.

@ilker-aktuna
Copy link
Author

zigbee2mqtt

there is no zigbee2mqtt in my setup. And I did not understand the relevance of your answer with my question.

I have a Hubitat hub which is acting as a zigbee coordinator.
I want to make a zigbee end device from ESP32-C6
so the esp32-c6 should join my hub using zigbee.

@Greginkansas
Copy link

The relevance is that it can connect to another system. So I would take a look at your zigbee coordinator, also as part of your trouble shooting.

@ilker-aktuna
Copy link
Author

you don't understand.
I have a Hubitat hub which is pretty known device. And on this hub , I have more than 50 zigbee devices connected. They are from different brands. So Hubitat follows zigbee standards. There is no problem on Hubitat side.

Besides , you are not connecting to a zigbee hub as I require.
Your scenario is very different from mine. And thus, it is not an answer.

I am waiting support from the project owners...

@TheKayneGame
Copy link

Whether the Hubitat hub is well known or not is not really relevant.
What is relevant, and what i think @Greginkansas is hinting at, is that the Coordinator supports the Device signature.
And if it does not what does it do with it.

What i expect zigbee2mqtt to do is, and @Greginkansas correct me if i am wrong, it will add the device anyways but will mark it as unsupported. Meaning it is not able to bind the signature to any distinct actions.
So to control the ESP zigbee device, you would need to send custom zigbee commands.

As for your hubitat, it might be that it just does not know the zigbee device signature and straight up rejects it.
I might be wrong in that.
That's why @Greginkansas suggestion, to take a look at the Coordinator, is relevant.
To ask the question: "is the Coordinator the problem?"

@ilker-aktuna
Copy link
Author

@TheKayneGame
actually Hubitat does not care about device signature at first pairing. If the device is not known to hub it first assigns the device as a "default device" with no capabilities. Then the user can select an appropriate device along from the internal devices or add a custom device driver to hub.
I got many Chinese devices like this. They were identified as default device and then either me or some other developer wrote a device driver to support it.
If the device is a simple one (like what I am trying to achieve at first) , then there's even no need for writing a device driver. I can just select a generic zigbee light bulb to control it.

In my experience with Esp32-c6 Arduino examples the device can not complete pairing. On the other hand other people had success with Espressif IDF examples slightly modifying them.
So, here the problem is with Arduino support on Zigbee.

I am still looking for Espressif developers' help. We need proper examples for pairing to a hub.
Even if they were working , there are only two examples (light bulb and ligth switch). There's no example for a RGB light bulb which we could easily test with the RGB led on the esp32-c6 dev kit.

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Jan 30, 2024

@ilker-aktuna To answer about the part of the Arduino support of Zigbee.
If you have any ESP-IDF example you can run it within Arduino just with small changes. We didn't created any wrapper library on top of the Zigbee SDK, we are just providing the libs, so they can be used in Arduino. Those 2 examples are just a slightly edited Zigbee SDK example, to not rely on other esp-idf libraries that we don't have available in Arduino.
So if you have sources to the examples, that worked with ESP-IDF and the Habitat, please share them and I am sure with not much effort they can be used within Arduino.

Question about the logs: Did you set the debug at least to error? To get all logs select in the Arduino IDE Tools menu -> Debug Level -> Verbose.

@fillibar
Copy link

I replaced the esp_zb_task with the below code (from within issue 10662's thread). This allowed it to work with the Hubitat when the ESP32-C6 was flashed using the IDF.

char modelid[] = {13, 'E', 'S', 'P', '3', '2', 'C', '6', '.', 'L', 'i', 'g', 'h', 't'};
char manufname[] = {9, 'E', 's', 'p', 'r', 'e', 's', 's', 'i', 'f'};

static void esp_zb_task(void *pvParameters)
{
    /* initialize Zigbee stack with Zigbee end-device config */
    esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG();
    esp_zb_init(&zb_nwk_cfg);
    esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);

    /* set the on-off light device config */
    uint8_t test_attr, test_attr2;
 
    test_attr = 0;
    test_attr2 = 4;
    /* basic cluster create with fully customized */
    esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_BASIC);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_POWER_SOURCE_ID, &test_attr2);
    esp_zb_cluster_update_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr2);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);
    esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, &manufname[0]);
    /* identify cluster create with fully customized */
    esp_zb_attribute_list_t *esp_zb_identify_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);
    esp_zb_identify_cluster_add_attr(esp_zb_identify_cluster, ESP_ZB_ZCL_ATTR_IDENTIFY_IDENTIFY_TIME_ID, &test_attr);
    /* group cluster create with fully customized */
    esp_zb_attribute_list_t *esp_zb_groups_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_GROUPS);
    esp_zb_groups_cluster_add_attr(esp_zb_groups_cluster, ESP_ZB_ZCL_ATTR_GROUPS_NAME_SUPPORT_ID, &test_attr);
    /* scenes cluster create with standard cluster + customized */
    esp_zb_attribute_list_t *esp_zb_scenes_cluster = esp_zb_scenes_cluster_create(NULL);
    esp_zb_cluster_update_attr(esp_zb_scenes_cluster, ESP_ZB_ZCL_ATTR_SCENES_NAME_SUPPORT_ID, &test_attr);
    /* on-off cluster create with standard cluster config*/
    esp_zb_on_off_cluster_cfg_t on_off_cfg;
    on_off_cfg.on_off = ESP_ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE;
    esp_zb_attribute_list_t *esp_zb_on_off_cluster = esp_zb_on_off_cluster_create(&on_off_cfg);
    /* create cluster lists for this endpoint */
    esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
    esp_zb_cluster_list_add_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    /* update basic cluster in the existed cluster list */
    //esp_zb_cluster_list_update_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_identify_cluster(esp_zb_cluster_list, esp_zb_identify_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_groups_cluster(esp_zb_cluster_list, esp_zb_groups_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_scenes_cluster(esp_zb_cluster_list, esp_zb_scenes_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
    esp_zb_cluster_list_add_on_off_cluster(esp_zb_cluster_list, esp_zb_on_off_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

    esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
    /* add created endpoint (cluster_list) to endpoint list */
    esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list, HA_ESP_LIGHT_ENDPOINT, ESP_ZB_AF_HA_PROFILE_ID, ESP_ZB_HA_ON_OFF_OUTPUT_DEVICE_ID);
    esp_zb_device_register(esp_zb_ep_list);
    esp_zb_core_action_handler_register(zb_action_handler);
    ESP_ERROR_CHECK(esp_zb_start(false));
    esp_zb_main_loop_iteration();
}

@ilker-aktuna
Copy link
Author

@P-R-O-C-H-Y
as you see, @fillibar had success with IDF example on the same hub.
Arduino version does not work as I wrote.
I don't know why I am trying to (or I have to) pursuade you that Arduino examples are not working. Somebody has to work on Ardunio version if it will be supported. Otherwise, let's say Zigbee is not supported on Arduino.

@Greginkansas
Copy link

I have 2 zigbee running now 1 on the garage door now running for 4 days with no crashes and 1 with get this a lux senser using a Adafruit driver. So this one both sends and receives commands.

/**

  • Light with a temp cluster sends LUX start
  • The example demonstrates how to use ESP Zigbee stack to create a end device light bulb.
  • The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator.
  • Proper Zigbee mode must be selected in Tools->Zigbee mode
  • and also the correct partition scheme must be selected in Tools->Partition Scheme.
  • Please check the README.md for instructions and more detailed description.
    */

#ifndef ZIGBEE_MODE_ED
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
#endif

#include "esp_zigbee_core.h"
#include "nvs_flash.h"
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "ha/esp_zigbee_ha_standard.h"

#include "Wire.h"
#include "Adafruit_VEML7700.h"
Adafruit_VEML7700 veml = Adafruit_VEML7700();
#include "esp_check.h"
#include "esp_err.h"
#include "esp_log.h"
#define SERIAL_BAUD 115200

float LUX_READ;
uint16_t temperature = 10; // old line gc
float temp;
///// gc test vars
uint16_t tempsendmin = 0, tempsendmaax = 2000;
bool temp_SW_state = false;
static const char *TAG = "ESP_GC";

#define LED_PIN RGB_BUILTIN

/* Default End Device config */
#define ESP_ZB_ZED_CONFIG()
{
.esp_zb_role = ESP_ZB_DEVICE_TYPE_ED,
.install_code_policy = INSTALLCODE_POLICY_ENABLE,
.nwk_cfg = {
.zed_cfg = {
.ed_timeout = ED_AGING_TIMEOUT,
.keep_alive = ED_KEEP_ALIVE,
},
},
}

#define ESP_ZB_DEFAULT_RADIO_CONFIG()
{
.radio_mode = RADIO_MODE_NATIVE,
}
#define ESP_ZB_DEFAULT_HOST_CONFIG()
{
.host_connection_mode = HOST_CONNECTION_MODE_NONE,
}

/* Zigbee configuration /
#define INSTALLCODE_POLICY_ENABLE false /
enable the install code policy for security /
#define ED_AGING_TIMEOUT ESP_ZB_ED_AGING_TIMEOUT_64MIN
#define ED_KEEP_ALIVE 3000 /
3000 millisecond /
#define HA_ESP_LIGHT_ENDPOINT 10 /
10 esp light bulb device endpoint, used to process light controlling commands /
#define ESP_ZB_PRIMARY_CHANNEL_MASK ESP_ZB_TRANSCEIVER_ALL_CHANNELS_MASK /
Zigbee primary channel mask use in the example */

/********************* Zigbee functions **************************/
static void bdb_start_top_level_commissioning_cb(uint8_t mode_mask)
{
ESP_ERROR_CHECK(esp_zb_bdb_start_top_level_commissioning(mode_mask));
}

void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
{
uint32_t *p_sg_p = signal_struct->p_app_signal;
esp_err_t err_status = signal_struct->esp_err_status;
esp_zb_app_signal_type_t sig_type = (esp_zb_app_signal_type_t)p_sg_p;
switch (sig_type) {
case ESP_ZB_ZDO_SIGNAL_SKIP_STARTUP:
Serial.println("Zigbee stack initialized");
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_INITIALIZATION);
break;
case ESP_ZB_BDB_SIGNAL_DEVICE_FIRST_START:
case ESP_ZB_BDB_SIGNAL_DEVICE_REBOOT:
if (err_status == ESP_OK) {
Serial.println("Start network steering");
esp_zb_bdb_start_top_level_commissioning(ESP_ZB_BDB_MODE_NETWORK_STEERING);
} else {
/
commissioning failed */
Serial.println("Failed to initialize Zigbee stack ");
}
break;
case ESP_ZB_BDB_SIGNAL_STEERING:
if (err_status == ESP_OK) {
esp_zb_ieee_addr_t extended_pan_id;
esp_zb_get_extended_pan_id(extended_pan_id);
log_i("Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4],
extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0],
esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());
} else {
Serial.println("Network steering was not successful ");
esp_zb_scheduler_alarm((esp_zb_callback_t)bdb_start_top_level_commissioning_cb, ESP_ZB_BDB_MODE_NETWORK_STEERING, 1000);
}
break;
default:
log_i("ZDO signal: %s (0x%x), status: %s", esp_zb_zdo_signal_to_string(sig_type), sig_type,
esp_err_to_name(err_status));
break;
}
}

static esp_err_t zb_action_handler(esp_zb_core_action_callback_id_t callback_id, const void *message)
{
esp_err_t ret = ESP_OK;
switch (callback_id) {
case ESP_ZB_CORE_SET_ATTR_VALUE_CB_ID:
ret = zb_attribute_handler((esp_zb_zcl_set_attr_value_message_t *)message);
break;
default:
Serial.println("Receive Zigbee action(0x%x) callback");
break;
}
return ret;
}

char modelid[] = {13, 'E', 'S', 'P', '3', '2', 'C', '6', '.', 'L', 'i', 'g', 'h', 't'};
char manufname[] = {9, 'E', 's', 'p', 'r', 'e', 's', 's', 'i', 'f'};

static void esp_zb_task(void *pvParameters)
{
// initialize Zigbee stack with Zigbee end-device config
esp_zb_cfg_t zb_nwk_cfg = ESP_ZB_ZED_CONFIG();
esp_zb_init(&zb_nwk_cfg);
esp_zb_set_primary_network_channel_set(ESP_ZB_PRIMARY_CHANNEL_MASK);

// set the on-off light device config
uint8_t test_attr, test_attr2;

test_attr = 0;
test_attr2 = 4;
// basic cluster create with fully customized
esp_zb_attribute_list_t *esp_zb_basic_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_BASIC);
esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr);
esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_POWER_SOURCE_ID, &test_attr2);
esp_zb_cluster_update_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_ZCL_VERSION_ID, &test_attr2);
esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MODEL_IDENTIFIER_ID, &modelid[0]);
esp_zb_basic_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_BASIC_MANUFACTURER_NAME_ID, &manufname[0]);
// identify cluster create with fully customized
esp_zb_attribute_list_t *esp_zb_identify_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);
esp_zb_identify_cluster_add_attr(esp_zb_identify_cluster, ESP_ZB_ZCL_ATTR_IDENTIFY_IDENTIFY_TIME_ID, &test_attr);
// group cluster create with fully customized
esp_zb_attribute_list_t *esp_zb_groups_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_GROUPS);
esp_zb_groups_cluster_add_attr(esp_zb_groups_cluster, ESP_ZB_ZCL_ATTR_GROUPS_NAME_SUPPORT_ID, &test_attr);
// scenes cluster create with standard cluster + customized
esp_zb_attribute_list_t *esp_zb_scenes_cluster = esp_zb_scenes_cluster_create(NULL);
esp_zb_cluster_update_attr(esp_zb_scenes_cluster, ESP_ZB_ZCL_ATTR_SCENES_NAME_SUPPORT_ID, &test_attr);
// on-off cluster create with standard cluster config
esp_zb_on_off_cluster_cfg_t on_off_cfg;
on_off_cfg.on_off = ESP_ZB_ZCL_ON_OFF_ON_OFF_DEFAULT_VALUE;
esp_zb_attribute_list_t *esp_zb_on_off_cluster = esp_zb_on_off_cluster_create(&on_off_cfg);

///////////////////////// Start illuminance_measurement

// Temperature cluster 
esp_zb_attribute_list_t *esp_zb_temperature_meas_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT);
esp_zb_temperature_meas_cluster_add_attr(esp_zb_temperature_meas_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, &temperature);
esp_zb_temperature_meas_cluster_add_attr(esp_zb_temperature_meas_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MIN_VALUE_ID, &tempsendmin);
esp_zb_temperature_meas_cluster_add_attr(esp_zb_temperature_meas_cluster, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_MAX_VALUE_ID, &tempsendmaax);

//////////////// START illuminance_measurement

// esp_zb_attribute_list_t *esp_zb_illuminance_measurement_cluster = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MEASURED_VALUE_DEFAULT);
// esp_zb_illuminance_meas_cluster_add_attr(esp_zb_basic_cluster, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MEASURED_VALUE_ID, &test_attr2);

//////////////// END illuminance_measurement
// create cluster lists for this endpoint
esp_zb_cluster_list_t *esp_zb_cluster_list = esp_zb_zcl_cluster_list_create();
esp_zb_cluster_list_add_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
// update basic cluster in the existed cluster list

///esp_zb_cluster_list_add_illuminance_meas_cluster(esp_zb_cluster_list, esp_zb_illuminance_measurement_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

esp_zb_cluster_list_add_temperature_meas_cluster(esp_zb_cluster_list, esp_zb_temperature_meas_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

// esp_zb_cluster_list_update_basic_cluster(esp_zb_cluster_list, esp_zb_basic_cluster_create(NULL), ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_identify_cluster(esp_zb_cluster_list, esp_zb_identify_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_groups_cluster(esp_zb_cluster_list, esp_zb_groups_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_scenes_cluster(esp_zb_cluster_list, esp_zb_scenes_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
esp_zb_cluster_list_add_on_off_cluster(esp_zb_cluster_list, esp_zb_on_off_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);

esp_zb_ep_list_t *esp_zb_ep_list = esp_zb_ep_list_create();
// add created endpoint (cluster_list) to endpoint list
esp_zb_ep_list_add_ep(esp_zb_ep_list, esp_zb_cluster_list, HA_ESP_LIGHT_ENDPOINT, ESP_ZB_AF_HA_PROFILE_ID, ESP_ZB_HA_ON_OFF_OUTPUT_DEVICE_ID);  //ESP_ZB_HA_SIMPLE_SENSOR_DEVICE_ID);
esp_zb_device_register(esp_zb_ep_list);
esp_zb_core_action_handler_register(zb_action_handler);
ESP_ERROR_CHECK(esp_zb_start(false));
esp_zb_main_loop_iteration();

}

/* Handle the light attribute */

static esp_err_t zb_attribute_handler(const esp_zb_zcl_set_attr_value_message_t *message)
{
esp_err_t ret = ESP_OK;
bool light_state = 0;

if(!message){
  Serial.println("Empty message");
}
if(message->info.status != ESP_ZB_ZCL_STATUS_SUCCESS){
  Serial.println("Received message:");
}

Serial.println("Received message: ");
if (message->info.dst_endpoint == HA_ESP_LIGHT_ENDPOINT) {
    if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ON_OFF) {
        if (message->attribute.id == ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_BOOL) {
            light_state = message->attribute.data.value ? *(bool *)message->attribute.data.value : light_state;
            Serial.println("Light sets to GC change");
            neopixelWrite(LED_PIN,0*light_state,55*light_state,0*light_state); // Toggle light
        }
    }
}
return ret;

}
////////////////////// read lux sesser
void update_lux(void *pvParameter)

{
while(1)
{

LUX_READ = veml.readLux();
// Serial.print("lux: "); Serial.println(veml.readLux());
// Serial.println("LUX_READ");
// temperature = LUX_READ * 100; // float to int
temperature = LUX_READ; // * 100;
// Serial.println(temperature);

esp_zb_zcl_status_t state_tmp = esp_zb_zcl_set_attribute_val(HA_ESP_LIGHT_ENDPOINT, ESP_ZB_ZCL_CLUSTER_ID_TEMP_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_TEMP_MEASUREMENT_VALUE_ID, &temperature , false); //er
// esp_zb_zcl_set_attribute_val(HA_ESP_LIGHT_ENDPOINT, ESP_ZB_ZCL_CLUSTER_ID_ILLUMINANCE_MEASUREMENT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ILLUMINANCE_MEASUREMENT_MEASURED_VALUE_ID, &temperature , false);

/* Check for error */
if(state_tmp != ESP_ZB_ZCL_STATUS_SUCCESS)
{
Serial.println("Setting temperature attribute failed!");
}

    vTaskDelay(1000 / portTICK_PERIOD_MS);  ///GC  slow update to 50000 from 5000 MS

}

}

/********************* Arduino functions **************************/
void setup() {
Serial.begin(SERIAL_BAUD);
// Init Zigbee
esp_zb_platform_config_t config = {
.radio_config = ESP_ZB_DEFAULT_RADIO_CONFIG(),
.host_config = ESP_ZB_DEFAULT_HOST_CONFIG(),
};
ESP_ERROR_CHECK(nvs_flash_init());
ESP_ERROR_CHECK(esp_zb_platform_config(&config));
Serial.println("Set up done");
// Init RMT and leave light OFF
neopixelWrite(LED_PIN,0,0,0);
Wire.begin(22,21);
//Start Zigbee task
if (!veml.begin()) {
Serial.println("Sensor not found");
// while (1);
}

xTaskCreate(update_lux, "update_lux_value", 4096, NULL, 2, NULL);
xTaskCreate(esp_zb_task, "Zigbee_main", 4096, NULL, 5, NULL);
}

void loop() {
//empty, zigbee running in task
}

@ilker-aktuna
Copy link
Author

@Greginkansas
do you say that this example is working with a Zigbee hub ?
If yes, can you put this example as raw file to somewhere ?
Because when you put it inline to your message it gets formatted and can't be copied fully.

@mitag
Copy link

mitag commented Feb 12, 2024

@ilker-aktuna

I am trying to make a working zigbee end device using a ESP32-C6 Dev module and Arduino IDE.

I tried @P-R-O-C-H-Y's example last night with success, but I downloaded it from a different link.
https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/Zigbee/Zigbee_Light_Bulb

I used an ESP32-C6-DevKitC. After a reset, the DevKit was recognised by ZHA. I use a Zigbee 3.0 USB Dongle Plus (ZBDongle-E EFR32MG21) with Multiprotocol firmware as coordinator. The Silicon Labs Multiprotocol Add-on forwards the ZigBee communication to ZHA.

@ilker-aktuna
Copy link
Author

@mitag
did you use the "Zigbee_Light_Bulb.ino" file from that link as is (without any modification) ?
If so, that file is not even trying to pair with a hub. How did you make it work ?
Maybe your dongle (and firmware) is starting pairing in reverse direction?

@mitag
Copy link

mitag commented Feb 12, 2024

To be honest, I don't remember if my other ZigBee devices automatically triggered pairing, as I set up Home Assisstant several times a year ago, first twice on Raspberrys and finally on an Intel Mini PC. When I set up the Bosch Smart Home Radiator Thermostats II last autumn, manual work was necessary.

That's why I didn't notice yesterday that I had to call up ZHA and initiate pairing from there. I'm sorry that this didn't seem worth mentioning.

Addendum: I have not changed anything in Zigbee_Light_Bulb.ino.

@ilker-aktuna
Copy link
Author

so your experience is not relevant to what I'm trying to achieve ?

@mitag
Copy link

mitag commented Feb 13, 2024

I'm sorry, I've probably written too much again. Only the following statements are relevant:
I had to call up ZHA and initiate pairing from there.
I have not changed anything in Zigbee_Light_Bulb.ino.

Have you tried to initiate the pairing from ZHA?

@superzanti
Copy link

I'm trying to achieve something similar with the ESP32-H2.
I have a zigstar coordinator connected to a zigbee2mqtt instance.

If I load in this Zigbee_Light_Bulb.ino does the ESP automatically enter pairing after flashing?

So would all I need to do is set the coordinator to pairing mode and it should connect? What's the device recognized as?

@ilker-aktuna
Copy link
Author

@superzanti
it did not pair with mu hub. Try and please let us know the result.

@mitag
Copy link

mitag commented Feb 16, 2024

@superzanti

If I load in this Zigbee_Light_Bulb.ino does the ESP automatically enter pairing after flashing?

Zigbee_Light_Bulb.ino is not able to initiate pairing on its own, you have to initiate it from the coordinator. This worked for me, as I described above. The pairing went perfectly, I was then able to switch the LED on and off and the status of the LED was also transmitted correctly by Zigbee_Light_Bulb.ino. I used an ESP32-C6, but it should work just as well with the ESP32-H2.

@superzanti
Copy link

@mitag Generally when pairing a device, I have tos et my coordinator in pairing mode AND the device in pairing mode.

I can initiate from the coordinator no problem (using the zigbee2mqtt interface).

So I'm assuming, if yours pairs perfectly after initiating from the coordinator, your ESP is either already paired to the coordinator (by manually setting some configs when flashing) or it flashes and starts in pairing mode. Can you clarify your setup?

@mitag
Copy link

mitag commented Feb 16, 2024

What I do know is that after flashing or resetting the ESP-C6, it is ready to perform a pairing initiated by the coordinator.

I flash Zigbee_Light_Bulb.ino without making any changes to it and I don't have to set any parameters anywhere, just let the coordinator search for new devices.

After resetting the ESP-C6 again, the pairing remains in place. If I delete the ESP-C6 in the coordinator, the pairing only works again after a reset of the ESP-C6.

As the example code refers to the importance of selecting the Partitio scheme (Zigbee 4MB with spiffs), I assume that the data transmitted by the coordinator during pairing is saved by one of the integrated libraries in the spiffs in order to survive a reset.

`
/**

  • @brief This example demonstrates simple Zigbee light bulb.
  • The example demonstrates how to use ESP Zigbee stack to create a end device light bulb.
  • The light bulb is a Zigbee end device, which is controlled by a Zigbee coordinator.
  • Proper Zigbee mode must be selected in Tools->Zigbee mode
  • and also the correct partition scheme must be selected in Tools->Partition Scheme.
  • Please check the README.md for instructions and more detailed description.

*/

`

I selected the following in the Arduino IDE, in Tools, because it seemed logical to me.
Partition Scheme: "Zigbee 4MB with spiffs"
...
Zigbee Mode: "Zigbee ED (end device)"

The pairing is performed here:
`
void esp_zb_app_signal_handler(esp_zb_app_signal_t *signal_struct)
{
...

case ESP_ZB_BDB_SIGNAL_STEERING:
    if (err_status == ESP_OK) {
        esp_zb_ieee_addr_t extended_pan_id;
        esp_zb_get_extended_pan_id(extended_pan_id);
        log_i("Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",
                 extended_pan_id[7], extended_pan_id[6], extended_pan_id[5], extended_pan_id[4],
                 extended_pan_id[3], extended_pan_id[2], extended_pan_id[1], extended_pan_id[0],
                 esp_zb_get_pan_id(), esp_zb_get_current_channel(), esp_zb_get_short_address());

`
The ESP32 only knows its ieee address and transmits this to the coordinator on request.

@ilker-aktuna
Copy link
Author

@mitag
what do you mean by "reset the ESP-C6"
how do you reset it ?

thanks.

@P-R-O-C-H-Y
Copy link
Member

P-R-O-C-H-Y commented Feb 17, 2024

If the end device was never connected to the coordinator, just restarting the ESP by reset button can help. If it was already connected to some coordinator and you want to create new connection, you need to erase flash memory (it may also help to erase it for the first time to be sure, that the zigbee partition will be also clear).

You can check the Readme of the example, all is written there:

If the End device flashed with this example is not connecting to the coordinator, erase the flash before flashing it to the board. It is recommended to do this if you did changes to the coordinator. You can do one of the following:

  • In the Arduino IDE go to the Tools menu and set Erase All Flash Before Sketch Upload to Enabled.
  • In the sketch uncomment function esp_zb_nvram_erase_at_start(true); located in esp_zb_task function.

@ilker-aktuna
Copy link
Author

I changed my hub from Hubitat C8 to C7 and now I am able to pair with esp32-c6 with the code from:

https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/Zigbee/Zigbee_Light_Bulb

My hub detects it as a generic light switch. But the on/off commands do nothing.
The code does not provide any logs, so I don't know what really is happening.
any ideas ?

@mitag
Copy link

mitag commented Feb 19, 2024

Check the logs on your Hubidat.

@ilker-aktuna
Copy link
Author

but why doesn't these log_i , log_w lines work ?

log_i("Start network steering");

log_w("Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status));

log_i("Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",

@P-R-O-C-H-Y
Copy link
Member

but why doesn't these log_i , log_w lines work ?

log_i("Start network steering");

log_w("Failed to initialize Zigbee stack (status: %s)", esp_err_to_name(err_status));

log_i("Joined network successfully (Extended PAN ID: %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x, PAN ID: 0x%04hx, Channel:%d, Short Address: 0x%04hx)",

You need to set Debug Level in Arduino IDE - Tools menu to "Verbose" or "Info" to see those in serial monitor.

@ilker-aktuna
Copy link
Author

Debugs seem to work after I set it on IDE and restart.

With the example code , currently this is what happens with Hubitat hubs:

On C8 hub it gets stuck at "initializing" phase
On C7 hub it pairs (fast enough) but it is identified as a zigbee power outlet. I change it to zigbee switch , but I could not control it yet. on/off does not work.
Just once it worked out of my attempts around hundred.
Someone from Hubitat forum says that it works on a C3 hub and that they could control it. However, same person could not make it work on a C7 and a C8 hub.

I really want this to work. But I'm not sure how to troubleshoot.
Debugs seem to work , but not really meaningful.
Would anyone be interested in looking at the debug outputs , I have ?

@Hedda
Copy link
Contributor

Hedda commented Apr 8, 2024

With the example code , currently this is what happens with Hubitat hubs:

On C8 hub it gets stuck at "initializing" phase On C7 hub it pairs (fast enough) but it is identified as a zigbee power outlet. I change it to zigbee switch , but I could not control it yet. on/off does not work. Just once it worked out of my attempts around hundred. Someone from Hubitat forum says that it works on a C3 hub and that they could control it. However, same person could not make it work on a C7 and a C8 hub.

I really want this to work. But I'm not sure how to troubleshoot.

FYI, you will get those same type of pairing/joning issues (including device interviewing failing or not completing) if you either have sources of EMF/EMI/RMI interference too close to the Zigbee devices (especially close to the Zigbee Coordinator and closest Zigbee Router) or similar problem symptoms you do not have enough "known good" Zigbee Router devices as well as also similar problem symptoms when having bad Zigbee Router devices that do not pass along all communication messages. See example:

Anyway, regardless of your enviroment and Zigbee gateway solution you are using, before troubleshooting any first, be aware that with all Zigbee setups you first be sure to always actively take some basic but important preventive actions to avoid EMF/EMI/RMI interference by using a long USB 2.0 extension cable (or USB 3.0 extension cable to a USB 2.0 port/hub) as well as adding known good Zigbee Router devices. If possible try to follow all the tips in these hardware-independent best practise guides:

Another tips; for easier troubleshooting from the Zigbee gateway side can I suggest that you buy one CC2652P based Zigbee Coordinator radio adapter dongle (like example the "Sonoff ZBDongle-P" by ITead), + flash that with the latest latest community Z-Stack Zigbee Coordinator (NCP) firmware build from Koenkk's master branch, and then install the latest version of Zigbee2MQTT to test with that as Zigbee Coordinator USB dongle? -> https://www.zigbee2mqtt.io

Zigbee2MQTT has a great community for troubleshooting (and developing of) third-party devices from the Zigbee gateway side:

Optionally, for some chaos engineering you could also buy the Home Assistant's SkyConnect USB stick and test with Home Assistant's ZHA integration as at least those should rule out of the problem is only with one Zigbee gateway solution or with all.

@ilker-aktuna
Copy link
Author

@Hedda
this is not about my setup , or my environment.
I have more than 40 zigbee devices (of several different brands) connected to my Zigbee coordinator (hubitat)
They all work fine.
The ESP-C6 does not have a good software adapting to the hub. That's it.
And I don't want to try with a USB stick. I want to make a zigbee device that will connect to my zigbee coordinator.
Besides, there is really very few documentation on Zigbee zupport of Esp32-c6. Only a switch and a light bulb. What if I want to make a temperature sensor ? Or a rgb bulb ?

@Hedda
Copy link
Contributor

Hedda commented Apr 9, 2024

The ESP-C6 does not have a good software adapting to the hub. That's it.

With Zigbee it can be the other way around if the devices do not just follow the most basic device function using Zigbee Home Automation profile specification, so much will depend on the device handling done on the Zigbee Gateway side, and depending on their implementation the Zigbee Gateway developers may need to make some custom changes to support new devices. Thus you get different results with different Zigbee Gateway software implementations.

Besides, there is really very few documentation on Zigbee zupport of Esp32-c6. Only a switch and a light bulb. What if I want to make a temperature sensor ? Or a rgb bulb ?

While they do not cover all sample scenarios, check out the recently added additional examples, see

https://github.com/espressif/esp-zigbee-sdk/tree/main/examples/esp_zigbee_HA_sample

and

https://github.com/espressif/esp-zigbee-sdk/tree/main/examples/

@ilker-aktuna
Copy link
Author

@Hedda

ok thank you. I'll try these. But really we have to understand what's missing that causes my hub not pair with this device...

@ilker-aktuna
Copy link
Author

are there Arduino versions of these ?

@Avenitos
Copy link

Avenitos commented Apr 26, 2024

Example: https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/Zigbee/Zigbee_Light_Bulb
Platform: Arduino ESP32 3.0.0-rc1

i try join in SLS and z2m and I didn't succeed, the announcement comes and that's it, the device does not respond to interview requests

[ 44665][I][sketch_apr26a.ino:102] esp_zb_app_signal_handler(): ZDO signal: ZDO Leave (0x3), status: ESP_OK
[ 44676][I][sketch_apr26a.ino:98] esp_zb_app_signal_handler(): Network steering was not successful (status: ESP_FAIL)
[ 66175][I][sketch_apr26a.ino:102] esp_zb_app_signal_handler(): ZDO signal: ZDO Leave (0x3), status: ESP_OK
[ 66186][I][sketch_apr26a.ino:98] esp_zb_app_signal_handler(): Network steering was not successful (status: ESP_FAIL)
[ 87685][I][sketch_apr26a.ino:102] esp_zb_app_signal_handler(): ZDO signal: ZDO Leave (0x3), status: ESP_OK
[ 87696][I][sketch_apr26a.ino:98] esp_zb_app_signal_handler(): Network steering was not successful (status: ESP_FAIL)

I have a suspicion that this is a problem with Install Code, although in the example install_code_policy = false

@Hedda
Copy link
Contributor

Hedda commented May 31, 2024

Zigbee examples in the arduino-esp32 repository should be syncronized and updated to work with latest esp-zigbee-sdk, see:

https://github.com/espressif/arduino-esp32/tree/master/libraries/ESP32/examples/Zigbee

Also, Espressif released "stable" version 3.0.0 Arduino ESP32 Core based on ESP-IDF v5.1.4 with support for ESP32-H2 / ESP32-C6:

https://github.com/espressif/arduino-esp32/releases/tag/3.0.0

(Arduino ESP32 core v3.0.0 was first announced over 7-month ago but this updated version is now finally been marked as stable).

As well means from now can report upstream problems or feature requests related to ESP32-H2/ESP32-C6 as new issues here:

https://github.com/espressif/arduino-esp32/issues/

PS: Espressif has still not created a Arduino wrapper library on top of the Zigbee SDK, they are however at least providing libraries:

espressif/arduino-esp32#9156

@chshu
Copy link
Collaborator

chshu commented Jul 26, 2024

Closing, please file separate issues if anything else need to follow up for this topic.

@chshu chshu closed this as completed Jul 26, 2024
@Hedda
Copy link
Contributor

Hedda commented Oct 7, 2024

FYI, looks like a Zigbee API/wrapper for Arduino on ESP32 (arduino-esp32) is being working on very activly right now and initial (basic) Zigbee library support has been merged into both master and release/v3.1 branches, so initial support and a few examples will be included in upcoming 3.0.6 and 3.1.0-rc2 releases of arduino-esp32. See:

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

10 participants