Skip to content

Commit 9a9cba6

Browse files
committed
feat(zigbee): Add endpoint identification in read handlers
1 parent 91fd517 commit 9a9cba6

File tree

5 files changed

+307
-10
lines changed

5 files changed

+307
-10
lines changed

libraries/Zigbee/examples/Zigbee_Thermostat/Zigbee_Thermostat.ino

Lines changed: 39 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,8 @@
3434
#include "Zigbee.h"
3535

3636
/* Zigbee thermostat configuration */
37-
#define THERMOSTAT_ENDPOINT_NUMBER 5
37+
#define THERMOSTAT_ENDPOINT_NUMBER 1
38+
#define USE_RECIEVE_TEMP_WITH_SOURCE 1
3839
uint8_t button = BOOT_PIN;
3940

4041
ZigbeeThermostat zbThermostat = ZigbeeThermostat(THERMOSTAT_ENDPOINT_NUMBER);
@@ -48,10 +49,21 @@ float sensor_tolerance;
4849
struct tm timeinfo = {}; // Time structure for Time cluster
4950

5051
/****************** Temperature sensor handling *******************/
52+
#if USE_RECIEVE_TEMP_WITH_SOURCE == 0
5153
void recieveSensorTemp(float temperature) {
5254
Serial.printf("Temperature sensor value: %.2f°C\n", temperature);
5355
sensor_temp = temperature;
5456
}
57+
#else
58+
void recieveSensorTempWithSource(float temperature, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address) {
59+
if (src_address.addr_type == ESP_ZB_ZCL_ADDR_TYPE_SHORT) {
60+
Serial.printf("Temperature sensor value: %.2f°C from endpoint %d, address 0x%04x\n", temperature, src_endpoint, src_address.u.short_addr);
61+
} else {
62+
Serial.printf("Temperature sensor value: %.2f°C from endpoint %d, address %02x:%02x:%02x:%02x:%02x:%02x:%02x:%02x\n", temperature, src_endpoint, src_address.u.ieee_addr[7], src_address.u.ieee_addr[6], src_address.u.ieee_addr[5], src_address.u.ieee_addr[4], src_address.u.ieee_addr[3], src_address.u.ieee_addr[2], src_address.u.ieee_addr[1], src_address.u.ieee_addr[0]);
63+
}
64+
sensor_temp = temperature;
65+
}
66+
#endif
5567

5668
void recieveSensorConfig(float min_temp, float max_temp, float tolerance) {
5769
Serial.printf("Temperature sensor settings: min %.2f°C, max %.2f°C, tolerance %.2f°C\n", min_temp, max_temp, tolerance);
@@ -66,8 +78,14 @@ void setup() {
6678
// Init button switch
6779
pinMode(button, INPUT_PULLUP);
6880

69-
// Set callback functions for temperature and configuration receive
70-
zbThermostat.onTempRecieve(recieveSensorTemp);
81+
// Set callback function for recieving temperature from sensor - Use only one option
82+
#if USE_RECIEVE_TEMP_WITH_SOURCE == 0
83+
zbThermostat.onTempRecieve(recieveSensorTemp); // If you bound only one sensor or you don't need to know the source of the temperature
84+
#else
85+
zbThermostat.onTempRecieveWithSource(recieveSensorTempWithSource);
86+
#endif
87+
88+
// Set callback function for recieving sensor configuration
7189
zbThermostat.onConfigRecieve(recieveSensorConfig);
7290

7391
//Optional: set Zigbee device name and model
@@ -107,7 +125,22 @@ void setup() {
107125

108126
Serial.println();
109127

110-
// Get temperature sensor configuration
128+
// Get temperature sensor configuration for each bound sensor
129+
std::list<zb_device_params_t *> boundLights = zbThermostat.getBoundDevices();
130+
for (const auto &device : boundLights) {
131+
Serial.println("--------------------------------");
132+
if(device->short_addr == 0x0000 || device->short_addr == 0xFFFF) { //End devices never have 0x0000 short address or 0xFFFF group address
133+
Serial.printf("Device on endpoint %d, IEEE Address: %02X:%02X:%02X:%02X:%02X:%02X:%02X:%02X\r\n", device->endpoint, device->ieee_addr[7], device->ieee_addr[6], device->ieee_addr[5], device->ieee_addr[4],
134+
device->ieee_addr[3], device->ieee_addr[2], device->ieee_addr[1], device->ieee_addr[0]);
135+
zbThermostat.getSensorSettings(device->endpoint, device->ieee_addr);
136+
} else {
137+
Serial.printf("Device on endpoint %d, short address: 0x%x\r\n", device->endpoint, device->short_addr);
138+
zbThermostat.getSensorSettings(device->endpoint, device->short_addr);
139+
}
140+
}
141+
142+
Serial.println("--------------------------------");
143+
Serial.println("Getting sensor settings for all bound sensors");
111144
zbThermostat.getSensorSettings();
112145
}
113146

@@ -130,5 +163,7 @@ void loop() {
130163
last_print = millis();
131164
int temp_percent = (int)((sensor_temp - sensor_min_temp) / (sensor_max_temp - sensor_min_temp) * 100);
132165
Serial.printf("Loop temperature info: %.2f°C (%d %%)\n", sensor_temp, temp_percent);
166+
Serial.println("Bound devices:");
167+
zbThermostat.printBoundDevices(Serial);
133168
}
134169
}

libraries/Zigbee/src/ZigbeeEP.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ class ZigbeeEP {
131131

132132
// list of all handlers function calls, to be override by EPs implementation
133133
virtual void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) {};
134-
virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute) {};
134+
virtual void zbAttributeRead(uint16_t cluster_id, const esp_zb_zcl_attribute_t *attribute, uint8_t src_endpoint, esp_zb_zcl_addr_t src_address) {};
135135
virtual void zbReadBasicCluster(const esp_zb_zcl_attribute_t *attribute); //already implemented
136136
virtual void zbIdentify(const esp_zb_zcl_set_attr_value_message_t *message);
137137
virtual void zbWindowCoveringMovementCmd(const esp_zb_zcl_window_covering_movement_message_t *message) {};

libraries/Zigbee/src/ZigbeeHandlers.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ static esp_err_t zb_attribute_reporting_handler(const esp_zb_zcl_report_attr_mes
108108
// List through all Zigbee EPs and call the callback function, with the message
109109
for (std::list<ZigbeeEP *>::iterator it = Zigbee.ep_objects.begin(); it != Zigbee.ep_objects.end(); ++it) {
110110
if (message->dst_endpoint == (*it)->getEndpoint()) {
111-
(*it)->zbAttributeRead(message->cluster, &message->attribute); //method zbAttributeRead must be implemented in specific EP class
111+
(*it)->zbAttributeRead(message->cluster, &message->attribute, message->src_endpoint, message->src_address); //method zbAttributeRead must be implemented in specific EP class
112112
}
113113
}
114114
return ESP_OK;
@@ -142,7 +142,7 @@ static esp_err_t zb_cmd_read_attr_resp_handler(const esp_zb_zcl_cmd_read_attr_re
142142
} else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_TIME) {
143143
(*it)->zbReadTimeCluster(&variable->attribute); //method zbReadTimeCluster implemented in the common EP class
144144
} else {
145-
(*it)->zbAttributeRead(message->info.cluster, &variable->attribute); //method zbAttributeRead must be implemented in specific EP class
145+
(*it)->zbAttributeRead(message->info.cluster, &variable->attribute, message->info.src_endpoint, message->info.src_address); //method zbAttributeRead must be implemented in specific EP class
146146
}
147147
}
148148
variable = variable->next;

0 commit comments

Comments
 (0)