ESPHome  2024.4.0
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. This is used by HA,
341  // which doesn't support CWWW modes (yet?), and for compatibility with the pre-colormode model,
342  // as CWWW and RGBWW lights used to represent their values as white + color temperature.
343  if (((this->white_.has_value() && *this->white_ > 0.0f) || this->color_temperature_.has_value()) && //
345  !(*this->color_mode_ & ColorCapability::WHITE) && //
347  traits.get_min_mireds() > 0.0f && traits.get_max_mireds() > 0.0f) {
348  ESP_LOGD(TAG, "'%s' - Setting cold/warm white channels using white/color temperature values.",
349  this->parent_->get_name().c_str());
350  auto current_values = this->parent_->remote_values;
351  if (this->color_temperature_.has_value()) {
352  const float white =
353  this->white_.value_or(fmaxf(current_values.get_cold_white(), current_values.get_warm_white()));
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_ = white * gamma_uncorrect(cw_fraction / max_cw_ww, this->parent_->get_gamma_correct());
360  this->warm_white_ = white * gamma_uncorrect(ww_fraction / max_cw_ww, this->parent_->get_gamma_correct());
361  } else {
362  const float max_cw_ww = std::max(current_values.get_warm_white(), current_values.get_cold_white());
363  this->cold_white_ = *this->white_ * current_values.get_cold_white() / max_cw_ww;
364  this->warm_white_ = *this->white_ * current_values.get_warm_white() / max_cw_ww;
365  }
366  }
367 }
369  auto supported_modes = this->parent_->get_traits().get_supported_color_modes();
370  int supported_count = supported_modes.size();
371 
372  // Some lights don't support any color modes (e.g. monochromatic light), leave it at unknown.
373  if (supported_count == 0)
374  return ColorMode::UNKNOWN;
375 
376  // In the common case of lights supporting only a single mode, use that one.
377  if (supported_count == 1)
378  return *supported_modes.begin();
379 
380  // Don't change if the light is being turned off.
381  ColorMode current_mode = this->parent_->remote_values.get_color_mode();
382  if (this->state_.has_value() && !*this->state_)
383  return current_mode;
384 
385  // If no color mode is specified, we try to guess the color mode. This is needed for backward compatibility to
386  // pre-colormode clients and automations, but also for the MQTT API, where HA doesn't let us know which color mode
387  // was used for some reason.
388  std::set<ColorMode> suitable_modes = this->get_suitable_color_modes_();
389 
390  // Don't change if the current mode is suitable.
391  if (suitable_modes.count(current_mode) > 0) {
392  ESP_LOGI(TAG, "'%s' - Keeping current color mode %s for call without color mode.",
393  this->parent_->get_name().c_str(), LOG_STR_ARG(color_mode_to_human(current_mode)));
394  return current_mode;
395  }
396 
397  // Use the preferred suitable mode.
398  for (auto mode : suitable_modes) {
399  if (supported_modes.count(mode) == 0)
400  continue;
401 
402  ESP_LOGI(TAG, "'%s' - Using color mode %s for call without color mode.", this->parent_->get_name().c_str(),
403  LOG_STR_ARG(color_mode_to_human(mode)));
404  return mode;
405  }
406 
407  // There's no supported mode for this call, so warn, use the current more or a mode at random and let validation strip
408  // out whatever we don't support.
409  auto color_mode = current_mode != ColorMode::UNKNOWN ? current_mode : *supported_modes.begin();
410  ESP_LOGW(TAG, "'%s' - No color mode suitable for this call supported, defaulting to %s!",
411  this->parent_->get_name().c_str(), LOG_STR_ARG(color_mode_to_human(color_mode)));
412  return color_mode;
413 }
415  bool has_white = this->white_.has_value() && *this->white_ > 0.0f;
416  bool has_ct = this->color_temperature_.has_value();
417  bool has_cwww = (this->cold_white_.has_value() && *this->cold_white_ > 0.0f) ||
418  (this->warm_white_.has_value() && *this->warm_white_ > 0.0f);
419  bool has_rgb = (this->color_brightness_.has_value() && *this->color_brightness_ > 0.0f) ||
420  (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value());
421 
422 #define KEY(white, ct, cwww, rgb) ((white) << 0 | (ct) << 1 | (cwww) << 2 | (rgb) << 3)
423 #define ENTRY(white, ct, cwww, rgb, ...) \
424  std::make_tuple<uint8_t, std::set<ColorMode>>(KEY(white, ct, cwww, rgb), __VA_ARGS__)
425 
426  // Flag order: white, color temperature, cwww, rgb
427  std::array<std::tuple<uint8_t, std::set<ColorMode>>, 10> lookup_table{
428  ENTRY(true, false, false, false,
431  ENTRY(false, true, false, false,
434  ENTRY(true, true, false, false,
436  ENTRY(false, false, true, false, {ColorMode::COLD_WARM_WHITE, ColorMode::RGB_COLD_WARM_WHITE}),
437  ENTRY(false, false, false, false,
440  ENTRY(true, false, false, true,
442  ENTRY(false, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
443  ENTRY(true, true, false, true, {ColorMode::RGB_COLOR_TEMPERATURE, ColorMode::RGB_COLD_WARM_WHITE}),
444  ENTRY(false, false, true, true, {ColorMode::RGB_COLD_WARM_WHITE}),
445  ENTRY(false, false, false, true,
447  };
448 
449  auto key = KEY(has_white, has_ct, has_cwww, has_rgb);
450  for (auto &item : lookup_table) {
451  if (std::get<0>(item) == key)
452  return std::get<1>(item);
453  }
454 
455  // This happens if there are conflicting flags given.
456  return {};
457 }
458 
459 LightCall &LightCall::set_effect(const std::string &effect) {
460  if (strcasecmp(effect.c_str(), "none") == 0) {
461  this->set_effect(0);
462  return *this;
463  }
464 
465  bool found = false;
466  for (uint32_t i = 0; i < this->parent_->effects_.size(); i++) {
467  LightEffect *e = this->parent_->effects_[i];
468 
469  if (strcasecmp(effect.c_str(), e->get_name().c_str()) == 0) {
470  this->set_effect(i + 1);
471  found = true;
472  break;
473  }
474  }
475  if (!found) {
476  ESP_LOGW(TAG, "'%s' - No such effect '%s'", this->parent_->get_name().c_str(), effect.c_str());
477  }
478  return *this;
479 }
481  this->set_state(values.is_on());
485  this->set_red_if_supported(values.get_red());
486  this->set_green_if_supported(values.get_green());
487  this->set_blue_if_supported(values.get_blue());
488  this->set_white_if_supported(values.get_white());
492  return *this;
493 }
496 }
499  this->set_transition_length(transition_length);
500  return *this;
501 }
504  this->set_brightness(brightness);
505  return *this;
506 }
508  if (this->parent_->get_traits().supports_color_mode(color_mode))
509  this->color_mode_ = color_mode;
510  return *this;
511 }
514  this->set_color_brightness(brightness);
515  return *this;
516 }
519  this->set_red(red);
520  return *this;
521 }
524  this->set_green(green);
525  return *this;
526 }
529  this->set_blue(blue);
530  return *this;
531 }
534  this->set_white(white);
535  return *this;
536 }
540  this->set_color_temperature(color_temperature);
541  return *this;
542 }
545  this->set_cold_white(cold_white);
546  return *this;
547 }
550  this->set_warm_white(warm_white);
551  return *this;
552 }
554  this->state_ = state;
555  return *this;
556 }
558  this->state_ = state;
559  return *this;
560 }
562  this->transition_length_ = transition_length;
563  return *this;
564 }
565 LightCall &LightCall::set_transition_length(uint32_t transition_length) {
566  this->transition_length_ = transition_length;
567  return *this;
568 }
570  this->flash_length_ = flash_length;
571  return *this;
572 }
573 LightCall &LightCall::set_flash_length(uint32_t flash_length) {
574  this->flash_length_ = flash_length;
575  return *this;
576 }
578  this->brightness_ = brightness;
579  return *this;
580 }
582  this->brightness_ = brightness;
583  return *this;
584 }
586  this->color_mode_ = color_mode;
587  return *this;
588 }
590  this->color_mode_ = color_mode;
591  return *this;
592 }
594  this->color_brightness_ = brightness;
595  return *this;
596 }
598  this->color_brightness_ = brightness;
599  return *this;
600 }
602  this->red_ = red;
603  return *this;
604 }
606  this->red_ = red;
607  return *this;
608 }
610  this->green_ = green;
611  return *this;
612 }
614  this->green_ = green;
615  return *this;
616 }
618  this->blue_ = blue;
619  return *this;
620 }
622  this->blue_ = blue;
623  return *this;
624 }
626  this->white_ = white;
627  return *this;
628 }
630  this->white_ = white;
631  return *this;
632 }
634  this->color_temperature_ = color_temperature;
635  return *this;
636 }
637 LightCall &LightCall::set_color_temperature(float color_temperature) {
638  this->color_temperature_ = color_temperature;
639  return *this;
640 }
642  this->cold_white_ = cold_white;
643  return *this;
644 }
646  this->cold_white_ = cold_white;
647  return *this;
648 }
650  this->warm_white_ = warm_white;
651  return *this;
652 }
654  this->warm_white_ = warm_white;
655  return *this;
656 }
658  if (effect.has_value())
659  this->set_effect(*effect);
660  return *this;
661 }
662 LightCall &LightCall::set_effect(uint32_t effect_number) {
663  this->effect_ = effect_number;
664  return *this;
665 }
667  this->effect_ = effect_number;
668  return *this;
669 }
671  this->publish_ = publish;
672  return *this;
673 }
675  this->save_ = save;
676  return *this;
677 }
678 LightCall &LightCall::set_rgb(float red, float green, float blue) {
679  this->set_red(red);
680  this->set_green(green);
681  this->set_blue(blue);
682  return *this;
683 }
684 LightCall &LightCall::set_rgbw(float red, float green, float blue, float white) {
685  this->set_rgb(red, green, blue);
686  this->set_white(white);
687  return *this;
688 }
689 
690 } // namespace light
691 } // 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:674
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:593
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:670
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:601
uint32_t default_transition_length_
Default transition length for all transitions in ms.
Definition: light_state.h:208
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:633
LightCall & set_green_if_supported(float green)
Set the green property if the light supports RGB.
Definition: light_call.cpp:522
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:641
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:114
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:678
LightCall & set_color_brightness_if_supported(float brightness)
Set the color brightness property if the light supports RGBW.
Definition: light_call.cpp:512
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:585
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:561
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:92
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:548
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:480
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:494
ColorMode compute_color_mode_()
Definition: light_call.cpp:368
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:151
LightCall & set_transition_length_if_supported(uint32_t transition_length)
Set the transition length property if the light supports transitions.
Definition: light_call.cpp:497
LightCall & set_color_temperature_if_supported(float color_temperature)
Set the color_temperature property if the light supports color temperature.
Definition: light_call.cpp:537
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:507
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:553
std::vector< LightEffect * > effects_
List of effects for this light.
Definition: light_state.h:216
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:649
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:657
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:543
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:414
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:684
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:569
LightCall & set_green(optional< float > green)
Set the green RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:609
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:205
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
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:184
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:77
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:502
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:625
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:577
LightCall & set_blue_if_supported(float blue)
Set the blue property if the light supports RGB.
Definition: light_call.cpp:527
LightCall & set_white_if_supported(float white)
Set the white property if the light supports RGB.
Definition: light_call.cpp:532
LightCall & set_blue(optional< float > blue)
Set the blue RGB value of the light from 0.0 to 1.0.
Definition: light_call.cpp:617
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:517
float gamma_uncorrect(float value, float gamma)
Reverts gamma correction of gamma to value.
Definition: helpers.cpp:446