Команды устройствам и ответы
Нажатие на панели — это только намерение. Чтобы что-то произошло в зале, программа должна отправить устройству команду. Чтобы на панели было видно, что произошло на самом деле, она должна принять ответ. На этой странице два узла (блока программы U-Logic): device - command отправляет команду, device - response - listener принимает ответ.
Эти же два узла вы уже использовали в «Первой программе»: блоки B–D там — самый короткий путь «нажали — команда — ответ — подпись». Блоки H и I (страница «Устройства») показывают ответы звукового процессора и кодека и то, что с ними делать. Здесь узлы разобраны подробнее.
Что нужно заранее: событие с панели уже принято и разложено по выходам ui - switch («Приём событий»), а драйвер устройства (описание протокола: команды, их параметры и разбор ответов) и подключение к нему созданы (как — в разделе «По шагам: подключить устройство и отправить команду»). Здесь — только то, что нужно для связи с интерфейсом; окна узлов подробно разобраны на странице «Узлы Dynamic Driver».
device - command: команда устройству
Зачем. Отправить устройству команду из его драйвера: «подать вход 2 на выход 1», «позвонить», «выключить микрофон».
Поля окна и выходы узла описаны в разделе device - command. Главное для связи с интерфейсом: «Соединение» и «Команда» обязательны (без соединения узел показывает «Не настроено соединение»), а «Параметры команды» задают значения по умолчанию.
Окно узла device - command «Кодек: команда»: 1 — «Соединение», 2 — «Команда», 3 — «Параметры команды»
В «Демо-зале» команда и параметры приходят в сообщении: msg.command (вместо команды из окна) и msg.parameters (сливается с параметрами из окна, сообщение главнее). Первый выход узла — состояние соединения, второй — копия входного сообщения без msg.command и msg.parameters; ответ устройства из device - command не выходит: его принимает device - response - listener. Пока устройство не подключено, команда теряется.
Как команда получает параметры из события
device - command не знает про интерфейс: ему важно только сообщение. Имя кнопки и значение из события превращает в команду и параметры узел перед ним. В «Демо-зале» так:
Один
device - commandна устройство. Команду в узел кладёт предыдущий узел вmsg.command, параметры — вmsg.parameters. Например, для кодека: «Контакты» →getContacts, «История» →getHistory, «Позвонить» →dialс номером в параметрах, «Завершить» →hangup, микрофон →setMute. Все команды идут в один узел «Кодек: команда».Элемент не привязывается к команде в окне. Привязка — это путь по проводам: правило
ui - switch→ узел, который готовит команду →device - command.Команда без соединения теряется. Поэтому подписки и запросы статуса запускают от первого выхода узла. Когда он сообщил «connected», в блоке «Шаги сценариев и подписки» через паузу отправляются подписки звукового процессора. Зачем нужна подписка и почему после подключения пауза — в «Первой программе», блок H.
Подготовить команду проще всего узлом change. Есть два случая.
Фиксированная команда: change с константами
Команда и параметры всегда одни и те же, поэтому достаточно двух правил «Установить»: msg.command — «строка» с именем команды, msg.parameters — «JSON» с параметрами (или одно правило, если параметров нет). В «Демо-зале» так сделаны «Завершить» (msg.command = hangup) и «Список: контакты» (getContacts), а микрофон — setMute с {"mute": false} или {"mute": true}. Названия команд и полей параметров берите в окне device - command: список «Команда» и блок «Параметры команды».
Команда зависит от кнопки: карта кнопок
Кнопок много, и у каждой свои параметры (каждый источник — свой вход матрицы). Вместо узла change на каждую кнопку заведите таблицу «кнопка → параметры» в памяти программы и один change, который достаёт из неё строку по имени нажатой кнопки: msg.parameters = flow. (или global.) demoMatrix[msg.payload.object], с флажком «Deep copy value» («глубокая копия»). Так сделан блок «Экран» в «Демо-зале»: одно правило Src_*_b, один change «Кнопка → параметры матрицы» и один device - command «Матрица: подать вход». Таблица записывается один раз при запуске (блок «Старт»). Как это устроено и почему работает, подробно описано в «Первой программе», блоки A и C. Там же есть более наглядный вариант, где на каждую кнопку свой change.
Для тех, кто программирует: function
Если подготовка команды сложнее «взять по ключу» (проверка условий, выбор из нескольких источников, сообщение пользователю), можно написать её узлом function (свой код). В «Демо-зале» так сделана кнопка «Позвонить»: функция «Позвонить выбранному» берёт из памяти строку, выбранную в списке, и, если ничего не выбрано, предупреждает об этом вместо команды. Дайте узлу понятное имя и напишите в комментарии в начале, что он принимает и что выдаёт («вход / выход»). Для новичка function не нужен: всё из этой страницы делается узлами change и switch.
Сценарий из нескольких команд
Кнопка «Начало совещания» на главной включает микрофоны, звук и матрицу сразу. В «Демо-зале» такой сценарий — список шагов [{устройство, команда, параметры}], который лежит в узле change. Узлы «Шаги: …» передают список в блок «Шаги сценариев и подписки». Там split разбирает список, delay (0,4 с) делает паузу между шагами, change превращает шаг в msg.command и msg.parameters, switch выбирает нужное устройство, и шаг уходит в device - command этого устройства. Поэтому «Выключить все» места — это один change со списком из 13 шагов, а не 13 проводов. Окно подтверждения «Выключить всё» делается в интерфейсе (фрейм с кнопкой «Выключить»): программа получает только нажатие «Выключить».
device - response - listener: ответ устройства
Зачем. Вернуть на панель то, что произошло на самом деле. Нажатие — это намерение, ответ устройства — факт: источник могли переключить с пульта или сценарием, команда могла не пройти. Кнопка, подсвеченная по ответу, не «врёт».
Как настроить окно — в разделе device - response - listener: то же «Соединение», что у device - command, число выходов и таблица «Типы ответов» с номером выхода для каждого типа. Ответ, для которого выход не выбран, уходит на первый выход.
Окно узла device - response - listener «Кодек: ответы»: 1 — «Соединение», 2 — «Выходы», 3 — «Типы ответов» и номера выходов
Что приходит: msg.payload содержит ответ драйвера, тип ответа — в msg.payload.type; к какому устройству относится ответ — в msg.device.
Как выглядят ответы
Состав полей зависит от драйвера. Проще всего увидеть его в отладке: подключите к выходу device - response - listener узел debug («весь msg») и вызовите ответ. Ответы устройств «Первой программы», как они приходят в msg.payload:
Устройство и тип ответа |
Что в |
Что из него берут |
|---|---|---|
Звуковой процессор, |
|
имя подписки |
Кодек, |
|
|
Кодек, |
|
массив |
Матрица, |
|
|
Как получить из такого ответа значение для панели, разобрано по примерам на странице «Изменение вида на панели». Для этого в узле change пишут выражение над msg.payload, а результат кладут в msg.topic для api - helper - 2. Примеры: кнопка по value (пример 1), ползунок и надпись по уровню в дБ (пример 2), текст и цвет по inCall (пример 3), список по list (пример 4).
Что слушает «Демо-зал»:
Устройство |
Что приходит |
Что делает поток |
|---|---|---|
Матрица |
ответ на |
после фильтров «Подтверждено?» и «Какой выход?» подсвечивает источник, пишет «На экране: …» |
Звуковой процессор |
уведомления подписок |
двигает ползунки, нажимает и отпускает кнопки mute, считает «Говорят» |
Кодек ВКС |
|
заполняет список, меняет «Идёт разговор» / «Нет звонка» и цвет плашки |
Фильтр ответа: switch
Один драйвер присылает ответы на разные команды и по разным выходам устройства. Матрица, например, отвечает «выход 2 ← вход 1», даже если вы работаете с экраном зала на выходе 1. Чтобы ответ не попал не в ту подпись, поставьте после device - response - listener обычный узел switch:
Свойство — поле ответа, по которому выбираете (
msg.payload.output).По одному правилу «==» на каждое значение: выход 1 — одна ветка (экран зала), выход 2 — другая (экран председателя). Ответ по выходу, которого нет среди правил, дальше не идёт.
Если драйвер сообщает об операции дважды (при отправке и по ответу устройства), первым поставьте
switchпо признаку подтверждения (msg.payload.ack«равно true»).
Так сделано в «Первой программе» (блок D, switch «Подтверждено?» и «Какой выход?») и в блоке «Экран» «Демо-зала».
Ответ → вид элементов
Дальше ответ превращают в сообщение для api - helper - 2 (как — на странице «Изменение вида на панели», с готовыми примерами для звука и ВКС) или interlock - 2 («Переключатели и группы») и отправляют в UI - Panel out.
Имя подписки = имя элемента. Звуковой процессор присылает уведомление вместе с именем, под которым оформлена подписка. Если подписку назвать именем кнопки (Mic_04_b, Snd_Hall_vol_sl, Hdr_Sound_b), уведомление само указывает, какой элемент менять. В блоке «Звуковой процессор: ответы → вид элементов» узел switch «Чьё уведомление» (проверка всех правил) отправляет уведомления мест Mic_* в два места: в блок «Микрофоны» и в шаблон «Кнопки по имени». Остальные кнопки он отправляет в шаблон вида { "{{payload.publishToken}}": { "uiState": "default" или "pressed" } } (поле с именем подписки в ответе этого драйвера называется publishToken) и дальше в api - helper - 2 «Кнопки по имени». Один шаблон работает для всех кнопок с mute: добавили новую подписку — менять поток не нужно.
Блок 9 «Звуковой процессор: ответы → вид элементов»: 1 — «Звук: уведомления», 2 — «Чьё уведомление», 3 — шаблоны по имени кнопки «Кнопка: обычная» и «Кнопка: нажата», 4 — api - helper - 2 «Кнопки по имени», 5 — ветки ползунков и подписей «Зал» и «ВКС»
Опрос, если устройство само не сообщает. Кодек не присылает состояние звонка сам, поэтому узел inject каждые 5 секунд посылает ему getCallInfo, а ответ callInfo с признаком inCall меняет надписи.
Частые ошибки
Ответ команды ищут на выходе
device - command. Ответ устройства приходит только вdevice - response - listener. Выход 2 — сквозная копия сообщения, она уходит сразу.Команда не доходит. У
device - commandне выбрано «Соединение» (в состоянии узла «Не настроено соединение») или устройство ещё не подключилось. Подключение смотрите по статусу узла и по первому выходу.Подписки и запросы статуса не срабатывают. Они ушли до подключения. Запускайте их от первого выхода
device - command.Подсвечивается не та кнопка или совсем не подсвечивается. Подсветка идёт по ответу устройства: проверьте, дошёл ли ответ до
device - response - listener, тот ли выбран тип ответа и тот ли выход. Если ответ приходит, но имя вinterlock - 2не подходит, исправьте имя, которое вы кладёте на его вход.Устройство ответило, но ничего не поменялось на панели. Ответ дошёл до
device - response - listener, но не подключён ни кapi - helper - 2, ни кinterlock - 2, либо их выход не подключён кUI - Panel out.