From 54eeece4b1e72d90f373cf9e9282fc3422274ab9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 May 2026 19:58:15 +0200 Subject: [PATCH 01/54] Link to plugwise_usb v0.47.7 --- custom_components/plugwise_usb/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/plugwise_usb/manifest.json b/custom_components/plugwise_usb/manifest.json index 1b14d83a..888d22bf 100644 --- a/custom_components/plugwise_usb/manifest.json +++ b/custom_components/plugwise_usb/manifest.json @@ -9,6 +9,6 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/plugwise/python-plugwise-usb/issues", "loggers": ["plugwise_usb"], - "requirements": ["plugwise-usb==0.47.6"], + "requirements": ["plugwise-usb==0.47.7"], "version": "0.59.2" } From bfd59a99fa39dd24c6fb6094e552353963f2f689 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 May 2026 19:58:57 +0200 Subject: [PATCH 02/54] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 2f8a8aa3..a3a567b2 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,6 +3,7 @@ ## Ongoing - Bump python to 3.14 +- Link to plugwise_usb [v0.47.7](https://github.com/plugwise/python-plugwise-usb/releases/tag/v0.47.7) ## v0.59.2 From a01661ab577ffa64e5a40a1799c74ba61d758897 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Mon, 18 May 2026 20:15:10 +0200 Subject: [PATCH 03/54] Try fix testcase --- custom_components/plugwise_usb/config_flow.py | 16 +++++----- tests/test_config_flow.py | 31 ++++++++++++------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index a1647b90..0f8fdf30 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -9,11 +9,11 @@ import voluptuous as vol from homeassistant.components import usb +from homeassistant.components.usb import USBDevice from homeassistant.config_entries import SOURCE_USER, ConfigFlow, ConfigFlowResult from homeassistant.const import CONF_BASE from homeassistant.core import callback from homeassistant.data_entry_flow import FlowResult -import serial.tools.list_ports from .const import CONF_MANUAL_PATH, CONF_USB_PATH, DOMAIN, MANUAL_PATH @@ -72,11 +72,11 @@ async def async_step_user( ) -> FlowResult: """Step when user initializes a integration.""" errors: dict[str, str] = {} - ports = await self.hass.async_add_executor_job(serial.tools.list_ports.comports) list_of_ports = [ - f"{p}, s/n: {p.serial_number or 'n/a'}" - + (f" - {p.manufacturer}" if p.manufacturer else "") - for p in ports + f"{port.device}, s/n: {port.serial_number or 'n/a'}" + + (f" - {port.manufacturer}" if port.manufacturer else "") + for port in await usb.async_scan_serial_ports(self.hass) + if isinstance(port, usb.USBDevice) ] list_of_ports.append(CONF_MANUAL_PATH) @@ -86,10 +86,8 @@ async def async_step_user( if user_selection == CONF_MANUAL_PATH: return await self.async_step_manual_path() - port = ports[list_of_ports.index(user_selection)] - device_path = await self.hass.async_add_executor_job( - usb.get_serial_by_id, port.device - ) + port = list_of_ports.index(user_selection) + device_path = port.device errors, mac_stick = await validate_usb_connection(self.hass, device_path) if not errors: await self.async_set_unique_id( diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 14a8b93f..994aa015 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -8,12 +8,14 @@ from custom_components.plugwise_usb.config_flow import CONF_MANUAL_PATH from custom_components.plugwise_usb.const import CONF_USB_PATH, DOMAIN +# from homeassistant.components import usb +from homeassistant.components.usb import USBDevice from homeassistant.config_entries import SOURCE_USER, ConfigFlowResult from homeassistant.const import CONF_SOURCE from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType, InvalidData from pytest_homeassistant_custom_component.common import MockConfigEntry -import serial.tools.list_ports +# import serial.tools.list_ports TEST_MAC: Final[str] = "01:23:45:67:AB" TEST_MAC2: Final[str] = "02:23:45:67:AB" @@ -21,22 +23,27 @@ TEST_USB2_PATH: Final[str] = "/dev/ttyUSB2" -def com_port(): +def com_port()-> USBDevice: """Mock of a serial port.""" - - port = serial.tools.list_ports_common.ListPortInfo(TEST_USB_PATH) - port.serial_number = "1234" - port.manufacturer = "Virtual serial port" - port.device = TEST_USB_PATH - port.description = "Some serial port" - return port + return USBDevice( + device=TEST_USB_PATH, + vid="04D2", + pid="162E", + serial_number="1234", + manufacturer="Virtual serial port", + description="Some serial port", + ) -@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()])) +#@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()])) +@patch( + "homeassistant.components.plugwise_usb.config_flow.usb.async_scan_serial_ports", + AsyncMock(return_value=[com_port()]), +) async def test_user_flow_select(hass, mock_usb_stick: MagicMock): """Test user flow when USB-stick is selected from list.""" port = com_port() - port_select = f"{port}, s/n: {port.serial_number} - {port.manufacturer}" + port_select = f"{port.device}, s/n: {port.serial_number} - {port.manufacturer}" result = await hass.config_entries.flow.async_init( DOMAIN, @@ -118,7 +125,7 @@ async def test_invalid_connection(hass): result = await hass.config_entries.flow.async_configure( result["flow_id"], - {CONF_USB_PATH: "/dev/null"}, + user_input={CONF_USB_PATH: "null"}, ) await hass.async_block_till_done() assert result.get("type") is FlowResultType.FORM From a29c00f2373cdbbe6b51047159eaf908f298adec Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 May 2026 17:56:45 +0200 Subject: [PATCH 04/54] Debug --- custom_components/plugwise_usb/config_flow.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index 0f8fdf30..eab69839 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -15,7 +15,7 @@ from homeassistant.core import callback from homeassistant.data_entry_flow import FlowResult -from .const import CONF_MANUAL_PATH, CONF_USB_PATH, DOMAIN, MANUAL_PATH +from .const import CONF_MANUAL_PATH, CONF_USB_PATH, DOMAIN, LOGGER, MANUAL_PATH STICK_RECONF_SCHEMA = vol.Schema( { @@ -79,6 +79,7 @@ async def async_step_user( if isinstance(port, usb.USBDevice) ] list_of_ports.append(CONF_MANUAL_PATH) + LOGGER.debug("HOI ports: %s", list_of_ports) if user_input is not None: user_selection = user_input[CONF_USB_PATH] @@ -87,6 +88,7 @@ async def async_step_user( return await self.async_step_manual_path() port = list_of_ports.index(user_selection) + LOGGER.debug("HOI port: %s", port) device_path = port.device errors, mac_stick = await validate_usb_connection(self.hass, device_path) if not errors: From 2904f9feb5c348894d26bdd1b4d2a8b7a9602bed Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 May 2026 18:02:26 +0200 Subject: [PATCH 05/54] Try 2 --- custom_components/plugwise_usb/config_flow.py | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index eab69839..8dc227a3 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -72,10 +72,11 @@ async def async_step_user( ) -> FlowResult: """Step when user initializes a integration.""" errors: dict[str, str] = {} + ports = await usb.async_scan_serial_ports(self.hass) list_of_ports = [ f"{port.device}, s/n: {port.serial_number or 'n/a'}" + (f" - {port.manufacturer}" if port.manufacturer else "") - for port in await usb.async_scan_serial_ports(self.hass) + for port in ports if isinstance(port, usb.USBDevice) ] list_of_ports.append(CONF_MANUAL_PATH) @@ -87,7 +88,7 @@ async def async_step_user( if user_selection == CONF_MANUAL_PATH: return await self.async_step_manual_path() - port = list_of_ports.index(user_selection) + port = ports[list_of_ports.index(user_selection)] LOGGER.debug("HOI port: %s", port) device_path = port.device errors, mac_stick = await validate_usb_connection(self.hass, device_path) From 6d1c5fc4c39ab4fb513632cea4ef00350d04ca55 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 May 2026 18:06:02 +0200 Subject: [PATCH 06/54] Debug 2 --- custom_components/plugwise_usb/config_flow.py | 1 + 1 file changed, 1 insertion(+) diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index 8dc227a3..da487a8c 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -91,6 +91,7 @@ async def async_step_user( port = ports[list_of_ports.index(user_selection)] LOGGER.debug("HOI port: %s", port) device_path = port.device + LOGGER.debug("HOI path: %s", device_path) errors, mac_stick = await validate_usb_connection(self.hass, device_path) if not errors: await self.async_set_unique_id( From 1bec01e78e711f3fb6b57518fad7f917aad17915 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Tue, 19 May 2026 18:20:16 +0200 Subject: [PATCH 07/54] Try 3 --- tests/test_config_flow.py | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 994aa015..4833cc24 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -23,7 +23,17 @@ TEST_USB2_PATH: Final[str] = "/dev/ttyUSB2" -def com_port()-> USBDevice: +@pytest.fixture(name="pyserial_comports") +def usb_comports() -> MockFixture: + """Mock scan_serial_ports.""" + with patch( + "homeassistant.components.plugwise_usb.config_flow.usb.async_scan_serial_ports", + AsyncMock(return_value=[mocked_com_port()]), + ) as comports_mock: + yield comports_mock + + +def mocked_com_port()-> USBDevice: """Mock of a serial port.""" return USBDevice( device=TEST_USB_PATH, @@ -35,12 +45,7 @@ def com_port()-> USBDevice: ) -#@patch("serial.tools.list_ports.comports", MagicMock(return_value=[com_port()])) -@patch( - "homeassistant.components.plugwise_usb.config_flow.usb.async_scan_serial_ports", - AsyncMock(return_value=[com_port()]), -) -async def test_user_flow_select(hass, mock_usb_stick: MagicMock): +async def test_user_flow_select(hass, mock_usb_stick: MagicMock, pyserial_comports: MockFixture): """Test user flow when USB-stick is selected from list.""" port = com_port() port_select = f"{port.device}, s/n: {port.serial_number} - {port.manufacturer}" From 1c38cbe7a23808464106be44bbfbf7218be04c66 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Wed, 2 Sep 2026 19:22:10 +0200 Subject: [PATCH 08/54] Update port function --- tests/test_config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 4833cc24..9d3487e7 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -47,7 +47,7 @@ def mocked_com_port()-> USBDevice: async def test_user_flow_select(hass, mock_usb_stick: MagicMock, pyserial_comports: MockFixture): """Test user flow when USB-stick is selected from list.""" - port = com_port() + port = mocked_com_port() port_select = f"{port.device}, s/n: {port.serial_number} - {port.manufacturer}" result = await hass.config_entries.flow.async_init( From b5f8b704f62576561cd14815fcec48afa08110a2 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:18:31 +0200 Subject: [PATCH 09/54] Implement updates by Copilot --- custom_components/plugwise_usb/config_flow.py | 1 - tests/test_config_flow.py | 6 +++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index da487a8c..e96d231d 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -9,7 +9,6 @@ import voluptuous as vol from homeassistant.components import usb -from homeassistant.components.usb import USBDevice from homeassistant.config_entries import SOURCE_USER, ConfigFlow, ConfigFlowResult from homeassistant.const import CONF_BASE from homeassistant.core import callback diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 9d3487e7..629a7711 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -23,11 +23,11 @@ TEST_USB2_PATH: Final[str] = "/dev/ttyUSB2" -@pytest.fixture(name="pyserial_comports") +@pytest.fixture(name="serial_ports", autouse=True) def usb_comports() -> MockFixture: """Mock scan_serial_ports.""" with patch( - "homeassistant.components.plugwise_usb.config_flow.usb.async_scan_serial_ports", + "custom_components.plugwise_usb.config_flow.usb.async_scan_serial_ports", AsyncMock(return_value=[mocked_com_port()]), ) as comports_mock: yield comports_mock @@ -45,7 +45,7 @@ def mocked_com_port()-> USBDevice: ) -async def test_user_flow_select(hass, mock_usb_stick: MagicMock, pyserial_comports: MockFixture): +async def test_user_flow_select(hass, mock_usb_stick: MagicMock): """Test user flow when USB-stick is selected from list.""" port = mocked_com_port() port_select = f"{port.device}, s/n: {port.serial_number} - {port.manufacturer}" From 66e7bfbae62b8075549257309d162d6a44bfdd64 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:20:54 +0200 Subject: [PATCH 10/54] Clean up --- tests/test_config_flow.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 629a7711..d0d60a35 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -8,14 +8,13 @@ from custom_components.plugwise_usb.config_flow import CONF_MANUAL_PATH from custom_components.plugwise_usb.const import CONF_USB_PATH, DOMAIN -# from homeassistant.components import usb + from homeassistant.components.usb import USBDevice from homeassistant.config_entries import SOURCE_USER, ConfigFlowResult from homeassistant.const import CONF_SOURCE from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType, InvalidData from pytest_homeassistant_custom_component.common import MockConfigEntry -# import serial.tools.list_ports TEST_MAC: Final[str] = "01:23:45:67:AB" TEST_MAC2: Final[str] = "02:23:45:67:AB" From c05c8a7ffb6d6a1920583a028e1e5a82fbc2f465 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:22:07 +0200 Subject: [PATCH 11/54] Import MockFixture --- tests/test_config_flow.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index d0d60a35..db0d6ff8 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -1,7 +1,7 @@ """Test the Plugwise config flow.""" from typing import Final -from unittest.mock import AsyncMock, MagicMock, patch +from unittest.mock import AsyncMock, MagicMock, MockFixture, patch from plugwise_usb.exceptions import StickError import pytest From d3a27fcd1086fac67f8347c414af14943ee70b52 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:26:24 +0200 Subject: [PATCH 12/54] Define MockFixture type --- tests/test_config_flow.py | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index db0d6ff8..21b6c107 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -1,7 +1,8 @@ """Test the Plugwise config flow.""" +from collections.abc import Generator from typing import Final -from unittest.mock import AsyncMock, MagicMock, MockFixture, patch +from unittest.mock import AsyncMock, MagicMock, patch from plugwise_usb.exceptions import StickError import pytest @@ -16,6 +17,8 @@ from homeassistant.data_entry_flow import FlowResultType, InvalidData from pytest_homeassistant_custom_component.common import MockConfigEntry +type MockFixture = Generator[MagicMock | AsyncMock] + TEST_MAC: Final[str] = "01:23:45:67:AB" TEST_MAC2: Final[str] = "02:23:45:67:AB" TEST_USB_PATH: Final[str] = "/dev/ttyUSB1" From 0afbd1591cf3a14a1e3430a31d87e489435abd30 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:27:48 +0200 Subject: [PATCH 13/54] Ruffed --- tests/test_config_flow.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 21b6c107..42318421 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -9,7 +9,6 @@ from custom_components.plugwise_usb.config_flow import CONF_MANUAL_PATH from custom_components.plugwise_usb.const import CONF_USB_PATH, DOMAIN - from homeassistant.components.usb import USBDevice from homeassistant.config_entries import SOURCE_USER, ConfigFlowResult from homeassistant.const import CONF_SOURCE From fbc44e8013c036a0a289446da08bfd0af89cc693 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:30:36 +0200 Subject: [PATCH 14/54] Remove test-logging --- custom_components/plugwise_usb/config_flow.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index e96d231d..8424acf0 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -14,7 +14,7 @@ from homeassistant.core import callback from homeassistant.data_entry_flow import FlowResult -from .const import CONF_MANUAL_PATH, CONF_USB_PATH, DOMAIN, LOGGER, MANUAL_PATH +from .const import CONF_MANUAL_PATH, CONF_USB_PATH, DOMAIN, MANUAL_PATH STICK_RECONF_SCHEMA = vol.Schema( { @@ -79,7 +79,6 @@ async def async_step_user( if isinstance(port, usb.USBDevice) ] list_of_ports.append(CONF_MANUAL_PATH) - LOGGER.debug("HOI ports: %s", list_of_ports) if user_input is not None: user_selection = user_input[CONF_USB_PATH] @@ -88,9 +87,7 @@ async def async_step_user( return await self.async_step_manual_path() port = ports[list_of_ports.index(user_selection)] - LOGGER.debug("HOI port: %s", port) device_path = port.device - LOGGER.debug("HOI path: %s", device_path) errors, mac_stick = await validate_usb_connection(self.hass, device_path) if not errors: await self.async_set_unique_id( From 20cd9ad9694e59503d86711317ebae3026eaf902 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:35:12 +0200 Subject: [PATCH 15/54] Link to plugwise v0.47.8 --- custom_components/plugwise_usb/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/plugwise_usb/manifest.json b/custom_components/plugwise_usb/manifest.json index 888d22bf..d6a9d509 100644 --- a/custom_components/plugwise_usb/manifest.json +++ b/custom_components/plugwise_usb/manifest.json @@ -9,6 +9,6 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/plugwise/python-plugwise-usb/issues", "loggers": ["plugwise_usb"], - "requirements": ["plugwise-usb==0.47.7"], + "requirements": ["plugwise-usb==0.47.8"], "version": "0.59.2" } From 124da0f1e1725ecfc7dbea18d4df61f021d438fc Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:39:02 +0200 Subject: [PATCH 16/54] Update CHANGELOG --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index a3a567b2..4f7363b5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -3,7 +3,7 @@ ## Ongoing - Bump python to 3.14 -- Link to plugwise_usb [v0.47.7](https://github.com/plugwise/python-plugwise-usb/releases/tag/v0.47.7) +- Link to plugwise_usb [v0.47.8](https://github.com/plugwise/python-plugwise-usb/releases/tag/v0.47.8), rework to using the HA USB platform ## v0.59.2 From 06408bf8e7e7912ca7982e3ee1201d2e46db9832 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:48:38 +0200 Subject: [PATCH 17/54] Fix test-code by Copilot --- tests/test_config_flow.py | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/tests/test_config_flow.py b/tests/test_config_flow.py index 42318421..8f246802 100644 --- a/tests/test_config_flow.py +++ b/tests/test_config_flow.py @@ -150,14 +150,11 @@ async def test_empty_connection(hass): ) await hass.async_block_till_done() - try: + with pytest.raises(InvalidData): result = await hass.config_entries.flow.async_configure( result["flow_id"], {CONF_USB_PATH: None}, ) - pytest.fail("Empty connection was accepted") - except InvalidData: - assert True assert result.get("type") is FlowResultType.FORM assert result.get("errors") == {} From 703c983f6915585bcf56a282694cd1802b658010 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 09:58:13 +0200 Subject: [PATCH 18/54] Set to v0.59.3a0 test-version --- CHANGELOG.md | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4f7363b5..e56a82bb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,6 +1,6 @@ # Changelog -## Ongoing +## v0.59.3 - Bump python to 3.14 - Link to plugwise_usb [v0.47.8](https://github.com/plugwise/python-plugwise-usb/releases/tag/v0.47.8), rework to using the HA USB platform diff --git a/pyproject.toml b/pyproject.toml index 1d5885df..ec57538d 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "plugwise_usb-beta" -version = "0.59.2" +version = "0.59.3a0" description = "Plugwise USB custom_component (BETA)" readme = "README.md" requires-python = ">=3.14" From 0e110536f12befafdedced959fb9dfe4b82a0743 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 10:13:46 +0200 Subject: [PATCH 19/54] Fix via_device_id compatibility --- custom_components/plugwise_usb/entity.py | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/custom_components/plugwise_usb/entity.py b/custom_components/plugwise_usb/entity.py index 045da4bb..0bc511c4 100644 --- a/custom_components/plugwise_usb/entity.py +++ b/custom_components/plugwise_usb/entity.py @@ -7,7 +7,11 @@ from plugwise_usb.api import NodeFeature, NodeInfo -from homeassistant.helpers.device_registry import CONNECTION_ZIGBEE, DeviceInfo +from homeassistant.helpers.device_registry import ( + CONNECTION_ZIGBEE, + DeviceInfo, + async_get_device_id_by_identifier, +) from homeassistant.helpers.entity import EntityDescription from homeassistant.helpers.update_coordinator import CoordinatorEntity @@ -38,9 +42,9 @@ def __init__( super().__init__(node_duc, context=entity_description.node_feature) self.node_duc = node_duc self.entity_description = entity_description + self.entry = node_duc.config_entry self._node_info: NodeInfo = node_duc.node.node_info self._attr_unique_id = f"{self._node_info.mac}-{entity_description.key}" - self._via_device = (DOMAIN, str(node_duc.api_stick.mac_stick)) @property def available(self) -> bool: @@ -61,7 +65,11 @@ def device_info(self) -> DeviceInfo: model_id=self._node_info.model_type, name=str(self._node_info.name), sw_version=str(self._node_info.firmware), - via_device=self._via_device, + via_device_id=async_get_device_id_by_identifier( + self.node_duc.hass, + (DOMAIN, str(self.node_duc.api_stick.mac_stick)), + config_entry_id=self.entry.entry_id, + ), ) async def async_added_to_hass(self): From 8704d56c89f0f8cad995f435724829fe625772b6 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 10:34:54 +0200 Subject: [PATCH 20/54] Clean up comments --- tests/conftest.py | 16 +--------------- 1 file changed, 1 insertion(+), 15 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index 781e980c..473dceda 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -30,7 +30,7 @@ def mock_setup_entry() -> Generator[AsyncMock]: @pytest.fixture def mock_config_entry() -> MockConfigEntry: - """Return a mocked v1.2 config entry.""" # pw-beta only + """Return a mocked v1.2 config entry.""" return MockConfigEntry( domain=DOMAIN, data={CONF_USB_PATH: TEST_USB_PATH}, @@ -53,20 +53,6 @@ async def init_integration( return mock_config_entry -# @pytest.fixture -# def mock_comport() -> Generator[MagicMock]: -# """Return a mocked comport.""" -# with patch( -# "serial.tools.list_ports.comports", -# ) as port: -# port = serial.tools.list_ports_common.ListPortInfo(TEST_USBPORT) -# port.serial_number = "1234" -# port.manufacturer = "Virtual serial port" -# port.device = TEST_USBPORT -# port.description = "Some serial port" -# yield [port] - - @pytest.fixture def mock_usb_stick_not_setup() -> Generator[MagicMock]: """Return a mocked usb_mock.""" From 00ff80566ff7aab8af70270c2c8490895afd630e Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 10:44:49 +0200 Subject: [PATCH 21/54] Bump to a1 --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index ec57538d..e4911a61 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "plugwise_usb-beta" -version = "0.59.3a0" +version = "0.59.3a1" description = "Plugwise USB custom_component (BETA)" readme = "README.md" requires-python = ">=3.14" From 2064a439ec8386e18c47834488cf153fdce36ae4 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 10:58:02 +0200 Subject: [PATCH 22/54] Bump versions --- .github/workflows/hassfest.yaml | 4 ++-- .github/workflows/test.yml | 12 ++++++------ 2 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/hassfest.yaml b/.github/workflows/hassfest.yaml index b9be3a52..e76ecadc 100644 --- a/.github/workflows/hassfest.yaml +++ b/.github/workflows/hassfest.yaml @@ -10,5 +10,5 @@ jobs: hassfest_custom: runs-on: "ubuntu-latest" steps: - - uses: "actions/checkout@v6.0.2" - - uses: home-assistant/actions/hassfest@master + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + - uses: home-assistant/actions/hassfest@f4ca6f671bd429efb108c0f2fa0ae8af0215986c diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ec72a1d1..dc55f80d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -34,10 +34,10 @@ jobs: python-version: ${{ steps.python.outputs.python-version }} steps: - name: Check out committed code - uses: actions/checkout@v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Set up Python ${{ env.DEFAULT_PYTHON }} id: python - uses: actions/setup-python@v6 + uses: actions/setup-python@5fda3b95a4ea91299a34e894583c3862153e4b97 with: python-version: ${{ env.DEFAULT_PYTHON }} - name: Fetch HA pyproject @@ -55,7 +55,7 @@ jobs: steps: - name: Prepare code checkout and python/prek/pre-commit setup id: cache-reuse - uses: plugwise/gh-actions/prepare-python-and-code@v2 + uses: plugwise/gh-actions/prepare-python-and-code@9054f02b05e53697300c41df27d0307332dc7cd8 with: cache-key: ${{ needs.cache.outputs.cache-key }} fail-on-miss: false # First time create cache (if not already exists) @@ -72,7 +72,7 @@ jobs: - prepare steps: - name: Check out committed code - uses: actions/checkout@v6 + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Restore cached environment id: cache-reuse uses: plugwise/gh-actions/restore-venv@v2 @@ -94,6 +94,6 @@ jobs: name: Shellcheck runs-on: ubuntu-latest steps: - - uses: actions/checkout@v6.0.2 + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Run ShellCheck - uses: ludeeus/action-shellcheck@master + uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 From 6d6289c8b8bd8538a9be9b921eacb715e0ee136b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 11:05:22 +0200 Subject: [PATCH 23/54] Update CACHE_VERSION --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dc55f80d..782e4423 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ name: Test against HA-core env: - CACHE_VERSION: 2 + CACHE_VERSION: 3 DEFAULT_PYTHON: "3.14" VENV: venv From a9f6d4d9704045e55dd963d47a950b606020dbd9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 12:28:04 +0200 Subject: [PATCH 24/54] Pin one more action --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 782e4423..ea973b7d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -75,7 +75,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Restore cached environment id: cache-reuse - uses: plugwise/gh-actions/restore-venv@v2 + uses: plugwise/gh-actions/restore-venv@9054f02b05e53697300c41df27d0307332dc7cd8 with: cache-key: ${{ needs.cache.outputs.cache-key }} python-version: ${{ needs.cache.outputs.python-version }} From 22d50339cea0f0ddfd8b75d53dc57b9508a6756a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 12:53:52 +0200 Subject: [PATCH 25/54] Update ci-core-testing script --- scripts/ci-core-testing.sh | 94 +++++++++++++++++--------------------- 1 file changed, 41 insertions(+), 53 deletions(-) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index 0f871856..d6d189d2 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -9,7 +9,6 @@ CWARN="\x1B[93m" # yellow # Repository name (for reuse betweeh plugwise network and usb REPO_NAME="plugwise_usb" -VENV_DIR=".venv" # By default assumes running against 'master' branch of Core-HA # as requested by @bouwew for on-par development with the releases @@ -60,6 +59,25 @@ which jq || ( echo -e "${CFAIL}You should have jq installed, exiting${CNORM}"; e my_path=$(git rev-parse --show-toplevel) +venv_and_uv() { + # shellcheck disable=SC1091 + source venv/bin/activate + if ! [ -x "$(command -v uv)" ]; then + echo -e "${CINFO}Ensure uv presence${CWARN}" + python3 -m pip install uv + fi + if ! [ -x "$(command -v prek)" ]; then + echo -e "${CINFO}Ensure prek presence${CWARN}" + uv pip install -r "${my_path}/requirements_commit.txt" + fi + if ! uv pip list | grep -q bcrypt; then + script/setup + fi + if ! [ -x "$(command -v pytest)" ]; then + uv pip install pytest + fi +} + # Ensure environment is set-up # 20250613 Copied from HA-core and shell-check adjusted and modified for local use @@ -67,12 +85,12 @@ set -e if [ -z "$VIRTUAL_ENV" ]; then if [ -x "$(command -v uv)" ]; then - uv venv --seed "${VENV_DIR}" + uv venv --seed venv else - python3 -m venv "${VENV_DIR}" + python3 -m venv venv fi # shellcheck disable=SC1091 # ingesting virtualenv - source "${VENV_DIR}/bin/activate" + source venv/bin/activate fi if ! [ -x "$(command -v uv)" ]; then @@ -81,13 +99,7 @@ fi # /20250613 # Install commit requirements -if ! [ -x "$(command -v prek)" ]; then - uv pip install prek -fi - uv pip install -r "${my_path}/requirements_commit.txt" - -# Install pre-commit hook prek install # i.e. args used for functions, not directions @@ -168,27 +180,14 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then # Fake branch git checkout -b fake_branch - echo "" - echo -e "${CINFO}Ensure HA-core venv${CWARN}" - if [ -x "$(command -v uv)" ]; then - uv venv --seed "${VENV_DIR}" - else - python3 -m venv "${VENV_DIR}" + if [ ! -d "venv" ]; then + echo -e "${CINFO}Ensure HA-core venv${CWARN}" + uv venv --seed venv fi + echo -e "${CINFO}(Re)setup HA-core ${CWARN}" + script/setup # shellcheck disable=SC1091 - source "${VENV_DIR}/bin/activate" - - if ! [ -x "$(command -v uv)" ]; then - echo -e "${CINFO}Ensure uv presence${CWARN}" - uv pip install -r "${my_path}/requirements_commit.txt" - fi - if ! [ -x "$(command -v pytest)" ]; then - echo -e "${CINFO}Ensure pytest presence${CWARN}" - uv pip install pytest - fi - - echo -e "${CINFO}Bootstrap pip parts of HA-core${CWARN}" - script/setup + source venv/bin/activate echo "" echo -e "${CINFO}Cleaning existing ${REPO_NAME} from HA core${CNORM}" @@ -198,12 +197,17 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then echo -e "${CINFO}Overwriting with ${REPO_NAME}-beta${CNORM}" echo "" cp -r ../custom_components/${REPO_NAME} ./homeassistant/components/ - mkdir -p ./tests/components/${REPO_NAME}/ cp -r ../tests/*py ./tests/components/${REPO_NAME}/ - # Rework pytest from custom_component to core - sed -i".sedbck" 's/pytest_homeassistant_custom_component.common/tests.common/g' ./tests/components/${REPO_NAME}/*py - sed -i".sedbck" 's/custom_components/homeassistant.components/g' ./tests/components/${REPO_NAME}/*py + echo "" + + echo -e "${CINFO}Validating prettierrc changes${CNORM}" + prettierrc=".prettierrc.js" + if ! diff -q <(sed 's/homeassistant/custom_components/g' "${prettierrc}") "../${prettierrc}" >/dev/null; then + echo -e "${CWARN}Updating prettierrc from core${CNORM}" + sed 's/homeassistant/custom_components/g' "${prettierrc}" > "../${prettierrc}" + fi + fi # core_prep set +u @@ -211,22 +215,12 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "pip_prep" ] ; then cd "${coredir}" || exit echo "" echo -e "${CINFO}Ensure HA-core venv${CNORM}" - # shellcheck disable=SC1091 - source "${VENV_DIR}/bin/activate" + venv_and_uv mkdir -p ./tmp echo "" echo -e "${CINFO}Ensure translations are there${CNORM}" echo "" python3 -m script.translations develop --all > /dev/null 2>&1 - echo "" - if ! [ -x "$(command -v uv)" ]; then - echo -e "${CINFO}Ensure uv is there${CNORM}" - python3 -m pip install uv - fi - echo -e "${CINFO}Installing pip modules (using uv)${CNORM}" - echo "" - script/setup - echo "" # When using test.py prettier makes multi-line, so use jq module=$(jq '.requirements[]' ../custom_components/${REPO_NAME}/manifest.json | tr -d '"') #module=$(grep require ../custom_components/${REPO_NAME}/manifest.json | cut -f 4 -d '"') @@ -240,8 +234,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "testing" ] ; then cd "${coredir}" || exit echo "" echo -e "${CINFO}Ensure HA-core venv${CNORM}" - # shellcheck disable=SC1091 - source "${VENV_DIR}/bin/activate" + venv_and_uv echo "" echo -e "${CINFO}Test commencing ...${CNORM}" echo "" @@ -257,8 +250,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "quality" ] ; then cd "${coredir}" || exit echo "" echo -e "${CINFO}Ensure HA-core venv${CNORM}" - # shellcheck disable=SC1091 - source "${VENV_DIR}/bin/activate" + venv_and_uv echo "" set +e echo -e "${CINFO}... ruff-ing component...${CNORM}" @@ -283,14 +275,10 @@ if [ -z "${GITHUB_ACTIONS}" ]; then cd "${coredir}" || exit echo "" echo "Ensure HA-core venv${CNORM}" - # shellcheck disable=SC1091 - source "${VENV_DIR}/bin/activate" + venv_and_uv echo "" echo -e "${CINFO}Copy back modified files ...${CNORM}" echo "" - sed -i".sedbck" 's/tests.common/pytest_homeassistant_custom_component.common/g' ./tests/components/${REPO_NAME}/*py - sed -i".sedbck" 's/homeassistant.components/custom_components/g' ./tests/components/${REPO_NAME}/*py - rm ./tests/components/${REPO_NAME}/*sedbck cp -r ./homeassistant/components/${REPO_NAME} ../custom_components/ cp -r ./tests/components/${REPO_NAME}/*py ../tests/ echo -e "${CINFO}Removing 'version' from manifest for hassfest-ing, version not allowed in core components${CNORM}" From 905f44894eb86ff4f84a7c310b0b4b6e33e55ed9 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 15:29:05 +0200 Subject: [PATCH 26/54] Correct to prek-home --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ea973b7d..e9d2c6d3 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -80,7 +80,7 @@ jobs: cache-key: ${{ needs.cache.outputs.cache-key }} python-version: ${{ needs.cache.outputs.python-version }} venv-dir: ${{ env.VENV }} - precommit-home: ${{ env.PRE_COMMIT_HOME }} + prek-home: ${{ env.PREK_HOME }} - name: Test through HA-core (master/release) id: ha_core_release_tests run: | From 25c550b4741a860f0e726924443e71103cd88273 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 15:39:12 +0200 Subject: [PATCH 27/54] Improve test.yaml --- .github/workflows/test.yml | 77 ++++++++++++++++++++++++++++++-------- 1 file changed, 61 insertions(+), 16 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index e9d2c6d3..07f06aaf 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,6 +25,14 @@ on: - unlabeled jobs: + shellcheck: + name: Shellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 + # Determine cache key once cache: runs-on: ubuntu-latest @@ -41,8 +49,14 @@ jobs: with: python-version: ${{ env.DEFAULT_PYTHON }} - name: Fetch HA pyproject - id: core-version + id: core-version run: wget -O ha_pyproject.toml "https://raw.githubusercontent.com/home-assistant/core/refs/heads/dev/pyproject.toml" + - name: Core dependencies + id: core-dependencies-1 + run: sudo apt-get update + - name: Core dependencies + id: core-dependencies-2 + run: sudo apt-get install python3-pip python3-dev python3-venv autoconf libssl-dev libxml2-dev libxslt1-dev libjpeg-dev libffi-dev libudev-dev zlib1g-dev pkg-config libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev ffmpeg libgammu-dev build-essential - name: Compute cache key id: set-key run: echo "cache-key=${{ runner.os }}--${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', 'requirements_test.txt', '.pre-commit-config.yaml', 'ha_pyproject.toml') }}" >> "$GITHUB_OUTPUT" @@ -64,36 +78,67 @@ jobs: clone-core: "true" # Prepare default python version environment - ha-core-release: + ha-core-release-prepare: + runs-on: ubuntu-latest + name: Prepare and validate prek (pre-commit) + needs: + - cache + - prepare + steps: + - name: Check out committed code + uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + - name: Prepare code checkout and python/prek/pre-commit setup + id: cache-reuse + uses: plugwise/gh-actions/prepare-python-and-code@9054f02b05e53697300c41df27d0307332dc7cd8 + with: + cache-key: ${{ needs.cache.outputs.cache-key }} + fail-on-miss: false # First time create cache (if not already exists) + python-version: ${{ needs.cache.outputs.python-version }} + venv-dir: ${{ env.VENV }} + - name: Run all-files prek (pre-commit) excluding testing + run: | + # shellcheck disable=SC1091 # ingesting virtualenv + source venv-${{ needs.cache.outputs.python-version }}/bin/activate + prek run --all-files --show-diff-on-failure + env: # While not problematic, save time on performing the local hooks as they are run from the complete script in the next job + SKIP: local-test-core-prep,local-test-pip-prep,local-testing,local-quality + + + ha-core-testing: runs-on: ubuntu-latest name: Setup for HA-core (release/master) needs: - cache - prepare + - ha-core-release-prepare + outputs: + release_failed: ${{ steps.ha_core_release_tests.outputs.release_failed }} steps: - name: Check out committed code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - name: Restore cached environment + - name: Prepare code checkout and python/prek/pre-commit setup id: cache-reuse - uses: plugwise/gh-actions/restore-venv@9054f02b05e53697300c41df27d0307332dc7cd8 + uses: plugwise/gh-actions/prepare-python-and-code@9054f02b05e53697300c41df27d0307332dc7cd8 with: cache-key: ${{ needs.cache.outputs.cache-key }} + fail-on-miss: false # First time create cache (if not already exists) python-version: ${{ needs.cache.outputs.python-version }} venv-dir: ${{ env.VENV }} - prek-home: ${{ env.PREK_HOME }} - - name: Test through HA-core (master/release) + - name: Test through HA-core (master/release) - continue-on-error = ${{ needs.determine-mode.outputs.strict_dev == 'true' }} id: ha_core_release_tests + continue-on-error: ${{ needs.determine-mode.outputs.strict_dev == 'true' }} # Allow master failures only if dev is strict run: | set +e - source venv-${{ needs.cache.outputs.python-version }}/bin/activate - GITHUB_ACTIONS="" scripts/ci-core-testing.sh + + GITHUB_ACTIONS="" scripts/core-testing.sh EXIT_CODE=$? - exit $EXIT_CODE - shellcheck: - name: Shellcheck - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - name: Run ShellCheck - uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 + if [ $EXIT_CODE -ne 0 ]; then + echo "::warning::Release HA core incompatibility" + echo "release_failed=true" >> "$GITHUB_OUTPUT" + else + echo "Successfully tested against released HA-core" + echo "release_failed=false" >> "$GITHUB_OUTPUT" + fi + + exit $EXIT_CODE From dc020dbc522f9ff90195ca96c89c2a6aed75eaf5 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 15:40:51 +0200 Subject: [PATCH 28/54] Bump CACHE_VERSION --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 07f06aaf..b30c6598 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ name: Test against HA-core env: - CACHE_VERSION: 3 + CACHE_VERSION: 4 DEFAULT_PYTHON: "3.14" VENV: venv From 8806030e2026a49d950df65e07ede66a9850355a Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 15:44:49 +0200 Subject: [PATCH 29/54] Fix script name --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index b30c6598..45d6f0a5 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -130,7 +130,7 @@ jobs: run: | set +e - GITHUB_ACTIONS="" scripts/core-testing.sh + GITHUB_ACTIONS="" scripts/ci-core-testing.sh EXIT_CODE=$? if [ $EXIT_CODE -ne 0 ]; then From 155e6faf7b3409a675ea8504a73123b95aeb2618 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Thu, 3 Sep 2026 15:47:35 +0200 Subject: [PATCH 30/54] Fix codefactor error --- .github/workflows/test.yml | 1 - 1 file changed, 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 45d6f0a5..46892861 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -103,7 +103,6 @@ jobs: env: # While not problematic, save time on performing the local hooks as they are run from the complete script in the next job SKIP: local-test-core-prep,local-test-pip-prep,local-testing,local-quality - ha-core-testing: runs-on: ubuntu-latest name: Setup for HA-core (release/master) From ac6b9b841dc752abe8ffa05f6356eaab58ae3ed5 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Fri, 4 Sep 2026 09:26:37 +0200 Subject: [PATCH 31/54] Update test.yaml --- .github/workflows/test.yml | 71 +++++++------------------------------- 1 file changed, 13 insertions(+), 58 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 46892861..01572683 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -25,14 +25,6 @@ on: - unlabeled jobs: - shellcheck: - name: Shellcheck - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - name: Run ShellCheck - uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 - # Determine cache key once cache: runs-on: ubuntu-latest @@ -49,14 +41,8 @@ jobs: with: python-version: ${{ env.DEFAULT_PYTHON }} - name: Fetch HA pyproject - id: core-version + id: core-version run: wget -O ha_pyproject.toml "https://raw.githubusercontent.com/home-assistant/core/refs/heads/dev/pyproject.toml" - - name: Core dependencies - id: core-dependencies-1 - run: sudo apt-get update - - name: Core dependencies - id: core-dependencies-2 - run: sudo apt-get install python3-pip python3-dev python3-venv autoconf libssl-dev libxml2-dev libxslt1-dev libjpeg-dev libffi-dev libudev-dev zlib1g-dev pkg-config libavformat-dev libavcodec-dev libavdevice-dev libavutil-dev libswscale-dev libswresample-dev libavfilter-dev ffmpeg libgammu-dev build-essential - name: Compute cache key id: set-key run: echo "cache-key=${{ runner.os }}--${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', 'requirements_test.txt', '.pre-commit-config.yaml', 'ha_pyproject.toml') }}" >> "$GITHUB_OUTPUT" @@ -77,41 +63,12 @@ jobs: venv-dir: ${{ env.VENV }} clone-core: "true" - # Prepare default python version environment - ha-core-release-prepare: - runs-on: ubuntu-latest - name: Prepare and validate prek (pre-commit) - needs: - - cache - - prepare - steps: - - name: Check out committed code - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - - name: Prepare code checkout and python/prek/pre-commit setup - id: cache-reuse - uses: plugwise/gh-actions/prepare-python-and-code@9054f02b05e53697300c41df27d0307332dc7cd8 - with: - cache-key: ${{ needs.cache.outputs.cache-key }} - fail-on-miss: false # First time create cache (if not already exists) - python-version: ${{ needs.cache.outputs.python-version }} - venv-dir: ${{ env.VENV }} - - name: Run all-files prek (pre-commit) excluding testing - run: | - # shellcheck disable=SC1091 # ingesting virtualenv - source venv-${{ needs.cache.outputs.python-version }}/bin/activate - prek run --all-files --show-diff-on-failure - env: # While not problematic, save time on performing the local hooks as they are run from the complete script in the next job - SKIP: local-test-core-prep,local-test-pip-prep,local-testing,local-quality - - ha-core-testing: + ha-core-release: runs-on: ubuntu-latest name: Setup for HA-core (release/master) needs: - cache - prepare - - ha-core-release-prepare - outputs: - release_failed: ${{ steps.ha_core_release_tests.outputs.release_failed }} steps: - name: Check out committed code uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 @@ -120,24 +77,22 @@ jobs: uses: plugwise/gh-actions/prepare-python-and-code@9054f02b05e53697300c41df27d0307332dc7cd8 with: cache-key: ${{ needs.cache.outputs.cache-key }} - fail-on-miss: false # First time create cache (if not already exists) python-version: ${{ needs.cache.outputs.python-version }} venv-dir: ${{ env.VENV }} - - name: Test through HA-core (master/release) - continue-on-error = ${{ needs.determine-mode.outputs.strict_dev == 'true' }} + prek-home: ${{ env.PREK_HOME }} + - name: Test through HA-core (master/release) id: ha_core_release_tests - continue-on-error: ${{ needs.determine-mode.outputs.strict_dev == 'true' }} # Allow master failures only if dev is strict run: | set +e - + source venv-${{ needs.cache.outputs.python-version }}/bin/activate GITHUB_ACTIONS="" scripts/ci-core-testing.sh EXIT_CODE=$? - - if [ $EXIT_CODE -ne 0 ]; then - echo "::warning::Release HA core incompatibility" - echo "release_failed=true" >> "$GITHUB_OUTPUT" - else - echo "Successfully tested against released HA-core" - echo "release_failed=false" >> "$GITHUB_OUTPUT" - fi - exit $EXIT_CODE + + shellcheck: + name: Shellcheck + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 + - name: Run ShellCheck + uses: ludeeus/action-shellcheck@00cae500b08a931fb5698e11e79bfbd38e612a38 From 8c2f0f7e9e49bb5e155ca2da384cb2b290da36b0 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Fri, 4 Sep 2026 18:50:21 +0000 Subject: [PATCH 32/54] Bump cache --- .github/workflows/test.yml | 6 +++--- .pre-commit-config.yaml | 8 ++++---- scripts/local-testing.sh | 6 +++--- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 01572683..dc9f4e1d 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -4,7 +4,7 @@ name: Test against HA-core env: - CACHE_VERSION: 4 + CACHE_VERSION: 5 DEFAULT_PYTHON: "3.14" VENV: venv @@ -55,7 +55,7 @@ jobs: steps: - name: Prepare code checkout and python/prek/pre-commit setup id: cache-reuse - uses: plugwise/gh-actions/prepare-python-and-code@9054f02b05e53697300c41df27d0307332dc7cd8 + uses: plugwise/gh-actions/prepare-python-and-code@dac5b9c5597fcc4d46b6fef622db5f8d57d2df81 with: cache-key: ${{ needs.cache.outputs.cache-key }} fail-on-miss: false # First time create cache (if not already exists) @@ -74,7 +74,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Prepare code checkout and python/prek/pre-commit setup id: cache-reuse - uses: plugwise/gh-actions/prepare-python-and-code@9054f02b05e53697300c41df27d0307332dc7cd8 + uses: plugwise/gh-actions/prepare-python-and-code@dac5b9c5597fcc4d46b6fef622db5f8d57d2df81 with: cache-key: ${{ needs.cache.outputs.cache-key }} python-version: ${{ needs.cache.outputs.python-version }} diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 49c03f6f..fc9c520c 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -5,7 +5,7 @@ default_language_version: repos: # Run manually in CI skipping the branch checks - repo: https://github.com/astral-sh/ruff-pre-commit - rev: v0.15.13 + rev: v0.16.6 hooks: - id: ruff name: "Ruff-ing code" @@ -27,7 +27,7 @@ repos: name: "Checking pyupgrade" args: [--py39-plus] - repo: https://github.com/codespell-project/codespell - rev: v2.4.2 + rev: v2.4.3 hooks: - id: codespell name: "Verifying/updating code for spelling issues" @@ -52,7 +52,7 @@ repos: - id: yamllint name: "Linting yaml" - repo: https://github.com/biomejs/pre-commit - rev: v2.4.15 + rev: v2.5.12 hooks: - id: biome-lint additional_dependencies: ["@biomejs/biome@2.0.4"] @@ -79,7 +79,7 @@ repos: language: script pass_filenames: false - repo: https://github.com/jackdewinter/pymarkdown - rev: v0.9.37 + rev: v0.9.39 hooks: - id: pymarkdown name: "MarkDown Lint" diff --git a/scripts/local-testing.sh b/scripts/local-testing.sh index 0bc6e64b..14ea5741 100755 --- a/scripts/local-testing.sh +++ b/scripts/local-testing.sh @@ -34,10 +34,10 @@ fi # /20250613 # Install commit requirements -uv pip install -q --upgrade pre-commit +uv pip install -q --upgrade prek # Install pre-commit hook -pre-commit install +prek install echo -e "${CINFO}Installing pip modules (using uv)${CNORM}" @@ -71,4 +71,4 @@ echo -e "${CFAIL}... SKIPPING mypy ...${CNORM}" #mypy custom_components/${REPO_NAME}/*.py || exit #echo -e "${CINFO}... markdownlint ...${CNORM}" -#pre-commit run --all-files --hook-stage manual markdownlint +#prek run --all-files --hook-stage manual markdownlint From d0a34fdeacd36380ff6426918ae5d4bdbc0877a3 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Fri, 4 Sep 2026 18:52:32 +0000 Subject: [PATCH 33/54] Squash uv alert --- scripts/local-testing.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/local-testing.sh b/scripts/local-testing.sh index 14ea5741..57e2f424 100755 --- a/scripts/local-testing.sh +++ b/scripts/local-testing.sh @@ -34,7 +34,7 @@ fi # /20250613 # Install commit requirements -uv pip install -q --upgrade prek +uv pip install --no-build -q --upgrade prek # Install pre-commit hook prek install From 313a55242d91f63537f6b36a47acaaa0230aedc5 Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Fri, 4 Sep 2026 18:56:44 +0000 Subject: [PATCH 34/54] Squash uv alerts and wget issue --- .github/workflows/test.yml | 2 +- scripts/ci-core-testing.sh | 10 +++++----- scripts/local-testing.sh | 4 ++-- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index dc9f4e1d..08a963c9 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,7 +42,7 @@ jobs: python-version: ${{ env.DEFAULT_PYTHON }} - name: Fetch HA pyproject id: core-version - run: wget -O ha_pyproject.toml "https://raw.githubusercontent.com/home-assistant/core/refs/heads/dev/pyproject.toml" + run: wget --https-only -O ha_pyproject.toml "https://raw.githubusercontent.com/home-assistant/core/refs/heads/dev/pyproject.toml" - name: Compute cache key id: set-key run: echo "cache-key=${{ runner.os }}--${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', 'requirements_test.txt', '.pre-commit-config.yaml', 'ha_pyproject.toml') }}" >> "$GITHUB_OUTPUT" diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index d6d189d2..58ac14b7 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -68,13 +68,13 @@ venv_and_uv() { fi if ! [ -x "$(command -v prek)" ]; then echo -e "${CINFO}Ensure prek presence${CWARN}" - uv pip install -r "${my_path}/requirements_commit.txt" + uv pip install --no-build -r "${my_path}/requirements_commit.txt" fi if ! uv pip list | grep -q bcrypt; then script/setup fi if ! [ -x "$(command -v pytest)" ]; then - uv pip install pytest + uv pip install --no-build pytest fi } @@ -99,7 +99,7 @@ fi # /20250613 # Install commit requirements -uv pip install -r "${my_path}/requirements_commit.txt" +uv pip install --no-build -r "${my_path}/requirements_commit.txt" prek install # i.e. args used for functions, not directions @@ -180,7 +180,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then # Fake branch git checkout -b fake_branch - if [ ! -d "venv" ]; then + if [[ ! -d "venv" ]]; then echo -e "${CINFO}Ensure HA-core venv${CWARN}" uv venv --seed venv fi @@ -226,7 +226,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "pip_prep" ] ; then #module=$(grep require ../custom_components/${REPO_NAME}/manifest.json | cut -f 4 -d '"') echo -e "${CINFO}Checking manifest for current python-${REPO_NAME} to install: ${module}${CNORM}" echo "" - uv pip install --upgrade "${module}" + uv pip install --no-build --upgrade "${module}" fi # pip_prep if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "testing" ] ; then diff --git a/scripts/local-testing.sh b/scripts/local-testing.sh index 57e2f424..56cf2160 100755 --- a/scripts/local-testing.sh +++ b/scripts/local-testing.sh @@ -43,13 +43,13 @@ prek install echo -e "${CINFO}Installing pip modules (using uv)${CNORM}" echo "" echo -e "${CINFO} - HA requirements (core and test)${CNORM}" -uv pip install -q --upgrade -r requirements_commit.txt -r requirements_test.txt +uv pip install --no-build -q --upgrade -r requirements_commit.txt -r requirements_test.txt # When using test.py prettier makes multi-line, so use jq module=$(jq '.requirements[]' custom_components/${REPO_NAME}/manifest.json | tr -d '"') echo -e "${CINFO}Checking manifest for current python-${REPO_NAME} to install: ${module}${CNORM}" echo "" -uv pip install -q --upgrade "${module}" +uv pip install --no-build -q --upgrade "${module}" debug_params="" if [ -n "${DEBUG}" ] ; then debug_params="-rpP --log-cli-level=DEBUG" From aa2b8587e909a096d2ccf475ba7cf0f7529019dd Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Fri, 4 Sep 2026 19:48:19 +0000 Subject: [PATCH 35/54] Curl to wget --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 08a963c9..ffaf6470 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -42,7 +42,7 @@ jobs: python-version: ${{ env.DEFAULT_PYTHON }} - name: Fetch HA pyproject id: core-version - run: wget --https-only -O ha_pyproject.toml "https://raw.githubusercontent.com/home-assistant/core/refs/heads/dev/pyproject.toml" + run: curl --fail --location --proto '=https' -o ha_pyproject.toml "https://raw.githubusercontent.com/home-assistant/core/refs/heads/dev/pyproject.toml" - name: Compute cache key id: set-key run: echo "cache-key=${{ runner.os }}--${{ env.CACHE_VERSION }}-${{ hashFiles('pyproject.toml', 'requirements_test.txt', '.pre-commit-config.yaml', 'ha_pyproject.toml') }}" >> "$GITHUB_OUTPUT" From 1c9b44e08142a8269e184c88d96dddad378fcdeb Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Fri, 4 Sep 2026 19:58:50 +0000 Subject: [PATCH 36/54] Bump action --- .github/workflows/test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index ffaf6470..46535835 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -55,7 +55,7 @@ jobs: steps: - name: Prepare code checkout and python/prek/pre-commit setup id: cache-reuse - uses: plugwise/gh-actions/prepare-python-and-code@dac5b9c5597fcc4d46b6fef622db5f8d57d2df81 + uses: plugwise/gh-actions/prepare-python-and-code@6b33ca47b5b47b3324e081221da2baa499905914 with: cache-key: ${{ needs.cache.outputs.cache-key }} fail-on-miss: false # First time create cache (if not already exists) @@ -74,7 +74,7 @@ jobs: uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 - name: Prepare code checkout and python/prek/pre-commit setup id: cache-reuse - uses: plugwise/gh-actions/prepare-python-and-code@dac5b9c5597fcc4d46b6fef622db5f8d57d2df81 + uses: plugwise/gh-actions/prepare-python-and-code@6b33ca47b5b47b3324e081221da2baa499905914 with: cache-key: ${{ needs.cache.outputs.cache-key }} python-version: ${{ needs.cache.outputs.python-version }} From 8e500aef5cb11c30ea2ba913988d5098f309398f Mon Sep 17 00:00:00 2001 From: Tom Scholten Date: Fri, 4 Sep 2026 20:14:05 +0000 Subject: [PATCH 37/54] Attempt to fix shared action --- .github/workflows/test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml index 46535835..771721d7 100644 --- a/.github/workflows/test.yml +++ b/.github/workflows/test.yml @@ -77,9 +77,9 @@ jobs: uses: plugwise/gh-actions/prepare-python-and-code@6b33ca47b5b47b3324e081221da2baa499905914 with: cache-key: ${{ needs.cache.outputs.cache-key }} + fail-on-miss: false # First time create cache (if not already exists) python-version: ${{ needs.cache.outputs.python-version }} venv-dir: ${{ env.VENV }} - prek-home: ${{ env.PREK_HOME }} - name: Test through HA-core (master/release) id: ha_core_release_tests run: | From 7f0b9752a91618c6df53e252dae779e969617e40 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 09:40:19 +0200 Subject: [PATCH 38/54] Revert --no-build --- scripts/ci-core-testing.sh | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index 58ac14b7..3a4e3b54 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -68,13 +68,13 @@ venv_and_uv() { fi if ! [ -x "$(command -v prek)" ]; then echo -e "${CINFO}Ensure prek presence${CWARN}" - uv pip install --no-build -r "${my_path}/requirements_commit.txt" + uv pip install -r "${my_path}/requirements_commit.txt" fi if ! uv pip list | grep -q bcrypt; then script/setup fi if ! [ -x "$(command -v pytest)" ]; then - uv pip install --no-build pytest + uv pip install pytest fi } @@ -99,7 +99,7 @@ fi # /20250613 # Install commit requirements -uv pip install --no-build -r "${my_path}/requirements_commit.txt" +uv pip install -r "${my_path}/requirements_commit.txt" prek install # i.e. args used for functions, not directions @@ -226,7 +226,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "pip_prep" ] ; then #module=$(grep require ../custom_components/${REPO_NAME}/manifest.json | cut -f 4 -d '"') echo -e "${CINFO}Checking manifest for current python-${REPO_NAME} to install: ${module}${CNORM}" echo "" - uv pip install --no-build --upgrade "${module}" + uv pip install --upgrade "${module}" fi # pip_prep if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "testing" ] ; then From f0e80430c0576b7afb86cb847d44c7ab9e5c4440 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 09:48:02 +0200 Subject: [PATCH 39/54] Correct to requirements_test.txt --- scripts/ci-core-testing.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index 3a4e3b54..06b51480 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -123,7 +123,7 @@ mkdir -p "${coredir}" if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then # If only dir exists, but not cloned yet - if [ ! -f "${coredir}/requirements_test_all.txt" ]; then + if [ ! -f "${coredir}/requirements_test.txt" ]; then if [ -d "${manualdir}" ]; then echo "" echo -e "${CINFO} ** Reusing copy, rebasing and copy to HA core**${CNORM}" @@ -143,7 +143,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then git clone https://github.com/home-assistant/core.git "${coredir}" cp -a "${coredir}." "${manualdir}" fi - if [ ! -f "${coredir}/requirements_test_all.txt" ]; then + if [ ! -f "${coredir}/requirements_test.txt" ]; then echo "" echo -e "${CFAIL}Cloning failed .. make sure ${coredir} exists and is an empty directory${CNORM}" echo "" From 5fcdf1a841d9e0928489b6e796ca588160ef4f35 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 09:55:52 +0200 Subject: [PATCH 40/54] Create plugwise_usb dir under tests, adapt test-script --- scripts/ci-core-testing.sh | 4 ++-- tests/{ => plugwise_usb}/__init__.py | 0 tests/{ => plugwise_usb}/bandit.yaml | 0 tests/{ => plugwise_usb}/conftest.py | 0 tests/{ => plugwise_usb}/ruff.toml | 0 tests/{ => plugwise_usb}/test_config_flow.py | 0 6 files changed, 2 insertions(+), 2 deletions(-) rename tests/{ => plugwise_usb}/__init__.py (100%) rename tests/{ => plugwise_usb}/bandit.yaml (100%) rename tests/{ => plugwise_usb}/conftest.py (100%) rename tests/{ => plugwise_usb}/ruff.toml (100%) rename tests/{ => plugwise_usb}/test_config_flow.py (100%) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index 06b51480..23221af3 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -37,7 +37,7 @@ ulimit -n 65536 # if you fancy more options (i.e. show test results) # run as "scripts/core_testing.sh test_config_flow.py -rP" # -# If you want to prepare for Core PR, run as +# If you want to prepare for Core PR, run ass # "COMMIT_CHECK=true scripts/core_testing.sh" echo "" @@ -197,7 +197,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then echo -e "${CINFO}Overwriting with ${REPO_NAME}-beta${CNORM}" echo "" cp -r ../custom_components/${REPO_NAME} ./homeassistant/components/ - cp -r ../tests/*py ./tests/components/${REPO_NAME}/ + cp -r ../tests/${REPO_NAME} ./tests/components/ echo "" diff --git a/tests/__init__.py b/tests/plugwise_usb/__init__.py similarity index 100% rename from tests/__init__.py rename to tests/plugwise_usb/__init__.py diff --git a/tests/bandit.yaml b/tests/plugwise_usb/bandit.yaml similarity index 100% rename from tests/bandit.yaml rename to tests/plugwise_usb/bandit.yaml diff --git a/tests/conftest.py b/tests/plugwise_usb/conftest.py similarity index 100% rename from tests/conftest.py rename to tests/plugwise_usb/conftest.py diff --git a/tests/ruff.toml b/tests/plugwise_usb/ruff.toml similarity index 100% rename from tests/ruff.toml rename to tests/plugwise_usb/ruff.toml diff --git a/tests/test_config_flow.py b/tests/plugwise_usb/test_config_flow.py similarity index 100% rename from tests/test_config_flow.py rename to tests/plugwise_usb/test_config_flow.py From fcefdfc35590369acbed33f910b4f4108cd70f38 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 10:09:24 +0200 Subject: [PATCH 41/54] Revert patch changes --- tests/plugwise_usb/conftest.py | 6 +++--- tests/plugwise_usb/test_config_flow.py | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/tests/plugwise_usb/conftest.py b/tests/plugwise_usb/conftest.py index 473dceda..e16c7ac6 100644 --- a/tests/plugwise_usb/conftest.py +++ b/tests/plugwise_usb/conftest.py @@ -9,11 +9,11 @@ from plugwise_usb.exceptions import StickError import pytest -from custom_components.plugwise_usb.const import CONF_USB_PATH, DOMAIN +from homeassistant.components.plugwise_usb.const import CONF_USB_PATH, DOMAIN from homeassistant.core import HomeAssistant from pytest_homeassistant_custom_component.common import MockConfigEntry -STICK_IMPORT_MOCK: Final[str] = "custom_components.plugwise_usb.config_flow.Stick" +STICK_IMPORT_MOCK: Final[str] = "homeassistant.components.plugwise_usb.config_flow.Stick" TEST_MAC: Final[str] = "01:23:45:67:AB" TEST_USB_PATH: Final[str] = "/dev/ttyUSB1" @@ -22,7 +22,7 @@ def mock_setup_entry() -> Generator[AsyncMock]: """Override async_setup_entry.""" with patch( - "custom_components.plugwise_usb.async_setup_entry", + "homeassistant.components.plugwise_usb.async_setup_entry", return_value=True, ) as mock_setup: yield mock_setup diff --git a/tests/plugwise_usb/test_config_flow.py b/tests/plugwise_usb/test_config_flow.py index 8f246802..93b5bf5f 100644 --- a/tests/plugwise_usb/test_config_flow.py +++ b/tests/plugwise_usb/test_config_flow.py @@ -7,8 +7,8 @@ from plugwise_usb.exceptions import StickError import pytest -from custom_components.plugwise_usb.config_flow import CONF_MANUAL_PATH -from custom_components.plugwise_usb.const import CONF_USB_PATH, DOMAIN +from homeassistant.components.plugwise_usb.config_flow import CONF_MANUAL_PATH +from homeassistant.components.plugwise_usb.const import CONF_USB_PATH, DOMAIN from homeassistant.components.usb import USBDevice from homeassistant.config_entries import SOURCE_USER, ConfigFlowResult from homeassistant.const import CONF_SOURCE @@ -28,7 +28,7 @@ def usb_comports() -> MockFixture: """Mock scan_serial_ports.""" with patch( - "custom_components.plugwise_usb.config_flow.usb.async_scan_serial_ports", + "homeassistant.components.plugwise_usb.config_flow.usb.async_scan_serial_ports", AsyncMock(return_value=[mocked_com_port()]), ) as comports_mock: yield comports_mock From 6bb31c58b7f8a558a06ec51f3e1a935488a2e8ab Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 10:22:27 +0200 Subject: [PATCH 42/54] Use tests.common --- tests/plugwise_usb/conftest.py | 3 ++- tests/plugwise_usb/test_config_flow.py | 3 ++- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/tests/plugwise_usb/conftest.py b/tests/plugwise_usb/conftest.py index e16c7ac6..0d382d01 100644 --- a/tests/plugwise_usb/conftest.py +++ b/tests/plugwise_usb/conftest.py @@ -11,7 +11,8 @@ from homeassistant.components.plugwise_usb.const import CONF_USB_PATH, DOMAIN from homeassistant.core import HomeAssistant -from pytest_homeassistant_custom_component.common import MockConfigEntry +# from pytest_homeassistant_custom_component.common import MockConfigEntry +from tests.common import MockConfigEntry STICK_IMPORT_MOCK: Final[str] = "homeassistant.components.plugwise_usb.config_flow.Stick" TEST_MAC: Final[str] = "01:23:45:67:AB" diff --git a/tests/plugwise_usb/test_config_flow.py b/tests/plugwise_usb/test_config_flow.py index 93b5bf5f..36894014 100644 --- a/tests/plugwise_usb/test_config_flow.py +++ b/tests/plugwise_usb/test_config_flow.py @@ -14,7 +14,8 @@ from homeassistant.const import CONF_SOURCE from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType, InvalidData -from pytest_homeassistant_custom_component.common import MockConfigEntry +# from pytest_homeassistant_custom_component.common import MockConfigEntry +from tests.common import MockConfigEntry type MockFixture = Generator[MagicMock | AsyncMock] From e8292f22b78787208584ca983fff96b9949ee5c0 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 10:29:20 +0200 Subject: [PATCH 43/54] Adapt missed line --- scripts/ci-core-testing.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index 23221af3..5800aff8 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -280,7 +280,7 @@ if [ -z "${GITHUB_ACTIONS}" ]; then echo -e "${CINFO}Copy back modified files ...${CNORM}" echo "" cp -r ./homeassistant/components/${REPO_NAME} ../custom_components/ - cp -r ./tests/components/${REPO_NAME}/*py ../tests/ + cp -r ./tests/components/${REPO_NAME}/ ../tests/ echo -e "${CINFO}Removing 'version' from manifest for hassfest-ing, version not allowed in core components${CNORM}" echo "" # shellcheck disable=SC2090 From 578f57504f39db7a5b9857f21b4c7ace3cb63eb6 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 10:32:35 +0200 Subject: [PATCH 44/54] Clean up --- .prettierrc.js | 24 +++++++++++++++++++ .../plugwise_usb/binary_sensor.py | 2 -- custom_components/plugwise_usb/button.py | 2 -- custom_components/plugwise_usb/config_flow.py | 2 -- custom_components/plugwise_usb/entity.py | 2 -- custom_components/plugwise_usb/event.py | 2 -- custom_components/plugwise_usb/number.py | 2 -- custom_components/plugwise_usb/select.py | 2 -- custom_components/plugwise_usb/sensor.py | 2 -- custom_components/plugwise_usb/switch.py | 2 -- 10 files changed, 24 insertions(+), 18 deletions(-) create mode 100644 .prettierrc.js diff --git a/.prettierrc.js b/.prettierrc.js new file mode 100644 index 00000000..3f046af9 --- /dev/null +++ b/.prettierrc.js @@ -0,0 +1,24 @@ +/** @type {import("prettier").Config} */ +module.exports = { + overrides: [ + { + files: "./custom_components/**/*.json", + options: { + plugins: [require.resolve("prettier-plugin-sort-json")], + jsonRecursiveSort: true, + jsonSortOrder: JSON.stringify({ [/.*/]: "numeric" }), + }, + }, + { + files: ["manifest.json", "./**/brands/*.json"], + options: { + // domain and name should stay at the top + jsonSortOrder: JSON.stringify({ + domain: null, + name: null, + [/.*/]: "numeric", + }), + }, + }, + ], +}; diff --git a/custom_components/plugwise_usb/binary_sensor.py b/custom_components/plugwise_usb/binary_sensor.py index 0650447b..47d78dbc 100644 --- a/custom_components/plugwise_usb/binary_sensor.py +++ b/custom_components/plugwise_usb/binary_sensor.py @@ -1,7 +1,5 @@ """Plugwise USB Binary Sensor component for Home Assistant.""" -from __future__ import annotations - from dataclasses import dataclass from datetime import timedelta import logging diff --git a/custom_components/plugwise_usb/button.py b/custom_components/plugwise_usb/button.py index 4151e205..616f52c2 100644 --- a/custom_components/plugwise_usb/button.py +++ b/custom_components/plugwise_usb/button.py @@ -1,7 +1,5 @@ """Plugwise USB Button component for HomeAssistant.""" -from __future__ import annotations - from dataclasses import dataclass from datetime import timedelta import logging diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index 8424acf0..029a5122 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -1,7 +1,5 @@ """Config flow for Plugwise USB integration.""" -from __future__ import annotations - from typing import Any from plugwise_usb import Stick diff --git a/custom_components/plugwise_usb/entity.py b/custom_components/plugwise_usb/entity.py index 0bc511c4..3d5ae77d 100644 --- a/custom_components/plugwise_usb/entity.py +++ b/custom_components/plugwise_usb/entity.py @@ -1,7 +1,5 @@ """Plugwise USB stick base entity.""" -from __future__ import annotations - from dataclasses import dataclass import logging diff --git a/custom_components/plugwise_usb/event.py b/custom_components/plugwise_usb/event.py index 26eb059e..981fda37 100644 --- a/custom_components/plugwise_usb/event.py +++ b/custom_components/plugwise_usb/event.py @@ -1,7 +1,5 @@ """Plugwise USB Event component for HomeAssistant.""" -from __future__ import annotations - from dataclasses import dataclass from datetime import timedelta import logging diff --git a/custom_components/plugwise_usb/number.py b/custom_components/plugwise_usb/number.py index 267486cf..9b3d0934 100644 --- a/custom_components/plugwise_usb/number.py +++ b/custom_components/plugwise_usb/number.py @@ -1,7 +1,5 @@ """Plugwise USB Number component for HomeAssistant.""" -from __future__ import annotations - from dataclasses import dataclass from datetime import timedelta import logging diff --git a/custom_components/plugwise_usb/select.py b/custom_components/plugwise_usb/select.py index 3764e86d..a500635b 100644 --- a/custom_components/plugwise_usb/select.py +++ b/custom_components/plugwise_usb/select.py @@ -1,7 +1,5 @@ """Plugwise USB Select component for HomeAssistant.""" -from __future__ import annotations - from dataclasses import dataclass from datetime import timedelta from enum import Enum diff --git a/custom_components/plugwise_usb/sensor.py b/custom_components/plugwise_usb/sensor.py index 3210b6d9..1a4e37d7 100644 --- a/custom_components/plugwise_usb/sensor.py +++ b/custom_components/plugwise_usb/sensor.py @@ -1,7 +1,5 @@ """Plugwise USB Sensor component for Home Assistant.""" -from __future__ import annotations - from dataclasses import dataclass from datetime import timedelta import logging diff --git a/custom_components/plugwise_usb/switch.py b/custom_components/plugwise_usb/switch.py index 0ea745b5..c485d07a 100644 --- a/custom_components/plugwise_usb/switch.py +++ b/custom_components/plugwise_usb/switch.py @@ -1,7 +1,5 @@ """Plugwise USB Switch component for HomeAssistant.""" -from __future__ import annotations - from dataclasses import dataclass from datetime import timedelta import logging From 2f09c8b5ae810ea9804f0e7a3afc7aac2c4f0e69 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 10:43:23 +0200 Subject: [PATCH 45/54] Fix path in ruff.toml --- tests/plugwise_usb/ruff.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/plugwise_usb/ruff.toml b/tests/plugwise_usb/ruff.toml index 9e07cdcb..33a56305 100644 --- a/tests/plugwise_usb/ruff.toml +++ b/tests/plugwise_usb/ruff.toml @@ -1,6 +1,6 @@ # This extend our general Ruff rules specifically for tests -extend = "../pyproject.toml" +extend = "../../../pyproject.toml" [lint] From 1af335cfc97ee74cd65efc71d5901e81d4160755 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 10:53:24 +0200 Subject: [PATCH 46/54] Ruffed --- tests/plugwise_usb/conftest.py | 3 +-- tests/plugwise_usb/test_config_flow.py | 1 + 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/plugwise_usb/conftest.py b/tests/plugwise_usb/conftest.py index 0d382d01..d21dbb5d 100644 --- a/tests/plugwise_usb/conftest.py +++ b/tests/plugwise_usb/conftest.py @@ -1,7 +1,5 @@ """Setup mocks for the Plugwise USB integration tests.""" -from __future__ import annotations - from collections.abc import Generator from typing import Final from unittest.mock import AsyncMock, MagicMock, patch @@ -11,6 +9,7 @@ from homeassistant.components.plugwise_usb.const import CONF_USB_PATH, DOMAIN from homeassistant.core import HomeAssistant + # from pytest_homeassistant_custom_component.common import MockConfigEntry from tests.common import MockConfigEntry diff --git a/tests/plugwise_usb/test_config_flow.py b/tests/plugwise_usb/test_config_flow.py index 36894014..a04a2786 100644 --- a/tests/plugwise_usb/test_config_flow.py +++ b/tests/plugwise_usb/test_config_flow.py @@ -14,6 +14,7 @@ from homeassistant.const import CONF_SOURCE from homeassistant.core import HomeAssistant from homeassistant.data_entry_flow import FlowResultType, InvalidData + # from pytest_homeassistant_custom_component.common import MockConfigEntry from tests.common import MockConfigEntry From cbe5a3d42bafccdc69bc9ac6bb96aadb7db890c0 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 10:55:23 +0200 Subject: [PATCH 47/54] Move config files to top-dir --- tests/{plugwise_usb => }/bandit.yaml | 0 tests/{plugwise_usb => }/ruff.toml | 2 +- 2 files changed, 1 insertion(+), 1 deletion(-) rename tests/{plugwise_usb => }/bandit.yaml (100%) rename tests/{plugwise_usb => }/ruff.toml (91%) diff --git a/tests/plugwise_usb/bandit.yaml b/tests/bandit.yaml similarity index 100% rename from tests/plugwise_usb/bandit.yaml rename to tests/bandit.yaml diff --git a/tests/plugwise_usb/ruff.toml b/tests/ruff.toml similarity index 91% rename from tests/plugwise_usb/ruff.toml rename to tests/ruff.toml index 33a56305..19e55e0d 100644 --- a/tests/plugwise_usb/ruff.toml +++ b/tests/ruff.toml @@ -1,6 +1,6 @@ # This extend our general Ruff rules specifically for tests -extend = "../../../pyproject.toml" +extend = "../../pyproject.toml" [lint] From 8c0219ff0d4ceefb20dc046d2f6727ed67b121d0 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 11:03:38 +0200 Subject: [PATCH 48/54] Implement suggested improvements --- scripts/ci-core-testing.sh | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index 5800aff8..7865889d 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -74,7 +74,7 @@ venv_and_uv() { script/setup fi if ! [ -x "$(command -v pytest)" ]; then - uv pip install pytest + uv pip install --only-binary :all: pytest fi } @@ -123,7 +123,7 @@ mkdir -p "${coredir}" if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then # If only dir exists, but not cloned yet - if [ ! -f "${coredir}/requirements_test.txt" ]; then + if [[ ! -f "${coredir}/requirements_test.txt" ]]; then if [ -d "${manualdir}" ]; then echo "" echo -e "${CINFO} ** Reusing copy, rebasing and copy to HA core**${CNORM}" @@ -143,7 +143,7 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then git clone https://github.com/home-assistant/core.git "${coredir}" cp -a "${coredir}." "${manualdir}" fi - if [ ! -f "${coredir}/requirements_test.txt" ]; then + if [[ ! -f "${coredir}/requirements_test.txt" ]]; then echo "" echo -e "${CFAIL}Cloning failed .. make sure ${coredir} exists and is an empty directory${CNORM}" echo "" From 399c9c647c4b3e1c213e344dbe425a3e23cad63b Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 11:07:45 +0200 Subject: [PATCH 49/54] Fix typo --- scripts/ci-core-testing.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index 7865889d..e1559aaa 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -37,7 +37,7 @@ ulimit -n 65536 # if you fancy more options (i.e. show test results) # run as "scripts/core_testing.sh test_config_flow.py -rP" # -# If you want to prepare for Core PR, run ass +# If you want to prepare for Core PR, run as # "COMMIT_CHECK=true scripts/core_testing.sh" echo "" From d66fef5befcb371de890ed35472b237a9bdcfee4 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 11:08:17 +0200 Subject: [PATCH 50/54] Delete saved .js file --- .prettierrc.js | 24 ------------------------ 1 file changed, 24 deletions(-) delete mode 100644 .prettierrc.js diff --git a/.prettierrc.js b/.prettierrc.js deleted file mode 100644 index 3f046af9..00000000 --- a/.prettierrc.js +++ /dev/null @@ -1,24 +0,0 @@ -/** @type {import("prettier").Config} */ -module.exports = { - overrides: [ - { - files: "./custom_components/**/*.json", - options: { - plugins: [require.resolve("prettier-plugin-sort-json")], - jsonRecursiveSort: true, - jsonSortOrder: JSON.stringify({ [/.*/]: "numeric" }), - }, - }, - { - files: ["manifest.json", "./**/brands/*.json"], - options: { - // domain and name should stay at the top - jsonSortOrder: JSON.stringify({ - domain: null, - name: null, - [/.*/]: "numeric", - }), - }, - }, - ], -}; From b0f56713922fd21449fe50d8b9235c4b538c9f55 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 11:09:17 +0200 Subject: [PATCH 51/54] Remove validation of prettierrc changes --- scripts/ci-core-testing.sh | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/ci-core-testing.sh b/scripts/ci-core-testing.sh index e1559aaa..48222210 100755 --- a/scripts/ci-core-testing.sh +++ b/scripts/ci-core-testing.sh @@ -199,15 +199,6 @@ if [ -z "${GITHUB_ACTIONS}" ] || [ "$1" == "core_prep" ] ; then cp -r ../custom_components/${REPO_NAME} ./homeassistant/components/ cp -r ../tests/${REPO_NAME} ./tests/components/ - echo "" - - echo -e "${CINFO}Validating prettierrc changes${CNORM}" - prettierrc=".prettierrc.js" - if ! diff -q <(sed 's/homeassistant/custom_components/g' "${prettierrc}") "../${prettierrc}" >/dev/null; then - echo -e "${CWARN}Updating prettierrc from core${CNORM}" - sed 's/homeassistant/custom_components/g' "${prettierrc}" > "../${prettierrc}" - fi - fi # core_prep set +u From 2a6ecbc1356fd4e39e523672b9ee233a7010ab1f Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 11:12:17 +0200 Subject: [PATCH 52/54] Update CHANGELOG --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index e56a82bb..d0226917 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,7 @@ ## v0.59.3 +- General environment and code updates, improve (test)files structure - Bump python to 3.14 - Link to plugwise_usb [v0.47.8](https://github.com/plugwise/python-plugwise-usb/releases/tag/v0.47.8), rework to using the HA USB platform From 9a840eadbed3faeda7999bbcaa871fd3d8b05c19 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 11:26:32 +0200 Subject: [PATCH 53/54] Set to v0.59.3 release-version --- custom_components/plugwise_usb/manifest.json | 2 +- pyproject.toml | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/custom_components/plugwise_usb/manifest.json b/custom_components/plugwise_usb/manifest.json index d6a9d509..ace55a6e 100644 --- a/custom_components/plugwise_usb/manifest.json +++ b/custom_components/plugwise_usb/manifest.json @@ -10,5 +10,5 @@ "issue_tracker": "https://github.com/plugwise/python-plugwise-usb/issues", "loggers": ["plugwise_usb"], "requirements": ["plugwise-usb==0.47.8"], - "version": "0.59.2" + "version": "0.59.3" } diff --git a/pyproject.toml b/pyproject.toml index e4911a61..a1f89188 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [project] name = "plugwise_usb-beta" -version = "0.59.3a1" +version = "0.59.3" description = "Plugwise USB custom_component (BETA)" readme = "README.md" requires-python = ">=3.14" From 26ab8f4c24fef87d2cb44d75f18c135e42fb6809 Mon Sep 17 00:00:00 2001 From: Bouwe Westerdijk Date: Sat, 5 Sep 2026 11:47:08 +0200 Subject: [PATCH 54/54] Implement suggested improvements --- custom_components/plugwise_usb/config_flow.py | 7 +++++-- custom_components/plugwise_usb/coordinator.py | 1 + tests/ruff.toml | 2 +- 3 files changed, 7 insertions(+), 3 deletions(-) diff --git a/custom_components/plugwise_usb/config_flow.py b/custom_components/plugwise_usb/config_flow.py index 029a5122..ad0cc527 100644 --- a/custom_components/plugwise_usb/config_flow.py +++ b/custom_components/plugwise_usb/config_flow.py @@ -69,12 +69,15 @@ async def async_step_user( ) -> FlowResult: """Step when user initializes a integration.""" errors: dict[str, str] = {} - ports = await usb.async_scan_serial_ports(self.hass) + ports = [ + port + for port in await usb.async_scan_serial_ports(self.hass) + if isinstance(port, usb.USBDevice) + ] list_of_ports = [ f"{port.device}, s/n: {port.serial_number or 'n/a'}" + (f" - {port.manufacturer}" if port.manufacturer else "") for port in ports - if isinstance(port, usb.USBDevice) ] list_of_ports.append(CONF_MANUAL_PATH) diff --git a/custom_components/plugwise_usb/coordinator.py b/custom_components/plugwise_usb/coordinator.py index 06010071..8f98bc61 100644 --- a/custom_components/plugwise_usb/coordinator.py +++ b/custom_components/plugwise_usb/coordinator.py @@ -54,6 +54,7 @@ def __init__( super().__init__( hass, _LOGGER, + config_entry=config_entry, name=node.node_info.name, update_interval=timedelta(seconds=15), update_method=self.async_node_update, diff --git a/tests/ruff.toml b/tests/ruff.toml index 19e55e0d..9e07cdcb 100644 --- a/tests/ruff.toml +++ b/tests/ruff.toml @@ -1,6 +1,6 @@ # This extend our general Ruff rules specifically for tests -extend = "../../pyproject.toml" +extend = "../pyproject.toml" [lint]