[template] alarm_control_panel collapse SensorDataStore and bypassed_sensor_indicies into SensorInfo (#14852)
Some checks failed
CI / Create common environment (push) Has been cancelled
CI / Check pylint (push) Has been cancelled
CI / Run script/ci-custom (push) Has been cancelled
CI / Run pytest (macOS-latest, 3.11) (push) Has been cancelled
CI / Run pytest (macOS-latest, 3.14) (push) Has been cancelled
CI / Run pytest (ubuntu-latest, 3.11) (push) Has been cancelled
CI / Run pytest (ubuntu-latest, 3.13) (push) Has been cancelled
CI / Run pytest (ubuntu-latest, 3.14) (push) Has been cancelled
CI / Run pytest (windows-latest, 3.11) (push) Has been cancelled
CI / Run pytest (windows-latest, 3.14) (push) Has been cancelled
CI / Determine which jobs to run (push) Has been cancelled
CI / Run integration tests (push) Has been cancelled
CI / Run C++ unit tests (push) Has been cancelled
CI / Run CodSpeed benchmarks (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 IDF (push) Has been cancelled
CI / Run script/clang-tidy for ESP8266 (push) Has been cancelled
CI / Run script/clang-tidy for ZEPHYR (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 1/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 2/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 3/4 (push) Has been cancelled
CI / Run script/clang-tidy for ESP32 Arduino 4/4 (push) Has been cancelled
CI / Test components batch (${{ matrix.components }}) (push) Has been cancelled
CI / pre-commit.ci lite (push) Has been cancelled
CI / Build target branch for memory impact (push) Has been cancelled
CI / Build PR branch for memory impact (push) Has been cancelled
CI / Comment memory impact (push) Has been cancelled
CI / CI Status (push) Has been cancelled
CI for docker images / Build docker containers (docker, ubuntu-24.04) (push) Has been cancelled
CI for docker images / Build docker containers (docker, ubuntu-24.04-arm) (push) Has been cancelled
CI for docker images / Build docker containers (ha-addon, ubuntu-24.04) (push) Has been cancelled
CI for docker images / Build docker containers (ha-addon, ubuntu-24.04-arm) (push) Has been cancelled
Synchronise Device Classes from Home Assistant / Sync Device Classes (push) Has been cancelled

Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: J. Nick Koston <nick@koston.org>
This commit is contained in:
Kent Gibson
2026-03-20 10:06:58 +08:00
committed by GitHub
parent 7df550f2a9
commit 6e87f8eb4e
2 changed files with 38 additions and 37 deletions

View File

@@ -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<std::string> 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) {

View File

@@ -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<AlarmSensor> sensors_;
// a list of automatically bypassed sensors
std::vector<uint8_t> bypassed_sensor_indicies_;
// Per sensor data store
std::vector<SensorDataStore> 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<std::string> code);
void arm_(optional<std::string> code, alarm_control_panel::AlarmControlPanelState state, uint32_t delay);
void auto_bypass_sensors_();
void clear_auto_bypassed_sensors_();
};
} // namespace esphome::template_