Add code_arm_required to manual alarm with MQTT (#22641)
* add code_arm_requited to manual-mqtt alarm * Add fix for alarm front end more-info-alarm_control_panel * Fix code mistake
This commit is contained in:
parent
cb5426c1fa
commit
f722a6c08d
4 changed files with 110 additions and 7 deletions
|
@ -19,6 +19,7 @@ SCAN_INTERVAL = timedelta(seconds=30)
|
|||
ATTR_CHANGED_BY = 'changed_by'
|
||||
FORMAT_TEXT = 'text'
|
||||
FORMAT_NUMBER = 'number'
|
||||
ATTR_CODE_ARM_REQUIRED = 'code_arm_required'
|
||||
|
||||
ENTITY_ID_FORMAT = DOMAIN + '.{}'
|
||||
|
||||
|
@ -87,6 +88,11 @@ class AlarmControlPanel(Entity):
|
|||
"""Last change triggered by."""
|
||||
return None
|
||||
|
||||
@property
|
||||
def code_arm_required(self):
|
||||
"""Whether the code is required for arm actions."""
|
||||
return True
|
||||
|
||||
def alarm_disarm(self, code=None):
|
||||
"""Send disarm command."""
|
||||
raise NotImplementedError()
|
||||
|
@ -159,6 +165,7 @@ class AlarmControlPanel(Entity):
|
|||
"""Return the state attributes."""
|
||||
state_attr = {
|
||||
ATTR_CODE_FORMAT: self.code_format,
|
||||
ATTR_CHANGED_BY: self.changed_by
|
||||
ATTR_CHANGED_BY: self.changed_by,
|
||||
ATTR_CODE_ARM_REQUIRED: self.code_arm_required
|
||||
}
|
||||
return state_attr
|
||||
|
|
|
@ -24,6 +24,7 @@ from homeassistant.helpers.event import track_point_in_time
|
|||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
CONF_CODE_TEMPLATE = 'code_template'
|
||||
CONF_CODE_ARM_REQUIRED = 'code_arm_required'
|
||||
|
||||
CONF_PAYLOAD_DISARM = 'payload_disarm'
|
||||
CONF_PAYLOAD_ARM_HOME = 'payload_arm_home'
|
||||
|
@ -108,6 +109,7 @@ PLATFORM_SCHEMA = vol.Schema(vol.All(mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend({
|
|||
_state_schema(STATE_ALARM_TRIGGERED),
|
||||
vol.Required(mqtt.CONF_COMMAND_TOPIC): mqtt.valid_publish_topic,
|
||||
vol.Required(mqtt.CONF_STATE_TOPIC): mqtt.valid_subscribe_topic,
|
||||
vol.Optional(CONF_CODE_ARM_REQUIRED, default=True): cv.boolean,
|
||||
vol.Optional(CONF_PAYLOAD_ARM_AWAY, default=DEFAULT_ARM_AWAY): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_ARM_HOME, default=DEFAULT_ARM_HOME): cv.string,
|
||||
vol.Optional(CONF_PAYLOAD_ARM_NIGHT, default=DEFAULT_ARM_NIGHT): cv.string,
|
||||
|
@ -126,6 +128,7 @@ def setup_platform(hass, config, add_entities, discovery_info=None):
|
|||
config.get(mqtt.CONF_STATE_TOPIC),
|
||||
config.get(mqtt.CONF_COMMAND_TOPIC),
|
||||
config.get(mqtt.CONF_QOS),
|
||||
config.get(CONF_CODE_ARM_REQUIRED),
|
||||
config.get(CONF_PAYLOAD_DISARM),
|
||||
config.get(CONF_PAYLOAD_ARM_HOME),
|
||||
config.get(CONF_PAYLOAD_ARM_AWAY),
|
||||
|
@ -146,9 +149,9 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
|
|||
"""
|
||||
|
||||
def __init__(self, hass, name, code, code_template, disarm_after_trigger,
|
||||
state_topic, command_topic, qos, payload_disarm,
|
||||
payload_arm_home, payload_arm_away, payload_arm_night,
|
||||
config):
|
||||
state_topic, command_topic, qos, code_arm_required,
|
||||
payload_disarm, payload_arm_home, payload_arm_away,
|
||||
payload_arm_night, config):
|
||||
"""Init the manual MQTT alarm panel."""
|
||||
self._state = STATE_ALARM_DISARMED
|
||||
self._hass = hass
|
||||
|
@ -175,6 +178,7 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
|
|||
self._state_topic = state_topic
|
||||
self._command_topic = command_topic
|
||||
self._qos = qos
|
||||
self._code_arm_required = code_arm_required
|
||||
self._payload_disarm = payload_disarm
|
||||
self._payload_arm_home = payload_arm_home
|
||||
self._payload_arm_away = payload_arm_away
|
||||
|
@ -237,6 +241,11 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
|
|||
return alarm.FORMAT_NUMBER
|
||||
return alarm.FORMAT_TEXT
|
||||
|
||||
@property
|
||||
def code_arm_required(self):
|
||||
"""Whether the code is required for arm actions."""
|
||||
return self._code_arm_required
|
||||
|
||||
def alarm_disarm(self, code=None):
|
||||
"""Send disarm command."""
|
||||
if not self._validate_code(code, STATE_ALARM_DISARMED):
|
||||
|
@ -248,21 +257,24 @@ class ManualMQTTAlarm(alarm.AlarmControlPanel):
|
|||
|
||||
def alarm_arm_home(self, code=None):
|
||||
"""Send arm home command."""
|
||||
if not self._validate_code(code, STATE_ALARM_ARMED_HOME):
|
||||
if self._code_arm_required and not \
|
||||
self._validate_code(code, STATE_ALARM_ARMED_HOME):
|
||||
return
|
||||
|
||||
self._update_state(STATE_ALARM_ARMED_HOME)
|
||||
|
||||
def alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
if not self._validate_code(code, STATE_ALARM_ARMED_AWAY):
|
||||
if self._code_arm_required and not \
|
||||
self._validate_code(code, STATE_ALARM_ARMED_AWAY):
|
||||
return
|
||||
|
||||
self._update_state(STATE_ALARM_ARMED_AWAY)
|
||||
|
||||
def alarm_arm_night(self, code=None):
|
||||
"""Send arm night command."""
|
||||
if not self._validate_code(code, STATE_ALARM_ARMED_NIGHT):
|
||||
if self._code_arm_required and not \
|
||||
self._validate_code(code, STATE_ALARM_ARMED_NIGHT):
|
||||
return
|
||||
|
||||
self._update_state(STATE_ALARM_ARMED_NIGHT)
|
||||
|
|
|
@ -192,6 +192,12 @@ class MqttAlarm(MqttAttributes, MqttAvailability, MqttDiscoveryUpdate,
|
|||
return alarm.FORMAT_NUMBER
|
||||
return alarm.FORMAT_TEXT
|
||||
|
||||
@property
|
||||
def code_arm_required(self):
|
||||
"""Whether the code is required for arm actions."""
|
||||
code_required = self._config.get(CONF_CODE_ARM_REQUIRED)
|
||||
return code_required
|
||||
|
||||
async def async_alarm_disarm(self, code=None):
|
||||
"""Send disarm command.
|
||||
|
||||
|
|
|
@ -77,6 +77,32 @@ class TestAlarmControlPanelManualMqtt(unittest.TestCase):
|
|||
assert STATE_ALARM_ARMED_HOME == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
def test_arm_home_no_pending_when_code_not_req(self):
|
||||
"""Test arm home method."""
|
||||
assert setup_component(
|
||||
self.hass, alarm_control_panel.DOMAIN,
|
||||
{'alarm_control_panel': {
|
||||
'platform': 'manual_mqtt',
|
||||
'name': 'test',
|
||||
'code': CODE,
|
||||
'code_arm_required': False,
|
||||
'pending_time': 0,
|
||||
'disarm_after_trigger': False,
|
||||
'command_topic': 'alarm/command',
|
||||
'state_topic': 'alarm/state',
|
||||
}})
|
||||
|
||||
entity_id = 'alarm_control_panel.test'
|
||||
|
||||
assert STATE_ALARM_DISARMED == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
common.alarm_arm_home(self.hass, 0)
|
||||
self.hass.block_till_done()
|
||||
|
||||
assert STATE_ALARM_ARMED_HOME == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
def test_arm_home_with_pending(self):
|
||||
"""Test arm home method."""
|
||||
assert setup_component(
|
||||
|
@ -164,6 +190,32 @@ class TestAlarmControlPanelManualMqtt(unittest.TestCase):
|
|||
assert STATE_ALARM_ARMED_AWAY == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
def test_arm_away_no_pending_when_code_not_req(self):
|
||||
"""Test arm home method."""
|
||||
assert setup_component(
|
||||
self.hass, alarm_control_panel.DOMAIN,
|
||||
{'alarm_control_panel': {
|
||||
'platform': 'manual_mqtt',
|
||||
'name': 'test',
|
||||
'code_arm_required': False,
|
||||
'code': CODE,
|
||||
'pending_time': 0,
|
||||
'disarm_after_trigger': False,
|
||||
'command_topic': 'alarm/command',
|
||||
'state_topic': 'alarm/state',
|
||||
}})
|
||||
|
||||
entity_id = 'alarm_control_panel.test'
|
||||
|
||||
assert STATE_ALARM_DISARMED == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
common.alarm_arm_away(self.hass, 0, entity_id)
|
||||
self.hass.block_till_done()
|
||||
|
||||
assert STATE_ALARM_ARMED_AWAY == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
def test_arm_home_with_template_code(self):
|
||||
"""Attempt to arm with a template-based code."""
|
||||
assert setup_component(
|
||||
|
@ -279,6 +331,32 @@ class TestAlarmControlPanelManualMqtt(unittest.TestCase):
|
|||
assert STATE_ALARM_ARMED_NIGHT == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
def test_arm_night_no_pending_when_code_not_req(self):
|
||||
"""Test arm night method."""
|
||||
assert setup_component(
|
||||
self.hass, alarm_control_panel.DOMAIN,
|
||||
{'alarm_control_panel': {
|
||||
'platform': 'manual_mqtt',
|
||||
'name': 'test',
|
||||
'code_arm_required': False,
|
||||
'code': CODE,
|
||||
'pending_time': 0,
|
||||
'disarm_after_trigger': False,
|
||||
'command_topic': 'alarm/command',
|
||||
'state_topic': 'alarm/state',
|
||||
}})
|
||||
|
||||
entity_id = 'alarm_control_panel.test'
|
||||
|
||||
assert STATE_ALARM_DISARMED == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
common.alarm_arm_night(self.hass, 0, entity_id)
|
||||
self.hass.block_till_done()
|
||||
|
||||
assert STATE_ALARM_ARMED_NIGHT == \
|
||||
self.hass.states.get(entity_id).state
|
||||
|
||||
def test_arm_night_with_pending(self):
|
||||
"""Test arm night method."""
|
||||
assert setup_component(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue