ESPHome 2025.5.0
Loading...
Searching...
No Matches
light_call.cpp
Go to the documentation of this file.
1#include <cinttypes>
2#include "light_call.h"
3#include "light_state.h"
4#include "esphome/core/log.h"
5
6namespace esphome {
7namespace light {
8
9static const char *const TAG = "light";
10
11static const LogString *color_mode_to_human(ColorMode color_mode) {
12 if (color_mode == ColorMode::UNKNOWN)
13 return LOG_STR("Unknown");
14 if (color_mode == ColorMode::WHITE)
15 return LOG_STR("White");
16 if (color_mode == ColorMode::COLOR_TEMPERATURE)
17 return LOG_STR("Color temperature");
18 if (color_mode == ColorMode::COLD_WARM_WHITE)
19 return LOG_STR("Cold/warm white");
20 if (color_mode == ColorMode::RGB)
21 return LOG_STR("RGB");
22 if (color_mode == ColorMode::RGB_WHITE)
23 return LOG_STR("RGBW");
24 if (color_mode == ColorMode::RGB_COLD_WARM_WHITE)
25 return LOG_STR("RGB + cold/warm white");
26 if (color_mode == ColorMode::RGB_COLOR_TEMPERATURE)
27 return LOG_STR("RGB + color temperature");
28 return LOG_STR("");
29}
30
32 const char *name = this->parent_->get_name().c_str();
33 LightColorValues v = this->validate_();
34
35 if (this->publish_) {
36 ESP_LOGD(TAG, "'%s' Setting:", name);
37
38 // Only print color mode when it's being changed
39 ColorMode current_color_mode = this->parent_->remote_values.get_color_mode();
40 if (this->color_mode_.value_or(current_color_mode) != current_color_mode) {
41 ESP_LOGD(TAG, " Color mode: %s", LOG_STR_ARG(color_mode_to_human(v.get_color_mode())));
42 }
43
44 // Only print state when it's being changed
45 bool current_state = this->parent_->remote_values.is_on();
46 if (this->state_.value_or(current_state) != current_state) {
47 ESP_LOGD(TAG, " State: %s", ONOFF(v.is_on()));
48 }
49
50 if (this->brightness_.has_value()) {
51 ESP_LOGD(TAG, " Brightness: %.0f%%", v.get_brightness() * 100.0f);
52 }
53
54 if (this->color_brightness_.has_value()) {
55 ESP_LOGD(TAG, " Color brightness: %.0f%%", v.get_color_brightness() * 100.0f);
56 }
57 if (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value()) {
58 ESP_LOGD(TAG, " Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.get_red() * 100.0f, v.get_green() * 100.0f,
59 v.get_blue() * 100.0f);
60 }
61
62 if (this->white_.has_value()) {
63 ESP_LOGD(TAG, " White: %.0f%%", v.get_white() * 100.0f);
64 }
65 if (this->color_temperature_.has_value()) {
66 ESP_LOGD(TAG, " Color temperature: %.1f mireds", v.get_color_temperature());
67 }
68
69 if (this->cold_white_.has_value() || this->warm_white_.has_value()) {
70 ESP_LOGD(TAG, " Cold white: %.0f%%, warm white: %.0f%%", v.get_cold_white() * 100.0f,
71 v.get_warm_white() * 100.0f);
72 }
73 }
74
75 if (this->has_flash_()) {
76 // FLASH
77 if (this->publish_) {
78 ESP_LOGD(TAG, " Flash length: %.1fs", *this->flash_length_ / 1e3f);
79 }
80
81 this->parent_->start_flash_(v, *this->flash_length_, this->publish_);
82 } else if (this->has_transition_()) {
83 // TRANSITION
84 if (this->publish_) {
85 ESP_LOGD(TAG, " Transition length: %.1fs", *this->transition_length_ / 1e3f);
86 }
87
88 // Special case: Transition and effect can be set when turning off
89 if (this->has_effect_()) {
90 if (this->publish_) {
91 ESP_LOGD(TAG, " Effect: 'None'");
92 }
93 this->parent_->stop_effect_();
94 }
95
97
98 } else if (this->has_effect_()) {
99 // EFFECT
100 auto effect = this->effect_;
101 const char *effect_s;
102 if (effect == 0u) {
103 effect_s = "None";
104 } else {
105 effect_s = this->parent_->effects_[*this->effect_ - 1]->get_name().c_str();
106 }
107
108 if (this->publish_) {
109 ESP_LOGD(TAG, " Effect: '%s'", effect_s);
110 }
111
112 this->parent_->start_effect_(*this->effect_);
113
114 // Also set light color values when starting an effect
115 // For example to turn off the light
116 this->parent_->set_immediately_(v, true);
117 } else {
118 // INSTANT CHANGE
119 this->parent_->set_immediately_(v, this->publish_);
120 }
121
122 if (!this->has_transition_()) {
124 }
125 if (this->publish_) {
126 this->parent_->publish_state();
127 }
128 if (this->save_) {
130 }
131}
132
134 auto *name = this->parent_->get_name().c_str();
135 auto traits = this->parent_->get_traits();
136
137 // Color mode check
138 if (this->color_mode_.has_value() && !traits.supports_color_mode(this->color_mode_.value())) {
139 ESP_LOGW(TAG, "'%s' - This light does not support color mode %s!", name,
140 LOG_STR_ARG(color_mode_to_human(this->color_mode_.value())));
141 this->color_mode_.reset();
142 }
143
144 // Ensure there is always a color mode set
145 if (!this->color_mode_.has_value()) {
146 this->color_mode_ = this->compute_color_mode_();
147 }
148 auto color_mode = *this->color_mode_;
149
150 // Transform calls that use non-native parameters for the current mode.
151 this->transform_parameters_();
152
153 // Brightness exists check
154 if (this->brightness_.has_value() && *this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS)) {
155 ESP_LOGW(TAG, "'%s' - This light does not support setting brightness!", name);
156 this->brightness_.reset();
157 }
158
159 // Transition length possible check
160 if (this->transition_length_.has_value() && *this->transition_length_ != 0 &&
161 !(color_mode & ColorCapability::BRIGHTNESS)) {
162 ESP_LOGW(TAG, "'%s' - This light does not support transitions!", name);
164 }
165
166 // Color brightness exists check
167 if (this->color_brightness_.has_value() && *this->color_brightness_ > 0.0f && !(color_mode & ColorCapability::RGB)) {
168 ESP_LOGW(TAG, "'%s' - This color mode does not support setting RGB brightness!", name);
169 this->color_brightness_.reset();
170 }
171
172 // RGB exists check
173 if ((this->red_.has_value() && *this->red_ > 0.0f) || (this->green_.has_value() && *this->green_ > 0.0f) ||
174 (this->blue_.has_value() && *this->blue_ > 0.0f)) {
175 if (!(color_mode & ColorCapability::RGB)) {
176 ESP_LOGW(TAG, "'%s' - This color mode does not support setting RGB color!", name);
177 this->red_.reset();
178 this->green_.reset();
179 this->blue_.reset();
180 }
181 }
182
183 // White value exists check
184 if (this->white_.has_value() && *this->white_ > 0.0f &&
185 !(color_mode & ColorCapability::WHITE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
186 ESP_LOGW(TAG, "'%s' - This color mode does not support setting white value!", name);
187 this->white_.reset();
188 }
189
190 // Color temperature exists check
191 if (this->color_temperature_.has_value() &&
193 ESP_LOGW(TAG, "'%s' - This color mode does not support setting color temperature!", name);
195 }
196
197 // Cold/warm white value exists check
198 if ((this->cold_white_.has_value() && *this->cold_white_ > 0.0f) ||
199 (this->warm_white_.has_value() && *this->warm_white_ > 0.0f)) {
200 if (!(color_mode & ColorCapability::COLD_WARM_WHITE)) {
201 ESP_LOGW(TAG, "'%s' - This color mode does not support setting cold/warm white value!", name);
202 this->cold_white_.reset();
203 this->warm_white_.reset();
204 }
205 }
206
207#define VALIDATE_RANGE_(name_, upper_name, min, max) \
208 if (name_##_.has_value()) { \
209 auto val = *name_##_; \
210 if (val < (min) || val > (max)) { \
211 ESP_LOGW(TAG, "'%s' - %s value %.2f is out of range [%.1f - %.1f]!", name, LOG_STR_LITERAL(upper_name), val, \
212 (min), (max)); \
213 name_##_ = clamp(val, (min), (max)); \
214 } \
215 }
216#define VALIDATE_RANGE(name, upper_name) VALIDATE_RANGE_(name, upper_name, 0.0f, 1.0f)
217
218 // Range checks
219 VALIDATE_RANGE(brightness, "Brightness")
220 VALIDATE_RANGE(color_brightness, "Color brightness")
221 VALIDATE_RANGE(red, "Red")
222 VALIDATE_RANGE(green, "Green")
223 VALIDATE_RANGE(blue, "Blue")
224 VALIDATE_RANGE(white, "White")
225 VALIDATE_RANGE(cold_white, "Cold white")
226 VALIDATE_RANGE(warm_white, "Warm white")
227 VALIDATE_RANGE_(color_temperature, "Color temperature", traits.get_min_mireds(), traits.get_max_mireds())
228
229 // Flag whether an explicit turn off was requested, in which case we'll also stop the effect.
230 bool explicit_turn_off_request = this->state_.has_value() && !*this->state_;
231
232 // Turn off when brightness is set to zero, and reset brightness (so that it has nonzero brightness when turned on).
233 if (this->brightness_.has_value() && *this->brightness_ == 0.0f) {
234 this->state_ = optional<float>(false);
235 this->brightness_ = optional<float>(1.0f);
236 }
237
238 // Set color brightness to 100% if currently zero and a color is set.
239 if (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value()) {
240 if (!this->color_brightness_.has_value() && this->parent_->remote_values.get_color_brightness() == 0.0f)
242 }
243
244 // Create color values for the light with this call applied.
245 auto v = this->parent_->remote_values;
246 if (this->color_mode_.has_value())
247 v.set_color_mode(*this->color_mode_);
248 if (this->state_.has_value())
249 v.set_state(*this->state_);
250 if (this->brightness_.has_value())
251 v.set_brightness(*this->brightness_);
252 if (this->color_brightness_.has_value())
253 v.set_color_brightness(*this->color_brightness_);
254 if (this->red_.has_value())
255 v.set_red(*this->red_);
256 if (this->green_.has_value())
257 v.set_green(*this->green_);
258 if (this->blue_.has_value())
259 v.set_blue(*this->blue_);
260 if (this->white_.has_value())
261 v.set_white(*this->white_);
262 if (this->color_temperature_.has_value())
263 v.set_color_temperature(*this->color_temperature_);
264 if (this->cold_white_.has_value())
265 v.set_cold_white(*this->cold_white_);
266 if (this->warm_white_.has_value())
267 v.set_warm_white(*this->warm_white_);
268
269 v.normalize_color();
270
271 // Flash length check
272 if (this->has_flash_() && *this->flash_length_ == 0) {
273 ESP_LOGW(TAG, "'%s' - Flash length must be greater than zero!", name);
274 this->flash_length_.reset();
275 }
276
277 // validate transition length/flash length/effect not used at the same time
278 bool supports_transition = color_mode & ColorCapability::BRIGHTNESS;
279
280 // If effect is already active, remove effect start
281 if (this->has_effect_() && *this->effect_ == this->parent_->active_effect_index_) {
282 this->effect_.reset();
283 }
284
285 // validate effect index
286 if (this->has_effect_() && *this->effect_ > this->parent_->effects_.size()) {
287 ESP_LOGW(TAG, "'%s' - Invalid effect index %" PRIu32 "!", name, *this->effect_);
288 this->effect_.reset();
289 }
290
291 if (this->has_effect_() && (this->has_transition_() || this->has_flash_())) {
292 ESP_LOGW(TAG, "'%s' - Effect cannot be used together with transition/flash!", name);
294 this->flash_length_.reset();
295 }
296
297 if (this->has_flash_() && this->has_transition_()) {
298 ESP_LOGW(TAG, "'%s' - Flash cannot be used together with transition!", name);
300 }
301
302 if (!this->has_transition_() && !this->has_flash_() && (!this->has_effect_() || *this->effect_ == 0) &&
303 supports_transition) {
304 // nothing specified and light supports transitions, set default transition length
306 }
307
308 if (this->transition_length_.value_or(0) == 0) {
309 // 0 transition is interpreted as no transition (instant change)
311 }
312
313 if (this->has_transition_() && !supports_transition) {
314 ESP_LOGW(TAG, "'%s' - Light does not support transitions!", name);
316 }
317
318 // If not a flash and turning the light off, then disable the light
319 // Do not use light color values directly, so that effects can set 0% brightness
320 // Reason: When user turns off the light in frontend, the effect should also stop
321 if (!this->has_flash_() && !this->state_.value_or(v.is_on())) {
322 if (this->has_effect_()) {
323 ESP_LOGW(TAG, "'%s' - Cannot start an effect when turning off!", name);
324 this->effect_.reset();
325 } else if (this->parent_->active_effect_index_ != 0 && explicit_turn_off_request) {
326 // Auto turn off effect
327 this->effect_ = 0;
328 }
329 }
330
331 // Disable saving for flashes
332 if (this->has_flash_())
333 this->save_ = false;
334
335 return v;
336}
338 auto traits = this->parent_->get_traits();
339
340 // Allow CWWW modes to be set with a white value and/or color temperature.
341 // This is used in three cases in HA:
342 // - CW/WW lights, which set the "brightness" and "color_temperature"
343 // - RGBWW lights with color_interlock=true, which also sets "brightness" and
344 // "color_temperature" (without color_interlock, CW/WW are set directly)
345 // - Legacy Home Assistant (pre-colormode), which sets "white" and "color_temperature"
346 if (((this->white_.has_value() && *this->white_ > 0.0f) || this->color_temperature_.has_value()) && //
347 (*this->color_mode_ & ColorCapability::COLD_WARM_WHITE) && //
348 !(*this->color_mode_ & ColorCapability::WHITE) && //
349 !(*this->color_mode_ & ColorCapability::COLOR_TEMPERATURE) && //
350 traits.get_min_mireds() > 0.0f && traits.get_max_mireds() > 0.0f) {
351 ESP_LOGD(TAG, "'%s' - Setting cold/warm white channels using white/color temperature values.",
352 this->parent_->get_name().c_str());
353 if (this->color_temperature_.has_value()) {
354 const float color_temp = clamp(*this->color_temperature_, traits.get_min_mireds(), traits.get_max_mireds());
355 const float ww_fraction =
356 (color_temp - traits.get_min_mireds()) / (traits.get_max_mireds() - traits.get_min_mireds());
357 const float cw_fraction = 1.0f - ww_fraction;
358 const float max_cw_ww = std::max(ww_fraction, cw_fraction);
359 this->cold_white_ = gamma_uncorrect(cw_fraction / max_cw_ww, this->parent_->get_gamma_correct());
360 this->warm_white_ = gamma_uncorrect(ww_fraction / max_cw_ww, this->parent_->get_gamma_correct());
361 }
362 if (this->white_.has_value()) {
363 this->brightness_ = *this->white_;
364 }
365 }
366}
368 auto supported_modes = this->parent_->get_traits().get_supported_color_modes();
369 int supported_count = supported_modes.size();
370
371 // Some lights don't support any color modes (e.g. monochromatic light), leave it at unknown.
372 if (supported_count == 0)
373 return ColorMode::UNKNOWN;
374
375 // In the common case of lights supporting only a single mode, use that one.
376 if (supported_count == 1)
377 return *supported_modes.begin();
378
379 // Don't change if the light is being turned off.
380 ColorMode current_mode = this->parent_->remote_values.get_color_mode();
381 if (this->state_.has_value() && !*this->state_)
382 return current_mode;
383
384 // If no color mode is specified, we try to guess the color mode. This is needed for backward compatibility to
385 // pre-colormode clients and automations, but also for the MQTT API, where HA doesn't let us know which color mode
386 // was used for some reason.
387 std::set<ColorMode> suitable_modes = this->get_suitable_color_modes_();
388
389 // Don't change if the current mode is suitable.
390 if (suitable_modes.count(current_mode) > 0) {
391 ESP_LOGI(TAG, "'%s' - Keeping current color mode %s for call without color mode.",
392 this->parent_->get_name().c_str(), LOG_STR_ARG(color_mode_to_human(current_mode)));
393 return current_mode;
394 }
395
396 // Use the preferred suitable mode.
397 for (auto mode : suitable_modes) {
398 if (supported_modes.count(mode) == 0)
399 continue;
400
401 ESP_LOGI(TAG, "'%s' - Using color mode %s for call without color mode.", this->parent_->get_name().c_str(),
402 LOG_STR_ARG(color_mode_to_human(mode)));
403 return mode;
404 }
405
406 // There's no supported mode for this call, so warn, use the current more or a mode at random and let validation strip
407 // out whatever we don't support.
408 auto color_mode = current_mode != ColorMode::UNKNOWN ? current_mode : *supported_modes.begin();
409 ESP_LOGW(TAG, "'%s' - No color mode suitable for this call supported, defaulting to %s!",
410 this->parent_->get_name().c_str(), LOG_STR_ARG(color_mode_to_human(color_mode)));
411 return color_mode;
412}
414 bool has_white = this->white_.has_value() && *this->white_ > 0.0f;
415 bool has_ct = this->color_temperature_.has_value();
416 bool has_cwww = (this->cold_white_.has_value() && *this->cold_white_ > 0.0f) ||
417 (this->warm_white_.has_value() && *this->warm_white_ > 0.0f);
418 bool has_rgb = (this->color_brightness_.has_value() && *this->color_brightness_ > 0.0f) ||
419 (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value());
420
421#define KEY(white, ct, cwww, rgb) ((white) << 0 | (ct) << 1 | (cwww) << 2 | (rgb) << 3)
422#define ENTRY(white, ct, cwww, rgb, ...) \
423 std::make_tuple<uint8_t, std::set<ColorMode>>(KEY(white, ct, cwww, rgb), __VA_ARGS__)
424
425 // Flag order: white, color temperature, cwww, rgb
426 std::array<std::tuple<uint8_t, std::set<ColorMode>>, 10> lookup_table{
427 ENTRY(true, false, false, false,
430 ENTRY(false, true, false, false,
433 ENTRY(true, true, false, false,
435 ENTRY(false, false, true, false, {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}),
436 ENTRY(false, false, false, false,
439 ENTRY(true, false, false, true,
441 ENTRY(false, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
442 ENTRY(true, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
443 ENTRY(false, false, true, true, {ColorMode::RGB_COLD_WARM_WHITE}),
444 ENTRY(false, false, false, true,
446 };
447
448 auto key = KEY(has_white, has_ct, has_cwww, has_rgb);
449 for (auto &item : lookup_table) {
450 if (std::get<0>(item) == key)
451 return std::get<1>(item);
452 }
453
454 // This happens if there are conflicting flags given.
455 return {};
456}
457
458LightCall &LightCall::set_effect(const std::string &effect) {
459 if (strcasecmp(effect.c_str(), "none") == 0) {
460 this->set_effect(0);
461 return *this;
462 }
463
464 bool found = false;
465 for (uint32_t i = 0; i < this->parent_->effects_.size(); i++) {
466 LightEffect *e = this->parent_->effects_[i];
467
468 if (strcasecmp(effect.c_str(), e->get_name().c_str()) == 0) {
469 this->set_effect(i + 1);
470 found = true;
471 break;
472 }
473 }
474 if (!found) {
475 ESP_LOGW(TAG, "'%s' - No such effect '%s'", this->parent_->get_name().c_str(), effect.c_str());
476 }
477 return *this;
478}
498 this->set_transition_length(transition_length);
499 return *this;
500}
503 this->set_brightness(brightness);
504 return *this;
505}
507 if (this->parent_->get_traits().supports_color_mode(color_mode))
508 this->color_mode_ = color_mode;
509 return *this;
510}
513 this->set_color_brightness(brightness);
514 return *this;
515}
518 this->set_red(red);
519 return *this;
520}
523 this->set_green(green);
524 return *this;
525}
528 this->set_blue(blue);
529 return *this;
530}
533 this->set_white(white);
534 return *this;
535}
544 this->set_cold_white(cold_white);
545 return *this;
546}
549 this->set_warm_white(warm_white);
550 return *this;
551}
553 this->state_ = state;
554 return *this;
555}
557 this->state_ = state;
558 return *this;
559}
561 this->transition_length_ = transition_length;
562 return *this;
563}
564LightCall &LightCall::set_transition_length(uint32_t transition_length) {
565 this->transition_length_ = transition_length;
566 return *this;
567}
569 this->flash_length_ = flash_length;
570 return *this;
571}
572LightCall &LightCall::set_flash_length(uint32_t flash_length) {
573 this->flash_length_ = flash_length;
574 return *this;
575}
577 this->brightness_ = brightness;
578 return *this;
579}
581 this->brightness_ = brightness;
582 return *this;
583}
585 this->color_mode_ = color_mode;
586 return *this;
587}
589 this->color_mode_ = color_mode;
590 return *this;
591}
593 this->color_brightness_ = brightness;
594 return *this;
595}
597 this->color_brightness_ = brightness;
598 return *this;
599}
601 this->red_ = red;
602 return *this;
603}
605 this->red_ = red;
606 return *this;
607}
609 this->green_ = green;
610 return *this;
611}
613 this->green_ = green;
614 return *this;
615}
617 this->blue_ = blue;
618 return *this;
619}
621 this->blue_ = blue;
622 return *this;
623}
625 this->white_ = white;
626 return *this;
627}
629 this->white_ = white;
630 return *this;
631}
633 this->color_temperature_ = color_temperature;
634 return *this;
635}
637 this->color_temperature_ = color_temperature;
638 return *this;
639}
641 this->cold_white_ = cold_white;
642 return *this;
643}
645 this->cold_white_ = cold_white;
646 return *this;
647}
649 this->warm_white_ = warm_white;
650 return *this;
651}
653 this->warm_white_ = warm_white;
654 return *this;
655}
657 if (effect.has_value())
658 this->set_effect(*effect);
659 return *this;
660}
661LightCall &LightCall::set_effect(uint32_t effect_number) {
662 this->effect_ = effect_number;
663 return *this;
664}
666 this->effect_ = effect_number;
667 return *this;
668}
670 this->publish_ = publish;
671 return *this;
672}
674 this->save_ = save;
675 return *this;
676}
677LightCall &LightCall::set_rgb(float red, float green, float blue) {
678 this->set_red(red);
679 this->set_green(green);
680 this->set_blue(blue);
681 return *this;
682}
683LightCall &LightCall::set_rgbw(float red, float green, float blue, float white) {
684 this->set_rgb(red, green, blue);
685 this->set_white(white);
686 return *this;
687}
688
689} // namespace light
690} // namespace esphome
BedjetMode mode
BedJet operating mode.
const StringRef & get_name() const
constexpr const char * c_str() const
Definition string_ref.h:68
This class represents a requested change in a light state.
Definition light_call.h:14
LightCall & set_color_mode_if_supported(ColorMode color_mode)
Set the color mode of the light, if this mode is supported.
optional< float > brightness_
Definition light_call.h:182
optional< float > red_
Definition light_call.h:184
LightCall & set_color_temperature(optional< float > color_temperature)
Set the color temperature of the light in mireds for CWWW or RGBWW lights.
LightCall & set_publish(bool publish)
Set whether this light call should trigger a publish state.
optional< float > white_
Definition light_call.h:187
optional< ColorMode > color_mode_
Definition light_call.h:181
LightCall & set_color_brightness(optional< float > brightness)
Set the color brightness of the light from 0.0 (no color) to 1.0 (fully on)
optional< float > color_brightness_
Definition light_call.h:183
LightCall & set_rgb(float red, float green, float blue)
Set the RGB color of the light by RGB values.
optional< uint32_t > flash_length_
Definition light_call.h:180
LightCall & set_transition_length_if_supported(uint32_t transition_length)
Set the transition length property if the light supports transitions.
LightCall & set_red_if_supported(float red)
Set the red property if the light supports RGB.
optional< float > cold_white_
Definition light_call.h:189
LightCall & set_effect(optional< std::string > effect)
Set the effect of the light by its name.
std::set< ColorMode > get_suitable_color_modes_()
Get potential color modes for this light call.
LightCall & set_color_brightness_if_supported(float brightness)
Set the color brightness property if the light supports RGBW.
LightCall & set_white(optional< float > white)
Set the white value value of the light from 0.0 to 1.0 for RGBW[W] lights.
optional< float > warm_white_
Definition light_call.h:190
LightCall & set_green(optional< float > green)
Set the green RGB value of the light from 0.0 to 1.0.
LightCall & set_green_if_supported(float green)
Set the green property if the light supports RGB.
LightCall & set_warm_white(optional< float > warm_white)
Set the warm white value of the light from 0.0 to 1.0.
LightCall & set_rgbw(float red, float green, float blue, float white)
Set the RGBW color of the light by RGB values.
LightCall & set_save(bool save)
Set whether this light call should trigger a save state to recover them at startup....
LightCall & set_color_temperature_if_supported(float color_temperature)
Set the color_temperature property if the light supports color temperature.
LightCall & set_blue(optional< float > blue)
Set the blue RGB value of the light from 0.0 to 1.0.
LightCall & set_flash_length(optional< uint32_t > flash_length)
Start and set the flash length of this call in milliseconds.
optional< float > blue_
Definition light_call.h:186
LightCall & set_cold_white(optional< float > cold_white)
Set the cold white value of the light from 0.0 to 1.0.
LightCall & set_red(optional< float > red)
Set the red RGB value of the light from 0.0 to 1.0.
ColorMode get_active_color_mode_()
Get the currently targeted, or active if none set, color mode.
optional< float > color_temperature_
Definition light_call.h:188
optional< uint32_t > effect_
Definition light_call.h:191
LightCall & set_white_if_supported(float white)
Set the white property if the light supports RGB.
LightCall & set_cold_white_if_supported(float cold_white)
Set the cold white property if the light supports cold white output.
LightCall & set_warm_white_if_supported(float warm_white)
Set the warm white property if the light supports cold white output.
LightCall & set_brightness_if_supported(float brightness)
Set the brightness property if the light supports brightness.
LightColorValues validate_()
Validate all properties and return the target light color values.
optional< float > green_
Definition light_call.h:185
LightCall & set_brightness(optional< float > brightness)
Set the target brightness of the light from 0.0 (fully off) to 1.0 (fully on)
LightCall & set_blue_if_supported(float blue)
Set the blue property if the light supports RGB.
void transform_parameters_()
Some color modes also can be set using non-native parameters, transform those calls.
LightCall & from_light_color_values(const LightColorValues &values)
LightCall & set_state(optional< bool > state)
Set the binary ON/OFF state of the light.
LightCall & set_color_mode(optional< ColorMode > color_mode)
Set the color mode of the light.
optional< bool > state_
Definition light_call.h:178
optional< uint32_t > transition_length_
Definition light_call.h:179
LightCall & set_transition_length(optional< uint32_t > transition_length)
Set the transition length of this call in milliseconds.
This class represents the color state for a light object.
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.
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 get_color_temperature() const
Get the color temperature property of these light color values in mired.
float get_cold_white() const
Get the cold white property of these light color values. In range 0.0 to 1.0.
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.
float get_warm_white() const
Get the warm white property of these light color values. In range 0.0 to 1.0.
ColorMode get_color_mode() const
Get the color mode of these light color values.
float get_red() const
Get the red property of these light color values. In range 0.0 to 1.0.
float get_color_brightness() const
Get the color brightness property of these light color values. In range 0.0 to 1.0.
const std::string & get_name()
void start_effect_(uint32_t effect_index)
Internal method to start an effect with the given index.
void stop_effect_()
Internal method to stop the current effect (if one is active).
LightColorValues remote_values
The remote color values reported to the frontend.
void save_remote_values_()
Internal method to save the current remote_values to the preferences.
void set_immediately_(const LightColorValues &target, bool set_remote_values)
Internal method to set the color values to target immediately (with no transition).
float get_gamma_correct() const
void publish_state()
Publish the currently active state to the frontend.
uint32_t active_effect_index_
Value for storing the index of the currently active effect. 0 if no effect is active.
void start_flash_(const LightColorValues &target, uint32_t length, bool set_remote_values)
Internal method to start a flash for the specified amount of time.
std::vector< LightEffect * > effects_
List of effects for this light.
CallbackManager< void()> target_state_reached_callback_
Callback to call when the state of current_values and remote_values are equal This should be called o...
void start_transition_(const LightColorValues &target, uint32_t length, bool set_remote_values)
Internal method to start a transition to the target color with the given length.
uint32_t default_transition_length_
Default transition length for all transitions in ms.
bool supports_color_mode(ColorMode color_mode) const
const std::set< ColorMode > & get_supported_color_modes() const
bool has_value() const
Definition optional.h:87
value_type value_or(U const &v) const
Definition optional.h:93
value_type const & value() const
Definition optional.h:89
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
@ RGB_COLD_WARM_WHITE
RGB color output, and separate cold and warm white outputs.
@ UNKNOWN
No color mode configured (cannot be a supported mode, only active when light is off).
@ RGB_WHITE
RGB color output and a separate white output.
@ RGB_COLOR_TEMPERATURE
RGB color output and a separate white output with controllable color temperature.
@ RGB
RGB color output.
@ COLOR_TEMPERATURE
Controllable color temperature output.
@ WHITE
White output only (use only if the light also has another color mode such as RGB).
@ COLD_WARM_WHITE
Cold and warm white output with individually controllable brightness.
@ BRIGHTNESS
Master brightness of the light can be controlled.
@ 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_uncorrect(float value, float gamma)
Reverts gamma correction of gamma to value.
Definition helpers.cpp:570
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition helpers.h:101