diff --git a/docs/STATUS.md b/docs/STATUS.md index 83508c3..817f461 100644 --- a/docs/STATUS.md +++ b/docs/STATUS.md @@ -24,7 +24,7 @@ | 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 | | Vacuums | Live robot vacuums shipped (docs/VACUUM.md): puck, server-side trails with display modes, fit-panel calibration. Verified on a live Dreame X50 Master | -| Demo stand | **https://demo.houseplan.tech** — public, login `demo`/`demo`, resets to a pristine synthetic home every hour. **https://dev.houseplan.tech** — closed (basic auth), auto-deploys the `dev` branch every 10 min. Host: `ssh -i ~/.ssh/hp_stand hp@135.106.166.146`; layout, seeds and gotchas in the memory note `houseplan-demo-stand` | +| Demo stand | **https://demo.houseplan.tech** — public, login `demo`/`demo`, resets to a pristine synthetic home every hour. **https://dev.houseplan.tech** — closed (basic auth), auto-deploys the `dev` branch every 10 min. Host: `ssh -i ~/.ssh/hp_stand hp@135.106.166.146`; layout, seeds and gotchas in the memory note `houseplan-demo-stand`. Since 2026-07-31 the stand covers most of the manual checklist: a scripted robot vacuum (`demo/stand/demo_robot` — Tasshack-shaped map sensor, serpentine run, pre-solved calibration, seeded server trail), Zigbee-style LQI template sensors, hand/auto-triggered leak+smoke alarms, an hvac_action climate marker and working script/scene/automation targets for tap-run. The stand-specific how-to-check guide is **docs/TESTING-DEMO.md** | | 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 | | Product scope | docs/SCOPE.md (2026-07-22) is the feature guard rail — check before accepting any feature | diff --git a/docs/TESTING-DEMO.md b/docs/TESTING-DEMO.md new file mode 100644 index 0000000..e3392fc --- /dev/null +++ b/docs/TESTING-DEMO.md @@ -0,0 +1,366 @@ +# Чек-лист ручного тестирования на публичном демо-стенде + +> **Стенд:** https://demo.houseplan.tech — вход **demo / demo** (админ). +> Dev-версия: https://dev.houseplan.tech (basic auth `hp` / `houseplan-dev-2026`, дальше тот же demo/demo). +> +> **Стенд сбрасывается каждый час** к эталонному состоянию — это фича: ломайте +> смело, удаляйте комнаты, заливайте планы, через час всё вернётся. Из этого же +> следует: долгоживущие проверки («файл исчез через сутки», «пережило рестарт») +> на стенде не живут. +> +> Источник истины — [TESTING.md](TESTING.md): формулировки пунктов и их +> `[auto:…]`-маркеры смотреть там. Здесь каждый пункт сокращён до сути и дополнен +> строкой «Стенд: …» — где и как ткнуть именно на демо-стенде. +> +> **Демо-дом:** дашборд «House plan» (виды: План / Киоск / Схема), пространства +> «1 этаж» (Гостиная, Кухня, Спальня, Кабинет, Прихожая) и «Двор». Ключевые +> демо-устройства: робот-пылесос (Прихожая, симулятор `demo_robot`), датчик +> протечки (Кухня, включается помощником `input_boolean.demo_leak`), датчик дыма +> (Спальня, сам срабатывает каждые 10 минут на 30 с), «Тёплый пол» (Кабинет, +> climate.heatpump, hvac_action=heating), 4 «Zigbee»-термометра + дверной датчик +> с атрибутом `linkquality` (отличный/средний/слабый сигнал по комнатам), +> маркер «Открыть шторы» (tap → запуск скрипта с подтверждением). + +## Вводные пункты (v1.43.x–v1.44.x) + +- Smoke-harness сам по себе — Стенд: не проверяется (это CI), только локально. +- Шестерёнка «⚙ Room» на каждой карточке комнаты в редакторе плана — Стенд: открыть «Редактор плана», убедиться что у всех 5 комнат есть кнопка ⚙ фиксированного размера, открывает настройки комнаты. +- Метрики 0.75 от имени комнаты — Стенд: включить метрики в настройках пространства (⚙ у «1 этаж») и посмотреть подпись под именем комнаты. +- Тултип не появляется после touch — Стенд: открыть с планшета/телефона, потыкать комнаты и иконки — hover-тултипов быть не должно. +- Флаг «источник света» у выключателя — Стенд: у «Decorative Lights» (Гостиная) в диалоге устройства включить «Это источник света» — при включении розетка светится в glow-заливке. +- Карточка устройства: управляемые сущности сверху, ≥30 px, замки не переключаются — Стенд: тапнуть «Котёл» или медиаплеер; для замка — открыть карточку двери (бейдж замка на двери в Прихожей). +- Инвариант замков на всех путях — Стенд: дверь в Прихожей: Unlock просит подтверждение, Lock — нет; иконка замка никогда не тогглится тапом. +- Транзакционная миграция вложений — Стенд: прикрепить PDF к устройству, перепривязать маркер на другую сущность — файл открывается после перепривязки. +- Планы и PDF в реальном браузере — Стенд: залить план в настройках пространства (любой PNG/SVG), DevTools → Network: `/api/houseplan/content/...` = 200 с `authSig`, тот же URL без authSig = 401. +- Единая политика прав (may_write) — Стенд: не проверяется напрямую (нужен не-админ; на стенде один пользователь demo-админ) — покрыто tests_backend. +- NaN/Infinity и лимиты openings — Стенд: не проверяется руками (нужен ручной WS-вызов) — tests_backend. +- Захват указателя при drag, декор не утаскивается за границы — Стенд: «Редактор фона», нарисовать фигуру и попытаться утащить её далеко за план. +- Скрытые термометры питают карточку комнаты — Стенд: скрыть «Термометр в гостиной» (галка «скрыть с плана») — температура в карточке Гостиной остаётся. +- Тултип комнаты без «открыть area» — Стенд: навести на комнату с десктопа: имя + температура/сигнал, никакого «открыть». + +## Матрица окружений ★ + +- Chrome/Edge desktop — Стенд: да, просто открыть. +- Firefox desktop — Стенд: да, со своей машины. +- Safari (macOS) — Стенд: да, при наличии Mac. +- HA Companion Android (холодный старт!) — Стенд: да: добавить `https://demo.houseplan.tech` как сервер в приложении (demo/demo), убить приложение, открыть заново на дашборде House plan. +- HA Companion iOS — Стенд: аналогично Android. +- Планшет-киоск — Стенд: частично: открыть вид «Киоск» браузером планшета во весь экран; реальный настенный планшет — только на железе. +- Телефон портрет ≤400 px — Стенд: да, или DevTools device mode. +- Тёмная/светлая тема — Стенд: профиль demo → тема; проверить бейджи/диалоги/контраст. +- RU/EN локали — Стенд: сменить язык в профиле пользователя demo; опцию `language:` карточки можно проверить, отредактировав вид дашборда. + +## Установка / обновление / удаление + +- Свежая установка через HACS — Стенд: не проверяется (интеграция ставится файлами, HACS нет) — локально. +- `single_config_entry` — Стенд: Настройки → Устройства и службы → Добавить интеграцию → «House Plan» недоступна второй раз. +- Обновление через HACS (`?v=` после рестарта) — Стенд: не проверяется (нет HACS; версию ресурса видно в DevTools: `houseplan-card.js?v=1.54.0`). +- YAML-mode Lovelace / extra_module_url — Стенд: частично: стенд как раз грузит карточку через `extra_module_url` (см. configuration.yaml) — если дашборд открылся, механизм жив. +- Удаление entry → ресурс исчезает, `.storage/houseplan.*` живёт — Стенд: можно (Настройки → Интеграции → House Plan → удалить), стенд сам восстановится при сбросе; переустановку файлами проверить нельзя. +- Diagnostics download + REDACTED — Стенд: Настройки → Интеграции → House Plan → «Загрузить диагностику», убедиться что name/link/description/pdfs = `**REDACTED**`. + +## Режимы ★ + +- Всегда открывается во View — Стенд: войти в редактор, перезагрузить страницу — карточка снова во View. +- View: только pan/zoom/tap/long-press, иконки не таскаются — Стенд: попробовать утащить любую иконку в режиме просмотра — должен идти pan. +- Шапка View: табы пространств, счётчик, zoom, табы редакторов, ⚙ — Стенд: глазами в шапке «1 этаж | Двор». +- Plan: тулбар разметки, иконки скрыты, оранжевая рамка — Стенд: вкладка «Редактор плана». +- Devices: drag иконок, клик открывает редактор маркера — Стенд: вкладка «Редактор устройств». +- Табы скрыты для не-админа — Стенд: не проверяется (второго, не-админского, пользователя на стенде нет). +- Открывания во View инертны (дверь/окно — чистый рисунок) — Стенд: во View потыкать дверь в Прихожей мимо бейджа замка — ничего не происходит. +- Бейдж замка — единственное исключение — Стенд: клик по замочку на двери открывает карточку двери; в редакторе плана он инертен. +- Курсор pointer во View, grab в Devices — Стенд: сравнить курсор над иконкой в двух режимах. +- В Plan открывание интерактивно (drag по стенам, 3 px порог) — Стенд: редактор плана → потаскать дверь вдоль стены, одиночный тап открывает свойства. + +## Онбординг ★ + +Все пункты онбординга требуют ПУСТОЙ конфиг. На стенде: Настройки → Устройства и службы → House Plan можно удалить и добавить интеграцию заново, либо стереть все пространства руками — и пройти онбординг; сброс через час всё вернёт. +- Мастер импорта этажей — Стенд: у демо-дома этажи HA не заведены, мастер предложит «Start from scratch»; полный сценарий с этажами — локально (или создать этажи в Настройки → Зоны и этажи, затем удалить пространства карточки). +- Остальные пункты мастера (снять галки → Create disabled, очередь диалогов, Skip/Cancel, авто-разметка с тостом, пустое состояние) — Стенд: в рамках того же прогона после удаления пространств. + +## Пространства ★ + +- Создание с картинкой (SVG/PNG/JPG/WebP), чёткость на зуме — Стенд: «+» в шапке → загрузить свой файл (демо-планы нарисованы без подложки — тем интереснее добавить). +- >8 MB → читаемый тост — Стенд: залить большой файл. +- «Без изображения — нарисую сам», ориентация — Стенд: «+» → режим рисования. +- Белый холст в draw-режиме — Стенд: оба демо-пространства такие: борта/имена читаемы на белом. +- Rename / замена картинки / image→draw отвязывает план — Стенд: ⚙ пространства. +- Удаление пространства — Стенд: удалить «Двор», убедиться что «1 этаж» не тронут; сброс вернёт. +- Настройки отображения: борта, имена, цвет+прозрачность, заливки — Стенд: ⚙ «1 этаж» — там всё живое, предпросмотр после сохранения. +- Заливка «zigbee»: красный→зелёный по среднему LQI — Стенд: ⚙ «1 этаж» → заливка «Сигнал Zigbee»: Гостиная зелёная (LQI ~206), Кабинет красный (~24), Двор не залит (нет zigbee). +- Заливка «lights» — Стенд: включить, зажечь свет в комнате с плана — комната жёлтая, потушить — серая. +- Заливка «temperature» + границы комфорта — Стенд: включить: Спальня синяя (~18.7°), Кухня жёлтая (~26°), Гостиная зелёная (~22.8°); границы 20–25 редактируются тут же. +- Радиогруппа заливок без легенды — Стенд: глазами в ⚙ пространства. +- Hover затемняет текущую заливку — Стенд: навести на комнату при любой заливке. +- Тултип комнаты со средней температурой — Стенд: навести на Кухню — «≈26°». +- Средняя температура только от термометров — Стенд: рядом с «Тёплым полом» (Кабинет) убедиться, что его current_temperature не ломает среднее (в Кабинете свой термометр). +- Ширина диалога 500 px, компактные поля — Стенд: глазами в ⚙ пространства. +- Общие настройки (⚙ в шапке): цвета по режимам + Reset — Стенд: покрутить цвета glow/temp/lqi, Reset. +- Пользовательские цвета и на статичной карточке — Стенд: сменить цвет заливки, открыть вид «Схема». +- Градиент LQI между настроенными цветами — Стенд: сменить цвета weak/strong в ⚙ и посмотреть заливку zigbee. +- Per-space «Показывать LQI» — Стенд: выключить в ⚙ «1 этаж» — бейджи цифр у термометров и строка сигнала в тултипах пропадают только там. +- Центровка бейджа и глифа — Стенд: глазами на любой иконке при максимальном зуме. +- Hover-подсветка при кастомных бортах — Стенд: покрасить борта и навести. +- Настройки живут на сервере — Стенд: сменить цвет, открыть стенд в приватном окне/другом браузере — цвет тот же. + +## Редактор разметки комнат ★ + +Всё проверяется в «Редакторе плана» на «1 этаже» (или создайте своё пространство — сброс простит всё). +- Сетка, снап, общие стены — Стенд: дорисовать комнату впритык к существующей. +- Линейка сегмента (метры; cm/cell из настроек) — Стенд: начать рисовать контур, смотреть на бегущую длину. +- Незакрытый контур не сохраняется — Стенд: начать контур, уйти из разметки, вернуться — линий нет. +- Удаление комнаты бережёт общие стены — Стенд: удалить Прихожую (⚙ комнаты → удалить), стены Кабинета/Спальни на месте; сброс вернёт. +- Нет инструмента «Erase» в тулбаре — Стенд: глазами. +- Пересечения запрещены (клик внутри чужой комнаты → тост) — Стенд: попытаться начать контур внутри Гостиной. +- Контур вокруг существующей комнаты отклоняется — Стенд: обвести Кабинет снаружи. +- Merge двух смежных / отказ для несмежных — Стенд: слить Кабинет+Прихожую, тост при попытке слить Кабинет+Кухню; сброс вернёт. +- Split: две точки на стенах, бОльшая часть сохраняет имя — Стенд: разрезать Гостиную; Cancel в диалоге — комната цела. +- Split с точкой вне стены / вдоль стены → тост — Стенд: там же. +- Split на не-грид комнатах (снап к стене) — Стенд: комнаты демо на гриде; полноценно — локально, но снап виден: клик чуть мимо стены цепляется. +- Промах далеко от стены → тост — Стенд: кликнуть в центр комнаты. +- Esc/Ctrl+Z снимает точку, Reset чистит — Стенд: во время рисования. +- Замыкание (≥4 точек) → диалог комнаты — Стенд: нарисовать комнату во «Дворе». +- В диалоге только свободные зоны; выбор зоны подставляет имя — Стенд: все 6 зон заняты — список пуст: создать комнату «без зоны». +- «Без зоны» требует имя, `area: null` — Стенд: там же. +- Cancel диалога возвращает контур — Стенд: там же. +- Сохранение с зоной раскладывает устройства зоны — Стенд: не проверяется как есть (у demo-сущностей нет device registry — автораскладка по зонам не работает, маркеры на стенде явные); полноценно — локально/на даче. +- Erase удаляет линию, удаление комнаты — полигон — Стенд: инструментом «ластик линий» в тулбаре (клик по своей линии). +- Иконки скрыты в разметке — Стенд: глазами. + +## Устройства на плане ★ + +- Авто-устройства только в комнатах своей зоны — Стенд: не проверяется (см. выше: без device registry автонаполнение молчит; все маркеры стенда — явные entity-маркеры). +- Фильтрация мостов/групп/сцен, 👁 «показать все» — Стенд: «Редактор устройств» → 👁: появляются скрытые сущности (сцены/скрипты в списке добавления отфильтрованы). +- Нумерация дубликатов имён — Стенд: добавить второй маркер той же сущности не даст (занята) — проверяется локально. +- Группы света сворачивают лампы — Стенд: не проверяется (в демо нет light-групп с device registry). +- Drag иконок, снап к сетке, позиция per-space — Стенд: редактор устройств: перетащить иконку, F5 — позиция жива; у «Двора» своя раскладка. +- ↺ сброс автолейаута — Стенд: не проверяется: кнопка Reset убрана в v1.33.2 (пункт в TESTING.md исторический). +- Бейдж температуры, LQI с цветом — Стенд: под «Zigbee»-термометрами цифра LQI (цвет от красного к зелёному: Кабинет красный, Гостиная зелёный), температура на бейдже. +- Живые состояния: свет жёлтый, открытая штора оранжевая, unavailable блёклый — Стенд: пощёлкать свет; открыть штору («Открыть шторы» или карточка); unavailable в демо нет — эмулировать нечем, но у робота после паузы всё живое. +- Морфинг иконок по состоянию — Стенд: дверь/замок: открыть lock.front_door из карточки двери — иконка меняется; гаражные ворота во «Дворе». +- «Значение вместо иконки» — Стенд: у термометра в диалоге выбрать display «значение» — на плане цифра. +- RGB только в glow/ripple — Стенд: включить RGBWW-лампу в Гостиной цветом: бейдж жёлтый стандартный, цвет только в пятне glow. +- Красная пульсация тревоги — Стенд: включить `input_boolean.demo_leak` (Настройки → Устройства и службы → Помощники) — датчик на Кухне пульсирует красным; дым в Спальне сам вспыхивает каждые 10 минут на 30 с. +- Стоимость рендера (geometry once) — Стенд: не проверяется руками — smoke_render_perf. +- Тап vs drag открывания — Стенд: редактор плана, тап по двери = свойства, drag на место = ничего не записано. +- Вогнутый остров — Стенд: нарисовать U-комнату во «Дворе» и остров внутри. +- Backend hardening (B2–B5) — Стенд: не проверяется руками — unit/backend. +- Гонка сохранений (markup vs Save) — Стенд: два окна: в одном правка разметки, в другом Save диалога — правка выживает; остальное — тесты. +- Niche split — Стенд: разрез, начинающийся и кончающийся на одной стене — вырезается ниша. +- Контент только через подписанные URL — Стенд: залить план, скопировать URL картинки из DevTools, убрать authSig → 401; старые пути `/houseplan_files/plans` → 404. +- Каждая опция редактора сохраняема — Стенд: перебрать display/tap/fill в диалогах — ошибок валидации быть не должно. +- Кнопка настроек комнаты в геометрическом центре — Стенд: редактор плана, глазами. +- Один индикатор всегда (лампа жёлтая в plan-редакторе glow-пространства) — Стенд: включить свет, открыть редактор плана — бейдж жёлтый (glow-слоя там нет). +- Size/angle parity — Стенд: задать маркеру size 3 / angle 37 в диалоге → и на «Схеме» тоже ×3 и повёрнут. +- Tap запускает автоматизацию — Стенд: тап по «Открыть шторы» (Гостиная) → диалог подтверждения → штора едет; в диалоге маркера видно «Run» + поиск по automation/script/scene (есть скрипт «Открыть шторы», автоматизация «Вечерний сценарий», сцены «Кино», «Вечер в гостиной»); Esc = не выполнять. +- Бейджи light-source в glow — Стенд: заливка glow (по умолчанию): у горящей лампы бейдж стандартный (индикатор — пятно), у розетки-«источника света» жёлтый. +- Множитель размера иконки растит глиф — Стенд: size 3 у любого маркера. +- Auto-grid parity, ripple ghost, hidden LQI parity, ghost без цифр — Стенд: скрыть «Zigbee»-термометр: LQI комнаты не меняется, «Схема» совпадает с планом; «Show hidden» в редакторе устройств показывает синий пунктирный призрак без значений. +- Флаг «скрыть с плана» — Стенд: галка в любом диалоге устройства; скрытый исчезает из всех режимов и счётчика, но LQI комнаты держит. +- «Жёлтый = работает» — Стенд: «Тёплый пол» в Кабинете: hvac_action=heating → жёлтая подложка. (Выключить нагрев можно, поставив target ниже 20° в карточке — бейдж гаснет.) +- Жесты редактора на touch — Стенд: с телефона в редакторе плана: pinch = zoom, палец = pan, отпускание не ставит точку. +- Legacy-геометрия, положительные размеры, границы 1e100, no-op repair — Стенд: не проверяется (нужен подложенный битый store, у тестировщика нет доступа к .storage) — unit/backend. +- Карточка под другим контентом дашборда — Стенд: вид «Схема» — карточка стоит после других карточек и не схлопывается. +- Stranded migration repair / geometry repair — Стенд: не проверяется руками (WS-команда) — backend. +- Редакторы видят весь холст — Стенд: «Двор» (одна комната): в редакторе плана виден весь белый квадрат, во View — контент-фит. +- Save ждёт пропорции выбранного плана — Стенд: прикрепить «уже загруженный» план и мгновенно Save. +- Зум ниже фита (пол 0.4x) — Стенд: минусовать зум ниже 100%. +- Migration crash / parallel upload quota — Стенд: не проверяется (kill HA между записями невозможен) — backend. +- Зум открывается на контенте — Стенд: «Двор» открывается комнатой на весь экран. +- Удаление используемого плана запрещено — Стенд: залить план, в списке «уже загруженные» его delete неактивен. +- Квота загрузок — Стенд: можно доливать планы до квоты — тост; сброс почистит. +- Миграция на квадратный холст — Стенд: не проверяется (миграция уже прошла; нужен старый store) — unit. +- Картинка плана по центру с полями — Стенд: залить широкую картинку — поля сверху/снизу, без растяжения. +- Re-attach отвязанного плана — Стенд: ⚙ пространства → «рисование» → Save → reload → «Уже загруженные» → прикрепить обратно. +- Detach хранит файл — Стенд: там же: после отвязки файл в списке; замена плана убирает старый сразу. +- Перепривязка не ест мануалы — Стенд: маркер с 2 PDF перепривязать на другую сущность — оба открываются. +- Ничего не копится на idle — Стенд: не проверяется полноценно (ежечасный сброс раньше суточного sweep) — backend. +- Drag выигрывает у удалённого move — Стенд: два окна, тащить разные иконки одновременно. +- Одноимённые загрузки из двух вкладок — Стенд: можно, два вложения обязаны выжить; тонкости — unit. +- Временные файлы не выживают — Стенд: не проверяется (нужен доступ к ФС) — backend. +- Две полные карточки согласны в позициях — Стенд: два окна: drag в одном виден во втором без reload. +- Загруженный SVG инертен (script не исполняется) — Стенд: залить SVG со ``, открыть его подписанный URL в новой вкладке — alert нет, план рендерится. +- Вложение не перезаписывает другое — Стенд: приложить manual.pdf к двум маркерам — два независимых файла. +- Два быстрых эдита выживают — Стенд: быстро сделать две правки подряд (throttle сети в DevTools) — обе на месте. +- Открытые границы следуют геометрии — Стенд: открыть границу (инструмент «Открыть границу») между Гостиной и Кухней, потом утащить вершину стены — разрыв едет вместе. +- Внутренние лимиты (max+1) — Стенд: не проверяется руками — unit/backend. +- Большие файлы стримятся (50 MB) — Стенд: можно залить 50 MB мануал и скачать дважды; память HA снаружи не видна — полноценно только локально. +- Паритет статичной карточки (fill none) — Стенд: у комнаты поставить fill «нет» и сравнить со «Схемой». +- Layout доходит до статичной карточки — Стенд: drag иконки на «Плане» → на «Схеме» (другая вкладка того же дашборда) двигается. +- Repair-issue смертны — Стенд: удалить пространство с битым планом… проще: удалить пространство — связанные предупреждения из Настройки → Ремонт исчезают. +- Не-подписанный путь не зацикливает запросы — Стенд: не проверяется руками — unit. +- Подписи не усиливаются на плохой сети — Стенд: DevTools throttling + Network: один sign-запрос на URL. +- Битая папка планов не валит save — Стенд: не проверяется (нужна ФС) — backend. +- Два редактора, один план — Стенд: две вкладки, залить подложку в каждой по очереди — служится последняя, файлы целы. +- Фон статичной карточки — Стенд: залить план «1 этажу», открыть «Схему»: картинка есть, в Network нет неподписанных запросов. +- Отклонённый save не трогает план — Стенд: две вкладки: обе меняют план, вторая получает конфликт — старый план жив. +- Кэш подписей на 200+ URL — Стенд: не воспроизводимо (нет 200 файлов) — smoke_sign_cap. +- Климат не дорожает с комнатами — Стенд: не проверяется руками — smoke_climate_once. +- Upload при конкурентной ревизии — Стенд: две вкладки: приложить фон при открытом втором редакторе. +- Подписанный фон плана — Стенд: см. выше: authSig в Network, нет failed login в журнале HA (Настройки → Система → Журналы). +- Зомби-диалоги — Стенд: Esc во время сохранения при throttling — диалог закрыт, тост об ошибке живёт. +- Нет hover-тултипов на touch — Стенд: с телефона. +- Слайдеры шрифтов (50–300%) — Стенд: ⚙ пространства + ⚙ комнаты: живой образец в диалоге следует слайдеру. +- Room settings tier 3 (имя, зона, fill override, источник T°/влажности) — Стенд: ⚙ любой комнаты; источник температуры прописан у комнат демо через зонные термометры — переопределить и посмотреть карточку. +- PDF переживает перепривязку — Стенд: см. «перепривязка не ест мануалы». +- Киоск-режим — Стенд: вид «Киоск» дашборда: шапки нет, свайп листает пространства с точками-индикатором, дабл-тап сброс зума, лонг-пресс 3 с на пустом месте — поповер размеров; авто-листание cycle — задано в конфиге вида; реальный планшет — руками на своём. +- Иконка-ссылка зоны у имени комнаты — Стенд: во View у имён комнат есть ↗ (зоны привязаны) — клик ведёт в зону HA; в редакторах иконки нет. +- Смарт-гайды — Стенд: тащить иконку в редакторе устройств — пунктирные направляющие от соседей, бейдж длина·угол. +- Свет тогглится по умолчанию — Стенд: тап по любой лампе во View = вкл/выкл без настройки. +- Производные стены тоже режутся (.seg) — Стенд: открыть границу и смотреть в редакторе плана: сплошной линии под пунктиром нет. +- Пунктир открытых границ в разметке — Стенд: там же. +- Nav-персистентность (пространство+режим) — Стенд: уйти в «Двор», закрыть вкладку, открыть — снова «Двор»; `#space=floor1` в URL сильнее. +- Чистка tap-действий + правый клик — Стенд: ПКМ по иконке во View = more-info HA. +- Редизайн секции биндинга — Стенд: «+» в редакторе устройств: радио Виртуальное/Из списка HA, «показать сущности», поиск в дропдауне. +- Настоящий пунктир открытой границы — Стенд: см. открытые границы. +- Hover открытия стены — Стенд: инструмент «Открыть границу»: у общей стены курсор pointer + янтарный пунктир-превью; на уже открытой — красное превью. +- Открытые границы: свет течёт по зоне — Стенд: открыть границу Гостиная-Кухня при glow: свет горящей лампы заливает обе. +- Секторы дверей не темнят комнату — Стенд: glow: открыть дверь Прихожей, смотреть сектор света. +- Per-source радиус glow — Стенд: поле «Радиус свечения» в диалоге лампы. +- Скрытая light-primary — Стенд: не проверяется (нет скрытых-в-реестре ламп в демо) — локально. +- Marker controls (тогл связки ламп) — Стенд: у «Котла»/виртуального маркера прописать «Управляет источниками света» + Toggle и тапнуть: обе лампы Гостиной разом. +- Glow fill в целом — Стенд: заливка по умолчанию на «1 этаже»: зажечь RGBWW-лампу цветом — цветное пятно, радиус в ⚙. +- Островные комнаты — Стенд: нарисовать остров во «Дворе». +- Иконка не прыгает при перепривязке — Стенд: перепривязать маркер: позиция та же; смена комнаты в том же пространстве тоже не двигает. +- Плейсхолдер автоиконки — Стенд: диалог без явной иконки: «Auto: mdi:…» с превью. +- Нет кнопки Reset в тулбаре Devices — Стенд: глазами: add / 👁 / ⬡. +- Сетка во всех редакторах + fade декора — Стенд: редактор фона: комнаты/иконки блёкнут до 35%, декор яркий. +- Редактор фона (фигуры/текст/ластик) — Стенд: порисовать во «Дворе»: прямоугольник-«газон», текст. +- Превью открывания (призрак 90 см) — Стенд: инструмент «Открывание», водить у стены. +- Split-polyline, курсоры, Esc-цепочка — Стенд: split Гостиной ломаной через середину. +- Подсветка выбранного в merge/split — Стенд: янтарная обводка первой комнаты. +- Карточка vs инструмент — Стенд: в редакторе плана тащить карточку комнаты при активном Draw — точек не ставится. +- Карточки комнат (метрики, drag, resize) — Стенд: включить метрики в ⚙ пространства; в редакторе плана карточку можно тащить и растягивать за углы. +- Esc закрывает диалоги по одному — Стенд: наоткрывать вложенных диалогов. +- Общая ⚙ видна во всех режимах — Стенд: глазами. +- Табы редакторов (2 шт + X) — Стенд: глазами. +- ⚙ пространства в каждом режиме — Стенд: глазами. +- Lock action (Unlock красный + подтверждение) — Стенд: карточка двери в Прихожей. +- Флаг нового устройства (красная точка) — Стенд: включить незанятую сущность… проще: не проверяется напрямую (набор сущностей демо фиксирован; точка была бы у новых) — локально. +- Ноль устройств в HA — Стенд: не проверяется (в демо 100+ сущностей) — smoke_new_device. + +## Диалог устройства (маркеры) ★ + +- Все поля сохраняются — Стенд: любой маркер: имя/иконка/модель/ссылка/описание, F5. +- Перепривязка с поиском, занятые исключены — Стенд: дропдаун биндинга: уже размещённые сущности в списке отсутствуют. +- Виртуальное устройство: имя+комната, пунктир — Стенд: «Котёл» — образец; создать своё. +- Комнаты без зоны в списке комнат — Стенд: нарисовать комнату «без зоны» и поместить туда маркер. +- Room override центрирует — Стенд: сменить комнату маркера. +- Tap-action override — Стенд: перебрать все варианты у одного маркера. +- PDF: ok / >50 MB / .exe — Стенд: приложить файлы к маркеру; большие и .exe должны дать читаемую ошибку. +- `javascript:` в ссылке не кликабелен — Стенд: вписать `javascript:alert(1)` в поле ссылки — в карточке не ссылка. +- Remove: авто → скрытый маркер, виртуальное → насовсем — Стенд: удалить «Котёл» (вернётся сбросом) и любой entity-маркер. + +## Правила иконок ★ + +- ⬡ открывает редактор с текущими правилами — Стенд: редактор устройств → ⬡. +- Тест-поле, добавление/удаление/порядок — Стенд: там же, ввести имя «Термометр…». +- Битый regex краснеет и пропускается — Стенд: вписать `([`. +- Reset к дефолтам — Стенд: там же. +- Правила переиконивают существующие; per-device иконка сильнее; замки всегда mdi:lock — Стенд: правило `.*свет.* → mdi:star` и смотреть план. +- Живут после reload и во втором браузере — Стенд: приватное окно. + +## Tap-действия и жесты ★ + +- Тап → карточка, `toggle` тогглит только свет/розетки/вентиляторы — Стенд: пощёлкать лампы (toggle по умолчанию), медиаплеер (карточка). +- Замки не тогглятся никогда; шторы только с явным override — Стенд: замок двери; штора Гостиной: выставить «Toggle» в диалоге — начнёт тогглиться, гаражные ворота — нет. +- Long-press всегда карточка — Стенд: зажать лампу на 600 мс — карточка вместо toggle. +- Drag >3 px отменяет tap/long-press — Стенд: потащить палец с иконки. +- pointercancel без фантомов — Стенд: с телефона: начать тап и свернуть браузер. + +## Zoom / pan / подписи + +- Wheel у курсора, +/−, fit, % — Стенд: глазами. +- Pinch + двухпальцевый pan — Стенд: с телефона. +- Зум живёт per-space в localStorage — Стенд: зазумить «1 этаж», перейти в «Двор» и назад, F5. +- Resize окна перефитит — Стенд: свернуть боковую панель HA. +- Подписи комнат таскаются (rl_*) — Стенд: в редакторе плана утащить имя комнаты, F5. +- Читаемость подписей на мин/макс зуме — Стенд: глазами на белом плане. + +## Мультиклиент ★ + +- Две вкладки: drag виден без reload — Стенд: два окна рядом. +- Конфликт конфига → тост, авторесинк, retry — Стенд: два окна: одновременно править настройки пространства. +- Точечные layout-апдейты не трутся — Стенд: тащить разные иконки в двух окнах. +- `admin_only` для не-админа — Стенд: не проверяется (нет второго пользователя) — backend. + +## Крайние случаи + +- HA без устройств/зон — Стенд: не проверяется (демо полон сущностей) — локально. +- Пространство без комнат — Стенд: создать пустое, видна подсказка разметки. +- Комната без зоны + борта — Стенд: нарисовать, кликнуть — ничего. +- Нет zigbee вовсе — Стенд: «Двор»: заливка lqi оставляет двор незалитым, бейджей нет. +- 100+ устройств в одном пространстве — Стенд: не проверяется (в «1 этаже» ~30 маркеров) — локальная синтетика. +- Длинные имена — Стенд: переименовать маркер в очень длинное имя. +- HTML/эмодзи в именах — Стенд: назвать маркер `xss🚿` — текст, не разметка. +- План удалён с диска → Repairs — Стенд: не проверяется (нет доступа к ФС) — backend. +- Битый houseplan.config — Стенд: не проверяется (нет доступа к .storage) — backend. +- Рестарт HA при открытом диалоге — Стенд: Настройки → Система → Перезапустить (админ может!), диалог держать открытым; после рестарта save даст чистую ошибку. Помнить: рестарт контейнера = сброс, но сам HA-рестарт изнутри сброс не триггерит. +- Legacy layout v1 — Стенд: не проверяется — unit. +- Киоск холодный старт в приложении — Стенд: Companion app + вид «Киоск», убить и открыть. + +## Релизные регрессии + +- Ноль ошибок консоли — Стенд: DevTools console на дашборде, в разметке, диалогах, зуме. +- Ноль houseplan-ошибок в логе HA — Стенд: Настройки → Система → Журналы, фильтр «houseplan». +- npm test / pytest / CI — Стенд: не про стенд — CI. +- Скриншоты README — Стенд: не про стенд. + +## houseplan-space-card (вид «Схема») + +- Рендер идентичен плану, без шапки — Стенд: вид «Схема» дашборда. +- Полностью неинтерактивна — Стенд: покликать по «Схеме» — ничего, даже тултипов. +- Кнопка-футер открывает полную карточку на этом пространстве — Стенд: клик по кнопке под «Схемой». +- Несколько с разными space — Стенд: «Схема» содержит обе (1 этаж и Двор) — один общий WS-запрос (Network). +- Неизвестный space → аккуратная ошибка — Стенд: отредактировать вид, вписать space: nope. +- show_button: false — Стенд: правкой YAML вида. +- #space= диплинк — Стенд: открыть `…/plan#space=yard`. + +## Presence ripples / per-device иконка + +- «Только пульсация»: бейдж исчезает, кольца при on — Стенд: у датчика движения «Movement Backyard» (Кухня) поставить display «пульсация» — он периодически on/off сам. +- «Иконка + пульсация» — Стенд: там же. +- Цвет и размер ×2..×8 — Стенд: там же. +- unavailable останавливает пульс — Стенд: не проверяется (нет unavailable-сущностей в демо) — smoke. +- Размер ×0.5..×3 и поворот; бейджи масштабируются — Стенд: любой маркер. +- Риплы при выключенных live-состояниях — Стенд: выключить «живые состояния» в конфиге карточки (правка вида) — риплы живут. +- reduce motion — Стенд: включить в ОС тестера. + +## Двери и окна + +Дверь с замком (Прихожая, lock.front_door) и окно с датчиком (Кухня, contact = «Basement Floor Wet») уже стоят. +- Клик мимо стены → тост; у стены → диалог — Стенд: инструмент «Открывание» в разметке. +- Дверь: косяки+полотно+дуга, длина в см — Стенд: глазами у входной двери. +- Контакт: open → створка + дуга акцентом — Стенд: датчик окна Кухни переключается сам (это «мокрый пол» из демо — он мигает); либо повесить contact на `binary_sensor.demo_leak` и дёргать помощник. +- Unavailable → статичный дефолт — Стенд: не проверяется (нет unavailable) — локально. +- Замок: зелёный/оранжевый/серый бейдж — Стенд: замок двери, открыть/закрыть из карточки. +- Карточка с двумя состояниями, замок не тогглится с плана — Стенд: клик по двери/замку во View. +- Flip зеркалит петли/сторону — Стенд: диалог открывания (двойной клик с инструментом). +- Клик с инструментом → редактирование; Delete — Стенд: там же. +- Hover: акцент + grab во View — Стенд: навести на дверь. +- Drag вдоль стен с переснапом за углы — Стенд: тащить дверь по периметру Прихожей. +- Один клик = карточка, дабл = свойства, drag = ничего — Стенд: там же. + +## Живые пылесосы (docs/VACUUM.md) + +Симулятор: «Робот-пылесос» в Прихожей (база = маркер), карта `sensor.demo_robot_map` +в стиле Tasshack (позиция-словарь, комнаты с именами как на плане, mm, ось Y +перевёрнута), калибровка уже прописана. Полный цикл уборки ~3.5 минуты. +- Docked: только маркер базы — Стенд: глазами (робот в Прихожей). +- Уборка: круглая пульсирующая шайба едет, база на месте — Стенд: карточка робота → Start (или Настройки → Устройства и службы → Сущности → vacuum.demo_robot); шайба змейкой объезжает все 5 комнат. +- Глайд ~1.2 с, телепорт при zoom/pan/switch — Стенд: во время уборки позумить. +- Режимы следа never/cleaning/always — Стенд: диалог маркера робота → «Показывать путь робота»; в always виден след прошлой уборки (40%) — он уже записан в эталоне. +- Серверный след (две уборки, переживает reload) — Стенд: запустить уборку, F5 посреди — линия продолжается с места; вторая вкладка видит ту же линию. +- Стиль: тёмный ореол + светлое ядро — Стенд: глазами поверх glow-заливки. +- Скрытый маркер: ни шайбы, ни следа — Стенд: скрыть маркер робота на время уборки. +- Калибровка: «Настроить автоматически» — Стенд: диалог робота → «Живая позиция»: имена комнат карты совпадают с планом (все 5) — автокалибровка сходится; панель подгонки (призрак, углы, поворот, зеркало — зеркало осмысленно: ось Y в карте перевёрнута) тоже можно открыть и покрутить, Esc/Cancel не портит. +- Мультиэтаж (матрица на карту) — Стенд: частично: карта одна (map 1), матрица хранится по её id; мультикарта — только на реальном Dreame. +- Pause/Return — Стенд: кнопки в карточке робота: пауза замирает, «домой» возвращает по своим следам с двойной скоростью. + +## Чего на стенде нет принципиально + +- Реальное Zigbee/Z-Wave железо, реальные роботы (Dreame/Xiaomi/Valetudo), реальный настенный планшет. +- HACS-путь установки/обновления, YAML-mode Lovelace, переустановка интеграции с сохранением конфига. +- Всё, что требует доступа к файловой системе стенда: битые store, kill -9 между записями, недоступные папки, наблюдение за памятью процесса. +- Долгоживущие сценарии (суточный sweep, «часом позже») — сброс стенда наступает раньше. +- Не-админский пользователь (admin_only, скрытие табов) — на стенде один админ demo.