Add init type hints to XiaomiMiioEntity derived entities (#145611)

This commit is contained in:
epenet 2025-05-26 14:46:07 +02:00 committed by GitHub
parent 2d2e0d0fb9
commit c68ab714b7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 155 additions and 35 deletions

View File

@ -3,7 +3,12 @@
from collections.abc import Callable from collections.abc import Callable
import logging import logging
from miio import AirQualityMonitor, AirQualityMonitorCGDN1, DeviceException from miio import (
AirQualityMonitor,
AirQualityMonitorCGDN1,
Device as MiioDevice,
DeviceException,
)
from homeassistant.components.air_quality import AirQualityEntity from homeassistant.components.air_quality import AirQualityEntity
from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_MODEL, CONF_TOKEN from homeassistant.const import CONF_DEVICE, CONF_HOST, CONF_MODEL, CONF_TOKEN
@ -40,12 +45,17 @@ PROP_TO_ATTR = {
class AirMonitorB1(XiaomiMiioEntity, AirQualityEntity): class AirMonitorB1(XiaomiMiioEntity, AirQualityEntity):
"""Air Quality class for Xiaomi cgllc.airmonitor.b1 device.""" """Air Quality class for Xiaomi cgllc.airmonitor.b1 device."""
def __init__(self, name, device, entry, unique_id): def __init__(
self,
name: str,
device: MiioDevice,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the entity.""" """Initialize the entity."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
self._icon = "mdi:cloud" self._icon = "mdi:cloud"
self._available = None
self._air_quality_index = None self._air_quality_index = None
self._carbon_dioxide = None self._carbon_dioxide = None
self._carbon_dioxide_equivalent = None self._carbon_dioxide_equivalent = None
@ -170,12 +180,17 @@ class AirMonitorV1(AirMonitorB1):
class AirMonitorCGDN1(XiaomiMiioEntity, AirQualityEntity): class AirMonitorCGDN1(XiaomiMiioEntity, AirQualityEntity):
"""Air Quality class for cgllc.airm.cgdn1 device.""" """Air Quality class for cgllc.airm.cgdn1 device."""
def __init__(self, name, device, entry, unique_id): def __init__(
self,
name: str,
device: MiioDevice,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the entity.""" """Initialize the entity."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
self._icon = "mdi:cloud" self._icon = "mdi:cloud"
self._available = None
self._carbon_dioxide = None self._carbon_dioxide = None
self._particulate_matter_2_5 = None self._particulate_matter_2_5 = None
self._particulate_matter_10 = None self._particulate_matter_10 = None

View File

@ -27,7 +27,13 @@ _LOGGER = logging.getLogger(__name__)
class XiaomiMiioEntity(Entity): class XiaomiMiioEntity(Entity):
"""Representation of a base Xiaomi Miio Entity.""" """Representation of a base Xiaomi Miio Entity."""
def __init__(self, name, device, entry, unique_id): def __init__(
self,
name: str,
device: MiioDevice,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the Xiaomi Miio Device.""" """Initialize the Xiaomi Miio Device."""
self._device = device self._device = device
self._model = entry.data[CONF_MODEL] self._model = entry.data[CONF_MODEL]
@ -35,7 +41,7 @@ class XiaomiMiioEntity(Entity):
self._device_id = entry.unique_id self._device_id = entry.unique_id
self._unique_id = unique_id self._unique_id = unique_id
self._name = name self._name = name
self._available = None self._available = False
@property @property
def unique_id(self): def unique_id(self):
@ -50,6 +56,8 @@ class XiaomiMiioEntity(Entity):
@property @property
def device_info(self) -> DeviceInfo: def device_info(self) -> DeviceInfo:
"""Return the device info.""" """Return the device info."""
if TYPE_CHECKING:
assert self._device_id is not None
device_info = DeviceInfo( device_info = DeviceInfo(
identifiers={(DOMAIN, self._device_id)}, identifiers={(DOMAIN, self._device_id)},
manufacturer="Xiaomi", manufacturer="Xiaomi",

View File

@ -259,15 +259,21 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity):
_attr_color_mode = ColorMode.BRIGHTNESS _attr_color_mode = ColorMode.BRIGHTNESS
_attr_supported_color_modes = {ColorMode.BRIGHTNESS} _attr_supported_color_modes = {ColorMode.BRIGHTNESS}
_device: Ceil | PhilipsBulb | PhilipsEyecare | PhilipsMoonlight
def __init__(self, name, device, entry, unique_id): def __init__(
self,
name: str,
device: Ceil | PhilipsBulb | PhilipsEyecare | PhilipsMoonlight,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
self._brightness = None self._brightness = None
self._available = False
self._state = None self._state = None
self._state_attrs = {} self._state_attrs: dict[str, Any] = {}
@property @property
def available(self) -> bool: def available(self) -> bool:
@ -348,7 +354,15 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity):
class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight): class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
"""Representation of a Generic Xiaomi Philips Light.""" """Representation of a Generic Xiaomi Philips Light."""
def __init__(self, name, device, entry, unique_id): _device: Ceil | PhilipsBulb | PhilipsEyecare | PhilipsMoonlight
def __init__(
self,
name: str,
device: Ceil | PhilipsBulb | PhilipsEyecare | PhilipsMoonlight,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
@ -390,7 +404,7 @@ class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
"""Set delayed turn off.""" """Set delayed turn off."""
await self._try_command( await self._try_command(
"Setting the turn off delay failed.", "Setting the turn off delay failed.",
self._device.delay_off, self._device.delay_off, # type: ignore[union-attr]
time_period.total_seconds(), time_period.total_seconds(),
) )
@ -421,12 +435,19 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
_attr_color_mode = ColorMode.COLOR_TEMP _attr_color_mode = ColorMode.COLOR_TEMP
_attr_supported_color_modes = {ColorMode.COLOR_TEMP} _attr_supported_color_modes = {ColorMode.COLOR_TEMP}
_device: Ceil | PhilipsBulb | PhilipsMoonlight
def __init__(self, name, device, entry, unique_id): def __init__(
self,
name: str,
device: Ceil | PhilipsBulb | PhilipsMoonlight,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
self._color_temp = None self._color_temp: int | None = None
@property @property
def _current_mireds(self): def _current_mireds(self):
@ -575,7 +596,15 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb): class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb):
"""Representation of a Xiaomi Philips Ceiling Lamp.""" """Representation of a Xiaomi Philips Ceiling Lamp."""
def __init__(self, name, device, entry, unique_id): _device: Ceil
def __init__(
self,
name: str,
device: Ceil,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
@ -635,7 +664,15 @@ class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb):
class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight): class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
"""Representation of a Xiaomi Philips Eyecare Lamp 2.""" """Representation of a Xiaomi Philips Eyecare Lamp 2."""
def __init__(self, name, device, entry, unique_id): _device: PhilipsEyecare
def __init__(
self,
name: str,
device: PhilipsEyecare,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
@ -748,7 +785,15 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight): class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight):
"""Representation of a Xiaomi Philips Eyecare Lamp Ambient Light.""" """Representation of a Xiaomi Philips Eyecare Lamp Ambient Light."""
def __init__(self, name, device, entry, unique_id): _device: PhilipsEyecare
def __init__(
self,
name: str,
device: PhilipsEyecare,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the light device.""" """Initialize the light device."""
name = f"{name} Ambient Light" name = f"{name} Ambient Light"
if unique_id is not None: if unique_id is not None:
@ -807,12 +852,19 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
"""Representation of a Xiaomi Philips Zhirui Bedside Lamp.""" """Representation of a Xiaomi Philips Zhirui Bedside Lamp."""
_attr_supported_color_modes = {ColorMode.COLOR_TEMP, ColorMode.HS} _attr_supported_color_modes = {ColorMode.COLOR_TEMP, ColorMode.HS}
_device: PhilipsMoonlight
def __init__(self, name, device, entry, unique_id): def __init__(
self,
name: str,
device: PhilipsMoonlight,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the light device.""" """Initialize the light device."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
self._hs_color = None self._hs_color: tuple[float, float] | None = None
self._state_attrs.pop(ATTR_DELAYED_TURN_OFF) self._state_attrs.pop(ATTR_DELAYED_TURN_OFF)
self._state_attrs.update( self._state_attrs.update(
{ {

View File

@ -925,11 +925,19 @@ class XiaomiGenericSensor(
class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity): class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity):
"""Representation of a Xiaomi Air Quality Monitor.""" """Representation of a Xiaomi Air Quality Monitor."""
def __init__(self, name, device, entry, unique_id, description): _device: AirQualityMonitor
def __init__(
self,
name: str,
device: AirQualityMonitor,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
description: XiaomiMiioSensorDescription,
) -> None:
"""Initialize the entity.""" """Initialize the entity."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
self._available = None
self._state = None self._state = None
self._state_attrs = { self._state_attrs = {
ATTR_POWER: None, ATTR_POWER: None,

View File

@ -803,13 +803,20 @@ class XiaomiGatewaySwitch(XiaomiGatewayDevice, SwitchEntity):
class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity): class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity):
"""Representation of a Xiaomi Plug Generic.""" """Representation of a Xiaomi Plug Generic."""
def __init__(self, name, device, entry, unique_id): _device: AirConditioningCompanionV3 | ChuangmiPlug | PowerStrip
def __init__(
self,
name: str,
device: AirConditioningCompanionV3 | ChuangmiPlug | PowerStrip,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the plug switch.""" """Initialize the plug switch."""
super().__init__(name, device, entry, unique_id) super().__init__(name, device, entry, unique_id)
self._icon = "mdi:power-socket" self._icon = "mdi:power-socket"
self._available = False self._state: bool | None = None
self._state = None
self._state_attrs = {ATTR_TEMPERATURE: None, ATTR_MODEL: self._model} self._state_attrs = {ATTR_TEMPERATURE: None, ATTR_MODEL: self._model}
self._device_features = FEATURE_FLAGS_GENERIC self._device_features = FEATURE_FLAGS_GENERIC
self._skip_update = False self._skip_update = False
@ -918,7 +925,7 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity):
await self._try_command( await self._try_command(
"Setting the power price of the power strip failed", "Setting the power price of the power strip failed",
self._device.set_power_price, self._device.set_power_price, # type: ignore[union-attr]
price, price,
) )
@ -926,9 +933,17 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity):
class XiaomiPowerStripSwitch(XiaomiPlugGenericSwitch): class XiaomiPowerStripSwitch(XiaomiPlugGenericSwitch):
"""Representation of a Xiaomi Power Strip.""" """Representation of a Xiaomi Power Strip."""
def __init__(self, name, plug, model, unique_id): _device: PowerStrip
def __init__(
self,
name: str,
plug: PowerStrip,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the plug switch.""" """Initialize the plug switch."""
super().__init__(name, plug, model, unique_id) super().__init__(name, plug, entry, unique_id)
if self._model == MODEL_POWER_STRIP_V2: if self._model == MODEL_POWER_STRIP_V2:
self._device_features = FEATURE_FLAGS_POWER_STRIP_V2 self._device_features = FEATURE_FLAGS_POWER_STRIP_V2
@ -995,7 +1010,16 @@ class XiaomiPowerStripSwitch(XiaomiPlugGenericSwitch):
class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch): class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch):
"""Representation of a Chuang Mi Plug V1 and V3.""" """Representation of a Chuang Mi Plug V1 and V3."""
def __init__(self, name, plug, entry, unique_id, channel_usb): _device: ChuangmiPlug
def __init__(
self,
name: str,
plug: ChuangmiPlug,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
channel_usb: bool,
) -> None:
"""Initialize the plug switch.""" """Initialize the plug switch."""
name = f"{name} USB" if channel_usb else name name = f"{name} USB" if channel_usb else name
@ -1015,11 +1039,13 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch):
"""Turn a channel on.""" """Turn a channel on."""
if self._channel_usb: if self._channel_usb:
result = await self._try_command( result = await self._try_command(
"Turning the plug on failed", self._device.usb_on "Turning the plug on failed",
self._device.usb_on,
) )
else: else:
result = await self._try_command( result = await self._try_command(
"Turning the plug on failed", self._device.on "Turning the plug on failed",
self._device.on,
) )
if result: if result:
@ -1030,7 +1056,8 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch):
"""Turn a channel off.""" """Turn a channel off."""
if self._channel_usb: if self._channel_usb:
result = await self._try_command( result = await self._try_command(
"Turning the plug off failed", self._device.usb_off "Turning the plug off failed",
self._device.usb_off,
) )
else: else:
result = await self._try_command( result = await self._try_command(
@ -1075,16 +1102,25 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch):
class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch): class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch):
"""Representation of a Xiaomi AirConditioning Companion.""" """Representation of a Xiaomi AirConditioning Companion."""
def __init__(self, name, plug, model, unique_id): _device: AirConditioningCompanionV3
def __init__(
self,
name: str,
plug: AirConditioningCompanionV3,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
) -> None:
"""Initialize the acpartner switch.""" """Initialize the acpartner switch."""
super().__init__(name, plug, model, unique_id) super().__init__(name, plug, entry, unique_id)
self._state_attrs.update({ATTR_TEMPERATURE: None, ATTR_LOAD_POWER: None}) self._state_attrs.update({ATTR_TEMPERATURE: None, ATTR_LOAD_POWER: None})
async def async_turn_on(self, **kwargs: Any) -> None: async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the socket on.""" """Turn the socket on."""
result = await self._try_command( result = await self._try_command(
"Turning the socket on failed", self._device.socket_on "Turning the socket on failed",
self._device.socket_on,
) )
if result: if result:
@ -1094,7 +1130,8 @@ class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch):
async def async_turn_off(self, **kwargs: Any) -> None: async def async_turn_off(self, **kwargs: Any) -> None:
"""Turn the socket off.""" """Turn the socket off."""
result = await self._try_command( result = await self._try_command(
"Turning the socket off failed", self._device.socket_off "Turning the socket off failed",
self._device.socket_off,
) )
if result: if result: