Update aiolyric to 2.0.1 (#123424)

update aiolyric to 2.0.1
This commit is contained in:
Ryan Mattson
2024-08-18 13:05:30 -05:00
committed by GitHub
parent 7d326ff076
commit df58068e84
6 changed files with 69 additions and 66 deletions

View File

@ -12,7 +12,7 @@ from aiolyric import Lyric
from aiolyric.exceptions import LyricAuthenticationException, LyricException from aiolyric.exceptions import LyricAuthenticationException, LyricException
from aiolyric.objects.device import LyricDevice from aiolyric.objects.device import LyricDevice
from aiolyric.objects.location import LyricLocation from aiolyric.objects.location import LyricLocation
from aiolyric.objects.priority import LyricAccessories, LyricRoom from aiolyric.objects.priority import LyricAccessory, LyricRoom
from homeassistant.config_entries import ConfigEntry from homeassistant.config_entries import ConfigEntry
from homeassistant.const import Platform from homeassistant.const import Platform
@ -80,11 +80,13 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
await lyric.get_locations() await lyric.get_locations()
await asyncio.gather( await asyncio.gather(
*( *(
lyric.get_thermostat_rooms(location.locationID, device.deviceID) lyric.get_thermostat_rooms(
location.location_id, device.device_id
)
for location in lyric.locations for location in lyric.locations
for device in location.devices for device in location.devices
if device.deviceClass == "Thermostat" if device.device_class == "Thermostat"
and device.deviceID.startswith("LCC") and device.device_id.startswith("LCC")
) )
) )
@ -143,7 +145,7 @@ class LyricEntity(CoordinatorEntity[DataUpdateCoordinator[Lyric]]):
super().__init__(coordinator) super().__init__(coordinator)
self._key = key self._key = key
self._location = location self._location = location
self._mac_id = device.macID self._mac_id = device.mac_id
self._update_thermostat = coordinator.data.update_thermostat self._update_thermostat = coordinator.data.update_thermostat
self._update_fan = coordinator.data.update_fan self._update_fan = coordinator.data.update_fan
@ -155,7 +157,7 @@ class LyricEntity(CoordinatorEntity[DataUpdateCoordinator[Lyric]]):
@property @property
def location(self) -> LyricLocation: def location(self) -> LyricLocation:
"""Get the Lyric Location.""" """Get the Lyric Location."""
return self.coordinator.data.locations_dict[self._location.locationID] return self.coordinator.data.locations_dict[self._location.location_id]
@property @property
def device(self) -> LyricDevice: def device(self) -> LyricDevice:
@ -173,7 +175,7 @@ class LyricDeviceEntity(LyricEntity):
identifiers={(dr.CONNECTION_NETWORK_MAC, self._mac_id)}, identifiers={(dr.CONNECTION_NETWORK_MAC, self._mac_id)},
connections={(dr.CONNECTION_NETWORK_MAC, self._mac_id)}, connections={(dr.CONNECTION_NETWORK_MAC, self._mac_id)},
manufacturer="Honeywell", manufacturer="Honeywell",
model=self.device.deviceModel, model=self.device.device_model,
name=f"{self.device.name} Thermostat", name=f"{self.device.name} Thermostat",
) )
@ -187,7 +189,7 @@ class LyricAccessoryEntity(LyricDeviceEntity):
location: LyricLocation, location: LyricLocation,
device: LyricDevice, device: LyricDevice,
room: LyricRoom, room: LyricRoom,
accessory: LyricAccessories, accessory: LyricAccessory,
key: str, key: str,
) -> None: ) -> None:
"""Initialize the Honeywell Lyric accessory entity.""" """Initialize the Honeywell Lyric accessory entity."""
@ -207,7 +209,7 @@ class LyricAccessoryEntity(LyricDeviceEntity):
}, },
manufacturer="Honeywell", manufacturer="Honeywell",
model="RCHTSENSOR", model="RCHTSENSOR",
name=f"{self.room.roomName} Sensor", name=f"{self.room.room_name} Sensor",
via_device=(dr.CONNECTION_NETWORK_MAC, self._mac_id), via_device=(dr.CONNECTION_NETWORK_MAC, self._mac_id),
) )
@ -217,7 +219,7 @@ class LyricAccessoryEntity(LyricDeviceEntity):
return self.coordinator.data.rooms_dict[self._mac_id][self._room_id] return self.coordinator.data.rooms_dict[self._mac_id][self._room_id]
@property @property
def accessory(self) -> LyricAccessories: def accessory(self) -> LyricAccessory:
"""Get the Lyric Device.""" """Get the Lyric Device."""
return next( return next(
accessory accessory

View File

@ -132,7 +132,7 @@ async def async_setup_entry(
LyricClimate( LyricClimate(
coordinator, coordinator,
ClimateEntityDescription( ClimateEntityDescription(
key=f"{device.macID}_thermostat", key=f"{device.mac_id}_thermostat",
name=device.name, name=device.name,
), ),
location, location,
@ -185,7 +185,7 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
) -> None: ) -> None:
"""Initialize Honeywell Lyric climate entity.""" """Initialize Honeywell Lyric climate entity."""
# Define thermostat type (TCC - e.g., Lyric round; LCC - e.g., T5,6) # Define thermostat type (TCC - e.g., Lyric round; LCC - e.g., T5,6)
if device.changeableValues.thermostatSetpointStatus: if device.changeable_values.thermostat_setpoint_status:
self._attr_thermostat_type = LyricThermostatType.LCC self._attr_thermostat_type = LyricThermostatType.LCC
else: else:
self._attr_thermostat_type = LyricThermostatType.TCC self._attr_thermostat_type = LyricThermostatType.TCC
@ -202,15 +202,15 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
self._attr_hvac_modes = [HVACMode.OFF] self._attr_hvac_modes = [HVACMode.OFF]
# Add supported lyric thermostat features # Add supported lyric thermostat features
if LYRIC_HVAC_MODE_HEAT in device.allowedModes: if LYRIC_HVAC_MODE_HEAT in device.allowed_modes:
self._attr_hvac_modes.append(HVACMode.HEAT) self._attr_hvac_modes.append(HVACMode.HEAT)
if LYRIC_HVAC_MODE_COOL in device.allowedModes: if LYRIC_HVAC_MODE_COOL in device.allowed_modes:
self._attr_hvac_modes.append(HVACMode.COOL) self._attr_hvac_modes.append(HVACMode.COOL)
if ( if (
LYRIC_HVAC_MODE_HEAT in device.allowedModes LYRIC_HVAC_MODE_HEAT in device.allowed_modes
and LYRIC_HVAC_MODE_COOL in device.allowedModes and LYRIC_HVAC_MODE_COOL in device.allowed_modes
): ):
self._attr_hvac_modes.append(HVACMode.HEAT_COOL) self._attr_hvac_modes.append(HVACMode.HEAT_COOL)
@ -242,19 +242,19 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
coordinator, coordinator,
location, location,
device, device,
f"{device.macID}_thermostat", f"{device.mac_id}_thermostat",
) )
self.entity_description = description self.entity_description = description
@property @property
def current_temperature(self) -> float | None: def current_temperature(self) -> float | None:
"""Return the current temperature.""" """Return the current temperature."""
return self.device.indoorTemperature return self.device.indoor_temperature
@property @property
def hvac_action(self) -> HVACAction | None: def hvac_action(self) -> HVACAction | None:
"""Return the current hvac action.""" """Return the current hvac action."""
action = HVAC_ACTIONS.get(self.device.operationStatus.mode, None) action = HVAC_ACTIONS.get(self.device.operation_status.mode, None)
if action == HVACAction.OFF and self.hvac_mode != HVACMode.OFF: if action == HVACAction.OFF and self.hvac_mode != HVACMode.OFF:
action = HVACAction.IDLE action = HVACAction.IDLE
return action return action
@ -262,63 +262,63 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
@property @property
def hvac_mode(self) -> HVACMode: def hvac_mode(self) -> HVACMode:
"""Return the hvac mode.""" """Return the hvac mode."""
return HVAC_MODES[self.device.changeableValues.mode] return HVAC_MODES[self.device.changeable_values.mode]
@property @property
def target_temperature(self) -> float | None: def target_temperature(self) -> float | None:
"""Return the temperature we try to reach.""" """Return the temperature we try to reach."""
device = self.device device = self.device
if ( if (
device.changeableValues.autoChangeoverActive device.changeable_values.auto_changeover_active
or HVAC_MODES[device.changeableValues.mode] == HVACMode.OFF or HVAC_MODES[device.changeable_values.mode] == HVACMode.OFF
): ):
return None return None
if self.hvac_mode == HVACMode.COOL: if self.hvac_mode == HVACMode.COOL:
return device.changeableValues.coolSetpoint return device.changeable_values.cool_setpoint
return device.changeableValues.heatSetpoint return device.changeable_values.heat_setpoint
@property @property
def target_temperature_high(self) -> float | None: def target_temperature_high(self) -> float | None:
"""Return the highbound target temperature we try to reach.""" """Return the highbound target temperature we try to reach."""
device = self.device device = self.device
if ( if (
not device.changeableValues.autoChangeoverActive not device.changeable_values.auto_changeover_active
or HVAC_MODES[device.changeableValues.mode] == HVACMode.OFF or HVAC_MODES[device.changeable_values.mode] == HVACMode.OFF
): ):
return None return None
return device.changeableValues.coolSetpoint return device.changeable_values.cool_setpoint
@property @property
def target_temperature_low(self) -> float | None: def target_temperature_low(self) -> float | None:
"""Return the lowbound target temperature we try to reach.""" """Return the lowbound target temperature we try to reach."""
device = self.device device = self.device
if ( if (
not device.changeableValues.autoChangeoverActive not device.changeable_values.auto_changeover_active
or HVAC_MODES[device.changeableValues.mode] == HVACMode.OFF or HVAC_MODES[device.changeable_values.mode] == HVACMode.OFF
): ):
return None return None
return device.changeableValues.heatSetpoint return device.changeable_values.heat_setpoint
@property @property
def preset_mode(self) -> str | None: def preset_mode(self) -> str | None:
"""Return current preset mode.""" """Return current preset mode."""
return self.device.changeableValues.thermostatSetpointStatus return self.device.changeable_values.thermostat_setpoint_status
@property @property
def min_temp(self) -> float: def min_temp(self) -> float:
"""Identify min_temp in Lyric API or defaults if not available.""" """Identify min_temp in Lyric API or defaults if not available."""
device = self.device device = self.device
if LYRIC_HVAC_MODE_COOL in device.allowedModes: if LYRIC_HVAC_MODE_COOL in device.allowed_modes:
return device.minCoolSetpoint return device.min_cool_setpoint
return device.minHeatSetpoint return device.min_heat_setpoint
@property @property
def max_temp(self) -> float: def max_temp(self) -> float:
"""Identify max_temp in Lyric API or defaults if not available.""" """Identify max_temp in Lyric API or defaults if not available."""
device = self.device device = self.device
if LYRIC_HVAC_MODE_HEAT in device.allowedModes: if LYRIC_HVAC_MODE_HEAT in device.allowed_modes:
return device.maxHeatSetpoint return device.max_heat_setpoint
return device.maxCoolSetpoint return device.max_cool_setpoint
@property @property
def fan_mode(self) -> str | None: def fan_mode(self) -> str | None:
@ -339,7 +339,7 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW) target_temp_low = kwargs.get(ATTR_TARGET_TEMP_LOW)
target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH) target_temp_high = kwargs.get(ATTR_TARGET_TEMP_HIGH)
if device.changeableValues.mode == LYRIC_HVAC_MODE_HEAT_COOL: if device.changeable_values.mode == LYRIC_HVAC_MODE_HEAT_COOL:
if target_temp_low is None or target_temp_high is None: if target_temp_low is None or target_temp_high is None:
raise HomeAssistantError( raise HomeAssistantError(
"Could not find target_temp_low and/or target_temp_high in" "Could not find target_temp_low and/or target_temp_high in"
@ -349,7 +349,7 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
# If TCC device pass the heatCoolMode value, otherwise # If TCC device pass the heatCoolMode value, otherwise
# if LCC device can skip the mode altogether # if LCC device can skip the mode altogether
if self._attr_thermostat_type is LyricThermostatType.TCC: if self._attr_thermostat_type is LyricThermostatType.TCC:
mode = HVAC_MODES[device.changeableValues.heatCoolMode] mode = HVAC_MODES[device.changeable_values.heat_cool_mode]
else: else:
mode = None mode = None
@ -401,7 +401,7 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
# otherwise it turns to Auto briefly and then reverts to Off. # otherwise it turns to Auto briefly and then reverts to Off.
# This is the behavior that happens with the native app as well, # This is the behavior that happens with the native app as well,
# so likely a bug in the api itself. # so likely a bug in the api itself.
if HVAC_MODES[self.device.changeableValues.mode] == HVACMode.OFF: if HVAC_MODES[self.device.changeable_values.mode] == HVACMode.OFF:
_LOGGER.debug( _LOGGER.debug(
"HVAC mode passed to lyric: %s", "HVAC mode passed to lyric: %s",
HVAC_MODES[LYRIC_HVAC_MODE_COOL], HVAC_MODES[LYRIC_HVAC_MODE_COOL],
@ -427,7 +427,7 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
else: else:
_LOGGER.debug( _LOGGER.debug(
"HVAC mode passed to lyric: %s", "HVAC mode passed to lyric: %s",
HVAC_MODES[self.device.changeableValues.mode], HVAC_MODES[self.device.changeable_values.mode],
) )
await self._update_thermostat( await self._update_thermostat(
self.location, self.device, autoChangeoverActive=True self.location, self.device, autoChangeoverActive=True
@ -448,7 +448,7 @@ class LyricClimate(LyricDeviceEntity, ClimateEntity):
# otherwise leave unchanged. # otherwise leave unchanged.
if ( if (
LYRIC_HVAC_MODES[hvac_mode] == LYRIC_HVAC_MODE_HEAT_COOL LYRIC_HVAC_MODES[hvac_mode] == LYRIC_HVAC_MODE_HEAT_COOL
and not self.device.changeableValues.autoChangeoverActive and not self.device.changeable_values.auto_changeover_active
): ):
auto_changeover = True auto_changeover = True
else: else:

View File

@ -22,5 +22,5 @@
"iot_class": "cloud_polling", "iot_class": "cloud_polling",
"loggers": ["aiolyric"], "loggers": ["aiolyric"],
"quality_scale": "silver", "quality_scale": "silver",
"requirements": ["aiolyric==1.1.0"] "requirements": ["aiolyric==2.0.1"]
} }

View File

@ -9,7 +9,7 @@ from datetime import datetime, timedelta
from aiolyric import Lyric from aiolyric import Lyric
from aiolyric.objects.device import LyricDevice from aiolyric.objects.device import LyricDevice
from aiolyric.objects.location import LyricLocation from aiolyric.objects.location import LyricLocation
from aiolyric.objects.priority import LyricAccessories, LyricRoom from aiolyric.objects.priority import LyricAccessory, LyricRoom
from homeassistant.components.sensor import ( from homeassistant.components.sensor import (
SensorDeviceClass, SensorDeviceClass,
@ -55,8 +55,8 @@ class LyricSensorEntityDescription(SensorEntityDescription):
class LyricSensorAccessoryEntityDescription(SensorEntityDescription): class LyricSensorAccessoryEntityDescription(SensorEntityDescription):
"""Class describing Honeywell Lyric room sensor entities.""" """Class describing Honeywell Lyric room sensor entities."""
value_fn: Callable[[LyricRoom, LyricAccessories], StateType | datetime] value_fn: Callable[[LyricRoom, LyricAccessory], StateType | datetime]
suitable_fn: Callable[[LyricRoom, LyricAccessories], bool] suitable_fn: Callable[[LyricRoom, LyricAccessory], bool]
DEVICE_SENSORS: list[LyricSensorEntityDescription] = [ DEVICE_SENSORS: list[LyricSensorEntityDescription] = [
@ -65,8 +65,8 @@ DEVICE_SENSORS: list[LyricSensorEntityDescription] = [
translation_key="indoor_temperature", translation_key="indoor_temperature",
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda device: device.indoorTemperature, value_fn=lambda device: device.indoor_temperature,
suitable_fn=lambda device: device.indoorTemperature, suitable_fn=lambda device: device.indoor_temperature,
), ),
LyricSensorEntityDescription( LyricSensorEntityDescription(
key="indoor_humidity", key="indoor_humidity",
@ -74,16 +74,16 @@ DEVICE_SENSORS: list[LyricSensorEntityDescription] = [
device_class=SensorDeviceClass.HUMIDITY, device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
value_fn=lambda device: device.indoorHumidity, value_fn=lambda device: device.indoor_humidity,
suitable_fn=lambda device: device.indoorHumidity, suitable_fn=lambda device: device.indoor_humidity,
), ),
LyricSensorEntityDescription( LyricSensorEntityDescription(
key="outdoor_temperature", key="outdoor_temperature",
translation_key="outdoor_temperature", translation_key="outdoor_temperature",
device_class=SensorDeviceClass.TEMPERATURE, device_class=SensorDeviceClass.TEMPERATURE,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
value_fn=lambda device: device.outdoorTemperature, value_fn=lambda device: device.outdoor_temperature,
suitable_fn=lambda device: device.outdoorTemperature, suitable_fn=lambda device: device.outdoor_temperature,
), ),
LyricSensorEntityDescription( LyricSensorEntityDescription(
key="outdoor_humidity", key="outdoor_humidity",
@ -91,29 +91,30 @@ DEVICE_SENSORS: list[LyricSensorEntityDescription] = [
device_class=SensorDeviceClass.HUMIDITY, device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
value_fn=lambda device: device.displayedOutdoorHumidity, value_fn=lambda device: device.displayed_outdoor_humidity,
suitable_fn=lambda device: device.displayedOutdoorHumidity, suitable_fn=lambda device: device.displayed_outdoor_humidity,
), ),
LyricSensorEntityDescription( LyricSensorEntityDescription(
key="next_period_time", key="next_period_time",
translation_key="next_period_time", translation_key="next_period_time",
device_class=SensorDeviceClass.TIMESTAMP, device_class=SensorDeviceClass.TIMESTAMP,
value_fn=lambda device: get_datetime_from_future_time( value_fn=lambda device: get_datetime_from_future_time(
device.changeableValues.nextPeriodTime device.changeable_values.next_period_time
), ),
suitable_fn=lambda device: ( suitable_fn=lambda device: (
device.changeableValues and device.changeableValues.nextPeriodTime device.changeable_values and device.changeable_values.next_period_time
), ),
), ),
LyricSensorEntityDescription( LyricSensorEntityDescription(
key="setpoint_status", key="setpoint_status",
translation_key="setpoint_status", translation_key="setpoint_status",
value_fn=lambda device: get_setpoint_status( value_fn=lambda device: get_setpoint_status(
device.changeableValues.thermostatSetpointStatus, device.changeable_values.thermostat_setpoint_status,
device.changeableValues.nextPeriodTime, device.changeable_values.next_period_time,
), ),
suitable_fn=lambda device: ( suitable_fn=lambda device: (
device.changeableValues and device.changeableValues.thermostatSetpointStatus device.changeable_values
and device.changeable_values.thermostat_setpoint_status
), ),
), ),
] ]
@ -133,7 +134,7 @@ ACCESSORY_SENSORS: list[LyricSensorAccessoryEntityDescription] = [
device_class=SensorDeviceClass.HUMIDITY, device_class=SensorDeviceClass.HUMIDITY,
state_class=SensorStateClass.MEASUREMENT, state_class=SensorStateClass.MEASUREMENT,
native_unit_of_measurement=PERCENTAGE, native_unit_of_measurement=PERCENTAGE,
value_fn=lambda room, _: room.roomAvgHumidity, value_fn=lambda room, _: room.room_avg_humidity,
suitable_fn=lambda _, accessory: accessory.type == "IndoorAirSensor", suitable_fn=lambda _, accessory: accessory.type == "IndoorAirSensor",
), ),
] ]
@ -182,7 +183,7 @@ async def async_setup_entry(
) )
for location in coordinator.data.locations for location in coordinator.data.locations
for device in location.devices for device in location.devices
for room in coordinator.data.rooms_dict.get(device.macID, {}).values() for room in coordinator.data.rooms_dict.get(device.mac_id, {}).values()
for accessory in room.accessories for accessory in room.accessories
for accessory_sensor in ACCESSORY_SENSORS for accessory_sensor in ACCESSORY_SENSORS
if accessory_sensor.suitable_fn(room, accessory) if accessory_sensor.suitable_fn(room, accessory)
@ -206,7 +207,7 @@ class LyricSensor(LyricDeviceEntity, SensorEntity):
coordinator, coordinator,
location, location,
device, device,
f"{device.macID}_{description.key}", f"{device.mac_id}_{description.key}",
) )
self.entity_description = description self.entity_description = description
if description.device_class == SensorDeviceClass.TEMPERATURE: if description.device_class == SensorDeviceClass.TEMPERATURE:
@ -233,7 +234,7 @@ class LyricAccessorySensor(LyricAccessoryEntity, SensorEntity):
location: LyricLocation, location: LyricLocation,
parentDevice: LyricDevice, parentDevice: LyricDevice,
room: LyricRoom, room: LyricRoom,
accessory: LyricAccessories, accessory: LyricAccessory,
) -> None: ) -> None:
"""Initialize.""" """Initialize."""
super().__init__( super().__init__(
@ -242,7 +243,7 @@ class LyricAccessorySensor(LyricAccessoryEntity, SensorEntity):
parentDevice, parentDevice,
room, room,
accessory, accessory,
f"{parentDevice.macID}_room{room.id}_acc{accessory.id}_{description.key}", f"{parentDevice.mac_id}_room{room.id}_acc{accessory.id}_{description.key}",
) )
self.entity_description = description self.entity_description = description
if description.device_class == SensorDeviceClass.TEMPERATURE: if description.device_class == SensorDeviceClass.TEMPERATURE:

View File

@ -285,7 +285,7 @@ aiolivisi==0.0.19
aiolookin==1.0.0 aiolookin==1.0.0
# homeassistant.components.lyric # homeassistant.components.lyric
aiolyric==1.1.0 aiolyric==2.0.1
# homeassistant.components.mealie # homeassistant.components.mealie
aiomealie==0.8.1 aiomealie==0.8.1

View File

@ -267,7 +267,7 @@ aiolivisi==0.0.19
aiolookin==1.0.0 aiolookin==1.0.0
# homeassistant.components.lyric # homeassistant.components.lyric
aiolyric==1.1.0 aiolyric==2.0.1
# homeassistant.components.mealie # homeassistant.components.mealie
aiomealie==0.8.1 aiomealie==0.8.1