diff --git a/CHANGELOG.md b/CHANGELOG.md index c4f9d8736..3a13d7cfa 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## v1.4.4 + +- Change connect() function to output the gateway firmware-version. + ## v1.4.3 - Clean up timeout-related, pass _request-function as an argument. diff --git a/plugwise/__init__.py b/plugwise/__init__.py index 6e08c09ae..977220987 100644 --- a/plugwise/__init__.py +++ b/plugwise/__init__.py @@ -31,6 +31,7 @@ import aiohttp from defusedxml import ElementTree as etree +from packaging.version import Version, parse class Smile(SmileComm): @@ -75,7 +76,7 @@ def __init__( self._target_smile: str = NONE self.gateway_id: str = NONE self.loc_data: dict[str, ThermoLoc] = {} - self.smile_fw_version: str | None = None + self.smile_fw_version: Version | None = None self.smile_hostname: str = NONE self.smile_hw_version: str | None = None self.smile_legacy = False @@ -84,10 +85,10 @@ def __init__( self.smile_model_id: str | None = None self.smile_name: str = NONE self.smile_type: str = NONE - self.smile_version: str = NONE + self.smile_version: Version | None = None self.smile_zigbee_mac_address: str | None = None - async def connect(self) -> bool: + async def connect(self) -> Version | None: """Connect to Plugwise device and determine its name, type and version.""" result = await self._request(DOMAIN_OBJECTS) # Work-around for Stretch fw 2.7.18 @@ -173,7 +174,7 @@ async def connect(self) -> bool: # Update all endpoints on first connect await self._smile_api.full_update_device() - return True + return self.smile_version async def _smile_detect(self, result: etree, dsmrmain: etree) -> None: """Helper-function for connect(). @@ -184,7 +185,7 @@ async def _smile_detect(self, result: etree, dsmrmain: etree) -> None: if (gateway := result.find("./gateway")) is not None: if (v_model := gateway.find("vendor_model")) is not None: model = v_model.text - self.smile_fw_version = gateway.find("firmware_version").text + self.smile_fw_version = parse(gateway.find("firmware_version").text) self.smile_hw_version = gateway.find("hardware_version").text self.smile_hostname = gateway.find("hostname").text self.smile_mac_address = gateway.find("mac_address").text @@ -200,7 +201,7 @@ async def _smile_detect(self, result: etree, dsmrmain: etree) -> None: ) raise UnsupportedDeviceError - version_major: str = self.smile_fw_version.split(".", 1)[0] + version_major= str(self.smile_fw_version.major) self._target_smile = f"{model}_v{version_major}" LOGGER.debug("Plugwise identified as %s", self._target_smile) if self._target_smile not in SMILES: @@ -267,7 +268,7 @@ async def _smile_detect_legacy( or network is not None ): system = await self._request(SYSTEM) - self.smile_fw_version = system.find("./gateway/firmware").text + self.smile_fw_version = parse(system.find("./gateway/firmware").text) return_model = system.find("./gateway/product").text self.smile_hostname = system.find("./gateway/hostname").text # If wlan0 contains data it's active, so eth0 should be checked last @@ -278,7 +279,7 @@ async def _smile_detect_legacy( # P1 legacy: elif dsmrmain is not None: status = await self._request(STATUS) - self.smile_fw_version = status.find("./system/version").text + self.smile_fw_version = parse(status.find("./system/version").text) return_model = status.find("./system/product").text self.smile_hostname = status.find("./network/hostname").text self.smile_mac_address = status.find("./network/mac_address").text diff --git a/plugwise/helper.py b/plugwise/helper.py index 2ddb61d46..da8cddbec 100644 --- a/plugwise/helper.py +++ b/plugwise/helper.py @@ -62,6 +62,7 @@ from dateutil.parser import parse from defusedxml import ElementTree as etree from munch import Munch +from packaging.version import Version class SmileComm: @@ -250,7 +251,7 @@ def __init__(self) -> None: self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} self.loc_data: dict[str, ThermoLoc] - self.smile_fw_version: str | None + self.smile_fw_version: Version | None self.smile_hw_version: str | None self.smile_mac_address: str | None self.smile_model: str @@ -425,7 +426,7 @@ def _energy_device_info_finder(self, appl: Munch, appliance: etree) -> Munch: def _appl_gateway_info(self, appl: Munch, appliance: etree) -> Munch: """Helper-function for _appliance_info_finder().""" self.gateway_id = appliance.attrib["id"] - appl.firmware = self.smile_fw_version + appl.firmware = str(self.smile_fw_version) appl.hardware = self.smile_hw_version appl.mac = self.smile_mac_address appl.model = self.smile_model diff --git a/plugwise/legacy/helper.py b/plugwise/legacy/helper.py index efce1db13..a82b7005b 100644 --- a/plugwise/legacy/helper.py +++ b/plugwise/legacy/helper.py @@ -44,6 +44,7 @@ # This way of importing aiohttp is because of patch/mocking in testing (aiohttp timeouts) from defusedxml import ElementTree as etree from munch import Munch +from packaging.version import Version def etree_to_dict(element: etree) -> dict[str, str]: @@ -81,7 +82,7 @@ def __init__(self) -> None: self.gw_data: GatewayData = {} self.gw_devices: dict[str, DeviceData] = {} self.loc_data: dict[str, ThermoLoc] - self.smile_fw_version: str | None + self.smile_fw_version: Version | None self.smile_hw_version: str | None self.smile_mac_address: str | None self.smile_model: str @@ -194,7 +195,7 @@ def _create_legacy_gateway(self) -> None: self.gw_devices[self.gateway_id] = {"dev_class": "gateway"} self._count += 1 for key, value in { - "firmware": self.smile_fw_version, + "firmware": str(self.smile_fw_version), "location": self._home_location, "mac_address": self.smile_mac_address, "model": self.smile_model, diff --git a/plugwise/legacy/smile.py b/plugwise/legacy/smile.py index 3f8a14f0f..a1813105a 100644 --- a/plugwise/legacy/smile.py +++ b/plugwise/legacy/smile.py @@ -29,6 +29,7 @@ import aiohttp from munch import Munch +from packaging.version import Version class SmileLegacyAPI(SmileLegacyData): @@ -48,7 +49,7 @@ def __init__( _stretch_v2: bool, _target_smile: str, loc_data: dict[str, ThermoLoc], - smile_fw_version: str | None, + smile_fw_version: Version | None, smile_hostname: str, smile_hw_version: str | None, smile_mac_address: str | None, diff --git a/plugwise/smile.py b/plugwise/smile.py index d7b42f760..9a725a470 100644 --- a/plugwise/smile.py +++ b/plugwise/smile.py @@ -35,6 +35,7 @@ # Dict as class from munch import Munch +from packaging.version import Version class SmileAPI(SmileData): @@ -57,7 +58,7 @@ def __init__( _schedule_old_states: dict[str, dict[str, str]], gateway_id: str, loc_data: dict[str, ThermoLoc], - smile_fw_version: str | None, + smile_fw_version: Version | None, smile_hostname: str | None, smile_hw_version: str | None, smile_mac_address: str | None, diff --git a/pyproject.toml b/pyproject.toml index 0ccc17d2d..742a72cf8 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta" [project] name = "plugwise" -version = "1.4.3" +version = "1.4.4" 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 f07de3ab1..823e04a64 100644 --- a/tests/test_init.py +++ b/tests/test_init.py @@ -17,6 +17,7 @@ # Testing import aiohttp from freezegun import freeze_time +from packaging import version pw_constants = importlib.import_module("plugwise.constants") pw_exceptions = importlib.import_module("plugwise.exceptions") @@ -344,15 +345,17 @@ async def connect( assert smile._timeout == 10 # Connect to the smile + version = None try: - connection_state = await smile.connect() - assert connection_state + version = await smile.connect() + assert version is not None return server, smile, client except ( pw_exceptions.ConnectionFailedError, pw_exceptions.InvalidXMLError, pw_exceptions.InvalidAuthentication, ) as exception: + assert version is None await self.disconnect(server, client) raise exception @@ -427,15 +430,17 @@ async def connect_legacy( assert smile._timeout == 30 # Connect to the smile + version = None try: - connection_state = await smile.connect() - assert connection_state + version = await smile.connect() + assert version is not None return server, smile, client except ( pw_exceptions.ConnectionFailedError, pw_exceptions.InvalidXMLError, pw_exceptions.InvalidAuthentication, ) as exception: + assert version is None await self.disconnect(server, client) raise exception @@ -1004,7 +1009,7 @@ def validate_test_basics( if smile_version: log_msg = f" # Assert version matching '{smile_version}" parent_logger.info(log_msg) - assert smile.smile_version == smile_version + assert smile.smile_version == version.parse(smile_version) log_msg = f" # Assert legacy {smile_legacy}" parent_logger.info(log_msg) if smile_legacy: