From 3c1c19da1c572f3ad60efc272513045cdc99c732 Mon Sep 17 00:00:00 2001 From: "J. Nick Koston" Date: Fri, 28 Nov 2025 16:23:31 -0600 Subject: [PATCH] tweaks --- .../alarm_control_panel.cpp | 6 +- .../alarm_control_panel/alarm_control_panel.h | 35 +++++--- .../alarm_control_panel/automation.h | 81 +++++-------------- .../mqtt/mqtt_alarm_control_panel.h | 4 +- 4 files changed, 50 insertions(+), 76 deletions(-) diff --git a/esphome/components/alarm_control_panel/alarm_control_panel.cpp b/esphome/components/alarm_control_panel/alarm_control_panel.cpp index 585401028a..733d255158 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel.cpp +++ b/esphome/components/alarm_control_panel/alarm_control_panel.cpp @@ -36,7 +36,7 @@ void AlarmControlPanel::publish_state(AlarmControlPanelState state) { LOG_STR_ARG(alarm_control_panel_state_to_string(prev_state))); this->current_state_ = state; - for (auto *listener : this->listeners_) { + for (auto *listener : this->state_listeners_) { listener->on_state(state, prev_state); } @@ -52,12 +52,12 @@ void AlarmControlPanel::publish_state(AlarmControlPanelState state) { } void AlarmControlPanel::notify_chime() { - for (auto *listener : this->listeners_) + for (auto *listener : this->event_listeners_) listener->on_chime(); } void AlarmControlPanel::notify_ready() { - for (auto *listener : this->listeners_) + for (auto *listener : this->event_listeners_) listener->on_ready(); } diff --git a/esphome/components/alarm_control_panel/alarm_control_panel.h b/esphome/components/alarm_control_panel/alarm_control_panel.h index d9090e3c19..80d3906aa3 100644 --- a/esphome/components/alarm_control_panel/alarm_control_panel.h +++ b/esphome/components/alarm_control_panel/alarm_control_panel.h @@ -14,16 +14,21 @@ namespace esphome { namespace alarm_control_panel { -/// Listener interface for alarm control panel events. -/// Implement this interface and register with add_listener() to receive notifications. -class AlarmControlPanelListener { +/// Listener interface for alarm control panel state changes. +class AlarmControlPanelStateListener { public: - virtual ~AlarmControlPanelListener() = default; - /// Called when state changes. Check new_state to filter specific states. - virtual void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) {} + virtual ~AlarmControlPanelStateListener() = default; + /// Called when state changes. Check new_state/prev_state to filter specific states. + virtual void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) = 0; +}; + +/// Listener interface for alarm events (chime, ready, etc). +class AlarmControlPanelEventListener { + public: + virtual ~AlarmControlPanelEventListener() = default; /// Called when a chime zone opens while disarmed. virtual void on_chime() {} - /// Called when ready state changes. + /// Called when zones ready state changes. virtual void on_ready() {} }; @@ -50,11 +55,17 @@ class AlarmControlPanel : public EntityBase { */ void publish_state(AlarmControlPanelState state); - /** Register a listener for alarm control panel events. + /** Register a listener for state changes. * * @param listener The listener to add (must remain valid for lifetime of panel) */ - void add_listener(AlarmControlPanelListener *listener) { this->listeners_.push_back(listener); } + void add_listener(AlarmControlPanelStateListener *listener) { this->state_listeners_.push_back(listener); } + + /** Register a listener for alarm events (chime/ready/etc). + * + * @param listener The listener to add (must remain valid for lifetime of panel) + */ + void add_listener(AlarmControlPanelEventListener *listener) { this->event_listeners_.push_back(listener); } /** Notify listeners of a chime event (zone opened while disarmed). */ @@ -135,8 +146,10 @@ class AlarmControlPanel : public EntityBase { uint32_t last_update_; // the call control function virtual void control(const AlarmControlPanelCall &call) = 0; - // registered listeners - std::vector listeners_; + // registered state listeners + std::vector state_listeners_; + // registered event listeners (chime/ready/etc) + std::vector event_listeners_; }; } // namespace alarm_control_panel diff --git a/esphome/components/alarm_control_panel/automation.h b/esphome/components/alarm_control_panel/automation.h index 533f4892d1..19a3662e83 100644 --- a/esphome/components/alarm_control_panel/automation.h +++ b/esphome/components/alarm_control_panel/automation.h @@ -6,76 +6,35 @@ namespace esphome { namespace alarm_control_panel { -class StateTrigger final : public Trigger<>, public AlarmControlPanelListener { +/// Trigger on any state change +class StateTrigger final : public Trigger<>, public AlarmControlPanelStateListener { public: explicit StateTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { this->trigger(); } }; -class TriggeredTrigger final : public Trigger<>, public AlarmControlPanelListener { +/// Template trigger that fires when entering a specific state +template +class StateEnterTrigger final : public Trigger<>, public AlarmControlPanelStateListener { public: - explicit TriggeredTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } + explicit StateEnterTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { - if (new_state == ACP_STATE_TRIGGERED) + if (new_state == State) this->trigger(); } }; -class ArmingTrigger final : public Trigger<>, public AlarmControlPanelListener { - public: - explicit ArmingTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } - void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { - if (new_state == ACP_STATE_ARMING) - this->trigger(); - } -}; +// Type aliases for state-specific triggers +using TriggeredTrigger = StateEnterTrigger; +using ArmingTrigger = StateEnterTrigger; +using PendingTrigger = StateEnterTrigger; +using ArmedHomeTrigger = StateEnterTrigger; +using ArmedNightTrigger = StateEnterTrigger; +using ArmedAwayTrigger = StateEnterTrigger; +using DisarmedTrigger = StateEnterTrigger; -class PendingTrigger final : public Trigger<>, public AlarmControlPanelListener { - public: - explicit PendingTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } - void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { - if (new_state == ACP_STATE_PENDING) - this->trigger(); - } -}; - -class ArmedHomeTrigger final : public Trigger<>, public AlarmControlPanelListener { - public: - explicit ArmedHomeTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } - void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { - if (new_state == ACP_STATE_ARMED_HOME) - this->trigger(); - } -}; - -class ArmedNightTrigger final : public Trigger<>, public AlarmControlPanelListener { - public: - explicit ArmedNightTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } - void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { - if (new_state == ACP_STATE_ARMED_NIGHT) - this->trigger(); - } -}; - -class ArmedAwayTrigger final : public Trigger<>, public AlarmControlPanelListener { - public: - explicit ArmedAwayTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } - void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { - if (new_state == ACP_STATE_ARMED_AWAY) - this->trigger(); - } -}; - -class DisarmedTrigger final : public Trigger<>, public AlarmControlPanelListener { - public: - explicit DisarmedTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } - void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { - if (new_state == ACP_STATE_DISARMED) - this->trigger(); - } -}; - -class ClearedTrigger final : public Trigger<>, public AlarmControlPanelListener { +/// Trigger when leaving TRIGGERED state (alarm cleared) +class ClearedTrigger final : public Trigger<>, public AlarmControlPanelStateListener { public: explicit ClearedTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } void on_state(AlarmControlPanelState new_state, AlarmControlPanelState prev_state) override { @@ -84,13 +43,15 @@ class ClearedTrigger final : public Trigger<>, public AlarmControlPanelListener } }; -class ChimeTrigger final : public Trigger<>, public AlarmControlPanelListener { +/// Trigger on chime event (zone opened while disarmed) +class ChimeTrigger final : public Trigger<>, public AlarmControlPanelEventListener { public: explicit ChimeTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } void on_chime() override { this->trigger(); } }; -class ReadyTrigger final : public Trigger<>, public AlarmControlPanelListener { +/// Trigger on ready state change +class ReadyTrigger final : public Trigger<>, public AlarmControlPanelEventListener { public: explicit ReadyTrigger(AlarmControlPanel *alarm_control_panel) { alarm_control_panel->add_listener(this); } void on_ready() override { this->trigger(); } diff --git a/esphome/components/mqtt/mqtt_alarm_control_panel.h b/esphome/components/mqtt/mqtt_alarm_control_panel.h index 47d8610d0b..c64b8c575d 100644 --- a/esphome/components/mqtt/mqtt_alarm_control_panel.h +++ b/esphome/components/mqtt/mqtt_alarm_control_panel.h @@ -12,7 +12,7 @@ namespace esphome { namespace mqtt { class MQTTAlarmControlPanelComponent final : public mqtt::MQTTComponent, - public alarm_control_panel::AlarmControlPanelListener { + public alarm_control_panel::AlarmControlPanelStateListener { public: explicit MQTTAlarmControlPanelComponent(alarm_control_panel::AlarmControlPanel *alarm_control_panel); @@ -26,7 +26,7 @@ class MQTTAlarmControlPanelComponent final : public mqtt::MQTTComponent, void dump_config() override; - // AlarmControlPanelListener interface + // AlarmControlPanelStateListener interface void on_state(alarm_control_panel::AlarmControlPanelState new_state, alarm_control_panel::AlarmControlPanelState prev_state) override { this->publish_state();