From c346b932f095cda9dc79876384ec5e7fa218ecea Mon Sep 17 00:00:00 2001 From: epenet <6771947+epenet@users.noreply.github.com> Date: Mon, 26 May 2025 15:57:01 +0200 Subject: [PATCH] Use shorthand attributes in xiaomi_miio (part 2) (#145616) * Use shorthand attributes in xiaomi_miio (part 2) * Brightness * Is_on --- homeassistant/components/xiaomi_miio/fan.py | 52 +++++++-------- homeassistant/components/xiaomi_miio/light.py | 66 +++++++------------ .../components/xiaomi_miio/sensor.py | 16 +---- .../components/xiaomi_miio/switch.py | 30 ++++----- .../components/xiaomi_miio/vacuum.py | 19 ++---- 5 files changed, 65 insertions(+), 118 deletions(-) diff --git a/homeassistant/components/xiaomi_miio/fan.py b/homeassistant/components/xiaomi_miio/fan.py index aa7069f1e92..4bb922383dc 100644 --- a/homeassistant/components/xiaomi_miio/fan.py +++ b/homeassistant/components/xiaomi_miio/fan.py @@ -313,7 +313,6 @@ class XiaomiGenericDevice( super().__init__(device, entry, unique_id, coordinator) self._available_attributes: dict[str, Any] = {} - self._state: bool | None = None self._mode: str | None = None self._fan_level: int | None = None self._state_attrs: dict[str, Any] = {} @@ -340,11 +339,6 @@ class XiaomiGenericDevice( """Return the state attributes of the device.""" return self._state_attrs - @property - def is_on(self) -> bool | None: - """Return true if device is on.""" - return self._state - async def async_turn_on( self, percentage: int | None = None, @@ -364,7 +358,7 @@ class XiaomiGenericDevice( await self.async_set_preset_mode(preset_mode) if result: - self._state = True + self._attr_is_on = True self.async_write_ha_state() async def async_turn_off(self, **kwargs: Any) -> None: @@ -375,7 +369,7 @@ class XiaomiGenericDevice( ) if result: - self._state = False + self._attr_is_on = False self.async_write_ha_state() @@ -402,7 +396,7 @@ class XiaomiGenericAirPurifier(XiaomiGenericDevice): @property def preset_mode(self) -> str | None: """Get the active preset mode.""" - if self._state: + 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 @@ -411,7 +405,7 @@ class XiaomiGenericAirPurifier(XiaomiGenericDevice): @callback def _handle_coordinator_update(self): """Fetch state from the device.""" - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._state_attrs.update( { key: self._extract_value_from_attribute(self.coordinator.data, value) @@ -510,7 +504,7 @@ class XiaomiAirPurifier(XiaomiGenericAirPurifier): FanEntityFeature.TURN_OFF | FanEntityFeature.TURN_ON ) - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._state_attrs.update( { key: self._extract_value_from_attribute(self.coordinator.data, value) @@ -528,7 +522,7 @@ class XiaomiAirPurifier(XiaomiGenericAirPurifier): @property def percentage(self) -> int | None: """Return the current percentage based speed.""" - if self._state: + if self._attr_is_on: mode = self.operation_mode_class(self._mode) if mode in self.REVERSE_SPEED_MODE_MAPPING: return ranged_value_to_percentage( @@ -604,7 +598,7 @@ class XiaomiAirPurifierMiot(XiaomiAirPurifier): """Return the current percentage based speed.""" if self._fan_level is None: return None - if self._state: + if self._attr_is_on: return ranged_value_to_percentage((1, 3), self._fan_level) return None @@ -652,7 +646,7 @@ class XiaomiAirPurifierMB4(XiaomiGenericAirPurifier): | FanEntityFeature.TURN_ON ) - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._mode = self.coordinator.data.mode.value self._favorite_rpm: int | None = None self._speed_range = (300, 2200) @@ -671,7 +665,7 @@ class XiaomiAirPurifierMB4(XiaomiGenericAirPurifier): return ranged_value_to_percentage(self._speed_range, self._motor_speed) if self._favorite_rpm is None: return None - if self._state: + if self._attr_is_on: return ranged_value_to_percentage(self._speed_range, self._favorite_rpm) return None @@ -698,7 +692,7 @@ class XiaomiAirPurifierMB4(XiaomiGenericAirPurifier): async def async_set_preset_mode(self, preset_mode: str) -> None: """Set the preset mode of the fan.""" - if not self._state: + if not self._attr_is_on: await self.async_turn_on() if await self._try_command( @@ -712,7 +706,7 @@ class XiaomiAirPurifierMB4(XiaomiGenericAirPurifier): @callback def _handle_coordinator_update(self): """Fetch state from the device.""" - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._mode = self.coordinator.data.mode.value self._favorite_rpm = getattr(self.coordinator.data, ATTR_FAVORITE_RPM, None) self._motor_speed = min( @@ -763,7 +757,7 @@ class XiaomiAirFresh(XiaomiGenericAirPurifier): | FanEntityFeature.TURN_ON ) - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._state_attrs.update( { key: getattr(self.coordinator.data, value) @@ -780,7 +774,7 @@ class XiaomiAirFresh(XiaomiGenericAirPurifier): @property def percentage(self) -> int | None: """Return the current percentage based speed.""" - if self._state: + if self._attr_is_on: mode = AirfreshOperationMode(self._mode) if mode in self.REVERSE_SPEED_MODE_MAPPING: return ranged_value_to_percentage( @@ -865,7 +859,7 @@ class XiaomiAirFreshA1(XiaomiGenericAirPurifier): | FanEntityFeature.TURN_ON ) - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._mode = self.coordinator.data.mode.value self._speed_range = (60, 150) @@ -879,7 +873,7 @@ class XiaomiAirFreshA1(XiaomiGenericAirPurifier): """Return the current percentage based speed.""" if self._favorite_speed is None: return None - if self._state: + if self._attr_is_on: return ranged_value_to_percentage(self._speed_range, self._favorite_speed) return None @@ -918,7 +912,7 @@ class XiaomiAirFreshA1(XiaomiGenericAirPurifier): @callback def _handle_coordinator_update(self): """Fetch state from the device.""" - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._mode = self.coordinator.data.mode.value self._favorite_speed = getattr(self.coordinator.data, ATTR_FAVORITE_SPEED, None) self.async_write_ha_state() @@ -993,7 +987,7 @@ class XiaomiGenericFan(XiaomiGenericDevice): @property def percentage(self) -> int | None: """Return the current speed as a percentage.""" - if self._state: + if self._attr_is_on: return self._percentage return None @@ -1038,7 +1032,7 @@ class XiaomiFan(XiaomiGenericFan): """Initialize the fan.""" super().__init__(device, entry, unique_id, coordinator) - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._oscillating = self.coordinator.data.oscillate self._nature_mode = self.coordinator.data.natural_speed != 0 if self._nature_mode: @@ -1063,7 +1057,7 @@ class XiaomiFan(XiaomiGenericFan): @callback def _handle_coordinator_update(self): """Fetch state from the device.""" - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._oscillating = self.coordinator.data.oscillate self._nature_mode = self.coordinator.data.natural_speed != 0 if self._nature_mode: @@ -1131,7 +1125,7 @@ class XiaomiFanP5(XiaomiGenericFan): """Initialize the fan.""" super().__init__(device, entry, unique_id, coordinator) - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._preset_mode = self.coordinator.data.mode.name self._oscillating = self.coordinator.data.oscillate self._percentage = self.coordinator.data.speed @@ -1144,7 +1138,7 @@ class XiaomiFanP5(XiaomiGenericFan): @callback def _handle_coordinator_update(self): """Fetch state from the device.""" - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._preset_mode = self.coordinator.data.mode.name self._oscillating = self.coordinator.data.oscillate self._percentage = self.coordinator.data.speed @@ -1197,7 +1191,7 @@ class XiaomiFanMiot(XiaomiGenericFan): @callback def _handle_coordinator_update(self): """Fetch state from the device.""" - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._preset_mode = self.coordinator.data.mode.name self._oscillating = self.coordinator.data.oscillate if self.coordinator.data.is_on: @@ -1264,7 +1258,7 @@ class XiaomiFan1C(XiaomiFanMiot): @callback def _handle_coordinator_update(self): """Fetch state from the device.""" - self._state = self.coordinator.data.is_on + self._attr_is_on = self.coordinator.data.is_on self._preset_mode = self.coordinator.data.mode.name self._oscillating = self.coordinator.data.oscillate if self.coordinator.data.is_on: diff --git a/homeassistant/components/xiaomi_miio/light.py b/homeassistant/components/xiaomi_miio/light.py index 6f4978b163e..4271894ba17 100644 --- a/homeassistant/components/xiaomi_miio/light.py +++ b/homeassistant/components/xiaomi_miio/light.py @@ -271,8 +271,6 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity): """Initialize the light device.""" super().__init__(name, device, entry, unique_id) - self._brightness = None - self._state = None self._state_attrs: dict[str, Any] = {} @property @@ -280,16 +278,6 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity): """Return the state attributes of the device.""" return self._state_attrs - @property - def is_on(self): - """Return true if light is on.""" - return self._state - - @property - def brightness(self): - """Return the brightness of this light between 0..255.""" - return self._brightness - async def _try_command(self, mask_error, func, *args, **kwargs): """Call a light command handling error messages.""" try: @@ -321,7 +309,7 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity): ) if result: - self._brightness = brightness + self._attr_brightness = brightness else: await self._try_command("Turning the light on failed.", self._device.on) @@ -342,8 +330,8 @@ class XiaomiPhilipsAbstractLight(XiaomiMiioEntity, LightEntity): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on - self._brightness = ceil((255 / 100.0) * state.brightness) + self._attr_is_on = state.is_on + self._attr_brightness = ceil((255 / 100.0) * state.brightness) class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight): @@ -376,8 +364,8 @@ class XiaomiPhilipsGenericLight(XiaomiPhilipsAbstractLight): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on - self._brightness = ceil((255 / 100.0) * state.brightness) + self._attr_is_on = state.is_on + self._attr_brightness = ceil((255 / 100.0) * state.brightness) delayed_turn_off = self.delayed_turn_off_timestamp( state.delay_off_countdown, @@ -510,7 +498,7 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight): if result: self._color_temp = color_temp - self._brightness = brightness + self._attr_brightness = brightness elif ATTR_COLOR_TEMP_KELVIN in kwargs: _LOGGER.debug( @@ -541,7 +529,7 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight): ) if result: - self._brightness = brightness + self._attr_brightness = brightness else: await self._try_command("Turning the light on failed.", self._device.on) @@ -559,8 +547,8 @@ class XiaomiPhilipsBulb(XiaomiPhilipsGenericLight): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on - self._brightness = ceil((255 / 100.0) * state.brightness) + self._attr_is_on = state.is_on + self._attr_brightness = ceil((255 / 100.0) * state.brightness) self._color_temp = self.translate( state.color_temperature, CCT_MIN, @@ -630,8 +618,8 @@ class XiaomiPhilipsCeilingLamp(XiaomiPhilipsBulb): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on - self._brightness = ceil((255 / 100.0) * state.brightness) + self._attr_is_on = state.is_on + self._attr_brightness = ceil((255 / 100.0) * state.brightness) self._color_temp = self.translate( state.color_temperature, CCT_MIN, @@ -688,8 +676,8 @@ class XiaomiPhilipsEyecareLamp(XiaomiPhilipsGenericLight): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on - self._brightness = ceil((255 / 100.0) * state.brightness) + self._attr_is_on = state.is_on + self._attr_brightness = ceil((255 / 100.0) * state.brightness) delayed_turn_off = self.delayed_turn_off_timestamp( state.delay_off_countdown, @@ -814,7 +802,7 @@ class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight): ) if result: - self._brightness = brightness + self._attr_brightness = brightness else: await self._try_command( "Turning the ambient light on failed.", self._device.ambient_on @@ -839,8 +827,8 @@ class XiaomiPhilipsEyecareLampAmbientLight(XiaomiPhilipsAbstractLight): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.ambient - self._brightness = ceil((255 / 100.0) * state.ambient_brightness) + self._attr_is_on = state.ambient + self._attr_brightness = ceil((255 / 100.0) * state.ambient_brightness) class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb): @@ -928,7 +916,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb): if result: self._hs_color = hs_color - self._brightness = brightness + self._attr_brightness = brightness elif ATTR_BRIGHTNESS in kwargs and ATTR_COLOR_TEMP_KELVIN in kwargs: _LOGGER.debug( @@ -951,7 +939,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb): if result: self._color_temp = color_temp - self._brightness = brightness + self._attr_brightness = brightness elif ATTR_HS_COLOR in kwargs: _LOGGER.debug("Setting color: %s", rgb) @@ -992,7 +980,7 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb): ) if result: - self._brightness = brightness + self._attr_brightness = brightness else: await self._try_command("Turning the light on failed.", self._device.on) @@ -1010,8 +998,8 @@ class XiaomiPhilipsMoonlightLamp(XiaomiPhilipsBulb): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on - self._brightness = ceil((255 / 100.0) * state.brightness) + self._attr_is_on = state.is_on + self._attr_brightness = ceil((255 / 100.0) * state.brightness) self._color_temp = self.translate( state.color_temperature, CCT_MIN, @@ -1050,7 +1038,6 @@ class XiaomiGatewayLight(LightEntity): self._gateway_device_id = gateway_device_id self._attr_unique_id = gateway_device_id self._attr_available = False - self._is_on = None self._brightness_pct = 100 self._rgb = (255, 255, 255) self._hs = (0, 0) @@ -1062,11 +1049,6 @@ class XiaomiGatewayLight(LightEntity): identifiers={(DOMAIN, self._gateway_device_id)}, ) - @property - def is_on(self): - """Return true if it is on.""" - return self._is_on - @property def brightness(self): """Return the brightness of this light between 0..255.""" @@ -1113,9 +1095,9 @@ class XiaomiGatewayLight(LightEntity): return self._attr_available = True - self._is_on = state_dict["is_on"] + self._attr_is_on = state_dict["is_on"] - if self._is_on: + if self._attr_is_on: self._brightness_pct = state_dict["brightness"] self._rgb = state_dict["rgb"] self._hs = color_util.color_RGB_to_hs(*self._rgb) @@ -1139,7 +1121,7 @@ class XiaomiGatewayBulb(XiaomiGatewayDevice, LightEntity): return self._sub_device.status["color_temp"] @property - def is_on(self): + def is_on(self) -> bool: """Return true if light is on.""" return self._sub_device.status["status"] == "on" diff --git a/homeassistant/components/xiaomi_miio/sensor.py b/homeassistant/components/xiaomi_miio/sensor.py index da4552cc63e..e7f652d1de2 100644 --- a/homeassistant/components/xiaomi_miio/sensor.py +++ b/homeassistant/components/xiaomi_miio/sensor.py @@ -938,7 +938,6 @@ class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity): """Initialize the entity.""" super().__init__(name, device, entry, unique_id) - self._state = None self._state_attrs = { ATTR_POWER: None, ATTR_BATTERY_LEVEL: None, @@ -951,11 +950,6 @@ class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity): } self.entity_description = description - @property - def native_value(self): - """Return the state of the device.""" - return self._state - @property def extra_state_attributes(self): """Return the state attributes of the device.""" @@ -968,7 +962,7 @@ class XiaomiAirQualityMonitor(XiaomiMiioEntity, SensorEntity): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.aqi + self._attr_native_value = state.aqi self._state_attrs.update( { ATTR_POWER: state.power, @@ -1023,17 +1017,11 @@ class XiaomiGatewayIlluminanceSensor(SensorEntity): self._gateway = gateway_device self.entity_description = description self._attr_available = False - self._state = None - - @property - def native_value(self): - """Return the state of the device.""" - return self._state async def async_update(self) -> None: """Fetch state from the device.""" try: - self._state = await self.hass.async_add_executor_job( + self._attr_native_value = await self.hass.async_add_executor_job( self._gateway.get_illumination ) self._attr_available = True diff --git a/homeassistant/components/xiaomi_miio/switch.py b/homeassistant/components/xiaomi_miio/switch.py index 508a6e1a227..ff6387bc7c1 100644 --- a/homeassistant/components/xiaomi_miio/switch.py +++ b/homeassistant/components/xiaomi_miio/switch.py @@ -783,7 +783,7 @@ class XiaomiGatewaySwitch(XiaomiGatewayDevice, SwitchEntity): self._attr_name = f"{sub_device.name} ch{self._channel} ({sub_device.sid})" @property - def is_on(self): + def is_on(self) -> bool: """Return true if switch is on.""" return self._sub_device.status[self._data_key] == "on" @@ -816,7 +816,6 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity): """Initialize the plug switch.""" super().__init__(name, device, entry, unique_id) - self._state: bool | None = None self._state_attrs = {ATTR_TEMPERATURE: None, ATTR_MODEL: self._model} self._device_features = FEATURE_FLAGS_GENERIC self._skip_update = False @@ -826,11 +825,6 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity): """Return the state attributes of the device.""" return self._state_attrs - @property - def is_on(self): - """Return true if switch is on.""" - return self._state - async def _try_command(self, mask_error, func, *args, **kwargs): """Call a plug command handling error messages.""" try: @@ -857,7 +851,7 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity): result = await self._try_command("Turning the plug on failed", self._device.on) if result: - self._state = True + self._attr_is_on = True self._skip_update = True async def async_turn_off(self, **kwargs: Any) -> None: @@ -867,7 +861,7 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity): ) if result: - self._state = False + self._attr_is_on = False self._skip_update = True async def async_update(self) -> None: @@ -882,7 +876,7 @@ class XiaomiPlugGenericSwitch(XiaomiMiioEntity, SwitchEntity): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on + self._attr_is_on = state.is_on self._state_attrs[ATTR_TEMPERATURE] = state.temperature except DeviceException as ex: @@ -963,7 +957,7 @@ class XiaomiPowerStripSwitch(XiaomiPlugGenericSwitch): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.is_on + self._attr_is_on = state.is_on self._state_attrs.update( {ATTR_TEMPERATURE: state.temperature, ATTR_LOAD_POWER: state.load_power} ) @@ -1039,7 +1033,7 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch): ) if result: - self._state = True + self._attr_is_on = True self._skip_update = True async def async_turn_off(self, **kwargs: Any) -> None: @@ -1055,7 +1049,7 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch): ) if result: - self._state = False + self._attr_is_on = False self._skip_update = True async def async_update(self) -> None: @@ -1071,9 +1065,9 @@ class ChuangMiPlugSwitch(XiaomiPlugGenericSwitch): self._attr_available = True if self._channel_usb: - self._state = state.usb_power + self._attr_is_on = state.usb_power else: - self._state = state.is_on + self._attr_is_on = state.is_on self._state_attrs[ATTR_TEMPERATURE] = state.temperature @@ -1114,7 +1108,7 @@ class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch): ) if result: - self._state = True + self._attr_is_on = True self._skip_update = True async def async_turn_off(self, **kwargs: Any) -> None: @@ -1125,7 +1119,7 @@ class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch): ) if result: - self._state = False + self._attr_is_on = False self._skip_update = True async def async_update(self) -> None: @@ -1140,7 +1134,7 @@ class XiaomiAirConditioningCompanionSwitch(XiaomiPlugGenericSwitch): _LOGGER.debug("Got new state: %s", state) self._attr_available = True - self._state = state.power_socket == "on" + self._attr_is_on = state.power_socket == "on" self._state_attrs[ATTR_LOAD_POWER] = state.load_power except DeviceException as ex: diff --git a/homeassistant/components/xiaomi_miio/vacuum.py b/homeassistant/components/xiaomi_miio/vacuum.py index ca6ab084324..3b397e9ccfd 100644 --- a/homeassistant/components/xiaomi_miio/vacuum.py +++ b/homeassistant/components/xiaomi_miio/vacuum.py @@ -6,7 +6,7 @@ from functools import partial import logging from typing import Any -from miio import Device as MiioDevice, DeviceException +from miio import DeviceException import voluptuous as vol from homeassistant.components.vacuum import ( @@ -194,17 +194,6 @@ class MiroboVacuum( | VacuumEntityFeature.START ) - def __init__( - self, - device: MiioDevice, - entry: XiaomiMiioConfigEntry, - unique_id: str | None, - coordinator: DataUpdateCoordinator[VacuumCoordinatorData], - ) -> None: - """Initialize the Xiaomi vacuum cleaner robot handler.""" - super().__init__(device, entry, unique_id, coordinator) - self._state: VacuumActivity | None = None - async def async_added_to_hass(self) -> None: """Run when entity is about to be added to hass.""" await super().async_added_to_hass() @@ -218,7 +207,7 @@ class MiroboVacuum( if self.coordinator.data.status.got_error: return VacuumActivity.ERROR - return self._state + return super().activity @property def battery_level(self) -> int: @@ -435,8 +424,8 @@ class MiroboVacuum( self.coordinator.data.status.state, self.coordinator.data.status.state_code, ) - self._state = None + self._attr_activity = None else: - self._state = STATE_CODE_TO_STATE[state_code] + self._attr_activity = STATE_CODE_TO_STATE[state_code] super()._handle_coordinator_update()