Add pause and resume services to Rachio (#43944)

* Add pause-resume

* address comments
This commit is contained in:
Brian Rogers 2020-12-07 14:22:23 -05:00 committed by GitHub
parent 886ce599ac
commit f18c6ae72c
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 86 additions and 3 deletions

View file

@ -49,8 +49,11 @@ KEY_CUSTOM_SLOPE = "customSlope"
STATUS_ONLINE = "ONLINE" STATUS_ONLINE = "ONLINE"
MODEL_GENERATION_1 = "GENERATION1"
SCHEDULE_TYPE_FIXED = "FIXED" SCHEDULE_TYPE_FIXED = "FIXED"
SCHEDULE_TYPE_FLEX = "FLEX" SCHEDULE_TYPE_FLEX = "FLEX"
SERVICE_PAUSE_WATERING = "pause_watering"
SERVICE_RESUME_WATERING = "resume_watering"
SERVICE_SET_ZONE_MOISTURE = "set_zone_moisture_percent" SERVICE_SET_ZONE_MOISTURE = "set_zone_moisture_percent"
SERVICE_START_MULTIPLE_ZONES = "start_multiple_zone_schedule" SERVICE_START_MULTIPLE_ZONES = "start_multiple_zone_schedule"

View file

@ -1,11 +1,14 @@
"""Adapter to wrap the rachiopy api for home assistant.""" """Adapter to wrap the rachiopy api for home assistant."""
import logging import logging
from typing import Optional from typing import Optional
import voluptuous as vol
from homeassistant.const import EVENT_HOMEASSISTANT_STOP, HTTP_OK from homeassistant.const import EVENT_HOMEASSISTANT_STOP, HTTP_OK
from homeassistant.helpers import config_validation as cv
from .const import ( from .const import (
DOMAIN,
KEY_DEVICES, KEY_DEVICES,
KEY_ENABLED, KEY_ENABLED,
KEY_EXTERNAL_ID, KEY_EXTERNAL_ID,
@ -19,11 +22,26 @@ from .const import (
KEY_STATUS, KEY_STATUS,
KEY_USERNAME, KEY_USERNAME,
KEY_ZONES, KEY_ZONES,
MODEL_GENERATION_1,
SERVICE_PAUSE_WATERING,
SERVICE_RESUME_WATERING,
) )
from .webhooks import LISTEN_EVENT_TYPES, WEBHOOK_CONST_ID from .webhooks import LISTEN_EVENT_TYPES, WEBHOOK_CONST_ID
_LOGGER = logging.getLogger(__name__) _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: class RachioPerson:
"""Represent a Rachio user.""" """Represent a Rachio user."""
@ -39,6 +57,8 @@ class RachioPerson:
def setup(self, hass): def setup(self, hass):
"""Rachio device setup.""" """Rachio device setup."""
all_devices = []
can_pause = False
response = self.rachio.person.info() response = self.rachio.person.info()
assert int(response[0][KEY_STATUS]) == HTTP_OK, "API key error" assert int(response[0][KEY_STATUS]) == HTTP_OK, "API key error"
self._id = response[1][KEY_ID] self._id = response[1][KEY_ID]
@ -68,8 +88,43 @@ class RachioPerson:
rachio_iro = RachioIro(hass, self.rachio, controller, webhooks) rachio_iro = RachioIro(hass, self.rachio, controller, webhooks)
rachio_iro.setup() rachio_iro.setup()
self._controllers.append(rachio_iro) 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) _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 @property
def user_id(self) -> str: def user_id(self) -> str:
"""Get the user ID as defined by the Rachio API.""" """Get the user ID as defined by the Rachio API."""
@ -102,7 +157,7 @@ class RachioIro:
self._flex_schedules = data[KEY_FLEX_SCHEDULES] self._flex_schedules = data[KEY_FLEX_SCHEDULES]
self._init_data = data self._init_data = data
self._webhooks = webhooks 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): def setup(self):
"""Rachio Iro setup for webhooks.""" """Rachio Iro setup for webhooks."""
@ -195,4 +250,14 @@ class RachioIro:
def stop_watering(self) -> None: def stop_watering(self) -> None:
"""Stop watering all zones connected to this controller.""" """Stop watering all zones connected to this controller."""
self.rachio.device.stop_water(self.controller_id) 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)

View file

@ -16,3 +16,18 @@ start_multiple_zone_schedule:
duration: 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] 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 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