From 899431235b281a306d1ad66c45b1f324c2351895 Mon Sep 17 00:00:00 2001 From: Brian Rogers Date: Sat, 10 Oct 2020 20:44:49 -0400 Subject: [PATCH] Bump rachiopy to 1.0.3 and update methods to handle changes (#41398) --- homeassistant/components/rachio/__init__.py | 6 ++---- homeassistant/components/rachio/config_flow.py | 7 +++---- homeassistant/components/rachio/const.py | 11 ----------- homeassistant/components/rachio/device.py | 18 ++++++++++-------- homeassistant/components/rachio/manifest.json | 2 +- homeassistant/components/rachio/switch.py | 10 +++++----- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- tests/components/rachio/test_config_flow.py | 10 +++++----- 9 files changed, 28 insertions(+), 40 deletions(-) diff --git a/homeassistant/components/rachio/__init__.py b/homeassistant/components/rachio/__init__.py index 8310a12d51c..2c2918da4c9 100644 --- a/homeassistant/components/rachio/__init__.py +++ b/homeassistant/components/rachio/__init__.py @@ -4,6 +4,7 @@ import logging import secrets from rachiopy import Rachio +from requests.exceptions import ConnectTimeout import voluptuous as vol from homeassistant.config_entries import SOURCE_IMPORT, ConfigEntry @@ -18,7 +19,6 @@ from .const import ( CONF_WEBHOOK_ID, DEFAULT_MANUAL_RUN_MINS, DOMAIN, - RACHIO_API_EXCEPTIONS, ) from .device import RachioPerson from .webhooks import ( @@ -113,9 +113,7 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry): # Get the API user try: await hass.async_add_executor_job(person.setup, hass) - # Yes we really do get all these exceptions (hopefully rachiopy switches to requests) - # and there is not a reasonable timeout here so it can block for a long time - except RACHIO_API_EXCEPTIONS as error: + except ConnectTimeout as error: _LOGGER.error("Could not reach the Rachio API: %s", error) raise ConfigEntryNotReady from error diff --git a/homeassistant/components/rachio/config_flow.py b/homeassistant/components/rachio/config_flow.py index f262843d4ad..96420d56ba7 100644 --- a/homeassistant/components/rachio/config_flow.py +++ b/homeassistant/components/rachio/config_flow.py @@ -2,6 +2,7 @@ import logging from rachiopy import Rachio +from requests.exceptions import ConnectTimeout import voluptuous as vol from homeassistant import config_entries, core, exceptions @@ -14,7 +15,6 @@ from .const import ( KEY_ID, KEY_STATUS, KEY_USERNAME, - RACHIO_API_EXCEPTIONS, ) from .const import DOMAIN # pylint:disable=unused-import @@ -31,7 +31,7 @@ async def validate_input(hass: core.HomeAssistant, data): rachio = Rachio(data[CONF_API_KEY]) username = None try: - data = await hass.async_add_executor_job(rachio.person.getInfo) + data = await hass.async_add_executor_job(rachio.person.info) _LOGGER.debug("rachio.person.getInfo: %s", data) if int(data[0][KEY_STATUS]) != HTTP_OK: raise InvalidAuth @@ -43,8 +43,7 @@ async def validate_input(hass: core.HomeAssistant, data): raise CannotConnect username = data[1][KEY_USERNAME] - # Yes we really do get all these exceptions (hopefully rachiopy switches to requests) - except RACHIO_API_EXCEPTIONS as error: + except ConnectTimeout as error: _LOGGER.error("Could not reach the Rachio API: %s", error) raise CannotConnect from error diff --git a/homeassistant/components/rachio/const.py b/homeassistant/components/rachio/const.py index aad3593eed5..a25d329c7c1 100644 --- a/homeassistant/components/rachio/const.py +++ b/homeassistant/components/rachio/const.py @@ -1,8 +1,5 @@ """Constants for rachio.""" -import http.client -import ssl - DEFAULT_NAME = "Rachio" DOMAIN = "rachio" @@ -50,14 +47,6 @@ KEY_CUSTOM_SHADE = "customShade" KEY_CUSTOM_CROP = "customCrop" KEY_CUSTOM_SLOPE = "customSlope" -# Yes we really do get all these exceptions (hopefully rachiopy switches to requests) -RACHIO_API_EXCEPTIONS = ( - http.client.HTTPException, - ssl.SSLError, - OSError, - AssertionError, -) - STATUS_ONLINE = "ONLINE" SCHEDULE_TYPE_FIXED = "FIXED" diff --git a/homeassistant/components/rachio/device.py b/homeassistant/components/rachio/device.py index f7357a1b2dc..64066ca7bd7 100644 --- a/homeassistant/components/rachio/device.py +++ b/homeassistant/components/rachio/device.py @@ -39,7 +39,7 @@ class RachioPerson: def setup(self, hass): """Rachio device setup.""" - response = self.rachio.person.getInfo() + response = self.rachio.person.info() assert int(response[0][KEY_STATUS]) == HTTP_OK, "API key error" self._id = response[1][KEY_ID] @@ -49,7 +49,9 @@ class RachioPerson: self.username = data[1][KEY_USERNAME] devices = data[1][KEY_DEVICES] for controller in devices: - webhooks = self.rachio.notification.getDeviceWebhook(controller[KEY_ID])[1] + webhooks = self.rachio.notification.get_device_webhook(controller[KEY_ID])[ + 1 + ] # The API does not provide a way to tell if a controller is shared # or if they are the owner. To work around this problem we fetch the webooks # before we setup the device so we can skip it instead of failing. @@ -113,7 +115,7 @@ class RachioIro: if not self._webhooks: # We fetched webhooks when we created the device, however if we call _init_webhooks # again we need to fetch again - self._webhooks = self.rachio.notification.getDeviceWebhook( + self._webhooks = self.rachio.notification.get_device_webhook( self.controller_id )[1] for webhook in self._webhooks: @@ -121,21 +123,21 @@ class RachioIro: webhook[KEY_EXTERNAL_ID].startswith(WEBHOOK_CONST_ID) or webhook[KEY_ID] == current_webhook_id ): - self.rachio.notification.deleteWebhook(webhook[KEY_ID]) + self.rachio.notification.delete(webhook[KEY_ID]) self._webhooks = None _deinit_webhooks(None) # Choose which events to listen for and get their IDs event_types = [] - for event_type in self.rachio.notification.getWebhookEventType()[1]: + for event_type in self.rachio.notification.get_webhook_event_type()[1]: if event_type[KEY_NAME] in LISTEN_EVENT_TYPES: event_types.append({"id": event_type[KEY_ID]}) # Register to listen to these events from the device url = self.rachio.webhook_url auth = WEBHOOK_CONST_ID + self.rachio.webhook_auth - new_webhook = self.rachio.notification.postWebhook( + new_webhook = self.rachio.notification.add( self.controller_id, auth, url, event_types ) # Save ID for deletion at shutdown @@ -154,7 +156,7 @@ class RachioIro: @property def current_schedule(self) -> str: """Return the schedule that the device is running right now.""" - return self.rachio.device.getCurrentSchedule(self.controller_id)[1] + return self.rachio.device.current_schedule(self.controller_id)[1] @property def init_data(self) -> dict: @@ -188,5 +190,5 @@ class RachioIro: def stop_watering(self) -> None: """Stop watering all zones connected to this controller.""" - self.rachio.device.stopWater(self.controller_id) + self.rachio.device.stop_water(self.controller_id) _LOGGER.info("Stopped watering of all zones on %s", str(self)) diff --git a/homeassistant/components/rachio/manifest.json b/homeassistant/components/rachio/manifest.json index 61148aae438..224f59ea173 100644 --- a/homeassistant/components/rachio/manifest.json +++ b/homeassistant/components/rachio/manifest.json @@ -2,7 +2,7 @@ "domain": "rachio", "name": "Rachio", "documentation": "https://www.home-assistant.io/integrations/rachio", - "requirements": ["rachiopy==0.1.4"], + "requirements": ["rachiopy==1.0.3"], "dependencies": ["http"], "after_dependencies": ["cloud"], "codeowners": ["@bdraco"], diff --git a/homeassistant/components/rachio/switch.py b/homeassistant/components/rachio/switch.py index b5dc71b585c..4af61d4f71b 100644 --- a/homeassistant/components/rachio/switch.py +++ b/homeassistant/components/rachio/switch.py @@ -179,11 +179,11 @@ class RachioStandbySwitch(RachioSwitch): def turn_on(self, **kwargs) -> None: """Put the controller in standby mode.""" - self._controller.rachio.device.off(self._controller.controller_id) + self._controller.rachio.device.turn_off(self._controller.controller_id) def turn_off(self, **kwargs) -> None: """Resume controller functionality.""" - self._controller.rachio.device.on(self._controller.controller_id) + self._controller.rachio.device.turn_on(self._controller.controller_id) async def async_added_to_hass(self): """Subscribe to updates.""" @@ -250,12 +250,12 @@ class RachioRainDelay(RachioSwitch): 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) + self._controller.rachio.device.rain_delay(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) + self._controller.rachio.device.rain_delay(self._controller.controller_id, 0) _LOGGER.debug("Canceling rain delay") async def async_added_to_hass(self): @@ -381,7 +381,7 @@ class RachioZone(RachioSwitch): def set_moisture_percent(self, percent) -> None: """Set the zone moisture percent.""" _LOGGER.debug("Setting %s moisture to %s percent", self._zone_name, percent) - self._controller.rachio.zone.setMoisturePercent(self._id, percent / 100) + self._controller.rachio.zone.set_moisture_percent(self._id, percent / 100) @callback def _async_handle_update(self, *args, **kwargs) -> None: diff --git a/requirements_all.txt b/requirements_all.txt index 8b87c749746..83225c39642 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1899,7 +1899,7 @@ qnapstats==0.3.0 quantum-gateway==0.0.5 # homeassistant.components.rachio -rachiopy==0.1.4 +rachiopy==1.0.3 # homeassistant.components.radiotherm radiotherm==2.0.0 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 3bb63a7ebec..d17dffacbb4 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -901,7 +901,7 @@ pywilight==0.0.65 pyzerproc==0.2.5 # homeassistant.components.rachio -rachiopy==0.1.4 +rachiopy==1.0.3 # homeassistant.components.rainmachine regenmaschine==2.1.0 diff --git a/tests/components/rachio/test_config_flow.py b/tests/components/rachio/test_config_flow.py index b107bd1514f..eb6b5ef4386 100644 --- a/tests/components/rachio/test_config_flow.py +++ b/tests/components/rachio/test_config_flow.py @@ -11,11 +11,11 @@ from tests.async_mock import MagicMock, patch from tests.common import MockConfigEntry -def _mock_rachio_return_value(get=None, getInfo=None): +def _mock_rachio_return_value(get=None, info=None): rachio_mock = MagicMock() person_mock = MagicMock() type(person_mock).get = MagicMock(return_value=get) - type(person_mock).getInfo = MagicMock(return_value=getInfo) + type(person_mock).info = MagicMock(return_value=info) type(rachio_mock).person = person_mock return rachio_mock @@ -31,7 +31,7 @@ async def test_form(hass): rachio_mock = _mock_rachio_return_value( get=({"status": 200}, {"username": "myusername"}), - getInfo=({"status": 200}, {"id": "myid"}), + info=({"status": 200}, {"id": "myid"}), ) with patch( @@ -71,7 +71,7 @@ async def test_form_invalid_auth(hass): rachio_mock = _mock_rachio_return_value( get=({"status": 200}, {"username": "myusername"}), - getInfo=({"status": 412}, {"error": "auth fail"}), + info=({"status": 412}, {"error": "auth fail"}), ) with patch( "homeassistant.components.rachio.config_flow.Rachio", return_value=rachio_mock @@ -93,7 +93,7 @@ async def test_form_cannot_connect(hass): rachio_mock = _mock_rachio_return_value( get=({"status": 599}, {"username": "myusername"}), - getInfo=({"status": 200}, {"id": "myid"}), + info=({"status": 200}, {"id": "myid"}), ) with patch( "homeassistant.components.rachio.config_flow.Rachio", return_value=rachio_mock