1
0
mirror of https://github.com/esphome/esphome.git synced 2025-11-01 23:51:47 +00:00

template_alarm_control_panel cleanups (#11469)

This commit is contained in:
Kent Gibson
2025-10-29 08:48:26 +08:00
committed by GitHub
parent 249cd7415b
commit 4f2d54be4e
2 changed files with 33 additions and 43 deletions

View File

@@ -80,19 +80,12 @@ void TemplateAlarmControlPanel::dump_config() {
} }
void TemplateAlarmControlPanel::setup() { void TemplateAlarmControlPanel::setup() {
switch (this->restore_mode_) {
case ALARM_CONTROL_PANEL_ALWAYS_DISARMED:
this->current_state_ = ACP_STATE_DISARMED; this->current_state_ = ACP_STATE_DISARMED;
break; if (this->restore_mode_ == ALARM_CONTROL_PANEL_RESTORE_DEFAULT_DISARMED) {
case ALARM_CONTROL_PANEL_RESTORE_DEFAULT_DISARMED: {
uint8_t value; uint8_t value;
this->pref_ = global_preferences->make_preference<uint8_t>(this->get_preference_hash()); this->pref_ = global_preferences->make_preference<uint8_t>(this->get_preference_hash());
if (this->pref_.load(&value)) { if (this->pref_.load(&value)) {
this->current_state_ = static_cast<alarm_control_panel::AlarmControlPanelState>(value); this->current_state_ = static_cast<alarm_control_panel::AlarmControlPanelState>(value);
} else {
this->current_state_ = ACP_STATE_DISARMED;
}
break;
} }
} }
this->desired_state_ = this->current_state_; this->desired_state_ = this->current_state_;
@@ -119,15 +112,15 @@ void TemplateAlarmControlPanel::loop() {
this->publish_state(ACP_STATE_TRIGGERED); this->publish_state(ACP_STATE_TRIGGERED);
return; return;
} }
auto future_state = this->current_state_; auto next_state = this->current_state_;
// reset triggered if all clear // reset triggered if all clear
if (this->current_state_ == ACP_STATE_TRIGGERED && this->trigger_time_ > 0 && if (this->current_state_ == ACP_STATE_TRIGGERED && this->trigger_time_ > 0 &&
(millis() - this->last_update_) > this->trigger_time_) { (millis() - this->last_update_) > this->trigger_time_) {
future_state = this->desired_state_; next_state = this->desired_state_;
} }
bool delayed_sensor_not_ready = false; bool delayed_sensor_faulted = false;
bool instant_sensor_not_ready = false; bool instant_sensor_faulted = false;
#ifdef USE_BINARY_SENSOR #ifdef USE_BINARY_SENSOR
// Test all of the sensors in the list regardless of the alarm panel state // Test all of the sensors in the list regardless of the alarm panel state
@@ -144,7 +137,7 @@ void TemplateAlarmControlPanel::loop() {
// Record the sensor state change // Record the sensor state change
this->sensor_data_[sensor_info.second.store_index].last_chime_state = sensor_info.first->state; this->sensor_data_[sensor_info.second.store_index].last_chime_state = sensor_info.first->state;
} }
// Check for triggered sensors // Check for faulted sensors
if (sensor_info.first->state) { // Sensor triggered? if (sensor_info.first->state) { // Sensor triggered?
// Skip if auto bypassed // Skip if auto bypassed
if (std::count(this->bypassed_sensor_indicies_.begin(), this->bypassed_sensor_indicies_.end(), if (std::count(this->bypassed_sensor_indicies_.begin(), this->bypassed_sensor_indicies_.end(),
@@ -163,42 +156,41 @@ void TemplateAlarmControlPanel::loop() {
} }
switch (sensor_info.second.type) { switch (sensor_info.second.type) {
case ALARM_SENSOR_TYPE_INSTANT:
instant_sensor_not_ready = true;
break;
case ALARM_SENSOR_TYPE_INSTANT_ALWAYS: case ALARM_SENSOR_TYPE_INSTANT_ALWAYS:
instant_sensor_not_ready = true; next_state = ACP_STATE_TRIGGERED;
future_state = ACP_STATE_TRIGGERED; [[fallthrough]];
case ALARM_SENSOR_TYPE_INSTANT:
instant_sensor_faulted = true;
break; break;
case ALARM_SENSOR_TYPE_DELAYED_FOLLOWER: case ALARM_SENSOR_TYPE_DELAYED_FOLLOWER:
// Look to see if we are in the pending state // Look to see if we are in the pending state
if (this->current_state_ == ACP_STATE_PENDING) { if (this->current_state_ == ACP_STATE_PENDING) {
delayed_sensor_not_ready = true; delayed_sensor_faulted = true;
} else { } else {
instant_sensor_not_ready = true; instant_sensor_faulted = true;
} }
break; break;
case ALARM_SENSOR_TYPE_DELAYED: case ALARM_SENSOR_TYPE_DELAYED:
default: default:
delayed_sensor_not_ready = true; delayed_sensor_faulted = true;
} }
} }
} }
// Update all sensors not ready flag // Update all sensors ready flag
this->sensors_ready_ = ((!instant_sensor_not_ready) && (!delayed_sensor_not_ready)); bool sensors_ready = !(instant_sensor_faulted || delayed_sensor_faulted);
// Call the ready state change callback if there was a change // Call the ready state change callback if there was a change
if (this->sensors_ready_ != this->sensors_ready_last_) { if (this->sensors_ready_ != sensors_ready) {
this->sensors_ready_ = sensors_ready;
this->ready_callback_.call(); this->ready_callback_.call();
this->sensors_ready_last_ = this->sensors_ready_;
} }
#endif #endif
if (this->is_state_armed(future_state) && (!this->sensors_ready_)) { if (this->is_state_armed(next_state) && (!this->sensors_ready_)) {
// Instant sensors // Instant sensors
if (instant_sensor_not_ready) { if (instant_sensor_faulted) {
this->publish_state(ACP_STATE_TRIGGERED); this->publish_state(ACP_STATE_TRIGGERED);
} else if (delayed_sensor_not_ready) { } else if (delayed_sensor_faulted) {
// Delayed sensors // Delayed sensors
if ((this->pending_time_ > 0) && (this->current_state_ != ACP_STATE_TRIGGERED)) { if ((this->pending_time_ > 0) && (this->current_state_ != ACP_STATE_TRIGGERED)) {
this->publish_state(ACP_STATE_PENDING); this->publish_state(ACP_STATE_PENDING);
@@ -206,8 +198,8 @@ void TemplateAlarmControlPanel::loop() {
this->publish_state(ACP_STATE_TRIGGERED); this->publish_state(ACP_STATE_TRIGGERED);
} }
} }
} else if (future_state != this->current_state_) { } else if (next_state != this->current_state_) {
this->publish_state(future_state); this->publish_state(next_state);
} }
} }
@@ -234,8 +226,6 @@ uint32_t TemplateAlarmControlPanel::get_supported_features() const {
return features; return features;
} }
bool TemplateAlarmControlPanel::get_requires_code() const { return !this->codes_.empty(); }
void TemplateAlarmControlPanel::arm_(optional<std::string> code, alarm_control_panel::AlarmControlPanelState state, void TemplateAlarmControlPanel::arm_(optional<std::string> code, alarm_control_panel::AlarmControlPanelState state,
uint32_t delay) { uint32_t delay) {
if (this->current_state_ != ACP_STATE_DISARMED) { if (this->current_state_ != ACP_STATE_DISARMED) {
@@ -258,9 +248,9 @@ void TemplateAlarmControlPanel::arm_(optional<std::string> code, alarm_control_p
void TemplateAlarmControlPanel::bypass_before_arming() { void TemplateAlarmControlPanel::bypass_before_arming() {
#ifdef USE_BINARY_SENSOR #ifdef USE_BINARY_SENSOR
for (auto sensor_info : this->sensor_map_) { for (auto sensor_info : this->sensor_map_) {
// Check for sensors left on and set to bypass automatically and remove them from monitoring // Check for faulted bypass_auto sensors and remove them from monitoring
if ((sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (sensor_info.first->state)) { if ((sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_AUTO) && (sensor_info.first->state)) {
ESP_LOGW(TAG, "'%s' is left on and will be automatically bypassed", sensor_info.first->get_name().c_str()); ESP_LOGW(TAG, "'%s' is faulted and will be automatically bypassed", sensor_info.first->get_name().c_str());
this->bypassed_sensor_indicies_.push_back(sensor_info.second.store_index); this->bypassed_sensor_indicies_.push_back(sensor_info.second.store_index);
} }
} }

View File

@@ -56,7 +56,7 @@ class TemplateAlarmControlPanel : public alarm_control_panel::AlarmControlPanel,
void setup() override; void setup() override;
void loop() override; void loop() override;
uint32_t get_supported_features() const override; uint32_t get_supported_features() const override;
bool get_requires_code() const override; bool get_requires_code() const override { return !this->codes_.empty(); }
bool get_requires_code_to_arm() const override { return this->requires_code_to_arm_; } bool get_requires_code_to_arm() const override { return this->requires_code_to_arm_; }
bool get_all_sensors_ready() { return this->sensors_ready_; }; bool get_all_sensors_ready() { return this->sensors_ready_; };
void set_restore_mode(TemplateAlarmControlPanelRestoreMode restore_mode) { this->restore_mode_ = restore_mode; } void set_restore_mode(TemplateAlarmControlPanelRestoreMode restore_mode) { this->restore_mode_ = restore_mode; }
@@ -66,7 +66,8 @@ class TemplateAlarmControlPanel : public alarm_control_panel::AlarmControlPanel,
/** Add a binary_sensor to the alarm_panel. /** Add a binary_sensor to the alarm_panel.
* *
* @param sensor The BinarySensor instance. * @param sensor The BinarySensor instance.
* @param ignore_when_home if this should be ignored when armed_home mode * @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, uint16_t flags = 0,
AlarmSensorType type = ALARM_SENSOR_TYPE_DELAYED); AlarmSensorType type = ALARM_SENSOR_TYPE_DELAYED);
@@ -121,7 +122,7 @@ class TemplateAlarmControlPanel : public alarm_control_panel::AlarmControlPanel,
protected: protected:
void control(const alarm_control_panel::AlarmControlPanelCall &call) override; void control(const alarm_control_panel::AlarmControlPanelCall &call) override;
#ifdef USE_BINARY_SENSOR #ifdef USE_BINARY_SENSOR
// This maps a binary sensor to its type and attribute bits // This maps a binary sensor to its alarm specific info
std::map<binary_sensor::BinarySensor *, SensorInfo> sensor_map_; std::map<binary_sensor::BinarySensor *, SensorInfo> sensor_map_;
// a list of automatically bypassed sensors // a list of automatically bypassed sensors
std::vector<uint8_t> bypassed_sensor_indicies_; std::vector<uint8_t> bypassed_sensor_indicies_;
@@ -147,7 +148,6 @@ class TemplateAlarmControlPanel : public alarm_control_panel::AlarmControlPanel,
bool supports_arm_home_ = false; bool supports_arm_home_ = false;
bool supports_arm_night_ = false; bool supports_arm_night_ = false;
bool sensors_ready_ = false; bool sensors_ready_ = false;
bool sensors_ready_last_ = false;
uint8_t next_store_index_ = 0; uint8_t next_store_index_ = 0;
// check if the code is valid // check if the code is valid
bool is_code_valid_(optional<std::string> code); bool is_code_valid_(optional<std::string> code);