mirror of
https://github.com/Matysh/houseplan-card
synced 2026-10-06 06:38:57 +00:00
fix: deduplicate entity markers from parent devices
Issue: #226 User-Visible: yes
This commit is contained in:
@@ -2,6 +2,12 @@
|
||||
|
||||
## Unreleased
|
||||
|
||||
- Placing an individual Home Assistant entity no longer leaves a duplicate
|
||||
automatic marker of its complete parent device. The automatic marker now
|
||||
contains only the remaining active visible entities and disappears when
|
||||
none remain; two explicitly placed entity/device markers still coexist
|
||||
([#226](https://github.com/Matysh/houseplan-card/issues/226)).
|
||||
|
||||
## v1.66.0 — 2026-08-20
|
||||
|
||||
- Text device markers once again use a capsule-shaped outer outline instead of
|
||||
|
||||
@@ -8,6 +8,13 @@
|
||||
|
||||
## Не выпущено
|
||||
|
||||
- Размещение отдельной сущности Home Assistant больше не оставляет рядом
|
||||
дублирующий автоматический маркер всего родительского устройства. В
|
||||
auto-marker теперь входят только оставшиеся активные видимые сущности, а при
|
||||
пустом остатке он исчезает; две явно размещённые привязки entity/device
|
||||
по-прежнему могут сосуществовать
|
||||
([#226](https://github.com/Matysh/houseplan-card/issues/226)).
|
||||
|
||||
## v1.66.0 — 2026-08-20
|
||||
|
||||
- Текстовые маркеры устройств снова получают капсульную внешнюю обводку вместо
|
||||
|
||||
@@ -26,6 +26,12 @@ as the SEEDER of initial hidden flags.
|
||||
automatic discovery cannot immediately recreate the deleted device. The
|
||||
same binding remains available in Add; saving it again replaces the
|
||||
tombstone and starts with a fresh position.
|
||||
- A live `entity:X` marker owns X inside its automatic parent `device:D`. A
|
||||
residual auto-device contains only active, HA-visible siblings not owned by
|
||||
other entity markers and disappears when that set is empty. A user-hidden
|
||||
live marker still owns X; an entity tombstone does not. An explicit
|
||||
`device:D` remains complete and may intentionally coexist with explicit
|
||||
entity markers.
|
||||
- No marker — never evaluated by the seeder yet, or a plain physical device.
|
||||
- `bindingStatus: ha_disabled` is runtime-only. It is derived from Home
|
||||
Assistant's device/entity registries and is never written into a marker or
|
||||
@@ -51,6 +57,10 @@ are never revisited. It fires on:
|
||||
3. a new device appearing in a bound area — non-physical ones are hidden
|
||||
silently (no red dot); physical ones keep the red-dot flow.
|
||||
|
||||
Entity-marker ownership uses the same residual projection here as in the
|
||||
renderer. The seeder never turns an automatic parent with an empty or
|
||||
HA-hidden-only residual into a persistent hidden `device:D` stub.
|
||||
|
||||
Until a config is seeded (`filter_seeded` absent), `buildDevices` applies the
|
||||
LEGACY runtime filter, so a read-only client on an old config sees exactly
|
||||
the old behaviour until an editing client materialises it.
|
||||
|
||||
@@ -676,6 +676,23 @@ separately promised workflows:
|
||||
## Devices on the plan ★
|
||||
|
||||
- [ ] Auto devices appear only in rooms bound to their area [manual]
|
||||
- [ ] **Entity/parent ownership (#226):** placing `entity:X` removes X from its
|
||||
automatic parent. A visible unclaimed sibling keeps one residual parent;
|
||||
an empty or HA-hidden-only residual removes it. State, primary/action,
|
||||
`allEntities`, light/Glow and LQI cannot see X twice
|
||||
[auto: unit `devices.test.mjs`; browser `smoke_entity_parent_dedup.mjs`].
|
||||
- [ ] Two explicit markers `entity:X` + `device:D` coexist and the device stays
|
||||
complete. A user-hidden live entity marker still owns X, while an entity
|
||||
tombstone returns X to the parent; disabled entity ownership follows the
|
||||
known full-registry relation [auto: unit `devices.test.mjs`].
|
||||
- [ ] The #94 curtain boundary is deliberate: untouched hidden `cover.*` stays
|
||||
cover-first, but after placing the only visible auxiliary switch the
|
||||
hidden-only automatic remainder disappears. An explicit `device:D`
|
||||
restores the complete curtain beside that entity marker
|
||||
[auto: unit `devices.test.mjs`].
|
||||
- [ ] Renderer and seeder cannot drift back to exact-binding-only ownership
|
||||
[mutation: `entity-marker-kept-in-parent-device`,
|
||||
`entity-marker-parent-seeded`].
|
||||
- [ ] Filtering hides bridges/groups/scenes/excluded integrations; 👁 "show all" reveals [manual]
|
||||
- [ ] Duplicate "name|area" numbered ("Lamp", "Lamp 2") [manual]
|
||||
- [ ] Light groups fold their single lamps; `group_lights=false` unfolds [manual]
|
||||
|
||||
@@ -338,6 +338,16 @@ Newly discovered devices get a red dot until first opened in Device.
|
||||
|
||||
The same binding cannot be used by two markers.
|
||||
|
||||
When an exact HA entity belongs to a device, placing that entity gives its
|
||||
channel to the entity marker. The automatic parent marker, if needed, contains
|
||||
only the remaining active, HA-visible and unplaced entities; it disappears
|
||||
when that residual is empty. HA-hidden siblings alone do not keep an automatic
|
||||
parent on the plan. To show both the exact entity and the complete device,
|
||||
place `entity:X` and `device:D` explicitly — two explicit markers are treated
|
||||
as an intentional configuration. Deleting an entity marker returns the entity
|
||||
to automatic parent discovery; its binding tombstone does not remove registry
|
||||
data from the live HA device.
|
||||
|
||||
### Device editor
|
||||
|
||||
- drag a marker to save its server-side position;
|
||||
|
||||
@@ -573,6 +573,16 @@ House Plan читает реестры устройств, сущностей и
|
||||
|
||||
Одну и ту же привязку нельзя одновременно использовать в двух маркерах.
|
||||
|
||||
Если отдельная HA-сущность принадлежит устройству, после её размещения этот
|
||||
канал принадлежит точному entity-marker. Автоматический родительский маркер,
|
||||
если он ещё нужен, строится только из оставшихся активных, видимых в HA и не
|
||||
размещённых отдельно сущностей; при пустом остатке он исчезает. Одни только
|
||||
скрытые в HA siblings не удерживают auto-marker на плане. Чтобы одновременно
|
||||
показать точную сущность и полное устройство, явно разместите и `entity:X`, и
|
||||
`device:D` — два явных маркера считаются осознанной конфигурацией. После
|
||||
удаления entity-marker сущность снова доступна автоматическому родителю:
|
||||
binding tombstone не вырезает её из живого устройства HA.
|
||||
|
||||
### Редактор устройств
|
||||
|
||||
| Действие | Результат |
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"version": 1,
|
||||
"fixture": "synthetic-only",
|
||||
"sourceFingerprint": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceFingerprint": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"captureScriptSha256": "34f2219790d46efd8250e7a1bd829cb8fc0b0547e1260635fefa52407551b41b",
|
||||
"command": "npm run build && node demo/docs/capture.mjs",
|
||||
"scenarios": {
|
||||
@@ -13,7 +13,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "2885f96e348b15ab7c696e56e99bddcd9bb2ee94218a883e5a2155f45f5042aa"
|
||||
},
|
||||
"view-touch": {
|
||||
@@ -24,7 +24,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "f62d8af3617c00a5e99511bd765980d2e27badf25047a1be34046b64195abe6c"
|
||||
},
|
||||
"space-create": {
|
||||
@@ -35,7 +35,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "c53db2e5c642a5549c13f3c93a5b359fed69bdb2621bf71a243a877ffcb95e6b"
|
||||
},
|
||||
"room-contour-close": {
|
||||
@@ -46,7 +46,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "2f13ea645af306eee9cc7c52699c928377b72f412b08c1a3db6beb848ace1b51"
|
||||
},
|
||||
"plan-context-tray": {
|
||||
@@ -57,7 +57,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "a6c526fede11bc3503fd2384bd4a3f6afa008f481c5c47578f06cae6c81c6f9b"
|
||||
},
|
||||
"device-editor": {
|
||||
@@ -68,7 +68,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "9585b59add4d35b5a6f028ce5b720ef1b77a3f8b19436d192cd1a0e6fc637264"
|
||||
},
|
||||
"device-display-preview": {
|
||||
@@ -79,7 +79,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "cfc317da4628d079a116ff71311fbf06b1eb3b181928a5ea7ba888ab936a5e8b"
|
||||
},
|
||||
"background-editor": {
|
||||
@@ -90,7 +90,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "d7cfe70551d9260169df8efd832e32ed7df99c7f60b55d1fd4a8322bd4c47175"
|
||||
},
|
||||
"room-card": {
|
||||
@@ -101,7 +101,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "029a3e69ec647a8a370d99e6bb7f9225833c526739076022f6b52ba54bff30ea"
|
||||
},
|
||||
"device-info": {
|
||||
@@ -112,7 +112,7 @@
|
||||
},
|
||||
"theme": "dark",
|
||||
"language": "en",
|
||||
"sourceSha256": "d2baf22d884daf235af39c2010d42f5fdefc4004ae30a45a6a4ce33115c52c8f",
|
||||
"sourceSha256": "264380083a9a18bfc2305a6577368068d6839fabe82fe1a1f440a62867b4e589",
|
||||
"imageSha256": "a06cbf83f09e2f67b3566d7c0b10e973db060c3d20786f26f74ada6a21937c3e"
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user