ESPHome  2024.11.3
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 
6 namespace esphome {
7 namespace light {
8 
9 static const char *const TAG = "light";
10 
11 static 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 
96  this->parent_->start_transition_(v, *this->transition_length_, this->publish_);
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_) {
129  this->parent_->save_remote_values_();
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);
163  this->transition_length_.reset();
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);
194  this->color_temperature_.reset();
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)
241  this->color_brightness_ = optional<float>(1.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);
293  this->transition_length_.reset();
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);
299  this->transition_length_.reset();
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)
310  this->transition_length_.reset();
311  }
312 
313  if (this->has_transition_() && !supports_transition) {
314  ESP_LOGW(TAG, "'%s' - Light does not support transitions!", name);
315  this->transition_length_.reset();
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()) && //
348  !(*this->color_mode_ & ColorCapability::WHITE) && //
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 
458 LightCall &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 }
480  this->set_state(values.is_on());
484  this->set_red_if_supported(values.get_red());
485  this->set_green_if_supported(values.get_green());
486  this->set_blue_if_supported(values.get_blue());
487  this->set_white_if_supported(values.get_white());
491  return *this;
492 }
495 }
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 }
539  this->set_color_temperature(color_temperature);
540  return *this;
541 }
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 }
564 LightCall &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 }
572 LightCall &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 }
636 LightCall &LightCall::set_color_temperature(float color_temperature) {
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 }
661 LightCall &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 }
677 LightCall &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 }
683 LightCall &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
value_type const & value() const
Definition: optional.h:89
LightCall & set_save(bool save)
Set whether this light call should trigger a save state to recover them at startup..
Definition: light_call.cpp:673
ColorMode
Color modes are a combination of color capabilities that can be used at the same time.
Definition: color_mode.h:49
const char * name
Definition: stm32flash.h:78
LightCall & set_color_brightness(optional< float > brightness)
Set the color brightness of the light from 0.0 (no color) to 1.0 (fully on)
Definition: light_call.cpp:592
float get_warm_white() const
Get the warm white property of these light color values. In range 0.0 to 1.0.
void publish_state()
Publish the currently active state to the frontend.
void set_immediately_(const LightColorValues &target, bool set_remote_values)
Internal method to set the color values to target immediately (with no transition).
LightCall & set_publish(bool publish)
Set whether this light call should trigger a publish state.
Definition: light_call.cpp:669
bool is_on() const
Get the binary true/false state of these light color values.
LightCall & set_red(optional< float > red)
Set the red RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:600
uint32_t default_transition_length_
Default transition length for all transitions in ms.
Definition: light_state.h:240
LightCall & set_color_temperature(optional< float > color_temperature)
Set the color temperature of the light in mireds for CWWW or RGBWW lights.
Definition: light_call.cpp:632
LightCall & set_green_if_supported(float green)
Set the green property if the light supports RGB.
Definition: light_call.cpp:521
optional< float > warm_white_
Definition: light_call.h:190
LightCall & set_cold_white(optional< float > cold_white)
Set the cold white value of the light from 0.0 to 1.0.
Definition: light_call.cpp:640
optional< uint32_t > effect_
Definition: light_call.h:191
optional< float > blue_
Definition: light_call.h:186
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.
float get_gamma_correct() const
Definition: light_state.h:143
float get_cold_white() const
Get the cold white property of these light color values. In range 0.0 to 1.0.
void start_effect_(uint32_t effect_index)
Internal method to start an effect with the given index.
RGB color output and a separate white output.
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.
float get_red() const
Get the red property of these light color values. In range 0.0 to 1.0.
LightCall & set_rgb(float red, float green, float blue)
Set the RGB color of the light by RGB values.
Definition: light_call.cpp:677
LightCall & set_color_brightness_if_supported(float brightness)
Set the color brightness property if the light supports RGBW.
Definition: light_call.cpp:511
optional< float > red_
Definition: light_call.h:184
Color temperature can be controlled.
optional< float > color_brightness_
Definition: light_call.h:183
optional< float > cold_white_
Definition: light_call.h:189
LightCall & set_color_mode(optional< ColorMode > color_mode)
Set the color mode of the light.
Definition: light_call.cpp:584
LightColorValues validate_()
Validate all properties and return the target light color values.
Definition: light_call.cpp:133
bool has_value() const
Definition: optional.h:87
LightCall & set_transition_length(optional< uint32_t > transition_length)
Set the transition length of this call in milliseconds.
Definition: light_call.cpp:560
void set_color_mode(ColorMode color_mode)
Set the color mode of these light color values.
constexpr const T & clamp(const T &v, const T &lo, const T &hi, Compare comp)
Definition: helpers.h:93
optional< bool > state_
Definition: light_call.h:178
LightCall & set_warm_white_if_supported(float warm_white)
Set the warm white property if the light supports cold white output.
Definition: light_call.cpp:547
float get_blue() const
Get the blue property of these light color values. In range 0.0 to 1.0.
RGB color output, and separate cold and warm white outputs.
LightCall & from_light_color_values(const LightColorValues &values)
Definition: light_call.cpp:479
optional< float > brightness_
Definition: light_call.h:182
optional< float > color_temperature_
Definition: light_call.h:188
This class represents the color state for a light object.
ColorMode get_active_color_mode_()
Get the currently targeted, or active if none set, color mode.
Definition: light_call.cpp:493
ColorMode compute_color_mode_()
Definition: light_call.cpp:367
Brightness of cold and warm white output can be controlled.
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.
Brightness of white channel can be controlled separately from other channels.
const std::set< ColorMode > & get_supported_color_modes() const
Definition: light_traits.h:15
BedjetMode mode
BedJet operating mode.
Definition: bedjet_codec.h:183
LightCall & set_transition_length_if_supported(uint32_t transition_length)
Set the transition length property if the light supports transitions.
Definition: light_call.cpp:496
LightCall & set_color_temperature_if_supported(float color_temperature)
Set the color_temperature property if the light supports color temperature.
Definition: light_call.cpp:536
LightCall & set_color_mode_if_supported(ColorMode color_mode)
Set the color mode of the light, if this mode is supported.
Definition: light_call.cpp:506
RGB color output and a separate white output with controllable color temperature. ...
This class represents a requested change in a light state.
Definition: light_call.h:14
ColorMode get_color_mode() const
Get the color mode of these light color values.
LightCall & set_state(optional< bool > state)
Set the binary ON/OFF state of the light.
Definition: light_call.cpp:552
std::vector< LightEffect * > effects_
List of effects for this light.
Definition: light_state.h:250
Master brightness of the light can be controlled.
White output only (use only if the light also has another color mode such as RGB).
void transform_parameters_()
Some color modes also can be set using non-native parameters, transform those calls.
Definition: light_call.cpp:337
LightCall & set_warm_white(optional< float > warm_white)
Set the warm white value of the light from 0.0 to 1.0.
Definition: light_call.cpp:648
const std::string & get_name()
Definition: light_effect.h:27
No color mode configured (cannot be a supported mode, only active when light is off).
constexpr const char * c_str() const
Definition: string_ref.h:68
bool supports_color_mode(ColorMode color_mode) const
Definition: light_traits.h:20
LightCall & set_effect(optional< std::string > effect)
Set the effect of the light by its name.
Definition: light_call.cpp:656
LightCall & set_cold_white_if_supported(float cold_white)
Set the cold white property if the light supports cold white output.
Definition: light_call.cpp:542
optional< ColorMode > color_mode_
Definition: light_call.h:181
std::set< ColorMode > get_suitable_color_modes_()
Get potential color modes for this light call.
Definition: light_call.cpp:413
optional< float > white_
Definition: light_call.h:187
LightCall & set_rgbw(float red, float green, float blue, float white)
Set the RGBW color of the light by RGB values.
Definition: light_call.cpp:683
optional< uint32_t > flash_length_
Definition: light_call.h:180
void save_remote_values_()
Internal method to save the current remote_values to the preferences.
LightCall & set_flash_length(optional< uint32_t > flash_length)
Start and set the flash length of this call in milliseconds.
Definition: light_call.cpp:568
LightCall & set_green(optional< float > green)
Set the green RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:608
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...
Definition: light_state.h:237
Implementation of SPI Controller mode.
Definition: a01nyub.cpp:7
uint32_t active_effect_index_
Value for storing the index of the currently active effect. 0 if no effect is active.
Definition: light_state.h:216
Color can be controlled using RGB format (includes a brightness control for the color).
LightColorValues remote_values
The remote color values reported to the frontend.
Definition: light_state.h:106
optional< float > green_
Definition: light_call.h:185
float get_color_brightness() const
Get the color brightness property of these light color values. In range 0.0 to 1.0.
optional< uint32_t > transition_length_
Definition: light_call.h:179
LightCall & set_brightness_if_supported(float brightness)
Set the brightness property if the light supports brightness.
Definition: light_call.cpp:501
LightCall & set_white(optional< float > white)
Set the white value value of the light from 0.0 to 1.0 for RGBW[W] lights.
Definition: light_call.cpp:624
LightCall & set_brightness(optional< float > brightness)
Set the target brightness of the light from 0.0 (fully off) to 1.0 (fully on)
Definition: light_call.cpp:576
LightCall & set_blue_if_supported(float blue)
Set the blue property if the light supports RGB.
Definition: light_call.cpp:526
LightCall & set_white_if_supported(float white)
Set the white property if the light supports RGB.
Definition: light_call.cpp:531
LightCall & set_blue(optional< float > blue)
Set the blue RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:616
void stop_effect_()
Internal method to stop the current effect (if one is active).
value_type value_or(U const &v) const
Definition: optional.h:93
float get_green() const
Get the green property of these light color values. In range 0.0 to 1.0.
const StringRef & get_name() const
Definition: entity_base.cpp:10
float get_brightness() const
Get the brightness property of these light color values. In range 0.0 to 1.0.
bool state
Definition: fan.h:34
LightCall & set_red_if_supported(float red)
Set the red property if the light supports RGB.
Definition: light_call.cpp:516
float gamma_uncorrect(float value, float gamma)
Reverts gamma correction of gamma to value.
Definition: helpers.cpp:562