ESPHome  2024.2.1
base_light_effects.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 #include <vector>
5 
7 #include "light_effect.h"
8 
9 namespace esphome {
10 namespace light {
11 
12 inline static float random_cubic_float() {
13  const float r = random_float() * 2.0f - 1.0f;
14  return r * r * r;
15 }
16 
18 class PulseLightEffect : public LightEffect {
19  public:
20  explicit PulseLightEffect(const std::string &name) : LightEffect(name) {}
21 
22  void apply() override {
23  const uint32_t now = millis();
24  if (now - this->last_color_change_ < this->update_interval_) {
25  return;
26  }
27  auto call = this->state_->turn_on();
28  float out = this->on_ ? this->max_brightness : this->min_brightness;
29  call.set_brightness_if_supported(out);
30  call.set_transition_length_if_supported(this->on_ ? this->transition_on_length_ : this->transition_off_length_);
31  this->on_ = !this->on_;
32  // don't tell HA every change
33  call.set_publish(false);
34  call.set_save(false);
35  call.perform();
36 
37  this->last_color_change_ = now;
38  }
39 
40  void set_transition_on_length(uint32_t transition_length) { this->transition_on_length_ = transition_length; }
41  void set_transition_off_length(uint32_t transition_length) { this->transition_off_length_ = transition_length; }
42 
43  void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
44 
45  void set_min_max_brightness(float min, float max) {
46  this->min_brightness = min;
47  this->max_brightness = max;
48  }
49 
50  protected:
51  bool on_ = false;
52  uint32_t last_color_change_{0};
55  uint32_t update_interval_{};
56  float min_brightness{0.0};
57  float max_brightness{1.0};
58 };
59 
62  public:
63  explicit RandomLightEffect(const std::string &name) : LightEffect(name) {}
64 
65  void apply() override {
66  const uint32_t now = millis();
67  if (now - this->last_color_change_ < this->update_interval_) {
68  return;
69  }
70 
71  auto color_mode = this->state_->remote_values.get_color_mode();
72  auto call = this->state_->turn_on();
73  bool changed = false;
74  if (color_mode & ColorCapability::RGB) {
75  call.set_red(random_float());
76  call.set_green(random_float());
77  call.set_blue(random_float());
78  changed = true;
79  }
80  if (color_mode & ColorCapability::COLOR_TEMPERATURE) {
81  float min = this->state_->get_traits().get_min_mireds();
82  float max = this->state_->get_traits().get_max_mireds();
83  call.set_color_temperature(min + random_float() * (max - min));
84  changed = true;
85  }
86  if (color_mode & ColorCapability::COLD_WARM_WHITE) {
87  call.set_cold_white(random_float());
88  call.set_warm_white(random_float());
89  changed = true;
90  }
91  if (!changed) {
92  // only randomize brightness if there's no colored option available
93  call.set_brightness(random_float());
94  }
95  call.set_transition_length_if_supported(this->transition_length_);
96  call.set_publish(true);
97  call.set_save(false);
98  call.perform();
99 
100  this->last_color_change_ = now;
101  }
102 
103  void set_transition_length(uint32_t transition_length) { this->transition_length_ = transition_length; }
104 
105  void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
106 
107  protected:
108  uint32_t last_color_change_{0};
109  uint32_t transition_length_{};
110  uint32_t update_interval_{};
111 };
112 
114  public:
115  LambdaLightEffect(const std::string &name, std::function<void(bool initial_run)> f, uint32_t update_interval)
116  : LightEffect(name), f_(std::move(f)), update_interval_(update_interval) {}
117 
118  void start() override { this->initial_run_ = true; }
119  void apply() override {
120  const uint32_t now = millis();
121  if (now - this->last_run_ >= this->update_interval_ || this->initial_run_) {
122  this->last_run_ = now;
123  this->f_(this->initial_run_);
124  this->initial_run_ = false;
125  }
126  }
127 
128  protected:
129  std::function<void(bool initial_run)> f_;
131  uint32_t last_run_{0};
133 };
134 
136  public:
137  AutomationLightEffect(const std::string &name) : LightEffect(name) {}
138  void stop() override { this->trig_->stop_action(); }
139  void apply() override {
140  if (!this->trig_->is_action_running()) {
141  this->trig_->trigger();
142  }
143  }
144  Trigger<> *get_trig() const { return trig_; }
145 
146  protected:
147  Trigger<> *trig_{new Trigger<>};
148 };
149 
152  uint32_t duration;
153 };
154 
156  public:
157  explicit StrobeLightEffect(const std::string &name) : LightEffect(name) {}
158  void apply() override {
159  const uint32_t now = millis();
160  if (now - this->last_switch_ < this->colors_[this->at_color_].duration)
161  return;
162 
163  // Switch to next color
164  this->at_color_ = (this->at_color_ + 1) % this->colors_.size();
165  auto color = this->colors_[this->at_color_].color;
166 
167  auto call = this->state_->turn_on();
168  call.from_light_color_values(this->colors_[this->at_color_].color);
169 
170  if (!color.is_on()) {
171  // Don't turn the light off, otherwise the light effect will be stopped
172  call.set_brightness(0.0f);
173  call.set_state(true);
174  }
175  call.set_publish(false);
176  call.set_save(false);
178  call.perform();
179  this->last_switch_ = now;
180  }
181 
182  void set_colors(const std::vector<StrobeLightEffectColor> &colors) { this->colors_ = colors; }
183 
184  protected:
185  std::vector<StrobeLightEffectColor> colors_;
186  uint32_t last_switch_{0};
187  size_t at_color_{0};
188 };
189 
191  public:
192  explicit FlickerLightEffect(const std::string &name) : LightEffect(name) {}
193 
194  void apply() override {
195  LightColorValues remote = this->state_->remote_values;
196  LightColorValues current = this->state_->current_values;
197  LightColorValues out;
198  const float alpha = this->alpha_;
199  const float beta = 1.0f - alpha;
200  out.set_state(true);
201  out.set_brightness(remote.get_brightness() * beta + current.get_brightness() * alpha +
202  (random_cubic_float() * this->intensity_));
203  out.set_red(remote.get_red() * beta + current.get_red() * alpha + (random_cubic_float() * this->intensity_));
204  out.set_green(remote.get_green() * beta + current.get_green() * alpha + (random_cubic_float() * this->intensity_));
205  out.set_blue(remote.get_blue() * beta + current.get_blue() * alpha + (random_cubic_float() * this->intensity_));
206  out.set_white(remote.get_white() * beta + current.get_white() * alpha + (random_cubic_float() * this->intensity_));
207  out.set_cold_white(remote.get_cold_white() * beta + current.get_cold_white() * alpha +
208  (random_cubic_float() * this->intensity_));
209  out.set_warm_white(remote.get_warm_white() * beta + current.get_warm_white() * alpha +
210  (random_cubic_float() * this->intensity_));
211 
212  auto call = this->state_->make_call();
213  call.set_publish(false);
214  call.set_save(false);
216  call.from_light_color_values(out);
217  call.set_state(true);
218  call.perform();
219  }
220 
221  void set_alpha(float alpha) { this->alpha_ = alpha; }
222  void set_intensity(float intensity) { this->intensity_ = intensity; }
223 
224  protected:
225  float intensity_{};
226  float alpha_{};
227 };
228 
229 } // namespace light
230 } // 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:674
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:670
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
LightColorValues current_values
The current values of the light as outputted to the light.
Definition: light_state.h:65
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:14
void set_transition_on_length(uint32_t transition_length)
float get_cold_white() const
Get the cold white property of these light color values. In range 0.0 to 1.0.
void set_min_max_brightness(float min, float max)
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:25
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:480
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.
void set_transition_off_length(uint32_t transition_length)
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
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:553
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:609
void set_cold_white(float cold_white)
Set the cold white property of these light color values. In range 0.0 to 1.0.
This is a workaround until we can figure out a way to get the tflite-micro idf component code availab...
Definition: a01nyub.cpp:7
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:77
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
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:617
float random_float()
Return a random float between 0 and 1.
Definition: helpers.cpp:214
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)