-
Couldn't load subscription status.
- Fork 7.7k
How to integrate multiple gang switches with ESP32-C6 Arduino Zigbee_On_Off_Switch? #11089
-
Board
ESP32-C6
Device Description
Dev module
Hardware Configuration
Base setting
Version
v3.1.0
IDE Name
Arduino IDE 2.3.4
Operating System
Windows11
Flash frequency
80Mhz
PSRAM enabled
no
Upload speed
115200
Description
Hello,
I am using the Zigbee_On_Off_Switch example for Arduino with the ESP32-C6 module.
I successfully integrated the wall light switches from Tuya and other manufacturers, and the switch On/Off works fine. However, the wall light switch I have is a 3-gang switch.
The first switch works well with Zigbee_On_Off_Switch, but how should I get the second and third switches to work?
I am new to Zigbee and am having difficulty understanding how to set it up.
Sketch
#ifndef ZIGBEE_MODE_ZCZR #error "Zigbee coordinator mode is not selected in Tools->Zigbee mode" #endif #include "Zigbee.h" /* Zigbee switch configuration */ #define SWITCH_ENDPOINT_NUMBER 5 uint8_t buttonPin = BOOT_PIN; ZigbeeSwitch zbSwitch = ZigbeeSwitch(SWITCH_ENDPOINT_NUMBER); int buttonState; int lastButtonState = LOW; unsigned long lastDebounceTime = 0; // the last time the output pin was toggled unsigned long debounceDelay = 50; // the debounce time; increase if the output flickers /********************* Arduino functions **************************/ void setup() { Serial.begin(115200); //Init button switch pinMode(buttonPin, INPUT_PULLUP); //Optional: set Zigbee device name and model zbSwitch.setManufacturerAndModel("SPACETALK", "ZigbeeWALLSwitch"); //Optional to allow multiple light to bind to the switch zbSwitch.allowMultipleBinding(false); //Add endpoint to Zigbee Core Serial.println("Adding ZigbeeSwitch endpoint to Zigbee Core"); Zigbee.addEndpoint(&zbSwitch); //Open network for 180 seconds after boot Zigbee.setRebootOpenNetwork(180); // When all EPs are registered, start Zigbee with ZIGBEE_COORDINATOR mode if (!Zigbee.begin(ZIGBEE_COORDINATOR)) { Serial.println("Zigbee failed to start!"); Serial.println("Rebooting..."); ESP.restart(); } Serial.println("Waiting for Light to bound to the switch"); //Wait for switch to bound to a light: while (!zbSwitch.bound()) { Serial.printf("."); delay(500); } Serial.println(); // Optional: List all bound devices and read manufacturer and model name std::list<zb_device_params_t *> boundLights = zbSwitch.getBoundDevices(); for (const auto &device : boundLights) { Serial.printf("Device on endpoint %d, short address: 0x%x\r\n", device->endpoint, device->short_addr); Serial.printf( "IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4], device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0] ); char *manufacturer = zbSwitch.readManufacturer(device->endpoint, device->short_addr, device->ieee_addr); char *model = zbSwitch.readModel(device->endpoint, device->short_addr, device->ieee_addr); if (manufacturer != nullptr) { Serial.printf("Light manufacturer: %s\r\n", manufacturer); } if (model != nullptr) { Serial.printf("Light model: %s\r\n", model); } } Serial.println(" ---- END SETUP ----"); } void loop() { int reading = digitalRead(buttonPin); if (reading != lastButtonState) { // reset the debouncing timer lastDebounceTime = millis(); } if ((millis() - lastDebounceTime) > debounceDelay) { if (reading != buttonState) { buttonState = reading; // only toggle the LED if the new button state is HIGH if (buttonState == HIGH) { // Toggle light Serial.println(" --> BTN Input : Light Toggle"); zbSwitch.lightToggle(); } } } lastButtonState = reading; if (Serial.available()) { String command = Serial.readStringUntil('\n'); Serial.print(" SIG IN : "); Serial.println(command); if (command == "on") { Serial.println(" --> SIG Input : Light ON"); zbSwitch.lightOn(); } else if (command == "off") { Serial.println(" --> SIG Input : Light OFF"); zbSwitch.lightOff(); } else if (command == "freset") { Serial.println(" --> SIG Input : Factory Reset!"); delay(1500); Zigbee.factoryReset(); } } static uint32_t last_print = 0; if (millis() - last_print > 30000) { last_print = millis(); zbSwitch.printBoundDevices(Serial); } }
Debug Message
18:54:18.029 -> Adding ZigbeeSwitch endpoint to Zigbee Core
18:54:18.029 -> [ 509][D][ZigbeeCore.cpp:84] addEndpoint(): Endpoint: 5, Device ID: 0x0000
18:54:18.029 -> [ 520][D][ZigbeeCore.cpp:123] zigbeeInit(): Initialize Zigbee stack
18:54:18.106 -> [ 612][D][ZigbeeCore.cpp:130] zigbeeInit(): Register all Zigbee EPs in list
18:54:18.143 -> [ 620][I][ZigbeeCore.cpp:138] zigbeeInit(): List of registered Zigbee EPs:
18:54:18.143 -> [ 626][I][ZigbeeCore.cpp:140] zigbeeInit(): Device type: General On/Off switch, Endpoint: 5, Device ID: 0x0000
18:54:18.143 -> [ 643][V][ZigbeeCore.cpp:352] esp_zb_app_signal_handler(): ZDO signal: ZDO Config Ready (0x17), status: ESP_FAIL
18:54:18.143 -> [ 653][I][ZigbeeCore.cpp:219] esp_zb_app_signal_handler(): Zigbee stack initialized
18:54:18.179 -> [ 667][I][ZigbeeCore.cpp:341] esp_zb_app_signal_handler(): Network(0xca17) closed, devices joining not allowed.
18:54:18.179 -> [ 678][I][ZigbeeCore.cpp:225] esp_zb_app_signal_handler(): Device started up in non factory-reset mode
18:54:18.179 -> [ 688][I][ZigbeeCore.cpp:238] esp_zb_app_signal_handler(): Device rebooted
18:54:18.212 -> [ 695][I][ZigbeeCore.cpp:242] esp_zb_app_signal_handler(): Opening network for joining for 180 seconds
18:54:18.212 -> [ 704][D][ZigbeeCore.cpp:479] searchBindings(): Requesting binding table for address 0x0000
18:54:18.212 -> [ 713][D][ZigbeeCore.cpp:419] bindingTableCb(): Binding table callback for address 0x0000 with status 0
18:54:18.247 -> [ 723][D][ZigbeeCore.cpp:422] bindingTableCb(): Binding table info: total 1, index 0, count 1
18:54:18.247 -> [ 731][D][ZigbeeCore.cpp:432] bindingTableCb(): Binding table record: src_endp 5, dst_endp 1, cluster_id 0x0006, dst_addr_mode 3
18:54:18.247 -> [ 743][D][ZigbeeCore.cpp:449] bindingTableCb(): Device bound to EP 5 -> device endpoint: 1, short addr: 0x0000, ieee addr: DC:8E:95:FF:FE:E1:18:D2
18:54:18.247 -> [ 756][D][ZigbeeCore.cpp:470] bindingTableCb(): Filling bounded devices finished
18:54:18.289 -> Waiting for Light to bound to the switch
18:54:18.289 ->
18:54:18.289 -> Device on endpoint 1, short address: 0x0
18:54:18.289 -> IEEE Address: DC:8E:95:FF:FE:E1:18:D2
18:54:18.335 -> [ 810][I][ZigbeeCore.cpp:339] esp_zb_app_signal_handler(): Network(0xca17) is open for 180 seconds
18:54:18.368 -> [ 869][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0x2dd8) src endpoint(1) to dst endpoint(5) cluster(0x0)
18:54:18.413 -> [ 883][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x4), type(0x42), value(9)
18:54:18.413 -> [ 897][I][ZigbeeEP.cpp:218] zbReadBasicCluster(): Peer Manufacturer is "DAWON_DNS"
18:54:18.492 -> [ 974][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0x2dd8) src endpoint(1) to dst endpoint(5) cluster(0x0)
18:54:18.492 -> [ 988][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x5), type(0x42), value(10)
18:54:18.523 -> [ 1002][I][ZigbeeEP.cpp:227] zbReadBasicCluster(): Peer Model is "PM-S350-ZB"
18:54:18.523 -> Light manufacturer: DAWON_DNS
18:54:18.523 -> Light model: PM-S350-ZB
18:54:18.523 -> ---- END SETUP ----
18:54:18.523 -> =========== After Setup Start ============
18:54:18.523 -> INTERNAL Memory Info:
18:54:18.523 -> ------------------------------------------
18:54:18.523 -> Total Size : 448396 B ( 437.9 KB)
18:54:18.557 -> Free Bytes : 381212 B ( 372.3 KB)
18:54:18.557 -> Allocated Bytes : 59032 B ( 57.6 KB)
18:54:18.557 -> Minimum Free Bytes: 381184 B ( 372.2 KB)
18:54:18.557 -> Largest Free Block: 352244 B ( 344.0 KB)
18:54:18.557 -> ------------------------------------------
18:54:18.557 -> GPIO Info:
18:54:18.557 -> ------------------------------------------
18:54:18.557 -> GPIO : BUS_TYPE[bus/unit][chan]
18:54:18.557 -> --------------------------------------
18:54:18.557 -> 9 : GPIO
18:54:18.557 -> 16 : UART_TX[0]
18:54:18.599 -> 17 : UART_RX[0]
18:54:18.599 -> ============ After Setup End =============
18:54:18.689 -> --> BTN Input : Light Toggle
18:54:18.689 -> [ 1149][V][ZigbeeSwitch.cpp:72] lightToggle(): Sending 'light toggle' command
18:54:18.721 -> [ 1217][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x2dd8), src_endpoint(1) to dst_endpoint(5), cluster(0x6) with status 0x81
18:54:40.404 -> SIG IN : on
18:54:40.404 -> --> SIG Input : Light ON
18:54:40.404 -> [ 22905][V][ZigbeeSwitch.cpp:140] lightOn(): Sending 'light on' command
18:54:40.481 -> [ 22976][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x2dd8), src_endpoint(1) to dst_endpoint(5), cluster(0x6) with status 0x0
18:54:42.246 -> SIG IN : off
18:54:42.246 -> --> SIG Input : Light OFF
18:54:42.246 -> [ 24717][V][ZigbeeSwitch.cpp:208] lightOff(): Sending 'light off' command
18:54:42.283 -> [ 24789][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x2dd8), src_endpoint(1) to dst_endpoint(5), cluster(0x6) with status 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.
Beta Was this translation helpful? Give feedback.
All reactions
Replies: 12 comments
-
Hi @luxert, I have been playing with this today and for now without any changes needed to the Zigbee library you can use approach of single Switch endpoint (Coordinator) + multiple light connected to it (end devices).
You just need to set the zbSwitch.allowMultipleBinding to true.
//Optional to allow multiple light to bind to the switch
zbSwitch.allowMultipleBinding(true);
After that all the lights can connect and will be bound to the switch.
To control the light/s you can do following:
Use any of the control function lightToggle, lightOn or lightOff. I will do an example for the lightToggle:
To control all light at once, use:
void lightToggle();
To control lights individually, you need to specify the endpoint, short_addr or endpoint, ieee_addr:
void lightToggle(uint8_t endpoint, uint16_t short_addr); void lightToggle(uint8_t endpoint, esp_zb_ieee_addr_t ieee_addr);
You can get the endpoints and addresses from the list of bound devices, which you can get by calling getBoundDevices() as its done in the example at the end of setup() after // Optional: List all bound devices and read manufacturer and model name.
Let me know if you need any help.
I have also in progress the 2nd approach of having multiple Switch endpoints where each switch endpoint can have 1 light bounded. This approach needs changes in the Zigbee library and is in progress.
Beta Was this translation helpful? Give feedback.
All reactions
-
Thank you very much for the detailed answer. @P-R-O-C-H-Y
I registered two wall light switches using zbSwitch.allowMultipleBinding(true) and successfully controlled the switches individually through the endpoint and Short_addr.
I have a few more questions:
After registering the device, the Short_Addr is displayed correctly in getBoundDevices(). However, after rebooting the ESP32-C6, the Short_Addr is displayed as 0x0. While the display shows 0x0, I can still control the device individually with the previously recorded short_addr. (When a signal is sent, the response shows the correct Short_addr). Is this a bug?
`----Register First
09:44:06.922 -> Device on endpoint 1, short address: 0xd301
09:44:06.922 -> IEEE Address: DC:8E:95:FF:FE:E1:18:D2
09:44:06.956 -> [136700][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0xd301) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:44:06.999 -> [136714][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x4), type(0x42), value(9)
09:44:06.999 -> [136728][I][ZigbeeEP.cpp:218] zbReadBasicCluster(): Peer Manufacturer is "DAWON_DNS"
09:44:07.078 -> [136804][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0xd301) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:44:07.078 -> [136819][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x5), type(0x42), value(10)
09:44:07.121 -> [136832][I][ZigbeeEP.cpp:227] zbReadBasicCluster(): Peer Model is "PM-S350-ZB"
09:44:07.121 -> Light manufacturer: DAWON_DNS
09:44:07.121 -> Light model: PM-S350-ZB
09:44:07.121 -> Device on endpoint 1, short address: 0x9a5f
09:44:07.121 -> IEEE Address: 00:15:8D:00:8B:0C:01:B3
09:44:07.153 -> [136876][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0x9a5f) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:44:07.153 -> [136891][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x4), type(0x42), value(11)
09:44:07.199 -> [136904][I][ZigbeeEP.cpp:218] zbReadBasicCluster(): Peer Manufacturer is "ShinaSystem"
09:44:07.233 -> [136948][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0x9a5f) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:44:07.233 -> [136962][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x5), type(0x42), value(8)
09:44:07.233 -> [136976][I][ZigbeeEP.cpp:227] zbReadBasicCluster(): Peer Model is "SBM300Z3"
09:44:07.276 -> Light manufacturer: ShinaSystem
09:44:07.276 -> Light model: SBM300Z3
----After Reboot
09:48:21.356 -> Device on endpoint 1, short address: 0x0
09:48:21.356 -> IEEE Address: DC:8E:95:FF:FE:E1:18:D2
09:48:21.387 -> [ 15460][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0xd301) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:48:21.433 -> [ 15474][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x4), type(0x42), value(9)
09:48:21.433 -> [ 15488][I][ZigbeeEP.cpp:218] zbReadBasicCluster(): Peer Manufacturer is "DAWON_DNS"
09:48:21.513 -> [ 15564][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0xd301) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:48:21.513 -> [ 15578][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x5), type(0x42), value(10)
09:48:21.556 -> [ 15592][I][ZigbeeEP.cpp:227] zbReadBasicCluster(): Peer Model is "PM-S350-ZB"
09:48:21.556 -> Light manufacturer: DAWON_DNS
09:48:21.556 -> Light model: PM-S350-ZB
09:48:21.556 -> Device on endpoint 1, short address: 0x0
09:48:21.556 -> IEEE Address: 00:15:8D:00:8B:0C:01:B3
09:48:21.589 -> [ 15634][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0x9a5f) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:48:21.589 -> [ 15648][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x4), type(0x42), value(11)
09:48:21.589 -> [ 15662][I][ZigbeeEP.cpp:218] zbReadBasicCluster(): Peer Manufacturer is "ShinaSystem"
09:48:21.621 -> [ 15688][V][ZigbeeHandlers.cpp:82] zb_cmd_read_attr_resp_handler(): Read attribute response: from address(0x9a5f) src endpoint(1) to dst endpoint(5) cluster(0x0)
09:48:21.664 -> [ 15702][V][ZigbeeHandlers.cpp:91] zb_cmd_read_attr_resp_handler(): Read attribute response: status(0), cluster(0x0), attribute(0x5), type(0x42), value(8)
09:48:21.664 -> [ 15716][I][ZigbeeEP.cpp:227] zbReadBasicCluster(): Peer Model is "SBM300Z3"
09:48:21.664 -> Light manufacturer: ShinaSystem
09:48:21.664 -> Light model: SBM300Z3`
I connected two wall light switches for testing. Can I unpair only one of the connected devices using its Short_addr and IEEE addr, etc.? In other words, can I unpair a specific device using Short_addr, etc.? Currently, I am performing a factory reset to unpair all devices and then registering them individually again.
Can I check the state of the wall light switch? I can use LightOn() and LightOff() to turn the switches on and off. However, I would like to know the state when the user turns the wall light switch on or off manually. I believe the off-the-shelf product might provide a response, but nothing is reported in the handler. I’m wondering if there is a way to know the state, either via an event or polling.
Can I check the connection status of the wall light switch? I turned off the power of one of the two connected wall light switches. When calling LightOn(), the following happens:
[1005698][V][ZigbeeCore.cpp:352] esp_zb_app_signal_handler(): ZDO signal: NLME Status Indication (0x32), status: ESP_OK 10:32:29.929 -> [1014712][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x9a5f), src_endpoint(1) to dst_endpoint(5), cluster(0x6) with status 0x0
The switch that is still on works normally and the response appears, while the switch that is off shows the NLME Status. I’m wondering if I can detect the device's connection status (e.g., Connected, Joined, or Disconnected) or any state without sending a control signal.
Do you have an estimate of when support for Tuya-style 3Gang wall light switches, such as Top_Button, Center_Button, and Bottom_Button, will be available?
Can the current control state not be feedback in the Zigbee_On_Off_Switch.ino through the zb_cmd_default_resp_handler()?
Once again, I am very, very, very grateful for your help!
Beta Was this translation helpful? Give feedback.
All reactions
-
You are welcome, I am glad that worked well for you @luxert.
After registering the device, the Short_Addr is displayed correctly in getBoundDevices(). However, after rebooting the ESP32-C6, the Short_Addr is displayed as 0x0. While the display shows 0x0, I can still control the device individually with the previously recorded short_addr. (When a signal is sent, the response shows the correct Short_addr). Is this a bug?
Thing is that only the ieee address + endpoint is stored in the binding table, which is recalled when you reset(reboot) the device. The devices still have the same short addresses, so you can use that to control it. It's not bug tho.
I connected two wall light switches for testing. Can I unpair only one of the connected devices using its Short_addr and IEEE addr, etc.? In other words, can I unpair a specific device using Short_addr, etc.? Currently, I am performing a factory reset to unpair all devices and then registering them individually again.
Currently no, but I will take a look and add API to do this. It should be possible for sure. Good feature request there.
Can I check the state of the wall light switch? I can use LightOn() and LightOff() to turn the switches on and off. However, I would like to know the state when the user turns the wall light switch on or off manually. I believe the off-the-shelf product might provide a response, but nothing is reported in the handler. I’m wondering if there is a way to know the state, either via an event or polling.
I was not testing that, as I most of time use HomeAssistant which does this exact thing. I will take a look on the correct approach.
It will be just about reading the state of the on/off attribute.
Can I check the connection status of the wall light switch? I turned off the power of one of the two connected wall light switches.
Not sure, as the device did not leave the network, it's just offline. I can take a look on this also.
Do you have an estimate of when support for Tuya-style 3Gang wall light switches, such as Top_Button, Center_Button, and Bottom_Button, will be available?
Can you please provide more info about this? I was assuming you are now doing exactly this, so there is not much needed to add some kind of support for this.
Can the current control state not be feedback in the Zigbee_On_Off_Switch.ino through the zb_cmd_default_resp_handler()?
I will take a look :)
Beta Was this translation helpful? Give feedback.
All reactions
-
Question 5. Test..
For Tuya-style multi-gang light switches, I tested by changing the Endpoint to 1, 2, and 3 using zbSwitch.lightOn(Endpoint, Short_addr), and both the second and third buttons worked properly.
if (command == "on11") { Serial.println(" --> SIG Input : Light ON"); zbSwitch.lightOn(1, 0x59d1); }else if (command == "on12") { Serial.println(" --> SIG Input : Light ON"); zbSwitch.lightOn(2, 0x59d1); }
18:14:31.868 -> SIG IN : on11
18:14:31.868 -> --> SIG Input : Light ON
18:14:31.868 -> [1046601][V][ZigbeeSwitch.cpp:173] lightOn(): Sending 'light on' command to endpoint 1, address 0x59d1
18:14:31.913 -> [1046639][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x59d1), src_endpoint(1) to dst_endpoint(5), cluster(0x6) with status 0x0
18:14:34.211 -> SIG IN : on12
18:14:34.212 -> --> SIG Input : Light ON
18:14:34.212 -> [1048969][V][ZigbeeSwitch.cpp:173] lightOn(): Sending 'light on' command to endpoint 2, address 0x59d1
18:14:34.245 -> [1049002][V][ZigbeeHandlers.cpp:134] zb_cmd_default_resp_handler(): Received default response: from address(0x59d1), src_endpoint(2) to dst_endpoint(5), cluster(0x6) with status 0x0
Beta Was this translation helpful? Give feedback.
All reactions
-
🎉 1
-
@P-R-O-C-H-Y
In the Zigbee_On_Off_Switch.ino, I want to receive a report every time the light state changes through an API like zb_cmd_default_resp_handler(). Could you please take a closer look? I would like to receive a report on the coordinator switch whenever a Tuya-style multi-gang switch is turned on or off. Please help me..
Beta Was this translation helpful? Give feedback.
All reactions
-
@luxert Do you mean to receive a response that the command did the effect (turned on/off), ro you mean if you physically turn on/off the switch so it sends a report to coordinator that it have been switched?
Beta Was this translation helpful? Give feedback.
All reactions
-
@P-R-O-C-H-Y
I would like to receive On/Off reports in the coordinator(Switch.ino example) when the user physically turns the switch( Tuya style multi gang switch) on or off.
Thank you for your help.
Beta Was this translation helpful? Give feedback.
All reactions
-
@P-R-O-C-H-Y
I referenced the example
(esp-zigbee-sdk/examples/esp_zigbee_customized_devices/customized_client/main/esp_HA_customized_switch.c)
and added code to the bindCb() function of ZigbeeSwitch.cpp for state change reporting. However, I am receiving the response
zb_configure_report_resp_handler() : Configure report response: status(0), cluster(0x6), direction(0xff), attribute(0xffff)
, and it's not working. Can you help me identify what the issue might be?
void ZigbeeSwitch::bindCb(esp_zb_zdp_status_t zdo_status, void *user_ctx) { if (zdo_status == ESP_ZB_ZDP_STATUS_SUCCESS) { log_i(" -------->>> Bound successfully!"); if (user_ctx) { zb_device_params_t *light = (zb_device_params_t *)user_ctx; log_i("The light originating from address(0x%x) on endpoint(%d)", light->short_addr, light->endpoint); _instance->_bound_devices.push_back(light); esp_zb_zcl_config_report_cmd_t report_cmd = {0}; bool report_change = 1; report_cmd.zcl_basic_cmd.dst_addr_u.addr_short = light->short_addr; // Tuya Multi Gang switch addr report_cmd.zcl_basic_cmd.dst_endpoint = light->endpoint; // Tuya Multi Gang switch endpoint report_cmd.zcl_basic_cmd.src_endpoint = 5; // ESP32-c6 Switch Endpoint report_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_16_ENDP_PRESENT; report_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ON_OFF; esp_zb_zcl_config_report_record_t records[] = { { //.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_SRV, .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 = 0, .max_interval = 30, .reportable_change = &report_change }, }; report_cmd.record_number = sizeof(records) / sizeof(esp_zb_zcl_config_report_record_t); report_cmd.record_field = records; esp_zb_zcl_config_report_cmd_req(&report_cmd); log_i(" -------->>> REPORT CONFIG SEND !!!! <<<--------"); } _is_bound = true; } }
Beta Was this translation helpful? Give feedback.
All reactions
-
@P-R-O-C-H-Y
Hello. I haven't been able to resolve the report issue yet.
I plan to periodically check the status of the switch temporarily through
esp_zb_zcl_read_attr_cmd_req(&cmd_req);
The next issue is how to specify and unbind a bound device (and also delete the bind table).
Using Zigbee.factoryReset(); disconnects all devices, so it cannot be used.
For example, when two devices are connected and I want to disconnect the first device, I used the IEEE address of the first device as shown below,
void STZigbeeSwitch::remove_device(esp_zb_ieee_addr_t ieee_address) { esp_zb_zdo_mgmt_leave_req_param_t leave_req; //leave_req.device_address = ieee_address, memcpy(leave_req.device_address, ieee_address, sizeof(esp_zb_ieee_addr_t)); leave_req.remove_children = true; leave_req.rejoin = false; Serial.printf( " >> LEAVE REQUEST IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", leave_req.device_address[0], leave_req.device_address[1], leave_req.device_address[2], leave_req.device_address[3], leave_req.device_address[4], leave_req.device_address[5], leave_req.device_address[6], leave_req.device_address[7] ); esp_zb_zdo_device_leave_req(&leave_req, leave_cb, NULL); }
but it failed.
07:10:32.300 -> >> LEAVE REQUEST IEEE Address: B3:01:0C:8B:00:8D:15:00
07:10:37.283 -> <><><><><><><><><><><><> Failed to remove device from the network.
07:10:42.331 -> [ 41608][V][STZigbeeCore.cpp:359] esp_zb_app_signal_handler(): ST ZDO signal: NLME Status Indication (0x32), status: ESP_OK
07:10:57.399 -> [ 56623][V][STZigbeeCore.cpp:359] esp_zb_app_signal_handler(): ST ZDO signal: NLME Status Indication (0x32), status: ESP_OK
07:11:12.396 -> [ 71637][V][STZigbeeCore.cpp:359] esp_zb_app_signal_handler(): ST ZDO signal: NLME Status Indication (0x32), status: ESP_OK
07:11:27.409 -> [ 86652][V][STZigbeeCore.cpp:359] esp_zb_app_signal_handler(): ST ZDO signal: NLME Status Indication (0x32), status: ESP_OK
07:11:32.288 -> [ 91568][V][STZigbeeCore.cpp:359] esp_zb_app_signal_handler(): ST ZDO signal: ZDO Device Unavailable (0x3c), status: ESP_OK
I am also wondering if I should use esp_zb_zdo_device_unbind_req() instead.
I am wondering if there is a solution for this.
Beta Was this translation helpful? Give feedback.
All reactions
-
Hello. I successfully unbound the device from the network using esp_zb_zdo_device_unbind_req().
void ZigbeeSwitch::zigbeeDeviceUnbindReq(uint16_t rid,esp_zb_ieee_addr_t src_addr,esp_zb_ieee_addr_t des_addr,uint16_t cluster_id,uint8_t src_ep,uint8_t des_ep){ ESP_LOGE("ZIGBEE","Sending UNBIND"); esp_zb_zdo_bind_req_param_t bind_req; uint16_t* user_rid = (uint16_t*)malloc(sizeof(uint16_t)); *user_rid=rid; bind_req.cluster_id=cluster_id; bind_req.dst_addr_mode=ESP_ZB_APS_ADDR_MODE_64_ENDP_PRESENT; memcpy(bind_req.src_address,src_addr,sizeof(esp_zb_ieee_addr_t)); memcpy(bind_req.dst_address_u.addr_long,des_addr,sizeof(esp_zb_ieee_addr_t)); //bind_req.dst_endp=des_ep; //bind_req.src_endp=src_ep; bind_req.dst_endp=1; bind_req.src_endp=5; bind_req.req_dst_addr=esp_zb_address_short_by_ieee(src_addr); esp_zb_zdo_device_unbind_req(&bind_req, unbindnew_cb, (void *)user_rid); } void ZigbeeSwitch::unbindnew_cb(esp_zb_zdp_status_t zdo_status, void *user_ctx) { ESP_LOGE("ZIGBEE","CALLBACK UNBIND status %d",zdo_status); free(user_ctx); }
I referred to the post on the following link: espressif/esp-zigbee-sdk#318
Thanks!!! @P-R-O-C-H-Y
Now, I just need to resolve the part where I automatically receive the light's status report.
I would appreciate a bit more help with the reporting.
Beta Was this translation helpful? Give feedback.
All reactions
-
🚀 1
-
Hi @luxert, I am glad you made that work! Great job.
Do you plan to open a PR with this feature or can I add it myself for all EPs :)
About the "automatically receive the light's status report", I think it may be done using the POLL cluster, but this is not implemented yet. I may need to take a look and prepare the code.
Beta Was this translation helpful? Give feedback.
All reactions
-
Hello all, great work
Any consolidated code combining all the fixes mentioned above or a complete example for multiple button/relay light switch ?
Beta Was this translation helpful? Give feedback.