mirror of
				https://github.com/esphome/esphome.git
				synced 2025-10-30 22:53:59 +00:00 
			
		
		
		
	[alarm_control_panel] BYPASS_AUTO option for Template Alarm Control Panel sensors left open when armed (#8795)
This commit is contained in:
		| @@ -10,6 +10,7 @@ CODEOWNERS = ["@grahambrown11", "@hwstar"] | |||||||
| CONF_CODES = "codes" | CONF_CODES = "codes" | ||||||
| CONF_BYPASS_ARMED_HOME = "bypass_armed_home" | CONF_BYPASS_ARMED_HOME = "bypass_armed_home" | ||||||
| CONF_BYPASS_ARMED_NIGHT = "bypass_armed_night" | CONF_BYPASS_ARMED_NIGHT = "bypass_armed_night" | ||||||
|  | CONF_BYPASS_AUTO = "bypass_auto" | ||||||
| CONF_CHIME = "chime" | CONF_CHIME = "chime" | ||||||
| CONF_TRIGGER_MODE = "trigger_mode" | CONF_TRIGGER_MODE = "trigger_mode" | ||||||
| CONF_REQUIRES_CODE_TO_ARM = "requires_code_to_arm" | CONF_REQUIRES_CODE_TO_ARM = "requires_code_to_arm" | ||||||
| @@ -23,6 +24,7 @@ CONF_TRIGGER_TIME = "trigger_time" | |||||||
| FLAG_NORMAL = "normal" | FLAG_NORMAL = "normal" | ||||||
| FLAG_BYPASS_ARMED_HOME = "bypass_armed_home" | FLAG_BYPASS_ARMED_HOME = "bypass_armed_home" | ||||||
| FLAG_BYPASS_ARMED_NIGHT = "bypass_armed_night" | FLAG_BYPASS_ARMED_NIGHT = "bypass_armed_night" | ||||||
|  | FLAG_BYPASS_AUTO = "bypass_auto" | ||||||
| FLAG_CHIME = "chime" | FLAG_CHIME = "chime" | ||||||
|  |  | ||||||
| BinarySensorFlags = { | BinarySensorFlags = { | ||||||
| @@ -30,6 +32,7 @@ BinarySensorFlags = { | |||||||
|     FLAG_BYPASS_ARMED_HOME: 1 << 1, |     FLAG_BYPASS_ARMED_HOME: 1 << 1, | ||||||
|     FLAG_BYPASS_ARMED_NIGHT: 1 << 2, |     FLAG_BYPASS_ARMED_NIGHT: 1 << 2, | ||||||
|     FLAG_CHIME: 1 << 3, |     FLAG_CHIME: 1 << 3, | ||||||
|  |     FLAG_BYPASS_AUTO: 1 << 4, | ||||||
| } | } | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -68,6 +71,7 @@ TEMPLATE_ALARM_CONTROL_PANEL_BINARY_SENSOR_SCHEMA = cv.maybe_simple_value( | |||||||
|         cv.Required(CONF_INPUT): cv.use_id(binary_sensor.BinarySensor), |         cv.Required(CONF_INPUT): cv.use_id(binary_sensor.BinarySensor), | ||||||
|         cv.Optional(CONF_BYPASS_ARMED_HOME, default=False): cv.boolean, |         cv.Optional(CONF_BYPASS_ARMED_HOME, default=False): cv.boolean, | ||||||
|         cv.Optional(CONF_BYPASS_ARMED_NIGHT, default=False): cv.boolean, |         cv.Optional(CONF_BYPASS_ARMED_NIGHT, default=False): cv.boolean, | ||||||
|  |         cv.Optional(CONF_BYPASS_AUTO, default=False): cv.boolean, | ||||||
|         cv.Optional(CONF_CHIME, default=False): cv.boolean, |         cv.Optional(CONF_CHIME, default=False): cv.boolean, | ||||||
|         cv.Optional(CONF_TRIGGER_MODE, default="DELAYED"): cv.enum( |         cv.Optional(CONF_TRIGGER_MODE, default="DELAYED"): cv.enum( | ||||||
|             ALARM_SENSOR_TYPES, upper=True, space="_" |             ALARM_SENSOR_TYPES, upper=True, space="_" | ||||||
| @@ -143,6 +147,8 @@ async def to_code(config): | |||||||
|         if sensor[CONF_BYPASS_ARMED_NIGHT]: |         if sensor[CONF_BYPASS_ARMED_NIGHT]: | ||||||
|             flags |= BinarySensorFlags[FLAG_BYPASS_ARMED_NIGHT] |             flags |= BinarySensorFlags[FLAG_BYPASS_ARMED_NIGHT] | ||||||
|             supports_arm_night = True |             supports_arm_night = True | ||||||
|  |         if sensor[CONF_BYPASS_AUTO]: | ||||||
|  |             flags |= BinarySensorFlags[FLAG_BYPASS_AUTO] | ||||||
|         if sensor[CONF_CHIME]: |         if sensor[CONF_CHIME]: | ||||||
|             flags |= BinarySensorFlags[FLAG_CHIME] |             flags |= BinarySensorFlags[FLAG_CHIME] | ||||||
|         cg.add(var.add_sensor(bs, flags, sensor[CONF_TRIGGER_MODE])) |         cg.add(var.add_sensor(bs, flags, sensor[CONF_TRIGGER_MODE])) | ||||||
|   | |||||||
| @@ -49,6 +49,7 @@ void TemplateAlarmControlPanel::dump_config() { | |||||||
|                   TRUEFALSE(sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_ARMED_HOME)); |                   TRUEFALSE(sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_ARMED_HOME)); | ||||||
|     ESP_LOGCONFIG(TAG, "    Armed night bypass: %s", |     ESP_LOGCONFIG(TAG, "    Armed night bypass: %s", | ||||||
|                   TRUEFALSE(sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_ARMED_NIGHT)); |                   TRUEFALSE(sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_ARMED_NIGHT)); | ||||||
|  |     ESP_LOGCONFIG(TAG, "    Auto bypass: %s", TRUEFALSE(sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_AUTO)); | ||||||
|     ESP_LOGCONFIG(TAG, "    Chime mode: %s", TRUEFALSE(sensor_info.second.flags & BINARY_SENSOR_MODE_CHIME)); |     ESP_LOGCONFIG(TAG, "    Chime mode: %s", TRUEFALSE(sensor_info.second.flags & BINARY_SENSOR_MODE_CHIME)); | ||||||
|     const char *sensor_type; |     const char *sensor_type; | ||||||
|     switch (sensor_info.second.type) { |     switch (sensor_info.second.type) { | ||||||
| @@ -101,6 +102,15 @@ void TemplateAlarmControlPanel::loop() { | |||||||
|       delay = this->arming_night_time_; |       delay = this->arming_night_time_; | ||||||
|     } |     } | ||||||
|     if ((millis() - this->last_update_) > delay) { |     if ((millis() - this->last_update_) > delay) { | ||||||
|  | #ifdef USE_BINARY_SENSOR | ||||||
|  |       for (auto sensor_info : this->sensor_map_) { | ||||||
|  |         // Check for sensors left on and set to bypass automatically and remove them from monitoring | ||||||
|  |         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()); | ||||||
|  |           this->bypassed_sensor_indicies_.push_back(sensor_info.second.store_index); | ||||||
|  |         } | ||||||
|  |       } | ||||||
|  | #endif | ||||||
|       this->publish_state(this->desired_state_); |       this->publish_state(this->desired_state_); | ||||||
|     } |     } | ||||||
|     return; |     return; | ||||||
| @@ -137,6 +147,11 @@ void TemplateAlarmControlPanel::loop() { | |||||||
|     } |     } | ||||||
|     // Check for triggered sensors |     // Check for triggered sensors | ||||||
|     if (sensor_info.first->state) {  // Sensor triggered? |     if (sensor_info.first->state) {  // Sensor triggered? | ||||||
|  |       // Skip if auto bypassed | ||||||
|  |       if (std::count(this->bypassed_sensor_indicies_.begin(), this->bypassed_sensor_indicies_.end(), | ||||||
|  |                      sensor_info.second.store_index) == 1) { | ||||||
|  |         continue; | ||||||
|  |       } | ||||||
|       // Skip if bypass armed home |       // Skip if bypass armed home | ||||||
|       if (this->current_state_ == ACP_STATE_ARMED_HOME && |       if (this->current_state_ == ACP_STATE_ARMED_HOME && | ||||||
|           (sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_ARMED_HOME)) { |           (sensor_info.second.flags & BINARY_SENSOR_MODE_BYPASS_ARMED_HOME)) { | ||||||
| @@ -255,6 +270,9 @@ void TemplateAlarmControlPanel::control(const AlarmControlPanelCall &call) { | |||||||
|       } |       } | ||||||
|       this->desired_state_ = ACP_STATE_DISARMED; |       this->desired_state_ = ACP_STATE_DISARMED; | ||||||
|       this->publish_state(ACP_STATE_DISARMED); |       this->publish_state(ACP_STATE_DISARMED); | ||||||
|  | #ifdef USE_BINARY_SENSOR | ||||||
|  |       this->bypassed_sensor_indicies_.clear(); | ||||||
|  | #endif | ||||||
|     } else if (call.get_state() == ACP_STATE_TRIGGERED) { |     } else if (call.get_state() == ACP_STATE_TRIGGERED) { | ||||||
|       this->publish_state(ACP_STATE_TRIGGERED); |       this->publish_state(ACP_STATE_TRIGGERED); | ||||||
|     } else if (call.get_state() == ACP_STATE_PENDING) { |     } else if (call.get_state() == ACP_STATE_PENDING) { | ||||||
|   | |||||||
| @@ -22,6 +22,7 @@ enum BinarySensorFlags : uint16_t { | |||||||
|   BINARY_SENSOR_MODE_BYPASS_ARMED_HOME = 1 << 1, |   BINARY_SENSOR_MODE_BYPASS_ARMED_HOME = 1 << 1, | ||||||
|   BINARY_SENSOR_MODE_BYPASS_ARMED_NIGHT = 1 << 2, |   BINARY_SENSOR_MODE_BYPASS_ARMED_NIGHT = 1 << 2, | ||||||
|   BINARY_SENSOR_MODE_CHIME = 1 << 3, |   BINARY_SENSOR_MODE_CHIME = 1 << 3, | ||||||
|  |   BINARY_SENSOR_MODE_BYPASS_AUTO = 1 << 4, | ||||||
| }; | }; | ||||||
|  |  | ||||||
| enum AlarmSensorType : uint16_t { | enum AlarmSensorType : uint16_t { | ||||||
| @@ -121,7 +122,8 @@ class TemplateAlarmControlPanel : public alarm_control_panel::AlarmControlPanel, | |||||||
| #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 type and attribute bits | ||||||
|   std::map<binary_sensor::BinarySensor *, SensorInfo> sensor_map_; |   std::map<binary_sensor::BinarySensor *, SensorInfo> sensor_map_; | ||||||
|  |   // a list of automatically bypassed sensors | ||||||
|  |   std::vector<uint8_t> bypassed_sensor_indicies_; | ||||||
| #endif | #endif | ||||||
|   TemplateAlarmControlPanelRestoreMode restore_mode_{}; |   TemplateAlarmControlPanelRestoreMode restore_mode_{}; | ||||||
|  |  | ||||||
|   | |||||||
| @@ -19,6 +19,7 @@ alarm_control_panel: | |||||||
|       - input: bin1 |       - input: bin1 | ||||||
|         bypass_armed_home: true |         bypass_armed_home: true | ||||||
|         bypass_armed_night: true |         bypass_armed_night: true | ||||||
|  |         bypass_auto: true | ||||||
|     on_state: |     on_state: | ||||||
|       then: |       then: | ||||||
|         - lambda: !lambda |- |         - lambda: !lambda |- | ||||||
| @@ -38,6 +39,7 @@ alarm_control_panel: | |||||||
|       - input: bin1 |       - input: bin1 | ||||||
|         bypass_armed_home: true |         bypass_armed_home: true | ||||||
|         bypass_armed_night: true |         bypass_armed_night: true | ||||||
|  |         bypass_auto: true | ||||||
|     on_disarmed: |     on_disarmed: | ||||||
|       then: |       then: | ||||||
|         - logger.log: "### DISARMED ###" |         - logger.log: "### DISARMED ###" | ||||||
|   | |||||||
		Reference in New Issue
	
	Block a user