diff --git a/CHANGELOG.md b/CHANGELOG.md
index b0d44cd93..c2b0ad019 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,7 +1,10 @@
# Changelog
-## Ongoing
+## v0.38.1
+- Add missing exception-handling for set-function in `__init__.py`
+- Add call_request() functions combining all common exception-handling for all set-functions
+- Update and improve test code
- Implementing code improvements as suggested in #567
## v0.38.0
diff --git a/plugwise/__init__.py b/plugwise/__init__.py
index 4ff7fea2b..7faef69a6 100644
--- a/plugwise/__init__.py
+++ b/plugwise/__init__.py
@@ -324,7 +324,10 @@ async def set_select(
state: str | None = None,
) -> None:
"""Set the selected option for the applicable Select."""
- await self._smile_api.set_select(key, loc_id, option, state)
+ try:
+ await self._smile_api.set_select(key, loc_id, option, state)
+ except ConnectionFailedError as exc:
+ raise ConnectionFailedError(f"Failed to set select option '{option}': {str(exc)}") from exc
async def set_schedule_state(
self,
@@ -333,15 +336,25 @@ async def set_schedule_state(
name: str | None = None,
) -> None:
"""Activate/deactivate the Schedule, with the given name, on the relevant Thermostat."""
- await self._smile_api.set_schedule_state(loc_id, state, name)
+ try:
+ await self._smile_api.set_schedule_state(loc_id, state, name)
+ except ConnectionFailedError as exc: # pragma no cover
+ raise ConnectionFailedError(f"Failed to set schedule state: {str(exc)}") from exc # pragma no cover
+
async def set_preset(self, loc_id: str, preset: str) -> None:
"""Set the given Preset on the relevant Thermostat."""
- await self._smile_api.set_preset(loc_id, preset)
+ try:
+ await self._smile_api.set_preset(loc_id, preset)
+ except ConnectionFailedError as exc:
+ raise ConnectionFailedError(f"Failed to set preset: {str(exc)}") from exc
async def set_temperature(self, loc_id: str, items: dict[str, float]) -> None:
"""Set the given Temperature on the relevant Thermostat."""
- await self._smile_api.set_temperature(loc_id, items)
+ try:
+ await self._smile_api.set_temperature(loc_id, items)
+ except ConnectionFailedError as exc:
+ raise ConnectionFailedError(f"Failed to set temperature: {str(exc)}") from exc
async def set_number(
self,
@@ -350,40 +363,58 @@ async def set_number(
temperature: float,
) -> None:
"""Set the maximum boiler- or DHW-setpoint on the Central Heating boiler or the temperature-offset on a Thermostat."""
- await self._smile_api.set_number(dev_id, key, temperature)
+ try:
+ await self._smile_api.set_number(dev_id, key, temperature)
+ except ConnectionFailedError as exc:
+ raise ConnectionFailedError(f"Failed to set number '{key}': {str(exc)}") from exc
async def set_temperature_offset(self, dev_id: str, offset: float) -> None:
"""Set the Temperature offset for thermostats that support this feature."""
- await self._smile_api.set_offset(dev_id, offset) # pragma: no cover
+ try: # pragma no cover
+ await self._smile_api.set_offset(dev_id, offset) # pragma: no cover
+ except ConnectionFailedError as exc: # pragma no cover
+ raise ConnectionFailedError(f"Failed to set temperature offset: {str(exc)}") from exc # pragma no cover
async def set_switch_state(
self, appl_id: str, members: list[str] | None, model: str, state: str
) -> None:
"""Set the given State of the relevant Switch."""
- await self._smile_api.set_switch_state(appl_id, members, model, state)
+ try:
+ await self._smile_api.set_switch_state(appl_id, members, model, state)
+ except ConnectionFailedError as exc:
+ raise ConnectionFailedError(f"Failed to set switch state: {str(exc)}") from exc
async def set_gateway_mode(self, mode: str) -> None:
"""Set the gateway mode."""
- await self._smile_api.set_gateway_mode(mode) # pragma: no cover
+ try: # pragma no cover
+ await self._smile_api.set_gateway_mode(mode) # pragma: no cover
+ except ConnectionFailedError as exc: # pragma no cover
+ raise ConnectionFailedError(f"Failed to set gateway mode: {str(exc)}") from exc # pragma no cover
async def set_regulation_mode(self, mode: str) -> None:
"""Set the heating regulation mode."""
- await self._smile_api.set_regulation_mode(mode) # pragma: no cover
+ try: # pragma no cover
+ await self._smile_api.set_regulation_mode(mode) # pragma: no cover
+ except ConnectionFailedError as exc: # pragma no cover
+ raise ConnectionFailedError(f"Failed to set regulation mode: {str(exc)}") from exc # pragma no cover
async def set_dhw_mode(self, mode: str) -> None:
"""Set the domestic hot water heating regulation mode."""
- await self._smile_api.set_dhw_mode(mode) # pragma: no cover
+ try: # pragma no cover
+ await self._smile_api.set_dhw_mode(mode) # pragma: no cover
+ except ConnectionFailedError as exc: # pragma no cover
+ raise ConnectionFailedError(f"Failed to set dhw mode: {str(exc)}") from exc # pragma no cover
async def delete_notification(self) -> None:
"""Delete the active Plugwise Notification."""
try:
await self._smile_api.delete_notification()
except ConnectionFailedError as exc:
- raise PlugwiseError(f"Failed to delete notification: {str(exc)}") from exc
+ raise ConnectionFailedError(f"Failed to delete notification: {str(exc)}") from exc
async def reboot_gateway(self) -> None:
"""Reboot the Plugwise Gateway."""
try:
await self._smile_api.reboot_gateway()
except ConnectionFailedError as exc:
- raise PlugwiseError(f"Failed to reboot gateway: {str(exc)}") from exc
+ raise ConnectionFailedError(f"Failed to reboot gateway: {str(exc)}") from exc
diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py
index 9048fa7e5..e72621b82 100644
--- a/plugwise/legacy/smile.py
+++ b/plugwise/legacy/smile.py
@@ -5,6 +5,7 @@
from __future__ import annotations
import datetime as dt
+from typing import Any
from plugwise.constants import (
APPLIANCES,
@@ -23,7 +24,7 @@
PlugwiseData,
ThermoLoc,
)
-from plugwise.exceptions import PlugwiseError
+from plugwise.exceptions import ConnectionFailedError, PlugwiseError
from plugwise.helper import SmileComm
from plugwise.legacy.data import SmileLegacyData
@@ -180,7 +181,7 @@ async def set_preset(self, _: str, preset: str) -> None:
rule = self._domain_objects.find(locator)
data = f'true'
- await self._request(RULES, method="put", data=data)
+ await self.call_request(RULES, method="put", data=data)
async def set_regulation_mode(self, mode: str) -> None:
"""Set-function placeholder for legacy devices."""
@@ -226,7 +227,7 @@ async def set_schedule_state(self, _: str, state: str | None, name: str | None)
f' id="{template_id}" />{new_state}'
)
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_switch_state(
self, appl_id: str, members: list[str] | None, model: str, state: str
@@ -254,7 +255,7 @@ async def set_switch_state(
if self._appliances.find(locator).text == "true":
raise PlugwiseError("Plugwise: the locked Relay was not switched.")
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def _set_groupswitch_member_state(
self, members: list[str], state: str, switch: Munch
@@ -267,7 +268,7 @@ async def _set_groupswitch_member_state(
uri = f"{APPLIANCES};id={member}/{switch.func_type}"
data = f"<{switch.func_type}><{switch.func}>{state}{switch.func}>{switch.func_type}>"
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_temperature(self, _: str, items: dict[str, float]) -> None:
"""Set the given Temperature on the relevant Thermostat."""
@@ -287,4 +288,13 @@ async def set_temperature(self, _: str, items: dict[str, float]) -> None:
f"{temperature}"
)
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
+
+ async def call_request(self, uri: str, **kwargs: Any) -> None:
+ """ConnectionFailedError wrapper for calling _request()."""
+ method: str = kwargs["method"]
+ data: str | None = kwargs.get("data")
+ try:
+ await self._request(uri, method=method, data=data)
+ except ConnectionFailedError as exc:
+ raise ConnectionFailedError from exc
diff --git a/plugwise/smile.py b/plugwise/smile.py
index c2d0ba5cf..ef3e13d55 100644
--- a/plugwise/smile.py
+++ b/plugwise/smile.py
@@ -149,14 +149,6 @@ async def async_update(self) -> PlugwiseData:
### API Set and HA Service-related Functions ###
########################################################################################################
- async def call_request(self, uri: str, **kwargs: Any) -> None:
- """ConnectionFailedError wrapper for calling _request()."""
- method: str = kwargs["method"]
- try:
- await self._request(uri, method=method)
- except ConnectionFailedError as exc:
- raise ConnectionFailedError from exc
-
async def delete_notification(self) -> None:
"""Delete the active Plugwise Notification."""
await self.call_request(NOTIFICATIONS, method="delete")
@@ -189,7 +181,7 @@ async def set_number(
uri = f"{APPLIANCES};id={self._heater_id}/thermostat;id={thermostat_id}"
data = f"{temp}"
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_offset(self, dev_id: str, offset: float) -> None:
"""Set the Temperature offset for thermostats that support this feature."""
@@ -202,7 +194,7 @@ async def set_offset(self, dev_id: str, offset: float) -> None:
uri = f"{APPLIANCES};id={dev_id}/offset;type=temperature_offset"
data = f"{value}"
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_preset(self, loc_id: str, preset: str) -> None:
"""Set the given Preset on the relevant Thermostat - from LOCATIONS."""
@@ -222,7 +214,7 @@ async def set_preset(self, loc_id: str, preset: str) -> None:
f"{preset}"
)
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_select(self, key: str, loc_id: str, option: str, state: str | None) -> None:
"""Set a dhw/gateway/regulation mode or the thermostat schedule option."""
@@ -245,7 +237,7 @@ async def set_dhw_mode(self, mode: str) -> None:
uri = f"{APPLIANCES};type=heater_central/domestic_hot_water_mode_control"
data = f"{mode}"
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_gateway_mode(self, mode: str) -> None:
"""Set the gateway mode."""
@@ -268,7 +260,7 @@ async def set_gateway_mode(self, mode: str) -> None:
uri = f"{APPLIANCES};id={self.gateway_id}/gateway_mode_control"
data = f"{mode}{valid}"
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_regulation_mode(self, mode: str) -> None:
"""Set the heating regulation mode."""
@@ -281,7 +273,7 @@ async def set_regulation_mode(self, mode: str) -> None:
duration = "300"
data = f"{duration}{mode}"
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_schedule_state(
self,
@@ -335,7 +327,7 @@ async def set_schedule_state(
f"{template}{contexts}"
)
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
self._schedule_old_states[loc_id][name] = new_state
def determine_contexts(
@@ -404,7 +396,7 @@ async def set_switch_state(
if self._domain_objects.find(locator).text == "true":
raise PlugwiseError("Plugwise: the locked Relay was not switched.")
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def _set_groupswitch_member_state(
self, members: list[str], state: str, switch: Munch
@@ -419,7 +411,7 @@ async def _set_groupswitch_member_state(
uri = f"{APPLIANCES};id={member}/{switch.device};id={switch_id}"
data = f"<{switch.func_type}><{switch.func}>{state}{switch.func}>{switch.func_type}>"
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
async def set_temperature(self, loc_id: str, items: dict[str, float]) -> None:
"""Set the given Temperature on the relevant Thermostat."""
@@ -460,4 +452,13 @@ async def set_temperature(self, loc_id: str, items: dict[str, float]) -> None:
f"{temperature}"
)
- await self._request(uri, method="put", data=data)
+ await self.call_request(uri, method="put", data=data)
+
+ async def call_request(self, uri: str, **kwargs: Any) -> None:
+ """ConnectionFailedError wrapper for calling _request()."""
+ method: str = kwargs["method"]
+ data: str | None = kwargs.get("data")
+ try:
+ await self._request(uri, method=method, data=data)
+ except ConnectionFailedError as exc:
+ raise ConnectionFailedError from exc
diff --git a/pyproject.toml b/pyproject.toml
index 8b0a29d33..e8cfc8121 100644
--- a/pyproject.toml
+++ b/pyproject.toml
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
[project]
name = "plugwise"
-version = "0.38.0"
+version = "0.38.1"
license = {file = "LICENSE"}
description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3."
readme = "README.md"
diff --git a/tests/test_adam.py b/tests/test_adam.py
index 17c2d563d..0a97cb10f 100644
--- a/tests/test_adam.py
+++ b/tests/test_adam.py
@@ -63,7 +63,7 @@ async def test_connect_adam_zone_per_device(self):
await self.disconnect(server, client)
server, smile, client = await self.connect_wrapper(raise_timeout=True)
- await self.device_test(smile, "2022-05-16 00:00:01", testdata)
+ await self.device_test(smile, "2022-05-16 00:00:01", testdata, skip_testing=True)
result = await self.tinker_thermostat(
smile,
"c50f167537524366a5af7aa3942feb1e",
@@ -79,15 +79,18 @@ async def test_connect_adam_zone_per_device(self):
)
assert result
+ tinkered = await self.tinker_max_boiler_temp(smile, unhappy=True)
+ assert not tinkered
+
try:
await smile.delete_notification()
notification_deletion = False # pragma: no cover
- except pw_exceptions.PlugwiseError:
+ except pw_exceptions.ConnectionFailedError:
notification_deletion = True
assert notification_deletion
reboot = await self.tinker_reboot(smile, unhappy=True)
- assert not reboot
+ assert reboot
await smile.close_connection()
await self.disconnect(server, client)
@@ -212,7 +215,7 @@ async def test_connect_adam_plus_anna(self):
await self.disconnect(server, client)
server, smile, client = await self.connect_wrapper(raise_timeout=True)
- await self.device_test(smile, "2020-03-22 00:00:01", testdata)
+ await self.device_test(smile, "2020-03-22 00:00:01", testdata, skip_testing=True)
result = await self.tinker_thermostat(
smile,
"009490cc2f674ce6b576863fbb64f867",
@@ -322,9 +325,14 @@ async def test_connect_adam_plus_anna_new(self):
)
assert not switch_change
- await self.tinker_gateway_mode(smile)
- await self.tinker_regulation_mode(smile)
- await self.tinker_max_boiler_temp(smile)
+ tinkered = await self.tinker_gateway_mode(smile)
+ assert not tinkered
+
+ tinkered = await self.tinker_regulation_mode(smile)
+ assert not tinkered
+
+ tinkered = await self.tinker_max_boiler_temp(smile)
+ assert not tinkered
# Now change some data and change directory reading xml from
# emulating reading newer dataset after an update_interval
@@ -353,6 +361,23 @@ async def test_connect_adam_plus_anna_new(self):
await smile.close_connection()
await self.disconnect(server, client)
+ self.smile_setup = "adam_plus_anna_new"
+ testdata = self.load_testdata(SMILE_TYPE, self.smile_setup)
+ server, smile, client = await self.connect_wrapper(raise_timeout=True)
+ await self.device_test(smile, "2023-12-17 00:00:01", testdata, skip_testing=True)
+
+ tinkered = await self.tinker_max_boiler_temp(smile, unhappy=True)
+ assert tinkered
+
+ tinkered = await self.tinker_gateway_mode(smile, unhappy=True)
+ assert tinkered
+
+ tinkered = await self.tinker_regulation_mode(smile, unhappy=True)
+ assert tinkered
+
+ await smile.close_connection()
+ await self.disconnect(server, client)
+
@pytest.mark.asyncio
async def test_adam_plus_jip(self):
"""Test Adam with Jip setup."""
diff --git a/tests/test_anna.py b/tests/test_anna.py
index c2b9d9bd5..a05cd48a2 100644
--- a/tests/test_anna.py
+++ b/tests/test_anna.py
@@ -70,7 +70,7 @@ async def test_connect_anna_v4(self):
server, smile, client = await self.connect_wrapper(raise_timeout=True)
# Reset self.smile_setup
self.smile_setup = "anna_v4"
- await self.device_test(smile, "2020-04-05 00:00:01", testdata)
+ await self.device_test(smile, "2020-04-05 00:00:01", testdata, skip_testing=True)
result = await self.tinker_thermostat(
smile,
"eb5309212bf5407bb143e5bfa3b18aee",
@@ -79,6 +79,12 @@ async def test_connect_anna_v4(self):
unhappy=True,
)
assert result
+
+ result = await self.tinker_temp_offset(
+ smile, "01b85360fdd243d0aaad4d6ac2a5ba7e", unhappy=True,
+ )
+ assert result
+
await smile.close_connection()
await self.disconnect(server, client)
@@ -458,11 +464,22 @@ async def test_connect_anna_loria_heating_idle(self):
"ERROR raised setting block cooling: %s", exc.value
) # pragma: no cover
- await self.tinker_dhw_mode(smile)
+ tinkered = await self.tinker_dhw_mode(smile)
+ assert not tinkered
await smile.close_connection()
await self.disconnect(server, client)
+ server, smile, client = await self.connect_wrapper(raise_timeout=True)
+ await self.device_test(smile, "2022-05-16 00:00:01", testdata, skip_testing=True)
+
+ tinkered = await self.tinker_dhw_mode(smile, unhappy=True)
+ assert tinkered
+
+ await smile.close_connection()
+ await self.disconnect(server, client)
+
+
@pytest.mark.asyncio
async def test_connect_anna_loria_cooling_active(self):
"""Test an Anna with a Loria in heating mode - state idle."""
diff --git a/tests/test_init.py b/tests/test_init.py
index 3407a67a0..b6c0dc47f 100644
--- a/tests/test_init.py
+++ b/tests/test_init.py
@@ -536,6 +536,7 @@ async def device_test(
test_time=None,
testdata=None,
initialize=True,
+ skip_testing=False,
):
"""Perform basic device tests."""
bsw_list = ["binary_sensors", "central", "climate", "sensors", "switches"]
@@ -588,6 +589,9 @@ async def device_test(
_LOGGER.info("Device list = %s", data.devices)
self.show_setup(location_list, data.devices)
+ if skip_testing:
+ return
+
# Perform tests and asserts
tests = 0
asserts = 0
@@ -644,10 +648,10 @@ async def tinker_reboot(self, smile, unhappy=False):
await smile.reboot_gateway()
_LOGGER.info(" + worked as intended")
return True
- except pw_exceptions.PlugwiseError:
+ except pw_exceptions.ConnectionFailedError:
if unhappy:
_LOGGER.info(" + failed as expected")
- return False
+ return True
else: # pragma: no cover
_LOGGER.info(" - failed unexpectedly")
return False
@@ -659,8 +663,8 @@ async def tinker_switch(
"""Turn a Switch on and off to test functionality."""
_LOGGER.info("Asserting modifying settings for switch devices:")
_LOGGER.info("- Devices (%s):", dev_id)
+ tinker_switch_passed = False
for new_state in ["false", "true", "false"]:
- tinker_switch_passed = False
_LOGGER.info("- Switching %s", new_state)
try:
await smile.set_switch_state(dev_id, members, model, new_state)
@@ -669,9 +673,9 @@ async def tinker_switch(
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + locked, not switched as expected")
return False
- except pw_exceptions.ConnectionFailedError:
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
if unhappy:
- tinker_switch_passed = True # test is pass!
+ return True # test is pass!
_LOGGER.info(" + failed as expected")
else: # pragma: no cover
_LOGGER.info(" - failed unexpectedly")
@@ -697,18 +701,18 @@ async def tinker_thermostat_temp(
except pw_exceptions.ConnectionFailedError:
if unhappy:
_LOGGER.info(" + tinker_thermostat_temp failed as expected")
- tinker_temp_passed = True
+ return True
else: # pragma: no cover
_LOGGER.info(" - tinker_thermostat_temp failed unexpectedly")
- tinker_temp_passed = False
+ return False
return tinker_temp_passed
@pytest.mark.asyncio
async def tinker_thermostat_preset(self, smile, loc_id, unhappy=False):
"""Toggle preset to test functionality."""
+ tinker_preset_passed = False
for new_preset in ["asleep", "home", BOGUS]:
- tinker_preset_passed = False
warning = ""
if new_preset[0] == "!":
warning = " TTP Negative test"
@@ -721,10 +725,10 @@ async def tinker_thermostat_preset(self, smile, loc_id, unhappy=False):
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + found invalid preset, as expected")
tinker_preset_passed = True
- except pw_exceptions.ConnectionFailedError:
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
if unhappy:
- tinker_preset_passed = True
_LOGGER.info(" + tinker_thermostat_preset failed as expected")
+ return True
else: # pragma: no cover
_LOGGER.info(" - tinker_thermostat_preset failed unexpectedly")
return False
@@ -740,8 +744,9 @@ async def tinker_thermostat_schedule(
if good_schedules != []:
if not single and ("!VeryBogusSchedule" not in good_schedules):
good_schedules.append("!VeryBogusSchedule")
+
+ tinker_schedule_passed = False
for new_schedule in good_schedules:
- tinker_schedule_passed = False
warning = ""
if new_schedule is not None and new_schedule[0] == "!":
warning = " TTS Negative test"
@@ -754,11 +759,11 @@ async def tinker_thermostat_schedule(
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + failed as expected")
tinker_schedule_passed = True
- except pw_exceptions.ConnectionFailedError:
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
tinker_schedule_passed = False
if unhappy:
_LOGGER.info(" + failed as expected before intended failure")
- tinker_schedule_passed = True
+ return True
else: # pragma: no cover
_LOGGER.info(" - succeeded unexpectedly for some reason")
return False
@@ -772,6 +777,7 @@ async def tinker_thermostat_schedule(
async def tinker_legacy_thermostat_schedule(self, smile, unhappy=False):
"""Toggle schedules to test functionality."""
states = ["on", "off", "!Bogus"]
+ tinker_schedule_passed = False
for state in states:
_LOGGER.info("- Adjusting schedule to state %s", state)
try:
@@ -781,11 +787,11 @@ async def tinker_legacy_thermostat_schedule(self, smile, unhappy=False):
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + failed as expected")
tinker_schedule_passed = True
- except pw_exceptions.ConnectionFailedError:
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
tinker_schedule_passed = False
if unhappy:
_LOGGER.info(" + failed as expected before intended failure")
- tinker_schedule_passed = True
+ return True
else: # pragma: no cover
_LOGGER.info(" - succeeded unexpectedly for some reason")
return False
@@ -833,7 +839,7 @@ async def tinker_legacy_thermostat(
smile,
schedule_on=True,
block_cooling=False,
- unhappy=False
+ unhappy=False,
):
"""Toggle various climate settings to test functionality."""
result_1 = await self.tinker_thermostat_temp(
@@ -847,8 +853,9 @@ async def tinker_legacy_thermostat(
return result_1 and result_2 and result_3
@staticmethod
- async def tinker_dhw_mode(smile):
+ async def tinker_dhw_mode(smile, unhappy=False):
"""Toggle dhw to test functionality."""
+ tinker_dhw_mode_passed = False
for mode in ["auto", "boost", BOGUS]:
warning = ""
if mode[0] == "!":
@@ -858,12 +865,24 @@ async def tinker_dhw_mode(smile):
try:
await smile.set_select("select_dhw_mode", "dummy", mode)
_LOGGER.info(" + tinker_dhw_mode worked as intended")
+ tinker_dhw_mode_passed = True
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + tinker_dhw_mode found invalid mode, as expected")
+ tinker_dhw_mode_passed = False
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
+ if unhappy:
+ _LOGGER.info(" + failed as expected before intended failure")
+ return True
+ else: # pragma: no cover
+ _LOGGER.info(" - succeeded unexpectedly for some reason")
+ return False
+
+ return tinker_dhw_mode_passed
@staticmethod
- async def tinker_regulation_mode(smile):
+ async def tinker_regulation_mode(smile, unhappy=False):
"""Toggle regulation_mode to test functionality."""
+ tinker_reg_mode_passed = False
for mode in ["off", "heating", "bleeding_cold", BOGUS]:
warning = ""
if mode[0] == "!":
@@ -873,25 +892,49 @@ async def tinker_regulation_mode(smile):
try:
await smile.set_select("select_regulation_mode", "dummy", mode)
_LOGGER.info(" + tinker_regulation_mode worked as intended")
+ tinker_reg_mode_passed = True
except pw_exceptions.PlugwiseError:
_LOGGER.info(
" + tinker_regulation_mode found invalid mode, as expected"
)
+ tinker_reg_mode_passed = False
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
+ if unhappy:
+ _LOGGER.info(" + failed as expected before intended failure")
+ return True
+ else: # pragma: no cover
+ _LOGGER.info(" - succeeded unexpectedly for some reason")
+ return False
+
+ return tinker_reg_mode_passed
@staticmethod
- async def tinker_max_boiler_temp(smile):
+ async def tinker_max_boiler_temp(smile, unhappy=False):
"""Change max boiler temp setpoint to test functionality."""
+ tinker_max_boiler_temp_passed = False
new_temp = 60.0
_LOGGER.info("- Adjusting temperature to %s", new_temp)
for test in ["maximum_boiler_temperature", "bogus_temperature"]:
+ _LOGGER.info(" + for %s", test)
try:
await smile.set_number("dummy", test, new_temp)
_LOGGER.info(" + tinker_max_boiler_temp worked as intended")
+ tinker_max_boiler_temp_passed = True
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + tinker_max_boiler_temp failed as intended")
+ tinker_max_boiler_temp_passed = False
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
+ if unhappy:
+ _LOGGER.info(" + failed as expected before intended failure")
+ return True
+ else: # pragma: no cover
+ _LOGGER.info(" - succeeded unexpectedly for some reason")
+ return False
+
+ return tinker_max_boiler_temp_passed
@staticmethod
- async def tinker_temp_offset(smile, dev_id):
+ async def tinker_temp_offset(smile, dev_id, unhappy=False):
"""Change temperature_offset to test functionality."""
new_offset = 1.0
_LOGGER.info("- Adjusting temperature offset to %s", new_offset)
@@ -902,10 +945,18 @@ async def tinker_temp_offset(smile, dev_id):
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + tinker_temp_offset failed as intended")
return False
+ except pw_exceptions.ConnectionFailedError:
+ if unhappy:
+ _LOGGER.info(" + failed as expected before intended failure")
+ return True
+ else: # pragma: no cover
+ _LOGGER.info(" - succeeded unexpectedly for some reason")
+ return False
@staticmethod
- async def tinker_gateway_mode(smile):
+ async def tinker_gateway_mode(smile, unhappy=False):
"""Toggle gateway_mode to test functionality."""
+ tinker_gateway_mode_passed = False
for mode in ["away", "full", "vacation", "!bogus"]:
warning = ""
if mode[0] == "!":
@@ -915,8 +966,19 @@ async def tinker_gateway_mode(smile):
try:
await smile.set_select("select_gateway_mode", "dummy", mode)
_LOGGER.info(" + worked as intended")
+ tinker_gateway_mode_passed = True
except pw_exceptions.PlugwiseError:
_LOGGER.info(" + found invalid mode, as expected")
+ tinker_gateway_mode_passed = False
+ except pw_exceptions.ConnectionFailedError: # leave for-loop at connect-error
+ if unhappy:
+ _LOGGER.info(" + failed as expected before intended failure")
+ return True
+ else: # pragma: no cover
+ _LOGGER.info(" - succeeded unexpectedly for some reason")
+ return False
+
+ return tinker_gateway_mode_passed
@staticmethod
def validate_test_basics(
diff --git a/tests/test_legacy_anna.py b/tests/test_legacy_anna.py
index cf6a62a70..2475aff83 100644
--- a/tests/test_legacy_anna.py
+++ b/tests/test_legacy_anna.py
@@ -39,7 +39,7 @@ async def test_connect_legacy_anna(self):
await self.disconnect(server, client)
server, smile, client = await self.connect_legacy_wrapper(raise_timeout=True)
- await self.device_test(smile, "2020-03-22 00:00:01", testdata)
+ await self.device_test(smile, "2020-03-22 00:00:01", testdata, skip_testing=True)
result = await self.tinker_legacy_thermostat(smile, unhappy=True)
assert result
await smile.close_connection()