Skip to content

Commit 16347a3

Browse files
committed
feat(matter): creates new color light endpoint
1 parent 0bcdd2c commit 16347a3

File tree

13 files changed

+989
-33
lines changed

13 files changed

+989
-33
lines changed

CMakeLists.txt

+3-2
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,7 @@ endif()
2525
set(CORE_SRCS
2626
cores/esp32/base64.cpp
2727
cores/esp32/cbuf.cpp
28+
cores/esp32/ColorFormat.c
2829
cores/esp32/chip-debug-report.cpp
2930
cores/esp32/esp32-hal-adc.c
3031
cores/esp32/esp32-hal-bt.c
@@ -170,7 +171,7 @@ set(ARDUINO_LIBRARY_Matter_SRCS
170171
libraries/Matter/src/MatterEndpoints/MatterOnOffLight.cpp
171172
libraries/Matter/src/MatterEndpoints/MatterDimmableLight.cpp
172173
libraries/Matter/src/MatterEndpoints/MatterColorTemperatureLight.cpp
173-
libraries/Matter/src/MatterUtil/ColorFormat.cpp
174+
libraries/Matter/src/MatterEndpoints/MatterColorLight.cpp
174175
libraries/Matter/src/Matter.cpp)
175176

176177
set(ARDUINO_LIBRARY_PPP_SRCS
@@ -396,4 +397,4 @@ if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_LittleFS
396397
endif()
397398
if(NOT CONFIG_ARDUINO_SELECTIVE_COMPILATION OR CONFIG_ARDUINO_SELECTIVE_WiFiProv)
398399
maybe_add_component(espressif__network_provisioning)
399-
endif()
400+
endif()

cores/esp32/ColorFormat.c

+291
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,291 @@
1+
/*
2+
*
3+
* Copyright (c) 2021 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#include "ColorFormat.h"
20+
21+
#include <math.h>
22+
23+
// define a clamp macro to substitute the std::clamp macro which is available from C++17 onwards
24+
#define clamp(a, min, max) ((a) < (min) ? (min) : ((a) > (max) ? (max) : (a)))
25+
26+
const espHsvColor_t HSV_BLACK = {0, 0, 0};
27+
const espHsvColor_t HSV_WHITE = {0, 0, 254};
28+
const espHsvColor_t HSV_RED = {0, 254, 254};
29+
const espHsvColor_t HSV_YELLOW = {42, 254, 254};
30+
const espHsvColor_t HSV_GREEN = {84, 254, 254};
31+
const espHsvColor_t HSV_CYAN = {127, 254, 254};
32+
const espHsvColor_t HSV_BLUE = {169, 254, 254};
33+
const espHsvColor_t HSV_MAGENTA = {211, 254, 254};
34+
35+
const espRgbColor_t RGB_BLACK = {0, 0, 0};
36+
const espRgbColor_t RGB_WHITE = {255, 255, 255};
37+
const espRgbColor_t RGB_RED = {255, 0, 0};
38+
const espRgbColor_t RGB_YELLOW = {255, 255, 0};
39+
const espRgbColor_t RGB_GREEN = {0, 255, 0};
40+
const espRgbColor_t RGB_CYAN = {0, 255, 255};
41+
const espRgbColor_t RGB_BLUE = {0, 0, 255};
42+
const espRgbColor_t RGB_MAGENTA = {255, 0, 255};
43+
44+
// main color temperature values
45+
const espCtColor_t COOL_WHITE_COLOR_TEMPERATURE = { 142 };
46+
const espCtColor_t DAYLIGHT_WHITE_COLOR_TEMPERATURE = { 181 };
47+
const espCtColor_t WHITE_COLOR_TEMPERATURE = { 250 };
48+
const espCtColor_t SOFT_WHITE_COLOR_TEMPERATURE = { 370 };
49+
const espCtColor_t WARM_WHITE_COLOR_TEMPERATURE = { 454 };
50+
51+
espRgbColor_t espHsvToRgbColor(uint16_t h, uint8_t s, uint8_t v) {
52+
espHsvColor_t hsv = {h, s, v};
53+
return espHsvColorToRgbColor(hsv);
54+
}
55+
56+
espRgbColor_t espHsvColorToRgbColor(espHsvColor_t hsv) {
57+
espRgbColor_t rgb;
58+
59+
uint8_t region, p, q, t;
60+
uint32_t h, s, v, remainder;
61+
62+
if (hsv.s == 0) {
63+
rgb.r = rgb.g = rgb.b = hsv.v;
64+
} else {
65+
h = hsv.h;
66+
s = hsv.s;
67+
v = hsv.v;
68+
69+
region = h / 43;
70+
remainder = (h - (region * 43)) * 6;
71+
p = (v * (255 - s)) >> 8;
72+
q = (v * (255 - ((s * remainder) >> 8))) >> 8;
73+
t = (v * (255 - ((s * (255 - remainder)) >> 8))) >> 8;
74+
switch (region) {
75+
case 0:
76+
rgb.r = v, rgb.g = t, rgb.b = p;
77+
break;
78+
case 1:
79+
rgb.r = q, rgb.g = v, rgb.b = p;
80+
break;
81+
case 2:
82+
rgb.r = p, rgb.g = v, rgb.b = t;
83+
break;
84+
case 3:
85+
rgb.r = p, rgb.g = q, rgb.b = v;
86+
break;
87+
case 4:
88+
rgb.r = t, rgb.g = p, rgb.b = v;
89+
break;
90+
case 5:
91+
default:
92+
rgb.r = v, rgb.g = p, rgb.b = q;
93+
break;
94+
}
95+
}
96+
return rgb;
97+
}
98+
99+
espHsvColor_t espRgbToHsvColor(uint8_t r, uint8_t g, uint8_t b) {
100+
espRgbColor_t rgb = {r, g, b};
101+
return espRgbColorToHsvColor(rgb);
102+
}
103+
104+
espHsvColor_t espRgbColorToHsvColor(espRgbColor_t rgb) {
105+
espHsvColor_t hsv;
106+
uint8_t rgbMin, rgbMax;
107+
108+
rgbMin = rgb.r < rgb.g ? (rgb.r < rgb.b ? rgb.r : rgb.b) : (rgb.g < rgb.b ? rgb.g : rgb.b);
109+
rgbMax = rgb.r > rgb.g ? (rgb.r > rgb.b ? rgb.r : rgb.b) : (rgb.g > rgb.b ? rgb.g : rgb.b);
110+
111+
hsv.v = rgbMax;
112+
if (hsv.v == 0) {
113+
hsv.h = 0;
114+
hsv.s = 0;
115+
return hsv;
116+
}
117+
118+
hsv.s = 255 * (rgbMax - rgbMin) / hsv.v;
119+
if (hsv.s == 0) {
120+
hsv.h = 0;
121+
return hsv;
122+
}
123+
if (rgbMax == rgb.r) {
124+
hsv.h = 0 + 43 * (rgb.g - rgb.b) / (rgbMax - rgbMin);
125+
} else if (rgbMax == rgb.g) {
126+
hsv.h = 85 + 43 * (rgb.b - rgb.r) / (rgbMax - rgbMin);
127+
} else {
128+
hsv.h = 171 + 43 * (rgb.r - rgb.g) / (rgbMax - rgbMin);
129+
}
130+
return hsv;
131+
}
132+
133+
espRgbColor_t espXYColorToRgbColor(uint8_t Level, espXyColor_t xy) {
134+
return espXYToRgbColor(Level, xy.x, xy.y);
135+
}
136+
137+
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y) {
138+
// convert xyY color space to RGB
139+
140+
// https://www.easyrgb.com/en/math.php
141+
// https://en.wikipedia.org/wiki/SRGB
142+
// refer https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space
143+
144+
// The current_X/current_Y attribute contains the current value of the normalized chromaticity value of x/y.
145+
// The value of x/y shall be related to the current_X/current_Y attribute by the relationship
146+
// x = current_X/65536
147+
// y = current_Y/65536
148+
// z = 1-x-y
149+
150+
espRgbColor_t rgb;
151+
152+
float x, y, z;
153+
float X, Y, Z;
154+
float r, g, b;
155+
156+
x = ((float)current_X) / 65535.0f;
157+
y = ((float)current_Y) / 65535.0f;
158+
159+
z = 1.0f - x - y;
160+
161+
// Calculate XYZ values
162+
163+
// Y - given brightness in 0 - 1 range
164+
Y = ((float)Level) / 254.0f;
165+
X = (Y / y) * x;
166+
Z = (Y / y) * z;
167+
168+
// X, Y and Z input refer to a D65/2° standard illuminant.
169+
// sR, sG and sB (standard RGB) output range = 0 ÷ 255
170+
// convert XYZ to RGB - CIE XYZ to sRGB
171+
X = X / 100.0f;
172+
Y = Y / 100.0f;
173+
Z = Z / 100.0f;
174+
175+
r = (X * 3.2406f) - (Y * 1.5372f) - (Z * 0.4986f);
176+
g = -(X * 0.9689f) + (Y * 1.8758f) + (Z * 0.0415f);
177+
b = (X * 0.0557f) - (Y * 0.2040f) + (Z * 1.0570f);
178+
179+
// apply gamma 2.2 correction
180+
r = (r <= 0.0031308f ? 12.92f * r : (1.055f) * pow(r, (1.0f / 2.4f)) - 0.055f);
181+
g = (g <= 0.0031308f ? 12.92f * g : (1.055f) * pow(g, (1.0f / 2.4f)) - 0.055f);
182+
b = (b <= 0.0031308f ? 12.92f * b : (1.055f) * pow(b, (1.0f / 2.4f)) - 0.055f);
183+
184+
// Round off
185+
r = clamp(r, 0, 1);
186+
g = clamp(g, 0, 1);
187+
b = clamp(b, 0, 1);
188+
189+
// these rgb values are in the range of 0 to 1, convert to limit of HW specific LED
190+
rgb.r = (uint8_t)(r * 255);
191+
rgb.g = (uint8_t)(g * 255);
192+
rgb.b = (uint8_t)(b * 255);
193+
194+
return rgb;
195+
}
196+
197+
espXyColor_t espRgbToXYColor(uint8_t r, uint8_t g, uint8_t b){
198+
espRgbColor_t rgb = {r, g, b};
199+
return espRgbColorToXYColor(rgb);
200+
}
201+
202+
espXyColor_t espRgbColorToXYColor(espRgbColor_t rgb) {
203+
// convert RGB to xy color space
204+
205+
// https://www.easyrgb.com/en/math.php
206+
// https://en.wikipedia.org/wiki/SRGB
207+
// refer https://en.wikipedia.org/wiki/CIE_1931_color_space#CIE_xy_chromaticity_diagram_and_the_CIE_xyY_color_space
208+
209+
espXyColor_t xy;
210+
211+
float r, g, b;
212+
float X, Y, Z;
213+
float x, y;
214+
215+
r = ((float)rgb.r) / 255.0f;
216+
g = ((float)rgb.g) / 255.0f;
217+
b = ((float)rgb.b) / 255.0f;
218+
219+
// convert RGB to XYZ - sRGB to CIE XYZ
220+
r = (r <= 0.04045f ? r / 12.92f : pow((r + 0.055f) / 1.055f, 2.4f));
221+
g = (g <= 0.04045f ? g / 12.92f : pow((g + 0.055f) / 1.055f, 2.4f));
222+
b = (b <= 0.04045f ? b / 12.92f : pow((b + 0.055f) / 1.055f, 2.4f));
223+
224+
// https://gist.github.com/popcorn245/30afa0f98eea1c2fd34d
225+
X = r * 0.649926f + g * 0.103455f + b * 0.197109f;
226+
Y = r * 0.234327f + g * 0.743075f + b * 0.022598f;
227+
Z = r * 0.0000000f + g * 0.053077f + b * 1.035763f;
228+
229+
// sR, sG and sB (standard RGB) input range = 0 ÷ 255
230+
// X, Y and Z output refer to a D65/2° standard illuminant.
231+
X = r * 0.4124564f + g * 0.3575761f + b * 0.1804375f;
232+
Y = r * 0.2126729f + g * 0.7151522f + b * 0.0721750f;
233+
Z = r * 0.0193339f + g * 0.1191920f + b * 0.9503041f;
234+
235+
// Calculate xy values
236+
x = X / (X + Y + Z);
237+
y = Y / (X + Y + Z);
238+
239+
// convert to 0-65535 range
240+
xy.x = (uint16_t)(x * 65535);
241+
xy.y = (uint16_t)(y * 65535);
242+
return xy;
243+
}
244+
245+
espRgbColor_t espCTToRgbColor(uint16_t ct){
246+
espCtColor_t ctColor = {ct};
247+
return espCTColorToRgbColor(ctColor);
248+
}
249+
250+
espRgbColor_t espCTColorToRgbColor(espCtColor_t ct) {
251+
espRgbColor_t rgb = {0, 0, 0};
252+
float r, g, b;
253+
254+
if (ct.ctMireds == 0) {
255+
return rgb;
256+
}
257+
// Algorithm credits to Tanner Helland: https://tannerhelland.com/2012/09/18/convert-temperature-rgb-algorithm-code.html
258+
259+
// Convert Mireds to centiKelvins. k = 1,000,000/mired
260+
float ctCentiKelvin = 10000 / ct.ctMireds;
261+
262+
// Red
263+
if (ctCentiKelvin <= 66) {
264+
r = 255;
265+
} else {
266+
r = 329.698727446f * pow(ctCentiKelvin - 60, -0.1332047592f);
267+
}
268+
269+
// Green
270+
if (ctCentiKelvin <= 66) {
271+
g = 99.4708025861f * log(ctCentiKelvin) - 161.1195681661f;
272+
} else {
273+
g = 288.1221695283f * pow(ctCentiKelvin - 60, -0.0755148492f);
274+
}
275+
276+
// Blue
277+
if (ctCentiKelvin >= 66) {
278+
b = 255;
279+
} else {
280+
if (ctCentiKelvin <= 19) {
281+
b = 0;
282+
} else {
283+
b = 138.5177312231 * log(ctCentiKelvin - 10) - 305.0447927307;
284+
}
285+
}
286+
rgb.r = (uint8_t)clamp(r, 0, 255);
287+
rgb.g = (uint8_t)clamp(g, 0, 255);
288+
rgb.b = (uint8_t)clamp(b, 0, 255);
289+
290+
return rgb;
291+
}

cores/esp32/ColorFormat.h

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
/*
2+
*
3+
* Copyright (c) 2021 Project CHIP Authors
4+
* All rights reserved.
5+
*
6+
* Licensed under the Apache License, Version 2.0 (the "License");
7+
* you may not use this file except in compliance with the License.
8+
* You may obtain a copy of the License at
9+
*
10+
* http://www.apache.org/licenses/LICENSE-2.0
11+
*
12+
* Unless required by applicable law or agreed to in writing, software
13+
* distributed under the License is distributed on an "AS IS" BASIS,
14+
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15+
* See the License for the specific language governing permissions and
16+
* limitations under the License.
17+
*/
18+
19+
#pragma once
20+
21+
#include <stdint.h>
22+
#ifdef __cplusplus
23+
extern "C" {
24+
#endif
25+
26+
struct RgbColor_t {
27+
uint8_t r;
28+
uint8_t g;
29+
uint8_t b;
30+
};
31+
32+
struct HsvColor_t {
33+
uint16_t h;
34+
uint8_t s;
35+
uint8_t v;
36+
};
37+
38+
struct XyColor_t {
39+
uint16_t x;
40+
uint16_t y;
41+
};
42+
43+
struct CtColor_t {
44+
uint16_t ctMireds;
45+
};
46+
47+
typedef struct RgbColor_t espRgbColor_t;
48+
typedef struct HsvColor_t espHsvColor_t;
49+
typedef struct XyColor_t espXyColor_t;
50+
typedef struct CtColor_t espCtColor_t;
51+
52+
espRgbColor_t espXYToRgbColor(uint8_t Level, uint16_t current_X, uint16_t current_Y);
53+
espRgbColor_t espXYColorToRgb(uint8_t Level, espXyColor_t xy);
54+
espXyColor_t espRgbColorToXYColor(espRgbColor_t rgb);
55+
espXyColor_t espRgbToXYColor(uint8_t r, uint8_t g, uint8_t b);
56+
espRgbColor_t espHsvColorToRgbColor(espHsvColor_t hsv);
57+
espRgbColor_t espHsvToRgbColor(uint16_t h, uint8_t s, uint8_t v);
58+
espRgbColor_t espCTColorToRgbColor(espCtColor_t ct);
59+
espRgbColor_t espCTToRgbColor(uint16_t ct);
60+
espHsvColor_t espRgbColorToHsvColor(espRgbColor_t rgb);
61+
espHsvColor_t espRgbToHsvColor(uint8_t r, uint8_t g, uint8_t b);
62+
63+
extern const espHsvColor_t HSV_BLACK, HSV_WHITE, HSV_RED, HSV_YELLOW, HSV_GREEN, HSV_CYAN, HSV_BLUE, HSV_MAGENTA;
64+
extern const espCtColor_t COOL_WHITE_COLOR_TEMPERATURE, DAYLIGHT_WHITE_COLOR_TEMPERATURE, WHITE_COLOR_TEMPERATURE, SOFT_WHITE_COLOR_TEMPERATURE, WARM_WHITE_COLOR_TEMPERATURE;
65+
extern const espRgbColor_t RGB_BLACK, RGB_WHITE, RGB_RED, RGB_YELLOW, RGB_GREEN, RGB_CYAN, RGB_BLUE, RGB_MAGENTA;
66+
67+
#ifdef __cplusplus
68+
}
69+
#endif

0 commit comments

Comments
 (0)