Skip to content

Lay Groundwork for Reference-Driven Device and Program Data Fetch - #17

Merged
CaseyRo merged 40 commits into
CaseyRo:masterfrom
jfhautenauven:feature/french-translations
Aug 11, 2026
Merged

Lay Groundwork for Reference-Driven Device and Program Data Fetch#17
CaseyRo merged 40 commits into
CaseyRo:masterfrom
jfhautenauven:feature/french-translations

Conversation

@jfhautenauven

@jfhautenauven jfhautenauven commented Aug 11, 2026

Copy link
Copy Markdown
Contributor

🚀 Improve POINTTAPI Discovery, Climate Behavior & Entity Modeling
📋 Summary

This PR significantly improves the POINTTAPI integration by making data discovery more reference-driven, improving climate behavior, adding missing high-value entities, and refining device grouping and localization for a better Home Assistant UX.

The discovery strategy for Zones, Programs, and Devices is now more consistent and adaptable to different POINTTAPI implementations, while preserving safe fallback behavior for existing installations.

✨ What changed

  1. 🔎 Reference-Driven Discovery & Coordinator Improvements

Programs and Devices now follow the same reference-driven discovery model already used for Zones.

📅 Dynamic Program discovery
Uses /programs references to dynamically discover the appropriate resources.
Added dynamic expansion of Program resources instead of relying exclusively on static paths.
📱 Dynamic Device discovery
Uses /devices references to dynamically discover available Device resources.
Added dynamic expansion of Device resources instead of relying exclusively on static paths.
🛡️ Safe fallback behavior

Discovery remains resilient when reference-based discovery is unavailable:

Programs discovery unavailable → falls back to fetching /programs
Devices discovery unavailable → falls back to fetching /devices

This makes entity creation more robust across installations with different gateway capabilities.

  1. 🌡️ Climate Behavior Fixes

Improved the handling of zone operating modes and climate state:

Implemented explicit program/manual semantics for zone operation.
Improved HVAC mode handling and write behavior for user mode updates.
Added more accurate hvac_action mapping, including:
idle
heat
heat-request states

These changes make the exposed Home Assistant climate behavior better match the expected POINTTAPI semantics.

  1. 🔧 Thermostat Valve Modeling

Added dynamic per-thermostat-valve entities based on /devices/list.

Each valve now exposes dedicated diagnostics:

📶 Signal strength
🔋 Battery
🏠 Assigned zone
📡 Protocol

Added proper warning handling through a dedicated binary problem sensor:

0 → ✅ No warning
Non-zero → ⚠️ Attention required

Each valve also receives its own device mapping, with valve names properly decoded from the gateway data.

  1. 📅 Assigned Program per Zone

Added a dedicated per-zone sensor displaying the currently assigned program name.

The mapping is resolved dynamically:

zone clockProgram → program ID → /programs/pgN/name

Program names are automatically Base64-decoded.

The implementation is resilient to incomplete data:

Missing program mapping → returns None
Missing program name → falls back to the program ID
Helpful attributes are exposed, including:
Program ID
Program path
5. ⚡ Energy Device & Electricity Averages

Energy-related entities have been moved out of the Boiler device into a dedicated device:

Performance energetique

Added conditional electricity sensors under the energy area:

📊 dayAverage
📊 monthAverage

These sensors are created only when the corresponding data is available.

This provides a clearer separation between boiler-related entities and overall energy/performance data.

  1. 🌍 Localization Improvements

Replaced hardcoded labels for newly introduced dynamic entities with proper translation keys.

Translation entries have been added across all supported locales for:

🔧 Thermostat valve diagnostics
⚠️ Thermostat valve warning
📅 Assigned program
⚡ Electricity day/month averages

Device names are now localized at creation time using the active Home Assistant language.

🎯 Why?

This change provides several improvements to the integration:

🧩 More flexible discovery

Prepares the integration for appliances exposing variable Program and Device sub-resources.

🚫 Fewer assumptions

Reduces reliance on static API paths and hardcoded resource structures.

🔄 Better adaptability

Allows the integration to adapt to different POINTTAPI implementations and gateway capabilities.

🏗️ Consistent discovery strategy

Aligns discovery behavior across:

Zones → Programs → Devices

🧭 Better Home Assistant UX

Provides clearer device grouping, more meaningful entities, and better diagnostics.

✅ Better correctness

Climate state handling, warning semantics, and resource mapping now more closely match the expected POINTTAPI behavior.

🌍 Better localization

New entities and dynamically created devices are consistently translatable across supported locales.

🧹 Better maintainability

A more consistent discovery architecture provides a cleaner foundation for supporting additional POINTTAPI resources in the future.

🧪 Validation

Added and updated targeted unit tests covering:

🔎 Reference-driven Programs discovery
📱 Reference-driven Devices discovery
🛡️ Programs/Devices fallback behavior
🔧 Dynamic thermostat valve entities
⚠️ Valve warning mapping
📅 Assigned program mapping
📭 Empty/incomplete program data handling
⚡ Energy routing to the dedicated device
📊 Conditional electricity average sensor creation
🌍 Localized device naming behavior

Targeted test suites pass locally after these changes. ✅

📦 Impact
✅ No breaking changes expected
🔙 Backward-compatible behavior preserved through the existing fallback paths
🚀 More flexible foundation for supporting new Program and Device resources
🧩 Better compatibility with installations exposing different POINTTAPI capabilities
🧹 Improved overall consistency and maintainability
📝 Notes

Some device names are now language-aware at creation time.

If the Home Assistant language is changed later, the integration may need to be reloaded to refresh existing device registry labels.

jfhautenauven and others added 30 commits August 10, 2026 16:02
Use live solar resource availability instead of root references when deciding whether to create POINTTAPI solar entities. Add regression coverage for unavailable resources and valid zero values.
…bility

Fix conditional Solar entity creation
Localize POINTTAPI entity names and state values across all supported languages, including comfort controls, diagnostics, firmware status, switches, and PIR sensitivity while preserving API values.
Use schema-valid normalized select state keys and map them back to Bosch values for writes. Remove invalid free-form no-update state translations and update regression coverage.
Remove stale Solar entities and the Solar device from the Home Assistant registries when POINTTAPI returns no usable solar resources. Also use the same availability check when creating Solar entities.
…to feature/french-translations

# Conflicts:
#	custom_components/bosch/sensor/__init__.py
# Conflicts:
#	custom_components/bosch/sensor/__init__.py
…ture/french-translations

# Conflicts:
#	custom_components/bosch/pointtapi_entities.py
#	custom_components/bosch/strings.json
#	custom_components/bosch/translations/de.json
#	custom_components/bosch/translations/en.json
#	custom_components/bosch/translations/fr.json
#	custom_components/bosch/translations/it.json
#	custom_components/bosch/translations/nl.json
#	custom_components/bosch/translations/pl.json
#	custom_components/bosch/translations/sk.json
#	unittests/test_pointtapi_new_entities.py
…ture/french-translations

# Conflicts:
#	custom_components/bosch/pointtapi_entities.py
#	unittests/test_pointtapi_multizone.py
…ture/french-translations

# Conflicts:
#	custom_components/bosch/pointtapi_entities.py
Add /programs and /devices to POINTTAPI_COORDINATOR_ROOTS so these resources are fetched at top-level during coordinator refresh. This keeps required metadata available for entity behavior that depends on those endpoints and avoids missing data when they are not reachable through reference traversal alone.
@jfhautenauven

Copy link
Copy Markdown
Contributor Author

@CaseyRo : I need to one to continue the work on devices and programs, what I added yesterday in the coordinator was not enough. This morning, while testing latest beta, I couldn't find the extracted data in the diag dump.
Would kindly appreciate also a new beta to grab my next data dump and get to work :)

@CaseyRo

CaseyRo commented Aug 11, 2026

Copy link
Copy Markdown
Owner

@jfhautenauven mystery solved — beta.6 was tagged before #15 merged, so the /devices + /programs polling was never in the build you tested this morning. Your dump was fine; the code just wasn't shipped yet. 😄

v1.2.0-beta.7 is out now with #15 aboard: https://github.com/CaseyRo/ha_bosch/releases/tag/v1.2.0-beta.7 — update, reload the integration once, and your next diag dump should have the extracted data for the telemetry work.

And thanks for the stable 👍 on #11 — I'll hold 1.2.0 until you've confirmed the /devices data lands in beta.7, then ship stable and close out #5, #10 and #11. 🙏

@jfhautenauven

Copy link
Copy Markdown
Contributor Author

@CaseyRo : this should be enough work done for the moment. I'm stopping with new functionalities. I let you review the code. I'm updating the description of the PR, and I'll call it a day codewise. Of course, eager to test as soon as you validate and release a beta :D

@jfhautenauven

Copy link
Copy Markdown
Contributor Author

@CaseyRo : I propose beta 8 is the last beta for 1.2.0. For new features / changes, that will be on 1.3.0

Given the fact I'm soon to go on holydays, I'd resume, speaking for myself, around end of August :)

@CaseyRo
CaseyRo merged commit 5e2eeec into CaseyRo:master Aug 11, 2026
3 checks passed
CaseyRo added a commit that referenced this pull request Aug 11, 2026
…us, missing diacritics

Review fixes on top of #17:
- valve signal sensor dropped SensorDeviceClass.SIGNAL_STRENGTH; HA only accepts
  dB/dBm for it, and /devices/list reports link quality as a percentage
- unknown zone /status no longer maps to HVACAction.COOLING on a heating-only
  appliance; unrecognised values are reported as unknown
- restored diacritics in the localized device-name table (fr/pl/sk) and in the
  two new Polish electricity strings
- dropped the now-empty _BOILER_KINDS set and its dead branch
- new guard test asserts every POINTTAPI sensor unit is valid for its device class
CaseyRo added a commit that referenced this pull request Aug 11, 2026
@CaseyRo

CaseyRo commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Merged, and v1.2.0-beta.8 is out with it: https://github.com/CaseyRo/ha_bosch/releases/tag/v1.2.0-beta.8 🚀

Deal on your plan: beta.8 is the last beta for 1.2.0, everything new goes to 1.3.0. Update + reload once, and if it looks right to you before you leave, stable ships and #5, #10, #11 and #16 close with it. If you don't get to it, I'll ship on @janfuu-cpu's confirmation — he gave the 👍 on beta.7 tonight — and your 1.3.0 items wait for you at the end of August.

Reference-driven expansion for /programs and /devices was the right call, and the fallback-on-missing-references handling is what makes it safe to ship on installs none of us can see. Nice work. 🙏

I fixed four things on top of the merge (7c8a6ea) — all mine to catch in review, none of them worth another round-trip while you're packing:

1. Valve signal strength would have errored on every valve. device_class=SIGNAL_STRENGTH only accepts dB/dBm in HA; /devices/list reports link quality as a percentage, so HA would reject the unit on each ETRV. Dropped the device class, kept %. There's now a test that walks every POINTTAPI sensor description and validates its unit against its device class — I confirmed it fails on the original code, so this class of bug can't return.

2. hvac_action reported "Cooling" for anything unrecognised. The else branch on zone status mapped to HVACAction.COOLING, which on a heating-only CT200 shows up as a cooling system in the UI. Unknown statuses now report unknown, and the two identical status blocks collapsed into one lookup table.

This one needs you: your test used circulation as the unknown value. If that's a real status your CT200 emits, it deserves a proper mapping rather than unknown — circulation sounds like idle-with-pump-running to me, but you have the hardware. When you're back, the full value set of /zones/{id}/status would let me finish the table.

3. Missing accents. _DEVICE_NAME_LOCALIZED was typed accent-free — "Chaudiere", "Kociol", "Zasobnik teplej vody", "Performance energetique" — and two new Polish strings in pl.json lost theirs while the rest of your file kept them (autocorrect, or a keyboard eating them?). Restored across fr/pl/sk.

4. Dead code. _BOILER_KINDS = {} is an empty dict after annual_gas_goal moved to _ENERGY_KINDS, so its branch was unreachable. Removed.

Two of your tests asserted the old behavior on 1 and 2, so I updated them rather than deleting them. 327 pass, lint clean.

Four things I deliberately left alone for 1.3.0, so they're waiting for you rather than decided without you:

  • Battery reads as a raw "ok" / "unknown" string in every language — the name is translated but the value isn't. thermal_disinfect_last_result already has the state: translation pattern to copy.
  • preset_mode duplicates hvac_modeAUTO ≡ program and HEAT ≡ manual both write userMode, so the same setting has two controls in the UI. Might be exactly what you want, might confuse; your call.
  • _zone_roots / _program_roots / _device_roots are three copies of one function. One _expand_roots(client, path) would do it. I left it because the auth-vs-generic exception handling is subtle and you weren't around to review a refactor of your own code.
  • Device names via a hardcoded dict — HA supports translation_key on DeviceInfo these days, which would move those seven blocks into strings.json with the rest.

Enjoy the holiday — genuinely, thank you for the pace this week. Nothing here is waiting on you until you're back. 🏖️

CaseyRo added a commit that referenced this pull request Aug 11, 2026
1.2.0 stable ships the beta.7 content confirmed by both multi-zone testers.
PR #17 (per-valve telemetry, assigned program, schedule/manual climate) moves
to the 1.3.0 line so it can be confirmed on real hardware first.
@CaseyRo

CaseyRo commented Aug 11, 2026

Copy link
Copy Markdown
Owner

Correction to what I wrote an hour ago, before you read it and act on it: #17 is not in stable 1.2.0. It went out as v1.3.0-beta.1 — same code, its own release line. v1.2.0-beta.8 is marked superseded; ignore it.

Stable v1.2.0 shipped the beta.7 content instead — the multi-zone work you and @janfuu-cpu both confirmed on real hardware.

Why the change: I agreed to your beta.8 plan too quickly. 1.2.0 had two testers with 17 ETRVs between them signing off; #17 has nobody yet, and I have a single-zone CT200 that can't exercise a single line of it. Stacking unverified work onto verified work right before you disappear for two weeks meant the first real report would land with nobody around to act on it. Your own boundary was the right one — I just drew it one PR earlier.

Nothing is lost: your work is released, installable, and testers can opt into it. It simply carries a version number that says "not proven yet", which is honest.

The /zones/{id}/status question stands for whenever you're back — your 12-zone setup will produce statuses mine never will, circulation being the obvious one. Right now it reads as unknown; if it means idle-with-pump-running, one line fixes it properly.

Enjoy the holiday. 🏖️

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants