mirror of
https://github.com/home-assistant/core.git
synced 2026-09-10 15:41:22 +01:00
132 lines
4.1 KiB
Python
132 lines
4.1 KiB
Python
"""Base Entity for all TelldusLive entities."""
|
|
|
|
from datetime import datetime
|
|
import logging
|
|
from typing import TYPE_CHECKING, Any, override
|
|
|
|
from tellduslive import BATTERY_LOW, BATTERY_OK, BATTERY_UNKNOWN
|
|
|
|
from homeassistant.const import ATTR_BATTERY_LEVEL, ATTR_MANUFACTURER, ATTR_MODEL
|
|
from homeassistant.helpers import device_registry as dr
|
|
from homeassistant.helpers.device_registry import DeviceInfo
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
from homeassistant.helpers.entity import Entity
|
|
|
|
from .const import DOMAIN, SIGNAL_UPDATE_ENTITY
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
ATTR_LAST_UPDATED = "time_last_updated"
|
|
|
|
|
|
class TelldusLiveEntity(Entity):
|
|
"""Base class for all Telldus Live entities."""
|
|
|
|
_attr_should_poll = False
|
|
_attr_has_entity_name = True
|
|
|
|
def __init__(self, client, device_id):
|
|
"""Initialize the entity."""
|
|
self._id = device_id
|
|
self._client = client
|
|
|
|
@override
|
|
async def async_added_to_hass(self) -> None:
|
|
"""Call when entity is added to hass."""
|
|
_LOGGER.debug("Created device %s", self)
|
|
self.async_on_remove(
|
|
async_dispatcher_connect(
|
|
self.hass, SIGNAL_UPDATE_ENTITY, self.async_write_ha_state
|
|
)
|
|
)
|
|
|
|
@property
|
|
def device_id(self):
|
|
"""Return the id of the device."""
|
|
return self._id
|
|
|
|
@property
|
|
def device(self):
|
|
"""Return the representation of the device."""
|
|
return self._client.device(self.device_id)
|
|
|
|
@property
|
|
def _state(self):
|
|
"""Return the state of the device."""
|
|
return self.device.state
|
|
|
|
@property
|
|
@override
|
|
def assumed_state(self) -> bool:
|
|
"""Return true if unable to access real state of entity."""
|
|
return True
|
|
|
|
@property
|
|
@override
|
|
def available(self) -> bool:
|
|
"""Return true if device is not offline."""
|
|
return self._client.is_available(self.device_id)
|
|
|
|
@property
|
|
@override
|
|
def extra_state_attributes(self) -> dict[str, Any]:
|
|
"""Return the state attributes."""
|
|
attrs = {}
|
|
if self._battery_level:
|
|
attrs[ATTR_BATTERY_LEVEL] = self._battery_level
|
|
if self._last_updated:
|
|
attrs[ATTR_LAST_UPDATED] = self._last_updated
|
|
return attrs
|
|
|
|
@property
|
|
def _battery_level(self):
|
|
"""Return the battery level of a device."""
|
|
if self.device.battery == BATTERY_LOW:
|
|
return 1
|
|
if self.device.battery == BATTERY_UNKNOWN:
|
|
return None
|
|
if self.device.battery == BATTERY_OK:
|
|
return 100
|
|
return self.device.battery # Percentage
|
|
|
|
@property
|
|
def _last_updated(self):
|
|
"""Return the last update of a device."""
|
|
return (
|
|
str(datetime.fromtimestamp(self.device.lastUpdated))
|
|
if self.device.lastUpdated
|
|
else None
|
|
)
|
|
|
|
@property
|
|
@override
|
|
def unique_id(self) -> str:
|
|
"""Return a unique ID."""
|
|
return self._id
|
|
|
|
@property
|
|
@override
|
|
def device_info(self) -> DeviceInfo:
|
|
"""Return device info."""
|
|
device = self._client.device_info(self.device.device_id)
|
|
device_info = DeviceInfo(
|
|
identifiers={(DOMAIN, self.device.device_id)},
|
|
name=self.device.name,
|
|
)
|
|
if (model := device.get("model")) is not None:
|
|
device_info[ATTR_MODEL] = model.title()
|
|
if (protocol := device.get("protocol")) is not None:
|
|
device_info[ATTR_MANUFACTURER] = protocol.title()
|
|
if (client := device.get("client")) is not None:
|
|
config_entry = self.platform.config_entry
|
|
if TYPE_CHECKING:
|
|
assert config_entry
|
|
# The hub is not registered when fetching the client list failed while
|
|
# device requests succeeded, so link only when the hub device exists.
|
|
hub_device = dr.async_get(self.hass).async_get_device_by_identifier(
|
|
(DOMAIN, client), config_entry.entry_id
|
|
)
|
|
if hub_device is not None:
|
|
device_info["via_device_id"] = hub_device.id
|
|
return device_info
|