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:
Alexei Chetroi 2021-09-06 19:00:06 -04:00 committed by GitHub
parent b1dbdec2ea
commit c6888e4faf
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
22 changed files with 2614 additions and 2592 deletions

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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(

View File

@ -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,

View File

@ -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: [],
}
}

View File

@ -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",

View File

@ -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"

View File

@ -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(

View File

@ -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",

View File

@ -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,
}
},
)

View File

@ -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)

View File

@ -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,
}
}
)

View File

@ -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",

View File

@ -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,

View File

@ -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,

View File

@ -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

View File

@ -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,
}
},
)

View File

@ -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)

View File

@ -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,
}
}
)

View File

@ -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