mirror of
https://github.com/Matysh/houseplan-card
synced 2026-09-30 19:58:50 +00:00
docs: specify linked virtual light control
Issue: #174 User-Visible: no
This commit is contained in:
committed by
claude[bot]
parent
e727023bf4
commit
dae2efc280
@@ -0,0 +1,435 @@
|
||||
# Issue #174 — связанный виртуальный источник следует реальному контроллеру
|
||||
|
||||
- **Issue:** https://github.com/Matysh/houseplan-card/issues/174
|
||||
- **Редакция:** первая редакция для независимого ревью; статус определяется только метками issue
|
||||
- **Тип / приоритет:** bug / P1
|
||||
- **Оценка:** пользовательская ценность 8/10; ценность для разработки 6/10;
|
||||
сложность и риск 5/10
|
||||
- **Область:** canonical light graph, универсальный Toggle, View/kiosk/touch,
|
||||
device presentation, preview/confirmation и тесты
|
||||
- **Модель данных:** без новых полей и миграции
|
||||
- **Связано:** #84, #94, #107, `docs/LIGHT.md`,
|
||||
`docs/DEVICE-LIGHT-SETTINGS-MATRIX.ru.md`, `docs/TOUCH-SUPPORT.md`
|
||||
|
||||
## 1. Сценарий и персона
|
||||
|
||||
**Персона:** администратор дома настраивает план, после чего он сам, домочадец
|
||||
или пользователь киоска управляет светом в обычном View.
|
||||
|
||||
**Поверхность и момент:** физическая лампа не имеет собственной сущности HA. На
|
||||
плане она представлена virtual marker с ролью **Всегда** и действием
|
||||
**Переключить состояние**. Реальный умный выключатель или реле имеет отдельный
|
||||
marker и в поле **Управляет другими источниками света** ссылается на эту лампу.
|
||||
Пользователь нажимает либо выключатель, либо изображение лампы.
|
||||
|
||||
Задача поддерживает:
|
||||
|
||||
- **J1:** Glow, заливка «Свет», статистика комнаты и оба marker показывают одно
|
||||
реальное текущее состояние;
|
||||
- **J3:** очевидное безопасное действие с любой из двух пространственных точек
|
||||
действительно переключает физический свет;
|
||||
- обязательный View/kiosk/touch-контракт: tap и click не расходятся и не создают
|
||||
отдельное состояние только внутри карточки.
|
||||
|
||||
## 2. Что человек увидит до и после
|
||||
|
||||
**До:** клик по реальному выключателю меняет его HA state, но Glow виртуальной
|
||||
лампы не меняется; клик по лампе меняет только внутреннее ручное состояние House
|
||||
Plan и не переключает физическое реле.
|
||||
|
||||
**После:** связанная пара ведёт себя как два умных представления одного света.
|
||||
Клик по выключателю или лампе переключает реальное реле, а его HA state едино
|
||||
управляет Glow, заливкой, статистикой и состоянием обоих marker. Несвязанная
|
||||
виртуальная лампа сохраняет ручное поведение #107.
|
||||
|
||||
## 3. Проблема и подтверждённая причина
|
||||
|
||||
В `resolvedLightSources()` passive source сначала получает правильное состояние
|
||||
по #84:
|
||||
|
||||
```text
|
||||
source.on = OR(active incoming controller driver entities)
|
||||
```
|
||||
|
||||
Затем точная тройка #107 — `binding=virtual`, `is_light=true`, effective
|
||||
`tap_action=toggle` — безусловно заменяет результат значением operational Store
|
||||
`virtual_lights`. Поэтому входящие контроллеры существуют в конфигурации, но не
|
||||
влияют ни на Glow, ни на остальные canonical consumers.
|
||||
|
||||
В `resolveToggleIntent()` та же тройка проверяется раньше `controls` и всегда
|
||||
возвращает operation `virtual-light`. Resolver не рассматривает incoming links
|
||||
на текущий marker, поэтому клик по лампе не может построить HA-команду к driver
|
||||
entities контроллеров.
|
||||
|
||||
Подтверждённая матрица текущего `dev`:
|
||||
|
||||
| Manual state | Реальный driver | Сейчас source.on |
|
||||
|---|---|---|
|
||||
| on | on | on |
|
||||
| on | off | on — driver проигнорирован |
|
||||
| off | on | off — driver проигнорирован |
|
||||
| off | off | off |
|
||||
|
||||
Это не дубликат:
|
||||
|
||||
- #84 ввёл связь passive lamp → реальные driver entities и OR-состояние;
|
||||
- #107 ввёл ручной state и намеренно дал ему абсолютный приоритет;
|
||||
- #174 по решению владельца меняет только конфликтующую комбинацию и объединяет
|
||||
её с реальным управлением.
|
||||
|
||||
## 4. Решение владельца
|
||||
|
||||
Владелец подтвердил изменение поведения 18.08.2026:
|
||||
https://github.com/Matysh/houseplan-card/issues/174#issuecomment-5330854846
|
||||
|
||||
1. Пара «умный выключатель/реле + virtual lamp» ведёт себя как два умных
|
||||
устройства, когда у обоих выбрано **Переключить состояние**.
|
||||
2. Клик по любому marker включает/выключает свет на плане и реально переключает
|
||||
выключатель/реле.
|
||||
3. В linked-режиме HA state реальных driver entities является единственным
|
||||
текущим источником истины; ручной state #107 применяется только без связи.
|
||||
4. Рекомендованный в issue default принят как граница lifecycle: создание связи
|
||||
не стирает сохранённый manual state, а снятие последней связи возвращает его.
|
||||
|
||||
## 5. Термины
|
||||
|
||||
| Термин | Значение |
|
||||
|---|---|
|
||||
| **Manual-eligible source** | Active marker точной тройки #107 |
|
||||
| **Incoming link** | Сохранённый `marker:<target_id>` в `controls` другого marker |
|
||||
| **Linked source** | Manual-eligible passive source, на который существует хотя бы один валидный incoming link |
|
||||
| **Controller** | Marker, содержащий incoming link |
|
||||
| **Driver entities** | Реальные effective `light.*`/`switch.*`, по которым #84 вычисляет состояние controller |
|
||||
| **Manual mode** | Operational `virtual_lights` state несвязанного manual-eligible source |
|
||||
| **Linked mode** | Состояние и действие через driver entities при наличии incoming link |
|
||||
|
||||
`marker:*` остаётся только идентификатором графа. Он никогда не становится HA
|
||||
entity ID, не читается из `hass.states` и не передаётся в `callService`.
|
||||
|
||||
## 6. Скоуп
|
||||
|
||||
В задачу входят:
|
||||
|
||||
1. приоритет linked controller state над manual state для точной тройки #107;
|
||||
2. обратное разрешение source → все его incoming controllers → реальные driver
|
||||
entities;
|
||||
3. клик/tap по linked virtual source через существующую групповую семантику HA;
|
||||
4. сохранение текущего клика по controller и согласование его с тем же driver
|
||||
projection;
|
||||
5. HA state updates от физического устройства и автоматизаций без клика House
|
||||
Plan;
|
||||
6. несколько controllers, дедупликация driver entities и partial availability;
|
||||
7. preview, confirmation и безопасная повторная резолюция цели;
|
||||
8. manual fallback после снятия последней связи без потери operational state;
|
||||
9. единое состояние для Glow, room fill/counts, device presentation, full/static
|
||||
cards и редакторского preview;
|
||||
10. unit, targeted browser smoke, документация и оба changelog.
|
||||
|
||||
## 7. Не входит в задачу
|
||||
|
||||
- новый UI, отдельная кнопка режима или новое поле конфигурации;
|
||||
- создание synthetic HA entity/helper либо запись manual state в HA;
|
||||
- изменение picker, синтаксиса `controls`, валидации, import/export или remap;
|
||||
- AND/NOT/приоритет между несколькими controllers вместо действующего OR;
|
||||
- синхронизация цвета/яркости реального relay с passive lamp;
|
||||
- вызов operational `houseplan/virtual_light/toggle` одновременно с HA service;
|
||||
- автоматическое связывание лампы и выключателя;
|
||||
- изменение безопасного запрета для lock/alarm/guarded cover;
|
||||
- общая переработка universal Toggle вне связи passive source;
|
||||
- история состояний, автоматизации или новая диагностическая поверхность.
|
||||
|
||||
## 8. Контракт состояния
|
||||
|
||||
### 8.1. Выбор authority
|
||||
|
||||
Для manual-eligible passive source:
|
||||
|
||||
```text
|
||||
if validIncomingLinks.length > 0:
|
||||
source.on = any(activeDriverEntity.state == "on")
|
||||
else:
|
||||
source.on = virtualLightIsOn(source, operationalSnapshot)
|
||||
```
|
||||
|
||||
- Сам факт валидной сохранённой связи включает linked mode.
|
||||
- Если links есть, но ни одного active driver нет, source dormant/off; он не
|
||||
возвращается к manual или constant-on.
|
||||
- Несколько controllers используют OR без второго голоса комнаты.
|
||||
- HA automation, физическая клавиша либо другой dashboard, изменивший driver,
|
||||
меняет source на следующем HA state update без House Plan WS-команды.
|
||||
- `virtual_lights` revision не может переопределить linked source. Событие Store
|
||||
допустимо инвалидирует cache, но визуальный результат остаётся driver-owned.
|
||||
|
||||
### 8.2. Driver projection
|
||||
|
||||
Driver entities определяются ровно по действующему правилу #84:
|
||||
|
||||
1. если controller имеет active реальные entity targets в `controls`, drivers —
|
||||
эти effective targets;
|
||||
2. иначе driver — собственная ведущая controllable entity controller;
|
||||
3. missing, HA-disabled, unavailable и неподдерживаемые targets не становятся
|
||||
executable service targets;
|
||||
4. одинаковая entity, найденная через несколько controllers/refs, учитывается
|
||||
один раз;
|
||||
5. `marker:*` и passive target не входят в service payload.
|
||||
|
||||
Один pure reverse-index/helper является authority и для `source.on`, и для
|
||||
source Toggle. Две независимо написанные проекции incoming graph запрещены.
|
||||
|
||||
### 8.3. Lifecycle manual state
|
||||
|
||||
- Добавление первой incoming связи немедленно переключает source на driver
|
||||
authority, но не удаляет существующий off-bit.
|
||||
- Клик по linked source не читает и не меняет off-bit.
|
||||
- Снятие последней связи немедленно возвращает exact сохранённый manual state;
|
||||
если записи нет, действует compatibility default `on`.
|
||||
- Role/action/binding/delete lifecycle по #107 остаётся прежним и может очистить
|
||||
manual state независимо от links.
|
||||
- Hidden source сохраняет state, но не рисуется. Hidden controller не разрывает
|
||||
сохранённую физическую связь по контракту #84.
|
||||
- Broken ref, target без forced-source роли и self/cycle не создают linked mode
|
||||
в runtime; их lossless/validation-поведение остаётся за #84.
|
||||
|
||||
## 9. Контракт действия
|
||||
|
||||
### 9.1. Клик по controller
|
||||
|
||||
Существующий controller Toggle остаётся групповым:
|
||||
|
||||
- если любой доступный target/driver включён — `turn_off` всех доступных;
|
||||
- иначе — `turn_on` всех доступных;
|
||||
- passive `marker:*` не уходит в HA service;
|
||||
- в простой паре команда содержит реальный relay controller;
|
||||
- после HA state update связанная лампа меняет все canonical consumers.
|
||||
|
||||
Реализация не должна поддерживать визуал отдельным optimistic manual flip.
|
||||
|
||||
### 9.2. Клик по linked virtual source
|
||||
|
||||
Для explicit Toggle linked source resolver возвращает обычную typed
|
||||
`ha-service` operation по объединённым driver entities incoming controllers:
|
||||
|
||||
- any available driver on → `turn_off` всех available drivers;
|
||||
- все available drivers off → `turn_on` всех available drivers;
|
||||
- partial group вызывает service только для показанного available subset и
|
||||
перечисляет пропуски существующим formatter;
|
||||
- нет available drivers → объяснённый safe no-op, без fallback к
|
||||
`virtual-light` и без вызова HA;
|
||||
- target preview показывает реальные driver names/current effect, а не
|
||||
operational virtual target;
|
||||
- service response сам по себе не меняет visual state; authority — последующий
|
||||
HA snapshot, как для обычного умного света.
|
||||
|
||||
Для manual-eligible source без incoming links сохраняется поведение #107:
|
||||
`virtual-light` operation, server-authoritative operational state, sync между
|
||||
карточками и отсутствие HA service.
|
||||
|
||||
### 9.3. Confirmation и гонки
|
||||
|
||||
`tap_confirm` сохраняет действующий confirmation flow. Перед выполнением intent
|
||||
резолвится заново.
|
||||
|
||||
- смена manual ↔ linked mode во время открытого confirmation меняет kind/target
|
||||
operation и отменяет старое подтверждение как «цель изменилась»;
|
||||
- изменение набора driver entities не разрешает тихо вызвать другую группу;
|
||||
- изменение только направления `turn_on` ↔ `turn_off` при том же target set
|
||||
допустимо и использует актуальный state;
|
||||
- исчезновение всех drivers заканчивается safe no-op, без operational fallback.
|
||||
|
||||
## 10. Единые визуальные consumers
|
||||
|
||||
Linked source получает один `source.on` из canonical light resolver. Этот же
|
||||
результат обязателен для:
|
||||
|
||||
- Glow full card и kiosk;
|
||||
- room fill «Свет»;
|
||||
- `resolvedLightState` и `resolvedLightStats` / `N из M`;
|
||||
- marker background/status и controller aggregate presentation;
|
||||
- device-editor preview;
|
||||
- `houseplan-space-card`.
|
||||
|
||||
Отдельная ветка в SVG, presentation resolver или room card запрещена. Один HA
|
||||
state tick обязан обновить все consumers без config rebuild, operational toggle
|
||||
или polling.
|
||||
|
||||
## 11. Модель данных, compatibility и миграция
|
||||
|
||||
`Marker`, `ServerConfig`, layout, Lovelace config и backend schema не меняются.
|
||||
Синтаксис `controls: [marker:<id>]` остаётся форматом #84. Operational Store
|
||||
`houseplan.virtual_lights` и wire snapshot #107 остаются без изменения.
|
||||
|
||||
Compatibility:
|
||||
|
||||
| Состояние конфигурации | Поведение после #174 |
|
||||
|---|---|
|
||||
| Exact triple, links отсутствуют | Manual state #107 без изменений |
|
||||
| Exact triple, valid incoming link | Driver-owned linked mode |
|
||||
| Exact triple, link снят | Прежний manual state снова видим |
|
||||
| Не exact triple | Обычная семантика #84/#94 |
|
||||
| Старый frontend/backend | Их прежнее поведение; конфигурация не повреждается |
|
||||
|
||||
Новых migration/compatibility fields, materialization, Store reconciliation и
|
||||
import/export изменений нет. Откат не требует преобразования данных.
|
||||
|
||||
## 12. UX, i18n, accessibility и touch
|
||||
|
||||
Новых controls, DOM-поверхностей, focus order и ARIA нет. Используются
|
||||
существующие localized group target/current/next/missing строки universal
|
||||
Toggle; новые RU/EN i18n-ключи не требуются. Если реализация докажет, что
|
||||
существующий formatter не может человекопонятно показать driver group, это
|
||||
считается отдельной продуктовой находкой, а не разрешением молча добавить текст.
|
||||
|
||||
View и kiosk на touch — блокирующие:
|
||||
|
||||
- один короткий tap выполняет ровно одну service operation;
|
||||
- long-press по-прежнему открывает карточку;
|
||||
- pan, pinch, pointercancel и suppressed synthetic click не выполняют Toggle;
|
||||
- confirmation остаётся доступным и не меняет target после подтверждения;
|
||||
- отсутствие/ошибка service не создаёт unhandled rejection или ложный Glow.
|
||||
|
||||
Device editor остаётся desktop-first; меняется только уже существующий preview.
|
||||
Touch editor: **best effort**, новых редакторских действий нет.
|
||||
|
||||
## 13. Критерии приёмки
|
||||
|
||||
- **AC1 (`unit`):** exact triple с incoming controller и `manual=off`,
|
||||
`driver=on` даёт `source.on=true`; `manual=on`, `driver=off` даёт false.
|
||||
Возврат безусловного manual override обязан красить тест.
|
||||
- **AC2 (`unit`):** HA state driver, изменённый без House Plan action, сразу
|
||||
меняет source, room state/stats и marker/controller presentation через один
|
||||
canonical resolver; operational revision не меняет linked result.
|
||||
- **AC3 (`unit`):** explicit Toggle linked virtual source возвращает
|
||||
`ha-service` operation к реальным driver entities, а не `virtual-light`;
|
||||
простой relay получает `turn_on`/`turn_off` и никогда не получает marker ID.
|
||||
- **AC4 (`unit`):** несколько controllers и aliases дают детерминированный
|
||||
deduplicated target set; any-on выключает все, all-off включает все.
|
||||
- **AC5 (`unit`):** unavailable/missing/HA-disabled subset пропускается и
|
||||
объясняется; при нуле available drivers intent является safe no-op без manual
|
||||
fallback и без service call.
|
||||
- **AC6 (`unit`):** клик по controller сохраняет #84/#94 group semantics и
|
||||
переключает тот же driver projection, которым вычисляется linked source.
|
||||
- **AC7 (`unit`):** добавление link не стирает manual off-bit; снятие последней
|
||||
связи возвращает exact прежний state и operation `virtual-light`. Несвязанные
|
||||
regression tests #107 остаются зелёными.
|
||||
- **AC8 (`unit`):** confirmation принимает смену направления при неизменном
|
||||
target set, но отказывает при смене manual/linked mode либо набора drivers.
|
||||
- **AC9 (`smoke`):** в full View реальный click по controller и по linked lamp
|
||||
по очереди вызывает реальное relay, а смоделированный HA state update вместе
|
||||
меняет Glow, room fill/count и presentation; operational WS toggle не вызван.
|
||||
- **AC10 (`smoke`):** touch tap по linked lamp выполняет один HA service;
|
||||
long-press/pan/pinch/pointercancel не выполняют service и не меняют visual.
|
||||
- **AC11 (`smoke`):** внешний HA state update/automation меняет связанный свет
|
||||
без клика; unlink возвращает сохранённый manual state и manual toggle #107.
|
||||
- **AC12 (`unit` + `ревью кода`):** incoming graph/driver projection реализован
|
||||
одним authority helper, переиспользованным light state и Toggle; renderer-only
|
||||
и дублирующая reverse-graph ветки отсутствуют.
|
||||
- **AC13 (`unit` + `build`):** no-link #84 constant-on, unlinked #107,
|
||||
stateful marker targets, direct entity controls, secure no-op и RU/EN parity
|
||||
остаются зелёными; три bundle snapshot побайтово совпадают.
|
||||
- **AC14 (`ревью кода`):** config/backend/Store/import/export schema не меняются;
|
||||
нет optimistic state, polling, новых network paths или ослабления lock/alarm
|
||||
invariant.
|
||||
|
||||
## 14. План автотестов и гейтов
|
||||
|
||||
### Unit
|
||||
|
||||
1. Расширить `test/devices.test.mjs` матрицей manual × driver, automation update,
|
||||
linked/unlinked lifecycle, multiple controllers и cache invalidation.
|
||||
2. Расширить `test/device-toggle.test.mjs` reverse source action, dedupe,
|
||||
any-on/all-off, partial/zero availability и operation identity.
|
||||
3. Расширить `test/device-presentation.test.mjs` общей linked-state проекцией.
|
||||
4. Добавить mutation assertions: возврат manual override и запись
|
||||
`virtual_lights` при linked click обязаны красить тесты.
|
||||
|
||||
### Targeted browser smoke
|
||||
|
||||
Новый `demo/smoke_linked_virtual_light.mjs` либо однозначно названное расширение
|
||||
существующего controls/Glow smoke строит одну пару relay + virtual lamp,
|
||||
перехватывает service/operational WS calls и доказывает AC9–AC11. Он выполняется
|
||||
локально перед `S7-code-review`.
|
||||
|
||||
### Implementation loop
|
||||
|
||||
```text
|
||||
npm run typecheck
|
||||
npm test
|
||||
npm run build
|
||||
node demo/smoke_linked_virtual_light.mjs
|
||||
```
|
||||
|
||||
После build три поставляемые bundle-копии совпадают byte-for-byte. Python/backend
|
||||
гейт не нужен, если diff действительно не затронет backend. Полные smoke,
|
||||
golden и performance выполняются перед бетой. Нового golden baseline нет: вид
|
||||
уже существующих on/off состояний не меняется, меняется источник их authority.
|
||||
|
||||
## 15. Риски, performance и security
|
||||
|
||||
| Риск | Мера |
|
||||
|---|---|
|
||||
| Light resolver и Toggle выберут разные driver entities. | Один reverse-index/helper и AC6/AC12. |
|
||||
| Source click при нескольких controllers переключит только один relay. | Детерминированный union/dedupe и group tests. |
|
||||
| Broken/dormant link неожиданно вернёт manual Glow. | Сам факт valid link фиксирует linked mode; zero-driver AC5. |
|
||||
| Confirmation вызовет новую цель после изменения config. | Сравнение operation target sets, AC8. |
|
||||
| HA service response даст преждевременный визуальный flip. | Только HA state authority, smoke проверяет отсутствие optimistic update. |
|
||||
| Исправление сломает несвязанную #107 лампу. | AC7 и существующая backend/frontend suite #107. |
|
||||
|
||||
Performance: reverse graph уже строится при canonical light resolution. Требуется
|
||||
переиспользовать или кэшировать ту же bounded проекцию по content fingerprint;
|
||||
нельзя добавлять полный O(markers + links) обход на каждый visual consumer либо
|
||||
pointer event сверх одного resolution действия. Нового численного budget нет;
|
||||
pre-release performance smoke остаётся обязательным.
|
||||
|
||||
Security/privacy: service targets остаются allow-listed реальными
|
||||
`light.*`/`switch.*`, resolver сохраняет unavailable/disabled guards, а
|
||||
`marker:*` не покидает frontend graph. Новых прав, payload, Store данных и
|
||||
внешних запросов нет. Lock/alarm invariant не затронут.
|
||||
|
||||
## 16. Откат
|
||||
|
||||
Откат — обычный revert frontend, тестов, документации, changelog и bundle.
|
||||
Форматы данных не меняются, поэтому migration/cleanup не нужны. Manual state в
|
||||
отдельном Store всё время сохраняется и после отката снова становится authority
|
||||
для exact triple по старому #107.
|
||||
|
||||
Feature flag не добавляется: это исправление уже обещанного J1/J3 поведения, а
|
||||
не экспериментальная presentation-функция.
|
||||
|
||||
## 17. Release-артефакты
|
||||
|
||||
- пользовательские записи в `docs/CHANGELOG.md` и `docs/CHANGELOG.ru.md` в том
|
||||
же implementation-коммите (`User-Visible: yes`);
|
||||
- `docs/USER-GUIDE.ru.md` — linked и unlinked recipe;
|
||||
- `docs/LIGHT.md` и `docs/DEVICE-LIGHT-SETTINGS-MATRIX.ru.md` — authority и
|
||||
action matrix;
|
||||
- supersession note в `docs/specs/107-virtual-light-toggle.md` для linked-случая;
|
||||
- `docs/ARCHITECTURE.md` — только если меняется публично описанная граница
|
||||
resolver/action modules;
|
||||
- unit и targeted browser smoke;
|
||||
- синхронные `dist/houseplan-card.js`, HA frontend и demo bundle;
|
||||
- новых screenshots, golden baseline, backend migration, security report и
|
||||
i18n keys не требуется;
|
||||
- issue закрывается только после включения в опубликованную бету.
|
||||
|
||||
## 18. Принятые технические предположения
|
||||
|
||||
1. Reverse-index может быть отдельным pure helper либо частью plan-wide light
|
||||
graph cache; его форма не продуктовый контракт, если state и action используют
|
||||
один результат.
|
||||
2. Существующий `ResolvedLightSource` можно расширить driver metadata либо
|
||||
оставить её в соседнем graph object; нельзя выдавать driver за собственный
|
||||
`serviceEids` passive lamp, если это ломает source/service identity #84.
|
||||
3. «Валидный incoming link» означает существующую runtime-связь к активному
|
||||
forced source. Broken/dormant legacy refs сохраняют lossless-поведение #84 и
|
||||
не создают выдуманную HA цель.
|
||||
4. Hidden controller продолжает быть физическим driver по #84; hidden target не
|
||||
рисуется, но связь и manual state остаются сохранены.
|
||||
5. Operational WS command #107 может оставаться backend-доступным для eligible
|
||||
marker, однако обычный frontend linked action его не вызывает, а linked
|
||||
resolver не читает изменённый off-bit.
|
||||
6. Existing group formatter и toast должны переиспользоваться. Если нужен новый
|
||||
пользовательский текст, это отдельная продуктовая находка и возврат в
|
||||
`S3-spec`, а не техническое предположение.
|
||||
7. Source service action не применяет optimistic Glow: задержка до HA state tick
|
||||
совпадает с обычным умным устройством и является частью единого authority.
|
||||
|
||||
@@ -93,6 +93,7 @@ GitHub Issues и GitHub Projects (v2) остаются единственным
|
||||
| [#157](https://github.com/Matysh/houseplan-card/issues/157) Тип проёма «Открытый проём» | [157-open-passage.md](157-open-passage.md) |
|
||||
| [#150](https://github.com/Matysh/houseplan-card/issues/150) Точная геометрия коллинеарного перепада толщины | [150-wall-thickness-transition.md](150-wall-thickness-transition.md) |
|
||||
| [#172](https://github.com/Matysh/houseplan-card/issues/172) Нулевой Split-разделитель не получает ложную толщину | [172-zero-divider-taper.md](172-zero-divider-taper.md) |
|
||||
| [#174](https://github.com/Matysh/houseplan-card/issues/174) Связанный виртуальный источник следует реальному контроллеру | [174-linked-virtual-light-controller.md](174-linked-virtual-light-controller.md) |
|
||||
|
||||
## Правило актуализации
|
||||
|
||||
|
||||
Reference in New Issue
Block a user