179 lines
5.8 KiB
Python
179 lines
5.8 KiB
Python
"""The test for zha device automation actions."""
|
|
from unittest.mock import patch
|
|
|
|
import pytest
|
|
import zigpy.profiles.zha
|
|
import zigpy.zcl.clusters.general as general
|
|
import zigpy.zcl.clusters.security as security
|
|
import zigpy.zcl.foundation as zcl_f
|
|
|
|
import homeassistant.components.automation as automation
|
|
from homeassistant.components.device_automation import DeviceAutomationType
|
|
from homeassistant.components.zha import DOMAIN
|
|
from homeassistant.const import Platform
|
|
from homeassistant.helpers import device_registry as dr
|
|
from homeassistant.setup import async_setup_component
|
|
|
|
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
|
|
|
from tests.common import async_get_device_automations, async_mock_service, mock_coro
|
|
from tests.components.blueprint.conftest import stub_blueprint_populate # noqa: F401
|
|
|
|
SHORT_PRESS = "remote_button_short_press"
|
|
COMMAND = "command"
|
|
COMMAND_SINGLE = "single"
|
|
|
|
|
|
@pytest.fixture(autouse=True)
|
|
def required_platforms_only():
|
|
"""Only setup the required platforms and required base platforms to speed up tests."""
|
|
with patch(
|
|
"homeassistant.components.zha.PLATFORMS",
|
|
(
|
|
Platform.BINARY_SENSOR,
|
|
Platform.DEVICE_TRACKER,
|
|
Platform.NUMBER,
|
|
Platform.SELECT,
|
|
Platform.SENSOR,
|
|
Platform.SIREN,
|
|
),
|
|
):
|
|
yield
|
|
|
|
|
|
@pytest.fixture
|
|
async def device_ias(hass, zigpy_device_mock, zha_device_joined_restored):
|
|
"""IAS device fixture."""
|
|
|
|
clusters = [general.Basic, security.IasZone, security.IasWd]
|
|
zigpy_device = zigpy_device_mock(
|
|
{
|
|
1: {
|
|
SIG_EP_INPUT: [c.cluster_id for c in clusters],
|
|
SIG_EP_OUTPUT: [general.OnOff.cluster_id],
|
|
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
|
}
|
|
},
|
|
)
|
|
|
|
zha_device = await zha_device_joined_restored(zigpy_device)
|
|
zha_device.update_available(True)
|
|
await hass.async_block_till_done()
|
|
return zigpy_device, zha_device
|
|
|
|
|
|
async def test_get_actions(hass, device_ias):
|
|
"""Test we get the expected actions from a zha device."""
|
|
|
|
ieee_address = str(device_ias[0].ieee)
|
|
|
|
ha_device_registry = dr.async_get(hass)
|
|
reg_device = ha_device_registry.async_get_device({(DOMAIN, ieee_address)})
|
|
|
|
actions = await async_get_device_automations(
|
|
hass, DeviceAutomationType.ACTION, reg_device.id
|
|
)
|
|
|
|
expected_actions = [
|
|
{
|
|
"domain": DOMAIN,
|
|
"type": "squawk",
|
|
"device_id": reg_device.id,
|
|
"metadata": {},
|
|
},
|
|
{"domain": DOMAIN, "type": "warn", "device_id": reg_device.id, "metadata": {}},
|
|
{
|
|
"domain": Platform.SELECT,
|
|
"type": "select_option",
|
|
"device_id": reg_device.id,
|
|
"entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_warningmode",
|
|
"metadata": {"secondary": True},
|
|
},
|
|
{
|
|
"domain": Platform.SELECT,
|
|
"type": "select_option",
|
|
"device_id": reg_device.id,
|
|
"entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_sirenlevel",
|
|
"metadata": {"secondary": True},
|
|
},
|
|
{
|
|
"domain": Platform.SELECT,
|
|
"type": "select_option",
|
|
"device_id": reg_device.id,
|
|
"entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_strobelevel",
|
|
"metadata": {"secondary": True},
|
|
},
|
|
{
|
|
"domain": Platform.SELECT,
|
|
"type": "select_option",
|
|
"device_id": reg_device.id,
|
|
"entity_id": "select.fakemanufacturer_fakemodel_e769900a_ias_wd_strobe",
|
|
"metadata": {"secondary": True},
|
|
},
|
|
]
|
|
|
|
assert actions == expected_actions
|
|
|
|
|
|
async def test_action(hass, device_ias):
|
|
"""Test for executing a zha device action."""
|
|
zigpy_device, zha_device = device_ias
|
|
|
|
zigpy_device.device_automation_triggers = {
|
|
(SHORT_PRESS, SHORT_PRESS): {COMMAND: COMMAND_SINGLE}
|
|
}
|
|
|
|
ieee_address = str(zha_device.ieee)
|
|
|
|
ha_device_registry = dr.async_get(hass)
|
|
reg_device = ha_device_registry.async_get_device({(DOMAIN, ieee_address)})
|
|
|
|
with patch(
|
|
"zigpy.zcl.Cluster.request",
|
|
return_value=mock_coro([0x00, zcl_f.Status.SUCCESS]),
|
|
):
|
|
assert await async_setup_component(
|
|
hass,
|
|
automation.DOMAIN,
|
|
{
|
|
automation.DOMAIN: [
|
|
{
|
|
"trigger": {
|
|
"device_id": reg_device.id,
|
|
"domain": "zha",
|
|
"platform": "device",
|
|
"type": SHORT_PRESS,
|
|
"subtype": SHORT_PRESS,
|
|
},
|
|
"action": {
|
|
"domain": DOMAIN,
|
|
"device_id": reg_device.id,
|
|
"type": "warn",
|
|
},
|
|
}
|
|
]
|
|
},
|
|
)
|
|
|
|
await hass.async_block_till_done()
|
|
calls = async_mock_service(hass, DOMAIN, "warning_device_warn")
|
|
|
|
channel = zha_device.channels.pools[0].client_channels["1:0x0006"]
|
|
channel.zha_send_event(COMMAND_SINGLE, [])
|
|
await hass.async_block_till_done()
|
|
|
|
assert len(calls) == 1
|
|
assert calls[0].domain == DOMAIN
|
|
assert calls[0].service == "warning_device_warn"
|
|
assert calls[0].data["ieee"] == ieee_address
|
|
|
|
|
|
async def test_invalid_zha_event_type(hass, device_ias):
|
|
"""Test that unexpected types are not passed to `zha_send_event`."""
|
|
zigpy_device, zha_device = device_ias
|
|
channel = zha_device.channels.pools[0].client_channels["1:0x0006"]
|
|
|
|
# `zha_send_event` accepts only zigpy responses, lists, and dicts
|
|
with pytest.raises(TypeError):
|
|
channel.zha_send_event(COMMAND_SINGLE, 123)
|