diff --git a/homeassistant/components/deconz/binary_sensor.py b/homeassistant/components/deconz/binary_sensor.py index b19301aa113..392d2e03885 100644 --- a/homeassistant/components/deconz/binary_sensor.py +++ b/homeassistant/components/deconz/binary_sensor.py @@ -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" diff --git a/homeassistant/components/deconz/climate.py b/homeassistant/components/deconz/climate.py index db68843080a..4f8345b5e92 100644 --- a/homeassistant/components/deconz/climate.py +++ b/homeassistant/components/deconz/climate.py @@ -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 diff --git a/homeassistant/components/deconz/const.py b/homeassistant/components/deconz/const.py index 799fc221e2c..d2d7025771e 100644 --- a/homeassistant/components/deconz/const.py +++ b/homeassistant/components/deconz/const.py @@ -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 diff --git a/homeassistant/components/deconz/cover.py b/homeassistant/components/deconz/cover.py index 68fb9527e87..21618127905 100644 --- a/homeassistant/components/deconz/cover.py +++ b/homeassistant/components/deconz/cover.py @@ -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): diff --git a/homeassistant/components/deconz/deconz_device.py b/homeassistant/components/deconz/deconz_device.py index 37a41845a00..63f624ba643 100644 --- a/homeassistant/components/deconz/deconz_device.py +++ b/homeassistant/components/deconz/deconz_device.py @@ -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 diff --git a/homeassistant/components/deconz/fan.py b/homeassistant/components/deconz/fan.py index dfb6802fd75..cb64bff6d16 100644 --- a/homeassistant/components/deconz/fan.py +++ b/homeassistant/components/deconz/fan.py @@ -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: diff --git a/homeassistant/components/deconz/light.py b/homeassistant/components/deconz/light.py index ac18d2de248..90d5e82af71 100644 --- a/homeassistant/components/deconz/light.py +++ b/homeassistant/components/deconz/light.py @@ -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 diff --git a/homeassistant/components/deconz/scene.py b/homeassistant/components/deconz/scene.py index ecd363f121a..f4a4d328d22 100644 --- a/homeassistant/components/deconz/scene.py +++ b/homeassistant/components/deconz/scene.py @@ -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 diff --git a/homeassistant/components/deconz/sensor.py b/homeassistant/components/deconz/sensor.py index bbc49f786ea..e0f12303946 100644 --- a/homeassistant/components/deconz/sensor.py +++ b/homeassistant/components/deconz/sensor.py @@ -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."""