ESPHome  2022.11.3
base_light_effects.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 
5 #include "light_effect.h"
7 
8 namespace esphome {
9 namespace light {
10 
11 inline static float random_cubic_float() {
12  const float r = random_float() * 2.0f - 1.0f;
13  return r * r * r;
14 }
15 
17 class PulseLightEffect : public LightEffect {
18  public:
19  explicit PulseLightEffect(const std::string &name) : LightEffect(name) {}
20 
21  void apply() override {
22  const uint32_t now = millis();
23  if (now - this->last_color_change_ < this->update_interval_) {
24  return;
25  }
26  auto call = this->state_->turn_on();
27  float out = this->on_ ? 1.0 : 0.0;
28  call.set_brightness_if_supported(out);
29  this->on_ = !this->on_;
30  call.set_transition_length_if_supported(this->transition_length_);
31  // don't tell HA every change
32  call.set_publish(false);
33  call.set_save(false);
34  call.perform();
35 
36  this->last_color_change_ = now;
37  }
38 
39  void set_transition_length(uint32_t transition_length) { this->transition_length_ = transition_length; }
40 
41  void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
42 
43  protected:
44  bool on_ = false;
45  uint32_t last_color_change_{0};
46  uint32_t transition_length_{};
47  uint32_t update_interval_{};
48 };
49 
52  public:
53  explicit RandomLightEffect(const std::string &name) : LightEffect(name) {}
54 
55  void apply() override {
56  const uint32_t now = millis();
57  if (now - this->last_color_change_ < this->update_interval_) {
58  return;
59  }
60 
61  auto color_mode = this->state_->remote_values.get_color_mode();
62  auto call = this->state_->turn_on();
63  bool changed = false;
64  if (color_mode & ColorCapability::RGB) {
65  call.set_red(random_float());
66  call.set_green(random_float());
67  call.set_blue(random_float());
68  changed = true;
69  }
70  if (color_mode & ColorCapability::COLOR_TEMPERATURE) {
71  float min = this->state_->get_traits().get_min_mireds();
72  float max = this->state_->get_traits().get_max_mireds();
73  call.set_color_temperature(min + random_float() * (max - min));
74  changed = true;
75  }
76  if (color_mode & ColorCapability::COLD_WARM_WHITE) {
77  call.set_cold_white(random_float());
78  call.set_warm_white(random_float());
79  changed = true;
80  }
81  if (!changed) {
82  // only randomize brightness if there's no colored option available
83  call.set_brightness(random_float());
84  }
85  call.set_transition_length_if_supported(this->transition_length_);
86  call.set_publish(true);
87  call.set_save(false);
88  call.perform();
89 
90  this->last_color_change_ = now;
91  }
92 
93  void set_transition_length(uint32_t transition_length) { this->transition_length_ = transition_length; }
94 
95  void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
96 
97  protected:
98  uint32_t last_color_change_{0};
99  uint32_t transition_length_{};
100  uint32_t update_interval_{};
101 };
102 
104  public:
105  LambdaLightEffect(const std::string &name, std::function<void(bool initial_run)> f, uint32_t update_interval)
106  : LightEffect(name), f_(std::move(f)), update_interval_(update_interval) {}
107 
108  void start() override { this->initial_run_ = true; }
109  void apply() override {
110  const uint32_t now = millis();
111  if (now - this->last_run_ >= this->update_interval_) {
112  this->last_run_ = now;
113  this->f_(this->initial_run_);
114  this->initial_run_ = false;
115  }
116  }
117 
118  protected:
119  std::function<void(bool initial_run)> f_;
121  uint32_t last_run_{0};
123 };
124 
126  public:
127  AutomationLightEffect(const std::string &name) : LightEffect(name) {}
128  void stop() override { this->trig_->stop_action(); }
129  void apply() override {
130  if (!this->trig_->is_action_running()) {
131  this->trig_->trigger();
132  }
133  }
134  Trigger<> *get_trig() const { return trig_; }
135 
136  protected:
137  Trigger<> *trig_{new Trigger<>};
138 };
139 
142  uint32_t duration;
143 };
144 
146  public:
147  explicit StrobeLightEffect(const std::string &name) : LightEffect(name) {}
148  void apply() override {
149  const uint32_t now = millis();
150  if (now - this->last_switch_ < this->colors_[this->at_color_].duration)
151  return;
152 
153  // Switch to next color
154  this->at_color_ = (this->at_color_ + 1) % this->colors_.size();
155  auto color = this->colors_[this->at_color_].color;
156 
157  auto call = this->state_->turn_on();
158  call.from_light_color_values(this->colors_[this->at_color_].color);
159 
160  if (!color.is_on()) {
161  // Don't turn the light off, otherwise the light effect will be stopped
162  call.set_brightness(0.0f);
163  call.set_state(true);
164  }
165  call.set_publish(false);
166  call.set_save(false);
168  call.perform();
169  this->last_switch_ = now;
170  }
171 
172  void set_colors(const std::vector<StrobeLightEffectColor> &colors) { this->colors_ = colors; }
173 
174  protected:
175  std::vector<StrobeLightEffectColor> colors_;
176  uint32_t last_switch_{0};
177  size_t at_color_{0};
178 };
179 
181  public:
182  explicit FlickerLightEffect(const std::string &name) : LightEffect(name) {}
183 
184  void apply() override {
185  LightColorValues remote = this->state_->remote_values;
186  LightColorValues current = this->state_->current_values;
187  LightColorValues out;
188  const float alpha = this->alpha_;
189  const float beta = 1.0f - alpha;
190  out.set_state(true);
191  out.set_brightness(remote.get_brightness() * beta + current.get_brightness() * alpha +
192  (random_cubic_float() * this->intensity_));
193  out.set_red(remote.get_red() * beta + current.get_red() * alpha + (random_cubic_float() * this->intensity_));
194  out.set_green(remote.get_green() * beta + current.get_green() * alpha + (random_cubic_float() * this->intensity_));
195  out.set_blue(remote.get_blue() * beta + current.get_blue() * alpha + (random_cubic_float() * this->intensity_));
196  out.set_white(remote.get_white() * beta + current.get_white() * alpha + (random_cubic_float() * this->intensity_));
197  out.set_cold_white(remote.get_cold_white() * beta + current.get_cold_white() * alpha +
198  (random_cubic_float() * this->intensity_));
199  out.set_warm_white(remote.get_warm_white() * beta + current.get_warm_white() * alpha +
200  (random_cubic_float() * this->intensity_));
201 
202  auto call = this->state_->make_call();
203  call.set_publish(false);
204  call.set_save(false);
206  call.from_light_color_values(out);
207  call.set_state(true);
208  call.perform();
209  }
210 
211  void set_alpha(float alpha) { this->alpha_ = alpha; }
212  void set_intensity(float intensity) { this->intensity_ = intensity; }
213 
214  protected:
215  float intensity_{};
216  float alpha_{};
217 };
218 
219 } // namespace light
220 } // namespace esphome
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
const char * name
Definition: stm32flash.h:78
float get_warm_white() const
Get the warm white property of these light color values. In range 0.0 to 1.0.
LightCall & set_publish(bool publish)
Set whether this light call should trigger a publish state.
Definition: light_call.cpp:669
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
LightColorValues current_values
The current values of the light as outputted to the light.
Definition: light_state.h:66
void set_warm_white(float warm_white)
Set the warm white property of these light color values. In range 0.0 to 1.0.
LightCall turn_on()
Make a light state call.
Definition: light_state.cpp:15
float get_cold_white() const
Get the cold white property of these light color values. In range 0.0 to 1.0.
void set_green(float green)
Set the green property of these light color values. In range 0.0 to 1.0.
float get_min_mireds() const
Definition: light_traits.h:49
void set_state(float state)
Set the state of these light color values. In range from 0.0 (off) to 1.0 (on)
float get_red() const
Get the red property of these light color values. In range 0.0 to 1.0.
STL namespace.
Color temperature can be controlled.
FlickerLightEffect(const std::string &name)
AutomationLightEffect(const std::string &name)
uint32_t IRAM_ATTR HOT millis()
Definition: core.cpp:26
void set_colors(const std::vector< StrobeLightEffectColor > &colors)
void set_red(float red)
Set the red property of these light color values. In range 0.0 to 1.0.
float get_blue() const
Get the blue property of these light color values. In range 0.0 to 1.0.
LambdaLightEffect(const std::string &name, std::function< void(bool initial_run)> f, uint32_t update_interval)
LightCall & from_light_color_values(const LightColorValues &values)
Definition: light_call.cpp:479
This class represents the color state for a light object.
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.
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
StrobeLightEffect(const std::string &name)
Random effect. Sets random colors every 10 seconds and slowly transitions between them...
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::function< void(bool initial_run)> f_
RandomLightEffect(const std::string &name)
void set_white(float white)
Set the white property of these light color values. In range 0.0 to 1.0.
std::vector< StrobeLightEffectColor > colors_
void set_update_interval(uint32_t update_interval)
void set_brightness(float brightness)
Set the brightness property of these light color values. In range 0.0 to 1.0.
void set_blue(float blue)
Set the blue property of these light color values. In range 0.0 to 1.0.
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
void set_cold_white(float cold_white)
Set the cold white property of these light color values. In range 0.0 to 1.0.
Definition: a4988.cpp:4
Color can be controlled using RGB format (includes a brightness control for the color).
float get_max_mireds() const
Definition: light_traits.h:51
LightColorValues remote_values
The remote color values reported to the frontend.
Definition: light_state.h:78
void set_transition_length(uint32_t transition_length)
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
PulseLightEffect(const std::string &name)
void set_update_interval(uint32_t update_interval)
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
float random_float()
Return a random float between 0 and 1.
Definition: helpers.cpp:111
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.
void set_transition_length(uint32_t transition_length)