Skip to content

Commit c6b6023

Browse files
committed
feat(zigbee): Dont force XY mode for state and level change + add helper f
1 parent d9c8245 commit c6b6023

File tree

2 files changed

+59
-30
lines changed

2 files changed

+59
-30
lines changed

libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp

Lines changed: 58 additions & 30 deletions
Original file line numberDiff line numberDiff line change
@@ -130,20 +130,7 @@ void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_me
130130
}
131131

132132
// Validate that the requested color mode is supported by capabilities
133-
bool mode_supported = false;
134-
switch (new_color_mode) {
135-
case ZIGBEE_COLOR_MODE_CURRENT_X_Y:
136-
mode_supported = (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_X_Y) != 0;
137-
break;
138-
case ZIGBEE_COLOR_MODE_HUE_SATURATION:
139-
mode_supported = (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_HUE_SATURATION) != 0;
140-
break;
141-
case ZIGBEE_COLOR_MODE_TEMPERATURE:
142-
mode_supported = (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_COLOR_TEMP) != 0;
143-
break;
144-
}
145-
146-
if (!mode_supported) {
133+
if (!isColorModeSupported(new_color_mode)) {
147134
log_w("Color mode %d not supported by current capabilities: 0x%04x", new_color_mode, _color_capabilities);
148135
return;
149136
}
@@ -362,11 +349,52 @@ bool ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red,
362349
}
363350

364351
bool ZigbeeColorDimmableLight::setLightState(bool state) {
365-
return setLight(state, _current_level, _current_color.r, _current_color.g, _current_color.b);
352+
if (_current_state == state) {
353+
return true; // No change needed
354+
}
355+
356+
_current_state = state;
357+
esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
358+
esp_zb_lock_acquire(portMAX_DELAY);
359+
ret = esp_zb_zcl_set_attribute_val(
360+
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_ON_OFF, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_ON_OFF_ON_OFF_ID, &_current_state, false
361+
);
362+
esp_zb_lock_release();
363+
364+
if (ret == ESP_ZB_ZCL_STATUS_SUCCESS) {
365+
lightChangedByMode(); // Call appropriate callback based on current color mode
366+
} else {
367+
log_e("Failed to set light state: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
368+
}
369+
370+
return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
366371
}
367372

368373
bool ZigbeeColorDimmableLight::setLightLevel(uint8_t level) {
369-
return setLight(_current_state, level, _current_color.r, _current_color.g, _current_color.b);
374+
if (_current_level == level) {
375+
return true; // No change needed
376+
}
377+
378+
_current_level = level;
379+
// Update HSV value if in HSV mode
380+
if (_current_color_mode == ZIGBEE_COLOR_MODE_HUE_SATURATION) {
381+
_current_hsv.v = level;
382+
}
383+
384+
esp_zb_zcl_status_t ret = ESP_ZB_ZCL_STATUS_SUCCESS;
385+
esp_zb_lock_acquire(portMAX_DELAY);
386+
ret = esp_zb_zcl_set_attribute_val(
387+
_endpoint, ESP_ZB_ZCL_CLUSTER_ID_LEVEL_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_LEVEL_CONTROL_CURRENT_LEVEL_ID, &_current_level, false
388+
);
389+
esp_zb_lock_release();
390+
391+
if (ret == ESP_ZB_ZCL_STATUS_SUCCESS) {
392+
lightChangedByMode(); // Call appropriate callback based on current color mode
393+
} else {
394+
log_e("Failed to set light level: 0x%x: %s", ret, esp_zb_zcl_status_to_name(ret));
395+
}
396+
397+
return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
370398
}
371399

372400
bool ZigbeeColorDimmableLight::setLightColor(uint8_t red, uint8_t green, uint8_t blue) {
@@ -461,27 +489,27 @@ bool ZigbeeColorDimmableLight::setLightColorTemperature(uint16_t color_temperatu
461489
return ret == ESP_ZB_ZCL_STATUS_SUCCESS;
462490
}
463491

492+
bool ZigbeeColorDimmableLight::isColorModeSupported(uint8_t color_mode) {
493+
switch (color_mode) {
494+
case ZIGBEE_COLOR_MODE_CURRENT_X_Y:
495+
return (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_X_Y) != 0;
496+
case ZIGBEE_COLOR_MODE_HUE_SATURATION:
497+
return (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_HUE_SATURATION) != 0;
498+
case ZIGBEE_COLOR_MODE_TEMPERATURE:
499+
return (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_COLOR_TEMP) != 0;
500+
default:
501+
return false;
502+
}
503+
}
504+
464505
bool ZigbeeColorDimmableLight::setLightColorMode(uint8_t color_mode) {
465506
if (color_mode > ZIGBEE_COLOR_MODE_TEMPERATURE) {
466507
log_e("Invalid color mode: %d", color_mode);
467508
return false;
468509
}
469510

470511
// Check if the requested color mode is supported by capabilities
471-
bool mode_supported = false;
472-
switch (color_mode) {
473-
case ZIGBEE_COLOR_MODE_CURRENT_X_Y:
474-
mode_supported = (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_X_Y) != 0;
475-
break;
476-
case ZIGBEE_COLOR_MODE_HUE_SATURATION:
477-
mode_supported = (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_HUE_SATURATION) != 0;
478-
break;
479-
case ZIGBEE_COLOR_MODE_TEMPERATURE:
480-
mode_supported = (_color_capabilities & ZIGBEE_COLOR_CAPABILITY_COLOR_TEMP) != 0;
481-
break;
482-
}
483-
484-
if (!mode_supported) {
512+
if (!isColorModeSupported(color_mode)) {
485513
log_e("Color mode %d not supported by current capabilities: 0x%04x", color_mode, _color_capabilities);
486514
return false;
487515
}

libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -157,6 +157,7 @@ class ZigbeeColorDimmableLight : public ZigbeeEP {
157157
private:
158158
void zbAttributeSet(const esp_zb_zcl_set_attr_value_message_t *message) override;
159159
bool setLightColorMode(uint8_t color_mode);
160+
bool isColorModeSupported(uint8_t color_mode);
160161

161162
uint16_t getCurrentColorX();
162163
uint16_t getCurrentColorY();

0 commit comments

Comments
 (0)