diff --git a/esphome/components/cover/__init__.py b/esphome/components/cover/__init__.py index 137aaac872..0fd27f3f27 100644 --- a/esphome/components/cover/__init__.py +++ b/esphome/components/cover/__init__.py @@ -15,6 +15,7 @@ from esphome.const import ( CONF_TILT_STATE_TOPIC, CONF_STOP, CONF_MQTT_ID, + CONF_TRIGGER_ID, ) from esphome.core import CORE, coroutine_with_priority from esphome.cpp_helpers import setup_entity @@ -67,6 +68,15 @@ CoverPublishAction = cover_ns.class_("CoverPublishAction", automation.Action) CoverIsOpenCondition = cover_ns.class_("CoverIsOpenCondition", Condition) CoverIsClosedCondition = cover_ns.class_("CoverIsClosedCondition", Condition) +# Triggers +CoverOpenTrigger = cover_ns.class_("CoverOpenTrigger", automation.Trigger.template()) +CoverClosedTrigger = cover_ns.class_( + "CoverClosedTrigger", automation.Trigger.template() +) + +CONF_ON_OPEN = "on_open" +CONF_ON_CLOSED = "on_closed" + COVER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).extend( { cv.GenerateID(): cv.declare_id(Cover), @@ -84,6 +94,16 @@ COVER_SCHEMA = cv.ENTITY_BASE_SCHEMA.extend(cv.MQTT_COMMAND_COMPONENT_SCHEMA).ex cv.Optional(CONF_TILT_STATE_TOPIC): cv.All( cv.requires_component("mqtt"), cv.subscribe_topic ), + cv.Optional(CONF_ON_OPEN): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CoverOpenTrigger), + } + ), + cv.Optional(CONF_ON_CLOSED): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(CoverClosedTrigger), + } + ), } ) @@ -94,6 +114,13 @@ async def setup_cover_core_(var, config): if CONF_DEVICE_CLASS in config: cg.add(var.set_device_class(config[CONF_DEVICE_CLASS])) + for conf in config.get(CONF_ON_OPEN, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [], conf) + for conf in config.get(CONF_ON_CLOSED, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [], conf) + if CONF_MQTT_ID in config: mqtt_ = cg.new_Pvariable(config[CONF_MQTT_ID], var) await mqtt.register_mqtt_component(mqtt_, config) diff --git a/esphome/components/cover/automation.h b/esphome/components/cover/automation.h index 79bca6826e..6406ba52cb 100644 --- a/esphome/components/cover/automation.h +++ b/esphome/components/cover/automation.h @@ -99,6 +99,7 @@ template class CoverIsOpenCondition : public Condition { protected: Cover *cover_; }; + template class CoverIsClosedCondition : public Condition { public: CoverIsClosedCondition(Cover *cover) : cover_(cover) {} @@ -108,5 +109,27 @@ template class CoverIsClosedCondition : public Condition Cover *cover_; }; +class CoverOpenTrigger : public Trigger<> { + public: + CoverOpenTrigger(Cover *a_cover) { + a_cover->add_on_state_callback([this, a_cover]() { + if (a_cover->is_fully_open()) { + this->trigger(); + } + }); + } +}; + +class CoverClosedTrigger : public Trigger<> { + public: + CoverClosedTrigger(Cover *a_cover) { + a_cover->add_on_state_callback([this, a_cover]() { + if (a_cover->is_fully_closed()) { + this->trigger(); + } + }); + } +}; + } // namespace cover } // namespace esphome diff --git a/tests/test1.yaml b/tests/test1.yaml index 058da35d2c..130022c14d 100644 --- a/tests/test1.yaml +++ b/tests/test1.yaml @@ -2307,6 +2307,12 @@ cover: tilt_lambda: !lambda 'return 0.5;' tilt_state_topic: tilt/state/topic tilt_command_topic: tilt/command/topic + on_open: + then: + - lambda: 'ESP_LOGD("cover", "open");' + on_closed: + then: + - lambda: 'ESP_LOGD("cover", "closed");' - platform: am43 name: 'Test AM43' id: am43_test