Skip to content

Commit fa56f6f

Browse files
committed
feat(zigbee): Add methot to set,get,report analog output
1 parent f3ae2a6 commit fa56f6f

File tree

4 files changed

+65
-13
lines changed

4 files changed

+65
-13
lines changed

libraries/Zigbee/examples/Zigbee_Analog_Input_Output/Zigbee_Analog_Input_Output.ino

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -26,8 +26,8 @@
2626
* Modified by Pat Clay
2727
*/
2828

29-
#ifndef ZIGBEE_MODE_ED
30-
#error "Zigbee end device mode is not selected in Tools->Zigbee mode"
29+
#ifndef ZIGBEE_MODE_ZCZR
30+
#error "Zigbee coordinator/router device mode is not selected in Tools->Zigbee mode"
3131
#endif
3232

3333
#include "Zigbee.h"
@@ -70,6 +70,7 @@ void setup() {
7070
zbAnalogDevice.addAnalogOutput();
7171
zbAnalogDevice.setAnalogOutputApplication(ESP_ZB_ZCL_AI_RPM_OTHER);
7272
zbAnalogDevice.setAnalogOutputDescription("Fan Speed (RPM)");
73+
zbAnalogDevice.setAnalogOutputResolution(1);
7374

7475
// If analog output cluster is added, set callback function for analog output change
7576
zbAnalogDevice.onAnalogOutputChange(onAnalogOutputChange);
@@ -99,8 +100,8 @@ void setup() {
99100
Zigbee.addEndpoint(&zbAnalogPercent);
100101

101102
Serial.println("Starting Zigbee...");
102-
// When all EPs are registered, start Zigbee in End Device mode
103-
if (!Zigbee.begin()) {
103+
// When all EPs are registered, start Zigbee in Router Device mode
104+
if (!Zigbee.begin(ZIGBEE_ROUTER)) {
104105
Serial.println("Zigbee failed to start!");
105106
Serial.println("Rebooting...");
106107
ESP.restart();
@@ -151,6 +152,9 @@ void loop() {
151152
Zigbee.factoryReset();
152153
}
153154
}
155+
// For demonstration purposes, increment the analog output value by 100
156+
zbAnalogDevice.setAnalogOutput(zbAnalogDevice.getAnalogOutput() + 100);
157+
zbAnalogDevice.reportAnalogOutput();
154158
}
155159
delay(100);
156160
}

libraries/Zigbee/keywords.txt

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -142,13 +142,14 @@ setSensorType KEYWORD2
142142
setCarbonDioxide KEYWORD2
143143

144144
# ZigbeeAnalog
145-
addAnalogValue KEYWORD2
146145
addAnalogInput KEYWORD2
147146
addAnalogOutput KEYWORD2
148147
onAnalogOutputChange KEYWORD2
149-
setAnalogValue KEYWORD2
150148
setAnalogInput KEYWORD2
149+
setAnalogOutput KEYWORD2
150+
getAnalogOutput KEYWORD2
151151
reportAnalogInput KEYWORD2
152+
reportAnalogOutput KEYWORD2
152153
setAnalogInputReporting KEYWORD2
153154

154155
# ZigbeeCarbonDioxideSensor

libraries/Zigbee/src/ep/ZigbeeAnalog.cpp

Lines changed: 45 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -129,8 +129,8 @@ bool ZigbeeAnalog::setAnalogOutputApplication(uint32_t application_type) {
129129
void ZigbeeAnalog::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) {
130130
if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_ANALOG_OUTPUT) {
131131
if (message->attribute.id == ESP_ZB_ZCL_ATTR_ANALOG_OUTPUT_PRESENT_VALUE_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_SINGLE) {
132-
float analog_output = *(float *)message->attribute.data.value;
133-
analogOutputChanged(analog_output);
132+
_output_state = *(float *)message->attribute.data.value;
133+
analogOutputChanged();
134134
} else {
135135
log_w("Received message ignored. Attribute ID: %d not supported for Analog Output", message->attribute.id);
136136
}
@@ -139,9 +139,9 @@ void ZigbeeAnalog::zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *mes
139139
}
140140
}
141141

142-
void ZigbeeAnalog::analogOutputChanged(float analog_output) {
142+
void ZigbeeAnalog::analogOutputChanged() {
143143
if (_on_analog_output_change) {
144-
_on_analog_output_change(analog_output);
144+
_on_analog_output_change(_output_state);
145145
} else {
146146
log_w("No callback function set for analog output change");
147147
}
@@ -166,6 +166,26 @@ bool ZigbeeAnalog::setAnalogInput(float analog) {
166166
return true;
167167
}
168168

169+
bool ZigbeeAnalog::setAnalogOutput(float analog) {
170+
esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
171+
_output_state = analog;
172+
analogOutputChanged();
173+
174+
log_v("Updating analog output to %.2f", analog);
175+
/* Update analog output */
176+
esp_zb_lock_acquire(portMAX_DELAY);
177+
ret = esp_zb_zcl_set_attribute_val(
178+
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_ANALOG_OUTPUT, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ANALOG_OUTPUT_PRESENT_VALUE_ID, &_output_state, false
179+
);
180+
esp_zb_lock_release();
181+
182+
if (ret != ESP_ZB_ZCL_STATUS_SUCCESS) {
183+
log_e("Failed to set analog output: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
184+
return false;
185+
}
186+
return true;
187+
}
188+
169189
bool ZigbeeAnalog::reportAnalogInput() {
170190
/* Send report attributes command */
171191
esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
@@ -187,6 +207,27 @@ bool ZigbeeAnalog::reportAnalogInput() {
187207
return true;
188208
}
189209

210+
bool ZigbeeAnalog::reportAnalogOutput() {
211+
/* Send report attributes command */
212+
esp_zb_zcl_report_attr_cmd_t report_attr_cmd;
213+
report_attr_cmd.address_mode = ESP_ZB_APS_ADDR_MODE_DST_ADDR_ENDP_NOT_PRESENT;
214+
report_attr_cmd.attributeID = ESP_ZB_ZCL_ATTR_ANALOG_OUTPUT_PRESENT_VALUE_ID;
215+
report_attr_cmd.direction = ESP_ZB_ZCL_CMD_DIRECTION_TO_CLI;
216+
report_attr_cmd.clusterID = ESP_ZB_ZCL_CLUSTER_ID_ANALOG_OUTPUT;
217+
report_attr_cmd.zcl_basic_cmd.src_endpoint = _endpoint;
218+
report_attr_cmd.manuf_code = ESP_ZB_ZCL_ATTR_NON_MANUFACTURER_SPECIFIC;
219+
220+
esp_zb_lock_acquire(portMAX_DELAY);
221+
esp_err_t ret = esp_zb_zcl_report_attr_cmd_req(&report_attr_cmd);
222+
esp_zb_lock_release();
223+
if (ret != ESP_OK) {
224+
log_e("Failed to send Analog Output report: 0x%x: %s", ret, esp_err_to_name(ret));
225+
return false;
226+
}
227+
log_v("Analog Output report sent");
228+
return true;
229+
}
230+
190231
bool ZigbeeAnalog::setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta) {
191232
esp_zb_zcl_reporting_info_t reporting_info;
192233
memset(&reporting_info, 0, sizeof(esp_zb_zcl_reporting_info_t));

libraries/Zigbee/src/ep/ZigbeeAnalog.h

Lines changed: 9 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -46,11 +46,16 @@ class ZigbeeAnalog : public ZigbeeEP {
4646
_on_analog_output_change = callback;
4747
}
4848

49-
// Set the analog input value
49+
// Set the Analog Input/Output value
5050
bool setAnalogInput(float analog);
51+
bool setAnalogOutput(float analog);
5152

52-
// Report Analog Input value
53+
// Get the Analog Output value
54+
float getAnalogOutput() { return _output_state; }
55+
56+
// Report Analog Input/Output
5357
bool reportAnalogInput();
58+
bool reportAnalogOutput();
5459

5560
// Set reporting for Analog Input
5661
bool setAnalogInputReporting(uint16_t min_interval, uint16_t max_interval, float delta);
@@ -59,9 +64,10 @@ class ZigbeeAnalog : public ZigbeeEP {
5964
void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override;
6065

6166
void (*_on_analog_output_change)(float);
62-
void analogOutputChanged(float analog_output);
67+
void analogOutputChanged();
6368

6469
uint8_t _analog_clusters;
70+
float _output_state;
6571
};
6672

6773
#endif // CONFIG_ZB_ENABLED

0 commit comments

Comments
 (0)