diff --git a/homeassistant/components/rachio/__init__.py b/homeassistant/components/rachio/__init__.py index 5feeacf5b89..b23508809bb 100644 --- a/homeassistant/components/rachio/__init__.py +++ b/homeassistant/components/rachio/__init__.py @@ -2,39 +2,29 @@ import asyncio import logging import secrets +from typing import Optional +from aiohttp import web from rachiopy import Rachio import voluptuous as vol +from homeassistant.components.http import HomeAssistantView from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry -from homeassistant.const import CONF_API_KEY +from homeassistant.const import CONF_API_KEY, EVENT_HOMEASSISTANT_STOP, URL_API from homeassistant.core import HomeAssistant from homeassistant.exceptions import ConfigEntryNotReady -from homeassistant.helpers import config_validation as cv +from homeassistant.helpers import config_validation as cv, device_registry +from homeassistant.helpers.dispatcher import async_dispatcher_send +from homeassistant.helpers.entity import Entity from .const import ( CONF_CUSTOM_URL, CONF_MANUAL_RUN_MINS, DEFAULT_MANUAL_RUN_MINS, + DEFAULT_NAME, DOMAIN, - KEY_DEVICES, - KEY_ENABLED, - KEY_EXTERNAL_ID, - KEY_ID, - KEY_MAC_ADDRESS, - KEY_MODEL, - KEY_NAME, - KEY_SCHEDULES, - KEY_SERIAL_NUMBER, - KEY_STATUS, - KEY_TYPE, - KEY_USERNAME, - KEY_ZONES, - RACHIO_API_EXCEPTIONS, ) -from .device import RachioPerson -from .webhooks import WEBHOOK_PATH, RachioWebhookView _LOGGER = logging.getLogger(__name__) @@ -55,56 +45,6 @@ CONFIG_SCHEMA = vol.Schema( extra=vol.ALLOW_EXTRA, ) - -STATUS_ONLINE = "ONLINE" -STATUS_OFFLINE = "OFFLINE" - -# Device webhook values -TYPE_CONTROLLER_STATUS = "DEVICE_STATUS" -SUBTYPE_OFFLINE = "OFFLINE" -SUBTYPE_ONLINE = "ONLINE" -SUBTYPE_OFFLINE_NOTIFICATION = "OFFLINE_NOTIFICATION" -SUBTYPE_COLD_REBOOT = "COLD_REBOOT" -SUBTYPE_SLEEP_MODE_ON = "SLEEP_MODE_ON" -SUBTYPE_SLEEP_MODE_OFF = "SLEEP_MODE_OFF" -SUBTYPE_BROWNOUT_VALVE = "BROWNOUT_VALVE" -SUBTYPE_RAIN_SENSOR_DETECTION_ON = "RAIN_SENSOR_DETECTION_ON" -SUBTYPE_RAIN_SENSOR_DETECTION_OFF = "RAIN_SENSOR_DETECTION_OFF" -SUBTYPE_RAIN_DELAY_ON = "RAIN_DELAY_ON" -SUBTYPE_RAIN_DELAY_OFF = "RAIN_DELAY_OFF" - -# Schedule webhook values -TYPE_SCHEDULE_STATUS = "SCHEDULE_STATUS" -SUBTYPE_SCHEDULE_STARTED = "SCHEDULE_STARTED" -SUBTYPE_SCHEDULE_STOPPED = "SCHEDULE_STOPPED" -SUBTYPE_SCHEDULE_COMPLETED = "SCHEDULE_COMPLETED" -SUBTYPE_WEATHER_NO_SKIP = "WEATHER_INTELLIGENCE_NO_SKIP" -SUBTYPE_WEATHER_SKIP = "WEATHER_INTELLIGENCE_SKIP" -SUBTYPE_WEATHER_CLIMATE_SKIP = "WEATHER_INTELLIGENCE_CLIMATE_SKIP" -SUBTYPE_WEATHER_FREEZE = "WEATHER_INTELLIGENCE_FREEZE" - -# Zone webhook values -TYPE_ZONE_STATUS = "ZONE_STATUS" -SUBTYPE_ZONE_STARTED = "ZONE_STARTED" -SUBTYPE_ZONE_STOPPED = "ZONE_STOPPED" -SUBTYPE_ZONE_COMPLETED = "ZONE_COMPLETED" -SUBTYPE_ZONE_CYCLING = "ZONE_CYCLING" -SUBTYPE_ZONE_CYCLING_COMPLETED = "ZONE_CYCLING_COMPLETED" - -# Webhook callbacks -LISTEN_EVENT_TYPES = [ - "DEVICE_STATUS_EVENT", - "ZONE_STATUS_EVENT", - "SCHEDULE_STATUS_EVENT", -] -WEBHOOK_CONST_ID = "homeassistant.rachio:" -WEBHOOK_PATH = URL_API + DOMAIN -SIGNAL_RACHIO_UPDATE = DOMAIN + "_update" -SIGNAL_RACHIO_CONTROLLER_UPDATE = SIGNAL_RACHIO_UPDATE + "_controller" -SIGNAL_RACHIO_ZONE_UPDATE = SIGNAL_RACHIO_UPDATE + "_zone" -SIGNAL_RACHIO_SCHEDULE_UPDATE = SIGNAL_RACHIO_UPDATE + "_schedule" - - async def async_setup(hass: HomeAssistant, config: dict): """Set up the rachio component from YAML.""" diff --git a/homeassistant/components/rachio/const.py b/homeassistant/components/rachio/const.py index 2c439407c71..27ab5e831a7 100644 --- a/homeassistant/components/rachio/const.py +++ b/homeassistant/components/rachio/const.py @@ -36,11 +36,6 @@ KEY_ZONE_NUMBER = "zoneNumber" KEY_ZONES = "zones" KEY_SCHEDULES = "scheduleRules" KEY_SCHEDULE_ID = "scheduleId" -KEY_CUSTOM_SHADE = "customShade" -KEY_CUSTOM_CROP = "customCrop" - -ATTR_ZONE_TYPE = "type" -ATTR_ZONE_SHADE = "shade" # Yes we really do get all these exceptions (hopefully rachiopy switches to requests) RACHIO_API_EXCEPTIONS = ( @@ -49,11 +44,3 @@ RACHIO_API_EXCEPTIONS = ( OSError, AssertionError, ) - -STATUS_ONLINE = "ONLINE" -STATUS_OFFLINE = "OFFLINE" - -SIGNAL_RACHIO_UPDATE = DOMAIN + "_update" -SIGNAL_RACHIO_CONTROLLER_UPDATE = SIGNAL_RACHIO_UPDATE + "_controller" -SIGNAL_RACHIO_ZONE_UPDATE = SIGNAL_RACHIO_UPDATE + "_zone" -SIGNAL_RACHIO_SCHEDULE_UPDATE = SIGNAL_RACHIO_UPDATE + "_schedule" diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index 5a11b2c8478..c11d5ad21ab 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -6,7 +6,6 @@ import logging from homeassistant.components.switch import SwitchDevice from homeassistant.helpers.dispatcher import async_dispatcher_connect - from . import ( SIGNAL_RACHIO_CONTROLLER_UPDATE, SIGNAL_RACHIO_SCHEDULE_UPDATE, @@ -21,15 +20,10 @@ from . import ( SUBTYPE_ZONE_STOPPED, RachioDeviceInfoProvider, ) - from .const import ( - ATTR_ZONE_SHADE, - ATTR_ZONE_TYPE, CONF_MANUAL_RUN_MINS, DEFAULT_MANUAL_RUN_MINS, DOMAIN as DOMAIN_RACHIO, - KEY_CUSTOM_CROP, - KEY_CUSTOM_SHADE, KEY_DEVICE_ID, KEY_DURATION, KEY_ENABLED, @@ -42,16 +36,6 @@ from .const import ( KEY_SUMMARY, KEY_ZONE_ID, KEY_ZONE_NUMBER, - SIGNAL_RACHIO_CONTROLLER_UPDATE, - SIGNAL_RACHIO_ZONE_UPDATE, -) -from .entity import RachioDevice -from .webhooks import ( - SUBTYPE_SLEEP_MODE_OFF, - SUBTYPE_SLEEP_MODE_ON, - SUBTYPE_ZONE_COMPLETED, - SUBTYPE_ZONE_STARTED, - SUBTYPE_ZONE_STOPPED, ) _LOGGER = logging.getLogger(__name__) @@ -90,7 +74,7 @@ def _create_entities(hass, config_entry): return entities -class RachioSwitch(RachioDevice, SwitchDevice): +class RachioSwitch(RachioDeviceInfoProvider, SwitchDevice): """Represent a Rachio state that can be toggled.""" def __init__(self, controller, poll=True): @@ -102,6 +86,11 @@ class RachioSwitch(RachioDevice, SwitchDevice): else: self._state = None + @property + def should_poll(self) -> bool: + """Declare that this entity pushes its state to HA.""" + return False + @property def name(self) -> str: """Get a name for this switch.""" @@ -115,6 +104,7 @@ class RachioSwitch(RachioDevice, SwitchDevice): @abstractmethod def _poll_update(self, data=None) -> bool: """Poll the API.""" + pass def _handle_any_update(self, *args, **kwargs) -> None: """Determine whether an update event applies to this device.""" @@ -128,6 +118,7 @@ class RachioSwitch(RachioDevice, SwitchDevice): @abstractmethod def _handle_update(self, *args, **kwargs) -> None: """Handle incoming webhook data.""" + pass class RachioStandbySwitch(RachioSwitch): @@ -190,19 +181,15 @@ 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] self._entity_picture = data.get(KEY_IMAGE_URL) self._person = person - self._shade_type = data.get(KEY_CUSTOM_SHADE, {}).get(KEY_NAME) - self._zone_type = data.get(KEY_CUSTOM_CROP, {}).get(KEY_NAME) self._summary = str() self._current_schedule = current_schedule super().__init__(controller, poll=False) self._state = self.zone_id == self._current_schedule.get(KEY_ZONE_ID) - self._undo_dispatcher = None def __str__(self): """Display the zone as a string.""" @@ -241,12 +228,7 @@ class RachioZone(RachioSwitch): @property def state_attributes(self) -> dict: """Return the optional state attributes.""" - props = {ATTR_ZONE_NUMBER: self._zone_number, ATTR_ZONE_SUMMARY: self._summary} - if self._shade_type: - props[ATTR_ZONE_SHADE] = self._shade_type - if self._zone_type: - props[ATTR_ZONE_TYPE] = self._zone_type - return props + return {ATTR_ZONE_NUMBER: self._zone_number, ATTR_ZONE_SUMMARY: self._summary} def turn_on(self, **kwargs) -> None: """Start watering this zone.""" @@ -292,7 +274,7 @@ class RachioZone(RachioSwitch): async def async_added_to_hass(self): """Subscribe to updates.""" - self._undo_dispatcher = async_dispatcher_connect( + async_dispatcher_connect( self.hass, SIGNAL_RACHIO_ZONE_UPDATE, self._handle_update ) @@ -388,8 +370,3 @@ class RachioSchedule(RachioSwitch): async_dispatcher_connect( self.hass, SIGNAL_RACHIO_SCHEDULE_UPDATE, self._handle_update ) - - async def async_will_remove_from_hass(self): - """Unsubscribe from updates.""" - if self._undo_dispatcher: - self._undo_dispatcher()