Use isinstance to verify class in deCONZ integration (#56794)

* Don't enable any variants of the daylight sensor entities by default

* Use isinstance rather than doing ZHATYPE compare

* Accidentally removed an import
This commit is contained in:
Robert Svensson 2021-09-29 21:19:21 +02:00 committed by GitHub
parent 0463007050
commit f224ab6d67
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
13 changed files with 95 additions and 86 deletions

View file

@ -76,7 +76,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None:
for sensor in sensors: for sensor in sensors:
if ( if (
sensor.type in AncillaryControl.ZHATYPE isinstance(sensor, AncillaryControl)
and sensor.unique_id not in gateway.entities[DOMAIN] and sensor.unique_id not in gateway.entities[DOMAIN]
and get_alarm_system_for_unique_id(gateway, sensor.unique_id) and get_alarm_system_for_unique_id(gateway, sensor.unique_id)
): ):

View file

@ -1,5 +1,15 @@
"""Support for deCONZ binary sensors.""" """Support for deCONZ binary sensors."""
from pydeconz.sensor import CarbonMonoxide, Fire, OpenClose, Presence, Vibration, Water from pydeconz.sensor import (
Alarm,
CarbonMonoxide,
Fire,
GenericFlag,
GenericStatus,
OpenClose,
Presence,
Vibration,
Water,
)
from homeassistant.components.binary_sensor import ( from homeassistant.components.binary_sensor import (
DEVICE_CLASS_GAS, DEVICE_CLASS_GAS,
@ -21,6 +31,18 @@ from .const import ATTR_DARK, ATTR_ON, NEW_SENSOR
from .deconz_device import DeconzDevice from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry from .gateway import get_gateway_from_config_entry
DECONZ_BINARY_SENSORS = (
Alarm,
CarbonMonoxide,
Fire,
GenericFlag,
GenericStatus,
OpenClose,
Presence,
Vibration,
Water,
)
ATTR_ORIENTATION = "orientation" ATTR_ORIENTATION = "orientation"
ATTR_TILTANGLE = "tiltangle" ATTR_TILTANGLE = "tiltangle"
ATTR_VIBRATIONSTRENGTH = "vibrationstrength" ATTR_VIBRATIONSTRENGTH = "vibrationstrength"
@ -65,13 +87,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for sensor in sensors: for sensor in sensors:
if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"):
continue
if ( if (
sensor.BINARY isinstance(sensor, DECONZ_BINARY_SENSORS)
and sensor.unique_id not in gateway.entities[DOMAIN] and sensor.unique_id not in gateway.entities[DOMAIN]
and (
gateway.option_allow_clip_sensor
or not sensor.type.startswith("CLIP")
)
): ):
entities.append(DeconzBinarySensor(sensor, gateway)) entities.append(DeconzBinarySensor(sensor, gateway))

View file

@ -84,13 +84,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for sensor in sensors: for sensor in sensors:
if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"):
continue
if ( if (
sensor.type in Thermostat.ZHATYPE isinstance(sensor, Thermostat)
and sensor.unique_id not in gateway.entities[DOMAIN] and sensor.unique_id not in gateway.entities[DOMAIN]
and (
gateway.option_allow_clip_sensor
or not sensor.type.startswith("CLIP")
)
): ):
entities.append(DeconzThermostat(sensor, gateway)) entities.append(DeconzThermostat(sensor, gateway))

View file

@ -57,23 +57,6 @@ ATTR_OFFSET = "offset"
ATTR_ON = "on" ATTR_ON = "on"
ATTR_VALVE = "valve" ATTR_VALVE = "valve"
# Covers
LEVEL_CONTROLLABLE_OUTPUT = "Level controllable output"
DAMPERS = [LEVEL_CONTROLLABLE_OUTPUT]
WINDOW_COVERING_CONTROLLER = "Window covering controller"
WINDOW_COVERING_DEVICE = "Window covering device"
WINDOW_COVERS = [WINDOW_COVERING_CONTROLLER, WINDOW_COVERING_DEVICE]
COVER_TYPES = DAMPERS + WINDOW_COVERS
# Fans
FANS = ["Fan"]
# Locks
LOCK_TYPES = ["Door Lock", "ZHADoorLock"]
# Sirens
SIRENS = ["Warning device"]
# Switches # Switches
POWER_PLUGS = ["On/Off light", "On/Off plug-in unit", "Smart plug"] POWER_PLUGS = ["On/Off light", "On/Off plug-in unit", "Smart plug"]

View file

@ -1,4 +1,7 @@
"""Support for deCONZ covers.""" """Support for deCONZ covers."""
from pydeconz.light import Cover
from homeassistant.components.cover import ( from homeassistant.components.cover import (
ATTR_POSITION, ATTR_POSITION,
ATTR_TILT_POSITION, ATTR_TILT_POSITION,
@ -18,20 +21,14 @@ from homeassistant.components.cover import (
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import ( from .const import NEW_LIGHT
COVER_TYPES,
LEVEL_CONTROLLABLE_OUTPUT,
NEW_LIGHT,
WINDOW_COVERING_CONTROLLER,
WINDOW_COVERING_DEVICE,
)
from .deconz_device import DeconzDevice from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry from .gateway import get_gateway_from_config_entry
DEVICE_CLASS = { DEVICE_CLASS = {
LEVEL_CONTROLLABLE_OUTPUT: DEVICE_CLASS_DAMPER, "Level controllable output": DEVICE_CLASS_DAMPER,
WINDOW_COVERING_CONTROLLER: DEVICE_CLASS_SHADE, "Window covering controller": DEVICE_CLASS_SHADE,
WINDOW_COVERING_DEVICE: DEVICE_CLASS_SHADE, "Window covering device": DEVICE_CLASS_SHADE,
} }
@ -47,7 +44,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for light in lights: for light in lights:
if ( if (
light.type in COVER_TYPES isinstance(light, Cover)
and light.unique_id not in gateway.entities[DOMAIN] and light.unique_id not in gateway.entities[DOMAIN]
): ):
entities.append(DeconzCover(light, gateway)) entities.append(DeconzCover(light, gateway))

View file

@ -1,4 +1,5 @@
"""Base class for deCONZ devices.""" """Base class for deCONZ devices."""
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect

View file

@ -40,23 +40,24 @@ async def async_setup_events(gateway) -> None:
@callback @callback
def async_add_sensor(sensors=gateway.api.sensors.values()): def async_add_sensor(sensors=gateway.api.sensors.values()):
"""Create DeconzEvent.""" """Create DeconzEvent."""
new_events = []
known_events = {event.unique_id for event in gateway.events}
for sensor in sensors: for sensor in sensors:
if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"): if not gateway.option_allow_clip_sensor and sensor.type.startswith("CLIP"):
continue continue
if ( if sensor.unique_id in known_events:
sensor.type not in Switch.ZHATYPE + AncillaryControl.ZHATYPE
or sensor.unique_id in {event.unique_id for event in gateway.events}
):
continue continue
if sensor.type in Switch.ZHATYPE: if isinstance(sensor, Switch):
new_event = DeconzEvent(sensor, gateway) new_events.append(DeconzEvent(sensor, gateway))
elif sensor.type in AncillaryControl.ZHATYPE: elif isinstance(sensor, AncillaryControl):
new_event = DeconzAlarmEvent(sensor, gateway) new_events.append(DeconzAlarmEvent(sensor, gateway))
for new_event in new_events:
gateway.hass.async_create_task(new_event.async_update_device_registry()) gateway.hass.async_create_task(new_event.async_update_device_registry())
gateway.events.append(new_event) gateway.events.append(new_event)

View file

@ -1,6 +1,8 @@
"""Support for deCONZ fans.""" """Support for deCONZ fans."""
from __future__ import annotations from __future__ import annotations
from pydeconz.light import Fan
from homeassistant.components.fan import ( from homeassistant.components.fan import (
DOMAIN, DOMAIN,
SPEED_HIGH, SPEED_HIGH,
@ -17,7 +19,7 @@ from homeassistant.util.percentage import (
percentage_to_ordered_list_item, percentage_to_ordered_list_item,
) )
from .const import FANS, NEW_LIGHT from .const import NEW_LIGHT
from .deconz_device import DeconzDevice from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry from .gateway import get_gateway_from_config_entry
@ -39,7 +41,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities) -> None:
for light in lights: for light in lights:
if light.type in FANS and light.unique_id not in gateway.entities[DOMAIN]: if (
isinstance(light, Fan)
and light.unique_id not in gateway.entities[DOMAIN]
):
entities.append(DeconzFan(light, gateway)) entities.append(DeconzFan(light, gateway))
if entities: if entities:

View file

@ -2,6 +2,8 @@
from __future__ import annotations from __future__ import annotations
from pydeconz.light import Light
from homeassistant.components.light import ( from homeassistant.components.light import (
ATTR_BRIGHTNESS, ATTR_BRIGHTNESS,
ATTR_COLOR_TEMP, ATTR_COLOR_TEMP,
@ -28,25 +30,12 @@ from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from homeassistant.util.color import color_hs_to_xy from homeassistant.util.color import color_hs_to_xy
from .const import ( from .const import DOMAIN as DECONZ_DOMAIN, NEW_GROUP, NEW_LIGHT, POWER_PLUGS
COVER_TYPES,
DOMAIN as DECONZ_DOMAIN,
LOCK_TYPES,
NEW_GROUP,
NEW_LIGHT,
POWER_PLUGS,
SIRENS,
)
from .deconz_device import DeconzDevice from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry from .gateway import get_gateway_from_config_entry
CONTROLLER = ["Configuration tool"]
DECONZ_GROUP = "is_deconz_group" DECONZ_GROUP = "is_deconz_group"
OTHER_LIGHT_RESOURCE_TYPES = (
CONTROLLER + COVER_TYPES + LOCK_TYPES + POWER_PLUGS + SIRENS
)
async def async_setup_entry(hass, config_entry, async_add_entities): async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up the deCONZ lights and groups from a config entry.""" """Set up the deCONZ lights and groups from a config entry."""
@ -60,7 +49,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for light in lights: for light in lights:
if ( if (
light.type not in OTHER_LIGHT_RESOURCE_TYPES isinstance(light, Light)
and light.type not in POWER_PLUGS
and light.unique_id not in gateway.entities[DOMAIN] and light.unique_id not in gateway.entities[DOMAIN]
): ):
entities.append(DeconzLight(light, gateway)) entities.append(DeconzLight(light, gateway))

View file

@ -1,9 +1,13 @@
"""Support for deCONZ locks.""" """Support for deCONZ locks."""
from pydeconz.light import Lock
from pydeconz.sensor import DoorLock
from homeassistant.components.lock import DOMAIN, LockEntity from homeassistant.components.lock import DOMAIN, LockEntity
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import LOCK_TYPES, NEW_LIGHT, NEW_SENSOR from .const import NEW_LIGHT, NEW_SENSOR
from .deconz_device import DeconzDevice from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry from .gateway import get_gateway_from_config_entry
@ -21,7 +25,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for light in lights: for light in lights:
if ( if (
light.type in LOCK_TYPES isinstance(light, Lock)
and light.unique_id not in gateway.entities[DOMAIN] and light.unique_id not in gateway.entities[DOMAIN]
): ):
entities.append(DeconzLock(light, gateway)) entities.append(DeconzLock(light, gateway))
@ -43,7 +47,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
for sensor in sensors: for sensor in sensors:
if ( if (
sensor.type in LOCK_TYPES isinstance(sensor, DoorLock)
and sensor.unique_id not in gateway.entities[DOMAIN] and sensor.unique_id not in gateway.entities[DOMAIN]
): ):
entities.append(DeconzLock(sensor, gateway)) entities.append(DeconzLock(sensor, gateway))

View file

@ -1,10 +1,9 @@
"""Support for deCONZ sensors.""" """Support for deCONZ sensors."""
from pydeconz.sensor import ( from pydeconz.sensor import (
AncillaryControl, AirQuality,
Battery, Battery,
Consumption, Consumption,
Daylight, Daylight,
DoorLock,
Humidity, Humidity,
LightLevel, LightLevel,
Power, Power,
@ -12,6 +11,7 @@ from pydeconz.sensor import (
Switch, Switch,
Temperature, Temperature,
Thermostat, Thermostat,
Time,
) )
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
@ -48,6 +48,18 @@ from .const import ATTR_DARK, ATTR_ON, NEW_SENSOR
from .deconz_device import DeconzDevice from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry from .gateway import get_gateway_from_config_entry
DECONZ_SENSORS = (
AirQuality,
Consumption,
Daylight,
Humidity,
LightLevel,
Power,
Pressure,
Temperature,
Time,
)
ATTR_CURRENT = "current" ATTR_CURRENT = "current"
ATTR_POWER = "power" ATTR_POWER = "power"
ATTR_DAYLIGHT = "daylight" ATTR_DAYLIGHT = "daylight"
@ -136,13 +148,8 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
battery_handler.create_tracker(sensor) battery_handler.create_tracker(sensor)
if ( if (
not sensor.BINARY isinstance(sensor, DECONZ_SENSORS)
and sensor.type and not isinstance(sensor, Thermostat)
not in AncillaryControl.ZHATYPE
+ Battery.ZHATYPE
+ DoorLock.ZHATYPE
+ Switch.ZHATYPE
+ Thermostat.ZHATYPE
and sensor.unique_id not in gateway.entities[DOMAIN] and sensor.unique_id not in gateway.entities[DOMAIN]
): ):
entities.append(DeconzSensor(sensor, gateway)) entities.append(DeconzSensor(sensor, gateway))
@ -301,7 +308,7 @@ class DeconzBattery(DeconzDevice, SensorEntity):
"""Return the state attributes of the battery.""" """Return the state attributes of the battery."""
attr = {} attr = {}
if self._device.type in Switch.ZHATYPE: if isinstance(self._device, Switch):
for event in self.gateway.events: for event in self.gateway.events:
if self._device == event.device: if self._device == event.device:
attr[ATTR_EVENT_ID] = event.event_id attr[ATTR_EVENT_ID] = event.event_id

View file

@ -1,9 +1,12 @@
"""Support for deCONZ switches.""" """Support for deCONZ switches."""
from pydeconz.light import Siren
from homeassistant.components.switch import DOMAIN, SwitchEntity from homeassistant.components.switch import DOMAIN, SwitchEntity
from homeassistant.core import callback from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import DOMAIN as DECONZ_DOMAIN, NEW_LIGHT, POWER_PLUGS, SIRENS from .const import DOMAIN as DECONZ_DOMAIN, NEW_LIGHT, POWER_PLUGS
from .deconz_device import DeconzDevice from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry from .gateway import get_gateway_from_config_entry
@ -20,10 +23,10 @@ async def async_setup_entry(hass, config_entry, async_add_entities):
# Siren platform replacing sirens in switch platform added in 2021.10 # Siren platform replacing sirens in switch platform added in 2021.10
for light in gateway.api.lights.values(): for light in gateway.api.lights.values():
if light.type not in SIRENS: if isinstance(light, Siren) and (
continue entity_id := entity_registry.async_get_entity_id(
if entity_id := entity_registry.async_get_entity_id(
DOMAIN, DECONZ_DOMAIN, light.unique_id DOMAIN, DECONZ_DOMAIN, light.unique_id
)
): ):
entity_registry.async_remove(entity_id) entity_registry.async_remove(entity_id)

View file

@ -15,7 +15,6 @@ from homeassistant.const import (
DEVICE_CLASS_POWER, DEVICE_CLASS_POWER,
DEVICE_CLASS_TEMPERATURE, DEVICE_CLASS_TEMPERATURE,
STATE_UNAVAILABLE, STATE_UNAVAILABLE,
STATE_UNKNOWN,
) )
from homeassistant.helpers import entity_registry as er from homeassistant.helpers import entity_registry as er
from homeassistant.util import dt from homeassistant.util import dt
@ -553,5 +552,4 @@ async def test_unsupported_sensor(hass, aioclient_mock):
with patch.dict(DECONZ_WEB_REQUEST, data): with patch.dict(DECONZ_WEB_REQUEST, data):
await setup_deconz_integration(hass, aioclient_mock) await setup_deconz_integration(hass, aioclient_mock)
assert len(hass.states.async_all()) == 1 assert len(hass.states.async_all()) == 0
assert hass.states.get("sensor.name").state == STATE_UNKNOWN