"""Lyric.""" import logging from aiohttp import ClientResponse from .client import LyricClient from .const import BASE_URL from .objects.device import LyricDevice from .objects.location import LyricLocation from .objects.priority import LyricPriority, LyricRoom class Lyric: """Handles authentication refresh tokens.""" logger = logging.getLogger(__name__) def __init__( self, client: LyricClient, client_id: str, ) -> None: """Initialize the token manager class.""" self._client = client self._client_id = client_id self._devices: list[LyricDevice] = [] self._devices_dict: dict = {} self._locations: list[LyricLocation] = [] self._locations_dict: dict = {} self._priorities_dict: dict[str, LyricPriority] = {} self._rooms_dict: dict = {} @property def client_id(self) -> str: """Return the client id.""" return self._client_id @property def devices(self) -> list[LyricDevice]: """Return the devices.""" return self._devices @property def devices_dict(self) -> dict: """Return the devices dict.""" return self._devices_dict @property def locations(self) -> list[LyricLocation]: """Return the locations.""" return self._locations @property def locations_dict(self) -> dict: """Return the locations dict.""" return self._locations_dict @property def priorities_dict(self) -> dict[str, LyricPriority]: """Return the priorities dict, keyed by device MAC address.""" return self._priorities_dict @property def rooms_dict(self) -> dict[str, dict[str, LyricRoom]]: """Return the rooms dict.""" return self._rooms_dict async def get_devices( self, location_id: int, ) -> None: """Get Devices.""" response: ClientResponse = await self._client.get( f"{BASE_URL}/devices?apikey={self.client_id}&locationId={location_id}" ) json = await response.json() self.logger.debug(json) self._devices = [LyricDevice(self._client, device) for device in json or []] self._devices_dict: dict = {} for device in self._devices: self._devices_dict[device.mac_id] = device async def get_locations(self) -> None: """Get Locations.""" response: ClientResponse = await self._client.get( f"{BASE_URL}/locations?apikey={self.client_id}" ) json = await response.json() self.logger.debug(json) self._locations = [ LyricLocation(self._client, location) for location in json or [] ] self._locations_dict: dict = {} for location in self._locations: self._locations_dict[location.location_id] = location async def get_thermostat_rooms( self, location_id: int, device_id: str, ) -> None: """Get Priority, which contains accessory information.""" response: ClientResponse = await self._client.get( f"{BASE_URL}/devices/thermostats/{device_id}/priority?apikey={self.client_id}&locationId={location_id}" ) json = await response.json() self.logger.debug(json) priority = LyricPriority(json) # device id in the priority payload refers to the mac address of the device mac_id = priority.device_id self._priorities_dict[mac_id] = priority self._rooms_dict[mac_id] = {} # add each room to the room dictionary. Rooms contain motion, temp, and humidity averages for all accessories in a room for room in priority.current_priority.rooms: self._rooms_dict[mac_id][room.id] = room async def update_thermostat( self, location: LyricLocation, device: LyricDevice, mode: str | None = None, heat_setpoint: int | float | None = None, cool_setpoint: int | float | None = None, auto_changeover_active: bool | None = None, thermostat_setpoint_status: str | None = None, next_period_time: str | None = None, ) -> ClientResponse: """Update Theremostat.""" self.logger.debug("Update Thermostat") data = {} if mode is not None: data["mode"] = mode else: data["mode"] = device.changeable_values.mode if heat_setpoint is not None: data["heatSetpoint"] = heat_setpoint else: data["heatSetpoint"] = device.changeable_values.heat_setpoint if cool_setpoint is not None: data["coolSetpoint"] = cool_setpoint else: data["coolSetpoint"] = device.changeable_values.cool_setpoint # Only for TCC devices if auto_changeover_active is not None: data["autoChangeoverActive"] = auto_changeover_active elif device.changeable_values.auto_changeover_active is not None: data["autoChangeoverActive"] = ( device.changeable_values.auto_changeover_active ) # Only for LCC devices if thermostat_setpoint_status is not None: data["thermostatSetpointStatus"] = thermostat_setpoint_status elif device.changeable_values.thermostat_setpoint_status is not None: if device.changeable_values.thermostat_setpoint_status == "NoHold": data["thermostatSetpointStatus"] = "TemporaryHold" else: data["thermostatSetpointStatus"] = ( device.changeable_values.thermostat_setpoint_status ) if data.get("thermostatSetpointStatus", "") == "HoldUntil": if next_period_time is not None: data["nextPeriodTime"] = next_period_time elif device.changeable_values.next_period_time == "NoHold" and mode is None: data["nextPeriodTime"] = "TemporaryHold" else: data["nextPeriodTime"] = device.changeable_values.next_period_time self.logger.debug(data) return await self._client.post( f"{BASE_URL}/devices/thermostats/{device.device_id}?apikey={self._client_id}&locationId={location.location_id}", json=data, ) async def update_fan( self, location: LyricLocation, device: LyricDevice, mode: str, ) -> ClientResponse: """Update Fan.""" self.logger.debug("Update Fan") data = {"mode": mode} self.logger.debug(data) return await self._client.post( f"{BASE_URL}/devices/thermostats/{device.device_id}/fan?apikey={self._client_id}&locationId={location.location_id}", json=data, ) async def update_priority( self, location: LyricLocation, device: LyricDevice, priority_type: str, rooms: list[int], ) -> ClientResponse: """Update Priority.""" self.logger.debug("Update Priority") priority = { "priorityType": priority_type, "selectedRooms": rooms, } data = {"currentPriority": priority} self.logger.debug(data) return await self._client.post( f"{BASE_URL}/devices/thermostats/{device.device_id}/priority?apikey={self._client_id}&locationId={location.location_id}", json=data, )