ESPHome  2024.6.6
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;
154 };
155 
157  public:
158  explicit StrobeLightEffect(const std::string &name) : LightEffect(name) {}
159  void apply() override {
160  const uint32_t now = millis();
161  if (now - this->last_switch_ < this->colors_[this->at_color_].duration)
162  return;
163 
164  // Switch to next color
165  this->at_color_ = (this->at_color_ + 1) % this->colors_.size();
166  auto color = this->colors_[this->at_color_].color;
167 
168  auto call = this->state_->turn_on();
169  call.from_light_color_values(this->colors_[this->at_color_].color);
170 
171  if (!color.is_on()) {
172  // Don't turn the light off, otherwise the light effect will be stopped
173  call.set_brightness(0.0f);
174  call.set_state(true);
175  }
176  call.set_publish(false);
177  call.set_save(false);
178  call.set_transition_length_if_supported(this->colors_[this->at_color_].transition_length);
179  call.perform();
180  this->last_switch_ = now;
181  }
182 
183  void set_colors(const std::vector<StrobeLightEffectColor> &colors) { this->colors_ = colors; }
184 
185  protected:
186  std::vector<StrobeLightEffectColor> colors_;
187  uint32_t last_switch_{0};
188  size_t at_color_{0};
189 };
190 
192  public:
193  explicit FlickerLightEffect(const std::string &name) : LightEffect(name) {}
194 
195  void apply() override {
196  LightColorValues remote = this->state_->remote_values;
197  LightColorValues current = this->state_->current_values;
198  LightColorValues out;
199  const float alpha = this->alpha_;
200  const float beta = 1.0f - alpha;
201  out.set_state(true);
202  out.set_brightness(remote.get_brightness() * beta + current.get_brightness() * alpha +
203  (random_cubic_float() * this->intensity_));
204  out.set_red(remote.get_red() * beta + current.get_red() * alpha + (random_cubic_float() * this->intensity_));
205  out.set_green(remote.get_green() * beta + current.get_green() * alpha + (random_cubic_float() * this->intensity_));
206  out.set_blue(remote.get_blue() * beta + current.get_blue() * alpha + (random_cubic_float() * this->intensity_));
207  out.set_white(remote.get_white() * beta + current.get_white() * alpha + (random_cubic_float() * this->intensity_));
208  out.set_cold_white(remote.get_cold_white() * beta + current.get_cold_white() * alpha +
209  (random_cubic_float() * this->intensity_));
210  out.set_warm_white(remote.get_warm_white() * beta + current.get_warm_white() * alpha +
211  (random_cubic_float() * this->intensity_));
212 
213  auto call = this->state_->make_call();
214  call.set_publish(false);
215  call.set_save(false);
217  call.from_light_color_values(out);
218  call.set_state(true);
219  call.perform();
220  }
221 
222  void set_alpha(float alpha) { this->alpha_ = alpha; }
223  void set_intensity(float intensity) { this->intensity_ = intensity; }
224 
225  protected:
226  float intensity_{};
227  float alpha_{};
228 };
229 
230 } // namespace light
231 } // 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: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: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.
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: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.
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: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:216
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)