From 592d30d495c6ce567a16e97a6a9bb0882c67353e Mon Sep 17 00:00:00 2001 From: "David F. Mulcahey" Date: Fri, 7 Jun 2019 11:13:55 -0400 Subject: [PATCH] Remove binary sensors for ZHA remotes and controllers (#24370) * remove remote binary sensor profiles * fix contact sensors --- homeassistant/components/zha/binary_sensor.py | 66 +++++-------------- .../components/zha/core/registries.py | 16 +---- tests/components/zha/test_binary_sensor.py | 62 +---------------- 3 files changed, 21 insertions(+), 123 deletions(-) diff --git a/homeassistant/components/zha/binary_sensor.py b/homeassistant/components/zha/binary_sensor.py index e9fa25c2577..c3e6208d824 100644 --- a/homeassistant/components/zha/binary_sensor.py +++ b/homeassistant/components/zha/binary_sensor.py @@ -1,27 +1,31 @@ """Binary sensors on Zigbee Home Automation networks.""" import logging -from homeassistant.components.binary_sensor import DOMAIN, BinarySensorDevice +from homeassistant.components.binary_sensor import ( + DOMAIN, BinarySensorDevice, DEVICE_CLASS_MOVING, DEVICE_CLASS_MOTION, + DEVICE_CLASS_OPENING, DEVICE_CLASS_MOISTURE, DEVICE_CLASS_SMOKE, + DEVICE_CLASS_GAS, DEVICE_CLASS_VIBRATION, DEVICE_CLASS_OCCUPANCY +) from homeassistant.const import STATE_ON from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from .core.const import ( DATA_ZHA, DATA_ZHA_DISPATCHERS, ZHA_DISCOVERY_NEW, ON_OFF_CHANNEL, - LEVEL_CHANNEL, ZONE_CHANNEL, SIGNAL_ATTR_UPDATED, SIGNAL_MOVE_LEVEL, - SIGNAL_SET_LEVEL, ATTRIBUTE_CHANNEL, UNKNOWN, OPENING, ZONE, OCCUPANCY, - ATTR_LEVEL, SENSOR_TYPE, ACCELERATION) + ZONE_CHANNEL, SIGNAL_ATTR_UPDATED, ATTRIBUTE_CHANNEL, UNKNOWN, OPENING, + ZONE, OCCUPANCY, SENSOR_TYPE, ACCELERATION +) from .entity import ZhaEntity _LOGGER = logging.getLogger(__name__) # Zigbee Cluster Library Zone Type to Home Assistant device class CLASS_MAPPING = { - 0x000d: 'motion', - 0x0015: 'opening', - 0x0028: 'smoke', - 0x002a: 'moisture', - 0x002b: 'gas', - 0x002d: 'vibration', + 0x000d: DEVICE_CLASS_MOTION, + 0x0015: DEVICE_CLASS_OPENING, + 0x0028: DEVICE_CLASS_SMOKE, + 0x002a: DEVICE_CLASS_MOISTURE, + 0x002b: DEVICE_CLASS_GAS, + 0x002d: DEVICE_CLASS_VIBRATION, } @@ -33,10 +37,10 @@ async def get_ias_device_class(channel): DEVICE_CLASS_REGISTRY = { UNKNOWN: None, - OPENING: OPENING, + OPENING: DEVICE_CLASS_OPENING, ZONE: get_ias_device_class, - OCCUPANCY: OCCUPANCY, - ACCELERATION: 'moving', + OCCUPANCY: DEVICE_CLASS_OCCUPANCY, + ACCELERATION: DEVICE_CLASS_MOVING, } @@ -85,10 +89,8 @@ class BinarySensor(ZhaEntity, BinarySensorDevice): self._device_state_attributes = {} self._zone_channel = self.cluster_channels.get(ZONE_CHANNEL) self._on_off_channel = self.cluster_channels.get(ON_OFF_CHANNEL) - self._level_channel = self.cluster_channels.get(LEVEL_CHANNEL) self._attr_channel = self.cluster_channels.get(ATTRIBUTE_CHANNEL) self._zha_sensor_type = kwargs[SENSOR_TYPE] - self._level = None async def _determine_device_class(self): """Determine the device class for this binary sensor.""" @@ -105,11 +107,6 @@ class BinarySensor(ZhaEntity, BinarySensorDevice): """Run when about to be added to hass.""" self._device_class = await self._determine_device_class() await super().async_added_to_hass() - if self._level_channel: - await self.async_accept_signal( - self._level_channel, SIGNAL_SET_LEVEL, self.set_level) - await self.async_accept_signal( - self._level_channel, SIGNAL_MOVE_LEVEL, self.move_level) if self._on_off_channel: await self.async_accept_signal( self._on_off_channel, SIGNAL_ATTR_UPDATED, @@ -126,8 +123,6 @@ class BinarySensor(ZhaEntity, BinarySensorDevice): """Restore previous state.""" super().async_restore_last_state(last_state) self._state = last_state.state == STATE_ON - if 'level' in last_state.attributes: - self._level = last_state.attributes['level'] @property def is_on(self) -> bool: @@ -146,36 +141,9 @@ class BinarySensor(ZhaEntity, BinarySensorDevice): self._state = bool(state) self.async_schedule_update_ha_state() - def move_level(self, change): - """Increment the level, setting state if appropriate.""" - level = self._level or 0 - if not self._state and change > 0: - level = 0 - self._level = min(254, max(0, level + change)) - self._state = bool(self._level) - self.async_schedule_update_ha_state() - - def set_level(self, level): - """Set the level, setting state if appropriate.""" - self._level = level - self._state = bool(level) - self.async_schedule_update_ha_state() - - @property - def device_state_attributes(self): - """Return the device state attributes.""" - if self._level_channel is not None: - self._device_state_attributes.update({ - ATTR_LEVEL: self._state and self._level or 0 - }) - return self._device_state_attributes - async def async_update(self): """Attempt to retrieve on off state from the binary sensor.""" await super().async_update() - if self._level_channel: - self._level = await self._level_channel.get_attribute_value( - 'current_level') if self._on_off_channel: self._state = await self._on_off_channel.get_attribute_value( 'on_off') diff --git a/homeassistant/components/zha/core/registries.py b/homeassistant/components/zha/core/registries.py index b585ce5f48a..af483c1f795 100644 --- a/homeassistant/components/zha/core/registries.py +++ b/homeassistant/components/zha/core/registries.py @@ -110,17 +110,11 @@ def establish_device_mappings(): BINDABLE_CLUSTERS.append(zcl.clusters.lighting.Color.cluster_id) DEVICE_CLASS[zha.PROFILE_ID].update({ - zha.DeviceType.ON_OFF_SWITCH: BINARY_SENSOR, - zha.DeviceType.LEVEL_CONTROL_SWITCH: BINARY_SENSOR, - zha.DeviceType.REMOTE_CONTROL: BINARY_SENSOR, zha.DeviceType.SMART_PLUG: SWITCH, zha.DeviceType.LEVEL_CONTROLLABLE_OUTPUT: LIGHT, zha.DeviceType.ON_OFF_LIGHT: LIGHT, zha.DeviceType.DIMMABLE_LIGHT: LIGHT, - zha.DeviceType.COLOR_DIMMABLE_LIGHT: LIGHT, - zha.DeviceType.ON_OFF_LIGHT_SWITCH: BINARY_SENSOR, - zha.DeviceType.DIMMER_SWITCH: BINARY_SENSOR, - zha.DeviceType.COLOR_DIMMER_SWITCH: BINARY_SENSOR, + zha.DeviceType.COLOR_DIMMABLE_LIGHT: LIGHT }) DEVICE_CLASS[zll.PROFILE_ID].update({ @@ -130,12 +124,7 @@ def establish_device_mappings(): zll.DeviceType.DIMMABLE_PLUGIN_UNIT: LIGHT, zll.DeviceType.COLOR_LIGHT: LIGHT, zll.DeviceType.EXTENDED_COLOR_LIGHT: LIGHT, - zll.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT, - zll.DeviceType.COLOR_CONTROLLER: BINARY_SENSOR, - zll.DeviceType.COLOR_SCENE_CONTROLLER: BINARY_SENSOR, - zll.DeviceType.CONTROLLER: BINARY_SENSOR, - zll.DeviceType.SCENE_CONTROLLER: BINARY_SENSOR, - zll.DeviceType.ON_OFF_SENSOR: BINARY_SENSOR, + zll.DeviceType.COLOR_TEMPERATURE_LIGHT: LIGHT }) SINGLE_INPUT_CLUSTER_DEVICE_CLASS.update({ @@ -285,7 +274,6 @@ def establish_device_mappings(): }) BINARY_SENSOR_CLUSTERS.add(zcl.clusters.general.OnOff.cluster_id) - BINARY_SENSOR_CLUSTERS.add(zcl.clusters.general.LevelControl.cluster_id) BINARY_SENSOR_CLUSTERS.add(zcl.clusters.security.IasZone.cluster_id) BINARY_SENSOR_CLUSTERS.add( zcl.clusters.measurement.OccupancySensing.cluster_id) diff --git a/tests/components/zha/test_binary_sensor.py b/tests/components/zha/test_binary_sensor.py index 1d6b4fd3e01..1a7ec667472 100644 --- a/tests/components/zha/test_binary_sensor.py +++ b/tests/components/zha/test_binary_sensor.py @@ -11,8 +11,7 @@ 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, Basic - from zigpy.profiles.zha import DeviceType + from zigpy.zcl.clusters.general import Basic # create zigpy devices zigpy_device_zone = await async_init_zigpy_device( @@ -23,17 +22,6 @@ async def test_binary_sensor(hass, config_entry, zha_gateway): 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, - ieee="00:0d:6f:11:0a:90:69:e7", - manufacturer="FakeManufacturer", - model="FakeRemoteModel" - ) - zigpy_device_occupancy = await async_init_zigpy_device( hass, [OccupancySensing.cluster_id, Basic.cluster_id], @@ -63,46 +51,20 @@ async def test_binary_sensor(hass, config_entry, zha_gateway): DOMAIN, zigpy_device_occupancy, occupancy_cluster) occupancy_zha_device = zha_gateway.get_device(zigpy_device_occupancy.ieee) - # dimmable binary_sensor - remote_on_off_cluster = zigpy_device_remote.endpoints.get( - 1).out_clusters[OnOff.cluster_id] - remote_level_cluster = zigpy_device_remote.endpoints.get( - 1).out_clusters[LevelControl.cluster_id] - remote_entity_id = make_entity_id(DOMAIN, zigpy_device_remote, - remote_on_off_cluster, - use_suffix=False) - remote_zha_device = zha_gateway.get_device(zigpy_device_remote.ieee) - # test that the sensors exist and are in the unavailable state assert hass.states.get(zone_entity_id).state == STATE_UNAVAILABLE - assert hass.states.get(remote_entity_id).state == STATE_UNAVAILABLE assert hass.states.get(occupancy_entity_id).state == STATE_UNAVAILABLE await async_enable_traffic(hass, zha_gateway, - [zone_zha_device, remote_zha_device, - occupancy_zha_device]) + [zone_zha_device, occupancy_zha_device]) # test that the sensors exist and are in the off state assert hass.states.get(zone_entity_id).state == STATE_OFF - assert hass.states.get(remote_entity_id).state == STATE_OFF assert hass.states.get(occupancy_entity_id).state == STATE_OFF # test getting messages that trigger and reset the sensors await async_test_binary_sensor_on_off(hass, occupancy_cluster, occupancy_entity_id) - await async_test_binary_sensor_on_off(hass, remote_on_off_cluster, - remote_entity_id) - - # test changing the level attribute for dimming remotes - await async_test_remote_level( - hass, remote_level_cluster, remote_entity_id, 150, STATE_ON) - await async_test_remote_level( - hass, remote_level_cluster, remote_entity_id, 0, STATE_OFF) - await async_test_remote_level( - hass, remote_level_cluster, remote_entity_id, 255, STATE_ON) - - await async_test_remote_move_level( - hass, remote_level_cluster, remote_entity_id, 20, STATE_ON) # test IASZone binary sensors await async_test_iaszone_on_off(hass, zone_cluster, zone_entity_id) @@ -127,26 +89,6 @@ async def async_test_binary_sensor_on_off(hass, cluster, entity_id): assert hass.states.get(entity_id).state == STATE_OFF -async def async_test_remote_level(hass, cluster, entity_id, level, - expected_state): - """Test dimmer functionality from the remote.""" - attr = make_attribute(0, level) - cluster.handle_message(False, 1, 0x0a, [[attr]]) - await hass.async_block_till_done() - assert hass.states.get(entity_id).state == expected_state - assert hass.states.get(entity_id).attributes.get('level') == level - - -async def async_test_remote_move_level(hass, cluster, entity_id, change, - expected_state): - """Test move to level command.""" - level = hass.states.get(entity_id).attributes.get('level') - cluster.listener_event('cluster_command', 1, 1, [1, change]) - await hass.async_block_till_done() - assert hass.states.get(entity_id).state == expected_state - assert hass.states.get(entity_id).attributes.get('level') == level - change - - async def async_test_iaszone_on_off(hass, cluster, entity_id): """Test getting on and off messages for iaszone binary sensors.""" # binary sensor on