Include supported states in Alexa SecurityPanelController configuration object (#31120)
* Update Security Panel Controller. * Update Security Panel Controller. * Sort imports.
This commit is contained in:
parent
71ae4b2623
commit
0eee152386
3 changed files with 42 additions and 6 deletions
|
@ -10,6 +10,11 @@ from homeassistant.components import (
|
||||||
vacuum,
|
vacuum,
|
||||||
)
|
)
|
||||||
from homeassistant.components.alarm_control_panel import ATTR_CODE_FORMAT, FORMAT_NUMBER
|
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.climate.const as climate
|
||||||
import homeassistant.components.media_player.const as media_player
|
import homeassistant.components.media_player.const as media_player
|
||||||
from homeassistant.const import (
|
from homeassistant.const import (
|
||||||
|
@ -1082,10 +1087,23 @@ class AlexaSecurityPanelController(AlexaCapability):
|
||||||
def configuration(self):
|
def configuration(self):
|
||||||
"""Return configuration object with supported authorization types."""
|
"""Return configuration object with supported authorization types."""
|
||||||
code_format = self.entity.attributes.get(ATTR_CODE_FORMAT)
|
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:
|
if code_format == FORMAT_NUMBER:
|
||||||
return {"supportedAuthorizationTypes": [{"type": "FOUR_DIGIT_PIN"}]}
|
configuration["supportedAuthorizationTypes"] = [{"type": "FOUR_DIGIT_PIN"}]
|
||||||
return None
|
|
||||||
|
return configuration
|
||||||
|
|
||||||
|
|
||||||
class AlexaModeController(AlexaCapability):
|
class AlexaModeController(AlexaCapability):
|
||||||
|
|
|
@ -908,8 +908,11 @@ async def async_api_arm(hass, config, directive, context):
|
||||||
entity.domain, service, data, blocking=False, context=context
|
entity.domain, service, data, blocking=False, context=context
|
||||||
)
|
)
|
||||||
|
|
||||||
|
# return 0 until alarm integration supports an exit delay
|
||||||
|
payload = {"exitDelayInSeconds": 0}
|
||||||
|
|
||||||
response = directive.response(
|
response = directive.response(
|
||||||
name="Arm.Response", namespace="Alexa.SecurityPanelController"
|
name="Arm.Response", namespace="Alexa.SecurityPanelController", payload=payload
|
||||||
)
|
)
|
||||||
|
|
||||||
response.add_context_property(
|
response.add_context_property(
|
||||||
|
@ -928,6 +931,12 @@ async def async_api_disarm(hass, config, directive, context):
|
||||||
"""Process a Security Panel Disarm request."""
|
"""Process a Security Panel Disarm request."""
|
||||||
entity = directive.entity
|
entity = directive.entity
|
||||||
data = {ATTR_ENTITY_ID: entity.entity_id}
|
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
|
payload = directive.payload
|
||||||
if "authorization" in payload:
|
if "authorization" in payload:
|
||||||
|
@ -941,7 +950,6 @@ async def async_api_disarm(hass, config, directive, context):
|
||||||
msg = "Invalid Code"
|
msg = "Invalid Code"
|
||||||
raise AlexaSecurityPanelUnauthorizedError(msg)
|
raise AlexaSecurityPanelUnauthorizedError(msg)
|
||||||
|
|
||||||
response = directive.response()
|
|
||||||
response.add_context_property(
|
response.add_context_property(
|
||||||
{
|
{
|
||||||
"name": "armState",
|
"name": "armState",
|
||||||
|
|
|
@ -2353,6 +2353,7 @@ async def test_alarm_control_panel_disarmed(hass):
|
||||||
"code_arm_required": False,
|
"code_arm_required": False,
|
||||||
"code_format": "number",
|
"code_format": "number",
|
||||||
"code": "1234",
|
"code": "1234",
|
||||||
|
"supported_features": 31,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
appliance = await discovery_test(device, hass)
|
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
|
assert security_panel_capability is not None
|
||||||
configuration = security_panel_capability["configuration"]
|
configuration = security_panel_capability["configuration"]
|
||||||
assert {"type": "FOUR_DIGIT_PIN"} in configuration["supportedAuthorizationTypes"]
|
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 = await reported_properties(hass, "alarm_control_panel#test_1")
|
||||||
properties.assert_equal("Alexa.SecurityPanelController", "armState", "DISARMED")
|
properties.assert_equal("Alexa.SecurityPanelController", "armState", "DISARMED")
|
||||||
|
@ -2420,6 +2425,7 @@ async def test_alarm_control_panel_armed(hass):
|
||||||
"code_arm_required": False,
|
"code_arm_required": False,
|
||||||
"code_format": "FORMAT_NUMBER",
|
"code_format": "FORMAT_NUMBER",
|
||||||
"code": "1234",
|
"code": "1234",
|
||||||
|
"supported_features": 3,
|
||||||
},
|
},
|
||||||
)
|
)
|
||||||
appliance = await discovery_test(device, hass)
|
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):
|
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 = (
|
device = (
|
||||||
"alarm_control_panel.test_3",
|
"alarm_control_panel.test_3",
|
||||||
"disarmed",
|
"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)
|
await discovery_test(device, hass, expected_endpoints=0)
|
||||||
|
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue