Skip to content

Commit f1faa17

Browse files
Redesign POINTTAPI Boost controls and installation settings (#34)
* Redesign POINTTAPI Boost and installation settings * Translate POINTTAPI Boost climate preset * Translate Boost climate preset states * Cover native Boost restart handling * Address PR #34 review comments: serialize boost locks, unique_id migration, decouple platforms, and update docs --------- Co-authored-by: Casey Romkes <mail@casey.berlin>
1 parent 7cf2c83 commit f1faa17

17 files changed

Lines changed: 1073 additions & 369 deletions

CHANGELOG.md

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,17 @@
22

33
All notable changes to this Bosch Home Assistant custom component will be documented in this file.
44

5+
## [Unreleased]
6+
7+
### Added
8+
- **Native-first Boost controls** — Redesigned POINTTAPI Boost controls with dedicated per-zone switches (`switch.*_boost`), serialized multi-zone activation via `asyncio.Lock` to prevent race conditions on rapid toggles, and integration into climate preset modes (`boost` / `none`) across all locales (#34).
9+
- **Dedicated Heating Circuit (`hc1`) device partition** — Moved circuit-level heating settings away from individual room thermostat devices to a dedicated **Heating Installation** (`/heatingCircuits/hc1`) device to accurately reflect hardware topology.
10+
- **Before:** Global circuit settings (e.g. supply limits, heating slope, boost duration/temperature) were incorrectly attached to the `zn1` room device (Zone 1 / Thermostat), duplicating or misattributing installation-wide properties.
11+
- **After:** Supply limits (`supplyTemperatureLimitMax`, `supplyTemperatureLimitMin`), heating dynamics (`heatupCoolingSlope`, `buildingHeatup`), and global Boost settings (`boostTemperature`, `boostDuration`, `boostRemainingTime`) are properly assigned to the Heating Circuit (`/heatingCircuits/hc1`) device, ensuring clean device separation in Home Assistant (#34).
12+
13+
### Changed
14+
- **Read-only number paths** — Number entities for POINTTAPI resources that are read-only (`writeable: 0` or `False`) are now hidden/unavailable, ensuring number entities only represent interactive setpoints and controls (#34).
15+
516
## [1.5.1-beta.1] — 2026-08-31
617

718
### Fixed

custom_components/bosch/__init__.py

Lines changed: 52 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -296,44 +296,63 @@ async def async_update_options(hass: HomeAssistant, entry: ConfigEntry):
296296

297297

298298
async def async_migrate_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool:
299-
"""Migrate POINTTAPI entity_ids from v0.30.x to v0.31.0 device-partition scheme.
299+
"""Migrate POINTTAPI entry versions.
300300
301-
Idempotent: returns True immediately on already-migrated entries.
302-
Fault-tolerant: per-rename try/except so one failure doesn't abort the batch.
303-
Bumps entry.version 1 → 2 after all renames are attempted.
301+
- v1 -> v2: entity_id renames (device-partition scheme)
302+
- v2 -> v3: unique_id rename for boost switch (per-zone unique_id)
304303
"""
305-
if entry.version >= 2:
306-
return True
307-
if entry.data.get(CONF_PROTOCOL) != POINTTAPI:
308-
hass.config_entries.async_update_entry(entry, version=2)
304+
if entry.version >= 3:
309305
return True
310306

311-
from homeassistant.helpers import entity_registry as er
312-
registry = er.async_get(hass)
313-
renames = {
314-
# solar_solar_* doubled prefix cleanup
315-
"sensor.solar_solar_collector_temperature": "sensor.solar_collector_temperature",
316-
"sensor.solar_solar_storage_temperature": "sensor.solar_storage_temperature",
317-
"sensor.solar_solar_pump_modulation": "sensor.solar_pump_modulation",
318-
"sensor.solar_total_solar_gain": "sensor.solar_total_gain",
319-
# water_heater rename
320-
"water_heater.water_heater": "water_heater.hot_water_tank",
321-
}
322-
renamed = 0
323-
for old_id, new_id in renames.items():
324-
try:
325-
if registry.async_get(old_id) and not registry.async_get(new_id):
326-
registry.async_update_entity(old_id, new_entity_id=new_id)
327-
renamed += 1
328-
except Exception as err: # pylint: disable=broad-except
329-
_LOGGER.warning(
330-
"Migration could not rename %s -> %s: %s", old_id, new_id, err
307+
if entry.version < 2:
308+
if entry.data.get(CONF_PROTOCOL) == POINTTAPI:
309+
from homeassistant.helpers import entity_registry as er
310+
registry = er.async_get(hass)
311+
renames = {
312+
# solar_solar_* doubled prefix cleanup
313+
"sensor.solar_solar_collector_temperature": "sensor.solar_collector_temperature",
314+
"sensor.solar_solar_storage_temperature": "sensor.solar_storage_temperature",
315+
"sensor.solar_solar_pump_modulation": "sensor.solar_pump_modulation",
316+
"sensor.solar_total_solar_gain": "sensor.solar_total_gain",
317+
# water_heater rename
318+
"water_heater.water_heater": "water_heater.hot_water_tank",
319+
}
320+
renamed = 0
321+
for old_id, new_id in renames.items():
322+
try:
323+
if registry.async_get(old_id) and not registry.async_get(new_id):
324+
registry.async_update_entity(old_id, new_entity_id=new_id)
325+
renamed += 1
326+
except Exception as err: # pylint: disable=broad-except
327+
_LOGGER.warning(
328+
"Migration could not rename %s -> %s: %s", old_id, new_id, err
329+
)
330+
_LOGGER.info(
331+
"Migrated POINTTAPI entry from version 1 to 2 (%d entity_ids renamed)",
332+
renamed,
331333
)
332-
hass.config_entries.async_update_entry(entry, version=2)
333-
_LOGGER.info(
334-
"Migrated POINTTAPI entry from version 1 to 2 (%d entity_ids renamed)",
335-
renamed,
336-
)
334+
hass.config_entries.async_update_entry(entry, version=2)
335+
336+
if entry.version < 3:
337+
if entry.data.get(CONF_PROTOCOL) == POINTTAPI:
338+
from homeassistant.helpers import entity_registry as er
339+
registry = er.async_get(hass)
340+
old_unique_id = f"{entry.entry_id}_pointtapi_boost"
341+
new_unique_id = f"{entry.entry_id}_pointtapi_boost_zone_1"
342+
try:
343+
entity_id = registry.async_get_entity_id("switch", DOMAIN, old_unique_id)
344+
if entity_id:
345+
registry.async_update_entity(entity_id, new_unique_id=new_unique_id)
346+
_LOGGER.info(
347+
"Migrated POINTTAPI boost switch unique_id %s -> %s for entity %s",
348+
old_unique_id, new_unique_id, entity_id,
349+
)
350+
except Exception as err: # pylint: disable=broad-except
351+
_LOGGER.warning(
352+
"Migration could not update unique_id %s: %s", old_unique_id, err
353+
)
354+
hass.config_entries.async_update_entry(entry, version=3)
355+
337356
return True
338357

339358

0 commit comments

Comments
 (0)