From 2b9e1ce315bc3bcdf865ce0f5097b0b97708e690 Mon Sep 17 00:00:00 2001 From: Edward Firmo <94725493+edwardtfn@users.noreply.github.com> Date: Sat, 9 Aug 2025 13:09:40 +0200 Subject: [PATCH] [switch] Add trigger ``on_state`` (#10108) --- esphome/components/switch/__init__.py | 12 ++++++++++++ esphome/components/switch/automation.h | 7 +++++++ tests/components/switch/common.yaml | 12 ++++++++++++ 3 files changed, 31 insertions(+) diff --git a/esphome/components/switch/__init__.py b/esphome/components/switch/__init__.py index 4668a1458c..f495dbc0b4 100644 --- a/esphome/components/switch/__init__.py +++ b/esphome/components/switch/__init__.py @@ -10,6 +10,7 @@ from esphome.const import ( CONF_ID, CONF_INVERTED, CONF_MQTT_ID, + CONF_ON_STATE, CONF_ON_TURN_OFF, CONF_ON_TURN_ON, CONF_RESTORE_MODE, @@ -56,6 +57,9 @@ TurnOnAction = switch_ns.class_("TurnOnAction", automation.Action) SwitchPublishAction = switch_ns.class_("SwitchPublishAction", automation.Action) SwitchCondition = switch_ns.class_("SwitchCondition", Condition) +SwitchStateTrigger = switch_ns.class_( + "SwitchStateTrigger", automation.Trigger.template(bool) +) SwitchTurnOnTrigger = switch_ns.class_( "SwitchTurnOnTrigger", automation.Trigger.template() ) @@ -77,6 +81,11 @@ _SWITCH_SCHEMA = ( cv.Optional(CONF_RESTORE_MODE, default="ALWAYS_OFF"): cv.enum( RESTORE_MODES, upper=True, space="_" ), + cv.Optional(CONF_ON_STATE): automation.validate_automation( + { + cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SwitchStateTrigger), + } + ), cv.Optional(CONF_ON_TURN_ON): automation.validate_automation( { cv.GenerateID(CONF_TRIGGER_ID): cv.declare_id(SwitchTurnOnTrigger), @@ -140,6 +149,9 @@ async def setup_switch_core_(var, config): if (inverted := config.get(CONF_INVERTED)) is not None: cg.add(var.set_inverted(inverted)) + for conf in config.get(CONF_ON_STATE, []): + trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) + await automation.build_automation(trigger, [(bool, "x")], conf) for conf in config.get(CONF_ON_TURN_ON, []): trigger = cg.new_Pvariable(conf[CONF_TRIGGER_ID], var) await automation.build_automation(trigger, [], conf) diff --git a/esphome/components/switch/automation.h b/esphome/components/switch/automation.h index 66818a80be..b8cbc9b976 100644 --- a/esphome/components/switch/automation.h +++ b/esphome/components/switch/automation.h @@ -64,6 +64,13 @@ template class SwitchCondition : public Condition { bool state_; }; +class SwitchStateTrigger : public Trigger { + public: + SwitchStateTrigger(Switch *a_switch) { + a_switch->add_on_state_callback([this](bool state) { this->trigger(state); }); + } +}; + class SwitchTurnOnTrigger : public Trigger<> { public: SwitchTurnOnTrigger(Switch *a_switch) { diff --git a/tests/components/switch/common.yaml b/tests/components/switch/common.yaml index b69e36a1c0..afdf26c150 100644 --- a/tests/components/switch/common.yaml +++ b/tests/components/switch/common.yaml @@ -9,6 +9,18 @@ switch: name: "Template Switch" id: the_switch optimistic: true + on_state: + - if: + condition: + - lambda: return x; + then: + - logger.log: "Switch turned ON" + else: + - logger.log: "Switch turned OFF" + on_turn_on: + - logger.log: "Switch is now ON" + on_turn_off: + - logger.log: "Switch is now OFF" esphome: on_boot: