mirror of
https://github.com/home-assistant/core.git
synced 2025-07-21 12:17:07 +00:00
MQTT Alarm control panel - Enable remote code validation (#57764)
* Enable remote code validation * Update homeassistant/components/mqtt/alarm_control_panel.py Co-authored-by: Erik Montnemery <erik@montnemery.com> Co-authored-by: Erik Montnemery <erik@montnemery.com>
This commit is contained in:
parent
4f2d313a4a
commit
58569a58a9
@ -67,6 +67,10 @@ DEFAULT_ARM_HOME = "ARM_HOME"
|
|||||||
DEFAULT_ARM_CUSTOM_BYPASS = "ARM_CUSTOM_BYPASS"
|
DEFAULT_ARM_CUSTOM_BYPASS = "ARM_CUSTOM_BYPASS"
|
||||||
DEFAULT_DISARM = "DISARM"
|
DEFAULT_DISARM = "DISARM"
|
||||||
DEFAULT_NAME = "MQTT Alarm"
|
DEFAULT_NAME = "MQTT Alarm"
|
||||||
|
|
||||||
|
REMOTE_CODE = "REMOTE_CODE"
|
||||||
|
REMOTE_CODE_TEXT = "REMOTE_CODE_TEXT"
|
||||||
|
|
||||||
PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
|
PLATFORM_SCHEMA = mqtt.MQTT_BASE_PLATFORM_SCHEMA.extend(
|
||||||
{
|
{
|
||||||
vol.Optional(CONF_CODE): cv.string,
|
vol.Optional(CONF_CODE): cv.string,
|
||||||
@ -204,7 +208,7 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
|||||||
code = self._config.get(CONF_CODE)
|
code = self._config.get(CONF_CODE)
|
||||||
if code is None:
|
if code is None:
|
||||||
return None
|
return None
|
||||||
if isinstance(code, str) and re.search("^\\d+$", code):
|
if code == REMOTE_CODE or (isinstance(code, str) and re.search("^\\d+$", code)):
|
||||||
return alarm.FORMAT_NUMBER
|
return alarm.FORMAT_NUMBER
|
||||||
return alarm.FORMAT_TEXT
|
return alarm.FORMAT_TEXT
|
||||||
|
|
||||||
@ -296,7 +300,12 @@ class MqttAlarm(MqttEntity, alarm.AlarmControlPanelEntity):
|
|||||||
def _validate_code(self, code, state):
|
def _validate_code(self, code, state):
|
||||||
"""Validate given code."""
|
"""Validate given code."""
|
||||||
conf_code = self._config.get(CONF_CODE)
|
conf_code = self._config.get(CONF_CODE)
|
||||||
check = conf_code is None or code == conf_code
|
check = (
|
||||||
|
conf_code is None
|
||||||
|
or code == conf_code
|
||||||
|
or (conf_code == REMOTE_CODE and code)
|
||||||
|
or (conf_code == REMOTE_CODE_TEXT and code)
|
||||||
|
)
|
||||||
if not check:
|
if not check:
|
||||||
_LOGGER.warning("Wrong code entered for %s", state)
|
_LOGGER.warning("Wrong code entered for %s", state)
|
||||||
return check
|
return check
|
||||||
|
@ -83,6 +83,28 @@ DEFAULT_CONFIG_CODE = {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
DEFAULT_CONFIG_REMOTE_CODE = {
|
||||||
|
alarm_control_panel.DOMAIN: {
|
||||||
|
"platform": "mqtt",
|
||||||
|
"name": "test",
|
||||||
|
"state_topic": "alarm/state",
|
||||||
|
"command_topic": "alarm/command",
|
||||||
|
"code": "REMOTE_CODE",
|
||||||
|
"code_arm_required": True,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DEFAULT_CONFIG_REMOTE_CODE_TEXT = {
|
||||||
|
alarm_control_panel.DOMAIN: {
|
||||||
|
"platform": "mqtt",
|
||||||
|
"name": "test",
|
||||||
|
"state_topic": "alarm/state",
|
||||||
|
"command_topic": "alarm/command",
|
||||||
|
"code": "REMOTE_CODE_TEXT",
|
||||||
|
"code_arm_required": True,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
async def test_fail_setup_without_state_topic(hass, mqtt_mock):
|
async def test_fail_setup_without_state_topic(hass, mqtt_mock):
|
||||||
"""Test for failing with no state topic."""
|
"""Test for failing with no state topic."""
|
||||||
@ -240,6 +262,86 @@ async def test_publish_mqtt_with_code(hass, mqtt_mock, service, payload):
|
|||||||
mqtt_mock.async_publish.assert_called_once_with("alarm/command", payload, 0, False)
|
mqtt_mock.async_publish.assert_called_once_with("alarm/command", payload, 0, False)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,payload",
|
||||||
|
[
|
||||||
|
(SERVICE_ALARM_ARM_HOME, "ARM_HOME"),
|
||||||
|
(SERVICE_ALARM_ARM_AWAY, "ARM_AWAY"),
|
||||||
|
(SERVICE_ALARM_ARM_NIGHT, "ARM_NIGHT"),
|
||||||
|
(SERVICE_ALARM_ARM_VACATION, "ARM_VACATION"),
|
||||||
|
(SERVICE_ALARM_ARM_CUSTOM_BYPASS, "ARM_CUSTOM_BYPASS"),
|
||||||
|
(SERVICE_ALARM_DISARM, "DISARM"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publish_mqtt_with_remote_code(hass, mqtt_mock, service, payload):
|
||||||
|
"""Test publishing of MQTT messages when remode code is configured."""
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
alarm_control_panel.DOMAIN,
|
||||||
|
DEFAULT_CONFIG_REMOTE_CODE,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
call_count = mqtt_mock.async_publish.call_count
|
||||||
|
|
||||||
|
# No code provided, should not publish
|
||||||
|
await hass.services.async_call(
|
||||||
|
alarm_control_panel.DOMAIN,
|
||||||
|
service,
|
||||||
|
{ATTR_ENTITY_ID: "alarm_control_panel.test"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert mqtt_mock.async_publish.call_count == call_count
|
||||||
|
|
||||||
|
# Any code numbered provided, should publish
|
||||||
|
await hass.services.async_call(
|
||||||
|
alarm_control_panel.DOMAIN,
|
||||||
|
service,
|
||||||
|
{ATTR_ENTITY_ID: "alarm_control_panel.test", ATTR_CODE: "1234"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
mqtt_mock.async_publish.assert_called_once_with("alarm/command", payload, 0, False)
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.mark.parametrize(
|
||||||
|
"service,payload",
|
||||||
|
[
|
||||||
|
(SERVICE_ALARM_ARM_HOME, "ARM_HOME"),
|
||||||
|
(SERVICE_ALARM_ARM_AWAY, "ARM_AWAY"),
|
||||||
|
(SERVICE_ALARM_ARM_NIGHT, "ARM_NIGHT"),
|
||||||
|
(SERVICE_ALARM_ARM_VACATION, "ARM_VACATION"),
|
||||||
|
(SERVICE_ALARM_ARM_CUSTOM_BYPASS, "ARM_CUSTOM_BYPASS"),
|
||||||
|
(SERVICE_ALARM_DISARM, "DISARM"),
|
||||||
|
],
|
||||||
|
)
|
||||||
|
async def test_publish_mqtt_with_remote_code_text(hass, mqtt_mock, service, payload):
|
||||||
|
"""Test publishing of MQTT messages when remote text code is configured."""
|
||||||
|
assert await async_setup_component(
|
||||||
|
hass,
|
||||||
|
alarm_control_panel.DOMAIN,
|
||||||
|
DEFAULT_CONFIG_REMOTE_CODE_TEXT,
|
||||||
|
)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
call_count = mqtt_mock.async_publish.call_count
|
||||||
|
|
||||||
|
# No code provided, should not publish
|
||||||
|
await hass.services.async_call(
|
||||||
|
alarm_control_panel.DOMAIN,
|
||||||
|
service,
|
||||||
|
{ATTR_ENTITY_ID: "alarm_control_panel.test"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
assert mqtt_mock.async_publish.call_count == call_count
|
||||||
|
|
||||||
|
# Any code numbered provided, should publish
|
||||||
|
await hass.services.async_call(
|
||||||
|
alarm_control_panel.DOMAIN,
|
||||||
|
service,
|
||||||
|
{ATTR_ENTITY_ID: "alarm_control_panel.test", ATTR_CODE: "any_code"},
|
||||||
|
blocking=True,
|
||||||
|
)
|
||||||
|
mqtt_mock.async_publish.assert_called_once_with("alarm/command", payload, 0, False)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.parametrize(
|
@pytest.mark.parametrize(
|
||||||
"service,payload,disable_code",
|
"service,payload,disable_code",
|
||||||
[
|
[
|
||||||
@ -367,6 +469,21 @@ async def test_attributes_code_number(hass, mqtt_mock):
|
|||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
async def test_attributes_remote_code_number(hass, mqtt_mock):
|
||||||
|
"""Test attributes which are not supported by the vacuum."""
|
||||||
|
config = copy.deepcopy(DEFAULT_CONFIG_REMOTE_CODE)
|
||||||
|
config[alarm_control_panel.DOMAIN]["code"] = "REMOTE_CODE"
|
||||||
|
|
||||||
|
assert await async_setup_component(hass, alarm_control_panel.DOMAIN, config)
|
||||||
|
await hass.async_block_till_done()
|
||||||
|
|
||||||
|
state = hass.states.get("alarm_control_panel.test")
|
||||||
|
assert (
|
||||||
|
state.attributes.get(alarm_control_panel.ATTR_CODE_FORMAT)
|
||||||
|
== alarm_control_panel.FORMAT_NUMBER
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
async def test_attributes_code_text(hass, mqtt_mock):
|
async def test_attributes_code_text(hass, mqtt_mock):
|
||||||
"""Test attributes which are not supported by the vacuum."""
|
"""Test attributes which are not supported by the vacuum."""
|
||||||
config = copy.deepcopy(DEFAULT_CONFIG)
|
config = copy.deepcopy(DEFAULT_CONFIG)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user