diff --git a/CHANGELOG.md b/CHANGELOG.md index 967f18b15..0e9ad0160 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v1.4.2 + +- Improve timeout setting: set it to 30s for the Stretch, to 10s for all other devices. + ## v1.4.1 - Prettying documents with Biome (CLI), fixture layout updated accordingly. diff --git a/plugwise/__init__.py b/plugwise/__init__.py index b1aac2301..3a481126f 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -5,9 +5,7 @@ from __future__ import annotations from plugwise.constants import ( - DEFAULT_LEGACY_TIMEOUT, DEFAULT_PORT, - DEFAULT_TIMEOUT, DEFAULT_USERNAME, DOMAIN_OBJECTS, LOGGER, @@ -47,7 +45,6 @@ def __init__( websession: aiohttp.ClientSession, username: str = DEFAULT_USERNAME, port: int = DEFAULT_PORT, - timeout: float = DEFAULT_LEGACY_TIMEOUT, ) -> None: """Set the constructor for this class.""" @@ -57,15 +54,13 @@ def __init__( websession, username, port, - timeout, ) self._host = host self._passwd = password self._websession = websession - self._user = username + self._username = username self._port = port - self._timeout = timeout self._cooling_present = False self._elga = False @@ -130,7 +125,6 @@ async def connect(self) -> bool: self._smile_api = SmileAPI( self._host, self._passwd, - self._timeout, self._websession, self._cooling_present, self._elga, @@ -149,12 +143,11 @@ async def connect(self) -> bool: self.smile_model_id, self.smile_name, self.smile_type, - self._user, + self._username, self._port, ) if not self.smile_legacy else SmileLegacyAPI( self._host, self._passwd, - self._timeout, self._websession, self._is_thermostat, self._on_off_device, @@ -170,7 +163,7 @@ async def connect(self) -> bool: self.smile_name, self.smile_type, self.smile_zigbee_mac_address, - self._user, + self._username, self._port, ) @@ -196,9 +189,6 @@ async def _smile_detect(self, result: etree, dsmrmain: etree) -> None: else: model = await self._smile_detect_legacy(result, dsmrmain, model) - if not self.smile_legacy: - self._timeout = DEFAULT_TIMEOUT - if model == "Unknown" or self.smile_fw_version is None: # pragma: no cover # Corner case check LOGGER.error( diff --git a/plugwise/helper.py b/plugwise/helper.py index bea10938e..1f679c0b8 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -16,6 +16,9 @@ ANNA, ATTR_NAME, DATA, + DEFAULT_LEGACY_TIMEOUT, + DEFAULT_TIMEOUT, + DEFAULT_USERNAME, DEVICE_MEASUREMENTS, DHW_SETPOINT, DOMAIN_OBJECTS, @@ -74,9 +77,12 @@ def __init__( websession: ClientSession | None, username: str, port: int, - timeout: float, ) -> None: """Set the constructor for this class.""" + timeout = DEFAULT_TIMEOUT + if username != DEFAULT_USERNAME: + timeout = DEFAULT_LEGACY_TIMEOUT + if not websession: aio_timeout = ClientTimeout(total=timeout) diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index c50e65637..642bbd951 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -41,7 +41,6 @@ version_to_model, ) -# This way of importing aiohttp is because of patch/mocking in testing (aiohttp timeouts) from defusedxml import ElementTree as etree from munch import Munch diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 710ea5901..2e3d37a68 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -40,7 +40,6 @@ def __init__( self, host: str, password: str, - timeout: float, websession: aiohttp.ClientSession, _is_thermostat: bool, _on_off_device: bool, @@ -66,7 +65,6 @@ def __init__( websession, username, port, - timeout, ) SmileLegacyData.__init__(self) @@ -76,7 +74,6 @@ def __init__( self._opentherm_device = _opentherm_device self._stretch_v2 = _stretch_v2 self._target_smile = _target_smile - self._timeout = timeout self.loc_data = loc_data self.smile_fw_version = smile_fw_version self.smile_hostname = smile_hostname diff --git a/plugwise/smile.py b/plugwise/smile.py index 1807ca5cd..055bd466a 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -46,7 +46,6 @@ def __init__( self, host: str, password: str, - timeout: float, websession: aiohttp.ClientSession, _cooling_present: bool, _elga: bool, @@ -75,7 +74,6 @@ def __init__( websession, username, port, - timeout, ) SmileData.__init__(self) @@ -86,7 +84,6 @@ def __init__( self._on_off_device = _on_off_device self._opentherm_device = _opentherm_device self._schedule_old_states = _schedule_old_states - self._timeout = timeout self.gateway_id = gateway_id self.loc_data = loc_data self.smile_fw_version = smile_fw_version diff --git a/pyproject.toml b/pyproject.toml index 64e81edae..5022b54d5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.4.1" +version = "1.4.2a0" license = {file = "LICENSE"} description = "Plugwise Smile (Adam/Anna/P1) and Stretch module for Python 3." readme = "README.md" diff --git a/tests/test_init.py b/tests/test_init.py index ba437a561..da1476bdd 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -87,7 +87,6 @@ async def setup_app( timeout=False, raise_timeout=False, fail_auth=False, - stretch=False, ): """Create mock webserver for Smile to interface with.""" app = aiohttp.web.Application() @@ -279,7 +278,6 @@ async def connect( timeout=False, raise_timeout=False, fail_auth=False, - stretch=False, ): """Connect to a smile environment and perform basic asserts.""" port = aiohttp.test_utils.unused_port() @@ -288,7 +286,7 @@ async def connect( ) # Happy flow - app = await self.setup_app(broken, timeout, raise_timeout, fail_auth, stretch) + app = await self.setup_app(broken, timeout, raise_timeout, fail_auth) server = aiohttp.test_utils.TestServer( app, port=port, scheme="http", host="127.0.0.1" @@ -339,7 +337,7 @@ async def connect( ) if not timeout: - assert smile._timeout == 30 + assert smile._timeout == 10 # Connect to the smile try: @@ -367,6 +365,9 @@ async def connect_legacy( test_password = "".join( secrets.choice(string.ascii_lowercase) for _ in range(8) ) + user_name = pw_constants.DEFAULT_USERNAME + if stretch: + user_name = pw_constants.STRETCH # Happy flow app = await self.setup_legacy_app(broken, timeout, raise_timeout, fail_auth, stretch) @@ -400,7 +401,7 @@ async def connect_legacy( try: smile = pw_smile.Smile( host=server.host, - username=pw_constants.DEFAULT_USERNAME, + username=user_name, password=test_password, port=server.port, websession=None, @@ -413,14 +414,17 @@ async def connect_legacy( smile = pw_smile.Smile( host=server.host, - username=pw_constants.DEFAULT_USERNAME, + username=user_name, password=test_password, port=server.port, websession=websession, ) if not timeout: - assert smile._timeout == 30 + if user_name == pw_constants.STRETCH: + assert smile._timeout == 30 + else: + assert smile._timeout == 10 # Connect to the smile try: @@ -437,7 +441,7 @@ async def connect_legacy( # Wrap connect for invalid connections async def connect_wrapper( - self, raise_timeout=False, fail_auth=False, stretch=False + self, raise_timeout=False, fail_auth=False, ): """Wrap connect to try negative testing before positive testing.""" if fail_auth: @@ -471,7 +475,7 @@ async def connect_wrapper( _LOGGER.info(" + successfully passed XML issue handling.") _LOGGER.info("Connecting to functioning device:") - return await self.connect(stretch=stretch) + return await self.connect() async def connect_legacy_wrapper( self, raise_timeout=False, fail_auth=False, stretch=False @@ -479,19 +483,19 @@ async def connect_legacy_wrapper( """Wrap connect to try negative testing before positive testing.""" if raise_timeout: _LOGGER.warning("Connecting to device exceeding timeout in handling:") - return await self.connect_legacy(raise_timeout=True) + return await self.connect_legacy(raise_timeout=True, stretch=stretch) try: _LOGGER.warning("Connecting to device exceeding timeout in response:") - await self.connect_legacy(timeout=True) + await self.connect_legacy(timeout=True, stretch=stretch) _LOGGER.error(" - timeout not handled") # pragma: no cover raise self.ConnectError # pragma: no cover except pw_exceptions.ConnectionFailedError: _LOGGER.info(" + successfully passed timeout handling.") try: - _LOGGER.warning("Connecting to device with missing data:") - await self.connect_legacy(broken=True) + _LOGGER.warning("Connecting to device, with missing data:") + await self.connect_legacy(broken=True, stretch=stretch) _LOGGER.error(" - broken information not handled") # pragma: no cover raise self.ConnectError # pragma: no cover except pw_exceptions.InvalidXMLError: @@ -552,7 +556,10 @@ async def device_test( await smile.full_update_device() smile.get_all_devices() data = await smile.async_update() - assert smile._timeout == 30 + if smile._username == pw_constants.STRETCH: + assert smile._timeout == 30 + else: + assert smile._timeout == 10 else: data = await smile.async_update() assert smile._timeout == 10