From 6e87f8eb4e350f4a7bbcb0d6dd6fc3c8d9d2b11e Mon Sep 17 00:00:00 2001 From: Kent Gibson Date: Fri, 20 Mar 2026 10:06:58 +0800 Subject: [PATCH] [template] alarm_control_panel collapse SensorDataStore and bypassed_sensor_indicies into SensorInfo (#14852) Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com> Co-authored-by: J. Nick Koston --- .../template_alarm_control_panel.cpp | 51 ++++++++++--------- .../template_alarm_control_panel.h | 24 ++++----- 2 files changed, 38 insertions(+), 37 deletions(-) diff --git a/esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp b/esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp index 651aa3c489..a224ab8459 100644 --- a/esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp +++ b/esphome/components/template/alarm_control_panel/template_alarm_control_panel.cpp @@ -16,17 +16,15 @@ static const char *const TAG = "template.alarm_control_panel"; TemplateAlarmControlPanel::TemplateAlarmControlPanel(){}; #ifdef USE_BINARY_SENSOR -void TemplateAlarmControlPanel::add_sensor(binary_sensor::BinarySensor *sensor, uint16_t flags, AlarmSensorType type) { - // Save the flags and type. Assign a store index for the per sensor data type. - SensorDataStore sd; - sd.last_chime_state = false; +void TemplateAlarmControlPanel::add_sensor(binary_sensor::BinarySensor *sensor, uint8_t flags, AlarmSensorType type) { + // Save the sensor pointer, flags, and type in the per-sensor info structure. AlarmSensor alarm_sensor; alarm_sensor.sensor = sensor; alarm_sensor.info.flags = flags; alarm_sensor.info.type = type; - alarm_sensor.info.store_index = this->next_store_index_++; + alarm_sensor.info.chime_active = false; + alarm_sensor.info.auto_bypassed = false; this->sensors_.push_back(alarm_sensor); - this->sensor_data_.push_back(sd); }; // Alarm sensor type strings indexed by AlarmSensorType enum (0-3): DELAYED, INSTANT, DELAYED_FOLLOWER, INSTANT_ALWAYS @@ -55,7 +53,7 @@ void TemplateAlarmControlPanel::dump_config() { (this->trigger_time_ / 1000), this->get_supported_features()); #ifdef USE_BINARY_SENSOR for (const auto &alarm_sensor : this->sensors_) { - const uint16_t flags = alarm_sensor.info.flags; + const uint8_t flags = alarm_sensor.info.flags; ESP_LOGCONFIG(TAG, " Binary Sensor:\n" " Name: %s\n" @@ -95,7 +93,7 @@ void TemplateAlarmControlPanel::loop() { delay = this->arming_night_time_; } if ((millis() - this->last_update_) > delay) { - this->bypass_before_arming(); + this->auto_bypass_sensors_(); this->publish_state(this->desired_state_); } return; @@ -117,26 +115,25 @@ void TemplateAlarmControlPanel::loop() { #ifdef USE_BINARY_SENSOR // Test all of the sensors regardless of the alarm panel state - for (const auto &alarm_sensor : this->sensors_) { - const auto &info = alarm_sensor.info; + for (auto &alarm_sensor : this->sensors_) { + auto &info = alarm_sensor.info; auto *sensor = alarm_sensor.sensor; // Check for chime zones if (info.flags & BINARY_SENSOR_MODE_CHIME) { // Look for the transition from closed to open - if ((!this->sensor_data_[info.store_index].last_chime_state) && (sensor->state)) { + if ((!info.chime_active) && (sensor->state)) { // Must be disarmed to chime if (this->current_state_ == ACP_STATE_DISARMED) { this->chime_callback_.call(); } } // Record the sensor state change - this->sensor_data_[info.store_index].last_chime_state = sensor->state; + info.chime_active = sensor->state; } // Check for faulted sensors if (sensor->state) { // Skip if auto bypassed - if (std::count(this->bypassed_sensor_indicies_.begin(), this->bypassed_sensor_indicies_.end(), - info.store_index) == 1) { + if (info.auto_bypassed) { continue; } // Skip if bypass armed home @@ -239,23 +236,33 @@ void TemplateAlarmControlPanel::arm_(optional code, alarm_control_p if (delay > 0) { this->publish_state(ACP_STATE_ARMING); } else { - this->bypass_before_arming(); + this->auto_bypass_sensors_(); this->publish_state(state); } } -void TemplateAlarmControlPanel::bypass_before_arming() { +void TemplateAlarmControlPanel::auto_bypass_sensors_() { #ifdef USE_BINARY_SENSOR - for (const auto &alarm_sensor : this->sensors_) { + for (auto &alarm_sensor : this->sensors_) { + auto &info = alarm_sensor.info; + auto *sensor = alarm_sensor.sensor; // Check for faulted bypass_auto sensors and remove them from monitoring - if ((alarm_sensor.info.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (alarm_sensor.sensor->state)) { - ESP_LOGW(TAG, "'%s' is faulted and will be automatically bypassed", alarm_sensor.sensor->get_name().c_str()); - this->bypassed_sensor_indicies_.push_back(alarm_sensor.info.store_index); + if ((info.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (sensor->state)) { + ESP_LOGW(TAG, "'%s' is faulted and will be automatically bypassed", sensor->get_name().c_str()); + info.auto_bypassed = true; } } #endif } +void TemplateAlarmControlPanel::clear_auto_bypassed_sensors_() { +#ifdef USE_BINARY_SENSOR + for (auto &alarm_sensor : this->sensors_) { + alarm_sensor.info.auto_bypassed = false; + } +#endif +} + void TemplateAlarmControlPanel::control(const AlarmControlPanelCall &call) { auto opt_state = call.get_state(); if (opt_state) { @@ -273,9 +280,7 @@ void TemplateAlarmControlPanel::control(const AlarmControlPanelCall &call) { } this->desired_state_ = ACP_STATE_DISARMED; this->publish_state(ACP_STATE_DISARMED); -#ifdef USE_BINARY_SENSOR - this->bypassed_sensor_indicies_.clear(); -#endif + this->clear_auto_bypassed_sensors_(); } else if (state == ACP_STATE_TRIGGERED) { this->publish_state(ACP_STATE_TRIGGERED); } else if (state == ACP_STATE_PENDING) { diff --git a/esphome/components/template/alarm_control_panel/template_alarm_control_panel.h b/esphome/components/template/alarm_control_panel/template_alarm_control_panel.h index 4f32e99fd7..57a99f2830 100644 --- a/esphome/components/template/alarm_control_panel/template_alarm_control_panel.h +++ b/esphome/components/template/alarm_control_panel/template_alarm_control_panel.h @@ -18,7 +18,7 @@ namespace esphome::template_ { #ifdef USE_BINARY_SENSOR -enum BinarySensorFlags : uint16_t { +enum BinarySensorFlags : uint8_t { BINARY_SENSOR_MODE_NORMAL = 1 << 0, BINARY_SENSOR_MODE_BYPASS_ARMED_HOME = 1 << 1, BINARY_SENSOR_MODE_BYPASS_ARMED_NIGHT = 1 << 2, @@ -41,14 +41,11 @@ enum TemplateAlarmControlPanelRestoreMode { }; #ifdef USE_BINARY_SENSOR -struct SensorDataStore { - bool last_chime_state; -}; - struct SensorInfo { - uint16_t flags; + uint8_t flags; AlarmSensorType type; - uint8_t store_index; + bool chime_active; + bool auto_bypassed; }; struct AlarmSensor { @@ -68,7 +65,9 @@ class TemplateAlarmControlPanel final : public alarm_control_panel::AlarmControl bool get_requires_code_to_arm() const override { return this->requires_code_to_arm_; } bool get_all_sensors_ready() { return this->sensors_ready_; }; void set_restore_mode(TemplateAlarmControlPanelRestoreMode restore_mode) { this->restore_mode_ = restore_mode; } - void bypass_before_arming(); + // Remove before 2026.10.0 + ESPDEPRECATED("bypass_before_arming() is deprecated and will be removed in 2026.10.0", "2026.4.0") + void bypass_before_arming() { this->auto_bypass_sensors_(); } #ifdef USE_BINARY_SENSOR /** Initialize the sensors vector with the specified capacity. @@ -83,7 +82,7 @@ class TemplateAlarmControlPanel final : public alarm_control_panel::AlarmControl * @param flags The OR of BinarySensorFlags for the sensor. * @param type The sensor type which determines its triggering behaviour. */ - void add_sensor(binary_sensor::BinarySensor *sensor, uint16_t flags = 0, + void add_sensor(binary_sensor::BinarySensor *sensor, uint8_t flags = 0, AlarmSensorType type = ALARM_SENSOR_TYPE_DELAYED); #endif @@ -141,11 +140,6 @@ class TemplateAlarmControlPanel final : public alarm_control_panel::AlarmControl #ifdef USE_BINARY_SENSOR // List of binary sensors with their alarm-specific info FixedVector sensors_; - // a list of automatically bypassed sensors - std::vector bypassed_sensor_indicies_; - // Per sensor data store - std::vector sensor_data_; - uint8_t next_store_index_ = 0; #endif TemplateAlarmControlPanelRestoreMode restore_mode_{}; @@ -170,6 +164,8 @@ class TemplateAlarmControlPanel final : public alarm_control_panel::AlarmControl bool is_code_valid_(optional code); void arm_(optional code, alarm_control_panel::AlarmControlPanelState state, uint32_t delay); + void auto_bypass_sensors_(); + void clear_auto_bypassed_sensors_(); }; } // namespace esphome::template_