Skip to content

fix(zigbee): Fix RGB color calculation #11624

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 22, 2025
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 7 additions & 5 deletions cores/esp32/ColorFormat.c
Original file line number Diff line number Diff line change
Expand Up @@ -119,10 +119,10 @@ espHsvColor_t espRgbColorToHsvColor(espRgbColor_t rgb) {
}

espRgbColor_t espXYColorToRgbColor(uint8_t Level, espXyColor_t xy) {
return espXYToRgbColor(Level, xy.x, xy.y);
return espXYToRgbColor(Level, xy.x, xy.y, true);
}

espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y) {
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y, bool addXYZScaling) {
// convert xyY color space to RGB

// https://www.easyrgb.com/en/math.php
Expand Down Expand Up @@ -156,9 +156,11 @@ espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t curren
// X, Y and Z input refer to a D65/2° standard illuminant.
// sR, sG and sB (standard RGB) output range = 0 ÷ 255
// convert XYZ to RGB - CIE XYZ to sRGB
X = X / 100.0f;
Y = Y / 100.0f;
Z = Z / 100.0f;
if (addXYZScaling) {
X = X / 100.0f;
Y = Y / 100.0f;
Z = Z / 100.0f;
}

r = (X * 3.2406f) - (Y * 1.5372f) - (Z * 0.4986f);
g = -(X * 0.9689f) + (Y * 1.8758f) + (Z * 0.0415f);
Expand Down
3 changes: 2 additions & 1 deletion cores/esp32/ColorFormat.h
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
#pragma once

#include <stdint.h>
#include <stdbool.h>
#ifdef __cplusplus
extern "C" {
#endif
Expand Down Expand Up @@ -49,7 +50,7 @@ typedef struct HsvColor_t espHsvColor_t;
typedef struct XyColor_t espXyColor_t;
typedef struct CtColor_t espCtColor_t;

espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y);
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y, bool addXYZScaling);
espRgbColor_t espXYColorToRgb(uint8_t Level, espXyColor_t xy);
espXyColor_t espRgbColorToXYColor(espRgbColor_t rgb);
espXyColor_t espRgbToXYColor(uint8_t r, uint8_t g, uint8_t b);
Expand Down
5 changes: 2 additions & 3 deletions libraries/Zigbee/src/ep/ZigbeeColorDimmableLight.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,22 +76,21 @@ void ZigbeeColorDimmableLight::zbAttributeSet(const esp_zb_zcl_set_attr_value_me
return;
} else {
log_w("Received message ignored. Attribute ID: %d not supported for Level Control", message->attribute.id);
//TODO: implement more attributes -> includes/zcl/esp_zigbee_zcl_level.h
}
} else if (message->info.cluster == ESP_ZB_ZCL_CLUSTER_ID_COLOR_CONTROL) {
if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_X_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) {
uint16_t light_color_x = (*(uint16_t *)message->attribute.data.value);
uint16_t light_color_y = getCurrentColorY();
//calculate RGB from XY and call setColor()
_current_color = espXYToRgbColor(255, light_color_x, light_color_y); //TODO: Check if level is correct
_current_color = espXYToRgbColor(255, light_color_x, light_color_y, false);
lightChanged();
return;

} else if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_Y_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U16) {
uint16_t light_color_x = getCurrentColorX();
uint16_t light_color_y = (*(uint16_t *)message->attribute.data.value);
//calculate RGB from XY and call setColor()
_current_color = espXYToRgbColor(255, light_color_x, light_color_y); //TODO: Check if level is correct
_current_color = espXYToRgbColor(255, light_color_x, light_color_y, false);
lightChanged();
return;
} else if (message->attribute.id == ESP_ZB_ZCL_ATTR_COLOR_CONTROL_CURRENT_HUE_ID && message->attribute.data.type == ESP_ZB_ZCL_ATTR_TYPE_U8) {
Expand Down
Loading