diff --git a/light/__init__.py b/light/__init__.py index a004859..8b06010 100644 --- a/light/__init__.py +++ b/light/__init__.py @@ -2,27 +2,39 @@ import esphome.codegen as cg import esphome.config_validation as cv import esphome.components.gpio.output as gpio_output from esphome.components import light, gpio, ledc -from esphome.const import CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_OUTPUT_ID +from esphome.const import CONF_RED, CONF_GREEN, CONF_BLUE, CONF_WHITE, CONF_OUTPUT_ID, CONF_TRIGGER_ID +from esphome import automation CONF_MASTER1 = "master1" CONF_MASTER2 = "master2" +CONF_ON_BRIGHTNESS = "on_brightness" yeelight_ns = cg.esphome_ns.namespace("yeelight") bs2_ns = yeelight_ns.namespace("bs2") light_state = bs2_ns.class_("YeelightBS2LightState", cg.Nameable, cg.Component) light_output = bs2_ns.class_("YeelightBS2LightOutput", light.LightOutput) -CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend({ - cv.GenerateID(): cv.declare_id(light_state), - cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(light_output), - cv.Required(CONF_RED): cv.use_id(ledc), - cv.Required(CONF_GREEN): cv.use_id(ledc), - cv.Required(CONF_BLUE): cv.use_id(ledc), - cv.Required(CONF_WHITE): cv.use_id(ledc), - cv.Required(CONF_WHITE): cv.use_id(ledc), - cv.Required(CONF_MASTER1): cv.use_id(gpio_output.GPIOBinaryOutput), - cv.Required(CONF_MASTER2): cv.use_id(gpio_output.GPIOBinaryOutput), -}) +BrightnessTrigger = bs2_ns.class_("BrightnessTrigger", automation.Trigger.template()) + +CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend( + { + cv.GenerateID(): cv.declare_id(light_state), + cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(light_output), + cv.Required(CONF_RED): cv.use_id(ledc), + cv.Required(CONF_GREEN): cv.use_id(ledc), + cv.Required(CONF_BLUE): cv.use_id(ledc), + cv.Required(CONF_WHITE): cv.use_id(ledc), + cv.Required(CONF_WHITE): cv.use_id(ledc), + cv.Required(CONF_MASTER1): cv.use_id(gpio_output.GPIOBinaryOutput), + cv.Required(CONF_MASTER2): cv.use_id(gpio_output.GPIOBinaryOutput), + + cv.Optional(CONF_ON_BRIGHTNESS): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(BrightnessTrigger), + } + ), + } +) def to_code(config): var = cg.new_Pvariable(config[CONF_OUTPUT_ID]) @@ -45,3 +57,7 @@ def to_code(config): master2 = yield cg.get_variable(config[CONF_MASTER2]) cg.add(var.set_master2_output(master2)) + + for conf in config.get(CONF_ON_BRIGHTNESS, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + yield automation.build_automation(trigger, [(float, "x")], conf) diff --git a/light/automation.h b/light/automation.h new file mode 100644 index 0000000..fc5fb17 --- /dev/null +++ b/light/automation.h @@ -0,0 +1,30 @@ +#pragma once + +#include +#include "esphome/core/component.h" +#include "esphome/core/automation.h" +#include "light_output.h" + +namespace esphome { +namespace yeelight { +namespace bs2 { + +class BrightnessTrigger : public Trigger { +public: + explicit BrightnessTrigger(YeelightBS2LightOutput *parent) { + parent->add_on_state_callback([this](light::LightColorValues values) { + auto new_brightness = values.get_state() == 0 ? 0.0f : values.get_brightness(); + new_brightness = roundf(new_brightness * 100.0f) / 100.0f; + if (last_brightness_ != new_brightness) { + this->trigger(new_brightness); + last_brightness_ = new_brightness; + } + }); + } +protected: + float last_brightness_ = -1.0f; +}; + +} // namespace yeelight_bs2 +} // namespace yeelight +} // namespace bs2 diff --git a/light/light.h b/light/light_output.h similarity index 95% rename from light/light.h rename to light/light_output.h index 3b8de4f..8cf78bb 100644 --- a/light/light.h +++ b/light/light_output.h @@ -59,6 +59,10 @@ public: return traits; } + void add_on_state_callback(std::function &&callback) { + this->state_callback_.add(std::move(callback)); + } + /** * Applies a requested light state to the physicial GPIO outputs. */ @@ -100,6 +104,8 @@ public: master2_->turn_off(); master1_->turn_off(); } + + this->state_callback_.call(values); } protected: @@ -111,6 +117,7 @@ protected: esphome::gpio::GPIOBinaryOutput *master2_; GPIOOutputs *transition_handler_; GPIOOutputs *instant_handler_ = new ColorInstantHandler(); + CallbackManager state_callback_{}; friend class YeelightBS2LightState;