Add device action support to the alarm_control_panel integration (#27616)
* Add device action support to the alarm_control_panel integration * Improve tests
This commit is contained in:
parent
6ffc520b1c
commit
43c85c0549
6 changed files with 623 additions and 0 deletions
126
homeassistant/components/alarm_control_panel/device_action.py
Normal file
126
homeassistant/components/alarm_control_panel/device_action.py
Normal file
|
@ -0,0 +1,126 @@
|
|||
"""Provides device automations for Alarm control panel."""
|
||||
from typing import Optional, List
|
||||
import voluptuous as vol
|
||||
|
||||
from homeassistant.const import (
|
||||
ATTR_CODE,
|
||||
ATTR_ENTITY_ID,
|
||||
CONF_CODE,
|
||||
CONF_DEVICE_ID,
|
||||
CONF_DOMAIN,
|
||||
CONF_ENTITY_ID,
|
||||
CONF_TYPE,
|
||||
SERVICE_ALARM_ARM_AWAY,
|
||||
SERVICE_ALARM_ARM_HOME,
|
||||
SERVICE_ALARM_ARM_NIGHT,
|
||||
SERVICE_ALARM_DISARM,
|
||||
SERVICE_ALARM_TRIGGER,
|
||||
)
|
||||
from homeassistant.core import HomeAssistant, Context
|
||||
from homeassistant.helpers import entity_registry
|
||||
import homeassistant.helpers.config_validation as cv
|
||||
from . import ATTR_CODE_ARM_REQUIRED, DOMAIN
|
||||
|
||||
ACTION_TYPES = {"arm_away", "arm_home", "arm_night", "disarm", "trigger"}
|
||||
|
||||
ACTION_SCHEMA = cv.DEVICE_ACTION_BASE_SCHEMA.extend(
|
||||
{
|
||||
vol.Required(CONF_TYPE): vol.In(ACTION_TYPES),
|
||||
vol.Required(CONF_ENTITY_ID): cv.entity_domain(DOMAIN),
|
||||
vol.Optional(CONF_CODE): cv.string,
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def async_get_actions(hass: HomeAssistant, device_id: str) -> List[dict]:
|
||||
"""List device actions for Alarm control panel devices."""
|
||||
registry = await entity_registry.async_get_registry(hass)
|
||||
actions = []
|
||||
|
||||
# Get all the integrations entities for this device
|
||||
for entry in entity_registry.async_entries_for_device(registry, device_id):
|
||||
if entry.domain != DOMAIN:
|
||||
continue
|
||||
|
||||
# Add actions for each entity that belongs to this integration
|
||||
actions.append(
|
||||
{
|
||||
CONF_DEVICE_ID: device_id,
|
||||
CONF_DOMAIN: DOMAIN,
|
||||
CONF_ENTITY_ID: entry.entity_id,
|
||||
CONF_TYPE: "arm_away",
|
||||
}
|
||||
)
|
||||
actions.append(
|
||||
{
|
||||
CONF_DEVICE_ID: device_id,
|
||||
CONF_DOMAIN: DOMAIN,
|
||||
CONF_ENTITY_ID: entry.entity_id,
|
||||
CONF_TYPE: "arm_home",
|
||||
}
|
||||
)
|
||||
actions.append(
|
||||
{
|
||||
CONF_DEVICE_ID: device_id,
|
||||
CONF_DOMAIN: DOMAIN,
|
||||
CONF_ENTITY_ID: entry.entity_id,
|
||||
CONF_TYPE: "arm_night",
|
||||
}
|
||||
)
|
||||
actions.append(
|
||||
{
|
||||
CONF_DEVICE_ID: device_id,
|
||||
CONF_DOMAIN: DOMAIN,
|
||||
CONF_ENTITY_ID: entry.entity_id,
|
||||
CONF_TYPE: "disarm",
|
||||
}
|
||||
)
|
||||
actions.append(
|
||||
{
|
||||
CONF_DEVICE_ID: device_id,
|
||||
CONF_DOMAIN: DOMAIN,
|
||||
CONF_ENTITY_ID: entry.entity_id,
|
||||
CONF_TYPE: "trigger",
|
||||
}
|
||||
)
|
||||
|
||||
return actions
|
||||
|
||||
|
||||
async def async_call_action_from_config(
|
||||
hass: HomeAssistant, config: dict, variables: dict, context: Optional[Context]
|
||||
) -> None:
|
||||
"""Execute a device action."""
|
||||
config = ACTION_SCHEMA(config)
|
||||
|
||||
service_data = {ATTR_ENTITY_ID: config[CONF_ENTITY_ID]}
|
||||
if CONF_CODE in config:
|
||||
service_data[ATTR_CODE] = config[CONF_CODE]
|
||||
|
||||
if config[CONF_TYPE] == "arm_away":
|
||||
service = SERVICE_ALARM_ARM_AWAY
|
||||
elif config[CONF_TYPE] == "arm_home":
|
||||
service = SERVICE_ALARM_ARM_HOME
|
||||
elif config[CONF_TYPE] == "arm_night":
|
||||
service = SERVICE_ALARM_ARM_NIGHT
|
||||
elif config[CONF_TYPE] == "disarm":
|
||||
service = SERVICE_ALARM_DISARM
|
||||
elif config[CONF_TYPE] == "trigger":
|
||||
service = SERVICE_ALARM_TRIGGER
|
||||
|
||||
await hass.services.async_call(
|
||||
DOMAIN, service, service_data, blocking=True, context=context
|
||||
)
|
||||
|
||||
|
||||
async def async_get_action_capabilities(hass, config):
|
||||
"""List action capabilities."""
|
||||
state = hass.states.get(config[CONF_ENTITY_ID])
|
||||
code_required = state.attributes.get(ATTR_CODE_ARM_REQUIRED) if state else False
|
||||
|
||||
if config[CONF_TYPE] == "trigger" or (
|
||||
config[CONF_TYPE] != "disarm" and not code_required
|
||||
):
|
||||
return {}
|
||||
|
||||
return {"extra_fields": vol.Schema({vol.Optional(CONF_CODE): str})}
|
11
homeassistant/components/alarm_control_panel/strings.json
Normal file
11
homeassistant/components/alarm_control_panel/strings.json
Normal file
|
@ -0,0 +1,11 @@
|
|||
{
|
||||
"device_automation": {
|
||||
"action_type": {
|
||||
"arm_away": "Arm {entity_name} away",
|
||||
"arm_home": "Arm {entity_name} home",
|
||||
"arm_night": "Arm {entity_name} night",
|
||||
"disarm": "Disarm {entity_name}",
|
||||
"trigger": "Trigger {entity_name}"
|
||||
}
|
||||
}
|
||||
}
|
|
@ -59,6 +59,9 @@ async def async_setup(hass, config):
|
|||
hass.components.websocket_api.async_register_command(
|
||||
websocket_device_automation_list_triggers
|
||||
)
|
||||
hass.components.websocket_api.async_register_command(
|
||||
websocket_device_automation_get_action_capabilities
|
||||
)
|
||||
hass.components.websocket_api.async_register_command(
|
||||
websocket_device_automation_get_condition_capabilities
|
||||
)
|
||||
|
@ -209,6 +212,22 @@ async def websocket_device_automation_list_triggers(hass, connection, msg):
|
|||
connection.send_result(msg["id"], triggers)
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
vol.Required("type"): "device_automation/action/capabilities",
|
||||
vol.Required("action"): dict,
|
||||
}
|
||||
)
|
||||
async def websocket_device_automation_get_action_capabilities(hass, connection, msg):
|
||||
"""Handle request for device action capabilities."""
|
||||
action = msg["action"]
|
||||
capabilities = await _async_get_device_automation_capabilities(
|
||||
hass, "action", action
|
||||
)
|
||||
connection.send_result(msg["id"], capabilities)
|
||||
|
||||
|
||||
@websocket_api.async_response
|
||||
@websocket_api.websocket_command(
|
||||
{
|
||||
|
|
274
tests/components/alarm_control_panel/test_device_action.py
Normal file
274
tests/components/alarm_control_panel/test_device_action.py
Normal file
|
@ -0,0 +1,274 @@
|
|||
"""The tests for Alarm control panel device actions."""
|
||||
import pytest
|
||||
|
||||
from homeassistant.components.alarm_control_panel import DOMAIN
|
||||
from homeassistant.const import (
|
||||
CONF_PLATFORM,
|
||||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
STATE_ALARM_ARMED_NIGHT,
|
||||
STATE_ALARM_DISARMED,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
STATE_UNKNOWN,
|
||||
)
|
||||
from homeassistant.setup import async_setup_component
|
||||
import homeassistant.components.automation as automation
|
||||
from homeassistant.helpers import device_registry
|
||||
|
||||
from tests.common import (
|
||||
MockConfigEntry,
|
||||
assert_lists_same,
|
||||
mock_device_registry,
|
||||
mock_registry,
|
||||
async_get_device_automations,
|
||||
async_get_device_automation_capabilities,
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def device_reg(hass):
|
||||
"""Return an empty, loaded, registry."""
|
||||
return mock_device_registry(hass)
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def entity_reg(hass):
|
||||
"""Return an empty, loaded, registry."""
|
||||
return mock_registry(hass)
|
||||
|
||||
|
||||
async def test_get_actions(hass, device_reg, entity_reg):
|
||||
"""Test we get the expected actions from a alarm_control_panel."""
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
entity_reg.async_get_or_create(DOMAIN, "test", "5678", device_id=device_entry.id)
|
||||
expected_actions = [
|
||||
{
|
||||
"domain": DOMAIN,
|
||||
"type": "arm_away",
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": "alarm_control_panel.test_5678",
|
||||
},
|
||||
{
|
||||
"domain": DOMAIN,
|
||||
"type": "arm_home",
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": "alarm_control_panel.test_5678",
|
||||
},
|
||||
{
|
||||
"domain": DOMAIN,
|
||||
"type": "arm_night",
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": "alarm_control_panel.test_5678",
|
||||
},
|
||||
{
|
||||
"domain": DOMAIN,
|
||||
"type": "disarm",
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": "alarm_control_panel.test_5678",
|
||||
},
|
||||
{
|
||||
"domain": DOMAIN,
|
||||
"type": "trigger",
|
||||
"device_id": device_entry.id,
|
||||
"entity_id": "alarm_control_panel.test_5678",
|
||||
},
|
||||
]
|
||||
actions = await async_get_device_automations(hass, "action", device_entry.id)
|
||||
assert_lists_same(actions, expected_actions)
|
||||
|
||||
|
||||
async def test_get_action_capabilities(hass, device_reg, entity_reg):
|
||||
"""Test we get the expected capabilities from a sensor trigger."""
|
||||
platform = getattr(hass.components, f"test.{DOMAIN}")
|
||||
platform.init()
|
||||
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
entity_reg.async_get_or_create(
|
||||
DOMAIN,
|
||||
"test",
|
||||
platform.ENTITIES["no_arm_code"].unique_id,
|
||||
device_id=device_entry.id,
|
||||
)
|
||||
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
|
||||
|
||||
expected_capabilities = {
|
||||
"arm_away": {"extra_fields": []},
|
||||
"arm_home": {"extra_fields": []},
|
||||
"arm_night": {"extra_fields": []},
|
||||
"disarm": {
|
||||
"extra_fields": [{"name": "code", "optional": True, "type": "string"}]
|
||||
},
|
||||
"trigger": {"extra_fields": []},
|
||||
}
|
||||
actions = await async_get_device_automations(hass, "action", device_entry.id)
|
||||
assert len(actions) == 5
|
||||
for action in actions:
|
||||
capabilities = await async_get_device_automation_capabilities(
|
||||
hass, "action", action
|
||||
)
|
||||
assert capabilities == expected_capabilities[action["type"]]
|
||||
|
||||
|
||||
async def test_get_action_capabilities_arm_code(hass, device_reg, entity_reg):
|
||||
"""Test we get the expected capabilities from a sensor trigger."""
|
||||
platform = getattr(hass.components, f"test.{DOMAIN}")
|
||||
platform.init()
|
||||
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
entity_reg.async_get_or_create(
|
||||
DOMAIN,
|
||||
"test",
|
||||
platform.ENTITIES["arm_code"].unique_id,
|
||||
device_id=device_entry.id,
|
||||
)
|
||||
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
|
||||
|
||||
expected_capabilities = {
|
||||
"arm_away": {
|
||||
"extra_fields": [{"name": "code", "optional": True, "type": "string"}]
|
||||
},
|
||||
"arm_home": {
|
||||
"extra_fields": [{"name": "code", "optional": True, "type": "string"}]
|
||||
},
|
||||
"arm_night": {
|
||||
"extra_fields": [{"name": "code", "optional": True, "type": "string"}]
|
||||
},
|
||||
"disarm": {
|
||||
"extra_fields": [{"name": "code", "optional": True, "type": "string"}]
|
||||
},
|
||||
"trigger": {"extra_fields": []},
|
||||
}
|
||||
actions = await async_get_device_automations(hass, "action", device_entry.id)
|
||||
assert len(actions) == 5
|
||||
for action in actions:
|
||||
capabilities = await async_get_device_automation_capabilities(
|
||||
hass, "action", action
|
||||
)
|
||||
assert capabilities == expected_capabilities[action["type"]]
|
||||
|
||||
|
||||
async def test_action(hass):
|
||||
"""Test for turn_on and turn_off actions."""
|
||||
platform = getattr(hass.components, f"test.{DOMAIN}")
|
||||
platform.init()
|
||||
|
||||
assert await async_setup_component(
|
||||
hass,
|
||||
automation.DOMAIN,
|
||||
{
|
||||
automation.DOMAIN: [
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "event",
|
||||
"event_type": "test_event_arm_away",
|
||||
},
|
||||
"action": {
|
||||
"domain": DOMAIN,
|
||||
"device_id": "abcdefgh",
|
||||
"entity_id": "alarm_control_panel.alarm_no_arm_code",
|
||||
"type": "arm_away",
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "event",
|
||||
"event_type": "test_event_arm_home",
|
||||
},
|
||||
"action": {
|
||||
"domain": DOMAIN,
|
||||
"device_id": "abcdefgh",
|
||||
"entity_id": "alarm_control_panel.alarm_no_arm_code",
|
||||
"type": "arm_home",
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "event",
|
||||
"event_type": "test_event_arm_night",
|
||||
},
|
||||
"action": {
|
||||
"domain": DOMAIN,
|
||||
"device_id": "abcdefgh",
|
||||
"entity_id": "alarm_control_panel.alarm_no_arm_code",
|
||||
"type": "arm_night",
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {"platform": "event", "event_type": "test_event_disarm"},
|
||||
"action": {
|
||||
"domain": DOMAIN,
|
||||
"device_id": "abcdefgh",
|
||||
"entity_id": "alarm_control_panel.alarm_no_arm_code",
|
||||
"type": "disarm",
|
||||
"code": "1234",
|
||||
},
|
||||
},
|
||||
{
|
||||
"trigger": {
|
||||
"platform": "event",
|
||||
"event_type": "test_event_trigger",
|
||||
},
|
||||
"action": {
|
||||
"domain": DOMAIN,
|
||||
"device_id": "abcdefgh",
|
||||
"entity_id": "alarm_control_panel.alarm_no_arm_code",
|
||||
"type": "trigger",
|
||||
},
|
||||
},
|
||||
]
|
||||
},
|
||||
)
|
||||
assert await async_setup_component(hass, DOMAIN, {DOMAIN: {CONF_PLATFORM: "test"}})
|
||||
assert (
|
||||
hass.states.get("alarm_control_panel.alarm_no_arm_code").state == STATE_UNKNOWN
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_event_arm_away")
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
hass.states.get("alarm_control_panel.alarm_no_arm_code").state
|
||||
== STATE_ALARM_ARMED_AWAY
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_event_arm_home")
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
hass.states.get("alarm_control_panel.alarm_no_arm_code").state
|
||||
== STATE_ALARM_ARMED_HOME
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_event_arm_night")
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
hass.states.get("alarm_control_panel.alarm_no_arm_code").state
|
||||
== STATE_ALARM_ARMED_NIGHT
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_event_disarm")
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
hass.states.get("alarm_control_panel.alarm_no_arm_code").state
|
||||
== STATE_ALARM_DISARMED
|
||||
)
|
||||
|
||||
hass.bus.async_fire("test_event_trigger")
|
||||
await hass.async_block_till_done()
|
||||
assert (
|
||||
hass.states.get("alarm_control_panel.alarm_no_arm_code").state
|
||||
== STATE_ALARM_TRIGGERED
|
||||
)
|
|
@ -170,6 +170,106 @@ async def test_websocket_get_triggers(hass, hass_ws_client, device_reg, entity_r
|
|||
assert _same_lists(triggers, expected_triggers)
|
||||
|
||||
|
||||
async def test_websocket_get_action_capabilities(
|
||||
hass, hass_ws_client, device_reg, entity_reg
|
||||
):
|
||||
"""Test we get the expected action capabilities for an alarm through websocket."""
|
||||
await async_setup_component(hass, "device_automation", {})
|
||||
config_entry = MockConfigEntry(domain="test", data={})
|
||||
config_entry.add_to_hass(hass)
|
||||
device_entry = device_reg.async_get_or_create(
|
||||
config_entry_id=config_entry.entry_id,
|
||||
connections={(device_registry.CONNECTION_NETWORK_MAC, "12:34:56:AB:CD:EF")},
|
||||
)
|
||||
entity_reg.async_get_or_create(
|
||||
"alarm_control_panel", "test", "5678", device_id=device_entry.id
|
||||
)
|
||||
expected_capabilities = {
|
||||
"arm_away": {"extra_fields": []},
|
||||
"arm_home": {"extra_fields": []},
|
||||
"arm_night": {"extra_fields": []},
|
||||
"disarm": {
|
||||
"extra_fields": [{"name": "code", "optional": True, "type": "string"}]
|
||||
},
|
||||
"trigger": {"extra_fields": []},
|
||||
}
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
await client.send_json(
|
||||
{"id": 1, "type": "device_automation/action/list", "device_id": device_entry.id}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
|
||||
assert msg["id"] == 1
|
||||
assert msg["type"] == TYPE_RESULT
|
||||
assert msg["success"]
|
||||
actions = msg["result"]
|
||||
|
||||
id = 2
|
||||
assert len(actions) == 5
|
||||
for action in actions:
|
||||
await client.send_json(
|
||||
{
|
||||
"id": id,
|
||||
"type": "device_automation/action/capabilities",
|
||||
"action": action,
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg["id"] == id
|
||||
assert msg["type"] == TYPE_RESULT
|
||||
assert msg["success"]
|
||||
capabilities = msg["result"]
|
||||
assert capabilities == expected_capabilities[action["type"]]
|
||||
id = id + 1
|
||||
|
||||
|
||||
async def test_websocket_get_bad_action_capabilities(
|
||||
hass, hass_ws_client, device_reg, entity_reg
|
||||
):
|
||||
"""Test we get no action capabilities for a non existing domain."""
|
||||
await async_setup_component(hass, "device_automation", {})
|
||||
expected_capabilities = {}
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "device_automation/action/capabilities",
|
||||
"action": {"domain": "beer"},
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg["id"] == 1
|
||||
assert msg["type"] == TYPE_RESULT
|
||||
assert msg["success"]
|
||||
capabilities = msg["result"]
|
||||
assert capabilities == expected_capabilities
|
||||
|
||||
|
||||
async def test_websocket_get_no_action_capabilities(
|
||||
hass, hass_ws_client, device_reg, entity_reg
|
||||
):
|
||||
"""Test we get no action capabilities for a domain with no device action capabilities."""
|
||||
await async_setup_component(hass, "device_automation", {})
|
||||
expected_capabilities = {}
|
||||
|
||||
client = await hass_ws_client(hass)
|
||||
await client.send_json(
|
||||
{
|
||||
"id": 1,
|
||||
"type": "device_automation/action/capabilities",
|
||||
"action": {"domain": "deconz"},
|
||||
}
|
||||
)
|
||||
msg = await client.receive_json()
|
||||
assert msg["id"] == 1
|
||||
assert msg["type"] == TYPE_RESULT
|
||||
assert msg["success"]
|
||||
capabilities = msg["result"]
|
||||
assert capabilities == expected_capabilities
|
||||
|
||||
|
||||
async def test_websocket_get_condition_capabilities(
|
||||
hass, hass_ws_client, device_reg, entity_reg
|
||||
):
|
||||
|
@ -204,6 +304,7 @@ async def test_websocket_get_condition_capabilities(
|
|||
conditions = msg["result"]
|
||||
|
||||
id = 2
|
||||
assert len(conditions) == 2
|
||||
for condition in conditions:
|
||||
await client.send_json(
|
||||
{
|
||||
|
@ -301,6 +402,7 @@ async def test_websocket_get_trigger_capabilities(
|
|||
triggers = msg["result"]
|
||||
|
||||
id = 2
|
||||
assert len(triggers) == 2
|
||||
for trigger in triggers:
|
||||
await client.send_json(
|
||||
{
|
||||
|
|
|
@ -0,0 +1,91 @@
|
|||
"""
|
||||
Provide a mock alarm_control_panel platform.
|
||||
|
||||
Call init before using it in your tests to ensure clean test data.
|
||||
"""
|
||||
from homeassistant.components.alarm_control_panel import AlarmControlPanel
|
||||
from homeassistant.const import (
|
||||
STATE_ALARM_ARMED_AWAY,
|
||||
STATE_ALARM_ARMED_HOME,
|
||||
STATE_ALARM_ARMED_NIGHT,
|
||||
STATE_ALARM_DISARMED,
|
||||
STATE_ALARM_TRIGGERED,
|
||||
)
|
||||
from tests.common import MockEntity
|
||||
|
||||
ENTITIES = {}
|
||||
|
||||
|
||||
def init(empty=False):
|
||||
"""Initialize the platform with entities."""
|
||||
global ENTITIES
|
||||
|
||||
ENTITIES = (
|
||||
{}
|
||||
if empty
|
||||
else {
|
||||
"arm_code": MockAlarm(
|
||||
name=f"Alarm arm code",
|
||||
code_arm_required=True,
|
||||
unique_id="unique_arm_code",
|
||||
),
|
||||
"no_arm_code": MockAlarm(
|
||||
name=f"Alarm no arm code",
|
||||
code_arm_required=False,
|
||||
unique_id="unique_no_arm_code",
|
||||
),
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
async def async_setup_platform(
|
||||
hass, config, async_add_entities_callback, discovery_info=None
|
||||
):
|
||||
"""Return mock entities."""
|
||||
async_add_entities_callback(list(ENTITIES.values()))
|
||||
|
||||
|
||||
class MockAlarm(MockEntity, AlarmControlPanel):
|
||||
"""Mock Alarm control panel class."""
|
||||
|
||||
def __init__(self, **values):
|
||||
"""Init the Mock Alarm Control Panel."""
|
||||
self._state = None
|
||||
|
||||
MockEntity.__init__(self, **values)
|
||||
|
||||
@property
|
||||
def code_arm_required(self):
|
||||
"""Whether the code is required for arm actions."""
|
||||
return self._handle("code_arm_required")
|
||||
|
||||
@property
|
||||
def state(self):
|
||||
"""Return the state of the device."""
|
||||
return self._state
|
||||
|
||||
def alarm_arm_away(self, code=None):
|
||||
"""Send arm away command."""
|
||||
self._state = STATE_ALARM_ARMED_AWAY
|
||||
self.async_write_ha_state()
|
||||
|
||||
def alarm_arm_home(self, code=None):
|
||||
"""Send arm home command."""
|
||||
self._state = STATE_ALARM_ARMED_HOME
|
||||
self.async_write_ha_state()
|
||||
|
||||
def alarm_arm_night(self, code=None):
|
||||
"""Send arm night command."""
|
||||
self._state = STATE_ALARM_ARMED_NIGHT
|
||||
self.async_write_ha_state()
|
||||
|
||||
def alarm_disarm(self, code=None):
|
||||
"""Send disarm command."""
|
||||
if code == "1234":
|
||||
self._state = STATE_ALARM_DISARMED
|
||||
self.async_write_ha_state()
|
||||
|
||||
def alarm_trigger(self, code=None):
|
||||
"""Send alarm trigger command."""
|
||||
self._state = STATE_ALARM_TRIGGERED
|
||||
self.async_write_ha_state()
|
Loading…
Add table
Add a link
Reference in a new issue