From 4caf65dc971f1ba8aa5ca6f92ec7844e96e07b6a Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Thu, 2 Apr 2020 14:43:40 -0400 Subject: [PATCH] Add Rachio Flex Schedules (#33533) * Add Rachio Flex Schedules * Remove Duration Property * Missed duration call * Black formatting --- homeassistant/components/rachio/const.py | 1 + homeassistant/components/rachio/device.py | 8 +++++- homeassistant/components/rachio/switch.py | 30 ++++++++++------------- 3 files changed, 21 insertions(+), 18 deletions(-) diff --git a/homeassistant/components/rachio/const.py b/homeassistant/components/rachio/const.py index 2c439407c71d92..587cd85a2a5001 100644 --- a/homeassistant/components/rachio/const.py +++ b/homeassistant/components/rachio/const.py @@ -35,6 +35,7 @@ KEY_ZONE_NUMBER = "zoneNumber" KEY_ZONES = "zones" KEY_SCHEDULES = "scheduleRules" +KEY_FLEX_SCHEDULES = "flexScheduleRules" KEY_SCHEDULE_ID = "scheduleId" KEY_CUSTOM_SHADE = "customShade" KEY_CUSTOM_CROP = "customCrop" diff --git a/homeassistant/components/rachio/device.py b/homeassistant/components/rachio/device.py index fbf49ffc67f123..7ff47f7a221544 100644 --- a/homeassistant/components/rachio/device.py +++ b/homeassistant/components/rachio/device.py @@ -9,6 +9,7 @@ KEY_DEVICES, KEY_ENABLED, KEY_EXTERNAL_ID, + KEY_FLEX_SCHEDULES, KEY_ID, KEY_MAC_ADDRESS, KEY_MODEL, @@ -92,6 +93,7 @@ def __init__(self, hass, rachio, data, webhooks): self.model = data[KEY_MODEL] self._zones = data[KEY_ZONES] self._schedules = data[KEY_SCHEDULES] + self._flex_schedules = data[KEY_FLEX_SCHEDULES] self._init_data = data self._webhooks = webhooks _LOGGER.debug('%s has ID "%s"', str(self), self.controller_id) @@ -177,9 +179,13 @@ def get_zone(self, zone_id) -> Optional[dict]: return None def list_schedules(self) -> list: - """Return a list of schedules.""" + """Return a list of fixed schedules.""" return self._schedules + def list_flex_schedules(self) -> list: + """Return a list of flex schedules.""" + return self._flex_schedules + def stop_watering(self) -> None: """Stop watering all zones connected to this controller.""" self.rachio.device.stopWater(self.controller_id) diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index 7be0c64ee1bac4..86b6097ad13f5a 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -4,6 +4,7 @@ import logging from homeassistant.components.switch import SwitchDevice +from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from .const import ( @@ -68,13 +69,13 @@ def _create_entities(hass, config_entry): entities.append(RachioStandbySwitch(controller)) zones = controller.list_zones() schedules = controller.list_schedules() + flex_schedules = controller.list_flex_schedules() current_schedule = controller.current_schedule for zone in zones: - _LOGGER.debug("Rachio setting up zone: %s", zone) entities.append(RachioZone(person, controller, zone, current_schedule)) - for sched in schedules: - _LOGGER.debug("Added schedule: %s", sched) + for sched in schedules + flex_schedules: entities.append(RachioSchedule(person, controller, sched, current_schedule)) + _LOGGER.debug("Added %s", entities) return entities @@ -180,7 +181,6 @@ class RachioZone(RachioSwitch): def __init__(self, person, controller, data, current_schedule): """Initialize a new Rachio Zone.""" self._id = data[KEY_ID] - _LOGGER.debug("zone_data: %s", data) self._zone_name = data[KEY_NAME] self._zone_number = data[KEY_ZONE_NUMBER] self._zone_enabled = data[KEY_ENABLED] @@ -297,21 +297,16 @@ class RachioSchedule(RachioSwitch): def __init__(self, person, controller, data, current_schedule): """Initialize a new Rachio Schedule.""" - self._id = data[KEY_ID] + self._schedule_id = data[KEY_ID] self._schedule_name = data[KEY_NAME] self._duration = data[KEY_DURATION] self._schedule_enabled = data[KEY_ENABLED] self._summary = data[KEY_SUMMARY] self._current_schedule = current_schedule super().__init__(controller, poll=False) - self._state = self.schedule_id == self._current_schedule.get(KEY_SCHEDULE_ID) + self._state = self._schedule_id == self._current_schedule.get(KEY_SCHEDULE_ID) self._undo_dispatcher = None - @property - def schedule_id(self) -> str: - """How the Rachio API refers to the schedule.""" - return self._id - @property def name(self) -> str: """Return the friendly name of the schedule.""" @@ -320,7 +315,7 @@ def name(self) -> str: @property def unique_id(self) -> str: """Return a unique id by combining controller id and schedule.""" - return f"{self._controller.controller_id}-schedule-{self.schedule_id}" + return f"{self._controller.controller_id}-schedule-{self._schedule_id}" @property def icon(self) -> str: @@ -333,7 +328,7 @@ def device_state_attributes(self) -> dict: return { ATTR_SCHEDULE_SUMMARY: self._summary, ATTR_SCHEDULE_ENABLED: self.schedule_is_enabled, - ATTR_SCHEDULE_DURATION: self._duration / 60, + ATTR_SCHEDULE_DURATION: f"{round(self._duration / 60)} minutes", } @property @@ -344,7 +339,7 @@ def schedule_is_enabled(self) -> bool: def turn_on(self, **kwargs) -> None: """Start this schedule.""" - self._controller.rachio.schedulerule.start(self.schedule_id) + self._controller.rachio.schedulerule.start(self._schedule_id) _LOGGER.debug( "Schedule %s started on %s", self.name, self._controller.name, ) @@ -356,13 +351,14 @@ def turn_off(self, **kwargs) -> None: def _poll_update(self, data=None) -> bool: """Poll the API to check whether the schedule is running.""" self._current_schedule = self._controller.current_schedule - return self.schedule_id == self._current_schedule.get(KEY_SCHEDULE_ID) + return self._schedule_id == self._current_schedule.get(KEY_SCHEDULE_ID) - def _handle_update(self, *args, **kwargs) -> None: + @callback + async def _handle_update(self, *args, **kwargs) -> None: """Handle incoming webhook schedule data.""" # Schedule ID not passed when running individual zones, so we catch that error try: - if args[0][KEY_SCHEDULE_ID] == self.schedule_id: + if args[0][KEY_SCHEDULE_ID] == self._schedule_id: if args[0][KEY_SUBTYPE] in [SUBTYPE_SCHEDULE_STARTED]: self._state = True elif args[0][KEY_SUBTYPE] in [