Add power source to device and clean up zha listeners (#21174)

check available and add comments

ensure order on API test
This commit is contained in:
David F. Mulcahey 2019-02-18 10:55:41 -05:00 committed by Paulus Schoutsen
parent 8b5aff63ae
commit d1fa341a78
12 changed files with 179 additions and 58 deletions

View File

@ -62,7 +62,6 @@ ILLUMINANCE = 'illuminance'
PRESSURE = 'pressure'
METERING = 'metering'
ELECTRICAL_MEASUREMENT = 'electrical_measurement'
POWER_CONFIGURATION = 'power_configuration'
GENERIC = 'generic'
UNKNOWN = 'unknown'
OPENING = 'opening'
@ -73,6 +72,7 @@ ATTR_LEVEL = 'level'
LISTENER_ON_OFF = 'on_off'
LISTENER_ATTRIBUTE = 'attribute'
LISTENER_BASIC = 'basic'
LISTENER_COLOR = 'color'
LISTENER_FAN = 'fan'
LISTENER_LEVEL = ATTR_LEVEL
@ -113,6 +113,7 @@ CLUSTER_REPORT_CONFIGS = {}
CUSTOM_CLUSTER_MAPPINGS = {}
COMPONENT_CLUSTERS = {}
EVENT_RELAY_CLUSTERS = []
NO_SENSOR_CLUSTERS = []
REPORT_CONFIG_MAX_INT = 900
REPORT_CONFIG_MAX_INT_BATTERY_SAVE = 10800

View File

@ -15,9 +15,9 @@ from .const import (
ATTR_CLUSTER_ID, ATTR_ATTRIBUTE, ATTR_VALUE, ATTR_COMMAND, SERVER,
ATTR_COMMAND_TYPE, ATTR_ARGS, CLIENT_COMMANDS, SERVER_COMMANDS,
ATTR_ENDPOINT_ID, IEEE, MODEL, NAME, UNKNOWN, QUIRK_APPLIED,
QUIRK_CLASS
QUIRK_CLASS, LISTENER_BASIC
)
from .listeners import EventRelayListener
from .listeners import EventRelayListener, BasicListener
_LOGGER = logging.getLogger(__name__)
@ -59,6 +59,7 @@ class ZHADevice:
self._zigpy_device.__class__.__module__,
self._zigpy_device.__class__.__name__
)
self.power_source = None
@property
def name(self):
@ -177,6 +178,13 @@ class ZHADevice:
"""Initialize listeners."""
_LOGGER.debug('%s: started initialization', self.name)
await self._execute_listener_tasks('async_initialize', from_cache)
self.power_source = self.cluster_listeners.get(
LISTENER_BASIC).get_power_source()
_LOGGER.debug(
'%s: power source: %s',
self.name,
BasicListener.POWER_SOURCES.get(self.power_source)
)
_LOGGER.debug('%s: completed initialization', self.name)
async def _execute_listener_tasks(self, task_name, *args):

View File

@ -18,15 +18,15 @@ from .const import (
ZHA_DISCOVERY_NEW, DEVICE_CLASS, SINGLE_INPUT_CLUSTER_DEVICE_CLASS,
SINGLE_OUTPUT_CLUSTER_DEVICE_CLASS, COMPONENT_CLUSTERS, HUMIDITY,
TEMPERATURE, ILLUMINANCE, PRESSURE, METERING, ELECTRICAL_MEASUREMENT,
POWER_CONFIGURATION, GENERIC, SENSOR_TYPE, EVENT_RELAY_CLUSTERS,
LISTENER_BATTERY, UNKNOWN, OPENING, ZONE, OCCUPANCY,
CLUSTER_REPORT_CONFIGS, REPORT_CONFIG_IMMEDIATE, REPORT_CONFIG_ASAP,
REPORT_CONFIG_DEFAULT, REPORT_CONFIG_MIN_INT, REPORT_CONFIG_MAX_INT,
REPORT_CONFIG_OP, SIGNAL_REMOVE)
GENERIC, SENSOR_TYPE, EVENT_RELAY_CLUSTERS, LISTENER_BATTERY, UNKNOWN,
OPENING, ZONE, OCCUPANCY, CLUSTER_REPORT_CONFIGS, REPORT_CONFIG_IMMEDIATE,
REPORT_CONFIG_ASAP, REPORT_CONFIG_DEFAULT, REPORT_CONFIG_MIN_INT,
REPORT_CONFIG_MAX_INT, REPORT_CONFIG_OP, SIGNAL_REMOVE, NO_SENSOR_CLUSTERS)
from .device import ZHADevice
from ..device_entity import ZhaDeviceEntity
from .listeners import (
LISTENER_REGISTRY, AttributeListener, EventRelayListener, ZDOListener)
LISTENER_REGISTRY, AttributeListener, EventRelayListener, ZDOListener,
BasicListener)
from .helpers import convert_ieee
_LOGGER = logging.getLogger(__name__)
@ -165,7 +165,21 @@ class ZHAGateway:
await self._component.async_add_entities([device_entity])
if is_new_join:
# because it's a new join we can immediately mark the device as
# available and we already loaded fresh state above
zha_device.update_available(True)
elif not zha_device.available and zha_device.power_source is not None\
and zha_device.power_source != BasicListener.BATTERY:
# the device is currently marked unavailable and it isn't a battery
# powered device so we should be able to update it now
_LOGGER.debug(
"attempting to request fresh state for %s %s",
zha_device.name,
"with power source: {}".format(
BasicListener.POWER_SOURCES.get(zha_device.power_source)
)
)
await zha_device.async_initialize(from_cache=False)
async def _async_process_endpoint(
self, endpoint_id, endpoint, discovery_infos, device, zha_device,
@ -312,6 +326,13 @@ async def _handle_single_cluster_matches(hass, endpoint, zha_device,
is_new_join,
))
if cluster.cluster_id in NO_SENSOR_CLUSTERS:
cluster_match_tasks.append(_handle_listener_only_cluster_match(
zha_device,
cluster,
is_new_join,
))
for cluster in endpoint.out_clusters.values():
if cluster.cluster_id not in profile_clusters[1]:
cluster_match_tasks.append(_handle_single_cluster_match(
@ -338,6 +359,12 @@ async def _handle_single_cluster_matches(hass, endpoint, zha_device,
return cluster_matches
async def _handle_listener_only_cluster_match(
zha_device, cluster, is_new_join):
"""Handle a listener only cluster match."""
await _create_cluster_listener(cluster, zha_device, is_new_join)
async def _handle_single_cluster_match(hass, zha_device, cluster, device_key,
device_classes, is_new_join):
"""Dispatch a single cluster match to a HA component."""
@ -352,11 +379,6 @@ async def _handle_single_cluster_match(hass, zha_device, cluster, device_key,
listeners = []
await _create_cluster_listener(cluster, zha_device, is_new_join,
listeners=listeners)
# don't actually create entities for PowerConfiguration
# find a better way to do this without abusing single cluster reg
from zigpy.zcl.clusters.general import PowerConfiguration
if cluster.cluster_id == PowerConfiguration.cluster_id:
return
cluster_key = "{}-{}".format(device_key, cluster.cluster_id)
discovery_info = {
@ -405,6 +427,10 @@ def establish_device_mappings():
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.LevelControl.cluster_id)
EVENT_RELAY_CLUSTERS.append(zcl.clusters.general.OnOff.cluster_id)
NO_SENSOR_CLUSTERS.append(zcl.clusters.general.Basic.cluster_id)
NO_SENSOR_CLUSTERS.append(
zcl.clusters.general.PowerConfiguration.cluster_id)
DEVICE_CLASS[zha.PROFILE_ID].update({
zha.DeviceType.ON_OFF_SWITCH: 'binary_sensor',
zha.DeviceType.LEVEL_CONTROL_SWITCH: 'binary_sensor',
@ -442,7 +468,6 @@ def establish_device_mappings():
zcl.clusters.measurement.IlluminanceMeasurement: 'sensor',
zcl.clusters.smartenergy.Metering: 'sensor',
zcl.clusters.homeautomation.ElectricalMeasurement: 'sensor',
zcl.clusters.general.PowerConfiguration: 'sensor',
zcl.clusters.security.IasZone: 'binary_sensor',
zcl.clusters.measurement.OccupancySensing: 'binary_sensor',
zcl.clusters.hvac.Fan: 'fan',
@ -462,8 +487,6 @@ def establish_device_mappings():
zcl.clusters.smartenergy.Metering.cluster_id: METERING,
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id:
ELECTRICAL_MEASUREMENT,
zcl.clusters.general.PowerConfiguration.cluster_id:
POWER_CONFIGURATION,
})
BINARY_SENSOR_TYPES.update({
@ -473,6 +496,19 @@ def establish_device_mappings():
})
CLUSTER_REPORT_CONFIGS.update({
zcl.clusters.general.Alarms.cluster_id: [],
zcl.clusters.general.Basic.cluster_id: [],
zcl.clusters.general.Commissioning.cluster_id: [],
zcl.clusters.general.Identify.cluster_id: [],
zcl.clusters.general.Groups.cluster_id: [],
zcl.clusters.general.Scenes.cluster_id: [],
zcl.clusters.general.Partition.cluster_id: [],
zcl.clusters.general.Ota.cluster_id: [],
zcl.clusters.general.PowerProfile.cluster_id: [],
zcl.clusters.general.ApplianceControl.cluster_id: [],
zcl.clusters.general.PollControl.cluster_id: [],
zcl.clusters.general.GreenPowerProxy.cluster_id: [],
zcl.clusters.general.OnOffConfiguration.cluster_id: [],
zcl.clusters.general.OnOff.cluster_id: [{
'attr': 'on_off',
'config': REPORT_CONFIG_IMMEDIATE

View File

@ -18,7 +18,10 @@ from .helpers import (
safe_read, get_attr_id_by_name, bind_cluster)
from .const import (
CLUSTER_REPORT_CONFIGS, REPORT_CONFIG_DEFAULT, SIGNAL_ATTR_UPDATED,
SIGNAL_MOVE_LEVEL, SIGNAL_SET_LEVEL, SIGNAL_STATE_ATTR, ATTR_LEVEL
SIGNAL_MOVE_LEVEL, SIGNAL_SET_LEVEL, SIGNAL_STATE_ATTR, LISTENER_BASIC,
LISTENER_ATTRIBUTE, LISTENER_ON_OFF, LISTENER_COLOR, LISTENER_FAN,
LISTENER_LEVEL, LISTENER_ZONE, LISTENER_ACTIVE_POWER, LISTENER_BATTERY,
LISTENER_EVENT_RELAY
)
LISTENER_REGISTRY = {}
@ -30,12 +33,25 @@ def populate_listener_registry():
"""Populate the listener registry."""
from zigpy import zcl
LISTENER_REGISTRY.update({
zcl.clusters.general.Alarms.cluster_id: ClusterListener,
zcl.clusters.general.Commissioning.cluster_id: ClusterListener,
zcl.clusters.general.Identify.cluster_id: ClusterListener,
zcl.clusters.general.Groups.cluster_id: ClusterListener,
zcl.clusters.general.Scenes.cluster_id: ClusterListener,
zcl.clusters.general.Partition.cluster_id: ClusterListener,
zcl.clusters.general.Ota.cluster_id: ClusterListener,
zcl.clusters.general.PowerProfile.cluster_id: ClusterListener,
zcl.clusters.general.ApplianceControl.cluster_id: ClusterListener,
zcl.clusters.general.PollControl.cluster_id: ClusterListener,
zcl.clusters.general.GreenPowerProxy.cluster_id: ClusterListener,
zcl.clusters.general.OnOffConfiguration.cluster_id: ClusterListener,
zcl.clusters.general.OnOff.cluster_id: OnOffListener,
zcl.clusters.general.LevelControl.cluster_id: LevelListener,
zcl.clusters.lighting.Color.cluster_id: ColorListener,
zcl.clusters.homeautomation.ElectricalMeasurement.cluster_id:
ActivePowerListener,
zcl.clusters.general.PowerConfiguration.cluster_id: BatteryListener,
zcl.clusters.general.Basic.cluster_id: BasicListener,
zcl.clusters.security.IasZone.cluster_id: IASZoneListener,
zcl.clusters.hvac.Fan.cluster_id: FanListener,
})
@ -92,6 +108,7 @@ class ClusterListener:
def __init__(self, cluster, device):
"""Initialize ClusterListener."""
self.name = 'cluster_{}'.format(cluster.cluster_id)
self._cluster = cluster
self._zha_device = device
self._unique_id = construct_unique_id(cluster)
@ -216,11 +233,10 @@ class ClusterListener:
class AttributeListener(ClusterListener):
"""Listener for the attribute reports cluster."""
name = 'attribute'
def __init__(self, cluster, device):
"""Initialize AttributeListener."""
super().__init__(cluster, device)
self.name = LISTENER_ATTRIBUTE
attr = self._report_config[0].get('attr')
if isinstance(attr, str):
self._value_attribute = get_attr_id_by_name(self.cluster, attr)
@ -247,13 +263,12 @@ class AttributeListener(ClusterListener):
class OnOffListener(ClusterListener):
"""Listener for the OnOff Zigbee cluster."""
name = 'on_off'
ON_OFF = 0
def __init__(self, cluster, device):
"""Initialize ClusterListener."""
"""Initialize OnOffListener."""
super().__init__(cluster, device)
self.name = LISTENER_ON_OFF
self._state = None
@callback
@ -295,10 +310,13 @@ class OnOffListener(ClusterListener):
class LevelListener(ClusterListener):
"""Listener for the LevelControl Zigbee cluster."""
name = ATTR_LEVEL
CURRENT_LEVEL = 0
def __init__(self, cluster, device):
"""Initialize LevelListener."""
super().__init__(cluster, device)
self.name = LISTENER_LEVEL
@callback
def cluster_command(self, tsn, command_id, args):
"""Handle commands received to this cluster."""
@ -350,7 +368,10 @@ class LevelListener(ClusterListener):
class IASZoneListener(ClusterListener):
"""Listener for the IASZone Zigbee cluster."""
name = 'zone'
def __init__(self, cluster, device):
"""Initialize LevelListener."""
super().__init__(cluster, device)
self.name = LISTENER_ZONE
@callback
def cluster_command(self, tsn, command_id, args):
@ -415,7 +436,10 @@ class IASZoneListener(ClusterListener):
class ActivePowerListener(AttributeListener):
"""Listener that polls active power level."""
name = 'active_power'
def __init__(self, cluster, device):
"""Initialize ActivePowerListener."""
super().__init__(cluster, device)
self.name = LISTENER_ACTIVE_POWER
async def async_update(self):
"""Retrieve latest state."""
@ -423,7 +447,7 @@ class ActivePowerListener(AttributeListener):
# This is a polling listener. Don't allow cache.
result = await self.get_attribute_value(
'active_power', from_cache=False)
LISTENER_ACTIVE_POWER, from_cache=False)
async_dispatcher_send(
self._zha_device.hass,
"{}_{}".format(self.unique_id, SIGNAL_ATTR_UPDATED),
@ -433,14 +457,53 @@ class ActivePowerListener(AttributeListener):
async def async_initialize(self, from_cache):
"""Initialize listener."""
await self.get_attribute_value(
'active_power', from_cache=from_cache)
LISTENER_ACTIVE_POWER, from_cache=from_cache)
await super().async_initialize(from_cache)
class BasicListener(ClusterListener):
"""Listener to interact with the basic cluster."""
BATTERY = 3
POWER_SOURCES = {
0: 'Unknown',
1: 'Mains (single phase)',
2: 'Mains (3 phase)',
BATTERY: 'Battery',
4: 'DC source',
5: 'Emergency mains constantly powered',
6: 'Emergency mains and transfer switch'
}
def __init__(self, cluster, device):
"""Initialize BasicListener."""
super().__init__(cluster, device)
self.name = LISTENER_BASIC
self._power_source = None
async def async_configure(self):
"""Configure this listener."""
await super().async_configure()
await self.async_initialize(False)
async def async_initialize(self, from_cache):
"""Initialize listener."""
self._power_source = await self.get_attribute_value(
'power_source', from_cache=from_cache)
await super().async_initialize(from_cache)
def get_power_source(self):
"""Get the power source."""
return self._power_source
class BatteryListener(ClusterListener):
"""Listener that polls active power level."""
name = 'battery'
def __init__(self, cluster, device):
"""Initialize BatteryListener."""
super().__init__(cluster, device)
self.name = LISTENER_BATTERY
@callback
def attribute_updated(self, attrid, value):
@ -480,7 +543,10 @@ class BatteryListener(ClusterListener):
class EventRelayListener(ClusterListener):
"""Event relay that can be attached to zigbee clusters."""
name = 'event_relay'
def __init__(self, cluster, device):
"""Initialize EventRelayListener."""
super().__init__(cluster, device)
self.name = LISTENER_EVENT_RELAY
@callback
def attribute_updated(self, attrid, value):
@ -512,15 +578,14 @@ class EventRelayListener(ClusterListener):
class ColorListener(ClusterListener):
"""Color listener."""
name = 'color'
CAPABILITIES_COLOR_XY = 0x08
CAPABILITIES_COLOR_TEMP = 0x10
UNSUPPORTED_ATTRIBUTE = 0x86
def __init__(self, cluster, device):
"""Initialize ClusterListener."""
"""Initialize ColorListener."""
super().__init__(cluster, device)
self.name = LISTENER_COLOR
self._color_capabilities = None
def get_color_capabilities(self):
@ -550,10 +615,13 @@ class ColorListener(ClusterListener):
class FanListener(ClusterListener):
"""Fan listener."""
name = 'fan'
_value_attribute = 0
def __init__(self, cluster, device):
"""Initialize FanListener."""
super().__init__(cluster, device)
self.name = LISTENER_FAN
async def async_set_speed(self, value) -> None:
"""Set the speed of the fan."""
from zigpy.exceptions import DeliveryError
@ -595,10 +663,9 @@ class FanListener(ClusterListener):
class ZDOListener:
"""Listener for ZDO events."""
name = 'zdo'
def __init__(self, cluster, device):
"""Initialize ClusterListener."""
"""Initialize ZDOListener."""
self.name = 'zdo'
self._cluster = cluster
self._zha_device = device
self._status = ListenerStatus.CREATED

View File

@ -12,8 +12,8 @@ from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .core.const import (
DATA_ZHA, DATA_ZHA_DISPATCHERS, ZHA_DISCOVERY_NEW, HUMIDITY, TEMPERATURE,
ILLUMINANCE, PRESSURE, METERING, ELECTRICAL_MEASUREMENT,
POWER_CONFIGURATION, GENERIC, SENSOR_TYPE, LISTENER_ATTRIBUTE,
LISTENER_ACTIVE_POWER, SIGNAL_ATTR_UPDATED, SIGNAL_STATE_ATTR)
GENERIC, SENSOR_TYPE, LISTENER_ATTRIBUTE, LISTENER_ACTIVE_POWER,
SIGNAL_ATTR_UPDATED, SIGNAL_STATE_ATTR)
from .entity import ZhaEntity
_LOGGER = logging.getLogger(__name__)
@ -71,7 +71,6 @@ UNIT_REGISTRY = {
ILLUMINANCE: 'lx',
METERING: 'W',
ELECTRICAL_MEASUREMENT: 'W',
POWER_CONFIGURATION: '%',
GENERIC: None
}

View File

@ -174,6 +174,7 @@ async def async_test_device_join(
only trigger during device joins can be tested.
"""
from zigpy.zcl.foundation import Status
from zigpy.zcl.clusters.general import Basic
# create zigpy device mocking out the zigbee network operations
with patch(
'zigpy.zcl.Cluster.configure_reporting',
@ -182,7 +183,8 @@ async def async_test_device_join(
'zigpy.zcl.Cluster.bind',
return_value=mock_coro([Status.SUCCESS, Status.SUCCESS])):
zigpy_device = await async_init_zigpy_device(
hass, [cluster_id], [], device_type, zha_gateway,
hass, [cluster_id, Basic.cluster_id], [], device_type,
zha_gateway,
ieee="00:0d:6f:00:0a:90:69:f7",
manufacturer="FakeMan{}".format(cluster_id),
model="FakeMod{}".format(cluster_id),

View File

@ -17,14 +17,14 @@ from .common import async_init_zigpy_device
@pytest.fixture
async def zha_client(hass, config_entry, zha_gateway, hass_ws_client):
"""Test zha switch platform."""
from zigpy.zcl.clusters.general import OnOff
from zigpy.zcl.clusters.general import OnOff, Basic
# load the ZHA API
async_load_api(hass, Mock(), zha_gateway)
# create zigpy device
await async_init_zigpy_device(
hass, [OnOff.cluster_id], [], None, zha_gateway)
hass, [OnOff.cluster_id, Basic.cluster_id], [], None, zha_gateway)
# load up switch domain
await hass.config_entries.async_forward_entry_setup(
@ -44,10 +44,16 @@ async def test_device_clusters(hass, config_entry, zha_gateway, zha_client):
msg = await zha_client.receive_json()
assert len(msg['result']) == 1
assert len(msg['result']) == 2
cluster_info = msg['result'][0]
cluster_infos = sorted(msg['result'], key=lambda k: k[ID])
cluster_info = cluster_infos[0]
assert cluster_info[TYPE] == IN
assert cluster_info[ID] == 0
assert cluster_info[NAME] == 'Basic'
cluster_info = cluster_infos[1]
assert cluster_info[TYPE] == IN
assert cluster_info[ID] == 6
assert cluster_info[NAME] == 'OnOff'

View File

@ -11,13 +11,13 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
"""Test zha binary_sensor platform."""
from zigpy.zcl.clusters.security import IasZone
from zigpy.zcl.clusters.measurement import OccupancySensing
from zigpy.zcl.clusters.general import OnOff, LevelControl
from zigpy.zcl.clusters.general import OnOff, LevelControl, Basic
from zigpy.profiles.zha import DeviceType
# create zigpy devices
zigpy_device_zone = await async_init_zigpy_device(
hass,
[IasZone.cluster_id],
[IasZone.cluster_id, Basic.cluster_id],
[],
None,
zha_gateway
@ -25,7 +25,7 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
zigpy_device_remote = await async_init_zigpy_device(
hass,
[],
[Basic.cluster_id],
[OnOff.cluster_id, LevelControl.cluster_id],
DeviceType.LEVEL_CONTROL_SWITCH,
zha_gateway,
@ -36,7 +36,7 @@ async def test_binary_sensor(hass, config_entry, zha_gateway):
zigpy_device_occupancy = await async_init_zigpy_device(
hass,
[OccupancySensing.cluster_id],
[OccupancySensing.cluster_id, Basic.cluster_id],
[],
None,
zha_gateway,

View File

@ -17,11 +17,12 @@ from .common import (
async def test_fan(hass, config_entry, zha_gateway):
"""Test zha fan platform."""
from zigpy.zcl.clusters.hvac import Fan
from zigpy.zcl.clusters.general import Basic
from zigpy.zcl.foundation import Status
# create zigpy device
zigpy_device = await async_init_zigpy_device(
hass, [Fan.cluster_id], [], None, zha_gateway)
hass, [Fan.cluster_id, Basic.cluster_id], [], None, zha_gateway)
# load up fan domain
await hass.config_entries.async_forward_entry_setup(

View File

@ -14,13 +14,13 @@ OFF = 0
async def test_light(hass, config_entry, zha_gateway):
"""Test zha light platform."""
from zigpy.zcl.clusters.general import OnOff, LevelControl
from zigpy.zcl.clusters.general import OnOff, LevelControl, Basic
from zigpy.profiles.zha import DeviceType
# create zigpy devices
zigpy_device_on_off = await async_init_zigpy_device(
hass,
[OnOff.cluster_id],
[OnOff.cluster_id, Basic.cluster_id],
[],
DeviceType.ON_OFF_LIGHT,
zha_gateway
@ -28,7 +28,7 @@ async def test_light(hass, config_entry, zha_gateway):
zigpy_device_level = await async_init_zigpy_device(
hass,
[OnOff.cluster_id, LevelControl.cluster_id],
[OnOff.cluster_id, LevelControl.cluster_id, Basic.cluster_id],
[],
DeviceType.ON_OFF_LIGHT,
zha_gateway,

View File

@ -86,6 +86,7 @@ async def async_build_devices(hass, zha_gateway, config_entry, cluster_ids):
A dict containing relevant device info for testing is returned. It contains
the entity id, zigpy device, and the zigbee cluster for the sensor.
"""
from zigpy.zcl.clusters.general import Basic
device_infos = {}
counter = 0
for cluster_id in cluster_ids:
@ -93,7 +94,7 @@ async def async_build_devices(hass, zha_gateway, config_entry, cluster_ids):
device_infos[cluster_id] = {"zigpy_device": None}
device_infos[cluster_id]["zigpy_device"] = await \
async_init_zigpy_device(
hass, [cluster_id], [], None, zha_gateway,
hass, [cluster_id, Basic.cluster_id], [], None, zha_gateway,
ieee="{}0:15:8d:00:02:32:4f:32".format(counter),
manufacturer="Fake{}".format(cluster_id),
model="FakeModel{}".format(cluster_id))

View File

@ -14,12 +14,12 @@ OFF = 0
async def test_switch(hass, config_entry, zha_gateway):
"""Test zha switch platform."""
from zigpy.zcl.clusters.general import OnOff
from zigpy.zcl.clusters.general import OnOff, Basic
from zigpy.zcl.foundation import Status
# create zigpy device
zigpy_device = await async_init_zigpy_device(
hass, [OnOff.cluster_id], [], None, zha_gateway)
hass, [OnOff.cluster_id, Basic.cluster_id], [], None, zha_gateway)
# load up switch domain
await hass.config_entries.async_forward_entry_setup(