From 4b190adadca10e17cd59f29ef78c8f4b38072fe5 Mon Sep 17 00:00:00 2001 From: Rein de Vries Date: Mon, 16 Feb 2026 16:58:13 +0100 Subject: [PATCH 1/4] fix: ci issues --- custom_components/boiler_controller/manifest.json | 4 ++-- custom_components/boiler_controller/translations/en.json | 6 +++++- custom_components/boiler_controller/translations/nl.json | 6 +++++- 3 files changed, 12 insertions(+), 4 deletions(-) diff --git a/custom_components/boiler_controller/manifest.json b/custom_components/boiler_controller/manifest.json index dea0833..669a26a 100644 --- a/custom_components/boiler_controller/manifest.json +++ b/custom_components/boiler_controller/manifest.json @@ -8,11 +8,11 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/BoilerController/boiler-controller-ha/issues", "requirements": [], + "version": "0.1.0", "zeroconf": [ { "type": "_http._tcp.local.", "name": "shelly0110dimg3-*" }, { "type": "_http._tcp.local.", "name": "shellyplusdimg3-*" }, { "type": "_shelly._tcp.local.", "name": "shelly0110dimg3-*" }, { "type": "_shelly._tcp.local.", "name": "shellyplusdimg3-*" } - ], - "version": "0.1.0" + ] } diff --git a/custom_components/boiler_controller/translations/en.json b/custom_components/boiler_controller/translations/en.json index 4c64189..c71573e 100644 --- a/custom_components/boiler_controller/translations/en.json +++ b/custom_components/boiler_controller/translations/en.json @@ -17,7 +17,11 @@ }, "shelly_config": { "title": "Configure Shelly Device", - "description": "Enter the Shelly URL or IP address. If you started this flow from a discovered device we will pre-fill the field for you (e.g. http://shelly0110dimg3-xxxx.local or http://shellyplusdimg3-xxxx.local).", + "description": "Enter the Shelly URL or IP address. If you started this flow from a discovered device we will pre-fill the field for you (e.g. {example_url1} or {example_url2}).", + "description_placeholders": { + "example_url1": "http://shelly0110dimg3-xxxx.local", + "example_url2": "http://shellyplusdimg3-xxxx.local" + }, "data": { "shelly_url": "Shelly Base URL" } diff --git a/custom_components/boiler_controller/translations/nl.json b/custom_components/boiler_controller/translations/nl.json index 003bc96..62fd115 100644 --- a/custom_components/boiler_controller/translations/nl.json +++ b/custom_components/boiler_controller/translations/nl.json @@ -17,7 +17,11 @@ }, "shelly_config": { "title": "Shelly Configureren", - "description": "Vul de Shelly RPC basis URL in. Startte je deze flow vanuit een gevonden apparaat? Dan vullen we dit veld alvast voor je in (bijv. http://shelly0110dimg3-xxxx.local of http://shellyplusdimg3-xxxx.local).", + "description": "Vul de Shelly RPC basis URL in. Startte je deze flow vanuit een gevonden apparaat? Dan vullen we dit veld alvast voor je in (bijv. {example_url1} of {example_url2}).", + "description_placeholders": { + "example_url1": "http://shelly0110dimg3-xxxx.local", + "example_url2": "http://shellyplusdimg3-xxxx.local" + }, "data": { "shelly_url": "Shelly Basis URL" } From 83a892a184d5439bf0648239aa900219ad4346d1 Mon Sep 17 00:00:00 2001 From: Rein de Vries Date: Mon, 16 Feb 2026 16:58:56 +0100 Subject: [PATCH 2/4] chore: update version number --- custom_components/boiler_controller/manifest.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom_components/boiler_controller/manifest.json b/custom_components/boiler_controller/manifest.json index 669a26a..3739182 100644 --- a/custom_components/boiler_controller/manifest.json +++ b/custom_components/boiler_controller/manifest.json @@ -8,7 +8,7 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/BoilerController/boiler-controller-ha/issues", "requirements": [], - "version": "0.1.0", + "version": "1.0.0", "zeroconf": [ { "type": "_http._tcp.local.", "name": "shelly0110dimg3-*" }, { "type": "_http._tcp.local.", "name": "shellyplusdimg3-*" }, From 986d34869cbf8b7ed165abac6f6551545843a5eb Mon Sep 17 00:00:00 2001 From: Rein de Vries Date: Mon, 16 Feb 2026 17:18:28 +0100 Subject: [PATCH 3/4] fix: version and translations --- .../boiler_controller/__init__.py | 13 +++- custom_components/boiler_controller/button.py | 6 +- .../boiler_controller/config_flow.py | 10 ++- custom_components/boiler_controller/const.py | 2 +- .../boiler_controller/controller.py | 4 +- custom_components/boiler_controller/number.py | 4 +- custom_components/boiler_controller/select.py | 4 +- custom_components/boiler_controller/sensor.py | 6 +- .../boiler_controller/strings.json | 65 +++++++++++++++++++ .../boiler_controller/translations/en.json | 4 -- .../boiler_controller/translations/nl.json | 6 +- 11 files changed, 104 insertions(+), 20 deletions(-) create mode 100644 custom_components/boiler_controller/strings.json diff --git a/custom_components/boiler_controller/__init__.py b/custom_components/boiler_controller/__init__.py index 62ab448..835e957 100644 --- a/custom_components/boiler_controller/__init__.py +++ b/custom_components/boiler_controller/__init__.py @@ -37,8 +37,17 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Set up Boiler Controller from a config entry.""" _LOGGER.info("Setting up Boiler Controller") - integration = await async_get_integration(hass, DOMAIN) - integration_version = integration.version + from .const import VERSION + + try: + integration = await async_get_integration(hass, DOMAIN) + integration_version = integration.version + except Exception as err: # pylint: disable=broad-except + _LOGGER.warning("Could not get integration version: %s, using fallback", err) + integration_version = None + + # Ensure we always have a valid version string + integration_version = str(integration_version) if integration_version else VERSION # Create the controller controller = BoilerController(hass, entry, integration_version) diff --git a/custom_components/boiler_controller/button.py b/custom_components/boiler_controller/button.py index aaa3bd2..49c5077 100644 --- a/custom_components/boiler_controller/button.py +++ b/custom_components/boiler_controller/button.py @@ -13,6 +13,7 @@ from .const import ( DOMAIN, + VERSION, CALIBRATION_START_PERCENTAGE, CALIBRATION_END_PERCENTAGE, CALIBRATION_STEP_PERCENTAGE, @@ -23,13 +24,14 @@ def _device_info(config_entry: ConfigEntry, controller) -> Dict[str, Any]: - version = controller.integration_version or str(config_entry.version) + from .const import VERSION + version = controller.integration_version if controller.integration_version else VERSION return { "identifiers": {(DOMAIN, config_entry.entry_id)}, "name": config_entry.title, "manufacturer": "Boiler Controller", "model": "P1 to Shelly Controller", - "sw_version": version, + "sw_version": str(version), } diff --git a/custom_components/boiler_controller/config_flow.py b/custom_components/boiler_controller/config_flow.py index 13b81d5..3ec15da 100644 --- a/custom_components/boiler_controller/config_flow.py +++ b/custom_components/boiler_controller/config_flow.py @@ -270,7 +270,11 @@ async def async_step_shelly_config(self, user_input=None): return self.async_show_form( step_id="shelly_config", data_schema=schema, - errors=errors + errors=errors, + description_placeholders={ + "example_url1": "http://shelly0110dimg3-xxxx.local", + "example_url2": "http://shellyplusdimg3-xxxx.local" + } ) async def _get_power_sensors(self): @@ -420,6 +424,10 @@ async def async_step_shelly_config(self, user_input=None): step_id="shelly_config", data_schema=schema, errors=errors, + description_placeholders={ + "example_url1": "http://shelly0110dimg3-xxxx.local", + "example_url2": "http://shellyplusdimg3-xxxx.local" + } ) async def _get_power_sensors(self): diff --git a/custom_components/boiler_controller/const.py b/custom_components/boiler_controller/const.py index 8d7b85a..e92b95e 100644 --- a/custom_components/boiler_controller/const.py +++ b/custom_components/boiler_controller/const.py @@ -1,5 +1,5 @@ DOMAIN = "boiler_controller" -VERSION = "0.1.0" +VERSION = "1.0.0" PLATFORMS = ["sensor", "select", "number", "button"] diff --git a/custom_components/boiler_controller/controller.py b/custom_components/boiler_controller/controller.py index c8d25b8..b155bf4 100644 --- a/custom_components/boiler_controller/controller.py +++ b/custom_components/boiler_controller/controller.py @@ -365,12 +365,14 @@ async def _set_dimmer_percentage(self, percentage: int, *, source: str = DIMMER_ @property def device_info(self): """Return device information.""" + from .const import VERSION as DEFAULT_VERSION + version = self.integration_version if self.integration_version else DEFAULT_VERSION return { "identifiers": {(DOMAIN, self.config_entry.entry_id)}, "name": self.config_entry.title, "manufacturer": "Boiler Controller", "model": "P1 to Dimmer Controller", - "sw_version": self.integration_version or str(self.config_entry.version), + "sw_version": str(version), } def get_status(self): diff --git a/custom_components/boiler_controller/number.py b/custom_components/boiler_controller/number.py index 71906e6..6fd9497 100644 --- a/custom_components/boiler_controller/number.py +++ b/custom_components/boiler_controller/number.py @@ -84,10 +84,12 @@ def available(self) -> bool: @property def device_info(self): + from .const import VERSION as DEFAULT_VERSION + version = self.controller.integration_version if self.controller.integration_version else DEFAULT_VERSION return { "identifiers": {(DOMAIN, self.config_entry.entry_id)}, "name": self.config_entry.title, "manufacturer": "Boiler Controller", "model": "P1 to Shelly Controller", - "sw_version": self.controller.integration_version or str(self.config_entry.version), + "sw_version": str(version), } diff --git a/custom_components/boiler_controller/select.py b/custom_components/boiler_controller/select.py index fe5c7db..2a40afc 100644 --- a/custom_components/boiler_controller/select.py +++ b/custom_components/boiler_controller/select.py @@ -81,10 +81,12 @@ def available(self) -> bool: @property def device_info(self): + from .const import VERSION as DEFAULT_VERSION + version = self.controller.integration_version if self.controller.integration_version else DEFAULT_VERSION return { "identifiers": {(DOMAIN, self.config_entry.entry_id)}, "name": self.config_entry.title, "manufacturer": "Boiler Controller", "model": "P1 to Shelly Controller", - "sw_version": self.controller.integration_version or str(self.config_entry.version), + "sw_version": str(version), } diff --git a/custom_components/boiler_controller/sensor.py b/custom_components/boiler_controller/sensor.py index 31f9bd7..64efe54 100644 --- a/custom_components/boiler_controller/sensor.py +++ b/custom_components/boiler_controller/sensor.py @@ -38,13 +38,15 @@ UNIT_TEMP = "°C" UNIT_ENERGY = "kWh" -from .const import DOMAIN +from .const import DOMAIN, VERSION _LOGGER = logging.getLogger(__name__) def _integration_version(controller, config_entry: ConfigEntry) -> str: - return controller.integration_version or str(config_entry.version) + from .const import VERSION as DEFAULT_VERSION + version = controller.integration_version if controller.integration_version else DEFAULT_VERSION + return str(version) def _device_info(config_entry: ConfigEntry, controller) -> Dict[str, Any]: diff --git a/custom_components/boiler_controller/strings.json b/custom_components/boiler_controller/strings.json new file mode 100644 index 0000000..1ef0476 --- /dev/null +++ b/custom_components/boiler_controller/strings.json @@ -0,0 +1,65 @@ +{ + "config": { + "step": { + "user": { + "title": "Setup Boiler Controller", + "description": "Select your power sensor and provide the Shelly device details.", + "data": { + "name": "Integration Name" + } + }, + "power_sensor": { + "title": "Select Power Sensor", + "description": "Choose the sensor that provides current power consumption/production data (in Watts)", + "data": { + "p1_total_entity": "Power Sensor" + } + }, + "shelly_config": { + "title": "Configure Shelly Device", + "description": "Enter the Shelly URL or IP address. If you started this flow from a discovered device we will pre-fill the field for you (e.g. {example_url1} or {example_url2}).", + "data": { + "shelly_url": "Shelly Base URL" + } + } + }, + "error": { + "no_power_sensors": "No power sensors found in Home Assistant", + "entity_not_found": "The selected entity was not found", + "no_dimmer_entities": "No light or input_number entities found in Home Assistant", + "invalid_url": "Provide a valid http(s) URL", + "cannot_connect": "Unable to reach the Shelly device", + "cannot_identify": "Unable to read the Shelly device identity", + "device_in_use": "This Shelly device is already configured" + }, + "abort": { + "already_configured": "Boiler Controller is already configured", + "unsupported_device": "The discovered device is not a supported Shelly dimmer" + } + }, + "options": { + "step": { + "init": { + "title": "Boiler Controller Options", + "description": "Switch the power sensor or Shelly device used by this controller", + "data": { + "change_devices": "Change power sensor or Shelly settings" + } + }, + "power_sensor": { + "title": "Select New Power Sensor", + "description": "Choose a new sensor that provides current power consumption/production data (in Watts)", + "data": { + "p1_total_entity": "Power Sensor" + } + }, + "shelly_config": { + "title": "Update Shelly Settings", + "description": "Adjust the Shelly URL. If the device was discovered previously, the current URL is shown here.", + "data": { + "shelly_url": "Shelly Base URL" + } + } + } + } +} diff --git a/custom_components/boiler_controller/translations/en.json b/custom_components/boiler_controller/translations/en.json index c71573e..7b33a23 100644 --- a/custom_components/boiler_controller/translations/en.json +++ b/custom_components/boiler_controller/translations/en.json @@ -18,10 +18,6 @@ "shelly_config": { "title": "Configure Shelly Device", "description": "Enter the Shelly URL or IP address. If you started this flow from a discovered device we will pre-fill the field for you (e.g. {example_url1} or {example_url2}).", - "description_placeholders": { - "example_url1": "http://shelly0110dimg3-xxxx.local", - "example_url2": "http://shellyplusdimg3-xxxx.local" - }, "data": { "shelly_url": "Shelly Base URL" } diff --git a/custom_components/boiler_controller/translations/nl.json b/custom_components/boiler_controller/translations/nl.json index 62fd115..eab4344 100644 --- a/custom_components/boiler_controller/translations/nl.json +++ b/custom_components/boiler_controller/translations/nl.json @@ -17,11 +17,7 @@ }, "shelly_config": { "title": "Shelly Configureren", - "description": "Vul de Shelly RPC basis URL in. Startte je deze flow vanuit een gevonden apparaat? Dan vullen we dit veld alvast voor je in (bijv. {example_url1} of {example_url2}).", - "description_placeholders": { - "example_url1": "http://shelly0110dimg3-xxxx.local", - "example_url2": "http://shellyplusdimg3-xxxx.local" - }, + "description": "Vul de Shelly URL of IP adres in. Startte je deze flow vanuit een gevonden apparaat? Dan vullen we dit veld alvast voor je in (bijv. {example_url1} of {example_url2}).", "data": { "shelly_url": "Shelly Basis URL" } From eb8d049e97fde5462893b28b422069f1e46acffa Mon Sep 17 00:00:00 2001 From: Rein de Vries Date: Mon, 16 Feb 2026 17:20:05 +0100 Subject: [PATCH 4/4] chore: remove unused file strings.json --- .../boiler_controller/strings.json | 65 ------------------- 1 file changed, 65 deletions(-) delete mode 100644 custom_components/boiler_controller/strings.json diff --git a/custom_components/boiler_controller/strings.json b/custom_components/boiler_controller/strings.json deleted file mode 100644 index 1ef0476..0000000 --- a/custom_components/boiler_controller/strings.json +++ /dev/null @@ -1,65 +0,0 @@ -{ - "config": { - "step": { - "user": { - "title": "Setup Boiler Controller", - "description": "Select your power sensor and provide the Shelly device details.", - "data": { - "name": "Integration Name" - } - }, - "power_sensor": { - "title": "Select Power Sensor", - "description": "Choose the sensor that provides current power consumption/production data (in Watts)", - "data": { - "p1_total_entity": "Power Sensor" - } - }, - "shelly_config": { - "title": "Configure Shelly Device", - "description": "Enter the Shelly URL or IP address. If you started this flow from a discovered device we will pre-fill the field for you (e.g. {example_url1} or {example_url2}).", - "data": { - "shelly_url": "Shelly Base URL" - } - } - }, - "error": { - "no_power_sensors": "No power sensors found in Home Assistant", - "entity_not_found": "The selected entity was not found", - "no_dimmer_entities": "No light or input_number entities found in Home Assistant", - "invalid_url": "Provide a valid http(s) URL", - "cannot_connect": "Unable to reach the Shelly device", - "cannot_identify": "Unable to read the Shelly device identity", - "device_in_use": "This Shelly device is already configured" - }, - "abort": { - "already_configured": "Boiler Controller is already configured", - "unsupported_device": "The discovered device is not a supported Shelly dimmer" - } - }, - "options": { - "step": { - "init": { - "title": "Boiler Controller Options", - "description": "Switch the power sensor or Shelly device used by this controller", - "data": { - "change_devices": "Change power sensor or Shelly settings" - } - }, - "power_sensor": { - "title": "Select New Power Sensor", - "description": "Choose a new sensor that provides current power consumption/production data (in Watts)", - "data": { - "p1_total_entity": "Power Sensor" - } - }, - "shelly_config": { - "title": "Update Shelly Settings", - "description": "Adjust the Shelly URL. If the device was discovered previously, the current URL is shown here.", - "data": { - "shelly_url": "Shelly Base URL" - } - } - } - } -}