From a78178be11c7f311d812d28da1d90ed28f4bfbe3 Mon Sep 17 00:00:00 2001 From: brg468 Date: Thu, 2 Apr 2020 10:10:56 -0400 Subject: [PATCH 1/4] Add Rachio Flex Schedules --- homeassistant/components/rachio/const.py | 1 + homeassistant/components/rachio/device.py | 8 ++++- homeassistant/components/rachio/switch.py | 40 +++++++++++++---------- 3 files changed, 30 insertions(+), 19 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 a4ba1a41fee0b0..c5a07a9d4ca6fb 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -3,6 +3,7 @@ from datetime import timedelta import logging +from homeassistant.core import callback from homeassistant.components.switch import SwitchDevice from homeassistant.helpers.dispatcher import async_dispatcher_connect @@ -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 @@ -178,7 +179,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] @@ -295,21 +295,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.""" @@ -318,20 +313,25 @@ 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: """Return the icon to display.""" return "mdi:water" + @property + def duration(self) -> str: + """Return the duration of each schedule.""" + return f"{round(self._duration / 60)} minutes" + @property def device_state_attributes(self) -> dict: """Return the optional state attributes.""" return { ATTR_SCHEDULE_SUMMARY: self._summary, ATTR_SCHEDULE_ENABLED: self.schedule_is_enabled, - ATTR_SCHEDULE_DURATION: self._duration / 60, + ATTR_SCHEDULE_DURATION: self.duration, } @property @@ -342,9 +342,12 @@ 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, + "Schedule %s started on %s for %s", + self.name, + self._controller.name, + self.duration, ) def turn_off(self, **kwargs) -> None: @@ -354,13 +357,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 [ From b26c7dddd19116d470dc1e912763f75a39760ab3 Mon Sep 17 00:00:00 2001 From: brg468 Date: Thu, 2 Apr 2020 12:42:56 -0400 Subject: [PATCH 2/4] Remove Duration Property --- homeassistant/components/rachio/switch.py | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index c5a07a9d4ca6fb..09b5df4255938a 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -3,8 +3,8 @@ from datetime import timedelta import logging -from homeassistant.core import callback from homeassistant.components.switch import SwitchDevice +from homeassistant.core import callback from homeassistant.helpers.dispatcher import async_dispatcher_connect from .const import ( @@ -320,18 +320,13 @@ def icon(self) -> str: """Return the icon to display.""" return "mdi:water" - @property - def duration(self) -> str: - """Return the duration of each schedule.""" - return f"{round(self._duration / 60)} minutes" - @property def device_state_attributes(self) -> dict: """Return the optional state attributes.""" return { ATTR_SCHEDULE_SUMMARY: self._summary, ATTR_SCHEDULE_ENABLED: self.schedule_is_enabled, - ATTR_SCHEDULE_DURATION: self.duration, + ATTR_SCHEDULE_DURATION: f"{round(self._duration / 60)} minutes", } @property From 991f20095cdba27552c769c979acb55f0254e342 Mon Sep 17 00:00:00 2001 From: brg468 Date: Thu, 2 Apr 2020 13:08:05 -0400 Subject: [PATCH 3/4] Missed duration call --- homeassistant/components/rachio/switch.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index 09b5df4255938a..7f92c87c7f622c 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -339,10 +339,9 @@ def turn_on(self, **kwargs) -> None: self._controller.rachio.schedulerule.start(self._schedule_id) _LOGGER.debug( - "Schedule %s started on %s for %s", + "Schedule %s started on %s", self.name, self._controller.name, - self.duration, ) def turn_off(self, **kwargs) -> None: From 4a9bdf1d15f036d210be24a82e0416aa4c0921d2 Mon Sep 17 00:00:00 2001 From: brg468 Date: Thu, 2 Apr 2020 13:13:57 -0400 Subject: [PATCH 4/4] Black formatting --- homeassistant/components/rachio/switch.py | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index 7f92c87c7f622c..9053204de1b6ee 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -339,9 +339,7 @@ def turn_on(self, **kwargs) -> None: self._controller.rachio.schedulerule.start(self._schedule_id) _LOGGER.debug( - "Schedule %s started on %s", - self.name, - self._controller.name, + "Schedule %s started on %s", self.name, self._controller.name, ) def turn_off(self, **kwargs) -> None: