diff --git a/homeassistant/components/rachio/const.py b/homeassistant/components/rachio/const.py index 943e1b33199..721fb36fd36 100644 --- a/homeassistant/components/rachio/const.py +++ b/homeassistant/components/rachio/const.py @@ -49,8 +49,11 @@ KEY_CUSTOM_SLOPE = "customSlope" STATUS_ONLINE = "ONLINE" +MODEL_GENERATION_1 = "GENERATION1" SCHEDULE_TYPE_FIXED = "FIXED" SCHEDULE_TYPE_FLEX = "FLEX" +SERVICE_PAUSE_WATERING = "pause_watering" +SERVICE_RESUME_WATERING = "resume_watering" SERVICE_SET_ZONE_MOISTURE = "set_zone_moisture_percent" SERVICE_START_MULTIPLE_ZONES = "start_multiple_zone_schedule" diff --git a/homeassistant/components/rachio/device.py b/homeassistant/components/rachio/device.py index 9d7c3057939..2ef904f8680 100644 --- a/homeassistant/components/rachio/device.py +++ b/homeassistant/components/rachio/device.py @@ -1,11 +1,14 @@ """Adapter to wrap the rachiopy api for home assistant.""" - import logging from typing import Optional +import voluptuous as vol + from homeassistant.const import EVENT_HOMEASSISTANT_STOP, HTTP_OK +from homeassistant.helpers import config_validation as cv from .const import ( + DOMAIN, KEY_DEVICES, KEY_ENABLED, KEY_EXTERNAL_ID, @@ -19,11 +22,26 @@ from .const import ( KEY_STATUS, KEY_USERNAME, KEY_ZONES, + MODEL_GENERATION_1, + SERVICE_PAUSE_WATERING, + SERVICE_RESUME_WATERING, ) from .webhooks import LISTEN_EVENT_TYPES, WEBHOOK_CONST_ID _LOGGER = logging.getLogger(__name__) +ATTR_DEVICES = "devices" +ATTR_DURATION = "duration" + +PAUSE_SERVICE_SCHEMA = vol.Schema( + { + vol.Optional(ATTR_DEVICES): cv.string, + vol.Optional(ATTR_DURATION, default=60): cv.positive_int, + } +) + +RESUME_SERVICE_SCHEMA = vol.Schema({vol.Optional(ATTR_DEVICES): cv.string}) + class RachioPerson: """Represent a Rachio user.""" @@ -39,6 +57,8 @@ class RachioPerson: def setup(self, hass): """Rachio device setup.""" + all_devices = [] + can_pause = False response = self.rachio.person.info() assert int(response[0][KEY_STATUS]) == HTTP_OK, "API key error" self._id = response[1][KEY_ID] @@ -68,8 +88,43 @@ class RachioPerson: rachio_iro = RachioIro(hass, self.rachio, controller, webhooks) rachio_iro.setup() self._controllers.append(rachio_iro) + all_devices.append(rachio_iro.name) + # Generation 1 controllers don't support pause or resume + if rachio_iro.model.split("_")[0] != MODEL_GENERATION_1: + can_pause = True + _LOGGER.info('Using Rachio API as user "%s"', self.username) + def pause_water(service): + """Service to pause watering on all or specific controllers.""" + duration = service.data[ATTR_DURATION] + devices = service.data.get(ATTR_DEVICES, all_devices) + for iro in self._controllers: + if iro.name in devices: + iro.pause_watering(duration) + + def resume_water(service): + """Service to resume watering on all or specific controllers.""" + devices = service.data.get(ATTR_DEVICES, all_devices) + for iro in self._controllers: + if iro.name in devices: + iro.resume_watering() + + if can_pause: + hass.services.register( + DOMAIN, + SERVICE_PAUSE_WATERING, + pause_water, + schema=PAUSE_SERVICE_SCHEMA, + ) + + hass.services.register( + DOMAIN, + SERVICE_RESUME_WATERING, + resume_water, + schema=RESUME_SERVICE_SCHEMA, + ) + @property def user_id(self) -> str: """Get the user ID as defined by the Rachio API.""" @@ -102,7 +157,7 @@ class RachioIro: 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) + _LOGGER.debug('%s has ID "%s"', self, self.controller_id) def setup(self): """Rachio Iro setup for webhooks.""" @@ -195,4 +250,14 @@ class RachioIro: def stop_watering(self) -> None: """Stop watering all zones connected to this controller.""" self.rachio.device.stop_water(self.controller_id) - _LOGGER.info("Stopped watering of all zones on %s", str(self)) + _LOGGER.info("Stopped watering of all zones on %s", self) + + def pause_watering(self, duration) -> None: + """Pause watering on this controller.""" + self.rachio.device.pause_zone_run(self.controller_id, duration * 60) + _LOGGER.debug("Paused watering on %s for %s minutes", self, duration) + + def resume_watering(self) -> None: + """Resume paused watering on this controller.""" + self.rachio.device.resume_zone_run(self.controller_id) + _LOGGER.debug("Resuming watering on %s", self) diff --git a/homeassistant/components/rachio/services.yaml b/homeassistant/components/rachio/services.yaml index 480d53aa454..815a8601314 100644 --- a/homeassistant/components/rachio/services.yaml +++ b/homeassistant/components/rachio/services.yaml @@ -16,3 +16,18 @@ start_multiple_zone_schedule: duration: description: Number of minutes to run the zone(s). If only 1 duration is given, that time will be used for all zones. If given a list of durations, the durations will apply to the respective zone listed above. [Required] example: 15, 20 +pause_watering: + description: Pause any currently running zones or schedules. + fields: + devices: + description: Name of controllers to pause. Defaults to all controllers on the account if not provided. [Optional] + example: Main House + duration: + description: The number of minutes to pause running schedules. Accepts 1-60. Default is 60 minutes. [Optional] + example: 30 +resume_watering: + description: Resume any paused zone runs or schedules. + fields: + devices: + description: Name of controllers to resume. Defaults to all controllers on the account if not provided. [Optional] + example: Main House