Clean up lyric sensor platform (#100495)

* Clean up lyric sensor platform

* Clean up lyric sensor platform

* Clean up lyric sensor platform

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

* Update homeassistant/components/lyric/sensor.py

Co-authored-by: Aidan Timson <aidan@timmo.dev>

---------

Co-authored-by: Aidan Timson <aidan@timmo.dev>
This commit is contained in:
Joost Lekkerkerker 2023-09-18 12:42:31 +02:00 committed by GitHub
parent 6ac1305c64
commit ec6c374761
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -4,7 +4,6 @@ from __future__ import annotations
from collections.abc import Callable from collections.abc import Callable
from dataclasses import dataclass from dataclasses import dataclass
from datetime import datetime, timedelta from datetime import datetime, timedelta
from typing import cast
from aiolyric import Lyric from aiolyric import Lyric
from aiolyric.objects.device import LyricDevice from aiolyric.objects.device import LyricDevice
@ -43,10 +42,84 @@ LYRIC_SETPOINT_STATUS_NAMES = {
@dataclass @dataclass
class LyricSensorEntityDescription(SensorEntityDescription): class LyricSensorEntityDescriptionMixin:
"""Mixin for required keys."""
value_fn: Callable[[LyricDevice], StateType | datetime]
suitable_fn: Callable[[LyricDevice], bool]
@dataclass
class LyricSensorEntityDescription(
SensorEntityDescription, LyricSensorEntityDescriptionMixin
):
"""Class describing Honeywell Lyric sensor entities.""" """Class describing Honeywell Lyric sensor entities."""
value: Callable[[LyricDevice], StateType | datetime] = round
DEVICE_SENSORS: list[LyricSensorEntityDescription] = [
LyricSensorEntityDescription(
key="indoor_temperature",
translation_key="indoor_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda device: device.indoorTemperature,
suitable_fn=lambda device: device.indoorTemperature,
),
LyricSensorEntityDescription(
key="indoor_humidity",
translation_key="indoor_humidity",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda device: device.indoorHumidity,
suitable_fn=lambda device: device.indoorHumidity,
),
LyricSensorEntityDescription(
key="outdoor_temperature",
translation_key="outdoor_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda device: device.outdoorTemperature,
suitable_fn=lambda device: device.outdoorTemperature,
),
LyricSensorEntityDescription(
key="outdoor_humidity",
translation_key="outdoor_humidity",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
value_fn=lambda device: device.displayedOutdoorHumidity,
suitable_fn=lambda device: device.displayedOutdoorHumidity,
),
LyricSensorEntityDescription(
key="next_period_time",
translation_key="next_period_time",
device_class=SensorDeviceClass.TIMESTAMP,
value_fn=lambda device: get_datetime_from_future_time(
device.changeableValues.nextPeriodTime
),
suitable_fn=lambda device: device.changeableValues
and device.changeableValues.nextPeriodTime,
),
LyricSensorEntityDescription(
key="setpoint_status",
translation_key="setpoint_status",
icon="mdi:thermostat",
value_fn=lambda device: get_setpoint_status(
device.changeableValues.thermostatSetpointStatus,
device.changeableValues.nextPeriodTime,
),
suitable_fn=lambda device: device.changeableValues
and device.changeableValues.thermostatSetpointStatus,
),
]
def get_setpoint_status(status: str, time: str) -> str | None:
"""Get status of the setpoint."""
if status == PRESET_HOLD_UNTIL:
return f"Held until {time}"
return LYRIC_SETPOINT_STATUS_NAMES.get(status, None)
def get_datetime_from_future_time(time_str: str) -> datetime: def get_datetime_from_future_time(time_str: str) -> datetime:
@ -68,129 +141,25 @@ async def async_setup_entry(
entities = [] entities = []
def get_setpoint_status(status: str, time: str) -> str | None:
if status == PRESET_HOLD_UNTIL:
return f"Held until {time}"
return LYRIC_SETPOINT_STATUS_NAMES.get(status, None)
for location in coordinator.data.locations: for location in coordinator.data.locations:
for device in location.devices: for device in location.devices:
if device.indoorTemperature: for device_sensor in DEVICE_SENSORS:
if device.units == "Fahrenheit": if device_sensor.suitable_fn(device):
native_temperature_unit = UnitOfTemperature.FAHRENHEIT
else:
native_temperature_unit = UnitOfTemperature.CELSIUS
entities.append(
LyricSensor(
coordinator,
LyricSensorEntityDescription(
key=f"{device.macID}_indoor_temperature",
translation_key="indoor_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=native_temperature_unit,
value=lambda device: device.indoorTemperature,
),
location,
device,
)
)
if device.indoorHumidity:
entities.append(
LyricSensor(
coordinator,
LyricSensorEntityDescription(
key=f"{device.macID}_indoor_humidity",
translation_key="indoor_humidity",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
value=lambda device: device.indoorHumidity,
),
location,
device,
)
)
if device.outdoorTemperature:
if device.units == "Fahrenheit":
native_temperature_unit = UnitOfTemperature.FAHRENHEIT
else:
native_temperature_unit = UnitOfTemperature.CELSIUS
entities.append(
LyricSensor(
coordinator,
LyricSensorEntityDescription(
key=f"{device.macID}_outdoor_temperature",
translation_key="outdoor_temperature",
device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=native_temperature_unit,
value=lambda device: device.outdoorTemperature,
),
location,
device,
)
)
if device.displayedOutdoorHumidity:
entities.append(
LyricSensor(
coordinator,
LyricSensorEntityDescription(
key=f"{device.macID}_outdoor_humidity",
translation_key="outdoor_humidity",
device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE,
value=lambda device: device.displayedOutdoorHumidity,
),
location,
device,
)
)
if device.changeableValues:
if device.changeableValues.nextPeriodTime:
entities.append( entities.append(
LyricSensor( LyricSensor(
coordinator, coordinator,
LyricSensorEntityDescription( device_sensor,
key=f"{device.macID}_next_period_time",
translation_key="next_period_time",
device_class=SensorDeviceClass.TIMESTAMP,
value=lambda device: get_datetime_from_future_time(
device.changeableValues.nextPeriodTime
),
),
location,
device,
)
)
if device.changeableValues.thermostatSetpointStatus:
entities.append(
LyricSensor(
coordinator,
LyricSensorEntityDescription(
key=f"{device.macID}_setpoint_status",
translation_key="setpoint_status",
icon="mdi:thermostat",
value=lambda device: get_setpoint_status(
device.changeableValues.thermostatSetpointStatus,
device.changeableValues.nextPeriodTime,
),
),
location, location,
device, device,
) )
) )
async_add_entities(entities, True) async_add_entities(entities)
class LyricSensor(LyricDeviceEntity, SensorEntity): class LyricSensor(LyricDeviceEntity, SensorEntity):
"""Define a Honeywell Lyric sensor.""" """Define a Honeywell Lyric sensor."""
coordinator: DataUpdateCoordinator[Lyric]
entity_description: LyricSensorEntityDescription entity_description: LyricSensorEntityDescription
def __init__( def __init__(
@ -205,15 +174,16 @@ class LyricSensor(LyricDeviceEntity, SensorEntity):
coordinator, coordinator,
location, location,
device, device,
description.key, f"{device.macID}_{description.key}",
) )
self.entity_description = description self.entity_description = description
if description.device_class == SensorDeviceClass.TEMPERATURE:
if device.units == "Fahrenheit":
self._attr_native_unit_of_measurement = UnitOfTemperature.FAHRENHEIT
else:
self._attr_native_unit_of_measurement = UnitOfTemperature.CELSIUS
@property @property
def native_value(self) -> StateType: def native_value(self) -> StateType | datetime:
"""Return the state.""" """Return the state."""
device: LyricDevice = self.device return self.entity_description.value_fn(self.device)
try:
return cast(StateType, self.entity_description.value(device))
except TypeError:
return None