From f48ec3dbb60ed849401d1d4a22c558af05f72516 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Tue, 10 Nov 2020 10:02:33 +0100 Subject: [PATCH 1/8] Switch to plugwise module and forthcoming changes --- CODEOWNERS | 2 +- homeassistant/components/plugwise/__init__.py | 27 ++++-------- homeassistant/components/plugwise/climate.py | 10 ++--- .../components/plugwise/config_flow.py | 7 ++-- homeassistant/components/plugwise/const.py | 4 +- homeassistant/components/plugwise/gateway.py | 24 +++++++---- .../components/plugwise/manifest.json | 4 +- homeassistant/components/plugwise/switch.py | 16 +++++--- requirements_all.txt | 6 +-- requirements_test_all.txt | 6 +-- tests/components/plugwise/conftest.py | 41 +++++++++++-------- tests/components/plugwise/test_config_flow.py | 18 ++++---- tests/components/plugwise/test_init.py | 5 ++- 13 files changed, 92 insertions(+), 78 deletions(-) diff --git a/CODEOWNERS b/CODEOWNERS index 215967c1c18a25..9c21f7606d99d2 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -336,7 +336,7 @@ homeassistant/components/pi_hole/* @fabaff @johnluetke @shenxn homeassistant/components/pilight/* @trekky12 homeassistant/components/plaato/* @JohNan homeassistant/components/plex/* @jjlawren -homeassistant/components/plugwise/* @CoMPaTech @bouwew +homeassistant/components/plugwise/* @CoMPaTech @bouwew @brefra homeassistant/components/plum_lightpad/* @ColinHarrington @prystupa homeassistant/components/point/* @fredrike homeassistant/components/poolsense/* @haemishkyd diff --git a/homeassistant/components/plugwise/__init__.py b/homeassistant/components/plugwise/__init__.py index ee6c44bc5587a6..16823ebbc4ad2f 100644 --- a/homeassistant/components/plugwise/__init__.py +++ b/homeassistant/components/plugwise/__init__.py @@ -1,14 +1,12 @@ """Plugwise platform for Home Assistant Core.""" -import asyncio - import voluptuous as vol from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant -from .const import ALL_PLATFORMS, DOMAIN, UNDO_UPDATE_LISTENER -from .gateway import async_setup_entry_gw +from .const import DOMAIN +from .gateway import async_setup_entry_gw, async_unload_entry_gw CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA) @@ -27,19 +25,8 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): - """Unload a config entry.""" - unload_ok = all( - await asyncio.gather( - *[ - hass.config_entries.async_forward_entry_unload(entry, component) - for component in ALL_PLATFORMS - ] - ) - ) - - hass.data[DOMAIN][entry.entry_id][UNDO_UPDATE_LISTENER]() - - if unload_ok: - hass.data[DOMAIN].pop(entry.entry_id) - - return unload_ok + """Unload the Plugwise components.""" + if entry.data.get(CONF_HOST): + return await async_unload_entry_gw(hass, entry) + # PLACEHOLDER USB entry setup + return False diff --git a/homeassistant/components/plugwise/climate.py b/homeassistant/components/plugwise/climate.py index 7981283f27d807..c8a2191963ee8e 100644 --- a/homeassistant/components/plugwise/climate.py +++ b/homeassistant/components/plugwise/climate.py @@ -2,7 +2,7 @@ import logging -from Plugwise_Smile.Smile import Smile +from plugwise.exceptions import PlugwiseException from homeassistant.components.climate import ClimateEntity from homeassistant.components.climate.const import ( @@ -192,7 +192,7 @@ async def async_set_temperature(self, **kwargs): await self._api.set_temperature(self._loc_id, temperature) self._setpoint = temperature self.async_write_ha_state() - except Smile.PlugwiseError: + except PlugwiseException: _LOGGER.error("Error while communicating to device") else: _LOGGER.error("Invalid temperature requested") @@ -205,7 +205,7 @@ async def async_set_hvac_mode(self, hvac_mode): try: await self._api.set_temperature(self._loc_id, self._schedule_temp) self._setpoint = self._schedule_temp - except Smile.PlugwiseError: + except PlugwiseException: _LOGGER.error("Error while communicating to device") try: await self._api.set_schedule_state( @@ -213,7 +213,7 @@ async def async_set_hvac_mode(self, hvac_mode): ) self._hvac_mode = hvac_mode self.async_write_ha_state() - except Smile.PlugwiseError: + except PlugwiseException: _LOGGER.error("Error while communicating to device") async def async_set_preset_mode(self, preset_mode): @@ -223,7 +223,7 @@ async def async_set_preset_mode(self, preset_mode): self._preset_mode = preset_mode self._setpoint = self._presets.get(self._preset_mode, "none")[0] self.async_write_ha_state() - except Smile.PlugwiseError: + except PlugwiseException: _LOGGER.error("Error while communicating to device") @callback diff --git a/homeassistant/components/plugwise/config_flow.py b/homeassistant/components/plugwise/config_flow.py index 6fd7cde44bcbd5..e0d2262773704d 100644 --- a/homeassistant/components/plugwise/config_flow.py +++ b/homeassistant/components/plugwise/config_flow.py @@ -1,7 +1,8 @@ """Config flow for Plugwise integration.""" import logging -from Plugwise_Smile.Smile import Smile +from plugwise.exceptions import InvalidAuthentication, PlugwiseException +from plugwise.smile import Smile import voluptuous as vol from homeassistant import config_entries, core, exceptions @@ -67,9 +68,9 @@ async def validate_gw_input(hass: core.HomeAssistant, data): try: await api.connect() - except Smile.InvalidAuthentication as err: + except InvalidAuthentication as err: raise InvalidAuth from err - except Smile.PlugwiseError as err: + except PlugwiseException as err: raise CannotConnect from err return api diff --git a/homeassistant/components/plugwise/const.py b/homeassistant/components/plugwise/const.py index f965676aef2530..c6ef43af602667 100644 --- a/homeassistant/components/plugwise/const.py +++ b/homeassistant/components/plugwise/const.py @@ -2,7 +2,9 @@ DOMAIN = "plugwise" SENSOR_PLATFORMS = ["sensor", "switch"] -ALL_PLATFORMS = ["binary_sensor", "climate", "sensor", "switch"] +PLATFORMS_GATEWAY = ["binary_sensor", "climate", "sensor", "switch"] +PW_TYPE = "plugwise_type" +GATEWAY = "gateway" # Sensor mapping SENSOR_MAP_DEVICE_CLASS = 2 diff --git a/homeassistant/components/plugwise/gateway.py b/homeassistant/components/plugwise/gateway.py index 5ba6eda2770ada..3b61bd3930d55d 100644 --- a/homeassistant/components/plugwise/gateway.py +++ b/homeassistant/components/plugwise/gateway.py @@ -5,8 +5,13 @@ import logging from typing import Dict -from Plugwise_Smile.Smile import Smile import async_timeout +from plugwise.exceptions import ( + InvalidAuthentication, + PlugwiseException, + XMLDataMissingError, +) +from plugwise.smile import Smile import voluptuous as vol from homeassistant.config_entries import ConfigEntry @@ -28,13 +33,15 @@ ) from .const import ( - ALL_PLATFORMS, COORDINATOR, DEFAULT_PORT, DEFAULT_SCAN_INTERVAL, DEFAULT_TIMEOUT, DEFAULT_USERNAME, DOMAIN, + GATEWAY, + PLATFORMS_GATEWAY, + PW_TYPE, SENSOR_PLATFORMS, UNDO_UPDATE_LISTENER, ) @@ -64,11 +71,11 @@ async def async_setup_entry_gw(hass: HomeAssistant, entry: ConfigEntry) -> bool: _LOGGER.error("Unable to connect to Smile") raise ConfigEntryNotReady - except Smile.InvalidAuthentication: + except InvalidAuthentication: _LOGGER.error("Invalid username or Smile ID") return False - except Smile.PlugwiseError as err: + except PlugwiseException as err: _LOGGER.error("Error while communicating to device %s", api.smile_name) raise ConfigEntryNotReady from err @@ -88,7 +95,7 @@ async def async_update_data(): async with async_timeout.timeout(DEFAULT_TIMEOUT): await api.full_update_device() return True - except Smile.XMLDataMissingError as err: + except XMLDataMissingError as err: raise UpdateFailed("Smile update failed") from err coordinator = DataUpdateCoordinator( @@ -115,6 +122,7 @@ async def async_update_data(): hass.data.setdefault(DOMAIN, {})[entry.entry_id] = { "api": api, COORDINATOR: coordinator, + PW_TYPE: GATEWAY, UNDO_UPDATE_LISTENER: undo_listener, } @@ -130,7 +138,7 @@ async def async_update_data(): single_master_thermostat = api.single_master_thermostat() - platforms = ALL_PLATFORMS + platforms = PLATFORMS_GATEWAY if single_master_thermostat is None: platforms = SENSOR_PLATFORMS @@ -150,13 +158,13 @@ async def _update_listener(hass: HomeAssistant, entry: ConfigEntry): ) -async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry): +async def async_unload_entry_gw(hass: HomeAssistant, entry: ConfigEntry): """Unload a config entry.""" unload_ok = all( await asyncio.gather( *[ hass.config_entries.async_forward_entry_unload(entry, component) - for component in ALL_PLATFORMS + for component in PLATFORMS_GATEWAY ] ) ) diff --git a/homeassistant/components/plugwise/manifest.json b/homeassistant/components/plugwise/manifest.json index f431ce9ee975bf..5637aee9b20a84 100644 --- a/homeassistant/components/plugwise/manifest.json +++ b/homeassistant/components/plugwise/manifest.json @@ -2,8 +2,8 @@ "domain": "plugwise", "name": "Plugwise", "documentation": "https://www.home-assistant.io/integrations/plugwise", - "requirements": ["Plugwise_Smile==1.6.0"], - "codeowners": ["@CoMPaTech", "@bouwew"], + "requirements": ["plugwise==0.8.1"], + "codeowners": ["@CoMPaTech", "@bouwew", "@brefra"], "zeroconf": ["_plugwise._tcp.local."], "config_flow": true } diff --git a/homeassistant/components/plugwise/switch.py b/homeassistant/components/plugwise/switch.py index 8221bc2cb579dc..ce3be04681ac74 100644 --- a/homeassistant/components/plugwise/switch.py +++ b/homeassistant/components/plugwise/switch.py @@ -2,7 +2,7 @@ import logging -from Plugwise_Smile.Smile import Smile +from plugwise.exceptions import PlugwiseException from homeassistant.components.switch import SwitchEntity from homeassistant.core import callback @@ -14,6 +14,12 @@ async def async_setup_entry(hass, config_entry, async_add_entities): + """Set up the Smile switches from a config entry.""" + # PLACEHOLDER USB entry setup + return await async_setup_entry_gateway(hass, config_entry, async_add_entities) + + +async def async_setup_entry_gateway(hass, config_entry, async_add_entities): """Set up the Smile switches from a config entry.""" api = hass.data[DOMAIN][config_entry.entry_id]["api"] coordinator = hass.data[DOMAIN][config_entry.entry_id][COORDINATOR] @@ -37,7 +43,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): model = "Switch Group" entities.append( - PwSwitch( + GwSwitch( api, coordinator, device_properties["name"], dev_id, members, model ) ) @@ -45,7 +51,7 @@ async def async_setup_entry(hass, config_entry, async_add_entities): async_add_entities(entities, True) -class PwSwitch(SmileGateway, SwitchEntity): +class GwSwitch(SmileGateway, SwitchEntity): """Representation of a Plugwise plug.""" def __init__(self, api, coordinator, name, dev_id, members, model): @@ -79,7 +85,7 @@ async def async_turn_on(self, **kwargs): if state_on: self._is_on = True self.async_write_ha_state() - except Smile.PlugwiseError: + except PlugwiseException: _LOGGER.error("Error while communicating to device") async def async_turn_off(self, **kwargs): @@ -91,7 +97,7 @@ async def async_turn_off(self, **kwargs): if state_off: self._is_on = False self.async_write_ha_state() - except Smile.PlugwiseError: + except PlugwiseException: _LOGGER.error("Error while communicating to device") @callback diff --git a/requirements_all.txt b/requirements_all.txt index a42c3829d0a262..a18cc373a6dff7 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -25,9 +25,6 @@ Mastodon.py==1.5.1 # homeassistant.components.orangepi_gpio OPi.GPIO==0.4.0 -# homeassistant.components.plugwise -Plugwise_Smile==1.6.0 - # homeassistant.components.essent PyEssent==0.14 @@ -1139,6 +1136,9 @@ plexauth==0.0.6 # homeassistant.components.plex plexwebsocket==0.0.12 +# homeassistant.components.plugwise +plugwise==0.8.1 + # homeassistant.components.plum_lightpad plumlightpad==0.0.11 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index ba665b3b7093d8..7702f0ba26289e 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -6,9 +6,6 @@ # homeassistant.components.homekit HAP-python==3.0.0 -# homeassistant.components.plugwise -Plugwise_Smile==1.6.0 - # homeassistant.components.flick_electric PyFlick==0.0.2 @@ -562,6 +559,9 @@ plexauth==0.0.6 # homeassistant.components.plex plexwebsocket==0.0.12 +# homeassistant.components.plugwise +plugwise==0.8.1 + # homeassistant.components.plum_lightpad plumlightpad==0.0.11 diff --git a/tests/components/plugwise/conftest.py b/tests/components/plugwise/conftest.py index 938e61146e5fab..ae934c565bc318 100644 --- a/tests/components/plugwise/conftest.py +++ b/tests/components/plugwise/conftest.py @@ -3,8 +3,13 @@ from functools import partial import re -from Plugwise_Smile.Smile import Smile import jsonpickle +from plugwise.exceptions import ( + ConnectionFailedError, + InvalidAuthentication, + PlugwiseException, + XMLDataMissingError, +) import pytest from tests.async_mock import AsyncMock, Mock, patch @@ -24,8 +29,8 @@ def mock_smile(): with patch( "homeassistant.components.plugwise.config_flow.Smile", ) as smile_mock: - smile_mock.InvalidAuthentication = Smile.InvalidAuthentication - smile_mock.ConnectionFailedError = Smile.ConnectionFailedError + smile_mock.InvalidAuthentication = InvalidAuthentication + smile_mock.ConnectionFailedError = ConnectionFailedError smile_mock.return_value.connect.return_value = True yield smile_mock.return_value @@ -48,9 +53,9 @@ def mock_smile_error(aioclient_mock: AiohttpClientMocker) -> None: def mock_smile_notconnect(): """Mock the Plugwise Smile general connection failure for Home Assistant.""" with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = Smile.InvalidAuthentication - smile_mock.ConnectionFailedError = Smile.ConnectionFailedError - smile_mock.PlugwiseError = Smile.PlugwiseError + smile_mock.InvalidAuthentication = InvalidAuthentication + smile_mock.ConnectionFailedError = ConnectionFailedError + smile_mock.PlugwiseException = PlugwiseException smile_mock.return_value.connect.side_effect = AsyncMock(return_value=False) yield smile_mock.return_value @@ -65,9 +70,9 @@ def mock_smile_adam(): """Create a Mock Adam environment for testing exceptions.""" chosen_env = "adam_multiple_devices_per_zone" with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = Smile.InvalidAuthentication - smile_mock.ConnectionFailedError = Smile.ConnectionFailedError - smile_mock.XMLDataMissingError = Smile.XMLDataMissingError + smile_mock.InvalidAuthentication = InvalidAuthentication + smile_mock.ConnectionFailedError = ConnectionFailedError + smile_mock.XMLDataMissingError = XMLDataMissingError smile_mock.return_value.gateway_id = "fe799307f1624099878210aa0b9f1475" smile_mock.return_value.heater_id = "90986d591dcd426cae3ec3e8111ff730" @@ -110,9 +115,9 @@ def mock_smile_anna(): """Create a Mock Anna environment for testing exceptions.""" chosen_env = "anna_heatpump" with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = Smile.InvalidAuthentication - smile_mock.ConnectionFailedError = Smile.ConnectionFailedError - smile_mock.XMLDataMissingError = Smile.XMLDataMissingError + smile_mock.InvalidAuthentication = InvalidAuthentication + smile_mock.ConnectionFailedError = ConnectionFailedError + smile_mock.XMLDataMissingError = XMLDataMissingError smile_mock.return_value.gateway_id = "015ae9ea3f964e668e490fa39da3870b" smile_mock.return_value.heater_id = "1cbf783bb11e4a7c8a6843dee3a86927" @@ -155,9 +160,9 @@ def mock_smile_p1(): """Create a Mock P1 DSMR environment for testing exceptions.""" chosen_env = "p1v3_full_option" with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = Smile.InvalidAuthentication - smile_mock.ConnectionFailedError = Smile.ConnectionFailedError - smile_mock.XMLDataMissingError = Smile.XMLDataMissingError + smile_mock.InvalidAuthentication = InvalidAuthentication + smile_mock.ConnectionFailedError = ConnectionFailedError + smile_mock.XMLDataMissingError = XMLDataMissingError smile_mock.return_value.gateway_id = "e950c7d5e1ee407a858e2a8b5016c8b3" smile_mock.return_value.heater_id = None @@ -191,9 +196,9 @@ def mock_stretch(): """Create a Mock Stretch environment for testing exceptions.""" chosen_env = "stretch_v31" with patch("homeassistant.components.plugwise.gateway.Smile") as smile_mock: - smile_mock.InvalidAuthentication = Smile.InvalidAuthentication - smile_mock.ConnectionFailedError = Smile.ConnectionFailedError - smile_mock.XMLDataMissingError = Smile.XMLDataMissingError + smile_mock.InvalidAuthentication = InvalidAuthentication + smile_mock.ConnectionFailedError = ConnectionFailedError + smile_mock.XMLDataMissingError = XMLDataMissingError smile_mock.return_value.gateway_id = "259882df3c05415b99c2d962534ce820" smile_mock.return_value.heater_id = None diff --git a/tests/components/plugwise/test_config_flow.py b/tests/components/plugwise/test_config_flow.py index dea42dfb01d478..fc0e5f9e69f7b5 100644 --- a/tests/components/plugwise/test_config_flow.py +++ b/tests/components/plugwise/test_config_flow.py @@ -1,5 +1,9 @@ """Test the Plugwise config flow.""" -from Plugwise_Smile.Smile import Smile +from plugwise.exceptions import ( + ConnectionFailedError, + InvalidAuthentication, + PlugwiseException, +) import pytest from homeassistant import config_entries, data_entry_flow, setup @@ -47,9 +51,9 @@ def mock_smile(): with patch( "homeassistant.components.plugwise.config_flow.Smile", ) as smile_mock: - smile_mock.PlugwiseError = Smile.PlugwiseError - smile_mock.InvalidAuthentication = Smile.InvalidAuthentication - smile_mock.ConnectionFailedError = Smile.ConnectionFailedError + smile_mock.PlugwiseError = PlugwiseException + smile_mock.InvalidAuthentication = InvalidAuthentication + smile_mock.ConnectionFailedError = ConnectionFailedError smile_mock.return_value.connect.return_value = True yield smile_mock.return_value @@ -207,7 +211,7 @@ async def test_form_invalid_auth(hass, mock_smile): DOMAIN, context={"source": config_entries.SOURCE_USER} ) - mock_smile.connect.side_effect = Smile.InvalidAuthentication + mock_smile.connect.side_effect = InvalidAuthentication mock_smile.gateway_id = "0a636a4fc1704ab4a24e4f7e37fb187a" result2 = await hass.config_entries.flow.async_configure( @@ -225,7 +229,7 @@ async def test_form_cannot_connect(hass, mock_smile): DOMAIN, context={"source": config_entries.SOURCE_USER} ) - mock_smile.connect.side_effect = Smile.ConnectionFailedError + mock_smile.connect.side_effect = ConnectionFailedError mock_smile.gateway_id = "0a636a4fc1704ab4a24e4f7e37fb187a" result2 = await hass.config_entries.flow.async_configure( @@ -243,7 +247,7 @@ async def test_form_cannot_connect_port(hass, mock_smile): DOMAIN, context={"source": config_entries.SOURCE_USER} ) - mock_smile.connect.side_effect = Smile.ConnectionFailedError + mock_smile.connect.side_effect = ConnectionFailedError mock_smile.gateway_id = "0a636a4fc1704ab4a24e4f7e37fb187a" result2 = await hass.config_entries.flow.async_configure( diff --git a/tests/components/plugwise/test_init.py b/tests/components/plugwise/test_init.py index db7a71d660b628..6e47b6d877fc42 100644 --- a/tests/components/plugwise/test_init.py +++ b/tests/components/plugwise/test_init.py @@ -2,9 +2,10 @@ import asyncio -from Plugwise_Smile.Smile import Smile +from plugwise.exceptions import XMLDataMissingError from homeassistant.components.plugwise import DOMAIN +from homeassistant.components.plugwise.gateway import async_unload_entry_gw from homeassistant.config_entries import ( ENTRY_STATE_NOT_LOADED, ENTRY_STATE_SETUP_ERROR, @@ -43,7 +44,7 @@ async def test_smile_timeout(hass, mock_smile_notconnect): async def test_smile_adam_xmlerror(hass, mock_smile_adam): """Detect malformed XML by Smile in Adam environment.""" - mock_smile_adam.full_update_device.side_effect = Smile.XMLDataMissingError + mock_smile_adam.full_update_device.side_effect = XMLDataMissingError entry = await async_init_integration(hass, mock_smile_adam) assert entry.state == ENTRY_STATE_SETUP_RETRY From fd593d66b1762c626d3e10d57e5a69c85da69f32 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Tue, 10 Nov 2020 16:47:14 +0100 Subject: [PATCH 2/8] Adjusted according to review --- homeassistant/components/plugwise/__init__.py | 4 ---- 1 file changed, 4 deletions(-) diff --git a/homeassistant/components/plugwise/__init__.py b/homeassistant/components/plugwise/__init__.py index 16823ebbc4ad2f..47a9a1e7d9c1d7 100644 --- a/homeassistant/components/plugwise/__init__.py +++ b/homeassistant/components/plugwise/__init__.py @@ -1,15 +1,11 @@ """Plugwise platform for Home Assistant Core.""" -import voluptuous as vol from homeassistant.config_entries import ConfigEntry from homeassistant.const import CONF_HOST from homeassistant.core import HomeAssistant -from .const import DOMAIN from .gateway import async_setup_entry_gw, async_unload_entry_gw -CONFIG_SCHEMA = vol.Schema({DOMAIN: vol.Schema({})}, extra=vol.ALLOW_EXTRA) - async def async_setup(hass: HomeAssistant, config: dict): """Set up the Plugwise platform.""" From a3803316135193ef8f6c3ad91db39c9a733f41d1 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Tue, 10 Nov 2020 17:11:48 +0100 Subject: [PATCH 3/8] Fix leaving out domain for tests --- tests/components/plugwise/common.py | 2 +- tests/components/plugwise/test_init.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/components/plugwise/common.py b/tests/components/plugwise/common.py index eb227322aa8366..379929ce2f150b 100644 --- a/tests/components/plugwise/common.py +++ b/tests/components/plugwise/common.py @@ -1,6 +1,6 @@ """Common initialisation for the Plugwise integration.""" -from homeassistant.components.plugwise import DOMAIN +from homeassistant.components.plugwise.const import DOMAIN from homeassistant.core import HomeAssistant from tests.common import MockConfigEntry diff --git a/tests/components/plugwise/test_init.py b/tests/components/plugwise/test_init.py index 6e47b6d877fc42..0633ac00554327 100644 --- a/tests/components/plugwise/test_init.py +++ b/tests/components/plugwise/test_init.py @@ -4,7 +4,7 @@ from plugwise.exceptions import XMLDataMissingError -from homeassistant.components.plugwise import DOMAIN +from homeassistant.components.plugwise.const import DOMAIN from homeassistant.components.plugwise.gateway import async_unload_entry_gw from homeassistant.config_entries import ( ENTRY_STATE_NOT_LOADED, From 7d24a7da4aa5fb86a2fec9ba85ad1345d4f8761b Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Tue, 10 Nov 2020 19:53:02 +0100 Subject: [PATCH 4/8] Add tests for exceptions --- tests/components/plugwise/test_climate.py | 30 +++++++++++++++++++++++ tests/components/plugwise/test_switch.py | 27 ++++++++++++++++++++ 2 files changed, 57 insertions(+) diff --git a/tests/components/plugwise/test_climate.py b/tests/components/plugwise/test_climate.py index 7c74d970d7e668..3529149f0e50b1 100644 --- a/tests/components/plugwise/test_climate.py +++ b/tests/components/plugwise/test_climate.py @@ -1,5 +1,7 @@ """Tests for the Plugwise Climate integration.""" +from plugwise.exceptions import PlugwiseException + from homeassistant.config_entries import ENTRY_STATE_LOADED from tests.components.plugwise.common import async_init_integration @@ -41,6 +43,34 @@ async def test_adam_climate_entity_attributes(hass, mock_smile_adam): assert attrs["preset_mode"] == "asleep" +async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam): + """Test exceptions of climate entities.""" + mock_smile_adam.set_temperature.side_effect = PlugwiseException + mock_smile_adam.set_preset.side_effect = PlugwiseException + entry = await async_init_integration(hass, mock_smile_adam) + assert entry.state == ENTRY_STATE_LOADED + + await hass.services.async_call( + "climate", + "set_temperature", + {"entity_id": "climate.zone_lisa_wk", "temperature": 25}, + blocking=True, + ) + state = hass.states.get("climate.zone_lisa_wk") + attrs = state.attributes + assert attrs["temperature"] == 21.5 + + await hass.services.async_call( + "climate", + "set_preset_mode", + {"entity_id": "climate.zone_thermostat_jessie", "preset_mode": "home"}, + blocking=True, + ) + state = hass.states.get("climate.zone_thermostat_jessie") + attrs = state.attributes + assert attrs["preset_mode"] == "asleep" + + async def test_adam_climate_entity_climate_changes(hass, mock_smile_adam): """Test handling of user requests in adam climate device environment.""" entry = await async_init_integration(hass, mock_smile_adam) diff --git a/tests/components/plugwise/test_switch.py b/tests/components/plugwise/test_switch.py index ded21113f2b5ce..b7237a261505d8 100644 --- a/tests/components/plugwise/test_switch.py +++ b/tests/components/plugwise/test_switch.py @@ -1,5 +1,7 @@ """Tests for the Plugwise switch integration.""" +from plugwise.exceptions import PlugwiseException + from homeassistant.config_entries import ENTRY_STATE_LOADED from tests.components.plugwise.common import async_init_integration @@ -17,6 +19,31 @@ async def test_adam_climate_switch_entities(hass, mock_smile_adam): assert str(state.state) == "on" +async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam): + """Test exceptions of climate related switch entities.""" + mock_smile_adam.set_relay_state.side_effect = PlugwiseException + entry = await async_init_integration(hass, mock_smile_adam) + assert entry.state == ENTRY_STATE_LOADED + + await hass.services.async_call( + "switch", + "turn_off", + {"entity_id": "switch.cv_pomp"}, + blocking=True, + ) + state = hass.states.get("switch.cv_pomp") + assert str(state.state) == "on" + + await hass.services.async_call( + "switch", + "turn_on", + {"entity_id": "switch.fibaro_hc2"}, + blocking=True, + ) + state = hass.states.get("switch.fibaro_hc2") + assert str(state.state) == "on" + + async def test_adam_climate_switch_changes(hass, mock_smile_adam): """Test changing of climate related switch entities.""" entry = await async_init_integration(hass, mock_smile_adam) From 6048cb4734401c6852eb4d0096db08321cd867a2 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Tue, 10 Nov 2020 20:24:28 +0100 Subject: [PATCH 5/8] Add more tests for exceptions --- tests/components/plugwise/test_climate.py | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/tests/components/plugwise/test_climate.py b/tests/components/plugwise/test_climate.py index 3529149f0e50b1..59ac4a4e3dfc36 100644 --- a/tests/components/plugwise/test_climate.py +++ b/tests/components/plugwise/test_climate.py @@ -2,6 +2,7 @@ from plugwise.exceptions import PlugwiseException +from homeassistant.components.climate.const import HVAC_MODE_AUTO, HVAC_MODE_HEAT from homeassistant.config_entries import ENTRY_STATE_LOADED from tests.components.plugwise.common import async_init_integration @@ -15,7 +16,7 @@ async def test_adam_climate_entity_attributes(hass, mock_smile_adam): state = hass.states.get("climate.zone_lisa_wk") attrs = state.attributes - assert attrs["hvac_modes"] == ["heat", "auto"] + assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_AUTO] assert "preset_modes" in attrs assert "no_frost" in attrs["preset_modes"] @@ -31,7 +32,7 @@ async def test_adam_climate_entity_attributes(hass, mock_smile_adam): state = hass.states.get("climate.zone_thermostat_jessie") attrs = state.attributes - assert attrs["hvac_modes"] == ["heat", "auto"] + assert attrs["hvac_modes"] == [HVAC_MODE_HEAT, HVAC_MODE_AUTO] assert "preset_modes" in attrs assert "no_frost" in attrs["preset_modes"] @@ -45,8 +46,9 @@ async def test_adam_climate_entity_attributes(hass, mock_smile_adam): async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam): """Test exceptions of climate entities.""" - mock_smile_adam.set_temperature.side_effect = PlugwiseException mock_smile_adam.set_preset.side_effect = PlugwiseException + mock_smile_adam.set_schedule_state.side_effect = PlugwiseException + mock_smile_adam.set_temperature.side_effect = PlugwiseException entry = await async_init_integration(hass, mock_smile_adam) assert entry.state == ENTRY_STATE_LOADED @@ -70,6 +72,15 @@ async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam): attrs = state.attributes assert attrs["preset_mode"] == "asleep" + await hass.services.async_call( + "climate", + "set_hvac_mode", + {"entity_id": "climate.zone_thermostat_jessie", "hvac_mode": HVAC_MODE_AUTO}, + blocking=True, + ) + state = hass.states.get("climate.zone_thermostat_jessie") + attrs = state.attributes + async def test_adam_climate_entity_climate_changes(hass, mock_smile_adam): """Test handling of user requests in adam climate device environment.""" @@ -142,7 +153,7 @@ async def test_anna_climate_entity_attributes(hass, mock_smile_anna): assert attrs["current_temperature"] == 23.3 assert attrs["temperature"] == 21.0 - assert state.state == "auto" + assert state.state == HVAC_MODE_AUTO assert attrs["hvac_action"] == "idle" assert attrs["preset_mode"] == "home" From ae26080b916340c1e460e5bdbee528210e1a1b9e Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Mon, 16 Nov 2020 19:58:12 +0100 Subject: [PATCH 6/8] Version bump --- homeassistant/components/plugwise/manifest.json | 2 +- requirements_all.txt | 2 +- requirements_test_all.txt | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/homeassistant/components/plugwise/manifest.json b/homeassistant/components/plugwise/manifest.json index 5637aee9b20a84..5a32341139c384 100644 --- a/homeassistant/components/plugwise/manifest.json +++ b/homeassistant/components/plugwise/manifest.json @@ -2,7 +2,7 @@ "domain": "plugwise", "name": "Plugwise", "documentation": "https://www.home-assistant.io/integrations/plugwise", - "requirements": ["plugwise==0.8.1"], + "requirements": ["plugwise==0.8.3"], "codeowners": ["@CoMPaTech", "@bouwew", "@brefra"], "zeroconf": ["_plugwise._tcp.local."], "config_flow": true diff --git a/requirements_all.txt b/requirements_all.txt index a18cc373a6dff7..d33b8842f4450b 100644 --- a/requirements_all.txt +++ b/requirements_all.txt @@ -1137,7 +1137,7 @@ plexauth==0.0.6 plexwebsocket==0.0.12 # homeassistant.components.plugwise -plugwise==0.8.1 +plugwise==0.8.3 # homeassistant.components.plum_lightpad plumlightpad==0.0.11 diff --git a/requirements_test_all.txt b/requirements_test_all.txt index 7702f0ba26289e..f616553fa2d9f2 100644 --- a/requirements_test_all.txt +++ b/requirements_test_all.txt @@ -560,7 +560,7 @@ plexauth==0.0.6 plexwebsocket==0.0.12 # homeassistant.components.plugwise -plugwise==0.8.1 +plugwise==0.8.3 # homeassistant.components.plum_lightpad plumlightpad==0.0.11 From f9c4192c64957cf38e8f10d77753b06fdafdef5a Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Mon, 16 Nov 2020 20:15:10 +0100 Subject: [PATCH 7/8] Wording on test --- tests/components/plugwise/test_climate.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/components/plugwise/test_climate.py b/tests/components/plugwise/test_climate.py index 59ac4a4e3dfc36..e85140660fd317 100644 --- a/tests/components/plugwise/test_climate.py +++ b/tests/components/plugwise/test_climate.py @@ -44,7 +44,7 @@ async def test_adam_climate_entity_attributes(hass, mock_smile_adam): assert attrs["preset_mode"] == "asleep" -async def test_adam_climate_switch_negative_testing(hass, mock_smile_adam): +async def test_adam_climate_adjust_negative_testing(hass, mock_smile_adam): """Test exceptions of climate entities.""" mock_smile_adam.set_preset.side_effect = PlugwiseException mock_smile_adam.set_schedule_state.side_effect = PlugwiseException From d0d151250bcc4a654c2db4c3a74212cb87885f58 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Tue, 17 Nov 2020 07:05:23 +0100 Subject: [PATCH 8/8] Catch-up with dev --- tests/components/plugwise/test_init.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/components/plugwise/test_init.py b/tests/components/plugwise/test_init.py index 0633ac00554327..eded1e55406604 100644 --- a/tests/components/plugwise/test_init.py +++ b/tests/components/plugwise/test_init.py @@ -5,7 +5,6 @@ from plugwise.exceptions import XMLDataMissingError from homeassistant.components.plugwise.const import DOMAIN -from homeassistant.components.plugwise.gateway import async_unload_entry_gw from homeassistant.config_entries import ( ENTRY_STATE_NOT_LOADED, ENTRY_STATE_SETUP_ERROR,