From 31ae337931399922b5d5fd3bbdeb545533af263b Mon Sep 17 00:00:00 2001 From: Guillermo Ruffino Date: Sat, 25 Apr 2020 15:39:34 -0300 Subject: [PATCH] add lights on off triggers (#1037) * add lights on off triggers * add test --- esphome/components/light/__init__.py | 20 ++++++++++++++-- esphome/components/light/automation.h | 34 +++++++++++++++++++++++++++ esphome/components/light/types.py | 4 ++++ tests/test1.yaml | 8 +++++++ 4 files changed, 64 insertions(+), 2 deletions(-) diff --git a/esphome/components/light/__init__.py b/esphome/components/light/__init__.py index 63aac69462..2a44b044b9 100644 --- a/esphome/components/light/__init__.py +++ b/esphome/components/light/__init__.py @@ -1,15 +1,18 @@ import esphome.codegen as cg import esphome.config_validation as cv +import esphome.automation as auto from esphome.components import mqtt, power_supply from esphome.const import CONF_COLOR_CORRECT, \ CONF_DEFAULT_TRANSITION_LENGTH, CONF_EFFECTS, CONF_GAMMA_CORRECT, CONF_ID, \ - CONF_INTERNAL, CONF_NAME, CONF_MQTT_ID, CONF_POWER_SUPPLY, CONF_RESTORE_MODE + CONF_INTERNAL, CONF_NAME, CONF_MQTT_ID, CONF_POWER_SUPPLY, CONF_RESTORE_MODE, \ + CONF_ON_TURN_OFF, CONF_ON_TURN_ON, CONF_TRIGGER_ID from esphome.core import coroutine, coroutine_with_priority from .automation import light_control_to_code # noqa from .effects import validate_effects, BINARY_EFFECTS, \ MONOCHROMATIC_EFFECTS, RGB_EFFECTS, ADDRESSABLE_EFFECTS, EFFECTS_REGISTRY from .types import ( # noqa - LightState, AddressableLightState, light_ns, LightOutput, AddressableLight) + LightState, AddressableLightState, light_ns, LightOutput, AddressableLight, \ + LightTurnOnTrigger, LightTurnOffTrigger) IS_PLATFORM_COMPONENT = True @@ -26,6 +29,12 @@ LIGHT_SCHEMA = cv.MQTT_COMMAND_COMPONENT_SCHEMA.extend({ cv.OnlyWith(CONF_MQTT_ID, 'mqtt'): cv.declare_id(mqtt.MQTTJSONLightComponent), cv.Optional(CONF_RESTORE_MODE, default='restore_default_off'): cv.enum(RESTORE_MODES, upper=True, space='_'), + cv.Optional(CONF_ON_TURN_ON): auto.validate_automation({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LightTurnOnTrigger), + }), + cv.Optional(CONF_ON_TURN_OFF): auto.validate_automation({ + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(LightTurnOffTrigger), + }), }) BINARY_LIGHT_SCHEMA = LIGHT_SCHEMA.extend({ @@ -62,6 +71,13 @@ def setup_light_core_(light_var, output_var, config): effects = yield cg.build_registry_list(EFFECTS_REGISTRY, config.get(CONF_EFFECTS, [])) cg.add(light_var.add_effects(effects)) + for conf in config.get(CONF_ON_TURN_ON, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], light_var) + yield auto.build_automation(trigger, [], conf) + for conf in config.get(CONF_ON_TURN_OFF, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], light_var) + yield auto.build_automation(trigger, [], conf) + if CONF_COLOR_CORRECT in config: cg.add(output_var.set_correction(*config[CONF_COLOR_CORRECT])) diff --git a/esphome/components/light/automation.h b/esphome/components/light/automation.h index 2cd55ab6f6..dfab780658 100644 --- a/esphome/components/light/automation.h +++ b/esphome/components/light/automation.h @@ -98,6 +98,40 @@ template class LightIsOffCondition : public Condition { LightState *state_; }; +class LightTurnOnTrigger : public Trigger<> { + public: + LightTurnOnTrigger(LightState *a_light) { + a_light->add_new_remote_values_callback([this, a_light]() { + auto is_on = a_light->current_values.is_on(); + if (is_on && !last_on_) { + this->trigger(); + } + last_on_ = is_on; + }); + last_on_ = a_light->current_values.is_on(); + } + + protected: + bool last_on_; +}; + +class LightTurnOffTrigger : public Trigger<> { + public: + LightTurnOffTrigger(LightState *a_light) { + a_light->add_new_remote_values_callback([this, a_light]() { + auto is_on = a_light->current_values.is_on(); + if (!is_on && last_on_) { + this->trigger(); + } + last_on_ = is_on; + }); + last_on_ = a_light->current_values.is_on(); + } + + protected: + bool last_on_; +}; + template class AddressableSet : public Action { public: explicit AddressableSet(LightState *parent) : parent_(parent) {} diff --git a/esphome/components/light/types.py b/esphome/components/light/types.py index fb88d021f2..d32ef0214c 100644 --- a/esphome/components/light/types.py +++ b/esphome/components/light/types.py @@ -21,6 +21,10 @@ AddressableSet = light_ns.class_('AddressableSet', automation.Action) LightIsOnCondition = light_ns.class_('LightIsOnCondition', automation.Condition) LightIsOffCondition = light_ns.class_('LightIsOffCondition', automation.Condition) +# Triggers +LightTurnOnTrigger = light_ns.class_('LightTurnOnTrigger', automation.Trigger.template()) +LightTurnOffTrigger = light_ns.class_('LightTurnOffTrigger', automation.Trigger.template()) + # Effects LightEffect = light_ns.class_('LightEffect') RandomLightEffect = light_ns.class_('RandomLightEffect', LightEffect) diff --git a/tests/test1.yaml b/tests/test1.yaml index dbb3a4bdb3..59b64b0b6d 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -1044,6 +1044,14 @@ light: duration: 250ms - state: False duration: 250ms + on_turn_on: + - switch.template.publish: + id: livingroom_lights + state: yes + on_turn_off: + - switch.template.publish: + id: livingroom_lights + state: yes - platform: monochromatic name: "Kitchen Lights" id: kitchen