Use more attr instead of properties in deCONZ integration (#52098)

This commit is contained in:
Robert Svensson 2021-06-23 21:40:34 +02:00 committed by GitHub
parent 1f4fdb50dc
commit 6352d8fb0e
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 80 additions and 124 deletions

View file

@ -81,6 +81,11 @@ class DeconzBinarySensor(DeconzDevice, BinarySensorEntity):
TYPE = DOMAIN
def __init__(self, device, gateway):
"""Initialize deCONZ binary sensor."""
super().__init__(device, gateway)
self._attr_device_class = DEVICE_CLASS.get(type(self._device))
@callback
def async_update_callback(self, force_update=False):
"""Update the sensor's state."""
@ -93,11 +98,6 @@ class DeconzBinarySensor(DeconzDevice, BinarySensorEntity):
"""Return true if sensor is on."""
return self._device.state
@property
def device_class(self):
"""Return the class of the sensor."""
return DEVICE_CLASS.get(type(self._device))
@property
def extra_state_attributes(self):
"""Return the state attributes of the sensor."""
@ -129,6 +129,12 @@ class DeconzTampering(DeconzDevice, BinarySensorEntity):
_attr_device_class = DEVICE_CLASS_PROBLEM
def __init__(self, device, gateway):
"""Initialize deCONZ binary sensor."""
super().__init__(device, gateway)
self._attr_name = f"{self._device.name} Tampered"
@property
def unique_id(self) -> str:
"""Return a unique identifier for this device."""
@ -145,8 +151,3 @@ class DeconzTampering(DeconzDevice, BinarySensorEntity):
def is_on(self) -> bool:
"""Return the state of the sensor."""
return self._device.tampered
@property
def name(self) -> str:
"""Return the name of the sensor."""
return f"{self._device.name} Tampered"

View file

@ -128,18 +128,13 @@ class DeconzThermostat(DeconzDevice, ClimateEntity):
value: key for key, value in self._hvac_mode_to_deconz.items()
}
self._features = SUPPORT_TARGET_TEMPERATURE
self._attr_supported_features = SUPPORT_TARGET_TEMPERATURE
if "fanmode" in device.raw["config"]:
self._features |= SUPPORT_FAN_MODE
self._attr_supported_features |= SUPPORT_FAN_MODE
if "preset" in device.raw["config"]:
self._features |= SUPPORT_PRESET_MODE
@property
def supported_features(self):
"""Return the list of supported features."""
return self._features
self._attr_supported_features |= SUPPORT_PRESET_MODE
# Fan control

View file

@ -56,8 +56,11 @@ ATTR_ON = "on"
ATTR_VALVE = "valve"
# Covers
DAMPERS = ["Level controllable output"]
WINDOW_COVERS = ["Window covering device", "Window covering controller"]
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

View file

@ -18,10 +18,22 @@ from homeassistant.components.cover import (
from homeassistant.core import callback
from homeassistant.helpers.dispatcher import async_dispatcher_connect
from .const import COVER_TYPES, DAMPERS, NEW_LIGHT, WINDOW_COVERS
from .const import (
COVER_TYPES,
LEVEL_CONTROLLABLE_OUTPUT,
NEW_LIGHT,
WINDOW_COVERING_CONTROLLER,
WINDOW_COVERING_DEVICE,
)
from .deconz_device import DeconzDevice
from .gateway import get_gateway_from_config_entry
DEVICE_CLASS = {
LEVEL_CONTROLLABLE_OUTPUT: DEVICE_CLASS_DAMPER,
WINDOW_COVERING_CONTROLLER: DEVICE_CLASS_SHADE,
WINDOW_COVERING_DEVICE: DEVICE_CLASS_SHADE,
}
async def async_setup_entry(hass, config_entry, async_add_entities):
"""Set up covers for deCONZ component."""
@ -61,29 +73,18 @@ class DeconzCover(DeconzDevice, CoverEntity):
"""Set up cover device."""
super().__init__(device, gateway)
self._features = SUPPORT_OPEN
self._features |= SUPPORT_CLOSE
self._features |= SUPPORT_STOP
self._features |= SUPPORT_SET_POSITION
self._attr_supported_features = SUPPORT_OPEN
self._attr_supported_features |= SUPPORT_CLOSE
self._attr_supported_features |= SUPPORT_STOP
self._attr_supported_features |= SUPPORT_SET_POSITION
if self._device.tilt is not None:
self._features |= SUPPORT_OPEN_TILT
self._features |= SUPPORT_CLOSE_TILT
self._features |= SUPPORT_STOP_TILT
self._features |= SUPPORT_SET_TILT_POSITION
self._attr_supported_features |= SUPPORT_OPEN_TILT
self._attr_supported_features |= SUPPORT_CLOSE_TILT
self._attr_supported_features |= SUPPORT_STOP_TILT
self._attr_supported_features |= SUPPORT_SET_TILT_POSITION
@property
def supported_features(self):
"""Flag supported features."""
return self._features
@property
def device_class(self):
"""Return the class of the cover."""
if self._device.type in DAMPERS:
return DEVICE_CLASS_DAMPER
if self._device.type in WINDOW_COVERS:
return DEVICE_CLASS_SHADE
self._attr_device_class = DEVICE_CLASS.get(self._device.type)
@property
def current_cover_position(self):

View file

@ -34,8 +34,6 @@ class DeconzBase:
if self.serial is None:
return None
bridgeid = self.gateway.api.config.bridgeid
return {
"connections": {(CONNECTION_ZIGBEE, self.serial)},
"identifiers": {(DECONZ_DOMAIN, self.serial)},
@ -43,13 +41,15 @@ class DeconzBase:
"model": self._device.modelid,
"name": self._device.name,
"sw_version": self._device.swversion,
"via_device": (DECONZ_DOMAIN, bridgeid),
"via_device": (DECONZ_DOMAIN, self.gateway.api.config.bridgeid),
}
class DeconzDevice(DeconzBase, Entity):
"""Representation of a deCONZ device."""
_attr_should_poll = False
TYPE = ""
def __init__(self, device, gateway):
@ -57,6 +57,8 @@ class DeconzDevice(DeconzBase, Entity):
super().__init__(device, gateway)
self.gateway.entities[self.TYPE].add(self.unique_id)
self._attr_name = self._device.name
@property
def entity_registry_enabled_default(self) -> bool:
"""Return if the entity should be enabled when first added to the entity registry.
@ -93,13 +95,3 @@ class DeconzDevice(DeconzBase, Entity):
def available(self):
"""Return True if device is available."""
return self.gateway.available and self._device.reachable
@property
def name(self):
"""Return the name of the device."""
return self._device.name
@property
def should_poll(self):
"""No polling needed."""
return False

View file

@ -67,7 +67,7 @@ class DeconzFan(DeconzDevice, FanEntity):
if self._device.speed in ORDERED_NAMED_FAN_SPEEDS:
self._default_on_speed = self._device.speed
self._features = SUPPORT_SET_SPEED
self._attr_supported_features = SUPPORT_SET_SPEED
@property
def is_on(self) -> bool:
@ -128,7 +128,7 @@ class DeconzFan(DeconzDevice, FanEntity):
@property
def supported_features(self) -> int:
"""Flag supported features."""
return self._features
return self._attr_supported_features
@callback
def async_update_callback(self, force_update=False) -> None:

View file

@ -273,14 +273,12 @@ class DeconzGroup(DeconzBaseLight):
@property
def device_info(self):
"""Return a device description for device registry."""
bridgeid = self.gateway.api.config.bridgeid
return {
"identifiers": {(DECONZ_DOMAIN, self.unique_id)},
"manufacturer": "Dresden Elektronik",
"model": "deCONZ group",
"name": self._device.name,
"via_device": (DECONZ_DOMAIN, bridgeid),
"via_device": (DECONZ_DOMAIN, self.gateway.api.config.bridgeid),
}
@property

View file

@ -38,6 +38,8 @@ class DeconzScene(Scene):
self._scene = scene
self.gateway = gateway
self._attr_name = scene.full_name
async def async_added_to_hass(self):
"""Subscribe to sensors events."""
self.gateway.deconz_ids[self.entity_id] = self._scene.deconz_id
@ -50,8 +52,3 @@ class DeconzScene(Scene):
async def async_activate(self, **kwargs: Any) -> None:
"""Activate the scene."""
await self._scene.async_set_state({})
@property
def name(self):
"""Return the name of the scene."""
return self._scene.full_name

View file

@ -149,6 +149,15 @@ class DeconzSensor(DeconzDevice, SensorEntity):
TYPE = DOMAIN
def __init__(self, device, gateway):
"""Initialize deCONZ binary sensor."""
super().__init__(device, gateway)
self._attr_device_class = DEVICE_CLASS.get(type(self._device))
self._attr_icon = ICON.get(type(self._device))
self._attr_state_class = STATE_CLASS.get(type(self._device))
self._attr_unit_of_measurement = UNIT_OF_MEASUREMENT.get(type(self._device))
@callback
def async_update_callback(self, force_update=False):
"""Update the sensor's state."""
@ -161,26 +170,6 @@ class DeconzSensor(DeconzDevice, SensorEntity):
"""Return the state of the sensor."""
return self._device.state
@property
def device_class(self):
"""Return the class of the sensor."""
return DEVICE_CLASS.get(type(self._device))
@property
def icon(self):
"""Return the icon to use in the frontend."""
return ICON.get(type(self._device))
@property
def state_class(self):
"""Return the state class of the sensor."""
return STATE_CLASS.get(type(self._device))
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this sensor."""
return UNIT_OF_MEASUREMENT.get(type(self._device))
@property
def extra_state_attributes(self):
"""Return the state attributes of the sensor."""
@ -219,8 +208,18 @@ class DeconzTemperature(DeconzDevice, SensorEntity):
Extra temperature sensor on certain Xiaomi devices.
"""
_attr_device_class = DEVICE_CLASS_TEMPERATURE
_attr_state_class = STATE_CLASS_MEASUREMENT
_attr_unit_of_measurement = TEMP_CELSIUS
TYPE = DOMAIN
def __init__(self, device, gateway):
"""Initialize deCONZ temperature sensor."""
super().__init__(device, gateway)
self._attr_name = f"{self._device.name} Temperature"
@property
def unique_id(self):
"""Return a unique identifier for this device."""
@ -238,32 +237,22 @@ class DeconzTemperature(DeconzDevice, SensorEntity):
"""Return the state of the sensor."""
return self._device.secondary_temperature
@property
def name(self):
"""Return the name of the temperature sensor."""
return f"{self._device.name} Temperature"
@property
def device_class(self):
"""Return the class of the sensor."""
return DEVICE_CLASS_TEMPERATURE
@property
def state_class(self):
"""Return the state class of the sensor."""
return STATE_CLASS_MEASUREMENT
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this sensor."""
return TEMP_CELSIUS
class DeconzBattery(DeconzDevice, SensorEntity):
"""Battery class for when a device is only represented as an event."""
_attr_device_class = DEVICE_CLASS_BATTERY
_attr_state_class = STATE_CLASS_MEASUREMENT
_attr_unit_of_measurement = PERCENTAGE
TYPE = DOMAIN
def __init__(self, device, gateway):
"""Initialize deCONZ battery level sensor."""
super().__init__(device, gateway)
self._attr_name = f"{self._device.name} Battery Level"
@callback
def async_update_callback(self, force_update=False):
"""Update the battery's state, if needed."""
@ -292,26 +281,6 @@ class DeconzBattery(DeconzDevice, SensorEntity):
"""Return the state of the battery."""
return self._device.battery
@property
def name(self):
"""Return the name of the battery."""
return f"{self._device.name} Battery Level"
@property
def device_class(self):
"""Return the class of the sensor."""
return DEVICE_CLASS_BATTERY
@property
def state_class(self):
"""Return the state class of the sensor."""
return STATE_CLASS_MEASUREMENT
@property
def unit_of_measurement(self):
"""Return the unit of measurement of this entity."""
return PERCENTAGE
@property
def extra_state_attributes(self):
"""Return the state attributes of the battery."""