Use shorthand attributes in xiaomi_aqara (#145253)

* Use shorthand attributes for is_on/is_locked in xiaomi_aqara

* Use _attr_changed_by

* Use _attr_device_class

* Remove unused class variable

* More
This commit is contained in:
epenet 2025-05-20 11:47:26 +02:00 committed by GitHub
parent f2233b3034
commit 43ae0f2541
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 48 additions and 87 deletions

View File

@ -140,20 +140,9 @@ class XiaomiBinarySensor(XiaomiDevice, BinarySensorEntity):
def __init__(self, device, name, xiaomi_hub, data_key, device_class, config_entry):
"""Initialize the XiaomiSmokeSensor."""
self._data_key = data_key
self._device_class = device_class
self._density = 0
self._attr_device_class = device_class
super().__init__(device, name, xiaomi_hub, config_entry)
@property
def is_on(self):
"""Return true if sensor is on."""
return self._state
@property
def device_class(self):
"""Return the class of binary sensor."""
return self._device_class
def update(self) -> None:
"""Update the sensor state."""
_LOGGER.debug("Updating xiaomi sensor (%s) by polling", self._sid)
@ -180,7 +169,7 @@ class XiaomiNatgasSensor(XiaomiBinarySensor):
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
self._state = False
self._attr_is_on = False
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
@ -192,13 +181,13 @@ class XiaomiNatgasSensor(XiaomiBinarySensor):
return False
if value in ("1", "2"):
if self._state:
if self._attr_is_on:
return False
self._state = True
self._attr_is_on = True
return True
if value == "0":
if self._state:
self._state = False
if self._attr_is_on:
self._attr_is_on = False
return True
return False
@ -232,13 +221,13 @@ class XiaomiMotionSensor(XiaomiBinarySensor):
def _async_set_no_motion(self, now):
"""Set state to False."""
self._unsub_set_no_motion = None
self._state = False
self._attr_is_on = False
self.async_write_ha_state()
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
self._state = False
self._attr_is_on = False
def parse_data(self, data, raw_data):
"""Parse data sent by gateway.
@ -274,7 +263,7 @@ class XiaomiMotionSensor(XiaomiBinarySensor):
if NO_MOTION in data:
self._no_motion_since = data[NO_MOTION]
self._state = False
self._attr_is_on = False
return True
value = data.get(self._data_key)
@ -295,9 +284,9 @@ class XiaomiMotionSensor(XiaomiBinarySensor):
)
self._no_motion_since = 0
if self._state:
if self._attr_is_on:
return False
self._state = True
self._attr_is_on = True
return True
return False
@ -335,7 +324,7 @@ class XiaomiDoorSensor(XiaomiBinarySensor, RestoreEntity):
if (state := await self.async_get_last_state()) is None:
return
self._state = state.state == "on"
self._attr_is_on = state.state == "on"
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
@ -350,14 +339,14 @@ class XiaomiDoorSensor(XiaomiBinarySensor, RestoreEntity):
if value == "open":
self._attr_should_poll = True
if self._state:
if self._attr_is_on:
return False
self._state = True
self._attr_is_on = True
return True
if value == "close":
self._open_since = 0
if self._state:
self._state = False
if self._attr_is_on:
self._attr_is_on = False
return True
return False
@ -385,7 +374,7 @@ class XiaomiWaterLeakSensor(XiaomiBinarySensor):
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
self._state = False
self._attr_is_on = False
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
@ -397,13 +386,13 @@ class XiaomiWaterLeakSensor(XiaomiBinarySensor):
if value == "leak":
self._attr_should_poll = True
if self._state:
if self._attr_is_on:
return False
self._state = True
self._attr_is_on = True
return True
if value == "no_leak":
if self._state:
self._state = False
if self._attr_is_on:
self._attr_is_on = False
return True
return False
@ -430,7 +419,7 @@ class XiaomiSmokeSensor(XiaomiBinarySensor):
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
self._state = False
self._attr_is_on = False
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
@ -441,13 +430,13 @@ class XiaomiSmokeSensor(XiaomiBinarySensor):
return False
if value in ("1", "2"):
if self._state:
if self._attr_is_on:
return False
self._state = True
self._attr_is_on = True
return True
if value == "0":
if self._state:
self._state = False
if self._attr_is_on:
self._attr_is_on = False
return True
return False
@ -472,7 +461,7 @@ class XiaomiVibration(XiaomiBinarySensor):
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
self._state = False
self._attr_is_on = False
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
@ -512,7 +501,7 @@ class XiaomiButton(XiaomiBinarySensor):
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
self._state = False
self._attr_is_on = False
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
@ -521,10 +510,10 @@ class XiaomiButton(XiaomiBinarySensor):
return False
if value == "long_click_press":
self._state = True
self._attr_is_on = True
click_type = "long_click_press"
elif value == "long_click_release":
self._state = False
self._attr_is_on = False
click_type = "hold"
elif value == "click":
click_type = "single"
@ -576,7 +565,7 @@ class XiaomiCube(XiaomiBinarySensor):
async def async_added_to_hass(self) -> None:
"""Handle entity which will be added."""
await super().async_added_to_hass()
self._state = False
self._attr_is_on = False
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""

View File

@ -26,7 +26,6 @@ class XiaomiDevice(Entity):
def __init__(self, device, device_type, xiaomi_hub, config_entry):
"""Initialize the Xiaomi device."""
self._state = None
self._is_available = True
self._sid = device["sid"]
self._model = device["model"]
@ -36,7 +35,7 @@ class XiaomiDevice(Entity):
self._type = device_type
self._write_to_hub = xiaomi_hub.write_to_hub
self._get_from_hub = xiaomi_hub.get_from_hub
self._extra_state_attributes = {}
self._attr_extra_state_attributes = {}
self._remove_unavailability_tracker = None
self._xiaomi_hub = xiaomi_hub
self.parse_data(device["data"], device["raw_data"])
@ -104,11 +103,6 @@ class XiaomiDevice(Entity):
"""Return True if entity is available."""
return self._is_available
@property
def extra_state_attributes(self):
"""Return the state attributes."""
return self._extra_state_attributes
@callback
def _async_set_unavailable(self, now):
"""Set state to UNAVAILABLE."""
@ -154,11 +148,11 @@ class XiaomiDevice(Entity):
max_volt = 3300
min_volt = 2800
voltage = data[voltage_key]
self._extra_state_attributes[ATTR_VOLTAGE] = round(voltage / 1000.0, 2)
self._attr_extra_state_attributes[ATTR_VOLTAGE] = round(voltage / 1000.0, 2)
voltage = min(voltage, max_volt)
voltage = max(voltage, min_volt)
percent = ((voltage - min_volt) / (max_volt - min_volt)) * 100
self._extra_state_attributes[ATTR_BATTERY_LEVEL] = round(percent, 1)
self._attr_extra_state_attributes[ATTR_BATTERY_LEVEL] = round(percent, 1)
return True
def parse_data(self, data, raw_data):

View File

@ -53,11 +53,6 @@ class XiaomiGatewayLight(XiaomiDevice, LightEntity):
super().__init__(device, name, xiaomi_hub, config_entry)
@property
def is_on(self):
"""Return true if it is on."""
return self._state
def parse_data(self, data, raw_data):
"""Parse data sent by gateway."""
value = data.get(self._data_key)
@ -65,7 +60,7 @@ class XiaomiGatewayLight(XiaomiDevice, LightEntity):
return False
if value == 0:
self._state = False
self._attr_is_on = False
return True
rgbhexstr = f"{value:x}"
@ -84,7 +79,7 @@ class XiaomiGatewayLight(XiaomiDevice, LightEntity):
self._brightness = brightness
self._hs = color_util.color_RGB_to_hs(*rgb)
self._state = True
self._attr_is_on = True
return True
@property
@ -111,11 +106,11 @@ class XiaomiGatewayLight(XiaomiDevice, LightEntity):
rgbhex = int(rgbhex_str, 16)
if self._write_to_hub(self._sid, **{self._data_key: rgbhex}):
self._state = True
self._attr_is_on = True
self.schedule_update_ha_state()
def turn_off(self, **kwargs: Any) -> None:
"""Turn the light off."""
if self._write_to_hub(self._sid, **{self._data_key: 0}):
self._state = False
self._attr_is_on = False
self.schedule_update_ha_state()

View File

@ -2,7 +2,7 @@
from __future__ import annotations
from homeassistant.components.lock import LockEntity, LockState
from homeassistant.components.lock import LockEntity
from homeassistant.config_entries import ConfigEntry
from homeassistant.core import HomeAssistant, callback
from homeassistant.helpers.entity_platform import AddConfigEntryEntitiesCallback
@ -40,23 +40,11 @@ class XiaomiAqaraLock(LockEntity, XiaomiDevice):
def __init__(self, device, name, xiaomi_hub, config_entry):
"""Initialize the XiaomiAqaraLock."""
self._changed_by = 0
self._attr_changed_by = "0"
self._verified_wrong_times = 0
super().__init__(device, name, xiaomi_hub, config_entry)
@property
def is_locked(self) -> bool | None:
"""Return true if lock is locked."""
if self._state is not None:
return self._state == LockState.LOCKED
return None
@property
def changed_by(self) -> str:
"""Last change triggered by."""
return self._changed_by
@property
def extra_state_attributes(self) -> dict[str, int]:
"""Return the state attributes."""
@ -65,7 +53,7 @@ class XiaomiAqaraLock(LockEntity, XiaomiDevice):
@callback
def clear_unlock_state(self, _):
"""Clear unlock state automatically."""
self._state = LockState.LOCKED
self._attr_is_locked = True
self.async_write_ha_state()
def parse_data(self, data, raw_data):
@ -76,9 +64,9 @@ class XiaomiAqaraLock(LockEntity, XiaomiDevice):
for key in (FINGER_KEY, PASSWORD_KEY, CARD_KEY):
if (value := data.get(key)) is not None:
self._changed_by = int(value)
self._attr_changed_by = str(int(value))
self._verified_wrong_times = 0
self._state = LockState.UNLOCKED
self._attr_is_locked = False
async_call_later(
self.hass, UNLOCK_MAINTAIN_TIME, self.clear_unlock_state
)

View File

@ -206,7 +206,7 @@ class XiaomiBatterySensor(XiaomiDevice, SensorEntity):
succeed = super().parse_voltage(data)
if not succeed:
return False
battery_level = int(self._extra_state_attributes.pop(ATTR_BATTERY_LEVEL))
battery_level = int(self._attr_extra_state_attributes.pop(ATTR_BATTERY_LEVEL))
if battery_level <= 0 or battery_level > 100:
return False
self._attr_native_value = battery_level

View File

@ -162,11 +162,6 @@ class XiaomiGenericSwitch(XiaomiDevice, SwitchEntity):
return "mdi:power-plug"
return "mdi:power-socket"
@property
def is_on(self):
"""Return true if it is on."""
return self._state
@property
def extra_state_attributes(self):
"""Return the state attributes."""
@ -184,13 +179,13 @@ class XiaomiGenericSwitch(XiaomiDevice, SwitchEntity):
def turn_on(self, **kwargs: Any) -> None:
"""Turn the switch on."""
if self._write_to_hub(self._sid, **{self._data_key: "on"}):
self._state = True
self._attr_is_on = True
self.schedule_update_ha_state()
def turn_off(self, **kwargs: Any) -> None:
"""Turn the switch off."""
if self._write_to_hub(self._sid, **{self._data_key: "off"}):
self._state = False
self._attr_is_on = False
self.schedule_update_ha_state()
def parse_data(self, data, raw_data):
@ -213,9 +208,9 @@ class XiaomiGenericSwitch(XiaomiDevice, SwitchEntity):
return False
state = value == "on"
if self._state == state:
if self._attr_is_on == state:
return False
self._state = state
self._attr_is_on = state
return True
def update(self) -> None: