Include supported states in Alexa SecurityPanelController configuration object (#31120)

* Update Security Panel Controller.

* Update Security Panel Controller.

* Sort imports.
This commit is contained in:
ochlocracy 2020-01-24 20:57:58 -05:00 committed by Paulus Schoutsen
parent 71ae4b2623
commit 0eee152386
3 changed files with 42 additions and 6 deletions

View file

@ -10,6 +10,11 @@ from homeassistant.components import (
vacuum,
)
from homeassistant.components.alarm_control_panel import ATTR_CODE_FORMAT, FORMAT_NUMBER
from homeassistant.components.alarm_control_panel.const import (
SUPPORT_ALARM_ARM_AWAY,
SUPPORT_ALARM_ARM_HOME,
SUPPORT_ALARM_ARM_NIGHT,
)
import homeassistant.components.climate.const as climate
import homeassistant.components.media_player.const as media_player
from homeassistant.const import (
@ -1082,10 +1087,23 @@ class AlexaSecurityPanelController(AlexaCapability):
def configuration(self):
"""Return configuration object with supported authorization types."""
code_format = self.entity.attributes.get(ATTR_CODE_FORMAT)
supported = self.entity.attributes[ATTR_SUPPORTED_FEATURES]
configuration = {}
supported_arm_states = [{"value": "DISARMED"}]
if supported & SUPPORT_ALARM_ARM_AWAY:
supported_arm_states.append({"value": "ARMED_AWAY"})
if supported & SUPPORT_ALARM_ARM_HOME:
supported_arm_states.append({"value": "ARMED_STAY"})
if supported & SUPPORT_ALARM_ARM_NIGHT:
supported_arm_states.append({"value": "ARMED_NIGHT"})
configuration["supportedArmStates"] = supported_arm_states
if code_format == FORMAT_NUMBER:
return {"supportedAuthorizationTypes": [{"type": "FOUR_DIGIT_PIN"}]}
return None
configuration["supportedAuthorizationTypes"] = [{"type": "FOUR_DIGIT_PIN"}]
return configuration
class AlexaModeController(AlexaCapability):

View file

@ -908,8 +908,11 @@ async def async_api_arm(hass, config, directive, context):
entity.domain, service, data, blocking=False, context=context
)
# return 0 until alarm integration supports an exit delay
payload = {"exitDelayInSeconds": 0}
response = directive.response(
name="Arm.Response", namespace="Alexa.SecurityPanelController"
name="Arm.Response", namespace="Alexa.SecurityPanelController", payload=payload
)
response.add_context_property(
@ -928,6 +931,12 @@ async def async_api_disarm(hass, config, directive, context):
"""Process a Security Panel Disarm request."""
entity = directive.entity
data = {ATTR_ENTITY_ID: entity.entity_id}
response = directive.response()
# Per Alexa Documentation: If you receive a Disarm directive, and the system is already disarmed,
# respond with a success response, not an error response.
if entity.state == STATE_ALARM_DISARMED:
return response
payload = directive.payload
if "authorization" in payload:
@ -941,7 +950,6 @@ async def async_api_disarm(hass, config, directive, context):
msg = "Invalid Code"
raise AlexaSecurityPanelUnauthorizedError(msg)
response = directive.response()
response.add_context_property(
{
"name": "armState",

View file

@ -2353,6 +2353,7 @@ async def test_alarm_control_panel_disarmed(hass):
"code_arm_required": False,
"code_format": "number",
"code": "1234",
"supported_features": 31,
},
)
appliance = await discovery_test(device, hass)
@ -2369,6 +2370,10 @@ async def test_alarm_control_panel_disarmed(hass):
assert security_panel_capability is not None
configuration = security_panel_capability["configuration"]
assert {"type": "FOUR_DIGIT_PIN"} in configuration["supportedAuthorizationTypes"]
assert {"value": "DISARMED"} in configuration["supportedArmStates"]
assert {"value": "ARMED_STAY"} in configuration["supportedArmStates"]
assert {"value": "ARMED_AWAY"} in configuration["supportedArmStates"]
assert {"value": "ARMED_NIGHT"} in configuration["supportedArmStates"]
properties = await reported_properties(hass, "alarm_control_panel#test_1")
properties.assert_equal("Alexa.SecurityPanelController", "armState", "DISARMED")
@ -2420,6 +2425,7 @@ async def test_alarm_control_panel_armed(hass):
"code_arm_required": False,
"code_format": "FORMAT_NUMBER",
"code": "1234",
"supported_features": 3,
},
)
appliance = await discovery_test(device, hass)
@ -2458,11 +2464,15 @@ async def test_alarm_control_panel_armed(hass):
async def test_alarm_control_panel_code_arm_required(hass):
"""Test alarm_control_panel with code_arm_required discovery."""
"""Test alarm_control_panel with code_arm_required not in discovery."""
device = (
"alarm_control_panel.test_3",
"disarmed",
{"friendly_name": "Test Alarm Control Panel 3", "code_arm_required": True},
{
"friendly_name": "Test Alarm Control Panel 3",
"code_arm_required": True,
"supported_features": 3,
},
)
await discovery_test(device, hass, expected_endpoints=0)