From 90fc42e14151e64d8da652b298602ccf0d0a051f Mon Sep 17 00:00:00 2001 From: Maurice Makaay Date: Sun, 11 Apr 2021 03:23:15 +0200 Subject: [PATCH] Moved the last few light GPIO pins into the HUB comopnent. --- __init__.py | 90 +++++++++++++++++++++++--------------------- light/__init__.py | 8 ---- light/light_output.h | 22 ++--------- yeelight_bs2_hub.h | 5 +++ 4 files changed, 57 insertions(+), 68 deletions(-) diff --git a/__init__.py b/__init__.py index 1d57ba2..615376c 100644 --- a/__init__.py +++ b/__init__.py @@ -1,11 +1,10 @@ import esphome.codegen as cg import esphome.config_validation as cv from esphome import pins -from esphome.components import output from esphome.components.ledc.output import LEDCOutput, validate_frequency +from esphome.components.gpio.output import GPIOBinaryOutput from esphome.core import coroutine from esphome.core import CORE -from esphome.config import get_platform from esphome.const import ( CONF_ID, CONF_RED, @@ -17,7 +16,8 @@ from esphome.const import ( CONF_TRIGGER_ID, CONF_PIN, CONF_FREQUENCY, - CONF_CHANNEL + CONF_CHANNEL, + CONF_PLATFORM, ) CONF_HUB_ID = "yeelight_bs2_hub_id" @@ -33,18 +33,20 @@ CONF_ON_BRIGHTNESS = "on_brightness" CODEOWNERS = ["@mmakaay"] -AUTO_LOAD = ["ledc"] +AUTO_LOAD = ["ledc", "output"] yeelight_ns = cg.esphome_ns.namespace("yeelight") bs2_ns = yeelight_ns.namespace("bs2") YeelightBS2Hub = bs2_ns.class_("YeelightBS2Hub", cg.Component) -LEDC_PINS = { - # Config key ID PIN FREQ CH - CONF_RED : ( CONF_RED_ID, "GPIO13", 3000, 0 ), - CONF_GREEN : ( CONF_GREEN_ID, "GPIO14", 3000, 1 ), - CONF_BLUE : ( CONF_BLUE_ID, "GPIO5", 3000, 2 ), - CONF_WHITE : ( CONF_WHITE_ID, "GPIO12", 10000, 4 ), +PINS = { + # Config key TYPE, ID GPIO, PARAMS + CONF_RED : ( LEDCOutput, CONF_RED_ID, "GPIO13", 3000, 0 ), + CONF_GREEN : ( LEDCOutput, CONF_GREEN_ID, "GPIO14", 3000, 1 ), + CONF_BLUE : ( LEDCOutput, CONF_BLUE_ID, "GPIO5", 3000, 2 ), + CONF_WHITE : ( LEDCOutput, CONF_WHITE_ID, "GPIO12", 10000, 4 ), + CONF_MASTER1 : ( GPIOBinaryOutput, CONF_MASTER1_ID, "GPIO33" ), + CONF_MASTER2 : ( GPIOBinaryOutput, CONF_MASTER2_ID, "GPIO4" ), } def make_config_schema(): @@ -56,10 +58,10 @@ def make_config_schema(): ), }) - for key, pin_config in LEDC_PINS.items(): - id_, pin, *_ = pin_config + for key, pin_config in PINS.items(): + type_, id_, pin, *_ = pin_config schema = schema.extend({ - cv.GenerateID(id_): cv.declare_id(LEDCOutput), + cv.GenerateID(id_): cv.declare_id(type_), cv.Optional(key, default=pin): pins.validate_gpio_pin }) @@ -69,25 +71,47 @@ def make_config_schema(): CONFIG_SCHEMA = make_config_schema() @coroutine -def make_ledc_pin(key, config): - id_, _, frequency, channel = LEDC_PINS[key] - gpio_var = yield cg.gpio_pin_expression({ +def make_gpio_pin(key, config): + type_, id_, *_ = PINS[key] + yield from cg.gpio_pin_expression({ "number": config[key], "mode": "OUTPUT" }); + +@coroutine +def make_gpio_binary_output(key, config, gpio_var): + type_, id_, *_ = PINS[key] + output_var = cg.new_Pvariable(config[id_]) + cg.add(output_var.set_pin(gpio_var)) + yield from cg.register_component(output_var, {}) + +@coroutine +def make_ledc_output(key, config, gpio_var): + type_, id_, _, frequency, channel = PINS[key] ledc_var = cg.new_Pvariable(config[id_], gpio_var) cg.add(ledc_var.set_frequency(frequency)); cg.add(ledc_var.set_channel(channel)); - yield from cg.register_component(ledc_var, {}) # TODO last arg? + yield from cg.register_component(ledc_var, {}) def to_code(config): + # Dirty little hack to make the ESPHome component loader inlcude + # the code for the "gpio" platform for the "output" domain. + # Loading specific platform components is not possible using + # the AUTO_LOAD feature unfortunately. + CORE.config["output"].append({ CONF_PLATFORM: "gpio" }) + hub_var = cg.new_Pvariable(config[CONF_ID]) yield cg.register_component(hub_var, config) - for key in LEDC_PINS: - ledc_pin = yield make_ledc_pin(key, config) + for key in PINS: + type_ = PINS[key][0] + gpio_var = yield make_gpio_pin(key, config) + if type_ == LEDCOutput: + pin_var = yield make_ledc_output(key, config, gpio_var) + if type_ == GPIOBinaryOutput: + pin_var = yield make_gpio_binary_output(key, config, gpio_var) setter = getattr(hub_var, "set_%s_pin" % key) - cg.add(setter(ledc_pin)) + cg.add(setter(pin_var)) trigger_pin = yield cg.gpio_pin_expression({ "number": config[CONF_TRIGGER_PIN], @@ -95,25 +119,7 @@ def to_code(config): "inverted": False }) cg.add(hub_var.set_trigger_pin(trigger_pin)) -# -# led_white = yield cg.get_variable(config[CONF_WHITE]) -# cg.add(var.set_white_output(led_white)) -# -# led_red = yield cg.get_variable(config[CONF_RED]) -# cg.add(var.set_red_output(led_red)) -# -# led_green = yield cg.get_variable(config[CONF_GREEN]) -# cg.add(var.set_green_output(led_green)) -# -# led_blue = yield cg.get_variable(config[CONF_BLUE]) -# cg.add(var.set_blue_output(led_blue)) -# -# master1 = yield cg.get_variable(config[CONF_MASTER1]) -# cg.add(var.set_master1_output(master1)) -# -# 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) + + 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/__init__.py b/light/__init__.py index 87d9be3..ac5e05e 100644 --- a/light/__init__.py +++ b/light/__init__.py @@ -22,8 +22,6 @@ CONFIG_SCHEMA = light.RGB_LIGHT_SCHEMA.extend( cv.GenerateID(): cv.declare_id(light_state), cv.GenerateID(CONF_HUB_ID): cv.use_id(YeelightBS2Hub), cv.GenerateID(CONF_OUTPUT_ID): cv.declare_id(light_output), - 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), @@ -39,12 +37,6 @@ def to_code(config): hub_var = yield cg.get_variable(config[CONF_HUB_ID]) cg.add(var.set_hub(hub_var)) - master1 = yield cg.get_variable(config[CONF_MASTER1]) - cg.add(var.set_master1_output(master1)) - - 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/light_output.h b/light/light_output.h index 9c75560..2a4d3ce 100644 --- a/light/light_output.h +++ b/light/light_output.h @@ -23,18 +23,6 @@ public: /** Sets the Yeelight BS2 hub component. */ void set_hub(YeelightBS2Hub *hub) { hub_ = hub; } - /** - * Sets the first GPIO binary output, used as internal master switch for - * the LED light circuitry. - */ - void set_master1_output(gpio::GPIOBinaryOutput *master1) { master1_ = master1; } - - /** - * Set the second GPIO binary output, used as internal master switch for - * the LED light circuitry. - */ - void set_master2_output(gpio::GPIOBinaryOutput *master2) { master2_ = master2; } - /** * Returns a LightTraits object, which is used to explain to the outside * world (e.g. Home Assistant) what features are supported by this device. @@ -82,8 +70,8 @@ public: // that's why these GPIOs are turned on at this point. if (values.get_state() != 0) { - master2_->turn_on(); - master1_->turn_on(); + hub_->master2->turn_on(); + hub_->master1->turn_on(); } // Apply the current GPIO output levels from the selected handler. @@ -94,8 +82,8 @@ public: if (values.get_state() == 0) { - master2_->turn_off(); - master1_->turn_off(); + hub_->master2->turn_off(); + hub_->master1->turn_off(); } this->state_callback_.call(values); @@ -103,8 +91,6 @@ public: protected: YeelightBS2Hub *hub_; - esphome::gpio::GPIOBinaryOutput *master1_; - esphome::gpio::GPIOBinaryOutput *master2_; GPIOOutputs *transition_handler_; GPIOOutputs *instant_handler_ = new ColorInstantHandler(); CallbackManager state_callback_{}; diff --git a/yeelight_bs2_hub.h b/yeelight_bs2_hub.h index 176b0d0..b3f8d32 100644 --- a/yeelight_bs2_hub.h +++ b/yeelight_bs2_hub.h @@ -4,6 +4,7 @@ #include "esphome/core/component.h" #include "esphome/core/esphal.h" #include "esphome/components/ledc/ledc_output.h" +#include "esphome/components/gpio/output/gpio_binary_output.h" namespace esphome { namespace yeelight { @@ -34,12 +35,16 @@ public: ledc::LEDCOutput *green; ledc::LEDCOutput *blue; ledc::LEDCOutput *white; + gpio::GPIOBinaryOutput *master1; + gpio::GPIOBinaryOutput *master2; void set_trigger_pin(GPIOPin *pin) { i2c_trigger_pin_ = pin; } void set_red_pin(ledc::LEDCOutput *pin) { red = pin; } void set_green_pin(ledc::LEDCOutput *pin) { green = pin; } void set_blue_pin(ledc::LEDCOutput *pin) { blue = pin; } void set_white_pin(ledc::LEDCOutput *pin) { white = pin; } + void set_master1_pin(gpio::GPIOBinaryOutput *pin) { master1 = pin; } + void set_master2_pin(gpio::GPIOBinaryOutput *pin) { master2 = pin; } void setup() { ESP_LOGCONFIG(TAG, "Setting up I2C trigger pin interrupt...");