Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

ESP32 C6 Zigbee custom switch (state reporting setting) question #11833

luxert started this conversation in General
Discussion options

Board

ESP32 C6

Device Description

ESP32 C6 devkit

Hardware Configuration

None

Version

v3.1.1

Type

Question

IDE Name

Arduino IDE 2.x

Operating System

Windows11

Flash frequency

80Mhz

PSRAM enabled

no

Upload speed

921600

Description

I am testing an ESP32-C6 Zigbee switch.
I paired it with a commercial wall switch, and the wall switch works fine when I send on/off commands from the C6.
However, I would like to receive the status on the C6 when the user physically toggles the wall switch.
Therefore, I modified the switch creation as follows.

STZigbeeSwitch::STZigbeeSwitch(uint8_t endpoint) : ZigbeeEP(endpoint)
{
 _device_id = ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID;
 _instance = this;
 _cluster_list = esp_zb_zcl_cluster_list_create();
 // basic Cluster
 esp_zb_on_off_switch_cfg_t switch_cfg = ESP_ZB_DEFAULT_ON_OFF_SWITCH_CONFIG();
 // Basic Cluster (Server Role)
 esp_zb_attribute_list_t *basic_cluster = esp_zb_basic_cluster_create(&switch_cfg.basic_cfg);
 esp_zb_cluster_list_add_basic_cluster(_cluster_list, basic_cluster, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
 // Identify Cluster (Server Role)
 esp_zb_attribute_list_t *identify_server = esp_zb_identify_cluster_create(&switch_cfg.identify_cfg);
 esp_zb_cluster_list_add_identify_cluster(_cluster_list, identify_server, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
 // Identify Cluster (Client Role)
 esp_zb_attribute_list_t *identify_client = esp_zb_zcl_attr_list_create(ESP_ZB_ZCL_CLUSTER_ID_IDENTIFY);
 esp_zb_cluster_list_add_identify_cluster(_cluster_list, identify_client, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
 // On/Off Cluster (Client Role) - Send CMD
 esp_zb_attribute_list_t *on_off_client = esp_zb_on_off_cluster_create(nullptr);
 esp_zb_cluster_list_add_on_off_cluster(_cluster_list, on_off_client, ESP_ZB_ZCL_CLUSTER_CLIENT_ROLE);
 // On/Off Cluster (Server Role) - Recv report
 esp_zb_attribute_list_t *on_off_server = esp_zb_on_off_cluster_create(nullptr);
 esp_zb_cluster_list_add_on_off_cluster(_cluster_list, on_off_server, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
 // Endpoint Setting
 _ep_config = {
 .endpoint = _endpoint,
 .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID,
 .app_device_id = ESP_ZB_HA_ON_OFF_SWITCH_DEVICE_ID,
 .app_device_version = 0};
}

And I executed the following code to configure the reporting settings.

esp_zb_zcl_config_report_cmd_t report_cmd = {0};
 uint8_t report_change = 1;
 report_cmd.zcl_basic_cmd.dst_endpoint = endPoint; // Wall switch endpoint(1)
 report_cmd.zcl_basic_cmd.src_endpoint = 5; // My C6 Switch endpoint
 report_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT;
 report_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF;
 memcpy(report_cmd.zcl_basic_cmd.dst_addr_u.addr_long, ieee_addr, sizeof(esp_zb_ieee_addr_t));
 esp_zb_zcl_config_report_record_t records[] = {
 {.direction = ESP_ZB_ZCL_REPORT_DIRECTION_SEND,
 .attributeID = ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID,
 .attrType = ESP_ZB_ZCL_ATTR_TYPE_BOOL,
 .min_interval = 5,
 .max_interval = 30,
 .reportable_change = (void *)&report_change},
 };
 report_cmd.record_number = sizeof(records) / sizeof(esp_zb_zcl_config_report_record_t);
 report_cmd.record_field = records;
 esp_zb_lock_acquire(portMAX_DELAY);
 esp_zb_zcl_config_report_cmd_req(&report_cmd);
 esp_zb_lock_release();

However, the following error is reported.

zb_configure_report_resp_handler(): CONFIGURE REPORT RESP response: status(135), cluster(0x6), direction(0x0), attribute(0x0)

I referred to the thermostat example, which has both server and client roles.
I’m not sure what I did wrong.
Does anyone happen to know?

Sketch

Included in the main text

Debug Message

zb_configure_report_resp_handler(): CONFIGURE REPORT RESP response: status(135), cluster(0x6), direction(0x0), attribute(0x0)

Other Steps to Reproduce

No response

I have checked existing issues, online documentation and the Troubleshooting Guide

  • I confirm I have checked existing issues, online documentation and Troubleshooting guide.
You must be logged in to vote

Replies: 7 comments

Comment options

Hi, this zb_configure_report_resp_handler(): CONFIGURE REPORT RESP response: status(135), cluster(0x6), direction(0x0), attribute(0x0) is not en error but the configure response. You need to implement also handler to receive the data void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address) override;.

Can you please better explain your scenario? You want to have switch-switch binding? If yes, you may also need to bind the CLIENT ON/OFF cluster you added as its done in Thermostat class.

You must be logged in to vote
0 replies
Comment options

I am developing an ESP32-C6 as a Zigbee switch coordinator using the Arduino IDE. I have successfully paired it with a commercial wall light switch (Tuya), and I can control the on/off state from the C6. I can also poll the on/off attribute to read its state correctly. However, I would like the C6 to receive the updated state automatically when the user physically toggles the Tuya wall switch.

From GPT and other sources, I found that status: 135 means UNREPORTABLE_ATTRIBUTE, so I am wondering if I misconfigured something. Could you please advise?

static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_message_t *message)
{
 if (!message)
 {
 log_e("Empty message");
 }
 if (message->status != ESP_ZB_ZCL_STATUS_SUCCESS)
 {
 log_e("Received message: error status(%d)", message->status);
 }
 log_v(
 "Received report from address(0x%x) src endpoint(%d) to dst endpoint(%d) cluster(0x%x)", message->src_address.u.short_addr, message->src_endpoint,
 message->dst_endpoint, message->cluster);
 // List through all Zigbee EPs and call the callback function, with the message
 for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it)
 {
 if (message->dst_endpoint == (*it)->getEndpoint())
 {
 (*it)->zbAttributeRead(message->cluster, &message->attribute); // method zbAttributeRead must be implemented in specific EP class
 }
 }
 return ESP_OK;
}

Because no logs are printed by this code, it appears execution never reaches zbAttributeRead(). I believe the config report setup itself is incorrect.

You must be logged in to vote
0 replies
Comment options

You should take a look on the Zigbee 3.0 Cluster Specification document and check the on/off cluster and its attributes to see If they are reportable. Sorry I have missed the status before. I will take a look also.

You must be logged in to vote
0 replies
Comment options

I will compare the binding details in
void ZigbeeThermostat::findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx)
with those in ZigbeeSwitch::findCb() in more detail.

You must be logged in to vote
0 replies
Comment options

Congratulations! I successfully got state reporting working. After pairing the Tuya commercial wall switch and physically toggling it ON/OFF, the state was automatically reported even without setting up a config report.

I set up bidirectional binding as shown in the code below, similar to the Thermostat example.

However, as a beginner with Zigbee, I still have an issue to resolve. I bound the device to a 3-gang wall switch, but currently only endpoint 1 is reporting. In the findCb() function stage, is it possible to check how many endpoints the switch has? If I can determine the number of endpoints, should I then create bindings for each of them?

I’d really appreciate it if you could help me just a little further.

void ZigbeeSwitch::findCb(esp_zb_zdp_status_t zdo_status, uint16_t addr, uint8_t endpoint, void *user_ctx)
{
 if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS)
 {
 log_d("Found light endpoint");
 zb_device_params_t *light = (zb_device_params_t *)malloc(sizeof(zb_device_params_t));
 light->endpoint = endpoint;
 light->short_addr = addr;
 esp_zb_ieee_address_by_short(light->short_addr, light->ieee_addr);
 uint8_t my_endpoint = *((uint8_t *)user_ctx);
 // 1. For report recv
 esp_zb_zdo_bind_req_param_t bind_req = {0};
 bind_req.req_dst_addr = addr;
 memcpy(bind_req.src_address, light->ieee_addr, sizeof(esp_zb_ieee_addr_t));
 bind_req.src_endp = endpoint;
 bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF;
 bind_req.dst_addr_mode = ESP_ZB_ZDO_BIND_DST_ADDR_MODE_64_BIT_EXTENDED;
 esp_zb_get_long_address(bind_req.dst_address_u.addr_long); // 내 주소
 bind_req.dst_endp = my_endpoint;
 log_i("Request light to bind us (for reporting)");
 esp_zb_zdo_device_bind_req(&bind_req, bindCb, (void *)light);
 // 2. For Cmd send
 memset(&bind_req, 0, sizeof(bind_req));
 bind_req.req_dst_addr = esp_zb_get_short_address();
 esp_zb_get_long_address(bind_req.src_address);
 bind_req.src_endp = my_endpoint;
 bind_req.cluster_id = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF;
 bind_req.dst_addr_mode = ESP_ZB_ZDO_BIND_DST_ADDR_MODE_64_BIT_EXTENDED;
 memcpy(bind_req.dst_address_u.addr_long, light->ieee_addr, sizeof(esp_zb_ieee_addr_t));
 bind_req.dst_endp = endpoint;
 log_i("Try to bind On/Off (for control)");
 esp_zb_zdo_device_bind_req(&bind_req, bindCb, (void *)light);
 }
 else
 {
 log_d("No light endpoint found");
 }
}

Log (VALUE is On & OFF)

19:53:09.297 -> Received report from address(0x276) src endpoint(1) to dst endpoint(5) cluster(0x6), VALUE(0)
19:53:11.710 -> Received report from address(0x276) src endpoint(1) to dst endpoint(5) cluster(0x6), VALUE(1)
19:53:12.302 -> Received report from address(0x276) src endpoint(1) to dst endpoint(5) cluster(0x6), VALUE(0)
19:53:12.846 -> Received report from address(0x276) src endpoint(1) to dst endpoint(5) cluster(0x6), VALUE(1)
You must be logged in to vote
0 replies
Comment options

@luxert Can you share your .ino file and complete custom ZigbeeSwitch class? So I can take a look and try to help.

You must be logged in to vote
0 replies
Comment options

Moving to discussions.

You must be logged in to vote
0 replies
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Question Only question Area: Zigbee Issues and Feature Request about Zigbee
Converted from issue

This discussion was converted from issue #11818 on September 15, 2025 07:13.

AltStyle によって変換されたページ (->オリジナル) /