diff --git a/homeassistant/components/zha/core/const.py b/homeassistant/components/zha/core/const.py index 5edcadc7fce9..faa423d8ac43 100644 --- a/homeassistant/components/zha/core/const.py +++ b/homeassistant/components/zha/core/const.py @@ -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 diff --git a/homeassistant/components/zha/core/device.py b/homeassistant/components/zha/core/device.py index 7c972988e9c3..7bb39f943f66 100644 --- a/homeassistant/components/zha/core/device.py +++ b/homeassistant/components/zha/core/device.py @@ -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): diff --git a/homeassistant/components/zha/core/gateway.py b/homeassistant/components/zha/core/gateway.py index ff3c374a8509..391b12189cf2 100644 --- a/homeassistant/components/zha/core/gateway.py +++ b/homeassistant/components/zha/core/gateway.py @@ -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 diff --git a/homeassistant/components/zha/core/listeners.py b/homeassistant/components/zha/core/listeners.py index 1b240d499b48..f8d24ce903c8 100644 --- a/homeassistant/components/zha/core/listeners.py +++ b/homeassistant/components/zha/core/listeners.py @@ -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 diff --git a/homeassistant/components/zha/sensor.py b/homeassistant/components/zha/sensor.py index ad566df00f44..9c00d8124bb3 100644 --- a/homeassistant/components/zha/sensor.py +++ b/homeassistant/components/zha/sensor.py @@ -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 } diff --git a/tests/components/zha/common.py b/tests/components/zha/common.py index f0e1aa701e76..cd2eb53c3fe7 100644 --- a/tests/components/zha/common.py +++ b/tests/components/zha/common.py @@ -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), diff --git a/tests/components/zha/test_api.py b/tests/components/zha/test_api.py index ad139d81ddf0..616a94e8b899 100644 --- a/tests/components/zha/test_api.py +++ b/tests/components/zha/test_api.py @@ -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' diff --git a/tests/components/zha/test_binary_sensor.py b/tests/components/zha/test_binary_sensor.py index c81f96468ce6..d0763b8fb102 100644 --- a/tests/components/zha/test_binary_sensor.py +++ b/tests/components/zha/test_binary_sensor.py @@ -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, diff --git a/tests/components/zha/test_fan.py b/tests/components/zha/test_fan.py index 6beafc6ca8e3..a70e0e5ea400 100644 --- a/tests/components/zha/test_fan.py +++ b/tests/components/zha/test_fan.py @@ -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( diff --git a/tests/components/zha/test_light.py b/tests/components/zha/test_light.py index 9c5e69d1347e..38d7caedaad5 100644 --- a/tests/components/zha/test_light.py +++ b/tests/components/zha/test_light.py @@ -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, diff --git a/tests/components/zha/test_sensor.py b/tests/components/zha/test_sensor.py index d16cafb7df89..c348ef0d0a71 100644 --- a/tests/components/zha/test_sensor.py +++ b/tests/components/zha/test_sensor.py @@ -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)) diff --git a/tests/components/zha/test_switch.py b/tests/components/zha/test_switch.py index 32c8ee64e678..1fc21e34cd83 100644 --- a/tests/components/zha/test_switch.py +++ b/tests/components/zha/test_switch.py @@ -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(