Skip to content

DALI: live device controls on device, group and bus pages - #1233

Open
evgeny-boger wants to merge 4 commits into
masterfrom
split/dali-live-controls-v2
Open

DALI: live device controls on device, group and bus pages#1233
evgeny-boger wants to merge 4 commits into
masterfrom
split/dali-live-controls-v2

Conversation

@evgeny-boger

@evgeny-boger evgeny-boger commented Sep 2, 2026

Copy link
Copy Markdown
Member

На страницах устройства, группы и шины 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 подтянулся

Уровень изменён из полосы, readback подтянулся

Полоса остаётся закреплённой при прокрутке, в углах ничего не просвечивает

Полоса остаётся закреплённой при прокрутке, в углах ничего не просвечивает

DT8: уставка↔чтение цветовой температуры в одном слоте — «Цветовая температура»

DT8: уставка↔чтение цветовой температуры в одном слоте — «Цветовая температура»

Телефон: строка «имя: значение» и раскрытый лист контролов

Телефон: строка «имя: значение» и раскрытый лист контролов Телефон: строка «имя: значение» и раскрытый лист контролов

Страница группы

Страница группы

Страница шины (broadcast, без readback)

Страница шины (broadcast, без readback)

Подсказка на значении в скобках

Значение в скобках — это чтение с устройства; при наведении показывается подсказка «Значение, прочитанное из устройства». Скриншота нет: это нативный title=, который Chromium рисует как элемент интерфейса браузера и не попадает в снимок страницы.

🤖 Generated with Claude Code

https://claude.ai/code/session_01BNC4oayJWjJaHMmvM8YMGC

evgeny-boger and others added 2 commits September 2, 2026 21:21
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
@codacy-production

codacy-production Bot commented Sep 2, 2026

Copy link
Copy Markdown

Up to standards ✅

🟢 Issues 0 issues

Results:
0 new issues

View in Codacy

🟢 Metrics 105 complexity · 0 duplication

Metric Results
Complexity 105
Duplication 0

View in Codacy

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.

@evgeny-boger
evgeny-boger marked this pull request as ready for review September 3, 2026 00:08
@evgeny-boger
evgeny-boger requested a review from a team as a code owner September 3, 2026 00:08

@ninedev-i ninedev-i left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

К коду вопросов нет
из визуального того, что бросилось в глаза

  1. дублирование процентного значения
Image 2. минорное - в версии для пк при скролле в углу грязь Image

evgeny-boger and others added 2 commits September 4, 2026 00:22
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
@evgeny-boger

Copy link
Copy Markdown
Member Author

Спасибо! Сделано в 88fb1c7 и 2cff11b.

2. «в углу грязь»88fb1c7. Полоса управления — карточка со скруглёнными углами, а форма параметров скроллится прямо под ней. В клиньях между скруглением и прямоугольной границей фон карточки не рисуется, и туда просвечивали кусочки едущего текста. Заполнил их второй тенью — непрозрачным кольцом цвета фона контейнера: тень рисуется под фоном карточки, а псевдоэлемент с z-index: -1 не подошёл бы — sticky-полоса с z-index: 100 создаёт свой контекст наложения и перекрасила бы саму карточку. Проверил на симулированной шине DALI в 1280x800 и 1920x1080 на девяти позициях скролла: артефакт пропал, остальные пиксели полосы не изменились.

Названия2cff11b. Демон называет записываемую половину пары «Желаемая яркость», а рядом в скобках печатается прочитанное значение — получается как будто две разные величины. Теперь слот называется самой величиной: «Яркость», «Цветовая температура», «Цвет», «Белый», координаты и основные цвета — по wire-id из control_ids.py, с общим запасным вариантом (снять префикс «Желаемый »/«Wanted ») для незнакомых типов устройств. Значение в скобках само по себе непонятно, поэтому получило подсказку: «Значение, прочитанное из устройства» / «Value read back from the device».

1. «дублирование процентного значения» — пока не трогал, нужно ваше мнение. Слайдер показывает уставку, в скобках — прочитанное с устройства; когда они совпадают (а в норме они совпадают почти всегда), это выглядит дублем. Подсказка теперь хотя бы объясняет, что за число в скобках. Варианты: прятать скобки, когда значения равны, или показывать их только при расхождении. Как лучше?

@KraPete KraPete left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Тут тоже везде раздутые комментарии.

Image Что такое Норма: выкл?
  1. Цвет, может, картинкой?
Image
  1. Выровнять бы подпись справа и фиксированую ширинуЮ чтоб ползунок не дёргался
Image
  1. Может рядом с DAPC этот реальный процент выводить? Всё равно ползунком не выставить сотые

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants