Use shorthand attributes for mobile_app sensor platforms (#108353)
parent
42154bd684
commit
4d69515849
|
@ -4,7 +4,7 @@ from typing import Any
|
|||
from homeassistant.components.binary_sensor import BinarySensorEntity
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_WEBHOOK_ID, STATE_ON
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import HomeAssistant, State, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
@ -70,13 +70,14 @@ async def async_setup_entry(
|
|||
class MobileAppBinarySensor(MobileAppEntity, BinarySensorEntity):
|
||||
"""Representation of an mobile app binary sensor."""
|
||||
|
||||
@property
|
||||
def is_on(self):
|
||||
"""Return the state of the binary sensor."""
|
||||
return self._config[ATTR_SENSOR_STATE]
|
||||
|
||||
async def async_restore_last_state(self, last_state):
|
||||
async def async_restore_last_state(self, last_state: State) -> None:
|
||||
"""Restore previous state."""
|
||||
|
||||
await super().async_restore_last_state(last_state)
|
||||
self._config[ATTR_SENSOR_STATE] = last_state.state == STATE_ON
|
||||
self._async_update_attr_from_config()
|
||||
|
||||
@callback
|
||||
def _async_update_attr_from_config(self) -> None:
|
||||
"""Update the entity from the config."""
|
||||
super()._async_update_attr_from_config()
|
||||
self._attr_is_on = self._config[ATTR_SENSOR_STATE]
|
||||
|
|
|
@ -5,7 +5,7 @@ from typing import Any
|
|||
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import ATTR_ICON, CONF_NAME, CONF_UNIQUE_ID, STATE_UNAVAILABLE
|
||||
from homeassistant.core import callback
|
||||
from homeassistant.core import State, callback
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.restore_state import RestoreEntity
|
||||
|
||||
|
@ -32,9 +32,23 @@ class MobileAppEntity(RestoreEntity):
|
|||
self._entry = entry
|
||||
self._registration = entry.data
|
||||
self._attr_unique_id = config[CONF_UNIQUE_ID]
|
||||
self._name = self._config[CONF_NAME]
|
||||
self._attr_entity_registry_enabled_default = not config.get(
|
||||
ATTR_SENSOR_DISABLED
|
||||
)
|
||||
self._attr_name = config[CONF_NAME]
|
||||
self._async_update_attr_from_config()
|
||||
|
||||
async def async_added_to_hass(self):
|
||||
@callback
|
||||
def _async_update_attr_from_config(self) -> None:
|
||||
"""Update the entity from the config."""
|
||||
config = self._config
|
||||
self._attr_device_class = config.get(ATTR_SENSOR_DEVICE_CLASS)
|
||||
self._attr_extra_state_attributes = config[ATTR_SENSOR_ATTRIBUTES]
|
||||
self._attr_icon = config[ATTR_SENSOR_ICON]
|
||||
self._attr_entity_category = config.get(ATTR_SENSOR_ENTITY_CATEGORY)
|
||||
self._attr_available = config.get(ATTR_SENSOR_STATE) != STATE_UNAVAILABLE
|
||||
|
||||
async def async_added_to_hass(self) -> None:
|
||||
"""Register callbacks."""
|
||||
self.async_on_remove(
|
||||
async_dispatcher_connect(
|
||||
|
@ -49,58 +63,25 @@ class MobileAppEntity(RestoreEntity):
|
|||
|
||||
await self.async_restore_last_state(state)
|
||||
|
||||
async def async_restore_last_state(self, last_state):
|
||||
async def async_restore_last_state(self, last_state: State) -> None:
|
||||
"""Restore previous state."""
|
||||
self._config[ATTR_SENSOR_STATE] = last_state.state
|
||||
self._config[ATTR_SENSOR_ATTRIBUTES] = {
|
||||
config = self._config
|
||||
config[ATTR_SENSOR_STATE] = last_state.state
|
||||
config[ATTR_SENSOR_ATTRIBUTES] = {
|
||||
**last_state.attributes,
|
||||
**self._config[ATTR_SENSOR_ATTRIBUTES],
|
||||
}
|
||||
if ATTR_ICON in last_state.attributes:
|
||||
self._config[ATTR_SENSOR_ICON] = last_state.attributes[ATTR_ICON]
|
||||
|
||||
@property
|
||||
def name(self):
|
||||
"""Return the name of the mobile app sensor."""
|
||||
return self._name
|
||||
|
||||
@property
|
||||
def entity_registry_enabled_default(self) -> bool:
|
||||
"""Return if entity should be enabled by default."""
|
||||
return not self._config.get(ATTR_SENSOR_DISABLED)
|
||||
|
||||
@property
|
||||
def device_class(self):
|
||||
"""Return the device class."""
|
||||
return self._config.get(ATTR_SENSOR_DEVICE_CLASS)
|
||||
|
||||
@property
|
||||
def extra_state_attributes(self):
|
||||
"""Return the device state attributes."""
|
||||
return self._config[ATTR_SENSOR_ATTRIBUTES]
|
||||
|
||||
@property
|
||||
def icon(self):
|
||||
"""Return the icon to use in the frontend, if any."""
|
||||
return self._config[ATTR_SENSOR_ICON]
|
||||
|
||||
@property
|
||||
def entity_category(self):
|
||||
"""Return the entity category, if any."""
|
||||
return self._config.get(ATTR_SENSOR_ENTITY_CATEGORY)
|
||||
config[ATTR_SENSOR_ICON] = last_state.attributes[ATTR_ICON]
|
||||
|
||||
@property
|
||||
def device_info(self):
|
||||
"""Return device registry information for this entity."""
|
||||
return device_info(self._registration)
|
||||
|
||||
@property
|
||||
def available(self) -> bool:
|
||||
"""Return True if entity is available."""
|
||||
return self._config.get(ATTR_SENSOR_STATE) != STATE_UNAVAILABLE
|
||||
|
||||
@callback
|
||||
def _handle_update(self, data: dict[str, Any]) -> None:
|
||||
"""Handle async event updates."""
|
||||
self._config.update(data)
|
||||
self._async_update_attr_from_config()
|
||||
self.async_write_ha_state()
|
||||
|
|
|
@ -2,12 +2,12 @@
|
|||
from __future__ import annotations
|
||||
|
||||
from datetime import date, datetime
|
||||
from typing import Any
|
||||
from typing import TYPE_CHECKING, Any
|
||||
|
||||
from homeassistant.components.sensor import RestoreSensor, SensorDeviceClass
|
||||
from homeassistant.config_entries import ConfigEntry
|
||||
from homeassistant.const import CONF_WEBHOOK_ID, STATE_UNKNOWN, UnitOfTemperature
|
||||
from homeassistant.core import HomeAssistant, callback
|
||||
from homeassistant.core import HomeAssistant, State, callback
|
||||
from homeassistant.helpers import entity_registry as er
|
||||
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
||||
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
||||
|
@ -79,26 +79,28 @@ async def async_setup_entry(
|
|||
class MobileAppSensor(MobileAppEntity, RestoreSensor):
|
||||
"""Representation of an mobile app sensor."""
|
||||
|
||||
async def async_restore_last_state(self, last_state):
|
||||
async def async_restore_last_state(self, last_state: State) -> None:
|
||||
"""Restore previous state."""
|
||||
|
||||
await super().async_restore_last_state(last_state)
|
||||
|
||||
config = self._config
|
||||
if not (last_sensor_data := await self.async_get_last_sensor_data()):
|
||||
# Workaround to handle migration to RestoreSensor, can be removed
|
||||
# in HA Core 2023.4
|
||||
self._config[ATTR_SENSOR_STATE] = None
|
||||
config[ATTR_SENSOR_STATE] = None
|
||||
webhook_id = self._entry.data[CONF_WEBHOOK_ID]
|
||||
if TYPE_CHECKING:
|
||||
assert self.unique_id is not None
|
||||
sensor_unique_id = _extract_sensor_unique_id(webhook_id, self.unique_id)
|
||||
if (
|
||||
self.device_class == SensorDeviceClass.TEMPERATURE
|
||||
and sensor_unique_id == "battery_temperature"
|
||||
):
|
||||
self._config[ATTR_SENSOR_UOM] = UnitOfTemperature.CELSIUS
|
||||
return
|
||||
config[ATTR_SENSOR_UOM] = UnitOfTemperature.CELSIUS
|
||||
else:
|
||||
config[ATTR_SENSOR_STATE] = last_sensor_data.native_value
|
||||
config[ATTR_SENSOR_UOM] = last_sensor_data.native_unit_of_measurement
|
||||
|
||||
self._config[ATTR_SENSOR_STATE] = last_sensor_data.native_value
|
||||
self._config[ATTR_SENSOR_UOM] = last_sensor_data.native_unit_of_measurement
|
||||
self._async_update_attr_from_config()
|
||||
|
||||
@property
|
||||
def native_value(self) -> StateType | date | datetime:
|
||||
|
@ -106,29 +108,25 @@ class MobileAppSensor(MobileAppEntity, RestoreSensor):
|
|||
if (state := self._config[ATTR_SENSOR_STATE]) in (None, STATE_UNKNOWN):
|
||||
return None
|
||||
|
||||
device_class = self.device_class
|
||||
|
||||
if (
|
||||
self.device_class
|
||||
in (
|
||||
SensorDeviceClass.DATE,
|
||||
SensorDeviceClass.TIMESTAMP,
|
||||
)
|
||||
device_class in (SensorDeviceClass.DATE, SensorDeviceClass.TIMESTAMP)
|
||||
# Only parse strings: if the sensor's state is restored, the state is a
|
||||
# native date or datetime, not str
|
||||
and isinstance(state, str)
|
||||
and (timestamp := dt_util.parse_datetime(state)) is not None
|
||||
):
|
||||
if self.device_class == SensorDeviceClass.DATE:
|
||||
if device_class == SensorDeviceClass.DATE:
|
||||
return timestamp.date()
|
||||
return timestamp
|
||||
|
||||
return state
|
||||
|
||||
@property
|
||||
def native_unit_of_measurement(self) -> str | None:
|
||||
"""Return the unit of measurement this sensor expresses itself in."""
|
||||
return self._config.get(ATTR_SENSOR_UOM)
|
||||
|
||||
@property
|
||||
def state_class(self) -> str | None:
|
||||
"""Return state class."""
|
||||
return self._config.get(ATTR_SENSOR_STATE_CLASS)
|
||||
@callback
|
||||
def _async_update_attr_from_config(self) -> None:
|
||||
"""Update the entity from the config."""
|
||||
super()._async_update_attr_from_config()
|
||||
config = self._config
|
||||
self._attr_native_unit_of_measurement = config.get(ATTR_SENSOR_UOM)
|
||||
self._attr_state_class = config.get(ATTR_SENSOR_STATE_CLASS)
|
||||
|
|
Loading…
Reference in New Issue