ESPHome  2023.3.2
base_light_effects.h
Go to the documentation of this file.
1 #pragma once
2 
3 #include <utility>
4 #include <vector>
5 
6 #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_ ? 1.0 : 0.0;
29  call.set_brightness_if_supported(out);
30  this->on_ = !this->on_;
31  call.set_transition_length_if_supported(this->transition_length_);
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_length(uint32_t transition_length) { this->transition_length_ = transition_length; }
41 
42  void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
43 
44  protected:
45  bool on_ = false;
46  uint32_t last_color_change_{0};
47  uint32_t transition_length_{};
48  uint32_t update_interval_{};
49 };
50 
53  public:
54  explicit RandomLightEffect(const std::string &name) : LightEffect(name) {}
55 
56  void apply() override {
57  const uint32_t now = millis();
58  if (now - this->last_color_change_ < this->update_interval_) {
59  return;
60  }
61 
62  auto color_mode = this->state_->remote_values.get_color_mode();
63  auto call = this->state_->turn_on();
64  bool changed = false;
65  if (color_mode & ColorCapability::RGB) {
66  call.set_red(random_float());
67  call.set_green(random_float());
68  call.set_blue(random_float());
69  changed = true;
70  }
71  if (color_mode & ColorCapability::COLOR_TEMPERATURE) {
72  float min = this->state_->get_traits().get_min_mireds();
73  float max = this->state_->get_traits().get_max_mireds();
74  call.set_color_temperature(min + random_float() * (max - min));
75  changed = true;
76  }
77  if (color_mode & ColorCapability::COLD_WARM_WHITE) {
78  call.set_cold_white(random_float());
79  call.set_warm_white(random_float());
80  changed = true;
81  }
82  if (!changed) {
83  // only randomize brightness if there's no colored option available
84  call.set_brightness(random_float());
85  }
86  call.set_transition_length_if_supported(this->transition_length_);
87  call.set_publish(true);
88  call.set_save(false);
89  call.perform();
90 
91  this->last_color_change_ = now;
92  }
93 
94  void set_transition_length(uint32_t transition_length) { this->transition_length_ = transition_length; }
95 
96  void set_update_interval(uint32_t update_interval) { this->update_interval_ = update_interval; }
97 
98  protected:
99  uint32_t last_color_change_{0};
100  uint32_t transition_length_{};
101  uint32_t update_interval_{};
102 };
103 
105  public:
106  LambdaLightEffect(const std::string &name, std::function<void(bool initial_run)> f, uint32_t update_interval)
107  : LightEffect(name), f_(std::move(f)), update_interval_(update_interval) {}
108 
109  void start() override { this->initial_run_ = true; }
110  void apply() override {
111  const uint32_t now = millis();
112  if (now - this->last_run_ >= this->update_interval_) {
113  this->last_run_ = now;
114  this->f_(this->initial_run_);
115  this->initial_run_ = false;
116  }
117  }
118 
119  protected:
120  std::function<void(bool initial_run)> f_;
122  uint32_t last_run_{0};
124 };
125 
127  public:
128  AutomationLightEffect(const std::string &name) : LightEffect(name) {}
129  void stop() override { this->trig_->stop_action(); }
130  void apply() override {
131  if (!this->trig_->is_action_running()) {
132  this->trig_->trigger();
133  }
134  }
135  Trigger<> *get_trig() const { return trig_; }
136 
137  protected:
138  Trigger<> *trig_{new Trigger<>};
139 };
140 
143  uint32_t duration;
144 };
145 
147  public:
148  explicit StrobeLightEffect(const std::string &name) : LightEffect(name) {}
149  void apply() override {
150  const uint32_t now = millis();
151  if (now - this->last_switch_ < this->colors_[this->at_color_].duration)
152  return;
153 
154  // Switch to next color
155  this->at_color_ = (this->at_color_ + 1) % this->colors_.size();
156  auto color = this->colors_[this->at_color_].color;
157 
158  auto call = this->state_->turn_on();
159  call.from_light_color_values(this->colors_[this->at_color_].color);
160 
161  if (!color.is_on()) {
162  // Don't turn the light off, otherwise the light effect will be stopped
163  call.set_brightness(0.0f);
164  call.set_state(true);
165  }
166  call.set_publish(false);
167  call.set_save(false);
169  call.perform();
170  this->last_switch_ = now;
171  }
172 
173  void set_colors(const std::vector<StrobeLightEffectColor> &colors) { this->colors_ = colors; }
174 
175  protected:
176  std::vector<StrobeLightEffectColor> colors_;
177  uint32_t last_switch_{0};
178  size_t at_color_{0};
179 };
180 
182  public:
183  explicit FlickerLightEffect(const std::string &name) : LightEffect(name) {}
184 
185  void apply() override {
186  LightColorValues remote = this->state_->remote_values;
187  LightColorValues current = this->state_->current_values;
188  LightColorValues out;
189  const float alpha = this->alpha_;
190  const float beta = 1.0f - alpha;
191  out.set_state(true);
192  out.set_brightness(remote.get_brightness() * beta + current.get_brightness() * alpha +
193  (random_cubic_float() * this->intensity_));
194  out.set_red(remote.get_red() * beta + current.get_red() * alpha + (random_cubic_float() * this->intensity_));
195  out.set_green(remote.get_green() * beta + current.get_green() * alpha + (random_cubic_float() * this->intensity_));
196  out.set_blue(remote.get_blue() * beta + current.get_blue() * alpha + (random_cubic_float() * this->intensity_));
197  out.set_white(remote.get_white() * beta + current.get_white() * alpha + (random_cubic_float() * this->intensity_));
198  out.set_cold_white(remote.get_cold_white() * beta + current.get_cold_white() * alpha +
199  (random_cubic_float() * this->intensity_));
200  out.set_warm_white(remote.get_warm_white() * beta + current.get_warm_white() * alpha +
201  (random_cubic_float() * this->intensity_));
202 
203  auto call = this->state_->make_call();
204  call.set_publish(false);
205  call.set_save(false);
207  call.from_light_color_values(out);
208  call.set_state(true);
209  call.perform();
210  }
211 
212  void set_alpha(float alpha) { this->alpha_ = alpha; }
213  void set_intensity(float intensity) { this->intensity_ = intensity; }
214 
215  protected:
216  float intensity_{};
217  float alpha_{};
218 };
219 
220 } // namespace light
221 } // 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:68
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:80
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)