ESPHome  2023.3.2
light_call.cpp
Go to the documentation of this file.
1 #include "light_call.h"
2 #include "light_state.h"
3 #include "esphome/core/log.h"
4 
5 namespace esphome {
6 namespace light {
7 
8 static const char *const TAG = "light";
9 
10 static const LogString *color_mode_to_human(ColorMode color_mode) {
11  if (color_mode == ColorMode::UNKNOWN)
12  return LOG_STR("Unknown");
13  if (color_mode == ColorMode::WHITE)
14  return LOG_STR("White");
15  if (color_mode == ColorMode::COLOR_TEMPERATURE)
16  return LOG_STR("Color temperature");
17  if (color_mode == ColorMode::COLD_WARM_WHITE)
18  return LOG_STR("Cold/warm white");
19  if (color_mode == ColorMode::RGB)
20  return LOG_STR("RGB");
21  if (color_mode == ColorMode::RGB_WHITE)
22  return LOG_STR("RGBW");
23  if (color_mode == ColorMode::RGB_COLD_WARM_WHITE)
24  return LOG_STR("RGB + cold/warm white");
25  if (color_mode == ColorMode::RGB_COLOR_TEMPERATURE)
26  return LOG_STR("RGB + color temperature");
27  return LOG_STR("");
28 }
29 
31  const char *name = this->parent_->get_name().c_str();
32  LightColorValues v = this->validate_();
33 
34  if (this->publish_) {
35  ESP_LOGD(TAG, "'%s' Setting:", name);
36 
37  // Only print color mode when it's being changed
38  ColorMode current_color_mode = this->parent_->remote_values.get_color_mode();
39  if (this->color_mode_.value_or(current_color_mode) != current_color_mode) {
40  ESP_LOGD(TAG, " Color mode: %s", LOG_STR_ARG(color_mode_to_human(v.get_color_mode())));
41  }
42 
43  // Only print state when it's being changed
44  bool current_state = this->parent_->remote_values.is_on();
45  if (this->state_.value_or(current_state) != current_state) {
46  ESP_LOGD(TAG, " State: %s", ONOFF(v.is_on()));
47  }
48 
49  if (this->brightness_.has_value()) {
50  ESP_LOGD(TAG, " Brightness: %.0f%%", v.get_brightness() * 100.0f);
51  }
52 
53  if (this->color_brightness_.has_value()) {
54  ESP_LOGD(TAG, " Color brightness: %.0f%%", v.get_color_brightness() * 100.0f);
55  }
56  if (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value()) {
57  ESP_LOGD(TAG, " Red: %.0f%%, Green: %.0f%%, Blue: %.0f%%", v.get_red() * 100.0f, v.get_green() * 100.0f,
58  v.get_blue() * 100.0f);
59  }
60 
61  if (this->white_.has_value()) {
62  ESP_LOGD(TAG, " White: %.0f%%", v.get_white() * 100.0f);
63  }
64  if (this->color_temperature_.has_value()) {
65  ESP_LOGD(TAG, " Color temperature: %.1f mireds", v.get_color_temperature());
66  }
67 
68  if (this->cold_white_.has_value() || this->warm_white_.has_value()) {
69  ESP_LOGD(TAG, " Cold white: %.0f%%, warm white: %.0f%%", v.get_cold_white() * 100.0f,
70  v.get_warm_white() * 100.0f);
71  }
72  }
73 
74  if (this->has_flash_()) {
75  // FLASH
76  if (this->publish_) {
77  ESP_LOGD(TAG, " Flash length: %.1fs", *this->flash_length_ / 1e3f);
78  }
79 
80  this->parent_->start_flash_(v, *this->flash_length_, this->publish_);
81  } else if (this->has_transition_()) {
82  // TRANSITION
83  if (this->publish_) {
84  ESP_LOGD(TAG, " Transition length: %.1fs", *this->transition_length_ / 1e3f);
85  }
86 
87  // Special case: Transition and effect can be set when turning off
88  if (this->has_effect_()) {
89  if (this->publish_) {
90  ESP_LOGD(TAG, " Effect: 'None'");
91  }
92  this->parent_->stop_effect_();
93  }
94 
95  this->parent_->start_transition_(v, *this->transition_length_, this->publish_);
96 
97  } else if (this->has_effect_()) {
98  // EFFECT
99  auto effect = this->effect_;
100  const char *effect_s;
101  if (effect == 0u) {
102  effect_s = "None";
103  } else {
104  effect_s = this->parent_->effects_[*this->effect_ - 1]->get_name().c_str();
105  }
106 
107  if (this->publish_) {
108  ESP_LOGD(TAG, " Effect: '%s'", effect_s);
109  }
110 
111  this->parent_->start_effect_(*this->effect_);
112 
113  // Also set light color values when starting an effect
114  // For example to turn off the light
115  this->parent_->set_immediately_(v, true);
116  } else {
117  // INSTANT CHANGE
118  this->parent_->set_immediately_(v, this->publish_);
119  }
120 
121  if (!this->has_transition_()) {
123  }
124  if (this->publish_) {
125  this->parent_->publish_state();
126  }
127  if (this->save_) {
128  this->parent_->save_remote_values_();
129  }
130 }
131 
133  auto *name = this->parent_->get_name().c_str();
134  auto traits = this->parent_->get_traits();
135 
136  // Color mode check
137  if (this->color_mode_.has_value() && !traits.supports_color_mode(this->color_mode_.value())) {
138  ESP_LOGW(TAG, "'%s' - This light does not support color mode %s!", name,
139  LOG_STR_ARG(color_mode_to_human(this->color_mode_.value())));
140  this->color_mode_.reset();
141  }
142 
143  // Ensure there is always a color mode set
144  if (!this->color_mode_.has_value()) {
145  this->color_mode_ = this->compute_color_mode_();
146  }
147  auto color_mode = *this->color_mode_;
148 
149  // Transform calls that use non-native parameters for the current mode.
150  this->transform_parameters_();
151 
152  // Brightness exists check
153  if (this->brightness_.has_value() && *this->brightness_ > 0.0f && !(color_mode & ColorCapability::BRIGHTNESS)) {
154  ESP_LOGW(TAG, "'%s' - This light does not support setting brightness!", name);
155  this->brightness_.reset();
156  }
157 
158  // Transition length possible check
159  if (this->transition_length_.has_value() && *this->transition_length_ != 0 &&
160  !(color_mode & ColorCapability::BRIGHTNESS)) {
161  ESP_LOGW(TAG, "'%s' - This light does not support transitions!", name);
162  this->transition_length_.reset();
163  }
164 
165  // Color brightness exists check
166  if (this->color_brightness_.has_value() && *this->color_brightness_ > 0.0f && !(color_mode & ColorCapability::RGB)) {
167  ESP_LOGW(TAG, "'%s' - This color mode does not support setting RGB brightness!", name);
168  this->color_brightness_.reset();
169  }
170 
171  // RGB exists check
172  if ((this->red_.has_value() && *this->red_ > 0.0f) || (this->green_.has_value() && *this->green_ > 0.0f) ||
173  (this->blue_.has_value() && *this->blue_ > 0.0f)) {
174  if (!(color_mode & ColorCapability::RGB)) {
175  ESP_LOGW(TAG, "'%s' - This color mode does not support setting RGB color!", name);
176  this->red_.reset();
177  this->green_.reset();
178  this->blue_.reset();
179  }
180  }
181 
182  // White value exists check
183  if (this->white_.has_value() && *this->white_ > 0.0f &&
184  !(color_mode & ColorCapability::WHITE || color_mode & ColorCapability::COLD_WARM_WHITE)) {
185  ESP_LOGW(TAG, "'%s' - This color mode does not support setting white value!", name);
186  this->white_.reset();
187  }
188 
189  // Color temperature exists check
190  if (this->color_temperature_.has_value() &&
192  ESP_LOGW(TAG, "'%s' - This color mode does not support setting color temperature!", name);
193  this->color_temperature_.reset();
194  }
195 
196  // Cold/warm white value exists check
197  if ((this->cold_white_.has_value() && *this->cold_white_ > 0.0f) ||
198  (this->warm_white_.has_value() && *this->warm_white_ > 0.0f)) {
199  if (!(color_mode & ColorCapability::COLD_WARM_WHITE)) {
200  ESP_LOGW(TAG, "'%s' - This color mode does not support setting cold/warm white value!", name);
201  this->cold_white_.reset();
202  this->warm_white_.reset();
203  }
204  }
205 
206 #define VALIDATE_RANGE_(name_, upper_name, min, max) \
207  if (name_##_.has_value()) { \
208  auto val = *name_##_; \
209  if (val < (min) || val > (max)) { \
210  ESP_LOGW(TAG, "'%s' - %s value %.2f is out of range [%.1f - %.1f]!", name, LOG_STR_LITERAL(upper_name), val, \
211  (min), (max)); \
212  name_##_ = clamp(val, (min), (max)); \
213  } \
214  }
215 #define VALIDATE_RANGE(name, upper_name) VALIDATE_RANGE_(name, upper_name, 0.0f, 1.0f)
216 
217  // Range checks
218  VALIDATE_RANGE(brightness, "Brightness")
219  VALIDATE_RANGE(color_brightness, "Color brightness")
220  VALIDATE_RANGE(red, "Red")
221  VALIDATE_RANGE(green, "Green")
222  VALIDATE_RANGE(blue, "Blue")
223  VALIDATE_RANGE(white, "White")
224  VALIDATE_RANGE(cold_white, "Cold white")
225  VALIDATE_RANGE(warm_white, "Warm white")
226  VALIDATE_RANGE_(color_temperature, "Color temperature", traits.get_min_mireds(), traits.get_max_mireds())
227 
228  // Flag whether an explicit turn off was requested, in which case we'll also stop the effect.
229  bool explicit_turn_off_request = this->state_.has_value() && !*this->state_;
230 
231  // Turn off when brightness is set to zero, and reset brightness (so that it has nonzero brightness when turned on).
232  if (this->brightness_.has_value() && *this->brightness_ == 0.0f) {
233  this->state_ = optional<float>(false);
234  this->brightness_ = optional<float>(1.0f);
235  }
236 
237  // Set color brightness to 100% if currently zero and a color is set.
238  if (this->red_.has_value() || this->green_.has_value() || this->blue_.has_value()) {
239  if (!this->color_brightness_.has_value() && this->parent_->remote_values.get_color_brightness() == 0.0f)
240  this->color_brightness_ = optional<float>(1.0f);
241  }
242 
243  // Create color values for the light with this call applied.
244  auto v = this->parent_->remote_values;
245  if (this->color_mode_.has_value())
246  v.set_color_mode(*this->color_mode_);
247  if (this->state_.has_value())
248  v.set_state(*this->state_);
249  if (this->brightness_.has_value())
250  v.set_brightness(*this->brightness_);
251  if (this->color_brightness_.has_value())
252  v.set_color_brightness(*this->color_brightness_);
253  if (this->red_.has_value())
254  v.set_red(*this->red_);
255  if (this->green_.has_value())
256  v.set_green(*this->green_);
257  if (this->blue_.has_value())
258  v.set_blue(*this->blue_);
259  if (this->white_.has_value())
260  v.set_white(*this->white_);
261  if (this->color_temperature_.has_value())
262  v.set_color_temperature(*this->color_temperature_);
263  if (this->cold_white_.has_value())
264  v.set_cold_white(*this->cold_white_);
265  if (this->warm_white_.has_value())
266  v.set_warm_white(*this->warm_white_);
267 
268  v.normalize_color();
269 
270  // Flash length check
271  if (this->has_flash_() && *this->flash_length_ == 0) {
272  ESP_LOGW(TAG, "'%s' - Flash length must be greater than zero!", name);
273  this->flash_length_.reset();
274  }
275 
276  // validate transition length/flash length/effect not used at the same time
277  bool supports_transition = color_mode & ColorCapability::BRIGHTNESS;
278 
279  // If effect is already active, remove effect start
280  if (this->has_effect_() && *this->effect_ == this->parent_->active_effect_index_) {
281  this->effect_.reset();
282  }
283 
284  // validate effect index
285  if (this->has_effect_() && *this->effect_ > this->parent_->effects_.size()) {
286  ESP_LOGW(TAG, "'%s' - Invalid effect index %u!", name, *this->effect_);
287  this->effect_.reset();
288  }
289 
290  if (this->has_effect_() && (this->has_transition_() || this->has_flash_())) {
291  ESP_LOGW(TAG, "'%s' - Effect cannot be used together with transition/flash!", name);
292  this->transition_length_.reset();
293  this->flash_length_.reset();
294  }
295 
296  if (this->has_flash_() && this->has_transition_()) {
297  ESP_LOGW(TAG, "'%s' - Flash cannot be used together with transition!", name);
298  this->transition_length_.reset();
299  }
300 
301  if (!this->has_transition_() && !this->has_flash_() && (!this->has_effect_() || *this->effect_ == 0) &&
302  supports_transition) {
303  // nothing specified and light supports transitions, set default transition length
305  }
306 
307  if (this->transition_length_.value_or(0) == 0) {
308  // 0 transition is interpreted as no transition (instant change)
309  this->transition_length_.reset();
310  }
311 
312  if (this->has_transition_() && !supports_transition) {
313  ESP_LOGW(TAG, "'%s' - Light does not support transitions!", name);
314  this->transition_length_.reset();
315  }
316 
317  // If not a flash and turning the light off, then disable the light
318  // Do not use light color values directly, so that effects can set 0% brightness
319  // Reason: When user turns off the light in frontend, the effect should also stop
320  if (!this->has_flash_() && !this->state_.value_or(v.is_on())) {
321  if (this->has_effect_()) {
322  ESP_LOGW(TAG, "'%s' - Cannot start an effect when turning off!", name);
323  this->effect_.reset();
324  } else if (this->parent_->active_effect_index_ != 0 && explicit_turn_off_request) {
325  // Auto turn off effect
326  this->effect_ = 0;
327  }
328  }
329 
330  // Disable saving for flashes
331  if (this->has_flash_())
332  this->save_ = false;
333 
334  return v;
335 }
337  auto traits = this->parent_->get_traits();
338 
339  // Allow CWWW modes to be set with a white value and/or color temperature. This is used by HA,
340  // which doesn't support CWWW modes (yet?), and for compatibility with the pre-colormode model,
341  // as CWWW and RGBWW lights used to represent their values as white + color temperature.
342  if (((this->white_.has_value() && *this->white_ > 0.0f) || this->color_temperature_.has_value()) && //
344  !(*this->color_mode_ & ColorCapability::WHITE) && //
346  traits.get_min_mireds() > 0.0f && traits.get_max_mireds() > 0.0f) {
347  ESP_LOGD(TAG, "'%s' - Setting cold/warm white channels using white/color temperature values.",
348  this->parent_->get_name().c_str());
349  auto current_values = this->parent_->remote_values;
350  if (this->color_temperature_.has_value()) {
351  const float white =
352  this->white_.value_or(fmaxf(current_values.get_cold_white(), current_values.get_warm_white()));
353  const float color_temp = clamp(*this->color_temperature_, traits.get_min_mireds(), traits.get_max_mireds());
354  const float ww_fraction =
355  (color_temp - traits.get_min_mireds()) / (traits.get_max_mireds() - traits.get_min_mireds());
356  const float cw_fraction = 1.0f - ww_fraction;
357  const float max_cw_ww = std::max(ww_fraction, cw_fraction);
358  this->cold_white_ = white * gamma_uncorrect(cw_fraction / max_cw_ww, this->parent_->get_gamma_correct());
359  this->warm_white_ = white * gamma_uncorrect(ww_fraction / max_cw_ww, this->parent_->get_gamma_correct());
360  } else {
361  const float max_cw_ww = std::max(current_values.get_warm_white(), current_values.get_cold_white());
362  this->cold_white_ = *this->white_ * current_values.get_cold_white() / max_cw_ww;
363  this->warm_white_ = *this->white_ * current_values.get_warm_white() / max_cw_ww;
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:200
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:117
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
const std::string & get_name() const
Definition: entity_base.cpp:11
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:132
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:89
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: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: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:208
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:336
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).
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:197
Definition: a4988.cpp:4
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:176
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:80
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.
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:322