2021-07-12 22:27:48 +00:00
|
|
|
"""Support for the Netatmo climate schedule selector."""
|
|
|
|
from __future__ import annotations
|
|
|
|
|
|
|
|
import logging
|
|
|
|
from typing import cast
|
|
|
|
|
|
|
|
import pyatmo
|
|
|
|
|
|
|
|
from homeassistant.components.select import SelectEntity
|
|
|
|
from homeassistant.config_entries import ConfigEntry
|
|
|
|
from homeassistant.core import HomeAssistant, callback
|
|
|
|
from homeassistant.exceptions import PlatformNotReady
|
|
|
|
from homeassistant.helpers.dispatcher import async_dispatcher_connect
|
|
|
|
from homeassistant.helpers.entity_platform import AddEntitiesCallback
|
|
|
|
|
|
|
|
from .const import (
|
|
|
|
DATA_HANDLER,
|
|
|
|
DATA_SCHEDULES,
|
|
|
|
DOMAIN,
|
|
|
|
EVENT_TYPE_SCHEDULE,
|
|
|
|
MANUFACTURER,
|
|
|
|
SIGNAL_NAME,
|
2021-10-22 09:14:28 +00:00
|
|
|
TYPE_ENERGY,
|
2021-07-12 22:27:48 +00:00
|
|
|
)
|
|
|
|
from .data_handler import HOMEDATA_DATA_CLASS_NAME, NetatmoDataHandler
|
2021-07-30 18:07:23 +00:00
|
|
|
from .helper import get_all_home_ids, update_climate_schedules
|
2021-07-12 22:27:48 +00:00
|
|
|
from .netatmo_entity_base import NetatmoBase
|
|
|
|
|
|
|
|
_LOGGER = logging.getLogger(__name__)
|
|
|
|
|
|
|
|
|
|
|
|
async def async_setup_entry(
|
|
|
|
hass: HomeAssistant, entry: ConfigEntry, async_add_entities: AddEntitiesCallback
|
|
|
|
) -> None:
|
|
|
|
"""Set up the Netatmo energy platform schedule selector."""
|
|
|
|
data_handler = hass.data[DOMAIN][entry.entry_id][DATA_HANDLER]
|
|
|
|
|
|
|
|
await data_handler.register_data_class(
|
|
|
|
HOMEDATA_DATA_CLASS_NAME, HOMEDATA_DATA_CLASS_NAME, None
|
|
|
|
)
|
|
|
|
home_data = data_handler.data.get(HOMEDATA_DATA_CLASS_NAME)
|
|
|
|
|
|
|
|
if not home_data or home_data.raw_data == {}:
|
|
|
|
raise PlatformNotReady
|
|
|
|
|
2021-07-30 18:07:23 +00:00
|
|
|
hass.data[DOMAIN][DATA_SCHEDULES].update(
|
|
|
|
update_climate_schedules(
|
|
|
|
home_ids=get_all_home_ids(home_data),
|
|
|
|
schedules=data_handler.data[HOMEDATA_DATA_CLASS_NAME].schedules,
|
|
|
|
)
|
|
|
|
)
|
2021-07-12 22:27:48 +00:00
|
|
|
|
|
|
|
entities = [
|
|
|
|
NetatmoScheduleSelect(
|
|
|
|
data_handler,
|
|
|
|
home_id,
|
|
|
|
list(hass.data[DOMAIN][DATA_SCHEDULES][home_id].values()),
|
|
|
|
)
|
2021-07-30 18:07:23 +00:00
|
|
|
for home_id in hass.data[DOMAIN][DATA_SCHEDULES]
|
2021-07-12 22:27:48 +00:00
|
|
|
]
|
|
|
|
|
|
|
|
_LOGGER.debug("Adding climate schedule select entities %s", entities)
|
|
|
|
async_add_entities(entities, True)
|
|
|
|
|
|
|
|
|
|
|
|
class NetatmoScheduleSelect(NetatmoBase, SelectEntity):
|
|
|
|
"""Representation a Netatmo thermostat schedule selector."""
|
|
|
|
|
|
|
|
def __init__(
|
|
|
|
self, data_handler: NetatmoDataHandler, home_id: str, options: list
|
|
|
|
) -> None:
|
|
|
|
"""Initialize the select entity."""
|
|
|
|
SelectEntity.__init__(self)
|
|
|
|
super().__init__(data_handler)
|
|
|
|
|
|
|
|
self._home_id = home_id
|
|
|
|
|
|
|
|
self._data_classes.extend(
|
|
|
|
[
|
|
|
|
{
|
|
|
|
"name": HOMEDATA_DATA_CLASS_NAME,
|
|
|
|
SIGNAL_NAME: HOMEDATA_DATA_CLASS_NAME,
|
|
|
|
},
|
|
|
|
]
|
|
|
|
)
|
|
|
|
|
|
|
|
self._device_name = self._data.homes[home_id]["name"]
|
|
|
|
self._attr_name = f"{MANUFACTURER} {self._device_name}"
|
|
|
|
|
|
|
|
self._model: str = "NATherm1"
|
2021-10-22 09:14:28 +00:00
|
|
|
self._netatmo_type = TYPE_ENERGY
|
2021-07-12 22:27:48 +00:00
|
|
|
|
|
|
|
self._attr_unique_id = f"{self._home_id}-schedule-select"
|
|
|
|
|
2021-07-15 04:44:57 +00:00
|
|
|
self._attr_current_option = self._data._get_selected_schedule(
|
|
|
|
home_id=self._home_id
|
|
|
|
).get("name")
|
2021-07-12 22:27:48 +00:00
|
|
|
self._attr_options = options
|
|
|
|
|
|
|
|
async def async_added_to_hass(self) -> None:
|
|
|
|
"""Entity created."""
|
|
|
|
await super().async_added_to_hass()
|
|
|
|
|
|
|
|
for event_type in (EVENT_TYPE_SCHEDULE,):
|
|
|
|
self._listeners.append(
|
|
|
|
async_dispatcher_connect(
|
|
|
|
self.hass,
|
|
|
|
f"signal-{DOMAIN}-webhook-{event_type}",
|
|
|
|
self.handle_event,
|
|
|
|
)
|
|
|
|
)
|
|
|
|
|
2021-07-30 18:07:23 +00:00
|
|
|
@callback
|
|
|
|
def handle_event(self, event: dict) -> None:
|
2021-07-12 22:27:48 +00:00
|
|
|
"""Handle webhook events."""
|
|
|
|
data = event["data"]
|
|
|
|
|
|
|
|
if self._home_id != data["home_id"]:
|
|
|
|
return
|
|
|
|
|
|
|
|
if data["event_type"] == EVENT_TYPE_SCHEDULE and "schedule_id" in data:
|
|
|
|
self._attr_current_option = self.hass.data[DOMAIN][DATA_SCHEDULES][
|
|
|
|
self._home_id
|
|
|
|
].get(data["schedule_id"])
|
|
|
|
self.async_write_ha_state()
|
|
|
|
|
|
|
|
@property
|
|
|
|
def _data(self) -> pyatmo.AsyncHomeData:
|
|
|
|
"""Return data for this entity."""
|
|
|
|
return cast(
|
|
|
|
pyatmo.AsyncHomeData,
|
|
|
|
self.data_handler.data[self._data_classes[0]["name"]],
|
|
|
|
)
|
|
|
|
|
|
|
|
async def async_select_option(self, option: str) -> None:
|
|
|
|
"""Change the selected option."""
|
|
|
|
for sid, name in self.hass.data[DOMAIN][DATA_SCHEDULES][self._home_id].items():
|
|
|
|
if name != option:
|
|
|
|
continue
|
|
|
|
_LOGGER.debug(
|
|
|
|
"Setting %s schedule to %s (%s)",
|
|
|
|
self._home_id,
|
|
|
|
option,
|
|
|
|
sid,
|
|
|
|
)
|
|
|
|
await self._data.async_switch_home_schedule(
|
|
|
|
home_id=self._home_id, schedule_id=sid
|
|
|
|
)
|
|
|
|
break
|
|
|
|
|
|
|
|
@callback
|
|
|
|
def async_update_callback(self) -> None:
|
|
|
|
"""Update the entity's state."""
|
|
|
|
self._attr_current_option = (
|
|
|
|
self._data._get_selected_schedule( # pylint: disable=protected-access
|
|
|
|
home_id=self._home_id
|
|
|
|
).get("name")
|
|
|
|
)
|
|
|
|
self.hass.data[DOMAIN][DATA_SCHEDULES][self._home_id] = {
|
|
|
|
schedule_id: schedule_data.get("name")
|
|
|
|
for schedule_id, schedule_data in (
|
|
|
|
self._data.schedules[self._home_id].items()
|
|
|
|
)
|
|
|
|
}
|
|
|
|
self._attr_options = list(
|
|
|
|
self.hass.data[DOMAIN][DATA_SCHEDULES][self._home_id].values()
|
|
|
|
)
|