Skip to content

Instantly share code, notes, and snippets.

@brandond
Last active January 14, 2020 07:52
Show Gist options
  • Save brandond/63dc9590465a095a478ae873780510d0 to your computer and use it in GitHub Desktop.
Save brandond/63dc9590465a095a478ae873780510d0 to your computer and use it in GitHub Desktop.
ESPHome Addressable Light Groups
#include "esphome/core/component.h"
#include "esphome/components/light/addressable_light.h"
namespace esphome {
namespace panel {
static const char *TAG = "panel.light";
class AddressablePanel;
class PanelLightOutput;
class AddressablePanel {
public:
AddressablePanel(light::LightState *src, int32_t height, int32_t width, int32_t rows, int32_t cols)
: src_(static_cast<light::AddressableLight *>(src->get_output())),
height_(height),
width_(width),
rows_(rows),
cols_(cols) {}
light::AddressableLight *get_src() const {
return this->src_;
}
int32_t get_size() const {
return this->rows_ * this->cols_;
}
void apply(const light::ESPColorCorrection *color_correction) {
for (int index = 0; index < this->get_size(); index++) {
int32_t base_index = this->base_index(index);
auto base_view = this->src_->get(base_index);
base_view.raw_set_color_correction(color_correction);
auto base_color = base_view.get();
for (int32_t i = 0; i < this->height_; i++) {
for (int32_t j = 0; j < this->width_; j++) {
int32_t src_index = base_index + j + (i * this->width_ * this->cols_);
if (src_index != base_index) {
auto src_view = this->src_->get(src_index);
src_view.raw_set_color_correction(color_correction);
src_view.set(base_color);
}
}
}
}
}
int32_t HOT base_index(uint32_t index) const {
return this->width_ * (this->height_ * this->cols_ * (index / this->cols_) + (index % this->cols_));
}
protected:
light::AddressableLight *src_;
int32_t height_;
int32_t width_;
int32_t rows_;
int32_t cols_;
};
class PanelLightOutput : public light::AddressableLight {
public:
PanelLightOutput(const AddressablePanel &panel) : panel_(panel) {}
int32_t size() const override {
return this->panel_.get_size();
}
void clear_effect_data() override {
return this->panel_.get_src()->clear_effect_data();
}
LightTraits get_traits() override {
return this->panel_.get_src()->get_traits();
}
void loop() override {
if (this->should_show_()) {
this->panel_.apply(&this->correction_);
this->panel_.get_src()->schedule_show();
this->mark_shown_();
}
}
protected:
light::ESPColorView get_view_internal(int32_t index) const override {
index = this->panel_.base_index(index);
auto view = this->panel_.get_src()->get(index);
view.raw_set_color_correction(&this->correction_);
return view;
}
AddressablePanel panel_;
};
} // namespace panel
} // namespace esphome
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment