mirror of
https://github.com/Matysh/houseplan-card
synced 2026-07-31 08:28:31 +00:00
docs: everything caught up with v1.51.1
A sweep of every document against the shipped behaviour: - README en+ru: the space dialog no longer claims a background is mandatory (draw-by-hand and the saved-plans picker exist; the canvas is square); 'Show all devices' sections rewritten for the hide-flag world — the checkbox, 'Show hidden' ghosts, LQI-yes/light-no; troubleshooting updated. - ARCHITECTURE: the config schema block still described v1.3 — aspect/device_overrides/virtual_devices/1000x1000-per-aspect/legacy-bundle fallback, all long gone. Rewritten to the current shape (square canvas, markers with hidden, filter_seeded, quotas, signed urls). The WS table dropped houseplan/file/set (removed in v1.10.0) and gained geometry/repair, layout/delete, files/migrate, files/cleanup, content/sign, the plans/list cap. - UX-MODES: the Devices-tab tool list names the checkbox and the local 'Show hidden' instead of the retired shared show-all. - ROADMAP: repair-issues, system_health, floors import, data icon rules, click actions, theming and JSON i18n were done releases ago — checked off with their versions; the HACS pointer is #9004 (bot closed #8995). - STATUS: SSH port is 22222 and the HA config root is /mnt/data/supervisor/homeassistant (/config does not exist there); the key lives in houseplan/.secrets; the PAT note reflects the fine-grained token; the feature surface gained the v1.42-v1.51 era. - DEVELOPMENT: deploy instructions with the real port, path and cache busting. - The owner's product description (user folder) refreshed the same way: square canvas, hide flags, the yellow principle.
This commit is contained in:
@@ -161,7 +161,7 @@ for each floor (names prefilled, a plan image is asked for one by one; any floor
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
In the dialog, set a **name** (for example, "1st floor") and **upload a background** — a floor-plan image in SVG, PNG or JPG format. Both fields are required: without a plan the "Save" button stays disabled.
|
In the dialog, set a **name** (for example, "1st floor") and pick the background: **upload** a floor-plan image (SVG, PNG, JPG, WebP), **choose one already uploaded** to the server earlier, or select **"no background, I'll draw the rooms"** for a hand-drawn space. The canvas is always square; an image keeps its own proportions and is centred inside it.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -204,7 +204,7 @@ walls** (it slides around corners too), and a **double click opens its propertie
|
|||||||
|
|
||||||
As soon as you save a room bound to an area, **the devices of that area are automatically laid out inside the outline**. These are the same devices shown on the **Settings → Devices → (filtered by the room)** page — only the meaningful ones, without service records, bridges and duplicates.
|
As soon as you save a room bound to an area, **the devices of that area are automatically laid out inside the outline**. These are the same devices shown on the **Settings → Devices → (filtered by the room)** page — only the meaningful ones, without service records, bridges and duplicates.
|
||||||
|
|
||||||
By default only meaningful devices make it onto the plan — service records, bridges and duplicates are filtered out. If you need to see **absolutely all** devices of the area, enable the **👁 "Show all devices"** button in the header.
|
By default only meaningful devices make it onto the plan: non-physical ones (service records, bridges, scenes, individual lamps folded into a light group) arrive with the **"Hide device from plan"** checkbox already ticked. The checkbox is yours from then on — every device dialog has it, virtual devices included. To see and un-hide them, open the device editor and press **"Show hidden"**: hidden devices appear as translucent blue ghosts, a click opens the dialog. Hidden devices still count toward the room's Zigbee signal, but cast no light.
|
||||||
|
|
||||||
From here on you can just use the plan: clicking an icon opens the device card with the model, link and a button to jump into Home Assistant.
|
From here on you can just use the plan: clicking an icon opens the device card with the model, link and a button to jump into Home Assistant.
|
||||||
|
|
||||||
@@ -286,7 +286,7 @@ Services → House Plan**.
|
|||||||
|
|
||||||
**Do I need to write anything in YAML?** No. The only line is adding the card to the dashboard; everything else is done with the mouse.
|
**Do I need to write anything in YAML?** No. The only line is adding the card to the dashboard; everything else is done with the mouse.
|
||||||
|
|
||||||
**My devices did not appear on the plan.** A device appears only if its Home Assistant area is bound to a drawn room. Check that the device has a room assigned (Settings → Devices) and that the room is outlined and bound to that area. If the device exists but is hidden by filtering (bridges, service records, duplicates) — enable the **👁 "Show all devices"** button in the header.
|
**My devices did not appear on the plan.** A device appears only if its Home Assistant area is bound to a drawn room. Check that the device has a room assigned (Settings → Devices) and that the room is outlined and bound to that area. If the device exists but is hidden (the "Hide device from plan" checkbox — set automatically for bridges, scenes and other non-physical records) — open the device editor, press **"Show hidden"** and untick the box in its dialog.
|
||||||
|
|
||||||
**Can I hide an unwanted device or rename it?** Yes — click the device on the plan and press "Edit" in its card: there you can change the name, icon, model or hide the icon.
|
**Can I hide an unwanted device or rename it?** Yes — click the device on the plan and press "Edit" in its card: there you can change the name, icon, model or hide the icon.
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -162,7 +162,7 @@ title: План дома
|
|||||||
|
|
||||||

|

|
||||||
|
|
||||||
В диалоге задайте **название** (например, «1 этаж») и **загрузите подложку** — картинку плана этажа в формате SVG, PNG или JPG. Оба поля обязательны: без плана кнопка «Сохранить» неактивна.
|
В диалоге задайте **название** (например, «1 этаж») и выберите подложку: **загрузите** картинку плана (SVG, PNG, JPG, WebP), **возьмите уже загруженную** на сервер ранее или отметьте **«без подложки, нарисую комнаты сам»**. Холст всегда квадратный; картинка сохраняет свои пропорции и центрируется внутри него.
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
@@ -205,7 +205,7 @@ title: План дома
|
|||||||
|
|
||||||
Как только вы сохранили комнату с привязкой к зоне, **устройства этой зоны автоматически расставляются внутри контура**. Берутся те же устройства, что показаны на странице **Настройки → Устройства → (фильтр по нужной комнате)** — только осмысленные, без служебных записей, мостов и дубликатов.
|
Как только вы сохранили комнату с привязкой к зоне, **устройства этой зоны автоматически расставляются внутри контура**. Берутся те же устройства, что показаны на странице **Настройки → Устройства → (фильтр по нужной комнате)** — только осмысленные, без служебных записей, мостов и дубликатов.
|
||||||
|
|
||||||
По умолчанию на план попадают только осмысленные устройства — служебные записи, мосты и дубликаты отфильтрованы. Если нужно видеть **вообще все** устройства зоны, включите в шапке кнопку **👁 «Показать все устройства»**.
|
По умолчанию на план попадают только осмысленные устройства: нефизические (служебные записи, мосты, сцены, лампы, свёрнутые в световую группу) приходят с уже установленной галкой **«Скрыть устройство с плана»**. Дальше галка принадлежит вам — она есть в диалоге каждого устройства, включая виртуальные. Чтобы увидеть и вернуть скрытые, откройте редактор устройств и нажмите **«Показать скрытые»**: скрытые отобразятся полупрозрачными синими призраками, клик открывает диалог. Скрытые устройства учитываются в Zigbee-сигнале комнаты, но света не дают.
|
||||||
|
|
||||||
Дальше можно просто пользоваться планом: клик по иконке открывает карточку устройства с моделью, ссылкой и кнопкой перехода в Home Assistant.
|
Дальше можно просто пользоваться планом: клик по иконке открывает карточку устройства с моделью, ссылкой и кнопкой перехода в Home Assistant.
|
||||||
|
|
||||||
@@ -288,7 +288,7 @@ title: План дома
|
|||||||
|
|
||||||
**Нужно ли что-то писать в YAML?** Нет. Единственная строчка — это добавление карточки на дашборд; всё остальное делается мышкой.
|
**Нужно ли что-то писать в YAML?** Нет. Единственная строчка — это добавление карточки на дашборд; всё остальное делается мышкой.
|
||||||
|
|
||||||
**Мои устройства не появились на плане.** Устройство появляется, только если его зона в Home Assistant привязана к нарисованной комнате. Проверьте, что у устройства задана комната (Настройки → Устройства), а комната обведена и привязана к этой зоне. Если устройство есть, но скрыто курированием (мосты, служебные, дубликаты) — включите в шапке кнопку **👁 «Показать все устройства»**.
|
**Мои устройства не появились на плане.** Устройство появляется, только если его зона в Home Assistant привязана к нарисованной комнате. Проверьте, что у устройства задана комната (Настройки → Устройства), а комната обведена и привязана к этой зоне. Если устройство есть, но скрыто (галка «Скрыть устройство с плана» — для мостов, сцен и прочих нефизических записей она ставится автоматически) — откройте редактор устройств, нажмите **«Показать скрытые»** и снимите галку в его диалоге.
|
||||||
|
|
||||||
**Можно ли скрыть лишнее устройство или переименовать его?** Да — кликните по устройству на плане и в его карточке нажмите «Редактировать»: там можно сменить имя, иконку, модель или скрыть значок.
|
**Можно ли скрыть лишнее устройство или переименовать его?** Да — кликните по устройству на плане и в его карточке нажмите «Редактировать»: там можно сменить имя, иконку, модель или скрыть значок.
|
||||||
|
|
||||||
|
|||||||
+34
-14
@@ -100,23 +100,36 @@ name?, icon?, model?, link?, description?, pdfs:[{name,url}]}`. A hybrid: auto-d
|
|||||||
appear on their own; a marker with `binding=device:<id>` overrides them (metadata/rebinding/hiding),
|
appear on their own; a marker with `binding=device:<id>` overrides them (metadata/rebinding/hiding),
|
||||||
`entity:<eid>` — for groups/helpers, `virtual` — a manual icon without HA. The marker id = device_id /
|
`entity:<eid>` — for groups/helpers, `virtual` — a manual icon without HA. The marker id = device_id /
|
||||||
`lg_<eid>` / `v_<rand>` (preserves the position in the layout). The binding picker excludes already-placed
|
`lg_<eid>` / `v_<rand>` (preserves the position in the layout). The binding picker excludes already-placed
|
||||||
references and duplicates by name|area. Manual files: `houseplan/file/set` → `/config/houseplan/files/<id>/`,
|
references and duplicates by name|area. Manual files: transactional HTTP upload into `<config>/houseplan/files/<id>/`
|
||||||
served from `/houseplan_files/files/`.
|
(staging `up_*` folders promoted on save), served via signed
|
||||||
|
`/api/houseplan/content/files/…` urls.
|
||||||
|
|
||||||
## Server-side configuration (v1.3.0+)
|
## Server-side configuration (current shape, v1.51+)
|
||||||
|
|
||||||
`.storage/houseplan.config` (Store):
|
`.storage/houseplan.config` (Store):
|
||||||
```json
|
```json
|
||||||
{ "spaces": [{ "id","title","plan_url","aspect","view_box":[4],"rooms":[{"id","name","area","x","y","w","h"}] }],
|
{ "spaces": [{ "id","title","plan_url","plan_aspect","view_box":[4],
|
||||||
"device_overrides": {"<device_id>": {"hidden","icon","name"}},
|
"rooms":[{"id","name","area","poly|x/y/w/h","open_to","settings"}],
|
||||||
"virtual_devices": [{"id","space","name","icon","x","y","note?","entity_id?"}],
|
"openings":[…], "decor":[…], "settings":{…} }],
|
||||||
"settings": {"exclude_integrations":[],"group_lights":true} }
|
"markers": [{ "id","binding":"device:<id>|entity:<eid>|virtual","hidden",
|
||||||
|
"name","icon","display","controls","is_light","tap_action",
|
||||||
|
"room_id","pdfs",… }],
|
||||||
|
"settings": { "exclude_integrations":[], "group_lights":true,
|
||||||
|
"filter_seeded":true, "fill_colors":{…}, "icon_rules":[…],
|
||||||
|
"known_devices":[…], "new_device_ids":[…] } }
|
||||||
```
|
```
|
||||||
All coordinates are **normalized (0..1 of the space plan)**; the render space is
|
All coordinates are **normalized (0..1 of the canvas)**; the canvas is always
|
||||||
1000 × 1000/aspect. Layout v2: `{device_id: {"s": space, "x", "y"}}` (normalized).
|
**square** (v1.48.0), render space `NORM_W × NORM_W` (1000×1000). A space has no
|
||||||
Plan files: `<config>/houseplan/plans/<space>.<ext>` → URL `/houseplan_files/plans/…`.
|
proportions of its own — `plan_aspect` is the IMAGE's ratio, used to letterbox
|
||||||
If the server config is empty, the card falls back to the legacy bundle (the dacha) and shows a
|
it centred on the square. The schema bounds geometry to ±4 with strictly
|
||||||
"To server" migration button in edit mode. The dacha was migrated on 2026-07-04.
|
positive sizes (HP-1501/1502). `device_overrides`/`virtual_devices` are long
|
||||||
|
gone — markers carry everything, `marker.hidden` is the explicit
|
||||||
|
"hide from plan" flag seeded once by the old filter (docs/FILTERING.md).
|
||||||
|
Layout v2: `{device_id | rl_<roomId>: {"s": space, "x", "y"}}` (normalized,
|
||||||
|
bounded ±4). Plan files: `<config>/houseplan/plans/<space>.<token>.<ext>`
|
||||||
|
(copy-on-write, never overwritten), served via signed
|
||||||
|
`/api/houseplan/content/plans/_/<name>` urls; growth is bounded by store
|
||||||
|
quotas, nothing is ever deleted for being old (docs/SCOPE.md).
|
||||||
|
|
||||||
## Room geometry rules (v1.19–v1.21)
|
## Room geometry rules (v1.19–v1.21)
|
||||||
|
|
||||||
@@ -178,9 +191,16 @@ double click → properties dialog. In markup mode the "Opening" tool handles cl
|
|||||||
| `houseplan/config/get` | — | `{config, rev}` |
|
| `houseplan/config/get` | — | `{config, rev}` |
|
||||||
| `houseplan/config/set` | `config`, `expected_rev?` | `{ok, rev}` / err `conflict`; event `houseplan_config_updated` |
|
| `houseplan/config/set` | `config`, `expected_rev?` | `{ok, rev}` / err `conflict`; event `houseplan_config_updated` |
|
||||||
| `houseplan/plan/set` | `space_id`, `ext` (svg/png/jpg/webp), `data` (b64, ≤8 MB) | `{ok, url}` — writes `<space>.<token>.<ext>`, deletes nothing |
|
| `houseplan/plan/set` | `space_id`, `ext` (svg/png/jpg/webp), `data` (b64, ≤8 MB) | `{ok, url}` — writes `<space>.<token>.<ext>`, deletes nothing |
|
||||||
| `houseplan/plans/list` | — | `{plans: [{name, url, size, modified, used_by}]}` |
|
| `houseplan/plans/list` | — | `{plans: [{name, url, size, modified, used_by}], total}` (newest 60) |
|
||||||
| `houseplan/plans/delete` | `name` | `{ok, removed}` / err `in_use` |
|
| `houseplan/plans/delete` | `name` | `{ok, removed}` / err `in_use` |
|
||||||
| `houseplan/file/set` | `marker_id`, `filename`, `data` (b64) | `{ok,url,name}` (legacy, WS limit) |
|
| `houseplan/layout/delete` | `device_id` | `{ok, rev}`; event `houseplan_layout_updated` |
|
||||||
|
| `houseplan/geometry/repair` | `space_id`, `aspect`, `dry_run?`, `undo?` | preview / `{ok, rev, moved}` / `{restored}`; errs `nothing_to_repair`, `no_backup` |
|
||||||
|
| `houseplan/files/migrate` | `from_id`, `to_id` | `{mapping}` — COPY, never move |
|
||||||
|
| `houseplan/files/cleanup` | `marker_id`, `keep?` | replacement-only collection |
|
||||||
|
| `houseplan/content/sign` | `paths[]` | `{urls}` — authSig for `<image>`/`<a>` fetches |
|
||||||
|
|
||||||
|
Manual attachments upload over HTTP (streaming, transactional staging), not WS —
|
||||||
|
the old `houseplan/file/set` was removed in v1.10.0.
|
||||||
|
|
||||||
**If the v1.48 migration crashed halfway** (HP-1500-01): the config write
|
**If the v1.48 migration crashed halfway** (HP-1500-01): the config write
|
||||||
landed, the layout write did not, and both triggers are gone — markers of that
|
landed, the layout write did not, and both triggers are gone — markers of that
|
||||||
|
|||||||
+7
-2
@@ -49,8 +49,13 @@ cp dist/houseplan-card.js custom_components/houseplan/frontend/
|
|||||||
|
|
||||||
## Deployment to the dacha (ha.jbstudio.pro)
|
## Deployment to the dacha (ha.jbstudio.pro)
|
||||||
|
|
||||||
- SSH: port **323**, root, key `ha_jb` (the user uploads it to the chat; in the sandbox /tmp/ha_jb, chmod 600).
|
- SSH: port **22222**, root, key `ha_jb` (lives in the user folder `houseplan/.secrets/ha_jb`,
|
||||||
- JS: `scp -P 323 -i /tmp/ha_jb dist/houseplan-card.js root@ha.jbstudio.pro:/config/custom_components/houseplan/frontend/`
|
outside git; copy into the sandbox with chmod 600 — only ask the user if it is gone).
|
||||||
|
- **The HA config root is `/mnt/data/supervisor/homeassistant`** — in this SSH
|
||||||
|
environment `/config` does not exist; a deploy aimed at `/config/...` fails
|
||||||
|
with "No such file or directory".
|
||||||
|
- JS: `scp -P 22222 -i <key> dist/houseplan-card.js root@ha.jbstudio.pro:/mnt/data/supervisor/homeassistant/custom_components/houseplan/frontend/`
|
||||||
|
- Cache busting: `sed` the `?v=` version in `.storage/lovelace_resources`, then restart HA.
|
||||||
- **The `frontend/` subfolder is not optional.** `__init__.py` registers
|
- **The `frontend/` subfolder is not optional.** `__init__.py` registers
|
||||||
`Path(__file__).parent / "frontend" / "houseplan-card.js"` as the static path.
|
`Path(__file__).parent / "frontend" / "houseplan-card.js"` as the static path.
|
||||||
A copy dropped next to `__init__.py` (…/houseplan/houseplan-card.js) is served
|
A copy dropped next to `__init__.py` (…/houseplan/houseplan-card.js) is served
|
||||||
|
|||||||
+14
-12
@@ -35,12 +35,12 @@ Track progress in `custom_components/houseplan/quality_scale.yaml` (done/exempt
|
|||||||
- [ ] `test-coverage` ≥95% backend; frontend: extract remaining pure logic (view math,
|
- [ ] `test-coverage` ≥95% backend; frontend: extract remaining pure logic (view math,
|
||||||
marker resolution) into `logic.ts`/`devices.ts` and cover with node:test.
|
marker resolution) into `logic.ts`/`devices.ts` and cover with node:test.
|
||||||
- [x] `diagnostics.py`: config + layout dump with `async_redact_data` (redact names/links/PDF paths).
|
- [x] `diagnostics.py`: config + layout dump with `async_redact_data` (redact names/links/PDF paths).
|
||||||
- [ ] `reconfiguration-flow` + richer **options flow**: admin_only, curation defaults
|
- [ ] `reconfiguration-flow` + richer **options flow**: admin_only, filtering defaults
|
||||||
(exclude domains — UI editable, replacing the hardcoded EXCLUDED_DOMAINS fallback),
|
(exclude domains — UI editable, replacing the hardcoded EXCLUDED_DOMAINS fallback),
|
||||||
LQI thresholds, group_lights default.
|
LQI thresholds, group_lights default.
|
||||||
- [ ] `repair-issues`: broken plan file references, orphaned layout entries, storage
|
- [x] `repair-issues`: broken plan references in Repairs (repairs.py, re-checked on
|
||||||
migration failures → Repairs UI instead of silent logs.
|
every config save); geometry/repair WS command for stranded migrations (v1.50.1).
|
||||||
- [ ] `system_health.py`: config rev, spaces/markers count, storage sizes.
|
- [x] `system_health.py` (v1.12.0).
|
||||||
- [ ] `exception-translations` + `icon-translations` where applicable.
|
- [ ] `exception-translations` + `icon-translations` where applicable.
|
||||||
- [ ] Frontend resource registration: adopt the community-consensus embedded-card pattern
|
- [ ] Frontend resource registration: adopt the community-consensus embedded-card pattern
|
||||||
end-to-end (we already do StaticPathConfig + storage-mode resource + `?v=` busting;
|
end-to-end (we already do StaticPathConfig + storage-mode resource + `?v=` busting;
|
||||||
@@ -48,26 +48,28 @@ Track progress in `custom_components/houseplan/quality_scale.yaml` (done/exempt
|
|||||||
|
|
||||||
## Phase 9 — Universality & flexibility (product depth)
|
## Phase 9 — Universality & flexibility (product depth)
|
||||||
|
|
||||||
- [ ] **Areas/floors registry integration**: import HA floors as spaces, suggest area
|
- [x] **Areas/floors registry integration**: floors-import wizard (v1.13.0); further: suggest area
|
||||||
bindings from the registry, sync names (HA is moving this way — native Areas/Home
|
bindings from the registry, sync names (HA is moving this way — native Areas/Home
|
||||||
dashboard; riding the registry is our moat).
|
dashboard; riding the registry is our moat).
|
||||||
- [ ] **Curation without hardcode**: icon rules (`iconFor`) become data — user-editable
|
- [x] **Filtering without hardcode**: icon rules became data (v1.13.0); the runtime
|
||||||
|
filter itself became explicit per-device hide flags in v1.51.0 (docs/FILTERING.md);
|
||||||
|
icon rules are user-editable
|
||||||
mapping (regex/domain/device_class → mdi icon) stored in config, shipping EN+RU
|
mapping (regex/domain/device_class → mdi icon) stored in config, shipping EN+RU
|
||||||
defaults; drop dacha-specific patterns from code.
|
defaults; drop dacha-specific patterns from code.
|
||||||
- [ ] **Click actions** per device/domain: toggle / more-info / navigate / custom service
|
- [x] **Click actions** per device (v1.13.0, simplified v1.38.1): card / more-info /
|
||||||
call (configurable, like standard card `tap_action`).
|
toggle, with the lock/alarm safety model.
|
||||||
- [ ] **Theming**: respect light themes (currently dark-leaning), use HA theme variables
|
- [x] **Theming**: light-theme pass done in v1.13.0; HA theme variables
|
||||||
everywhere, optional per-space background color.
|
everywhere, optional per-space background color.
|
||||||
- [ ] Multi-instance question: keep single-instance (one house) but support **multiple
|
- [ ] Multi-instance question: keep single-instance (one house) but support **multiple
|
||||||
cards** with different default spaces (already works) — document as a decision.
|
cards** with different default spaces (already works) — document as a decision.
|
||||||
- [ ] Plan formats: keep SVG/PNG/JPG/WebP; add max dimensions guidance; optional
|
- [ ] Plan formats: keep SVG/PNG/JPG/WebP; add max dimensions guidance; optional
|
||||||
auto-downscale on upload.
|
auto-downscale on upload.
|
||||||
- [ ] More locales: extract i18n dictionaries to JSON so contributors can add languages
|
- [x] More locales: i18n dictionaries are JSON since v1.13.0 (src/i18n/*.json).
|
||||||
without touching TS.
|
|
||||||
|
|
||||||
## Phase 10 — Community & distribution
|
## Phase 10 — Community & distribution
|
||||||
|
|
||||||
- [ ] hacs/default PR #8995 through moderation (expect drafting for fixes).
|
- [ ] hacs/default PR **#9004** through moderation (#8995 was bot-closed for a
|
||||||
|
non-template body; #9004 is queued with the label since 2026-07-22).
|
||||||
- [ ] Demo GIF/video for README (the single biggest driver of adoption for dashboard cards).
|
- [ ] Demo GIF/video for README (the single biggest driver of adoption for dashboard cards).
|
||||||
- [ ] Forum post in the Floorplan category + Reddit r/homeassistant showcase once
|
- [ ] Forum post in the Floorplan category + Reddit r/homeassistant showcase once
|
||||||
the demo assets exist.
|
the demo assets exist.
|
||||||
|
|||||||
+28
-7
@@ -11,7 +11,7 @@
|
|||||||
> (versions, publication, infrastructure), DEVELOPMENT.md for new gotchas,
|
> (versions, publication, infrastructure), DEVELOPMENT.md for new gotchas,
|
||||||
> ARCHITECTURE.md for design changes, ROADMAP.md when plans move.
|
> ARCHITECTURE.md for design changes, ROADMAP.md when plans move.
|
||||||
|
|
||||||
## Snapshot (2026-07-28)
|
## Snapshot (2026-07-29)
|
||||||
|
|
||||||
| Item | State |
|
| Item | State |
|
||||||
|---|---|
|
|---|---|
|
||||||
@@ -20,7 +20,7 @@
|
|||||||
| GitHub | https://github.com/Matysh/houseplan-card — **`main` carries every published release, the latest tag is the current version above**; `dev` is where work lands and is merged into `main` at release time (so `dev` is normally equal to or ahead of `main`, never behind). Push via SSH key `ha_jb` (remote git@github.com:…); API releases via the fine-grained PAT in `~/.git-credentials` (Contents R/W, issued 2026-07-23) |
|
| GitHub | https://github.com/Matysh/houseplan-card — **`main` carries every published release, the latest tag is the current version above**; `dev` is where work lands and is merged into `main` at release time (so `dev` is normally equal to or ahead of `main`, never behind). Push via SSH key `ha_jb` (remote git@github.com:…); API releases via the fine-grained PAT in `~/.git-credentials` (Contents R/W, issued 2026-07-23) |
|
||||||
| CI | validate.yml (hacs + hassfest + frontend + backend) green; release.yml attaches the bundle on release publish |
|
| CI | validate.yml (hacs + hassfest + frontend + backend) green; release.yml attaches the bundle on release publish |
|
||||||
| HACS | Custom repository works. **Inclusion PR: hacs/default#9004** — open, valid, labeled; ~864 older open PRs but merge rate ≈180/mo; realistic ETA 1–3 months (checked 2026-07-24) |
|
| HACS | Custom repository works. **Inclusion PR: hacs/default#9004** — open, valid, labeled; ~864 older open PRs but merge rate ≈180/mo; realistic ETA 1–3 months (checked 2026-07-24) |
|
||||||
| Home instance | ha.jbstudio.pro (SSH port 323, key `ha_jb`), deployed **v1.51.1** via direct copy (HACS custom repo also installed) |
|
| Home instance | ha.jbstudio.pro (SSH port **22222**, key `ha_jb`; HA config root is `/mnt/data/supervisor/homeassistant` — `/config` does NOT exist in this SSH environment), deployed **v1.51.1** via direct copy (HACS custom repo also installed) |
|
||||||
| Localization | UI en/ru (src/i18n/*.json), everything user-visible localized incl. kiosk popover |
|
| Localization | UI en/ru (src/i18n/*.json), everything user-visible localized incl. kiosk popover |
|
||||||
| Tests | Four layers: frontend unit (`npm test`, node:test over `test-build/`), pure backend (`pytest tests_backend`, runs anywhere), HA-harness backend (same folder, CI only — needs py3.13 + pytest-homeassistant-custom-component), and browser smokes (`demo/smoke_*.mjs`, headless chromium). **Counts are not written down here** — they went stale within two releases while the version line beside them was kept current, which reads as less coverage than exists (review R5-2). Run `npm run inventory` for the current numbers, or read them off the last CI run |
|
| Tests | Four layers: frontend unit (`npm test`, node:test over `test-build/`), pure backend (`pytest tests_backend`, runs anywhere), HA-harness backend (same folder, CI only — needs py3.13 + pytest-homeassistant-custom-component), and browser smokes (`demo/smoke_*.mjs`, headless chromium). **Counts are not written down here** — they went stale within two releases while the version line beside them was kept current, which reads as less coverage than exists (review R5-2). Run `npm run inventory` for the current numbers, or read them off the last CI run |
|
||||||
| Community | **Telegram chat: https://t.me/ha_houseplan** (created 2026-07-27) — the primary user-facing support channel; GitHub issues stay for bugs/features. Link it from any new release notes and posts |
|
| Community | **Telegram chat: https://t.me/ha_houseplan** (created 2026-07-27) — the primary user-facing support channel; GitHub issues stay for bugs/features. Link it from any new release notes and posts |
|
||||||
@@ -48,6 +48,24 @@
|
|||||||
- **Dialog UX**: binding radios + entities checkbox + search dropdown
|
- **Dialog UX**: binding radios + entities checkbox + search dropdown
|
||||||
(v1.38.0); tap actions simplified to Device card / more-info / Toggle,
|
(v1.38.0); tap actions simplified to Device card / more-info / Toggle,
|
||||||
right-click → more-info (v1.38.1); Esc closes every dialog (v1.30.4).
|
right-click → more-info (v1.38.1); Esc closes every dialog (v1.30.4).
|
||||||
|
- **Room settings, tier 3** (v1.42.0): per-room fill/temp-source/label sizes;
|
||||||
|
the settings button sits at the room's VISUAL centre (inscribed circle +
|
||||||
|
centroid pull), icon-derived size, zooms with the plan (v1.51.0).
|
||||||
|
- **Files & plans** (v1.44–v1.50): signed content urls with sandbox CSP,
|
||||||
|
copy-on-write plan files, "already uploaded" picker + explicit delete
|
||||||
|
(v1.47.0), store quotas instead of any age-based deletion (v1.49.0),
|
||||||
|
nothing is ever deleted on an inference (docs/SCOPE.md rule).
|
||||||
|
- **Square canvas** (v1.48.0) with a crash-safe two-store migration
|
||||||
|
(geom_pending, v1.50.0) and an explicit geometry/repair command (v1.50.1);
|
||||||
|
content-fit default zoom with devices as content, zoom out to 0.4×,
|
||||||
|
measured stage height (v1.49–v1.50.2).
|
||||||
|
- **Explicit hide flags** (v1.51.0, docs/FILTERING.md): per-device
|
||||||
|
"Hide from plan" checkbox seeded once from the old filter; local
|
||||||
|
"Show hidden" ghosts; hidden counts toward room LQI on both cards, casts
|
||||||
|
no light (v1.51.1).
|
||||||
|
- **Yellow = working right now** (v1.51.0): climate by hvac_action, service
|
||||||
|
switches can no longer become primary, glow pool and icon share one
|
||||||
|
condition. Editor gestures on touch (pinch/pan) landed the same release.
|
||||||
|
|
||||||
## Recent milestones (details in CHANGELOG.md)
|
## Recent milestones (details in CHANGELOG.md)
|
||||||
|
|
||||||
@@ -129,8 +147,9 @@
|
|||||||
|
|
||||||
1. **hacs/default PR #9004** — accepted by the bot into the review queue ('New default
|
1. **hacs/default PR #9004** — accepted by the bot into the review queue ('New default
|
||||||
repository' label). Minor issues ⇒ the bot drafts the PR (fix and re-ready).
|
repository' label). Minor issues ⇒ the bot drafts the PR (fix and re-ready).
|
||||||
2. GitHub PAT `houseplan-card-publish` (repo+workflow) expires ~2026-07-12; in sandbox
|
2. GitHub auth: fine-grained PAT (Contents R/W, issued 2026-07-23) in the sandbox
|
||||||
`~/.git-credentials`. Revoke after the HACS queue clears, or re-issue when needed.
|
`~/.git-credentials`; pushes go over SSH with the `ha_jb` key. The old classic PAT
|
||||||
|
expired and is gone.
|
||||||
3. Privacy: legacy real-house plan sources (`assets/`) removed from the tree in
|
3. Privacy: legacy real-house plan sources (`assets/`) removed from the tree in
|
||||||
v1.13.3, but they persist in git history and old release archives; 8 README
|
v1.13.3, but they persist in git history and old release archives; 8 README
|
||||||
screenshots in docs/images are still from the real house (replacement with
|
screenshots in docs/images are still from the real house (replacement with
|
||||||
@@ -150,12 +169,14 @@
|
|||||||
2. Restore the repo: `git clone <user-folder>/houseplan-card.git.bundle hpcN` in `/tmp`
|
2. Restore the repo: `git clone <user-folder>/houseplan-card.git.bundle hpcN` in `/tmp`
|
||||||
(files from *previous* sandbox sessions in `/tmp` belong to `nobody` and are unreadable —
|
(files from *previous* sandbox sessions in `/tmp` belong to `nobody` and are unreadable —
|
||||||
always clone into a fresh directory; `npm ci` again).
|
always clone into a fresh directory; `npm ci` again).
|
||||||
3. Deployment needs the `ha_jb` SSH key — ask the user to upload it (uploads are readable
|
3. Deployment needs the `ha_jb` SSH key — it lives in the user folder at
|
||||||
only in the session they were uploaded in).
|
`houseplan/.secrets/ha_jb` (outside git) and often survives in the sandbox home
|
||||||
|
`~/.ssh/ha_jb`; copy with chmod 600. Only ask the user if both are gone.
|
||||||
4. Build only in `/tmp` (never on the mount), `npm run build` (starts with `tsc --noEmit`),
|
4. Build only in `/tmp` (never on the mount), `npm run build` (starts with `tsc --noEmit`),
|
||||||
md5-verify after every deploy, restart HA via
|
md5-verify after every deploy, restart HA via
|
||||||
`nohup ha core restart >/dev/null 2>&1 </dev/null &` (otherwise the SSH session hangs).
|
`nohup ha core restart >/dev/null 2>&1 </dev/null &` (otherwise the SSH session hangs).
|
||||||
5. GitHub pushes need a PAT (create via the user's Chrome: settings/tokens, repo+workflow scope).
|
5. GitHub pushes: SSH remote with the `ha_jb` key; API releases with the fine-grained
|
||||||
|
PAT from `~/.git-credentials` (see the watchlist).
|
||||||
|
|
||||||
## Product scope
|
## Product scope
|
||||||
|
|
||||||
|
|||||||
+5
-3
@@ -59,8 +59,10 @@ Header in View: space tabs, device count, zoom cluster. Nothing else.
|
|||||||
- Icon dragging (ONLY here). Click on a device opens the **edit dialog directly**
|
- Icon dragging (ONLY here). Click on a device opens the **edit dialog directly**
|
||||||
(binding, name, icon, size/angle, display badge/ripple + colors, tap override,
|
(binding, name, icon, size/angle, display badge/ripple + colors, tap override,
|
||||||
model/link/description/PDFs, room).
|
model/link/description/PDFs, room).
|
||||||
- + add device/entity/virtual, hide device, ↺ reset layout, 👁 show-all (curation
|
- + add device/entity/virtual, the "Hide device from plan" checkbox (since
|
||||||
tool), ⬡ icon rules.
|
v1.51.0 the one hiding mechanism, docs/FILTERING.md), ↺ reset layout,
|
||||||
|
👁 "Show hidden" (local editor tool; replaced the shared show-all toggle),
|
||||||
|
⬡ icon rules.
|
||||||
|
|
||||||
## Deprecations decided
|
## Deprecations decided
|
||||||
|
|
||||||
@@ -85,7 +87,7 @@ Header in View: space tabs, device count, zoom cluster. Nothing else.
|
|||||||
edit interactions/buttons (biggest UX win, smallest surface).
|
edit interactions/buttons (biggest UX win, smallest surface).
|
||||||
- **It.2 — Plan tab:** move markup tools + space dialogs + labels drag + openings
|
- **It.2 — Plan tab:** move markup tools + space dialogs + labels drag + openings
|
||||||
editing under Plan; colored frame indicator.
|
editing under Plan; colored frame indicator.
|
||||||
- **It.3 — Devices tab:** drag + direct-edit click + curation tools under Devices.
|
- **It.3 — Devices tab:** drag + direct-edit click + filtering tools under Devices.
|
||||||
- **It.4+:** follow-up features 1–5 above, each its own release.
|
- **It.4+:** follow-up features 1–5 above, each its own release.
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user