44ZigbeeColorDimmableLight::ZigbeeColorDimmableLight (uint8_t endpoint) : ZigbeeEP(endpoint) {
55 _device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID;
66
7- esp_zb_color_dimmable_light_cfg_t light_cfg = ESP_ZB_DEFAULT_COLOR_DIMMABLE_LIGHT_CONFIG ();
7+ esp_zb_color_dimmable_light_cfg_t light_cfg = ZIGBEE_DEFAULT_COLOR_DIMMABLE_LIGHT_CONFIG ();
88 _cluster_list = esp_zb_color_dimmable_light_clusters_create (&light_cfg);
9+
10+ // Add support for hue and saturation
11+ uint8_t hue = 0 ;
12+ uint8_t saturation = 0 ;
13+
14+ esp_zb_attribute_list_t *color_cluster = esp_zb_cluster_list_get_cluster (_cluster_list, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE);
15+ esp_zb_color_control_cluster_add_attr (color_cluster, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, &hue);
16+ esp_zb_color_control_cluster_add_attr (color_cluster, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &saturation);
17+
918 _ep_config = {
1019 .endpoint = _endpoint, .app_profile_id = ESP_ZB_AF_HA_PROFILE_ID, .app_device_id = ESP_ZB_HA_COLOR_DIMMABLE_LIGHT_DEVICE_ID, .app_device_version = 0
1120 };
1221
1322 // set default values
1423 _current_state = false ;
1524 _current_level = 255 ;
16- _current_red = 255 ;
17- _current_green = 255 ;
18- _current_blue = 255 ;
25+ _current_color = {255 , 255 , 255 };
1926}
2027
2128uint16_t ZigbeeColorDimmableLight::getCurrentColorX () {
@@ -32,37 +39,18 @@ uint16_t ZigbeeColorDimmableLight::getCurrentColorY() {
3239 ->data_p );
3340}
3441
35- void ZigbeeColorDimmableLight::calculateRGB (uint16_t x, uint16_t y, uint8_t &red, uint8_t &green, uint8_t &blue) {
36- float r, g, b, color_x, color_y;
37- color_x = (float )x / 65535 ;
38- color_y = (float )y / 65535 ;
39-
40- float color_X = color_x / color_y;
41- float color_Z = (1 - color_x - color_y) / color_y;
42-
43- XYZ_TO_RGB (color_X, 1 , color_Z, r, g, b);
44-
45- red = (uint8_t )(r * (float )255 );
46- green = (uint8_t )(g * (float )255 );
47- blue = (uint8_t )(b * (float )255 );
42+ uint8_t ZigbeeColorDimmableLight::getCurrentColorHue () {
43+ return (*(uint8_t *)esp_zb_zcl_get_attribute (
44+ _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID
45+ )
46+ ->data_p );
4847}
4948
50- void ZigbeeColorDimmableLight::calculateXY (uint8_t red, uint8_t green, uint8_t blue, uint16_t &x, uint16_t &y) {
51- // Convert RGB to XYZ
52- float r = (float )red / 255 .0f ;
53- float g = (float )green / 255 .0f ;
54- float b = (float )blue / 255 .0f ;
55-
56- float X, Y, Z;
57- RGB_TO_XYZ (r, g, b, X, Y, Z);
58-
59- // Convert XYZ to xy chromaticity coordinates
60- float color_x = X / (X + Y + Z);
61- float color_y = Y / (X + Y + Z);
62-
63- // Convert normalized xy to 16-bit values
64- x = (uint16_t )(color_x * 65535 .0f );
65- y = (uint16_t )(color_y * 65535 .0f );
49+ uint8_t ZigbeeColorDimmableLight::getCurrentColorSaturation () {
50+ return (*(uint16_t *)esp_zb_zcl_get_attribute (
51+ _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID
52+ )
53+ ->data_p );
6654}
6755
6856// set attribute method -> method overridden in child class
@@ -94,23 +82,25 @@ void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_me
9482 uint16_t light_color_x = (*(uint16_t *)message->attribute .data .value );
9583 uint16_t light_color_y = getCurrentColorY ();
9684 // calculate RGB from XY and call setColor()
97- uint8_t red, green, blue;
98- calculateRGB (light_color_x, light_color_y, red, green, blue);
99- _current_blue = blue;
100- _current_green = green;
101- _current_red = red;
85+ _current_color = espXYToRgbColor (255 , light_color_x, light_color_y); // TODO: Check if level is correct
10286 lightChanged ();
10387 return ;
10488
10589 } else if (message->attribute .id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID && message->attribute .data .type == ESP_ZB_ZCL_ATTR_TYPE_U16) {
10690 uint16_t light_color_x = getCurrentColorX ();
10791 uint16_t light_color_y = (*(uint16_t *)message->attribute .data .value );
10892 // calculate RGB from XY and call setColor()
109- uint8_t red, green, blue;
110- calculateRGB (light_color_x, light_color_y, red, green, blue);
111- _current_blue = blue;
112- _current_green = green;
113- _current_red = red;
93+ _current_color = espXYToRgbColor (255 , light_color_x, light_color_y); // TODO: Check if level is correct
94+ lightChanged ();
95+ return ;
96+ } else if (message->attribute .id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID && message->attribute .data .type == ESP_ZB_ZCL_ATTR_TYPE_U8) {
97+ uint8_t light_color_hue = (*(uint8_t *)message->attribute .data .value );
98+ _current_color = espHsvToRgbColor (light_color_hue, getCurrentColorSaturation (), 255 );
99+ lightChanged ();
100+ return ;
101+ } else if (message->attribute .id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID && message->attribute .data .type == ESP_ZB_ZCL_ATTR_TYPE_U8) {
102+ uint8_t light_color_saturation = (*(uint8_t *)message->attribute .data .value );
103+ _current_color = espHsvToRgbColor (getCurrentColorHue (), light_color_saturation, 255 );
114104 lightChanged ();
115105 return ;
116106 } else {
@@ -123,20 +113,21 @@ void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_me
123113
124114void ZigbeeColorDimmableLight::lightChanged () {
125115 if (_on_light_change) {
126- _on_light_change (_current_state, _current_red, _current_green, _current_blue , _current_level);
116+ _on_light_change (_current_state, _current_color. r , _current_color. g , _current_color. b , _current_level);
127117 }
128118}
129119
130120void ZigbeeColorDimmableLight::setLight (bool state, uint8_t level, uint8_t red, uint8_t green, uint8_t blue) {
131121 // Update all attributes
132122 _current_state = state;
133123 _current_level = level;
134- _current_red = red;
135- _current_green = green;
136- _current_blue = blue;
124+ _current_color = {red, green, blue};
137125 lightChanged ();
138126
139- log_v (" Updating on/off light state to %d" , state);
127+ espXyColor_t xy_color = espRgbColorToXYColor (_current_color);
128+ espHsvColor_t hsv_color = espRgbColorToHsvColor (_current_color);
129+
130+ log_v (" Updating light state: %d, level: %d, color: %d, %d, %d" , state, level, red, green, blue);
140131 /* Update light clusters */
141132 esp_zb_lock_acquire (portMAX_DELAY);
142133 // set on/off state
@@ -147,28 +138,43 @@ void ZigbeeColorDimmableLight::setLight(bool state, uint8_t level, uint8_t red,
147138 esp_zb_zcl_set_attribute_val (
148139 _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
149140 );
150- // set color
151- uint16_t color_x, color_y;
152- calculateXY (red, green, blue, color_x, color_y);
141+ // set xy color
142+ esp_zb_zcl_set_attribute_val (
143+ _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID, &xy_color.x , false
144+ );
153145 esp_zb_zcl_set_attribute_val (
154- _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID , &color_x , false
146+ _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID , &xy_color. y , false
155147 );
148+ // set hsv color
149+ uint8_t hue = (uint8_t )hsv_color.h ;
156150 esp_zb_zcl_set_attribute_val (
157- _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID, &color_y, false
151+ _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID, &hue, false
152+ );
153+ esp_zb_zcl_set_attribute_val (
154+ _endpoint, ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL, ESP_ZB_ZCL_CLUSTER_SERVER_ROLE, ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_SATURATION_ID, &hsv_color.s , false
158155 );
159156 esp_zb_lock_release ();
160157}
161158
162159void ZigbeeColorDimmableLight::setLightState (bool state) {
163- setLight (state, _current_level, _current_red, _current_green, _current_blue );
160+ setLight (state, _current_level, _current_color. r , _current_color. g , _current_color. b );
164161}
165162
166163void ZigbeeColorDimmableLight::setLightLevel (uint8_t level) {
167- setLight (_current_state, level, _current_red, _current_green, _current_blue );
164+ setLight (_current_state, level, _current_color. r , _current_color. g , _current_color. b );
168165}
169166
170167void ZigbeeColorDimmableLight::setLightColor (uint8_t red, uint8_t green, uint8_t blue) {
171168 setLight (_current_state, _current_level, red, green, blue);
172169}
173170
171+ void ZigbeeColorDimmableLight::setLightColor (espRgbColor_t rgb_color) {
172+ setLight (_current_state, _current_level, rgb_color.r , rgb_color.g , rgb_color.b );
173+ }
174+
175+ void ZigbeeColorDimmableLight::setLightColor (espHsvColor_t hsv_color) {
176+ espRgbColor_t rgb_color = espHsvColorToRgbColor (hsv_color);
177+ setLight (_current_state, _current_level, rgb_color.r , rgb_color.g , rgb_color.b );
178+ }
179+
174180#endif // SOC_IEEE802154_SUPPORTED && CONFIG_ZB_ENABLED
0 commit comments