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