ESPHome 2025.6.0
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Modules Pages
light_color_values.h
Go to the documentation of this file.
1#pragma once
2
4#include "color_mode.h"
5#include <cmath>
6
7namespace esphome {
8namespace light {
9
10inline static uint8_t to_uint8_scale(float x) { return static_cast<uint8_t>(roundf(x * 255.0f)); }
11
46 public:
50 state_(0.0f),
51 brightness_(1.0f),
53 red_(1.0f),
54 green_(1.0f),
55 blue_(1.0f),
56 white_(1.0f),
58 cold_white_{1.0f},
59 warm_white_{1.0f} {}
60
61 LightColorValues(ColorMode color_mode, float state, float brightness, float color_brightness, float red, float green,
62 float blue, float white, float color_temperature, float cold_white, float warm_white) {
63 this->set_color_mode(color_mode);
64 this->set_state(state);
65 this->set_brightness(brightness);
66 this->set_color_brightness(color_brightness);
67 this->set_red(red);
68 this->set_green(green);
69 this->set_blue(blue);
70 this->set_white(white);
71 this->set_color_temperature(color_temperature);
72 this->set_cold_white(cold_white);
73 this->set_warm_white(warm_white);
74 }
75
86 static LightColorValues lerp(const LightColorValues &start, const LightColorValues &end, float completion) {
88 v.set_color_mode(end.color_mode_);
89 v.set_state(esphome::lerp(completion, start.get_state(), end.get_state()));
90 v.set_brightness(esphome::lerp(completion, start.get_brightness(), end.get_brightness()));
91 v.set_color_brightness(esphome::lerp(completion, start.get_color_brightness(), end.get_color_brightness()));
92 v.set_red(esphome::lerp(completion, start.get_red(), end.get_red()));
93 v.set_green(esphome::lerp(completion, start.get_green(), end.get_green()));
94 v.set_blue(esphome::lerp(completion, start.get_blue(), end.get_blue()));
95 v.set_white(esphome::lerp(completion, start.get_white(), end.get_white()));
96 v.set_color_temperature(esphome::lerp(completion, start.get_color_temperature(), end.get_color_temperature()));
97 v.set_cold_white(esphome::lerp(completion, start.get_cold_white(), end.get_cold_white()));
98 v.set_warm_white(esphome::lerp(completion, start.get_warm_white(), end.get_warm_white()));
99 return v;
100 }
101
112 if (this->color_mode_ & ColorCapability::RGB) {
113 float max_value = fmaxf(this->get_red(), fmaxf(this->get_green(), this->get_blue()));
114 if (max_value == 0.0f) {
115 this->set_red(1.0f);
116 this->set_green(1.0f);
117 this->set_blue(1.0f);
118 } else {
119 this->set_red(this->get_red() / max_value);
120 this->set_green(this->get_green() / max_value);
121 this->set_blue(this->get_blue() / max_value);
122 }
123 }
124 }
125
126 // Note that method signature of as_* methods is kept as-is for compatibility reasons, so not all parameters
127 // are always used or necessary. Methods will be deprecated later.
128
130 void as_binary(bool *binary) const { *binary = this->state_ == 1.0f; }
131
133 void as_brightness(float *brightness, float gamma = 0) const {
134 *brightness = gamma_correct(this->state_ * this->brightness_, gamma);
135 }
136
138 void as_rgb(float *red, float *green, float *blue, float gamma = 0, bool color_interlock = false) const {
139 if (this->color_mode_ & ColorCapability::RGB) {
140 float brightness = this->state_ * this->brightness_ * this->color_brightness_;
141 *red = gamma_correct(brightness * this->red_, gamma);
142 *green = gamma_correct(brightness * this->green_, gamma);
143 *blue = gamma_correct(brightness * this->blue_, gamma);
144 } else {
145 *red = *green = *blue = 0;
146 }
147 }
148
150 void as_rgbw(float *red, float *green, float *blue, float *white, float gamma = 0,
151 bool color_interlock = false) const {
152 this->as_rgb(red, green, blue, gamma);
154 *white = gamma_correct(this->state_ * this->brightness_ * this->white_, gamma);
155 } else {
156 *white = 0;
157 }
158 }
159
161 void as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white, float gamma = 0,
162 bool constant_brightness = false) const {
163 this->as_rgb(red, green, blue, gamma);
164 this->as_cwww(cold_white, warm_white, gamma, constant_brightness);
165 }
166
168 void as_rgbct(float color_temperature_cw, float color_temperature_ww, float *red, float *green, float *blue,
169 float *color_temperature, float *white_brightness, float gamma = 0) const {
170 this->as_rgb(red, green, blue, gamma);
171 this->as_ct(color_temperature_cw, color_temperature_ww, color_temperature, white_brightness, gamma);
172 }
173
175 void as_cwww(float *cold_white, float *warm_white, float gamma = 0, bool constant_brightness = false) const {
177 const float cw_level = gamma_correct(this->cold_white_, gamma);
178 const float ww_level = gamma_correct(this->warm_white_, gamma);
179 const float white_level = gamma_correct(this->state_ * this->brightness_, gamma);
180 if (!constant_brightness) {
181 *cold_white = white_level * cw_level;
182 *warm_white = white_level * ww_level;
183 } else {
184 // Just multiplying by cw_level / (cw_level + ww_level) would divide out the brightness information from the
185 // cold_white and warm_white settings (i.e. cw=0.8, ww=0.4 would be identical to cw=0.4, ww=0.2), which breaks
186 // transitions. Use the highest value as the brightness for the white channels (the alternative, using cw+ww/2,
187 // reduces to cw/2 and ww/2, which would still limit brightness to 100% of a single channel, but isn't very
188 // useful in all other aspects -- that behaviour can also be achieved by limiting the output power).
189 const float sum = cw_level > 0 || ww_level > 0 ? cw_level + ww_level : 1; // Don't divide by zero.
190 *cold_white = white_level * std::max(cw_level, ww_level) * cw_level / sum;
191 *warm_white = white_level * std::max(cw_level, ww_level) * ww_level / sum;
192 }
193 } else {
194 *cold_white = *warm_white = 0;
195 }
196 }
197
199 void as_ct(float color_temperature_cw, float color_temperature_ww, float *color_temperature, float *white_brightness,
200 float gamma = 0) const {
201 const float white_level = this->color_mode_ & ColorCapability::RGB ? this->white_ : 1;
203 *color_temperature =
204 (this->color_temperature_ - color_temperature_cw) / (color_temperature_ww - color_temperature_cw);
205 *white_brightness = gamma_correct(this->state_ * this->brightness_ * white_level, gamma);
206 } else { // Probably won't get here but put this here anyway.
207 *white_brightness = 0;
208 }
209 }
210
212 bool operator==(const LightColorValues &rhs) const {
213 return color_mode_ == rhs.color_mode_ && state_ == rhs.state_ && brightness_ == rhs.brightness_ &&
214 color_brightness_ == rhs.color_brightness_ && red_ == rhs.red_ && green_ == rhs.green_ &&
215 blue_ == rhs.blue_ && white_ == rhs.white_ && color_temperature_ == rhs.color_temperature_ &&
217 }
218 bool operator!=(const LightColorValues &rhs) const { return !(rhs == *this); }
219
221 ColorMode get_color_mode() const { return this->color_mode_; }
223 void set_color_mode(ColorMode color_mode) { this->color_mode_ = color_mode; }
224
226 float get_state() const { return this->state_; }
228 bool is_on() const { return this->get_state() != 0.0f; }
230 void set_state(float state) { this->state_ = clamp(state, 0.0f, 1.0f); }
232 void set_state(bool state) { this->state_ = state ? 1.0f : 0.0f; }
233
235 float get_brightness() const { return this->brightness_; }
237 void set_brightness(float brightness) { this->brightness_ = clamp(brightness, 0.0f, 1.0f); }
238
240 float get_color_brightness() const { return this->color_brightness_; }
242 void set_color_brightness(float brightness) { this->color_brightness_ = clamp(brightness, 0.0f, 1.0f); }
243
245 float get_red() const { return this->red_; }
247 void set_red(float red) { this->red_ = clamp(red, 0.0f, 1.0f); }
248
250 float get_green() const { return this->green_; }
252 void set_green(float green) { this->green_ = clamp(green, 0.0f, 1.0f); }
253
255 float get_blue() const { return this->blue_; }
257 void set_blue(float blue) { this->blue_ = clamp(blue, 0.0f, 1.0f); }
258
260 float get_white() const { return white_; }
262 void set_white(float white) { this->white_ = clamp(white, 0.0f, 1.0f); }
263
265 float get_color_temperature() const { return this->color_temperature_; }
267 void set_color_temperature(float color_temperature) { this->color_temperature_ = color_temperature; }
268
271 if (this->color_temperature_ <= 0) {
272 return this->color_temperature_;
273 }
274 return 1000000.0 / this->color_temperature_;
275 }
277 void set_color_temperature_kelvin(float color_temperature) {
278 if (color_temperature <= 0) {
279 return;
280 }
281 this->color_temperature_ = 1000000.0 / color_temperature;
282 }
283
285 float get_cold_white() const { return this->cold_white_; }
287 void set_cold_white(float cold_white) { this->cold_white_ = clamp(cold_white, 0.0f, 1.0f); }
288
290 float get_warm_white() const { return this->warm_white_; }
292 void set_warm_white(float warm_white) { this->warm_white_ = clamp(warm_white, 0.0f, 1.0f); }
293
294 protected:
296 float state_;
299 float red_;
300 float green_;
301 float blue_;
302 float white_;
306};
307
308} // namespace light
309} // namespace esphome
This class represents the color state for a light object.
float get_state() const
Get the state of these light color values. In range from 0.0 (off) to 1.0 (on)
void set_color_mode(ColorMode color_mode)
Set the color mode of these light color values.
float get_brightness() const
Get the brightness property of these light color values. In range 0.0 to 1.0.
void as_ct(float color_temperature_cw, float color_temperature_ww, float *color_temperature, float *white_brightness, float gamma=0) const
Convert these light color values to a CT+BR representation with the given parameters.
float get_blue() const
Get the blue property of these light color values. In range 0.0 to 1.0.
float get_white() const
Get the white property of these light color values. In range 0.0 to 1.0.
float state_
ON / OFF, float for transition.
float get_color_temperature() const
Get the color temperature property of these light color values in mired.
void as_rgb(float *red, float *green, float *blue, float gamma=0, bool color_interlock=false) const
Convert these light color values to an RGB representation and write them to red, green,...
bool operator!=(const LightColorValues &rhs) const
void set_state(bool state)
Set the state of these light color values as a binary true/false.
static LightColorValues lerp(const LightColorValues &start, const LightColorValues &end, float completion)
Linearly interpolate between the values in start to the values in end.
void set_brightness(float brightness)
Set the brightness property of these light color values. In range 0.0 to 1.0.
float get_cold_white() const
Get the cold white property of these light color values. In range 0.0 to 1.0.
void set_blue(float blue)
Set the blue property of these light color values. In range 0.0 to 1.0.
void set_cold_white(float cold_white)
Set the cold white property of these light color values. In range 0.0 to 1.0.
void set_color_brightness(float brightness)
Set the color brightness property of these light color values. In range 0.0 to 1.0.
void set_color_temperature_kelvin(float color_temperature)
Set the color temperature property of these light color values in kelvin.
bool operator==(const LightColorValues &rhs) const
Compare this LightColorValues to rhs, return true if and only if all attributes match.
void set_warm_white(float warm_white)
Set the warm white property of these light color values. In range 0.0 to 1.0.
void as_cwww(float *cold_white, float *warm_white, float gamma=0, bool constant_brightness=false) const
Convert these light color values to an CWWW representation with the given parameters.
bool is_on() const
Get the binary true/false state of these light color values.
float get_green() const
Get the green property of these light color values. In range 0.0 to 1.0.
void set_state(float state)
Set the state of these light color values. In range from 0.0 (off) to 1.0 (on)
void set_color_temperature(float color_temperature)
Set the color temperature property of these light color values in mired.
float get_warm_white() const
Get the warm white property of these light color values. In range 0.0 to 1.0.
LightColorValues()
Construct the LightColorValues with all attributes enabled, but state set to off.
void as_binary(bool *binary) const
Convert these light color values to a binary representation and write them to binary.
float color_temperature_
Color Temperature in Mired.
LightColorValues(ColorMode color_mode, float state, float brightness, float color_brightness, float red, float green, float blue, float white, float color_temperature, float cold_white, float warm_white)
void as_rgbw(float *red, float *green, float *blue, float *white, float gamma=0, bool color_interlock=false) const
Convert these light color values to an RGBW representation and write them to red, green,...
ColorMode get_color_mode() const
Get the color mode of these light color values.
void set_white(float white)
Set the white property of these light color values. In range 0.0 to 1.0.
float get_red() const
Get the red property of these light color values. In range 0.0 to 1.0.
void set_green(float green)
Set the green property of these light color values. In range 0.0 to 1.0.
void set_red(float red)
Set the red property of these light color values. In range 0.0 to 1.0.
void normalize_color()
Normalize the color (RGB/W) component.
float get_color_brightness() const
Get the color brightness property of these light color values. In range 0.0 to 1.0.
void as_brightness(float *brightness, float gamma=0) const
Convert these light color values to a brightness-only representation and write them to brightness.
void as_rgbct(float color_temperature_cw, float color_temperature_ww, float *red, float *green, float *blue, float *color_temperature, float *white_brightness, float gamma=0) const
Convert these light color values to an RGB+CT+BR representation with the given parameters.
float get_color_temperature_kelvin() const
Get the color temperature property of these light color values in kelvin.
void as_rgbww(float *red, float *green, float *blue, float *cold_white, float *warm_white, float gamma=0, bool constant_brightness=false) const
Convert these light color values to an RGBWW representation with the given parameters.
bool state
Definition fan.h:0
ColorMode
Color modes are a combination of color capabilities that can be used at the same time.
Definition color_mode.h:49
@ UNKNOWN
No color mode configured (cannot be a supported mode, only active when light is off).
@ RGB
Color can be controlled using RGB format (includes a brightness control for the color).
@ COLOR_TEMPERATURE
Color temperature can be controlled.
@ WHITE
Brightness of white channel can be controlled separately from other channels.
@ COLD_WARM_WHITE
Brightness of cold and warm white output can be controlled.
Providing packet encoding functions for exchanging data with a remote host.
Definition a01nyub.cpp:7
float gamma_correct(float value, float gamma)
Applies gamma correction of gamma to value.
Definition helpers.cpp:562
float lerp(float completion, float start, float end)
Linearly interpolate between start and end by completion (between 0 and 1).
Definition helpers.cpp:95
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition helpers.h:102
uint8_t end[39]
Definition sun_gtil2.cpp:17
uint16_t x
Definition tt21100.cpp:5