mirror of
https://github.com/home-assistant/core.git
synced 2025-04-25 09:47:52 +00:00
Refactor ZHA tests (#55844)
* Replace ZHA tests FakeDevice * Refactor ZHA tests to use zigpy devices and endpoints * Use common consts for zigpy device mocks Use the same dict key names for device signature mocks as zha quirks. * Use const for test device list * Update tests/components/zha/common.py
This commit is contained in:
parent
b1dbdec2ea
commit
c6888e4faf
@ -503,7 +503,7 @@ class ZHADevice(LogMixin):
|
||||
names.append(
|
||||
{
|
||||
ATTR_NAME: f"unknown {endpoint.device_type} device_type "
|
||||
f"of 0x{endpoint.profile_id:04x} profile id"
|
||||
f"of 0x{(endpoint.profile_id or 0xFFFF):04x} profile id"
|
||||
}
|
||||
)
|
||||
device_info[ATTR_ENDPOINT_NAMES] = names
|
||||
|
@ -1,75 +1,14 @@
|
||||
"""Common test objects."""
|
||||
import asyncio
|
||||
import math
|
||||
import time
|
||||
from unittest.mock import AsyncMock, Mock
|
||||
|
||||
import zigpy.device as zigpy_dev
|
||||
import zigpy.endpoint as zigpy_ep
|
||||
import zigpy.profiles.zha
|
||||
import zigpy.types
|
||||
import zigpy.zcl
|
||||
import zigpy.zcl.clusters.general
|
||||
import zigpy.zcl.foundation as zcl_f
|
||||
import zigpy.zdo.types
|
||||
|
||||
import homeassistant.components.zha.core.const as zha_const
|
||||
from homeassistant.util import slugify
|
||||
|
||||
|
||||
class FakeEndpoint:
|
||||
"""Fake endpoint for moking zigpy."""
|
||||
|
||||
def __init__(self, manufacturer, model, epid=1):
|
||||
"""Init fake endpoint."""
|
||||
self.device = None
|
||||
self.endpoint_id = epid
|
||||
self.in_clusters = {}
|
||||
self.out_clusters = {}
|
||||
self._cluster_attr = {}
|
||||
self.member_of = {}
|
||||
self.status = zigpy_ep.Status.ZDO_INIT
|
||||
self.manufacturer = manufacturer
|
||||
self.model = model
|
||||
self.profile_id = zigpy.profiles.zha.PROFILE_ID
|
||||
self.device_type = None
|
||||
self.request = AsyncMock(return_value=[0])
|
||||
|
||||
def add_input_cluster(self, cluster_id, _patch_cluster=True):
|
||||
"""Add an input cluster."""
|
||||
cluster = zigpy.zcl.Cluster.from_id(self, cluster_id, is_server=True)
|
||||
if _patch_cluster:
|
||||
patch_cluster(cluster)
|
||||
self.in_clusters[cluster_id] = cluster
|
||||
ep_attribute = cluster.ep_attribute
|
||||
if ep_attribute:
|
||||
setattr(self, ep_attribute, cluster)
|
||||
|
||||
def add_output_cluster(self, cluster_id, _patch_cluster=True):
|
||||
"""Add an output cluster."""
|
||||
cluster = zigpy.zcl.Cluster.from_id(self, cluster_id, is_server=False)
|
||||
if _patch_cluster:
|
||||
patch_cluster(cluster)
|
||||
self.out_clusters[cluster_id] = cluster
|
||||
|
||||
reply = AsyncMock(return_value=[0])
|
||||
request = AsyncMock(return_value=[0])
|
||||
|
||||
@property
|
||||
def __class__(self):
|
||||
"""Fake being Zigpy endpoint."""
|
||||
return zigpy_ep.Endpoint
|
||||
|
||||
@property
|
||||
def unique_id(self):
|
||||
"""Return the unique id for the endpoint."""
|
||||
return self.device.ieee, self.endpoint_id
|
||||
|
||||
|
||||
FakeEndpoint.add_to_group = zigpy_ep.Endpoint.add_to_group
|
||||
FakeEndpoint.remove_from_group = zigpy_ep.Endpoint.remove_from_group
|
||||
|
||||
|
||||
def patch_cluster(cluster):
|
||||
"""Patch a cluster for testing."""
|
||||
cluster.PLUGGED_ATTR_READS = {}
|
||||
@ -115,35 +54,6 @@ def patch_cluster(cluster):
|
||||
cluster.add = AsyncMock(return_value=[0])
|
||||
|
||||
|
||||
class FakeDevice:
|
||||
"""Fake device for mocking zigpy."""
|
||||
|
||||
def __init__(self, app, ieee, manufacturer, model, node_desc=None, nwk=0xB79C):
|
||||
"""Init fake device."""
|
||||
self._application = app
|
||||
self.application = app
|
||||
self.ieee = zigpy.types.EUI64.convert(ieee)
|
||||
self.nwk = nwk
|
||||
self.zdo = Mock()
|
||||
self.endpoints = {0: self.zdo}
|
||||
self.lqi = 255
|
||||
self.rssi = 8
|
||||
self.last_seen = time.time()
|
||||
self.status = zigpy_dev.Status.ENDPOINTS_INIT
|
||||
self.initializing = False
|
||||
self.skip_configuration = False
|
||||
self.manufacturer = manufacturer
|
||||
self.model = model
|
||||
self.remove_from_group = AsyncMock()
|
||||
if node_desc is None:
|
||||
node_desc = b"\x02@\x807\x10\x7fd\x00\x00*d\x00\x00"
|
||||
self.node_desc = zigpy.zdo.types.NodeDescriptor.deserialize(node_desc)[0]
|
||||
self.neighbors = []
|
||||
|
||||
|
||||
FakeDevice.add_to_group = zigpy_dev.Device.add_to_group
|
||||
|
||||
|
||||
def get_zha_gateway(hass):
|
||||
"""Return ZHA gateway from hass.data."""
|
||||
try:
|
||||
|
@ -1,22 +1,26 @@
|
||||
"""Test configuration for the ZHA component."""
|
||||
import time
|
||||
from unittest.mock import AsyncMock, MagicMock, PropertyMock, patch
|
||||
|
||||
import pytest
|
||||
import zigpy
|
||||
from zigpy.application import ControllerApplication
|
||||
import zigpy.config
|
||||
from zigpy.const import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
import zigpy.device
|
||||
import zigpy.group
|
||||
import zigpy.profiles
|
||||
import zigpy.types
|
||||
import zigpy.zdo.types as zdo_t
|
||||
|
||||
from homeassistant.components.zha import DOMAIN
|
||||
import homeassistant.components.zha.core.const as zha_const
|
||||
import homeassistant.components.zha.core.device as zha_core_device
|
||||
from homeassistant.setup import async_setup_component
|
||||
|
||||
from .common import FakeDevice, FakeEndpoint, get_zha_gateway
|
||||
|
||||
from tests.common import MockConfigEntry
|
||||
from tests.components.light.conftest import mock_light_profiles # noqa: F401
|
||||
from tests.components.zha import common
|
||||
|
||||
FIXTURE_GRP_ID = 0x1001
|
||||
FIXTURE_GRP_NAME = "fixture group"
|
||||
@ -114,23 +118,29 @@ def zigpy_device_mock(zigpy_app_controller):
|
||||
patch_cluster=True,
|
||||
):
|
||||
"""Make a fake device using the specified cluster classes."""
|
||||
device = FakeDevice(
|
||||
zigpy_app_controller, ieee, manufacturer, model, node_descriptor, nwk=nwk
|
||||
device = zigpy.device.Device(
|
||||
zigpy_app_controller, zigpy.types.EUI64.convert(ieee), nwk
|
||||
)
|
||||
device.manufacturer = manufacturer
|
||||
device.model = model
|
||||
device.node_desc = zdo_t.NodeDescriptor.deserialize(node_descriptor)[0]
|
||||
device.last_seen = time.time()
|
||||
|
||||
for epid, ep in endpoints.items():
|
||||
endpoint = FakeEndpoint(manufacturer, model, epid)
|
||||
endpoint.device = device
|
||||
device.endpoints[epid] = endpoint
|
||||
endpoint.device_type = ep["device_type"]
|
||||
profile_id = ep.get("profile_id")
|
||||
if profile_id:
|
||||
endpoint.profile_id = profile_id
|
||||
endpoint = device.add_endpoint(epid)
|
||||
endpoint.device_type = ep[SIG_EP_TYPE]
|
||||
endpoint.profile_id = ep.get(SIG_EP_PROFILE)
|
||||
endpoint.request = AsyncMock(return_value=[0])
|
||||
|
||||
for cluster_id in ep.get("in_clusters", []):
|
||||
endpoint.add_input_cluster(cluster_id, _patch_cluster=patch_cluster)
|
||||
for cluster_id in ep.get(SIG_EP_INPUT, []):
|
||||
cluster = endpoint.add_input_cluster(cluster_id)
|
||||
if patch_cluster:
|
||||
common.patch_cluster(cluster)
|
||||
|
||||
for cluster_id in ep.get("out_clusters", []):
|
||||
endpoint.add_output_cluster(cluster_id, _patch_cluster=patch_cluster)
|
||||
for cluster_id in ep.get(SIG_EP_OUTPUT, []):
|
||||
cluster = endpoint.add_output_cluster(cluster_id)
|
||||
if patch_cluster:
|
||||
common.patch_cluster(cluster)
|
||||
|
||||
return device
|
||||
|
||||
@ -143,7 +153,7 @@ def zha_device_joined(hass, setup_zha):
|
||||
|
||||
async def _zha_device(zigpy_dev):
|
||||
await setup_zha()
|
||||
zha_gateway = get_zha_gateway(hass)
|
||||
zha_gateway = common.get_zha_gateway(hass)
|
||||
await zha_gateway.async_device_initialized(zigpy_dev)
|
||||
await hass.async_block_till_done()
|
||||
return zha_gateway.get_device(zigpy_dev.ieee)
|
||||
|
@ -18,6 +18,7 @@ from homeassistant.const import (
|
||||
)
|
||||
|
||||
from .common import async_enable_traffic, find_entity_id
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
@ -25,9 +26,10 @@ def zigpy_device(zigpy_device_mock):
|
||||
"""Device tracker zigpy device."""
|
||||
endpoints = {
|
||||
1: {
|
||||
"in_clusters": [security.IasAce.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.IAS_ANCILLARY_CONTROL,
|
||||
SIG_EP_INPUT: [security.IasAce.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.IAS_ANCILLARY_CONTROL,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(
|
||||
|
@ -40,7 +40,14 @@ from homeassistant.components.zha.core.const import (
|
||||
from homeassistant.const import ATTR_NAME
|
||||
from homeassistant.core import Context
|
||||
|
||||
from .conftest import FIXTURE_GRP_ID, FIXTURE_GRP_NAME
|
||||
from .conftest import (
|
||||
FIXTURE_GRP_ID,
|
||||
FIXTURE_GRP_NAME,
|
||||
SIG_EP_INPUT,
|
||||
SIG_EP_OUTPUT,
|
||||
SIG_EP_PROFILE,
|
||||
SIG_EP_TYPE,
|
||||
)
|
||||
|
||||
IEEE_SWITCH_DEVICE = "01:2d:6f:00:0a:90:69:e7"
|
||||
IEEE_GROUPABLE_DEVICE = "01:2d:6f:00:0a:90:69:e8"
|
||||
@ -53,9 +60,10 @@ async def device_switch(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.OnOff.cluster_id, general.Basic.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [general.OnOff.cluster_id, general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_SWITCH_DEVICE,
|
||||
@ -72,13 +80,14 @@ async def device_groupable(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.OnOff.cluster_id,
|
||||
general.Basic.cluster_id,
|
||||
general.Groups.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE,
|
||||
|
@ -13,21 +13,24 @@ from .common import (
|
||||
find_entity_id,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
DEVICE_IAS = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.IAS_ZONE,
|
||||
"in_clusters": [security.IasZone.cluster_id],
|
||||
"out_clusters": [],
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
|
||||
SIG_EP_INPUT: [security.IasZone.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
DEVICE_OCCUPANCY = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.OCCUPANCY_SENSOR,
|
||||
"in_clusters": [measurement.OccupancySensing.cluster_id],
|
||||
"out_clusters": [],
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.OCCUPANCY_SENSOR,
|
||||
SIG_EP_INPUT: [measurement.OccupancySensing.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -15,6 +15,7 @@ import homeassistant.components.zha.core.const as zha_const
|
||||
import homeassistant.components.zha.core.registries as registries
|
||||
|
||||
from .common import get_zha_gateway, make_zcl_header
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
||||
|
||||
from tests.common import async_capture_events
|
||||
|
||||
@ -43,7 +44,7 @@ def zigpy_coordinator_device(zigpy_device_mock):
|
||||
"""Coordinator device fixture."""
|
||||
|
||||
coordinator = zigpy_device_mock(
|
||||
{1: {"in_clusters": [0x1000], "out_clusters": [], "device_type": 0x1234}},
|
||||
{1: {SIG_EP_INPUT: [0x1000], SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x1234}},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
"test manufacturer",
|
||||
"test model",
|
||||
@ -69,7 +70,7 @@ def poll_control_ch(channel_pool, zigpy_device_mock):
|
||||
"""Poll control channel fixture."""
|
||||
cluster_id = zigpy.zcl.clusters.general.PollControl.cluster_id
|
||||
zigpy_dev = zigpy_device_mock(
|
||||
{1: {"in_clusters": [cluster_id], "out_clusters": [], "device_type": 0x1234}},
|
||||
{1: {SIG_EP_INPUT: [cluster_id], SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x1234}},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
"test manufacturer",
|
||||
"test model",
|
||||
@ -85,7 +86,7 @@ async def poll_control_device(zha_device_restored, zigpy_device_mock):
|
||||
"""Poll control device fixture."""
|
||||
cluster_id = zigpy.zcl.clusters.general.PollControl.cluster_id
|
||||
zigpy_dev = zigpy_device_mock(
|
||||
{1: {"in_clusters": [cluster_id], "out_clusters": [], "device_type": 0x1234}},
|
||||
{1: {SIG_EP_INPUT: [cluster_id], SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x1234}},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
"test manufacturer",
|
||||
"test model",
|
||||
@ -159,7 +160,7 @@ async def test_in_channel_config(
|
||||
):
|
||||
"""Test ZHA core channel configuration for input clusters."""
|
||||
zigpy_dev = zigpy_device_mock(
|
||||
{1: {"in_clusters": [cluster_id], "out_clusters": [], "device_type": 0x1234}},
|
||||
{1: {SIG_EP_INPUT: [cluster_id], SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x1234}},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
"test manufacturer",
|
||||
"test model",
|
||||
@ -221,7 +222,7 @@ async def test_out_channel_config(
|
||||
):
|
||||
"""Test ZHA core channel configuration for output clusters."""
|
||||
zigpy_dev = zigpy_device_mock(
|
||||
{1: {"out_clusters": [cluster_id], "in_clusters": [], "device_type": 0x1234}},
|
||||
{1: {SIG_EP_OUTPUT: [cluster_id], SIG_EP_INPUT: [], SIG_EP_TYPE: 0x1234}},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
"test manufacturer",
|
||||
"test model",
|
||||
@ -328,14 +329,14 @@ def test_ep_channels_all_channels(m1, zha_device_mock):
|
||||
zha_device = zha_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [0, 1, 6, 8],
|
||||
"out_clusters": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [0, 1, 6, 8],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
},
|
||||
2: {
|
||||
"in_clusters": [0, 1, 6, 8, 768],
|
||||
"out_clusters": [],
|
||||
"device_type": 0x0000,
|
||||
SIG_EP_INPUT: [0, 1, 6, 8, 768],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: 0x0000,
|
||||
},
|
||||
}
|
||||
)
|
||||
@ -379,11 +380,11 @@ def test_channel_power_config(m1, zha_device_mock):
|
||||
in_clusters = [0, 1, 6, 8]
|
||||
zha_device = zha_device_mock(
|
||||
{
|
||||
1: {"in_clusters": in_clusters, "out_clusters": [], "device_type": 0x0000},
|
||||
1: {SIG_EP_INPUT: in_clusters, SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x0000},
|
||||
2: {
|
||||
"in_clusters": [*in_clusters, 768],
|
||||
"out_clusters": [],
|
||||
"device_type": 0x0000,
|
||||
SIG_EP_INPUT: [*in_clusters, 768],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: 0x0000,
|
||||
},
|
||||
}
|
||||
)
|
||||
@ -402,8 +403,8 @@ def test_channel_power_config(m1, zha_device_mock):
|
||||
|
||||
zha_device = zha_device_mock(
|
||||
{
|
||||
1: {"in_clusters": [], "out_clusters": [], "device_type": 0x0000},
|
||||
2: {"in_clusters": in_clusters, "out_clusters": [], "device_type": 0x0000},
|
||||
1: {SIG_EP_INPUT: [], SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x0000},
|
||||
2: {SIG_EP_INPUT: in_clusters, SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x0000},
|
||||
}
|
||||
)
|
||||
channels = zha_channels.Channels.new(zha_device)
|
||||
@ -412,7 +413,7 @@ def test_channel_power_config(m1, zha_device_mock):
|
||||
assert "2:0x0001" in pools[2].all_channels
|
||||
|
||||
zha_device = zha_device_mock(
|
||||
{2: {"in_clusters": in_clusters, "out_clusters": [], "device_type": 0x0000}}
|
||||
{2: {SIG_EP_INPUT: in_clusters, SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x0000}}
|
||||
)
|
||||
channels = zha_channels.Channels.new(zha_device)
|
||||
pools = {pool.id: pool for pool in channels.pools}
|
||||
@ -556,7 +557,7 @@ def zigpy_zll_device(zigpy_device_mock):
|
||||
"""ZLL device fixture."""
|
||||
|
||||
return zigpy_device_mock(
|
||||
{1: {"in_clusters": [0x1000], "out_clusters": [], "device_type": 0x1234}},
|
||||
{1: {SIG_EP_INPUT: [0x1000], SIG_EP_OUTPUT: [], SIG_EP_TYPE: 0x1234}},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
"test manufacturer",
|
||||
"test model",
|
||||
|
@ -3,6 +3,7 @@
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
import zigpy.profiles
|
||||
import zigpy.zcl.clusters
|
||||
from zigpy.zcl.clusters.hvac import Thermostat
|
||||
import zigpy.zcl.foundation as zcl_f
|
||||
@ -51,74 +52,79 @@ from homeassistant.components.zha.core.const import PRESET_COMPLEX, PRESET_SCHED
|
||||
from homeassistant.const import ATTR_ENTITY_ID, ATTR_TEMPERATURE, STATE_UNKNOWN
|
||||
|
||||
from .common import async_enable_traffic, find_entity_id, send_attributes_report
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
CLIMATE = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
SIG_EP_INPUT: [
|
||||
zigpy.zcl.clusters.general.Basic.cluster_id,
|
||||
zigpy.zcl.clusters.general.Identify.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.Thermostat.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.UserInterface.cluster_id,
|
||||
],
|
||||
"out_clusters": [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
SIG_EP_OUTPUT: [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
|
||||
CLIMATE_FAN = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
SIG_EP_INPUT: [
|
||||
zigpy.zcl.clusters.general.Basic.cluster_id,
|
||||
zigpy.zcl.clusters.general.Identify.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.Fan.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.Thermostat.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.UserInterface.cluster_id,
|
||||
],
|
||||
"out_clusters": [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
SIG_EP_OUTPUT: [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
|
||||
CLIMATE_SINOPE = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
SIG_EP_INPUT: [
|
||||
zigpy.zcl.clusters.general.Basic.cluster_id,
|
||||
zigpy.zcl.clusters.general.Identify.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.Thermostat.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.UserInterface.cluster_id,
|
||||
65281,
|
||||
],
|
||||
"out_clusters": [zigpy.zcl.clusters.general.Ota.cluster_id, 65281],
|
||||
"profile_id": 260,
|
||||
SIG_EP_OUTPUT: [zigpy.zcl.clusters.general.Ota.cluster_id, 65281],
|
||||
},
|
||||
}
|
||||
|
||||
CLIMATE_ZEN = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
SIG_EP_INPUT: [
|
||||
zigpy.zcl.clusters.general.Basic.cluster_id,
|
||||
zigpy.zcl.clusters.general.Identify.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.Fan.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.Thermostat.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.UserInterface.cluster_id,
|
||||
],
|
||||
"out_clusters": [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
SIG_EP_OUTPUT: [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
|
||||
CLIMATE_MOES = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.THERMOSTAT,
|
||||
SIG_EP_INPUT: [
|
||||
zigpy.zcl.clusters.general.Basic.cluster_id,
|
||||
zigpy.zcl.clusters.general.Identify.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.Thermostat.cluster_id,
|
||||
zigpy.zcl.clusters.hvac.UserInterface.cluster_id,
|
||||
61148,
|
||||
],
|
||||
"out_clusters": [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
SIG_EP_OUTPUT: [zigpy.zcl.clusters.general.Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
MANUF_SINOPE = "Sinope Technologies"
|
||||
|
@ -32,6 +32,7 @@ from .common import (
|
||||
make_zcl_header,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
from tests.common import async_capture_events, mock_coro, mock_restore_cache
|
||||
|
||||
@ -42,9 +43,10 @@ def zigpy_cover_device(zigpy_device_mock):
|
||||
|
||||
endpoints = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.IAS_ZONE,
|
||||
"in_clusters": [closures.WindowCovering.cluster_id],
|
||||
"out_clusters": [],
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.IAS_ZONE,
|
||||
SIG_EP_INPUT: [closures.WindowCovering.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(endpoints)
|
||||
@ -56,9 +58,10 @@ def zigpy_cover_remote(zigpy_device_mock):
|
||||
|
||||
endpoints = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.WINDOW_COVERING_CONTROLLER,
|
||||
"in_clusters": [],
|
||||
"out_clusters": [closures.WindowCovering.cluster_id],
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.WINDOW_COVERING_CONTROLLER,
|
||||
SIG_EP_INPUT: [],
|
||||
SIG_EP_OUTPUT: [closures.WindowCovering.cluster_id],
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(endpoints)
|
||||
@ -70,13 +73,14 @@ def zigpy_shade_device(zigpy_device_mock):
|
||||
|
||||
endpoints = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.SHADE,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.SHADE,
|
||||
SIG_EP_INPUT: [
|
||||
closures.Shade.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
general.OnOff.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
SIG_EP_OUTPUT: [],
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(endpoints)
|
||||
@ -88,9 +92,10 @@ def zigpy_keen_vent(zigpy_device_mock):
|
||||
|
||||
endpoints = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.LEVEL_CONTROLLABLE_OUTPUT,
|
||||
"in_clusters": [general.LevelControl.cluster_id, general.OnOff.cluster_id],
|
||||
"out_clusters": [],
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.LEVEL_CONTROLLABLE_OUTPUT,
|
||||
SIG_EP_INPUT: [general.LevelControl.cluster_id, general.OnOff.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(
|
||||
|
@ -17,6 +17,7 @@ import homeassistant.helpers.device_registry as dr
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .common import async_enable_traffic, make_zcl_header
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
@ -32,9 +33,9 @@ def zigpy_device(zigpy_device_mock):
|
||||
|
||||
endpoints = {
|
||||
3: {
|
||||
"in_clusters": in_clusters,
|
||||
"out_clusters": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: in_clusters,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(endpoints)
|
||||
@ -53,9 +54,9 @@ def zigpy_device_mains(zigpy_device_mock):
|
||||
|
||||
endpoints = {
|
||||
3: {
|
||||
"in_clusters": in_clusters,
|
||||
"out_clusters": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: in_clusters,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(
|
||||
@ -83,9 +84,9 @@ async def ota_zha_device(zha_device_restored, zigpy_device_mock):
|
||||
zigpy_dev = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.Basic.cluster_id],
|
||||
"out_clusters": [general.Ota.cluster_id],
|
||||
"device_type": 0x1234,
|
||||
SIG_EP_INPUT: [general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [general.Ota.cluster_id],
|
||||
SIG_EP_TYPE: 0x1234,
|
||||
}
|
||||
},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
|
@ -12,6 +12,8 @@ from homeassistant.components.zha import DOMAIN
|
||||
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
|
||||
|
||||
@ -28,9 +30,9 @@ async def device_ias(hass, zigpy_device_mock, zha_device_joined_restored):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [c.cluster_id for c in clusters],
|
||||
"out_clusters": [general.OnOff.cluster_id],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
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,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -3,6 +3,7 @@ from datetime import timedelta
|
||||
import time
|
||||
|
||||
import pytest
|
||||
import zigpy.profiles.zha
|
||||
import zigpy.zcl.clusters.general as general
|
||||
|
||||
from homeassistant.components.device_tracker import DOMAIN, SOURCE_TYPE_ROUTER
|
||||
@ -18,6 +19,7 @@ from .common import (
|
||||
find_entity_id,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
|
||||
@ -27,15 +29,16 @@ def zigpy_device_dt(zigpy_device_mock):
|
||||
"""Device tracker zigpy device."""
|
||||
endpoints = {
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.Basic.cluster_id,
|
||||
general.PowerConfiguration.cluster_id,
|
||||
general.Identify.cluster_id,
|
||||
general.PollControl.cluster_id,
|
||||
general.BinaryInput.cluster_id,
|
||||
],
|
||||
"out_clusters": [general.Identify.cluster_id, general.Ota.cluster_id],
|
||||
"device_type": SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE,
|
||||
SIG_EP_OUTPUT: [general.Identify.cluster_id, general.Ota.cluster_id],
|
||||
SIG_EP_TYPE: SMARTTHINGS_ARRIVAL_SENSOR_DEVICE_TYPE,
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(endpoints)
|
||||
|
@ -12,6 +12,7 @@ from homeassistant.setup import async_setup_component
|
||||
import homeassistant.util.dt as dt_util
|
||||
|
||||
from .common import async_enable_traffic
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
from tests.common import (
|
||||
async_fire_time_changed,
|
||||
@ -57,9 +58,10 @@ async def mock_devices(hass, zigpy_device_mock, zha_device_joined_restored):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.Basic.cluster_id],
|
||||
"out_clusters": [general.OnOff.cluster_id],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [general.OnOff.cluster_id],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_PROFILE: zigpy.profiles.zha.PROFILE_ID,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -5,6 +5,7 @@ from unittest import mock
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
import pytest
|
||||
from zigpy.const import SIG_ENDPOINTS, SIG_MANUFACTURER, SIG_MODEL, SIG_NODE_DESC
|
||||
import zigpy.profiles.zha
|
||||
import zigpy.quirks
|
||||
import zigpy.types
|
||||
@ -29,7 +30,15 @@ import homeassistant.components.zha.switch
|
||||
import homeassistant.helpers.entity_registry
|
||||
|
||||
from .common import get_zha_gateway
|
||||
from .zha_devices_list import DEVICES
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
from .zha_devices_list import (
|
||||
DEV_SIG_CHANNELS,
|
||||
DEV_SIG_ENT_MAP,
|
||||
DEV_SIG_ENT_MAP_CLASS,
|
||||
DEV_SIG_ENT_MAP_ID,
|
||||
DEV_SIG_EVT_CHANNELS,
|
||||
DEVICES,
|
||||
)
|
||||
|
||||
NO_TAIL_ID = re.compile("_\\d$")
|
||||
|
||||
@ -72,11 +81,11 @@ async def test_devices(
|
||||
)
|
||||
|
||||
zigpy_device = zigpy_device_mock(
|
||||
device["endpoints"],
|
||||
device[SIG_ENDPOINTS],
|
||||
"00:11:22:33:44:55:66:77",
|
||||
device["manufacturer"],
|
||||
device["model"],
|
||||
node_descriptor=device["node_descriptor"],
|
||||
device[SIG_MANUFACTURER],
|
||||
device[SIG_MODEL],
|
||||
node_descriptor=device[SIG_NODE_DESC],
|
||||
patch_cluster=False,
|
||||
)
|
||||
|
||||
@ -120,11 +129,13 @@ async def test_devices(
|
||||
ch.id for pool in zha_dev.channels.pools for ch in pool.client_channels.values()
|
||||
}
|
||||
|
||||
entity_map = device["entity_map"]
|
||||
entity_map = device[DEV_SIG_ENT_MAP]
|
||||
assert zha_entity_ids == {
|
||||
e["entity_id"] for e in entity_map.values() if not e.get("default_match", False)
|
||||
e[DEV_SIG_ENT_MAP_ID]
|
||||
for e in entity_map.values()
|
||||
if not e.get("default_match", False)
|
||||
}
|
||||
assert event_channels == set(device["event_channels"])
|
||||
assert event_channels == set(device[DEV_SIG_EVT_CHANNELS])
|
||||
|
||||
for call in _dispatch.call_args_list:
|
||||
_, component, entity_cls, unique_id, channels = call[0]
|
||||
@ -133,10 +144,10 @@ async def test_devices(
|
||||
|
||||
assert key in entity_map
|
||||
assert entity_id is not None
|
||||
no_tail_id = NO_TAIL_ID.sub("", entity_map[key]["entity_id"])
|
||||
no_tail_id = NO_TAIL_ID.sub("", entity_map[key][DEV_SIG_ENT_MAP_ID])
|
||||
assert entity_id.startswith(no_tail_id)
|
||||
assert {ch.name for ch in channels} == set(entity_map[key]["channels"])
|
||||
assert entity_cls.__name__ == entity_map[key]["entity_class"]
|
||||
assert {ch.name for ch in channels} == set(entity_map[key][DEV_SIG_CHANNELS])
|
||||
assert entity_cls.__name__ == entity_map[key][DEV_SIG_ENT_MAP_CLASS]
|
||||
|
||||
|
||||
def _get_first_identify_cluster(zigpy_device):
|
||||
@ -258,20 +269,20 @@ async def test_discover_endpoint(device_info, channels_mock, hass):
|
||||
"homeassistant.components.zha.core.channels.Channels.async_new_entity"
|
||||
) as new_ent:
|
||||
channels = channels_mock(
|
||||
device_info["endpoints"],
|
||||
manufacturer=device_info["manufacturer"],
|
||||
model=device_info["model"],
|
||||
node_desc=device_info["node_descriptor"],
|
||||
device_info[SIG_ENDPOINTS],
|
||||
manufacturer=device_info[SIG_MANUFACTURER],
|
||||
model=device_info[SIG_MODEL],
|
||||
node_desc=device_info[SIG_NODE_DESC],
|
||||
patch_cluster=False,
|
||||
)
|
||||
|
||||
assert device_info["event_channels"] == sorted(
|
||||
assert device_info[DEV_SIG_EVT_CHANNELS] == sorted(
|
||||
ch.id for pool in channels.pools for ch in pool.client_channels.values()
|
||||
)
|
||||
assert new_ent.call_count == len(
|
||||
[
|
||||
device_info
|
||||
for device_info in device_info["entity_map"].values()
|
||||
for device_info in device_info[DEV_SIG_ENT_MAP].values()
|
||||
if not device_info.get("default_match", False)
|
||||
]
|
||||
)
|
||||
@ -279,10 +290,10 @@ async def test_discover_endpoint(device_info, channels_mock, hass):
|
||||
for call_args in new_ent.call_args_list:
|
||||
comp, ent_cls, unique_id, channels = call_args[0]
|
||||
map_id = (comp, unique_id)
|
||||
assert map_id in device_info["entity_map"]
|
||||
entity_info = device_info["entity_map"][map_id]
|
||||
assert {ch.name for ch in channels} == set(entity_info["channels"])
|
||||
assert ent_cls.__name__ == entity_info["entity_class"]
|
||||
assert map_id in device_info[DEV_SIG_ENT_MAP]
|
||||
entity_info = device_info[DEV_SIG_ENT_MAP][map_id]
|
||||
assert {ch.name for ch in channels} == set(entity_info[DEV_SIG_CHANNELS])
|
||||
assert ent_cls.__name__ == entity_info[DEV_SIG_ENT_MAP_CLASS]
|
||||
|
||||
|
||||
def _ch_mock(cluster):
|
||||
@ -377,11 +388,11 @@ async def test_device_override(
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
"endpoint_id": 1,
|
||||
"in_clusters": [0, 3, 4, 5, 6, 8, 768, 2821, 64513],
|
||||
"out_clusters": [25],
|
||||
"profile_id": 260,
|
||||
SIG_EP_INPUT: [0, 3, 4, 5, 6, 8, 768, 2821, 64513],
|
||||
SIG_EP_OUTPUT: [25],
|
||||
SIG_EP_PROFILE: 260,
|
||||
}
|
||||
},
|
||||
"00:11:22:33:44:55:66:77",
|
||||
|
@ -49,6 +49,7 @@ from .common import (
|
||||
get_zha_gateway,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
from tests.components.zha.common import async_wait_for_updates
|
||||
|
||||
@ -61,9 +62,10 @@ def zigpy_device(zigpy_device_mock):
|
||||
"""Device tracker zigpy device."""
|
||||
endpoints = {
|
||||
1: {
|
||||
"in_clusters": [hvac.Fan.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [hvac.Fan.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(
|
||||
@ -78,9 +80,10 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.Groups.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_INPUT: [general.Groups.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee="00:15:8d:00:02:32:4f:32",
|
||||
@ -99,13 +102,14 @@ async def device_fan_1(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.Groups.cluster_id,
|
||||
general.OnOff.cluster_id,
|
||||
hvac.Fan.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.ON_OFF_LIGHT,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
},
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE,
|
||||
@ -123,14 +127,15 @@ async def device_fan_2(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.Groups.cluster_id,
|
||||
general.OnOff.cluster_id,
|
||||
hvac.Fan.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.ON_OFF_LIGHT,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
},
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE2,
|
||||
|
@ -13,6 +13,7 @@ from homeassistant.components.zha.core.group import GroupMember
|
||||
from homeassistant.components.zha.core.store import TOMBSTONE_LIFETIME
|
||||
|
||||
from .common import async_enable_traffic, async_find_group_entity_id, get_zha_gateway
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
IEEE_GROUPABLE_DEVICE = "01:2d:6f:00:0a:90:69:e8"
|
||||
IEEE_GROUPABLE_DEVICE2 = "02:2d:6f:00:0a:90:69:e8"
|
||||
@ -24,9 +25,10 @@ def zigpy_dev_basic(zigpy_device_mock):
|
||||
return zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.Basic.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -47,9 +49,10 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_INPUT: [],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee="00:15:8d:00:02:32:4f:32",
|
||||
@ -68,14 +71,15 @@ async def device_light_1(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.OnOff.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
lighting.Color.cluster_id,
|
||||
general.Groups.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE,
|
||||
@ -92,14 +96,15 @@ async def device_light_2(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.OnOff.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
lighting.Color.cluster_id,
|
||||
general.Groups.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE2,
|
||||
|
@ -1,6 +1,6 @@
|
||||
"""Test zha light."""
|
||||
from datetime import timedelta
|
||||
from unittest.mock import AsyncMock, MagicMock, call, patch, sentinel
|
||||
from unittest.mock import AsyncMock, call, patch, sentinel
|
||||
|
||||
import pytest
|
||||
import zigpy.profiles.zha as zha
|
||||
@ -23,6 +23,7 @@ from .common import (
|
||||
get_zha_gateway,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_PROFILE, SIG_EP_TYPE
|
||||
|
||||
from tests.common import async_fire_time_changed
|
||||
from tests.components.zha.common import async_wait_for_updates
|
||||
@ -35,39 +36,42 @@ IEEE_GROUPABLE_DEVICE3 = "03:2d:6f:00:0a:90:69:e7"
|
||||
|
||||
LIGHT_ON_OFF = {
|
||||
1: {
|
||||
"device_type": zha.DeviceType.ON_OFF_LIGHT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_LIGHT,
|
||||
SIG_EP_INPUT: [
|
||||
general.Basic.cluster_id,
|
||||
general.Identify.cluster_id,
|
||||
general.OnOff.cluster_id,
|
||||
],
|
||||
"out_clusters": [general.Ota.cluster_id],
|
||||
SIG_EP_OUTPUT: [general.Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
|
||||
LIGHT_LEVEL = {
|
||||
1: {
|
||||
"device_type": zha.DeviceType.DIMMABLE_LIGHT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zha.DeviceType.DIMMABLE_LIGHT,
|
||||
SIG_EP_INPUT: [
|
||||
general.Basic.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
general.OnOff.cluster_id,
|
||||
],
|
||||
"out_clusters": [general.Ota.cluster_id],
|
||||
SIG_EP_OUTPUT: [general.Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
|
||||
LIGHT_COLOR = {
|
||||
1: {
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
"in_clusters": [
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_INPUT: [
|
||||
general.Basic.cluster_id,
|
||||
general.Identify.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
general.OnOff.cluster_id,
|
||||
lighting.Color.cluster_id,
|
||||
],
|
||||
"out_clusters": [general.Ota.cluster_id],
|
||||
SIG_EP_OUTPUT: [general.Ota.cluster_id],
|
||||
}
|
||||
}
|
||||
|
||||
@ -79,9 +83,10 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.Groups.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_INPUT: [general.Groups.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee="00:15:8d:00:02:32:4f:32",
|
||||
@ -100,15 +105,16 @@ async def device_light_1(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.OnOff.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
lighting.Color.cluster_id,
|
||||
general.Groups.cluster_id,
|
||||
general.Identify.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE,
|
||||
@ -126,15 +132,16 @@ async def device_light_2(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.OnOff.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
lighting.Color.cluster_id,
|
||||
general.Groups.cluster_id,
|
||||
general.Identify.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE2,
|
||||
@ -152,15 +159,16 @@ async def device_light_3(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
general.OnOff.cluster_id,
|
||||
general.LevelControl.cluster_id,
|
||||
lighting.Color.cluster_id,
|
||||
general.Groups.cluster_id,
|
||||
general.Identify.cluster_id,
|
||||
],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_PROFILE: zha.PROFILE_ID,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE3,
|
||||
@ -171,14 +179,14 @@ async def device_light_3(hass, zigpy_device_mock, zha_device_joined):
|
||||
return zha_device
|
||||
|
||||
|
||||
@patch("zigpy.zcl.clusters.general.OnOff.read_attributes", new=MagicMock())
|
||||
async def test_light_refresh(hass, zigpy_device_mock, zha_device_joined_restored):
|
||||
"""Test zha light platform refresh."""
|
||||
|
||||
# create zigpy devices
|
||||
zigpy_device = zigpy_device_mock(LIGHT_ON_OFF)
|
||||
zha_device = await zha_device_joined_restored(zigpy_device)
|
||||
on_off_cluster = zigpy_device.endpoints[1].on_off
|
||||
on_off_cluster.PLUGGED_ATTR_READS = {"on_off": 0}
|
||||
zha_device = await zha_device_joined_restored(zigpy_device)
|
||||
entity_id = await find_entity_id(DOMAIN, zha_device, hass)
|
||||
|
||||
# allow traffic to flow through the gateway and device
|
||||
@ -193,7 +201,7 @@ async def test_light_refresh(hass, zigpy_device_mock, zha_device_joined_restored
|
||||
assert hass.states.get(entity_id).state == STATE_OFF
|
||||
|
||||
# 1 interval - 1 call
|
||||
on_off_cluster.read_attributes.return_value = [{"on_off": 1}, {}]
|
||||
on_off_cluster.PLUGGED_ATTR_READS = {"on_off": 1}
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=80))
|
||||
await hass.async_block_till_done()
|
||||
assert on_off_cluster.read_attributes.call_count == 1
|
||||
@ -201,7 +209,7 @@ async def test_light_refresh(hass, zigpy_device_mock, zha_device_joined_restored
|
||||
assert hass.states.get(entity_id).state == STATE_ON
|
||||
|
||||
# 2 intervals - 2 calls
|
||||
on_off_cluster.read_attributes.return_value = [{"on_off": 0}, {}]
|
||||
on_off_cluster.PLUGGED_ATTR_READS = {"on_off": 0}
|
||||
async_fire_time_changed(hass, dt_util.utcnow() + timedelta(minutes=80))
|
||||
await hass.async_block_till_done()
|
||||
assert on_off_cluster.read_attributes.call_count == 2
|
||||
|
@ -11,6 +11,7 @@ from homeassistant.components.lock import DOMAIN
|
||||
from homeassistant.const import STATE_LOCKED, STATE_UNAVAILABLE, STATE_UNLOCKED
|
||||
|
||||
from .common import async_enable_traffic, find_entity_id, send_attributes_report
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
||||
|
||||
from tests.common import mock_coro
|
||||
|
||||
@ -28,9 +29,9 @@ async def lock(hass, zigpy_device_mock, zha_device_joined_restored):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [closures.DoorLock.cluster_id, general.Basic.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.DOOR_LOCK,
|
||||
SIG_EP_INPUT: [closures.DoorLock.cluster_id, general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.DOOR_LOCK,
|
||||
}
|
||||
},
|
||||
)
|
||||
|
@ -17,6 +17,7 @@ from .common import (
|
||||
find_entity_id,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
||||
|
||||
from tests.common import mock_coro
|
||||
|
||||
@ -27,9 +28,9 @@ def zigpy_analog_output_device(zigpy_device_mock):
|
||||
|
||||
endpoints = {
|
||||
1: {
|
||||
"device_type": zigpy.profiles.zha.DeviceType.LEVEL_CONTROL_SWITCH,
|
||||
"in_clusters": [general.AnalogOutput.cluster_id, general.Basic.cluster_id],
|
||||
"out_clusters": [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.LEVEL_CONTROL_SWITCH,
|
||||
SIG_EP_INPUT: [general.AnalogOutput.cluster_id, general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(endpoints)
|
||||
|
@ -34,6 +34,7 @@ from .common import (
|
||||
send_attribute_report,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
||||
|
||||
|
||||
async def async_test_humidity(hass, cluster, entity_id):
|
||||
@ -163,9 +164,9 @@ async def test_sensor(
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [cluster_id, general.Basic.cluster_id],
|
||||
"out_cluster": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [cluster_id, general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -284,12 +285,12 @@ async def test_temp_uom(
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [
|
||||
SIG_EP_INPUT: [
|
||||
measurement.TemperatureMeasurement.cluster_id,
|
||||
general.Basic.cluster_id,
|
||||
],
|
||||
"out_cluster": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
}
|
||||
)
|
||||
@ -327,9 +328,9 @@ async def test_electrical_measurement_init(
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [cluster_id, general.Basic.cluster_id],
|
||||
"out_cluster": [],
|
||||
"device_type": zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [cluster_id, general.Basic.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zigpy.profiles.zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
}
|
||||
)
|
||||
|
@ -18,6 +18,7 @@ from .common import (
|
||||
get_zha_gateway,
|
||||
send_attributes_report,
|
||||
)
|
||||
from .conftest import SIG_EP_INPUT, SIG_EP_OUTPUT, SIG_EP_TYPE
|
||||
|
||||
from tests.common import mock_coro
|
||||
from tests.components.zha.common import async_wait_for_updates
|
||||
@ -33,9 +34,9 @@ def zigpy_device(zigpy_device_mock):
|
||||
"""Device tracker zigpy device."""
|
||||
endpoints = {
|
||||
1: {
|
||||
"in_clusters": [general.Basic.cluster_id, general.OnOff.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [general.Basic.cluster_id, general.OnOff.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
}
|
||||
return zigpy_device_mock(endpoints)
|
||||
@ -48,9 +49,9 @@ async def coordinator(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
SIG_EP_INPUT: [],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.COLOR_DIMMABLE_LIGHT,
|
||||
}
|
||||
},
|
||||
ieee="00:15:8d:00:02:32:4f:32",
|
||||
@ -69,9 +70,9 @@ async def device_switch_1(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.OnOff.cluster_id, general.Groups.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [general.OnOff.cluster_id, general.Groups.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE,
|
||||
@ -89,9 +90,9 @@ async def device_switch_2(hass, zigpy_device_mock, zha_device_joined):
|
||||
zigpy_device = zigpy_device_mock(
|
||||
{
|
||||
1: {
|
||||
"in_clusters": [general.OnOff.cluster_id, general.Groups.cluster_id],
|
||||
"out_clusters": [],
|
||||
"device_type": zha.DeviceType.ON_OFF_SWITCH,
|
||||
SIG_EP_INPUT: [general.OnOff.cluster_id, general.Groups.cluster_id],
|
||||
SIG_EP_OUTPUT: [],
|
||||
SIG_EP_TYPE: zha.DeviceType.ON_OFF_SWITCH,
|
||||
}
|
||||
},
|
||||
ieee=IEEE_GROUPABLE_DEVICE2,
|
||||
|
File diff suppressed because it is too large
Load Diff
Loading…
x
Reference in New Issue
Block a user