Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions homeassistant/components/rachio/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@
KEY_MODEL = "model"
KEY_ON = "on"
KEY_DURATION = "totalDuration"
KEY_RAIN_DELAY = "rainDelayExpirationDate"
KEY_STATUS = "status"
KEY_SUBTYPE = "subType"
KEY_SUMMARY = "summary"
Expand Down Expand Up @@ -56,6 +57,7 @@

SIGNAL_RACHIO_UPDATE = f"{DOMAIN}_update"
SIGNAL_RACHIO_CONTROLLER_UPDATE = f"{SIGNAL_RACHIO_UPDATE}_controller"
SIGNAL_RACHIO_RAIN_DELAY_UPDATE = f"{SIGNAL_RACHIO_UPDATE}_rain_delay"
SIGNAL_RACHIO_ZONE_UPDATE = f"{SIGNAL_RACHIO_UPDATE}_zone"
SIGNAL_RACHIO_SCHEDULE_UPDATE = f"{SIGNAL_RACHIO_UPDATE}_schedule"

Expand Down
71 changes: 70 additions & 1 deletion homeassistant/components/rachio/switch.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@
from abc import abstractmethod
from datetime import timedelta
import logging
import time

from homeassistant.components.switch import SwitchEntity
from homeassistant.core import callback
Expand All @@ -22,17 +23,21 @@
KEY_IMAGE_URL,
KEY_NAME,
KEY_ON,
KEY_RAIN_DELAY,
KEY_SCHEDULE_ID,
KEY_SUBTYPE,
KEY_SUMMARY,
KEY_ZONE_ID,
KEY_ZONE_NUMBER,
SIGNAL_RACHIO_CONTROLLER_UPDATE,
SIGNAL_RACHIO_RAIN_DELAY_UPDATE,
SIGNAL_RACHIO_SCHEDULE_UPDATE,
SIGNAL_RACHIO_ZONE_UPDATE,
)
from .entity import RachioDevice
from .webhooks import (
SUBTYPE_RAIN_DELAY_OFF,
SUBTYPE_RAIN_DELAY_ON,
SUBTYPE_SCHEDULE_COMPLETED,
SUBTYPE_SCHEDULE_STARTED,
SUBTYPE_SCHEDULE_STOPPED,
Expand Down Expand Up @@ -67,6 +72,7 @@ def _create_entities(hass, config_entry):
# in order to avoid every zone doing it
for controller in person.controllers:
entities.append(RachioStandbySwitch(controller))
entities.append(RachioRainDelay(controller))
zones = controller.list_zones()
schedules = controller.list_schedules()
flex_schedules = controller.list_flex_schedules()
Expand Down Expand Up @@ -179,6 +185,69 @@ async def async_added_to_hass(self):
)


class RachioRainDelay(RachioSwitch):
"""Representation of a rain delay status/switch."""

def __init__(self, controller):
"""Instantiate a new Rachio rain delay switch."""
super().__init__(controller, poll=True)
self._poll_update(controller.init_data)
Comment thread
bdraco marked this conversation as resolved.

@property
def name(self) -> str:
"""Return the name of the switch."""
return f"{self._controller.name} rain delay"

@property
def unique_id(self) -> str:
"""Return a unique id by combining controller id and purpose."""
return f"{self._controller.controller_id}-delay"

@property
def icon(self) -> str:
"""Return an icon for rain delay."""
return "mdi:camera-timer"

def _poll_update(self, data=None) -> bool:
"""Request the state from the API."""
# API returns either 0 or current UNIX time when rain delay was canceled
# depending if it was done from the app or via the API
if data is None:
data = self._controller.rachio.device.get(self._controller.controller_id)[1]
Comment thread
bdraco marked this conversation as resolved.

return data[KEY_RAIN_DELAY] / 1000 > time.time()

@callback
def _async_handle_update(self, *args, **kwargs) -> None:
"""Update the state using webhook data."""
if args[0][0][KEY_SUBTYPE] == SUBTYPE_RAIN_DELAY_ON:
self._state = True
elif args[0][0][KEY_SUBTYPE] == SUBTYPE_RAIN_DELAY_OFF:
self._state = False

self.async_write_ha_state()

def turn_on(self, **kwargs) -> None:
"""Activate a 24 hour rain delay on the controller."""
self._controller.rachio.device.rainDelay(self._controller.controller_id, 86400)
_LOGGER.debug("Starting rain delay for 24 hours")

def turn_off(self, **kwargs) -> None:
"""Resume controller functionality."""
self._controller.rachio.device.rainDelay(self._controller.controller_id, 0)
_LOGGER.debug("Canceling rain delay")

async def async_added_to_hass(self):
"""Subscribe to updates."""
self.async_on_remove(
async_dispatcher_connect(
self.hass,
SIGNAL_RACHIO_RAIN_DELAY_UPDATE,
self._async_handle_any_update,
)
)


class RachioZone(RachioSwitch):
"""Representation of one zone of sprinklers connected to the Rachio Iro."""

Expand Down Expand Up @@ -320,7 +389,7 @@ def unique_id(self) -> str:
@property
def icon(self) -> str:
"""Return the icon to display."""
return "mdi:water"
return "mdi:water" if self.schedule_is_enabled else "mdi:water-off"

@property
def device_state_attributes(self) -> dict:
Expand Down
6 changes: 6 additions & 0 deletions homeassistant/components/rachio/webhooks.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
KEY_EXTERNAL_ID,
KEY_TYPE,
SIGNAL_RACHIO_CONTROLLER_UPDATE,
SIGNAL_RACHIO_RAIN_DELAY_UPDATE,
SIGNAL_RACHIO_SCHEDULE_UPDATE,
SIGNAL_RACHIO_ZONE_UPDATE,
)
Expand All @@ -30,6 +31,9 @@
SUBTYPE_BROWNOUT_VALVE = "BROWNOUT_VALVE"
SUBTYPE_RAIN_SENSOR_DETECTION_ON = "RAIN_SENSOR_DETECTION_ON"
SUBTYPE_RAIN_SENSOR_DETECTION_OFF = "RAIN_SENSOR_DETECTION_OFF"

# Rain dealay values
TYPE_RAIN_DELAY_STATUS = "RAIN_DELAY"
SUBTYPE_RAIN_DELAY_ON = "RAIN_DELAY_ON"
SUBTYPE_RAIN_DELAY_OFF = "RAIN_DELAY_OFF"

Expand All @@ -55,13 +59,15 @@
LISTEN_EVENT_TYPES = [
"DEVICE_STATUS_EVENT",
"ZONE_STATUS_EVENT",
"RAIN_DELAY_EVENT",
"SCHEDULE_STATUS_EVENT",
]
WEBHOOK_CONST_ID = "homeassistant.rachio:"
WEBHOOK_PATH = URL_API + DOMAIN

SIGNAL_MAP = {
TYPE_CONTROLLER_STATUS: SIGNAL_RACHIO_CONTROLLER_UPDATE,
TYPE_RAIN_DELAY_STATUS: SIGNAL_RACHIO_RAIN_DELAY_UPDATE,
TYPE_SCHEDULE_STATUS: SIGNAL_RACHIO_SCHEDULE_UPDATE,
TYPE_ZONE_STATUS: SIGNAL_RACHIO_ZONE_UPDATE,
}
Expand Down