ESPHome  2023.5.5
e131_addressable_light_effect.cpp
Go to the documentation of this file.
1 #ifdef USE_ARDUINO
2 
3 #include "e131.h"
5 #include "esphome/core/log.h"
6 
7 namespace esphome {
8 namespace e131 {
9 
10 static const char *const TAG = "e131_addressable_light_effect";
11 static const int MAX_DATA_SIZE = (sizeof(E131Packet::values) - 1);
12 
13 E131AddressableLightEffect::E131AddressableLightEffect(const std::string &name) : AddressableLightEffect(name) {}
14 
16 
17 int E131AddressableLightEffect::get_lights_per_universe() const { return MAX_DATA_SIZE / channels_; }
18 
20 
22 
24  // Round up to lights_per_universe
25  auto lights = get_lights_per_universe();
26  return (get_addressable_()->size() + lights - 1) / lights;
27 }
28 
30  AddressableLightEffect::start();
31 
32  if (this->e131_) {
33  this->e131_->add_effect(this);
34  }
35 }
36 
38  if (this->e131_) {
39  this->e131_->remove_effect(this);
40  }
41 
42  AddressableLightEffect::stop();
43 }
44 
46  // ignore, it is run by `E131Component::update()`
47 }
48 
50  auto *it = get_addressable_();
51 
52  // check if this is our universe and data are valid
53  if (universe < first_universe_ || universe > get_last_universe())
54  return false;
55 
56  int output_offset = (universe - first_universe_) * get_lights_per_universe();
57  // limit amount of lights per universe and received
58  int output_end =
59  std::min(it->size(), std::min(output_offset + get_lights_per_universe(), output_offset + packet.count - 1));
60  auto *input_data = packet.values + 1;
61 
62  ESP_LOGV(TAG, "Applying data for '%s' on %d universe, for %d-%d.", get_name().c_str(), universe, output_offset,
63  output_end);
64 
65  switch (channels_) {
66  case E131_MONO:
67  for (; output_offset < output_end; output_offset++, input_data++) {
68  auto output = (*it)[output_offset];
69  output.set(Color(input_data[0], input_data[0], input_data[0], input_data[0]));
70  }
71  break;
72 
73  case E131_RGB:
74  for (; output_offset < output_end; output_offset++, input_data += 3) {
75  auto output = (*it)[output_offset];
76  output.set(
77  Color(input_data[0], input_data[1], input_data[2], (input_data[0] + input_data[1] + input_data[2]) / 3));
78  }
79  break;
80 
81  case E131_RGBW:
82  for (; output_offset < output_end; output_offset++, input_data += 4) {
83  auto output = (*it)[output_offset];
84  output.set(Color(input_data[0], input_data[1], input_data[2], input_data[3]));
85  }
86  break;
87  }
88 
89  it->schedule_show();
90  return true;
91 }
92 
93 } // namespace e131
94 } // namespace esphome
95 
96 #endif // USE_ARDUINO
const char * name
Definition: stm32flash.h:78
bool process_(int universe, const E131Packet &packet)
uint8_t values[E131_MAX_PROPERTY_VALUES_COUNT]
Definition: e131.h:25
uint16_t universe
const std::string & get_name()
Definition: light_effect.h:27
void add_effect(E131AddressableLightEffect *light_effect)
Definition: e131.cpp:65
void remove_effect(E131AddressableLightEffect *light_effect)
Definition: e131.cpp:80
Definition: a4988.cpp:4