Files
houseplan-card/docs/CHANGELOG.md
T

282 lines
31 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Changelog
## v1.9.3 — 2026-07-05 (аудит + рефакторинг + тесты)
- Чистые функции `fitView` (contain-прямоугольник вьюпорта) и `declump` (расталкивание значков)
вынесены из карточки в `logic.ts` — покрыты юнит-тестами (было 9 → стало 14 тестов).
- `_lqiFor` и `_roomLqi` теперь используют общую `averageLqi` (убрано дублирование усреднения).
- Удалён мёртвый код после отказа от отдельного режима правки: поле `_edit` (писалось, но не
читалось), методы `_renderEditbar` и `_applyXY` (не вызывались).
- Поведение не изменилось — только структура и покрытие тестами. Проверено: tsc, сборка,
14 фронт-тестов + 10 бэк-тестов зелёные, headless-дымтест (рендер/зум/устройства/declump) чист.
## v1.9.2 — 2026-07-05 (сетка вдвое мельче)
- Шаг сетки разметки/привязки уменьшен вдвое: `GRID_N` 120 → 240. Позиции устройств и контуры
комнат НЕ пересчитываются и не сдвигаются: координаты хранятся нормированными долями и снапятся
к узлам сетки, а старые узлы (кратные 1/120) — точное подмножество новых (кратных 1/240).
Проверено на живой раскладке (65 позиций — все уже на новой сетке). Перетаскивание теперь
позволяет более точное позиционирование.
## v1.9.1 — 2026-07-05 (сигнал Zigbee: чтение из атрибута + ZHA)
- Уровень сигнала теперь берётся не только из выделенного сенсора `*_linkquality` (Z2M), но и:
из сенсоров `*_lqi` (ZHA), и из АТРИБУТА `linkquality`/`lqi` на любой сущности устройства.
Это покрывает устройства, у которых отдельный сенсор сигнала отключён, но значение есть в атрибуте.
- ПРИМЕЧАНИЕ: если у устройства сенсор `*_linkquality` отключён (disabled_by=integration) И значение
нигде не публикуется как атрибут — сигнал показать нельзя, нужно включить сенсор в реестре HA.
## v1.9.0 — 2026-07-05 (UX: перетаскивание всегда, расталкивание, показать все, адаптив)
- **Перетаскивание значков доступно всегда** — отдельный «режим правки» убран (кнопка ✥ удалена).
Клик по значку открывает карточку устройства (правка метаданных — через кнопку «Редактировать»
в ней), перетаскивание работает в любой момент. `_pointerDown` больше не требует `_edit`.
- **Значки не скучиваются** (`_declump`): после авто-раскладки по сетке выполняется расталкивание
в пределах комнаты, чтобы иконки не налезали друг на друга.
- **Позиции фиксируются при сохранении комнаты**: авто-позиции устройств зоны один раз пишутся
в раскладку, поэтому при смене порядка в реестре HA значки не перетасовываются.
- **Дубли не скрываются, а нумеруются**: устройства с одинаковым «имя|зона» получают суффикс
(« 2», « 3»…) вместо тихого исчезновения.
- **Кнопка 👁 «Показать все устройства»** в шапке: временно отключает курирование и показывает
все устройства зоны (мосты, служебные, дубли) — на случай, если нужное скрыто. Флаг `show_all`
в настройках конфига.
- **Подсказка продолжения разметки**: после сохранения комнаты тост показывает счётчик комнат и
предлагает обвести следующую или выйти из разметки.
- **Адаптивная шапка**: тулбар переносится и ужимается на узких экранах (media-query ≤620px).
## v1.8.4 — 2026-07-04 (онбординг: обязательные поля + ведение пользователя)
- Первичная инициализация приведена к целевому сценарию: установка → диалог пространства →
комнаты → авто-значки устройств.
- **Подложка обязательна** при создании пространства: «Сохранить» неактивна без загруженного
плана (раньше требовалось только название — можно было создать пустое пространство).
- **Зона комнаты обязательна** с явным выходом: основная «Сохранить» требует привязку к зоне HA;
для декоративных комнат без устройств (холл, сауна) есть отдельная кнопка «Без зоны»
(нужно только имя). Раньше сохранить можно было по «имя ИЛИ зона».
- **Ведение пользователя:** на пустом серверном конфиге диалог пространства открывается
автоматически; после добавления первого пространства карточка сама входит в режим разметки
комнат с подсказкой «обведите комнаты».
- При сохранении комнаты с зоной значки устройств этой зоны авто-расставляются внутри контура
(курируемый набор: без мостов/служебных/дублей/одиночных ламп из групп), тост показывает,
сколько устройств добавлено.
## v1.8.3 — 2026-07-04 (мгновенный старт: кэш конфига, данные в фоне)
- Иконки и план появлялись с задержкой — карточка ждала ответа сервера (WS `config/get`
+ ретраи прогрева соединения), до этого модель пространств была пуста.
- Внедрён кэш «stale-while-revalidate»: снимок серверного конфига + rev + раскладки
сохраняется в `localStorage['houseplan_card_cfg_v1']`. В `setConfig` (синхронно, до прихода
hass) он восстанавливается — план и значки рисуются сразу из кэша (проверено: setConfig
наполняет модель за 0.2 мс без сервера), а свежие данные догружаются в фоне и обновляют
карточку. Живые состояния/температуры/сигнал подтягиваются по мере прогрева hass.
- Кэш обновляется после каждой успешной загрузки, live-ресинка и сохранения позиций иконок,
поэтому при следующем открытии виден актуальный снимок. При недоступном сервере показывается
последний известный план вместо пустого онбординга.
## v1.8.2 — 2026-07-04 (векторно-чёткий зум через viewBox + полная ширина сцены)
- Зум переведён с CSS `transform: scale()` на манипуляцию `viewBox` SVG. Раньше слой
растрировался и потом масштабировался — при приближении всё «мылилось». Теперь браузер
перерисовывает вектор в целевом разрешении: иконки, подписи комнат, линии, штриховка и
векторная подложка остаются чёткими на любом масштабе (проверено на 274%).
- Слой иконок (HTML) позиционируется и масштабируется по тому же `view`, а не общим
transform — иконки чёткие и растут вместе с планом.
- Сцена теперь занимает всю ширину вьюпорта (модель «contain» по аспекту сцены): при
зум-ине контент заполняет ширину без чёрных полей по бокам. При полном отдалении виден
весь план (по ширине и высоте), поля вокруг залиты фоном карточки, а не чёрным.
- Вся координатная математика (клик разметки `_svgPoint`, drag иконок, pan, pinch) переписана
в единых `view`-координатах — редактирование корректно на любом зуме. ResizeObserver сцены
пересчитывает `view` при изменении размеров (сайдбар, поворот). Пан/зум ограничены `fit`.
## v1.8.1 — 2026-07-04 (fit-to-viewport + сохранение зума по пространствам)
- Уменьшение масштаба до полного вида: нижний предел зума = 100% совпадает с полностью
видимым планом. `.stage` теперь ограничена по высоте вьюпорта
(`width:min(100%, calc((100dvh 118px) × aspect))`, `max-width:100%`, центрирование),
поэтому при сбросе/зум-ауте вся схема видна и по ширине, и по высоте без обрезки.
- Масштаб запоминается для каждого пространства отдельно и локально на устройстве
(`localStorage['houseplan_card_zoom_v1']`, `_zoomBySpace`): переключение этажей
восстанавливает свой зум; при возврате пан центрируется и ограничивается.
- Проверено на живом HA: f1→196%, f2→140%, двор нетронут — после переключений
значения восстанавливаются; сброс даёт 100% и полный план (874≤992 px по высоте).
## v1.8.0 — 2026-07-04 (зумирование плана)
- Зум и панорама схемы: колёсико мыши (к курсору), щипок двумя пальцами (pinch) на тач-экране,
перетаскивание фона одним пальцем при увеличении, кнопки −/сброс/+ в тулбаре, бейдж масштаба.
- Реализовано через CSS-transform на `.zoomwrap` (translate+scale); координатная математика
(клик разметки, drag иконок, тултипы) пересчитана с учётом зума/пана — редактирование
работает и при увеличении. Пан ограничен, чтобы контент всегда покрывал сцену. Зум 100–800%.
- `.stage`: overflow hidden + touch-action none (свои жесты вместо браузерных).
## v1.7.4 — 2026-07-04 (PDF по HTTP вместо WebSocket)
- КОРНЕВАЯ ПРИЧИНА невозможности загрузить PDF: файл слался как base64 одним WebSocket-сообщением,
а у WS есть лимит размера — реальный мануал (>2–3 МБ) превышал его, соединение рвалось
(«Connection lost»), из-за чего и падала загрузка, и закрывался диалог (обрыв WS → переподключение
→ ре-рендер). Подтверждено тестом: 1 МБ по WS ок, 3 МБ → Connection lost.
- Файлы-инструкции теперь грузятся через HTTP-эндпоинт `POST /api/houseplan/upload` (multipart,
HomeAssistantView, requires_auth, admin_only-проверка) — как медиа в самом HA. Проверено:
3 МБ (182мс) и 10 МБ (446мс) загружаются на ура.
- Читаемые ошибки везде (`_errText`): больше никаких «[object Object]»; понятные тексты для
too_large / bad_ext / unauthorized.
- WS-команда houseplan/file/set оставлена для совместимости, но фронт использует HTTP.
## v1.7.3 — 2026-07-04 (фиксы диалога устройства)
- PDF-инструкции не загружались: ручной base64 (`btoa(String.fromCharCode(...subarray))`) падал
на реальных файлах (RangeError при спреде больших массивов), а при закрытии диалога во время
await бросал null-доступ. Заменено на `FileReader.readAsDataURL` (надёжно для любого размера),
результаты аккумулируются и добавляются, только если диалог ещё открыт (без исключений).
- Диалог редактирования устройства/пространства/комнаты закрывался по клику мимо и «сам»
(случайный клик по фон-оверлею, в т.ч. после закрытия системного выбора файла). Убрано
закрытие по клику на фон у диалогов-редакторов — только явные Отмена/Сохранить/Esc.
Инфо-карточка (только чтение) по-прежнему закрывается кликом мимо.
- Проверено на живом HA: PDF прикрепляется; клик по фону и обновление данных диалог не закрывают.
## v1.7.2 — 2026-07-04 (фикс мобильного «ошибка конфигурации»)
- ПРИЧИНА: карточка подключалась только через `add_extra_js_url` (extra_module_url), загрузку
которого фронтенд НЕ дожидается — на холодном старте мобильного приложения дашборд рисовался
раньше регистрации элемента → «ошибка конфигурации». (Все рабочие HACS-карточки — Lovelace-ресурсы.)
- ФИКС 1: интеграция регистрирует карточку как **Lovelace-ресурс** (module) — их фронтенд ждёт
перед рендером. Идемпотентно (обновляет URL при смене версии, без дублей); фолбэк на
extra_module_url для YAML-режима Lovelace. `_register_lovelace_resource` в __init__.py.
- ФИКС 2: `_loadFromServer` ретраит (до 8 попыток по обновлениям hass) — если hass пришёл раньше
готовности WS, карточка не застревает на онбординге, а дожидается конфига.
- Проверено: ресурс houseplan-card.js зарегистрирован, extra_module_url пуст (единый чистый
модуль), карточка рендерит план на свежей вкладке без ошибки.
## v1.7.0 — 2026-07-04 (аудит + рефакторинг + тесты)
- Удалён вшитый в бандл дом-образец (дача, ~245 КБ base64 планов + ROOMS/FLOOR_*): бандл
293 КБ → 83 КБ. Свежая установка показывает онбординг «Добавить пространство», а не чужой дом.
- Удалён код миграции legacy→сервер (дача уже на server config) и мёртвые пути
device_overrides/virtual_devices (заменены markers[]).
- Чистая логика вынесена в src/logic.ts (lqiColor, snapToGrid, segKey, pointInPolygon,
markerIdForBinding, averageLqi) — покрыта юнит-тестами (node:test, 9 тестов + iconFor).
- Бэкенд: валидация/санитайзеры вынесены в validation.py (без HA-импортов) — pytest, 10 тестов.
- БЕЗОПАСНОСТЬ: тест выявил, что санитайзер имён файлов/маркеров сохранял ведущие точки
(риск обхода каталогов через «..»); добавлено срезание ведущих точек, пустое → misc/file.
- Исправлены реальные баги, ранее замаскированные обрезанным rules.ts: DOMAIN_PRIORITY был
усечён (ломало выбор more-info-сущности); _defaultPositions падал на полигон-комнатах
(теперь bbox). tsc --noEmit добавлен в сборку и CI — строгая типизация проходит.
- Убраны дубли-мусор src/data/{editor,rules}.ts; версии синхронизированы (manifest застрял на 1.4.0).
- CI: добавлены typecheck, юнит-тесты фронта и бэка.
## v1.6.2 — 2026-07-04
- Поле «Комната» в диалоге устройства теперь для ВСЕХ значков (не только виртуальных):
для привязанных — «переопределить размещение» (по умолчанию по зоне устройства); смена
комнаты переставляет значок в её центр. Сохраняется в marker.space/area и выигрывает у зоны HA.
- В инфо-карточке добавлена кнопка «Редактировать» — открывает диалог редактирования устройства.
## v1.6.0 — 2026-07-04 (Фаза 3: редактор устройств)
- Модель «маркеров» (config.markers[]): гибрид — авто-устройства HA появляются сами, маркеры
правят/перепривязывают/дополняют их и описывают ручные/виртуальные значки. id маркера
сохраняет позицию (device→device_id, entity→lg_<eid>, virtual→v_<rand>).
- Клик по значку: обычный режим → инфо-карточка (имя, модель, состояние, ссылка, описание,
PDF-инструкции, кнопка «Открыть в HA»); режим правки → диалог редактирования.
- Диалог устройства: имя, привязка (пикер всех устройств/групп HA+Z2M+хелперов с текстовым
фильтром, минус уже размещённые и дубли по имя|area, + «Виртуальное устройство»), MDI-иконка
(ha-icon-picker), модель, ссылка, описание, прикрепление файлов-инструкций (PDF на сервер),
комната (для виртуальных), Убрать/Отмена/Сохранить.
- Тулбар: кнопка «+» (тултип «Добавить устройство») — пустой диалог.
- Бэкенд: MARKER_SCHEMA в config; WS houseplan/file/set (файлы в /config/houseplan/files/,
≤25 МБ, отдача /houseplan_files/files/); статика files зарегистрирована.
- Виртуальные значки теперь перетаскиваются и позиционируются как обычные (layout по id).
## v1.6.1 — 2026-07-04
- Пикер привязки прячет дубли устройств по «имя|area» (Tuya/LocalTuya), как дедуп на плане.
## v1.5.1 — 2026-07-04 (управление пространствами)
- Иконка-карандаш справа от названия каждого пространства в верхнем тулбаре + кнопка «+»
(только при server config).
- Диалог пространства: поле «Название», превью текущей подложки + «Загрузить/Заменить…»
(SVG/PNG/JPG/WebP, base64 → houseplan/plan/set, пропорции определяются из файла),
кнопки Удалить / Отмена / Сохранить. Создание пустого пространства и удаление (со всеми
комнатами и разметкой, с подтверждением). Сохранение через config/set с ревизией.
## v1.5.0 — 2026-07-04 (группы света = сущности)
- Лампы заменены сущностями групп: HA light-groups (platform=group, area из реестра сущности)
и Z2M-группы (device model=Group) рендерятся иконкой mdi:lightbulb-group; клик → more-info
группы (управление всей группой и участниками штатно в HA).
- Одиночные лампы скрываются в комнатах, где есть группа света (settings.group_lights=false
возвращает поштучный режим).
- Выпилена старая визуальная группировка и кастомное меню участников (упрощение кода).
- Позиции старых групп (grp_<area>) перенесены на новые id (lg_<entity_id>) в раскладке дачи.
## v1.4.4 — 2026-07-04 (КРИТИЧЕСКИЙ фикс: гонка конфигураций)
- ИНЦИДЕНТ: config сохранялся целиком по принципу last-writer-wins — открытый клиент со
старой копией затирал чужие правки (потеряна первая итерация пользовательской разметки).
- Фикс: оптимистичная блокировка — конфиг несёт `rev`; `config/set` принимает `expected_rev`
и возвращает ошибку `conflict` при несовпадении; клиент перечитывает конфиг.
- Live-синхронизация: `config/set` рассылает событие `houseplan_config_updated`; все открытые
карточки подписаны и перечитывают конфиг автоматически (окна больше не расходятся).
- Позиции при drag сохраняются точечно через `layout/update` (dirty-set), а не полным
`layout/set` — раскладка тоже больше не затирается между окнами.
- Бэкап конфига перед деплоем: .storage/houseplan.config.bak-*.
## v1.4.3 — 2026-07-04
- Иконки устройств привязываются к той же сетке, что и разметка (центр иконки = узел, снап
при перетаскивании и вводе X/Y). Существующие 57 позиций в БД дачи снапнуты к узлам.
## v1.4.2 — 2026-07-04 (сетка разметки)
- Шаг сетки уменьшен в 2 раза: GRID_N 60 → 120 (шаг 8.33 рендер-ед. ≈ 0.83% ширины плана).
- Точки сетки рендерятся ПОВЕРХ плана и комнат (grid-rect перенесён из под-плана в верхний
markup-слой); точки контрастнее (r=0.14g, обводка).
- Данные дачи: границы всех 13 комнат привязаны к узлам сетки (снап рёбер, сдвиги ≤ полшага;
правка только конфига инстанса через houseplan/config/set, код не менялся).
- Кэш карточки: URL модуля ?v= берётся из const.VERSION — при обновлении фронтенда бампать
const.py и рестартовать HA, иначе браузеры держат старый модуль в memory-cache.
## v1.4.1 — 2026-07-04 (UX разметки)
- Esc / Ctrl+Z при рисовании убирают последнюю точку (и её линию, если она была добавлена
этим шагом; переиспользованные чужие стены не трогаются).
- Панель редактирования (разметка и правка раскладки) перенесена наверх под шапку карточки
и закреплена вместе с ней (общий sticky-контейнер .hdr).
- Замыкание контура автоматически открывает модальный диалог «Новая комната»: отображаемое
имя, выпадающий список ТОЛЬКО свободных зон HA (не назначенных ни одной комнате конфига),
Сохранить/Отмена. Отмена (или Esc) снимает замыкающую точку — контур можно продолжить.
Выбор зоны при пустом имени подставляет название зоны.
## v1.4.0 — 2026-07-04 (Фаза 2: редактор разметки комнат)
- Режим «Разметка» в карточке (кнопка mdi:vector-square-edit, только при server config):
сетка точек (60 узлов по ширине), линии парами кликов со снапом к узлам, полилиния-превью.
- Замкнутый контур (клик по первой точке) активирует «Сохранить»: выбор зоны HA из
выпадающего списка + название; комната сохраняется полигоном (poly, нормированные вершины).
- Инструменты: Добавить (рисование), Стереть линию (клик по линии), Удалить комнату
(клик внутри + confirm). Линии-«стены» хранятся в space.segments и переиспользуются
соседними комнатами (общие стены — кликами по существующим узлам).
- Рендер комнат: полигоны наравне с прямоугольниками (hover, клик в зону, LQI-тултип,
подпись в центроиде); в режиме разметки контуры и названия всех комнат видимы.
- Бэкенд: ROOM_SCHEMA принимает poly (≥3 вершин) или x/y/w/h; SPACE_SCHEMA — segments.
## v1.3.0 — 2026-07-04 (Фаза 1: серверная конфигурация)
- Store `houseplan.config`: spaces (план, aspect, view_box, комнаты), device_overrides
(hidden/icon/name), virtual_devices, settings (exclude_integrations, group_lights).
- WS: `houseplan/config/get|set`, `houseplan/plan/set` (загрузка файла плана base64 →
`<config>/houseplan/plans/`, отдача через /houseplan_files/plans/).
- Карточка: резолв-модель — server config (координаты НОРМИРОВАННЫЕ 0..1, рендер 1000×1000/aspect)
или legacy-бандл (холст 1489×1053). Раскладка v2: {device_id: {s, x, y}} нормированная.
- Кнопка «На сервер» в режиме правки — миграция legacy-конфига в один клик (планы, комнаты,
view_box, раскладка). Выполнена на даче: .storage/houseplan.config + plans/f1.svg,f2.svg.
- Read-side поддержка оверрайдов устройств и виртуальных устройств (UI управления — фазы 3–4).
## v1.2.2 — 2026-07-04
- Тулбар карточки (вкладки этажей) закрепляется при скролле под шапкой HA
(`position: sticky; top: var(--header-height)`; ha-card overflow: visible).
- Инцидент: промежуточная сборка на нестабильном mount дала битый бандл, роняющий рендер
дашбордов; правило «собирать только в /tmp + md5-контроль» закреплено в DEVELOPMENT.md.
## v1.2.1 — 2026-07-04
- Иконки не увеличиваются при наведении/перетаскивании (убран transform: scale).
## v1.2.0 — 2026-07-03
- Границы комнат сняппены к стенам векторного плана.
- Zigbee LQI: значение под иконкой, среднее по комнате в тултипе, градиент красный→зелёный,
опция show_signal.
- `mdi:lock` для любых устройств с сущностью lock.* (TTLock).
- Выключатель прихожей: исправлена зона устройства в реестре HA (был в detskaia_elina).
## v1.1.0 — 2026-07-03
- Векторные подложки (SVG РЕМПЛАННЕР), автосовмещение масштаба/сдвига растровой корреляцией.
- Размер иконок в % ширины плана (container queries, дефолт 2.5%).
## v1.0.1 — 2026-07-03
- fix: вложенные SVG-фрагменты через lit svg`` (подложка/комнаты не рендерились).
- fix: версия из const вместо блокирующего чтения manifest.json в event loop.
## v1.0.0 — 2026-07-03
- Первый релиз: Lovelace-карточка (TS+Lit, без токена, от hass) + интеграция houseplan
(WS-хранилище раскладки, раздача JS). Перенос модели прототипа: курирование, группы ламп,
iconFor, температура, more-info, навигация в зоны, drag-раскладка.