@@ -36,7 +36,7 @@ void RGBLEDWidget::SetColor(uint8_t red, uint8_t green, uint8_t blue)
3636{
3737 if (GetPlatform ().GetRGBLedState (GetLED ()))
3838 {
39- ChipLogProgress (Zcl, " SetColor : %u|%u|%u" , red, green, blue);
39+ ChipLogProgress (Zcl, " SetColor : R: %u|G: %u|B: %u" , red, green, blue);
4040 GetPlatform ().SetLedColor (GetLED (), red, green, blue);
4141 }
4242}
@@ -54,16 +54,77 @@ void RGBLEDWidget::GetColor(uint16_t & r, uint16_t & g, uint16_t & b)
5454
5555 ChipLogProgress (Zcl, " RGB Values: R=%u G=%u B=%u" , r, g, b);
5656}
57-
57+ /* *
58+ * @brief Convert Data model hue and saturation to RGB and set the color
59+ * As per spec, hue range from 0 to 254 and saturation from 0 to 254
60+ * Since the equation expects hue in 0-360 and saturation in percentage, we scale them accordingly
61+ *
62+ * @param hue
63+ * @param saturation
64+ */
5865void RGBLEDWidget::SetColorFromHSV (uint8_t hue, uint8_t saturation)
5966{
60- RGBLEDWidget::HsvColor_t hsv;
61- hsv.h = hue;
62- hsv.s = saturation;
63- hsv.v = GetLevel ();
64- ChipLogProgress (Zcl, " SetColorFromHSV : %u|%u" , hsv.h , hsv.s );
65- RGBLEDWidget::RgbColor_t rgb = RGBLEDWidget::HsvToRgb (hsv);
66- SetColor (rgb.r , rgb.g , rgb.b );
67+ ChipLogDetail (Zcl, " SetColorFromHSV : H:%u|S:%u|V:%u" , hue, saturation, GetLevel ());
68+ // Per spec max value for each attribute is 254
69+ float h = (hue * 360 .0f ) / 254 .0f , s = (saturation / 254 .0f ), v = (GetLevel () / 254 .0f );
70+ float hh, p, q, t, ff, r, g, b;
71+ long i;
72+
73+ ChipLogDetail (Zcl, " HUE Values: H=%u S=%u V=%u" , static_cast <uint8_t >(h), static_cast <uint8_t >(s * 100.0 ),
74+ static_cast <uint8_t >(v * 100.0 ));
75+
76+ if (s <= 0.0 )
77+ { // Achromatic (grey)
78+ SetColor (static_cast <uint8_t >(v * 255 ), static_cast <uint8_t >(v * 255 ), static_cast <uint8_t >(v * 255 ));
79+ return ;
80+ }
81+
82+ hh = h;
83+ if (hh >= 360.0 )
84+ hh = 0.0 ;
85+ hh /= 60.0 ;
86+ i = (long ) hh;
87+ ff = hh - i;
88+ p = v * (1.0 - s);
89+ q = v * (1.0 - (s * ff));
90+ t = v * (1.0 - (s * (1.0 - ff)));
91+
92+ switch (i)
93+ {
94+ case 0 :
95+ r = v;
96+ g = t;
97+ b = p;
98+ break ;
99+ case 1 :
100+ r = q;
101+ g = v;
102+ b = p;
103+ break ;
104+ case 2 :
105+ r = p;
106+ g = v;
107+ b = t;
108+ break ;
109+ case 3 :
110+ r = p;
111+ g = q;
112+ b = v;
113+ break ;
114+ case 4 :
115+ r = t;
116+ g = p;
117+ b = v;
118+ break ;
119+ case 5 :
120+ default :
121+ r = v;
122+ g = p;
123+ b = q;
124+ break ;
125+ }
126+
127+ SetColor (static_cast <uint8_t >(r * 255 ), static_cast <uint8_t >(g * 255 ), static_cast <uint8_t >(b * 255 ));
67128}
68129
69130void RGBLEDWidget::SetColorFromXY (uint16_t currentX, uint16_t currentY)
@@ -214,55 +275,6 @@ RgbColor_t RGBLEDWidget::ConvertXYZToRGB(float X, float Y, float Z)
214275 return rgb;
215276}
216277
217- // Calculate the P value for HSV to RGB conversion
218- uint8_t RGBLEDWidget::CalculateP (uint8_t v, uint8_t s)
219- {
220- // RGB value when the hue is at its minimum for the current region.
221- return (v * (kMaxColorValue - s)) >> 8 ;
222- }
223-
224- // Calculate the Q value for HSV to RGB conversion
225- uint8_t RGBLEDWidget::CalculateQ (uint8_t v, uint8_t s, uint32_t remainder)
226- {
227- // RGB value when the hue is transitioning from one primary color to another within the current region.
228- return (v * (kMaxColorValue - ((s * remainder) >> 8 ))) >> 8 ;
229- }
230-
231- // Calculate the T value for HSV to RGB conversion
232- uint8_t RGBLEDWidget::CalculateT (uint8_t v, uint8_t s, uint32_t remainder)
233- {
234- // RGB value when the hue is transitioning from one primary color to another within the current region, but in the opposite
235- // direction of q.
236-
237- return (v * (kMaxColorValue - ((s * (kMaxColorValue - remainder)) >> 8 ))) >> 8 ;
238- }
239-
240- // Set RGB values based on the region for HSV to RGB conversion
241- void RGBLEDWidget::SetRgbByRegion (uint8_t region, uint8_t v, uint8_t p, uint8_t q, uint8_t t, RgbColor_t & rgb)
242- {
243- switch (region)
244- {
245- case 0 :
246- rgb.r = v, rgb.g = t, rgb.b = p;
247- break ;
248- case 1 :
249- rgb.r = q, rgb.g = v, rgb.b = p;
250- break ;
251- case 2 :
252- rgb.r = p, rgb.g = v, rgb.b = t;
253- break ;
254- case 3 :
255- rgb.r = p, rgb.g = q, rgb.b = v;
256- break ;
257- case 4 :
258- rgb.r = t, rgb.g = p, rgb.b = v;
259- break ;
260- default :
261- rgb.r = v, rgb.g = p, rgb.b = q;
262- break ;
263- }
264- }
265-
266278// Convert color temperature to RGB color space
267279RgbColor_t RGBLEDWidget::CTToRgb (uint16_t ctMireds)
268280{
@@ -278,39 +290,6 @@ RgbColor_t RGBLEDWidget::CTToRgb(uint16_t ctMireds)
278290 return rgb;
279291}
280292
281- // Convert HSV color space to RGB color space
282- RgbColor_t RGBLEDWidget::HsvToRgb (HsvColor_t hsv)
283- {
284- RgbColor_t rgb;
285-
286- uint8_t region, p, q, t;
287- uint32_t remainder;
288-
289- if (hsv.s == 0 )
290- {
291- rgb.r = rgb.g = rgb.b = hsv.v ;
292- }
293- else
294- {
295- // region variable is calculated by dividing the hue value by 43 (since the hue value ranges from 0 to 255, and there
296- // are 6 regions, each region spans approximately 43 units)
297- region = hsv.h / kHueRegionDivider ;
298-
299- // Calculates the position of h within the current region.Multiplying by 6 scales this position to a range of 0 to 255,
300- // which is used to calculate intermediate RGB values.
301- remainder = (hsv.h - (region * kHueRegionDivider )) * 6 ;
302-
303- // p,q and t intermediate values used to calculate the final RGB values
304- p = CalculateP (hsv.v , hsv.s );
305- q = CalculateQ (hsv.v , hsv.s , remainder);
306- t = CalculateT (hsv.v , hsv.s , remainder);
307-
308- SetRgbByRegion (region, hsv.v , p, q, t, rgb);
309- }
310-
311- return rgb;
312- }
313-
314293// Convert XY color space to RGB color space
315294RgbColor_t RGBLEDWidget::XYToRgb (uint8_t Level, uint16_t currentX, uint16_t currentY)
316295{
0 commit comments