Repository navigation
Stable entity ids: read-only twin + tier-gated control (2.4.0) - #28
Merged
Merged
Conversation
A setting used to change component with its write tier: sensor when off, number when on. The domain is part of the entity id, so Home Assistant treated every toggle as a different entity — deleting one, registering another. Dashboards, automations, templates and statistics referencing the old id broke silently, and HA's registry restored obsolete ids by unique_id: enabling both tiers on a 6-pack install flipped 204 entities and resurrected 156 pre-2.2.0 ids. Each setting is now two entities: - a read-only sensor / binary_sensor, published whatever the tier, whose id is stable for the life of the install; - a number / switch control with its own object_id and name (`<object_id>_control`, "<name> control"), published only while the setting's write tier is on. Both share the existing control/<param> state topic, and the control's command_topic is the existing control/<param>/set — the write path from Home Assistant through MQTT to RS485 is unchanged, as is the write executor's tier gating. MQTT discovery cannot express a read-only number or switch: command_topic is Required in MQTT_RW_SCHEMA for both, and HA has no per-entity read-only flag (home-assistant/discussions#13, still open). Two entities are therefore the only way to keep an id stable across a tier toggle. The control topic older versions published under the setting's own object_id is now always cleared, so those entities disappear on upgrade instead of lingering or being restored. Dashboard, entity-drift check and the rename tool all follow: the generated dashboard points at the control when a tier is on and at the twin otherwise, and with both tiers off its output is byte-identical to 2.3.0. Add-on version 2.4.0. Closes #23 Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
A setting changed component with its write tier —
sensor↔number,binary_sensor↔switch. The domain is part of the entity id, so each toggle was a delete plus a register: every hand-written dashboard, automation, template and statistics series referencing the old id broke, silently. Worse, HA restores deleted registry rows byunique_id, so on a 6-pack install enabling both tiers flipped 204 entities and brought 156 pre-2.2.0 ids back from the dead, needing a secondrename_entities.py --applyto repair.What changes
Each setting is published as two entities:
sensor.bms_1_maximum_charge_currentnumber.bms_1_maximum_charge_current_controlPacked bits likewise:
binary_sensor.bms_1_smart_sleep+switch.bms_1_smart_sleep_control.The twin's id is stable for the life of the install. The control appears when you enable a tier and disappears when you disable it — and nothing else moves. Both share the existing
control/<param>state topic; the control'scommand_topicis the existingcontrol/<param>/set, so the write path HA → MQTT → RS485 is unchanged, as is the write executor's tier gating.Why two entities rather than one
MQTT discovery cannot express a read-only
numberorswitch:command_topicisvol.RequiredinMQTT_RW_SCHEMA, which both platforms extend. I checked that specifically, including thatMQTT_ENTITY_COMMON_SCHEMAdoes not later downgrade it — voluptuousextend()overrides keys, and thevol.Optional(CONF_COMMAND_TOPIC)elsewhere belongs toDEVICE_DISCOVERY_SCHEMA. HA also has no per-entity read-only flag; discussion #13 is open with nothing shipped, and its author notes "unavailable" is not a substitute because it hides the value.Upgrade
The control topic older versions published under the setting's own object_id is now always cleared, so those entities vanish on first start instead of lingering or being restored by
unique_id.Hand-written dashboards referencing a setting's
number.*/switch.*id need pointing at either the stable read-only id (to display) or the new…_controlid (to change).Test plan
ruff,mypy,pytest— 575 passed, 100 % branch coverageCloses #23
🤖 Generated with Claude Code