Связь интерфейса с программой

Интерфейс, нарисованный в UI-Designer (редактор интерфейсов), сам ничего не делает. Он присылает в программу U-Logic (редактор программы управления) события («кнопку нажали», «ползунок сдвинули», «выбрали строку») и показывает то, что велит программа. Этот раздел объясняет, как соединить одно с другим: принять событие с панели, превратить его в команду устройству и вернуть на панель результат.

Раздел написан для тех, кто делает это впервые, и идёт от простого к сложному. Сначала — маленькая учебная программа «Первая программа»: вы собираете её по шагам и видите, как каждый узел (блок программы U-Logic) меняет то, что происходит на панели. Затем — по одной странице на каждый приём. В конце — большая учебная программа «Демо-зал», где все приёмы работают вместе. Как загрузить их интерфейсы — в «UI-Designer».

Описание каждого узла по отдельности есть в разделе «Узлы U-Logic» (узлы интерфейса — на странице «Интерфейс и панели») и в «Dynamic Driver» (узлы device - command, device - response - listener и драйверы устройств). Здесь они не пересказываются: показано, как узлы работают вместе.

Что нужно знать заранее:

Как читать раздел

Идите по порядку: каждая следующая страница опирается на предыдущую. Если вы уже знаете приём, откройте нужную страницу из таблицы.

Шаг

Что нужно

Страница

1

Собрать за один подход всё главное: нажатие → команда → ответ → вид на панели

«Первая программа по шагам»

2

Подробно про приём события и правила ui - switch

«Приём событий»

3

По ответу устройства поменять кнопку, ползунок, надпись, цвет, список; открыть другую страницу

«Изменение вида на панели»

4

Отправить команду устройству и принять ответ

«Команды устройствам и ответы»

5

Сделать переключатель или группу кнопок

«Переключатели и группы»

6

Загрузить большую программу и посмотреть, как приёмы работают вместе

«Программа «Демо-зал»: обзор»

Общая схема

Как эта часть связана с остальной системой — на странице «Как устроена система».

Связь идёт в две стороны. Вперёд: оператор нажал кнопку на панели, событие попало в программу, программа отправила команду устройству. Назад: устройство ответило, программа перекрасила кнопку или поменяла надпись на панели.

        flowchart LR
    P["Панель<br/>(UI-Panel)"] --> IN["UI - Panel in"]
    IN --> SW["ui - switch"]
    SW --> CH["change"]
    CH --> DC["device - command"]
    DC --> DEV["Устройство"]
    DEV --> RL["device - response - listener"]
    RL --> FL["switch"]
    FL --> FN["change"]
    FN --> IL["interlock - 2"]
    FN --> AH["api - helper - 2"]
    IL --> OUT["UI - Panel out"]
    AH --> OUT
    OUT --> P
    

Что делает каждый узел:

Узел

Роль

UI - Panel in

принимает все события с панелей: вход программы

ui - switch

раскладывает события по выходам по правилам: «эта кнопка — сюда, этот ползунок — туда»

change

готовит команду: берёт из события имя элемента и значение и подставляет в параметры; готовит и данные для обратного пути

switch

выбирает путь по значению: «включить» или «выключить», ответ по этому выходу или по другому

device - command

отправляет команду устройству

device - response - listener

принимает ответы и уведомления устройства

interlock - 2

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

api - helper - 2

меняет вид элементов: текст, цвет, состояние кнопки, значение ползунка, строки списка

UI - Panel out

отправляет на панель то, что сформировали api - helper - 2 и interlock - 2: выход программы

Узел function (свой код) в этом разделе нужен только тем, кто программирует: см. подраздел в «Команды устройствам и ответы». Новичку хватает узлов из схемы.

Примечание

Схема показывает порядок, а не обязательный набор. Нужна только команда — берите путь «вперёд» без обратного. Нужно только поменять надпись — обойдитесь без устройства. Но в учебных программах кнопки подсвечиваются по ответу устройства, а не по нажатию: так на панели видно то, что действительно произошло.

Два узла есть в любой программе с панелью: UI - Panel in на входе и UI - Panel out на выходе. Если UI - Panel in не развёрнут (кнопка «Развернуть» запускает правки программы в работу), панель не получает интерфейсы. Страница UI-Panel (на ней оператор работает с интерфейсом) открывается, но на ней бесконечно крутятся точки загрузки, а селектора интерфейсов нет. Опубликованный в UI-Designer интерфейс сам по себе не появится: его панелям передаёт программа через этот узел и его подключение UI-listener. Если в вашей программе нет узла UI - Panel in, добавьте его по шагам из раздела «Подготовьте U-Logic» страницы «Первый интерфейс».

Имя элемента — это ID

В UI-Designer у каждого элемента есть поле «Имя». Для программы это единственный способ найти элемент. Имя из UI-Designer должно совпасть с тем, что написано в узле, буква в букву.

Что это значит на практике:

  • Регистр и пробелы важны: Src_Cam1_b и src_cam1_b — разные элементы, имя с пробелом на конце — тоже другое имя. Узлы ничего не обрезают и не приводят к одному регистру.

  • Совпадение точное: правило без шаблона в ui - switch сравнивает имя целиком, а режимы шаблона (startsWith, wildcard и другие) тоже различают регистр.

  • Одинаковые имена не различаются. Если двум элементам дали одно имя, в списке узла они сливаются в одну строку, и программа не отличит один от другого. Давайте каждому элементу своё имя (подробно — в «Кнопки и состояния»).

  • Интерфейс тоже выбирается по имени: узлы ui - switch, api - helper - 2 и interlock - 2 просят выбрать интерфейс, без этого они не работают.

  • Список элементов в узле появляется после «Сохранить» и «Опубликовать» в UI-Designer. Добавили кнопку, но не опубликовали — в узле её нет.

  • Переименовывайте осознанно. Если элемент выбран в узле из списка, узел запоминает и его внутренний номер, поэтому при запуске узла имя в нём обновляется. Это работает только для элементов, выбранных из списка: правила с шаблоном и имена внутри ваших узлов change сами не обновятся. Лучше не переименовывать элементы готовой программы.

Одно имя на всём пути

В «Демо-зале» имя элемента не меняется во всей цепочке: оно же ключ в настройках зала и имя подписки на звуковом процессоре. Поэтому уведомление процессора приходит уже с именем кнопки, которую надо перекрасить, и ничего переводить не нужно. Если одно состояние должно вести две кнопки, на этот канал подписывают два имени. Так кнопка Snd_Hall_mute_b на экране «Звук» и кнопка «Звук в зале» в шапке (Hdr_Sound_b) показывают один и тот же mute.

Если вы строите интерфейс под готовую программу или программу под готовый интерфейс, сначала договоритесь об именах: исправить их потом дороже, чем придумать сразу. По именам вида Группа_Объект_тип (см. «Первый интерфейс») одно правило охватывает всю группу: об этом на странице «Приём событий».

Что приходит с панели

Каждое действие оператора панель отправляет в программу как событие. Узел UI - Panel in принимает его и выдаёт в msg.payload такую запись:

{
  "UI": {
    "Демо-зал": {
      "object": "Mic_09_b",
      "event": "release"
    }
  },
  "Client": "192.168.1.100"
}
  • UI — имя интерфейса, в котором произошло событие;

  • object — имя элемента, то самое поле «Имя» из UI-Designer;

  • event — что произошло;

  • value — значение (есть не у всех событий, см. таблицу);

  • Client — адрес устройства, где открыта панель (в примере выше он условный).

Дальше событие обрабатывает ui - switch. На его выходах в msg.payload добавлены отдельные поля, которые можно брать в change: ui, object, event, value, client.

События по элементам

Таблица составлена по тому, что показывал узел debug (вывод $string(payload)):

Элемент

События

Значение value

Кнопка

push — нажата, release — отпущена, tap — касание; один «клик» даёт все три

нет

Кнопка-переключатель

те же и ещё value_changed — положение сменилось (только вместе с tap)

новое состояние: pressed при включении, при выключении — состояние кнопки по умолчанию (обычно default)

Ползунок

slide_begin, value_changed, slide_end

число от 0 до 1, например 0.27

Список

item_selected

ключ выбранной строки, например Дежурная служба

Инпут

value_changed после «Кнопки отправки»

введённый текст, всегда строкой: "1003"

Панель подключилась к интерфейсу

connected, без поля object

нет

Панель закрыли

disconnected, без поля object

нет

Из таблицы следует:

  • Выбирайте одно событие. Один клик по кнопке — три сообщения (push, release, tap); если оставить в правиле «Любое событие», действие выполнится трижды. Для команды обычно берут push; для действия «пока держат» (двигать камеру) — пару push и release.

  • Ползунок лучше ловить по slide_end: команда уходит один раз, когда оператор отпустил ползунок, а не сотни раз при движении.

  • Список возвращает ключ строки, а не её номер и не значение. Строки списка задаёт программа как [{"ключ": "значение"}] (см. «Изменение вида на панели»), и обратно приходит ключ.

  • Сообщения connected и disconnected не имеют object: их присылает панель при подключении к интерфейсу и при закрытии, а ui - switch пропускает такие сообщения без выхода. Если в отладке перед нажатиями видна «лишняя» строка без object, это подключение панели.

  • В списке событий ui - switch есть и другие: hold — повтор, пока кнопку держат (если у неё включён «Повтор нажатия при удержании»), без значения; события спидометров (см. «События элементов»); popup_show и popup_hide не используйте. Об открытии окна программа узнаёт по push кнопки, которая его открывает.

Как посмотреть событие самому

Это самый быстрый способ понять, что именно присылает панель. Используйте его всегда, прежде чем настраивать правила.

  1. Перетащите на вкладку узел debug и соедините его с выходом UI - Panel in.

  2. Откройте узел debug: в «Выводить» выберите «выражение» и впишите $string(payload). Нажмите «Готово» и «Развернуть».

  3. Откройте на правой боковой панели вкладку отладки (значок «жук»).

  4. Нажмите нужный элемент на панели — в отладке появится строка с событием.

Узел debug включается и выключается кнопкой справа от него. В «Демо-зале» такой узел есть в блоке «Связь с панелью» («Что прислала панель») и по умолчанию выключен.

../_images/debug-events.png

Боковая панель отладки: 1 — событие push кнопки Src_Cam1_b, 2 — release той же кнопки, 3 — item_selected списка ВКС, в value — ключ выбранной строки. Между ними — события tap и нажатия кнопок вкладок (Nav_…); адрес клиента скрыт

Что вы увидите: за одно нажатие кнопки в отладке три строки (push, release, tap), в каждой — object с именем кнопки. Имя из этой строки впишите в правило.

Частые ошибки

Общий маршрут проверки по цепочке «панель → программа → устройство → панель» — на странице «Не работает: где смотреть».

  • На панели только точки загрузки. В программе U-Logic нет развёрнутого узла UI - Panel in (или узел добавлен, но не нажато «Развернуть»). Добавьте узел, в поле Path создайте подключение UI-listener с путём /web-client, нажмите «Готово» и «Развернуть», затем обновите страницу панели (см. «Первый интерфейс»). Если селектор «Интерфейсы» есть, а нужного интерфейса в нём нет, проект не опубликован — или опубликован без сохранения.

  • Элемента нет в списке узла. В UI-Designer не нажали «Сохранить» и «Опубликовать» (см. «UI-Designer»). Если в списке рядом с именем звёздочки ** — такого элемента в интерфейсе уже нет: его переименовали или удалили.

  • Действие выполняется три раза. В правиле ui - switch оставили «Любое событие». Выберите push.

  • Изменения в U-Logic не действуют. Правки узлов работают после «Развернуть».