DALI: live device controls on device, group and bus pages - #1233
DALI: live device controls on device, group and bus pages#1233evgeny-boger wants to merge 4 commits into
Conversation
The `/on` command topic was spelled inside DevicesStore. The DALI page's embedded controls drive cells without that store, so the one spelling moves into a helper both use. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC
Commissioning a lamp is one half of the job; the other is seeing it react. Each device page now carries the daemon's live controls for that device — a featured strip of what one reaches for first (level, colour, colour temperature, on/off) and the rest behind "All controls"; a group page shows the group's virtual device, a bus page the bus's broadcast device. The strip reuses the dashboard Cell components, so a control behaves exactly as it does on the Devices page. The tab toolbar gains the page's title: on mobile the tree is hidden while a page is open, so nothing else said what was on screen. Its buttons wrap on phone widths instead of stacking on top of each other. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC
Up to standards ✅🟢 Issues
|
| Metric | Results |
|---|---|
| Complexity | 105 |
| Duplication | 0 |
NEW Get contextual insights on your PRs based on Codacy's metrics, along with PR and Jira context, without leaving GitHub. Enable AI reviewer
TIP This summary will be updated as you push new changes.
The featured strip is a rounded card pinned under the page toolbar while the parameters form scrolls directly behind it. Between each rounded corner and the strip's rectangular box the card's background does not paint, so slivers of the moving form showed through the corners as specks of dirt — the second point of review 5103128797 on #1233 ("минорное - в версии для пк при скролле в углу грязь"). Fill those wedges with an opaque ring in the scroll container's own ground colour, added as a second box-shadow. A shadow paints behind the card's own background, where a z-index: -1 pseudo-element would not: the strip is sticky with z-index 100 and so establishes a stacking context, inside which a negative-z child still paints above the element's own background — it hid the white card instead of backing it. Checked against the simulated DALI bus at 1280x800 and 1920x1080 over nine scroll offsets: the pixels that leaked at the strip's corners are gone and no other pixel of the strip changes. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC
…eadback wb-mqtt-dali names the writable half of a setpoint/readback pair for the write — "Wanted Level", «Желаемая яркость» — which in the strip reads as a different quantity from the live value printed right next to it in brackets. Name the slot for the quantity instead: «Яркость», «Цветовая температура», «Цвет», «Белый», the XY coordinates and the primary colours, keyed by the wire control id from the daemon's control_ids.py. Anything not on that list falls back to dropping a leading "Wanted " / «Желаемый » from the daemon's own title, so a device type we have not met still gets a sensible slot name rather than the raw key. The bracketed number is then unexplained, so it carries the explanation as a tooltip: «Значение, прочитанное из устройства» / "Value read back from the device". The colour swatch keeps its value in its tooltip, which the swatch itself cannot show. Both strings are in en/ru. Addresses the naming half of review 5103128797 on #1233 and makes the phone peek line agree with the desktop strip, which used the readback's own title there. No existing test needed adjusting: the strip's cell titles were never asserted, so the new stripLabel cases (against the real locale files) and the ReadbackSuffix render test are purely additive. `Translate` and the readback props moved into types.ts, where frontend/project-rules.md keeps a directory's types. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC
|
Спасибо! Сделано в 88fb1c7 и 2cff11b. 2. «в углу грязь» — 88fb1c7. Полоса управления — карточка со скруглёнными углами, а форма параметров скроллится прямо под ней. В клиньях между скруглением и прямоугольной границей фон карточки не рисуется, и туда просвечивали кусочки едущего текста. Заполнил их второй тенью — непрозрачным кольцом цвета фона контейнера: тень рисуется под фоном карточки, а псевдоэлемент с Названия — 2cff11b. Демон называет записываемую половину пары «Желаемая яркость», а рядом в скобках печатается прочитанное значение — получается как будто две разные величины. Теперь слот называется самой величиной: «Яркость», «Цветовая температура», «Цвет», «Белый», координаты и основные цвета — по wire-id из 1. «дублирование процентного значения» — пока не трогал, нужно ваше мнение. Слайдер показывает уставку, в скобках — прочитанное с устройства; когда они совпадают (а в норме они совпадают почти всегда), это выглядит дублем. Подсказка теперь хотя бы объясняет, что за число в скобках. Варианты: прятать скобки, когда значения равны, или показывать их только при расхождении. Как лучше? |





На страницах устройства, группы и шины DALI появляется закреплённая полоса живых контролов устройства (
device-controls/): выбранные контролы видны прямо в настройках и управляются оттуда, без перехода на вкладку «Устройства». Всё идёт через обычные retained-топики демона/devices/<id>/controls/…, поэтому одинаково работает на контроллере и в браузере — от WASM-редактора не зависит.Тикет: SOFT-7431
Что попадает в полосу
Набор выбирается по структуре контролов, а не «показать всё». Берутся чтения (read-only, кроме
pushbutton), но только одиночные: семейства вида «Button 2»…«Button 18» — три и более однотипных имени с числовым суффиксом — отсеиваются. К ним писчиеrange(уровень, цветовая температура),rgb-пикеры и две универсальные кнопки, Off и Recall Max Level, опознаваемые по wire-id и английскому заголовку, а не по локализованному имени. Приоритет при упоре в лимит (6 слотов): чтения → основной слайдер → цвет → Off → Recall Max → остальные слайдеры. У датчика DALI-2 это оставляет в полосе три живых чтения вместо двух десятков кнопочных индикаторов; остальное — за «Все контролы».Пара «уставка ↔ чтение» занимает один слот:
wanted_levelпоказывается с «Actual Level» в суффиксе,set_rgb— со swatch'ем, так же для белого, цветовой температуры и координат XY. Чтения сенсоров выводятся как «имя: значение» («Освещённость 1 537»). На широком экране полоса закреплена под тулбаром, на телефоне — нижний лист с peek-строкой.Инфраструктура
tab-toolbar/публикует свою высоту в--dali-toolbar-heightчерезResizeObserver, чтобы полоса вставала вплотную под тулбар при любом переносе заголовка и кнопок.stores/devices/send-cell-value.ts— единственное написание команды записи (/devices/<id>/controls/<ctl>/on, non-retained), общее для полосы иDevicesStore.DeviceStoreберётmqtt_idиз конфига,GroupStore.controlsMqttIdсобирает id виртуального устройства группы из id шины с ведущими нулями.Тесты
device-controls/featured.test.ts— эвристика выбора (broadcast-устройство, лимит в пользу Off, отсев кнопочного шума датчика) и слияние уставки с чтением;stores/dali/device-store-controls.test.tsиgroup-store-mqtt-id.test.ts— mqtt-id, от которого зависит рендер полосы;collapsible-panel-toggle.test.tsx— клик по строке заголовка переключает панель ровно один раз. Весь фронтенд-набор vitest зелёный (2507 тестов), eslint чист.debian/changelog— 2.250.4.Как попробовать
Открыть страницу DALI-устройства с несколькими контролами (диммер DT6/DT8, датчик DALI-2) — полоса сверху. Изменить уровень из полосы: устройство реагирует, чтение подтягивается. Проскроллить форму — полоса остаётся под тулбаром.
Скриншоты
Страница устройства: полоса контролов под тулбаром, слот назван величиной — «Яркость»
Уровень изменён из полосы, readback подтянулся
Полоса остаётся закреплённой при прокрутке, в углах ничего не просвечивает
DT8: уставка↔чтение цветовой температуры в одном слоте — «Цветовая температура»
Телефон: строка «имя: значение» и раскрытый лист контролов
Страница группы
Страница шины (broadcast, без readback)
Подсказка на значении в скобках
Значение в скобках — это чтение с устройства; при наведении показывается подсказка «Значение, прочитанное из устройства». Скриншота нет: это нативный
title=, который Chromium рисует как элемент интерфейса браузера и не попадает в снимок страницы.🤖 Generated with Claude Code
https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC