Use shorthand attributes in xiaomi_miio (part 3) (#145617)

This commit is contained in:
epenet 2025-05-26 16:16:18 +02:00 committed by GitHub
parent 0260a03447
commit 109bcf362a
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 96 additions and 155 deletions

View File

@ -301,6 +301,7 @@ class XiaomiGenericDevice(
"""Representation of a generic Xiaomi device."""
_attr_name = None
_attr_preset_modes: list[str]
def __init__(
self,
@ -315,30 +316,20 @@ class XiaomiGenericDevice(
self._available_attributes: dict[str, Any] = {}
self._mode: str | None = None
self._fan_level: int | None = None
self._state_attrs: dict[str, Any] = {}
self._attr_extra_state_attributes = {}
self._device_features = 0
self._preset_modes: list[str] = []
self._attr_preset_modes = []
@property
@abstractmethod
def operation_mode_class(self):
"""Hold operation mode class."""
@property
def preset_modes(self) -> list[str]:
"""Get the list of available preset modes."""
return self._preset_modes
@property
def percentage(self) -> int | None:
"""Return the percentage based speed of the fan."""
return None
@property
def extra_state_attributes(self) -> dict[str, Any]:
"""Return the state attributes of the device."""
return self._state_attrs
async def async_turn_on(
self,
percentage: int | None = None,
@ -376,29 +367,12 @@ class XiaomiGenericDevice(
class XiaomiGenericAirPurifier(XiaomiGenericDevice):
"""Representation of a generic AirPurifier device."""
def __init__(
self,
device: MiioDevice,
entry: XiaomiMiioConfigEntry,
unique_id: str | None,
coordinator: DataUpdateCoordinator[Any],
) -> None:
"""Initialize the generic AirPurifier device."""
super().__init__(device, entry, unique_id, coordinator)
self._speed_count = 100
@property
def speed_count(self) -> int:
"""Return the number of speeds of the fan supported."""
return self._speed_count
@property
def preset_mode(self) -> str | None:
"""Get the active preset mode."""
if self._attr_is_on:
preset_mode = self.operation_mode_class(self._mode).name
return preset_mode if preset_mode in self._preset_modes else None
return preset_mode if preset_mode in self._attr_preset_modes else None
return None
@ -406,7 +380,7 @@ class XiaomiGenericAirPurifier(XiaomiGenericDevice):
def _handle_coordinator_update(self):
"""Fetch state from the device."""
self._attr_is_on = self.coordinator.data.is_on
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{
key: self._extract_value_from_attribute(self.coordinator.data, value)
for key, value in self._available_attributes.items()
@ -442,70 +416,70 @@ class XiaomiAirPurifier(XiaomiGenericAirPurifier):
if self._model == MODEL_AIRPURIFIER_PRO:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_PRO
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_PRO
self._preset_modes = PRESET_MODES_AIRPURIFIER_PRO
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_PRO
self._attr_supported_features = FanEntityFeature.PRESET_MODE
self._speed_count = 1
self._attr_speed_count = 1
elif self._model in [MODEL_AIRPURIFIER_4, MODEL_AIRPURIFIER_4_PRO]:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_4
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_MIOT
self._preset_modes = PRESET_MODES_AIRPURIFIER_MIOT
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_MIOT
self._attr_supported_features = (
FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
)
self._speed_count = 3
self._attr_speed_count = 3
elif self._model in [
MODEL_AIRPURIFIER_4_LITE_RMA1,
MODEL_AIRPURIFIER_4_LITE_RMB1,
]:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_4_LITE
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_MIOT
self._preset_modes = PRESET_MODES_AIRPURIFIER_4_LITE
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_4_LITE
self._attr_supported_features = FanEntityFeature.PRESET_MODE
self._speed_count = 1
self._attr_speed_count = 1
elif self._model == MODEL_AIRPURIFIER_PRO_V7:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_PRO_V7
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_PRO_V7
self._preset_modes = PRESET_MODES_AIRPURIFIER_PRO_V7
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_PRO_V7
self._attr_supported_features = FanEntityFeature.PRESET_MODE
self._speed_count = 1
self._attr_speed_count = 1
elif self._model in [MODEL_AIRPURIFIER_2S, MODEL_AIRPURIFIER_2H]:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_2S
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_COMMON
self._preset_modes = PRESET_MODES_AIRPURIFIER_2S
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_2S
self._attr_supported_features = FanEntityFeature.PRESET_MODE
self._speed_count = 1
self._attr_speed_count = 1
elif self._model == MODEL_AIRPURIFIER_ZA1:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_ZA1
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_MIOT
self._preset_modes = PRESET_MODES_AIRPURIFIER_ZA1
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_ZA1
self._attr_supported_features = FanEntityFeature.PRESET_MODE
self._speed_count = 1
self._attr_speed_count = 1
elif self._model in MODELS_PURIFIER_MIOT:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_MIOT
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_MIOT
self._preset_modes = PRESET_MODES_AIRPURIFIER_MIOT
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_MIOT
self._attr_supported_features = (
FanEntityFeature.SET_SPEED | FanEntityFeature.PRESET_MODE
)
self._speed_count = 3
self._attr_speed_count = 3
elif self._model == MODEL_AIRPURIFIER_V3:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_V3
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER_V3
self._preset_modes = PRESET_MODES_AIRPURIFIER_V3
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_V3
self._attr_supported_features = FanEntityFeature.PRESET_MODE
self._speed_count = 1
self._attr_speed_count = 1
else:
self._device_features = FEATURE_FLAGS_AIRPURIFIER_MIIO
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRPURIFIER
self._preset_modes = PRESET_MODES_AIRPURIFIER
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER
self._attr_supported_features = FanEntityFeature.PRESET_MODE
self._speed_count = 1
self._attr_speed_count = 1
self._attr_supported_features |= (
FanEntityFeature.TURN_OFF | FanEntityFeature.TURN_ON
)
self._attr_is_on = self.coordinator.data.is_on
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{
key: self._extract_value_from_attribute(self.coordinator.data, value)
for key, value in self._available_attributes.items()
@ -526,7 +500,7 @@ class XiaomiAirPurifier(XiaomiGenericAirPurifier):
mode = self.operation_mode_class(self._mode)
if mode in self.REVERSE_SPEED_MODE_MAPPING:
return ranged_value_to_percentage(
(1, self._speed_count), self.REVERSE_SPEED_MODE_MAPPING[mode]
(1, self.speed_count), self.REVERSE_SPEED_MODE_MAPPING[mode]
)
return None
@ -541,7 +515,7 @@ class XiaomiAirPurifier(XiaomiGenericAirPurifier):
return
speed_mode = math.ceil(
percentage_to_ranged_value((1, self._speed_count), percentage)
percentage_to_ranged_value((1, self.speed_count), percentage)
)
if speed_mode:
await self._try_command(
@ -638,7 +612,7 @@ class XiaomiAirPurifierMB4(XiaomiGenericAirPurifier):
super().__init__(device, entry, unique_id, coordinator)
self._device_features = FEATURE_FLAGS_AIRPURIFIER_3C
self._preset_modes = PRESET_MODES_AIRPURIFIER_3C
self._attr_preset_modes = PRESET_MODES_AIRPURIFIER_3C
self._attr_supported_features = (
FanEntityFeature.SET_SPEED
| FanEntityFeature.PRESET_MODE
@ -748,8 +722,8 @@ class XiaomiAirFresh(XiaomiGenericAirPurifier):
self._device_features = FEATURE_FLAGS_AIRFRESH
self._available_attributes = AVAILABLE_ATTRIBUTES_AIRFRESH
self._speed_count = 4
self._preset_modes = PRESET_MODES_AIRFRESH
self._attr_speed_count = 4
self._attr_preset_modes = PRESET_MODES_AIRFRESH
self._attr_supported_features = (
FanEntityFeature.SET_SPEED
| FanEntityFeature.PRESET_MODE
@ -758,7 +732,7 @@ class XiaomiAirFresh(XiaomiGenericAirPurifier):
)
self._attr_is_on = self.coordinator.data.is_on
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{
key: getattr(self.coordinator.data, value)
for key, value in self._available_attributes.items()
@ -778,7 +752,7 @@ class XiaomiAirFresh(XiaomiGenericAirPurifier):
mode = AirfreshOperationMode(self._mode)
if mode in self.REVERSE_SPEED_MODE_MAPPING:
return ranged_value_to_percentage(
(1, self._speed_count), self.REVERSE_SPEED_MODE_MAPPING[mode]
(1, self.speed_count), self.REVERSE_SPEED_MODE_MAPPING[mode]
)
return None
@ -789,7 +763,7 @@ class XiaomiAirFresh(XiaomiGenericAirPurifier):
This method is a coroutine.
"""
speed_mode = math.ceil(
percentage_to_ranged_value((1, self._speed_count), percentage)
percentage_to_ranged_value((1, self.speed_count), percentage)
)
if speed_mode:
if await self._try_command(
@ -851,7 +825,7 @@ class XiaomiAirFreshA1(XiaomiGenericAirPurifier):
super().__init__(device, entry, unique_id, coordinator)
self._favorite_speed: int | None = None
self._device_features = FEATURE_FLAGS_AIRFRESH_A1
self._preset_modes = PRESET_MODES_AIRFRESH_A1
self._attr_preset_modes = PRESET_MODES_AIRFRESH_A1
self._attr_supported_features = (
FanEntityFeature.SET_SPEED
| FanEntityFeature.PRESET_MODE
@ -970,15 +944,8 @@ class XiaomiGenericFan(XiaomiGenericDevice):
)
if self._model != MODEL_FAN_1C:
self._attr_supported_features |= FanEntityFeature.DIRECTION
self._preset_mode: str | None = None
self._oscillating: bool | None = None
self._percentage: int | None = None
@property
def preset_mode(self) -> str | None:
"""Get the active preset mode."""
return self._preset_mode
@property
def preset_modes(self) -> list[str]:
"""Get the list of available preset modes."""
@ -992,11 +959,6 @@ class XiaomiGenericFan(XiaomiGenericDevice):
return None
@property
def oscillating(self) -> bool | None:
"""Return whether or not the fan is currently oscillating."""
return self._oscillating
async def async_oscillate(self, oscillating: bool) -> None:
"""Set oscillation."""
await self._try_command(
@ -1004,12 +966,12 @@ class XiaomiGenericFan(XiaomiGenericDevice):
self._device.set_oscillate, # type: ignore[attr-defined]
oscillating,
)
self._oscillating = oscillating
self._attr_oscillating = oscillating
self.async_write_ha_state()
async def async_set_direction(self, direction: str) -> None:
"""Set the direction of the fan."""
if self._oscillating:
if self._attr_oscillating:
await self.async_oscillate(oscillating=False)
await self._try_command(
@ -1033,7 +995,7 @@ class XiaomiFan(XiaomiGenericFan):
super().__init__(device, entry, unique_id, coordinator)
self._attr_is_on = self.coordinator.data.is_on
self._oscillating = self.coordinator.data.oscillate
self._attr_oscillating = self.coordinator.data.oscillate
self._nature_mode = self.coordinator.data.natural_speed != 0
if self._nature_mode:
self._percentage = self.coordinator.data.natural_speed
@ -1058,7 +1020,7 @@ class XiaomiFan(XiaomiGenericFan):
def _handle_coordinator_update(self):
"""Fetch state from the device."""
self._attr_is_on = self.coordinator.data.is_on
self._oscillating = self.coordinator.data.oscillate
self._attr_oscillating = self.coordinator.data.oscillate
self._nature_mode = self.coordinator.data.natural_speed != 0
if self._nature_mode:
self._percentage = self.coordinator.data.natural_speed
@ -1082,7 +1044,7 @@ class XiaomiFan(XiaomiGenericFan):
self._percentage,
)
self._preset_mode = preset_mode
self._attr_preset_mode = preset_mode
self.async_write_ha_state()
async def async_set_percentage(self, percentage: int) -> None:
@ -1126,8 +1088,8 @@ class XiaomiFanP5(XiaomiGenericFan):
super().__init__(device, entry, unique_id, coordinator)
self._attr_is_on = self.coordinator.data.is_on
self._preset_mode = self.coordinator.data.mode.name
self._oscillating = self.coordinator.data.oscillate
self._attr_preset_mode = self.coordinator.data.mode.name
self._attr_oscillating = self.coordinator.data.oscillate
self._percentage = self.coordinator.data.speed
@property
@ -1139,8 +1101,8 @@ class XiaomiFanP5(XiaomiGenericFan):
def _handle_coordinator_update(self):
"""Fetch state from the device."""
self._attr_is_on = self.coordinator.data.is_on
self._preset_mode = self.coordinator.data.mode.name
self._oscillating = self.coordinator.data.oscillate
self._attr_preset_mode = self.coordinator.data.mode.name
self._attr_oscillating = self.coordinator.data.oscillate
self._percentage = self.coordinator.data.speed
self.async_write_ha_state()
@ -1152,7 +1114,7 @@ class XiaomiFanP5(XiaomiGenericFan):
self._device.set_mode, # type: ignore[attr-defined]
self.operation_mode_class[preset_mode],
)
self._preset_mode = preset_mode
self._attr_preset_mode = preset_mode
self.async_write_ha_state()
async def async_set_percentage(self, percentage: int) -> None:
@ -1183,17 +1145,12 @@ class XiaomiFanMiot(XiaomiGenericFan):
"""Hold operation mode class."""
return FanOperationMode
@property
def preset_mode(self) -> str | None:
"""Get the active preset mode."""
return self._preset_mode
@callback
def _handle_coordinator_update(self):
"""Fetch state from the device."""
self._attr_is_on = self.coordinator.data.is_on
self._preset_mode = self.coordinator.data.mode.name
self._oscillating = self.coordinator.data.oscillate
self._attr_preset_mode = self.coordinator.data.mode.name
self._attr_oscillating = self.coordinator.data.oscillate
if self.coordinator.data.is_on:
self._percentage = self.coordinator.data.speed
else:
@ -1208,7 +1165,7 @@ class XiaomiFanMiot(XiaomiGenericFan):
self._device.set_mode, # type: ignore[attr-defined]
self.operation_mode_class[preset_mode],
)
self._preset_mode = preset_mode
self._attr_preset_mode = preset_mode
self.async_write_ha_state()
async def async_set_percentage(self, percentage: int) -> None:
@ -1253,17 +1210,17 @@ class XiaomiFan1C(XiaomiFanMiot):
) -> None:
"""Initialize MIOT fan with speed count."""
super().__init__(device, entry, unique_id, coordinator)
self._speed_count = 3
self._attr_speed_count = 3
@callback
def _handle_coordinator_update(self):
"""Fetch state from the device."""
self._attr_is_on = self.coordinator.data.is_on
self._preset_mode = self.coordinator.data.mode.name
self._oscillating = self.coordinator.data.oscillate
self._attr_preset_mode = self.coordinator.data.mode.name
self._attr_oscillating = self.coordinator.data.oscillate
if self.coordinator.data.is_on:
self._percentage = ranged_value_to_percentage(
(1, self._speed_count), self.coordinator.data.speed
(1, self.speed_count), self.coordinator.data.speed
)
else:
self._percentage = 0
@ -1277,9 +1234,7 @@ class XiaomiFan1C(XiaomiFanMiot):
await self.async_turn_off()
return
speed = math.ceil(
percentage_to_ranged_value((1, self._speed_count), percentage)
)
speed = math.ceil(percentage_to_ranged_value((1, self.speed_count), percentage))
# if the fan is not on, we have to turn it on first
if not self.is_on:
@ -1292,5 +1247,5 @@ class XiaomiFan1C(XiaomiFanMiot):
)
if result:
self._percentage = ranged_value_to_percentage((1, self._speed_count), speed)
self._percentage = ranged_value_to_percentage((1, self.speed_count), speed)
self.async_write_ha_state()

View File

@ -271,12 +271,7 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity):
"""Initialize the light device."""
super().__init__(name, device, entry, unique_id)
self._state_attrs: dict[str, Any] = {}
@property
def extra_state_attributes(self):
"""Return the state attributes of the device."""
return self._state_attrs
self._attr_extra_state_attributes = {}
async def _try_command(self, mask_error, func, *args, **kwargs):
"""Call a light command handling error messages."""
@ -349,7 +344,9 @@ class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
"""Initialize the light device."""
super().__init__(name, device, entry, unique_id)
self._state_attrs.update({ATTR_SCENE: None, ATTR_DELAYED_TURN_OFF: None})
self._attr_extra_state_attributes.update(
{ATTR_SCENE: None, ATTR_DELAYED_TURN_OFF: None}
)
async def async_update(self) -> None:
"""Fetch state from the device."""
@ -370,10 +367,10 @@ class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight):
delayed_turn_off = self.delayed_turn_off_timestamp(
state.delay_off_countdown,
dt_util.utcnow(),
self._state_attrs[ATTR_DELAYED_TURN_OFF],
self._attr_extra_state_attributes[ATTR_DELAYED_TURN_OFF],
)
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{ATTR_SCENE: state.scene, ATTR_DELAYED_TURN_OFF: delayed_turn_off}
)
@ -560,10 +557,10 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight):
delayed_turn_off = self.delayed_turn_off_timestamp(
state.delay_off_countdown,
dt_util.utcnow(),
self._state_attrs[ATTR_DELAYED_TURN_OFF],
self._attr_extra_state_attributes[ATTR_DELAYED_TURN_OFF],
)
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{ATTR_SCENE: state.scene, ATTR_DELAYED_TURN_OFF: delayed_turn_off}
)
@ -591,7 +588,7 @@ class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb):
"""Initialize the light device."""
super().__init__(name, device, entry, unique_id)
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{ATTR_NIGHT_LIGHT_MODE: None, ATTR_AUTOMATIC_COLOR_TEMPERATURE: None}
)
@ -631,10 +628,10 @@ class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb):
delayed_turn_off = self.delayed_turn_off_timestamp(
state.delay_off_countdown,
dt_util.utcnow(),
self._state_attrs[ATTR_DELAYED_TURN_OFF],
self._attr_extra_state_attributes[ATTR_DELAYED_TURN_OFF],
)
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{
ATTR_SCENE: state.scene,
ATTR_DELAYED_TURN_OFF: delayed_turn_off,
@ -659,7 +656,7 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
"""Initialize the light device."""
super().__init__(name, device, entry, unique_id)
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{ATTR_REMINDER: None, ATTR_NIGHT_LIGHT_MODE: None, ATTR_EYECARE_MODE: None}
)
@ -682,10 +679,10 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight):
delayed_turn_off = self.delayed_turn_off_timestamp(
state.delay_off_countdown,
dt_util.utcnow(),
self._state_attrs[ATTR_DELAYED_TURN_OFF],
self._attr_extra_state_attributes[ATTR_DELAYED_TURN_OFF],
)
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{
ATTR_SCENE: state.scene,
ATTR_DELAYED_TURN_OFF: delayed_turn_off,
@ -847,9 +844,8 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
"""Initialize the light device."""
super().__init__(name, device, entry, unique_id)
self._hs_color: tuple[float, float] | None = None
self._state_attrs.pop(ATTR_DELAYED_TURN_OFF)
self._state_attrs.update(
self._attr_extra_state_attributes.pop(ATTR_DELAYED_TURN_OFF)
self._attr_extra_state_attributes.update(
{
ATTR_SLEEP_ASSISTANT: None,
ATTR_SLEEP_OFF_TIME: None,
@ -869,11 +865,6 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
"""Return the warmest color_temp that this light supports."""
return 588
@property
def hs_color(self) -> tuple[float, float] | None:
"""Return the hs color value."""
return self._hs_color
@property
def color_mode(self) -> ColorMode:
"""Return the color mode of the light."""
@ -915,7 +906,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
)
if result:
self._hs_color = hs_color
self._attr_hs_color = hs_color
self._attr_brightness = brightness
elif ATTR_BRIGHTNESS in kwargs and ATTR_COLOR_TEMP_KELVIN in kwargs:
@ -949,7 +940,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
)
if result:
self._hs_color = hs_color
self._attr_hs_color = hs_color
elif ATTR_COLOR_TEMP_KELVIN in kwargs:
_LOGGER.debug(
@ -1007,9 +998,9 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb):
self._max_mireds,
self._min_mireds,
)
self._hs_color = color_util.color_RGB_to_hs(*state.rgb)
self._attr_hs_color = color_util.color_RGB_to_hs(*state.rgb)
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{
ATTR_SCENE: state.scene,
ATTR_SLEEP_ASSISTANT: state.sleep_assistant,

View File

@ -938,7 +938,7 @@ class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity):
"""Initialize the entity."""
super().__init__(name, device, entry, unique_id)
self._state_attrs = {
self._attr_extra_state_attributes = {
ATTR_POWER: None,
ATTR_BATTERY_LEVEL: None,
ATTR_CHARGING: None,
@ -950,11 +950,6 @@ class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity):
}
self.entity_description = description
@property
def extra_state_attributes(self):
"""Return the state attributes of the device."""
return self._state_attrs
async def async_update(self) -> None:
"""Fetch state from the miio device."""
try:
@ -963,7 +958,7 @@ class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity):
self._attr_available = True
self._attr_native_value = state.aqi
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{
ATTR_POWER: state.power,
ATTR_CHARGING: state.usb_power,

View File

@ -816,15 +816,13 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity):
"""Initialize the plug switch."""
super().__init__(name, device, entry, unique_id)
self._state_attrs = {ATTR_TEMPERATURE: None, ATTR_MODEL: self._model}
self._attr_extra_state_attributes = {
ATTR_TEMPERATURE: None,
ATTR_MODEL: self._model,
}
self._device_features = FEATURE_FLAGS_GENERIC
self._skip_update = False
@property
def extra_state_attributes(self):
"""Return the state attributes of the device."""
return self._state_attrs
async def _try_command(self, mask_error, func, *args, **kwargs):
"""Call a plug command handling error messages."""
try:
@ -877,7 +875,7 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity):
self._attr_available = True
self._attr_is_on = state.is_on
self._state_attrs[ATTR_TEMPERATURE] = state.temperature
self._attr_extra_state_attributes[ATTR_TEMPERATURE] = state.temperature
except DeviceException as ex:
if self._attr_available:
@ -934,16 +932,16 @@ class XiaomiPowerStripSwitch(XiaomiPlugGenericSwitch):
else:
self._device_features = FEATURE_FLAGS_POWER_STRIP_V1
self._state_attrs[ATTR_LOAD_POWER] = None
self._attr_extra_state_attributes[ATTR_LOAD_POWER] = None
if self._device_features & FEATURE_SET_POWER_MODE == 1:
self._state_attrs[ATTR_POWER_MODE] = None
self._attr_extra_state_attributes[ATTR_POWER_MODE] = None
if self._device_features & FEATURE_SET_WIFI_LED == 1:
self._state_attrs[ATTR_WIFI_LED] = None
self._attr_extra_state_attributes[ATTR_WIFI_LED] = None
if self._device_features & FEATURE_SET_POWER_PRICE == 1:
self._state_attrs[ATTR_POWER_PRICE] = None
self._attr_extra_state_attributes[ATTR_POWER_PRICE] = None
async def async_update(self) -> None:
"""Fetch state from the device."""
@ -958,21 +956,21 @@ class XiaomiPowerStripSwitch(XiaomiPlugGenericSwitch):
self._attr_available = True
self._attr_is_on = state.is_on
self._state_attrs.update(
self._attr_extra_state_attributes.update(
{ATTR_TEMPERATURE: state.temperature, ATTR_LOAD_POWER: state.load_power}
)
if self._device_features & FEATURE_SET_POWER_MODE == 1 and state.mode:
self._state_attrs[ATTR_POWER_MODE] = state.mode.value
self._attr_extra_state_attributes[ATTR_POWER_MODE] = state.mode.value
if self._device_features & FEATURE_SET_WIFI_LED == 1 and state.wifi_led:
self._state_attrs[ATTR_WIFI_LED] = state.wifi_led
self._attr_extra_state_attributes[ATTR_WIFI_LED] = state.wifi_led
if (
self._device_features & FEATURE_SET_POWER_PRICE == 1
and state.power_price
):
self._state_attrs[ATTR_POWER_PRICE] = state.power_price
self._attr_extra_state_attributes[ATTR_POWER_PRICE] = state.power_price
except DeviceException as ex:
if self._attr_available:
@ -1015,9 +1013,9 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch):
if self._model == MODEL_PLUG_V3:
self._device_features = FEATURE_FLAGS_PLUG_V3
self._state_attrs[ATTR_WIFI_LED] = None
self._attr_extra_state_attributes[ATTR_WIFI_LED] = None
if self._channel_usb is False:
self._state_attrs[ATTR_LOAD_POWER] = None
self._attr_extra_state_attributes[ATTR_LOAD_POWER] = None
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn a channel on."""
@ -1069,13 +1067,13 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch):
else:
self._attr_is_on = state.is_on
self._state_attrs[ATTR_TEMPERATURE] = state.temperature
self._attr_extra_state_attributes[ATTR_TEMPERATURE] = state.temperature
if state.wifi_led:
self._state_attrs[ATTR_WIFI_LED] = state.wifi_led
self._attr_extra_state_attributes[ATTR_WIFI_LED] = state.wifi_led
if self._channel_usb is False and state.load_power:
self._state_attrs[ATTR_LOAD_POWER] = state.load_power
self._attr_extra_state_attributes[ATTR_LOAD_POWER] = state.load_power
except DeviceException as ex:
if self._attr_available:
@ -1098,7 +1096,9 @@ class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch):
"""Initialize the acpartner switch."""
super().__init__(name, plug, entry, unique_id)
self._state_attrs.update({ATTR_TEMPERATURE: None, ATTR_LOAD_POWER: None})
self._attr_extra_state_attributes.update(
{ATTR_TEMPERATURE: None, ATTR_LOAD_POWER: None}
)
async def async_turn_on(self, **kwargs: Any) -> None:
"""Turn the socket on."""
@ -1135,7 +1135,7 @@ class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch):
self._attr_available = True
self._attr_is_on = state.power_socket == "on"
self._state_attrs[ATTR_LOAD_POWER] = state.load_power
self._attr_extra_state_attributes[ATTR_LOAD_POWER] = state.load_power
except DeviceException as ex:
if self._attr_available: