Files
core/homeassistant/components/cielo_home/entity.py
T

109 lines
3.4 KiB
Python

"""Base entity for Cielo integration."""
from typing import override
from cieloconnectapi.device import CieloDeviceAPI
from cieloconnectapi.model import CieloDevice
from homeassistant.const import UnitOfTemperature
from homeassistant.helpers.device_registry import CONNECTION_NETWORK_MAC, DeviceInfo
from homeassistant.helpers.update_coordinator import CoordinatorEntity
from .const import DOMAIN
from .coordinator import CieloDataUpdateCoordinator
def normalize_temp_unit(client: CieloDeviceAPI) -> str:
"""Normalize a raw device temperature unit to a UnitOfTemperature value.
Unrecognized or empty values fall back to Celsius.
"""
unit = client.temperature_unit()
if not unit:
return UnitOfTemperature.CELSIUS
normalized = unit.strip().lower()
if normalized in {"c", "°c", "celsius"}:
return UnitOfTemperature.CELSIUS
if normalized in {"f", "°f", "fahrenheit"}:
return UnitOfTemperature.FAHRENHEIT
return UnitOfTemperature.CELSIUS
class CieloBaseEntity(CoordinatorEntity[CieloDataUpdateCoordinator]):
"""Representation of a Cielo base entity."""
_attr_has_entity_name = True
def __init__(
self,
coordinator: CieloDataUpdateCoordinator,
device_id: str,
) -> None:
"""Initialize the Cielo base entity."""
super().__init__(coordinator)
self._device_id = device_id
self.client = CieloDeviceAPI(
coordinator.client, coordinator.data.parsed[device_id]
)
@override
def _handle_coordinator_update(self) -> None:
"""Handle updated data from the coordinator."""
if (dev := self.device_data) is not None:
self.client.device_data = dev
super()._handle_coordinator_update()
@property
def device_data(self) -> CieloDevice | None:
"""Return the device data from the coordinator."""
return self.coordinator.data.parsed.get(self._device_id)
@property
@override
def available(self) -> bool:
"""Return if the device is available and online."""
if not (super().available and self._device_id in self.coordinator.data.parsed):
return False
dev = self.device_data
return bool(dev and dev.device_status)
class CieloDeviceEntity(CieloBaseEntity):
"""Representation of a Cielo Device."""
def __init__(
self,
coordinator: CieloDataUpdateCoordinator,
device_id: str,
) -> None:
"""Initialize the device entity."""
super().__init__(coordinator, device_id)
self.device_id = device_id
device = coordinator.data.parsed[device_id]
self._attr_device_info = DeviceInfo(
identifiers={(DOMAIN, device.id)},
name=device.name,
connections={(CONNECTION_NETWORK_MAC, device.mac_address)},
manufacturer="Cielo",
configuration_url="https://home.cielowigle.com/",
suggested_area=device.name,
)
@property
def temperature_unit(self) -> str:
"""Return the unit of temperature for the device.
The unit can change over time based on the device settings,
so it is fetched dynamically from the client. This dynamic
nature means that if a user changes the device's temperature
unit, historical statistics may be affected.
"""
return normalize_temp_unit(self.client)