Узлы «Функции»

Эти узлы подготавливают данные между событием и действием: подставляют значения в сообщение (change), выбирают нужную ветку (switch), собирают текст или объект по шаблону (template), делают паузу (delay). Ещё несколько узлов с ограниченной задачей (trigger, range, filter, цикл, calculator, process - stat) описаны в разделе «Короткие узлы», у каждого свой подраздел. Для тех, кто пишет код, есть узел function: ему отведён отдельный раздел в конце страницы, новичку он не нужен.

Как открыть окно узла и как пользоваться встроенной справкой — на странице «Узлы U-Logic». Примеры взяты с учебных вкладок «Первая программа» (по шагам) и «Демо-зал» (обзор). Подписи полей даны так, как они показаны в окне узла; английские подписи не переводятся.

change: записать значение в сообщение

Зачем. Команде устройству нужны параметры, панели — готовые подписи, а у сообщения, пришедшего с кнопки, есть только имя кнопки. Узел change меняет поля сообщения по правилам: записывает константу, берёт значение из памяти программы, вычисляет выражение. Самая частая работа — подготовить msg.command и msg.parameters перед device - command. Один вход, один выход.

../../_images/node-change.png

Окно узла change «Кнопка → параметры по карте»: 1 — «Имя», 2 — действие правила, 3 — свойство, 4 — «to the value» и тип значения, 5 — «Deep copy value», 6 — «добавить»

Поля окна:

  1. «Имя» — подпись на вкладке: «HDMI 2 → экран».

  2. Действие правила: «Установить», «Изменить», «Удалить» или «Переместить» (таблица ниже).

  3. Свойство, с которым работает правило: msg., flow. или global. и имя после точки.

  4. Значение — подпись «to the value» и тип значения: строка, число, логический тип, JSON, буфер, метка времени, выражение, переменная среды, msg., flow., global..

  5. Отметка «Deep copy value» («глубокая копия») — появляется, когда значение берётся из msg., flow. или global.; зачем она, — в примере 2.

  6. Кнопка «добавить» — ещё одно правило. Правил в одном узле может быть сколько нужно.

Действие

Что делает

Поля

«Установить»

записывает значение в свойство

свойство; «to the value» и тип значения

«Изменить»

ищет текст в строке и заменяет

«Искать», «Заменить на»; отметка «Использовать регул. выражение». Работает только со строками

«Удалить»

убирает свойство из сообщения

свойство

«Переместить»

переносит значение из одного свойства в другое

свойство; «в» — куда

Правила выполняются сверху вниз, порядок важен: если второе правило использует то, что записало первое, оно должно стоять ниже.

Тип значения определяет, что будет записано. «Строка» — текст как есть; «число», «логический тип» (true/false); «JSON» — готовая таблица или список, например {"input": 2, "output": 1}; msg., flow., global. — взять значение из другого свойства сообщения или из памяти программы; «выражение» — вычислить значение по формуле (см. ниже «JSONata»). Если нужно значение из сообщения, а выбрана «строка», в поле попадёт буквальный текст payload.value, а не значение.

Пример 1: готовые параметры на кнопку

В «Первой программе» (блок B) каждая из трёх кнопок источника попадает на свой выход ui - switch, а к каждому выходу подключён свой change. «HDMI 2 → экран» записывает одно правило: «Установить» msg.parameters как «JSON» {"input": 2, "output": 1}. Дальше device - command «Матрица: подать вход» берёт эти параметры в команду route. Такую цепочку легко читать; она подходит, когда кнопок две-три.

../../_images/flow-function-change-1.png

Цепочка примера: UI - Panel in → ui - switch → три change «HDMI 1 → экран», «HDMI 2 → экран», «HDMI 3 → экран» → device - command «Матрица: подать вход»

Пример 2: таблица в памяти и подстановка по ключу

Когда кнопок много, одна таблица в памяти заменяет десятки узлов. Это два шага.

  1. Записать таблицу при запуске. inject «При запуске» → change «Карты кнопок и входов». В нём правило «Установить» global.fpInputs, тип «JSON», значение — таблица «имя кнопки → параметры»:

    {"Fp_Map_Hdmi1_b": {"input": 1, "output": 2},
     "Fp_Map_Hdmi2_b": {"input": 2, "output": 2}}
    

    Таблица лежит в памяти программы, пока она запущена. global. видят все вкладки, flow. — только та вкладка, где записали. «Демо-зал» хранит такие таблицы в flow., «Первая программа» — в global. Подробнее о переменных — «Понимание переменных».

    ../../_images/flow-function-change-2-start.png

    Цепочка примера: inject «При запуске» → change «Карты кнопок и входов»

  2. Достать строку по имени кнопки. После ui - switch стоит change «Кнопка → параметры по карте» (окно — на снимке в начале раздела): «Установить» msg.parameters, тип значения global., значение fpInputs[msg.payload.object], отметка «Deep copy value» включена. В квадратных скобках — ключ: имя нажатой кнопки, которое пришло с панели в msg.payload.object. Поэтому имя элемента в UI-Designer (редактор интерфейсов) должно совпадать с ключом до буквы. «Глубокая копия» даёт сообщению свою копию строки, а не ссылку на таблицу в памяти. Включайте отметку, когда берёте таблицу или список целиком.

    ../../_images/flow-function-change-2-lookup.png

    Цепочка примера: UI - Panel in → ui - switch «Кнопки HDMI: по шаблону» → change «Кнопка → параметры по карте» → device - command

Как это работает по шагам и как проверить в отладке — в «Первой программе», блоки A и C. Тот же приём в «Демо-зале»: change «Кнопка → параметры матрицы» берёт строку из flow.demoMatrix.

JSONata: выражение вместо switch

Что это. JSONata — короткий язык формул: узел вычисляет формулу над сообщением и подставляет результат (payload.value — то же, что msg.payload.value). В окне change его включает тип значения «выражение». Пример: в «Первой программе» (блок F) change «setMute по JSONata» записывает в msg.parameters выражение

{"mute": payload.value = "default"}

Оно возвращает {"mute": true}, если с кнопки пришло "default" (кнопку выключили), и {"mute": false} для "pressed": одна формула заменяет switch и два change.

../../_images/flow-function-change-jsonata.png

Цепочка примера: UI - Panel in → ui - switch → change «setMute по JSONata» → device - command

Разбор формулы — в блоке F «Первой программы». Тот же приём в блоке E сделан узлом switch: он нагляднее, когда на каждое положение нужны разные действия (см. ниже раздел о switch и страницу «Переключатели и группы»).

Что вы увидите. Ничего на панели: change только готовит данные. Чтобы проверить, подключите к выходу debug с выводом «весь msg объект сообщения» и посмотрите parameters. Если поля parameters в сообщении нет, ключа в таблице нет. Проверьте, что узел записи таблицы развёрнут и запущен и что имя кнопки совпадает с ключом.

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

  • Значение с типом «строка» вместо «выражение» или msg.: в сообщение попадает текст формулы, а не результат.

  • Таблица записана, но change читает другую область: если таблицу положили в global., читать нужно из global., не из flow..

  • Правило «Изменить» применили не к строке: оно работает только с текстом.

  • Не включили «Deep copy value» при чтении таблицы целиком.

  • Изменили таблицу в change записи, но не нажали «Развернуть» и кнопку у inject: в памяти осталась старая таблица.

switch: выбрать ветку

Зачем. Сообщение нужно отправить в разные ветки в зависимости от его содержимого. Самая частая задача в зале — отсеивать ответы устройства. Матрица одна, а выходов у неё несколько: ответ «выход 2 ← вход 1» не должен менять подпись экрана зала, если на выходе 2 экран председателя. Один вход, выходов столько, сколько правил.

../../_images/node-switch.png

Окно узла switch «Какой выход?»: 1 — «Имя», 2 — «Свойство», 3 — оператор правила, 4 — значение правила, 5 — переключатель «остановка после первого совпадения», 6 — «добавить»

Поля окна:

  1. «Имя» — подпись на вкладке: «Какой выход?».

  2. «Свойство» — что проверяем. По умолчанию msg.payload; для ответа устройства это поле вроде msg.payload.output. Свойство можно взять из msg., flow., global., задать выражением или переменной среды.

  3. Оператор правила — «==», «!=», «<», «<=», «>», «>=», «имеет ключ», «между», «содержит», «подходит под регул. выраж.», «равно true», «равно false», «равно null», «не равно null», «является типом», «пустое», «не пустое», «первые N», «последние N», «индекс между», «выраж. JSONata» или «иначе».

  4. Значение, с которым сравниваем, и его тип (строка, число…). У правила «подходит под регул. выраж.» есть отметка «игнорировать регистр».

  5. Переключатель «проверка всех правил» / «остановка после первого совпадения» — что делать, когда правило подошло.

  6. Кнопка «добавить» — новое правило. Каждое правило — отдельный выход, выходы нумеруются сверху вниз.

Ниже списка правил есть отметка «воссоздать последовательность сообщений». Она нужна только при работе с последовательностями сообщений; новичку её включать не нужно.

Пример на «Первой программе».

  • switch «Какой выход?» (блок D, окно — на снимке выше) стоит после ответа матрицы. Свойство — msg.payload.output, два правила «==» (число): 1 и 2. Выход 1 ведёт к подписи экрана зала, выход 2 — к экрану председателя и к подписи кнопки («Вход → кнопка»). Ответ по выходу, которого нет среди правил, дальше не идёт, и подпись «Экран» остаётся прежней.

  • switch «Подтверждено?» перед ним проверяет msg.payload.ack, правило «равно true»: из двух ответов драйвера матрицы (команда отправлена и матрица ответила) нужен только второй.

  • switch «Нажата?» (блок E) смотрит на кнопку-переключатель: свойство msg.payload.value, два правила «==» (строка): pressed и default. Верхний выход — «включили», нижний — «выключили».

../../_images/flow-function-switch-answer.png

Цепочка примера: «Матрица: ответы» → switch «Подтверждено?» → switch «Какой выход?» → три change («Вход → название экрана», «Вход → название председателя», «Вход → кнопка»)

../../_images/flow-function-switch-mic.png

Цепочка примера: ui - switch → switch «Нажата?» → change «Микрофон: включить» и «Микрофон: выключить» → device - command

Во всех трёх стоит «остановка после первого совпадения». Подробно — в «Первой программе», блоки D и E. Как ответ устройства попадает в такой switch — на странице «Команды устройствам и ответы».

Что вы увидите. Сообщение выходит по выходу подошедшего правила; если не подошло ни одно правило, сообщение никуда не идёт. Чтобы проверить, подключите debug к нужному выходу.

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

  • В режиме «проверка всех правил» одно сообщение может уйти сразу на несколько выходов: если нужен ровно один, выберите «остановка после первого совпадения».

  • Правило «иначе» срабатывает, только если не подошло ни одно правило выше. Поставьте его последним.

  • Сравниваете число со строкой: проверьте тип значения рядом с правилом.

  • Ответ не доходит ни до одного выхода — свойство указано неверно (в отладке посмотрите, как называется нужное поле).

template: собрать текст или объект по шаблону

Зачем. Нужен текст или объект, в который вставлены значения из сообщения: «Звук: 70 %» или {"Mic_04_b": {"uiState": "pressed"}}. В шаблоне вы пишете готовую форму, а на место {{…}} узел подставляет значение. Один вход, один выход.

../../_images/node-template.png

Окно узла template «Кнопка: нажата»: 1 — «Имя», 2 — «Свойство», 3 — «Шаблон», 4 — «Подсветка синтаксиса», 5 — «Формат», 6 — «Вывести как»

Поля окна:

  1. «Имя» — подпись на вкладке. Рядом с полем есть кнопка библиотеки шаблонов; для работы по этой странице она не нужна.

  2. «Свойство» — куда записать результат. По умолчанию msg.payload.

  3. «Шаблон» — окно с текстом шаблона. Подстановки пишутся в двойных фигурных скобках: {{payload}}, {{topic}}, {{flow.имя}}, {{global.имя}}, {{payload.value}}.

  4. «Подсветка синтаксиса» — только оформление окна (JSON, HTML и другие), на результат не влияет.

  5. «Формат» — «Mustache шаблон» (подстановки работают) или «Простой текст» (шаблон записывается как есть).

  6. «Вывести как» — «Простой текст», «JSON» или «YAML»: в каком виде результат попадёт в свойство.

Пример на «Демо-зале». Ответ звукового процессора несёт имя подписки publishToken (она названа так же, как кнопка) и значение. Узлу api - helper - 2 нужен объект «имя элемента → состояние». Узел template «Кнопка: нажата» строит его из ответа: «Свойство» — msg.topic, «Формат» — «Mustache шаблон», «Вывести как» — «JSON», шаблон

{ "{{payload.publishToken}}": { "uiState": "pressed" } }

Второй такой узел, «Кнопка: обычная», отличается словом default вместо pressed. Один шаблон подходит для всех кнопок с mute: появилась новая подписка — программу менять не нужно (подробнее — «Команды устройствам и ответы»).

../../_images/flow-function-template.png

Цепочка примера: «Звук: уведомления» → switch «Чьё уведомление» → switch «Выключено?» → template «Кнопка: обычная» и «Кнопка: нажата» → «Кнопки по имени»

Ещё один template в «Демо-зале», «Зал: ползунок и тексты», подставляет {{payload.value}} в две надписи рядом с ползунком громкости.

Что вы увидите. В msg.topic лежит готовый объект, например {"Mic_04_b": {"uiState": "pressed"}}. Проверьте debug с выводом «весь msg объект сообщения».

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

  • «Формат» — «Простой текст»: {{…}} остаются буквальным текстом. Для подстановок нужен «Mustache шаблон».

  • «Вывести как» — «JSON», а шаблон — некорректный JSON (лишняя запятая, незакрытая скобка): результат не получится.

  • Подставляете поле, которого нет в сообщении: на его месте окажется пустота. Проверьте поле в отладке.

delay: пауза или ограничение скорости

Зачем. Устройствам нужно время: после подключения подождать, прежде чем подписываться; при сценарии из нескольких команд не слать их все разом. delay либо держит каждое сообщение заданное время, либо пропускает сообщения не чаще заданной скорости. Один вход, один выход.

../../_images/node-delay.png

Окно узла delay «Пауза 2 с» в режиме задержки: 1 — «Имя», 2 — «Действие», 3 — «Фиксированная задержка», 4 — «На … сек»

../../_images/node-delay-rate.png

Окно узла delay «Шаг в 0,4 с» в режиме ограничения скорости: 1 — «Имя», 2 — «Действие», 5 — «Все сообщения» и «Скорость … сообщений в … сек», 6 — выбор, что делать с лишними сообщениями

Поля окна (номера — как на снимках; в самом окне «Имя» стоит последним):

  1. «Имя» — подпись на вкладке: «Пауза 2 с».

  2. «Действие» — «Задержка каждого сообщения» (по умолчанию) или «Ограничение скорости».

  3. Для задержки — второй список под «Действием»: «Фиксированная задержка», «Случайная задержка» (между двумя значениями) или «Переопределять задержку с msg.delay» (время берётся из сообщения).

  4. «На … сек» — время; единицы: мсек, сек, мин, час, сут. Для случайной задержки — «Между … и …».

  5. Для ограничения скорости: «Все сообщения» или «Для каждого msg.topic», затем «Скорость … сообщений в … сек» (или мин, час, сут). Ниже есть отметка «allow msg.rate (in ms) to override rate»: с ней скорость берётся из msg.rate сообщения (в миллисекундах).

  6. Что делать с лишними сообщениями при ограничении: «Queue intermediate messages» (поставить в очередь), «без промежуточных сообщений» (отбросить) или «Send intermediate messages on 2nd output» (отправить на второй выход, он появляется только при этом выборе). Для режима «Для каждого msg.topic» ещё выбирается «Отправлять темы по очереди» или «Отправлять все темы».

Пример на учебных вкладках.

  • В «Первой программе» delay «Пауза 2 с» — «Задержка каждого сообщения», «Фиксированная задержка» на 2 секунды. Он стоит между сообщением «подключился» и подпиской: сразу после подключения связь ещё не готова принимать команды, и первая команда может потеряться (подробно — блок H «Первой программы»).

    ../../_images/flow-function-delay-pause.png

    Цепочка примера: switch «Подключился?» → delay «Пауза 2 с» → change «Подписка…» → device - command «Звук: подписаться»

  • В «Демо-зале» delay «Шаг в 0,4 с» работает как «Ограничение скорости»: одно сообщение в 0,4 секунды. Сценарий «Начало совещания» — список из многих шагов; delay отпускает их по одному, а не все разом.

    ../../_images/flow-sequence-parser-demo-steps.png

    Цепочка примера: link in «шаги» → split «По одному шагу» → delay «Шаг в 0,4 с» → change «Шаг → команда»

Что вы увидите. Сообщение выходит из узла не сразу: с паузой (режим задержки) или в порядке очереди (ограничение скорости). Для проверки подключите debug после delay.

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

  • Перепутали режимы: «Задержка каждого сообщения» держит каждое сообщение заданное время, а «Ограничение скорости» пропускает сообщения не чаще заданной скорости.

  • Очередь выросла больше 1000 сообщений: узел сообщает, что буфер превысил 1000 сообщений. Уменьшите поток сообщений или отбрасывайте лишние («без промежуточных сообщений»).

  • Нужна разная пауза для разных сообщений, а задана фиксированная: возьмите «Переопределять задержку с msg.delay» и запишите нужное время в сообщение узлом change.

Короткие узлы

Узлы с небольшим числом полей — у каждого свой раздел ниже. Все поля узла — во встроенной справке: откройте вкладку «справка» боковой панели (значок книги) и выберите узел.

Узел

Что делает

trigger

по входящему сообщению отправляет значение, ждёт и отправляет второе; может переотправлять значение по кругу

range

пересчитывает число из одного диапазона в другой

filter

пропускает сообщение, только если значение изменилось

цикл

повторяет часть программы заданное число раз, пока выполняется условие или для каждого элемента списка

calculator

считает одно значение: сумма, среднее, округление, остаток и другое

process - stat

выдаёт сведения о нагрузке на U-Logic

Узлы trigger, цикл, calculator и process - stat на учебных вкладках не использованы, поэтому их примеры собраны на отдельной вкладке: каждый узел стоит между inject и debug.

../../_images/flow-function-short-nodes.png

Цепочки примеров: inject «Нажатие» → trigger «Нажатие и автосброс» → debug «Что вышло»; inject «Старт цикла» → цикл «Три прохода» → два debug («Конец цикла», «Проход цикла»); inject «Число» → calculator «Прибавить 1» → debug «Результат»; inject «Спросить» → process - stat «Нагрузка» → debug «Сведения»

Узел scripter описан отдельно: «Скриптер».

trigger: «нажатие» и автосброс

Зачем. Нужно подать значение на короткое время и вернуть обратно: включить на 250 миллисекунд и выключить, послать «нажатие» и «отпускание». trigger по входящему сообщению отправляет первое значение, ждёт и отправляет второе; может и переотправлять значение по кругу. Один вход, один выход (второй выход появляется, если включить «отправить второе сообщение на отдельный выход»).

../../_images/node-trigger.png

Окно узла trigger «Нажатие и автосброс»: 1 — «Имя», 2 — «Отправить», 3 — «затем», 4 — «затем отправить», 5 — «Сбрасывать триггер, если», 6 — «Обрабатывать»

Поля окна (номера — как на снимке; в самом окне «Имя» стоит последним):

  1. «Имя» — подпись на вкладке.

  2. «Отправить» — первое значение и его тип (по умолчанию 1).

  3. «затем» — что делать после первого значения: «ждать сброс», «ждать» (по умолчанию 250 мсек; есть отметки «продлить при поступлении нового сообщения» и «заменить задержку через msg.delay») или «переотправлять его каждые».

  4. «затем отправить» — второе значение и его тип (по умолчанию 0); рядом отметка «отправить второе сообщение на отдельный выход».

  5. «Сбрасывать триггер, если» — какое сообщение сбрасывает ожидание: с msg.reset или с заданным msg.payload.

  6. «Обрабатывать» — «все сообщения» или «каждый msg.topic».

На учебных вкладках trigger не использован; цепочка примера — на снимке в начале раздела «Короткие узлы».

range: пересчитать число из одного диапазона в другой

Зачем. Ползунок и устройство измеряют величину в разных единицах: ползунок даёт 0…1, а устройству нужны децибелы −60…0. range пересчитывает число из входного диапазона в целевой. Работает только с числами. Один вход, один выход.

../../_images/node-range.png

Окно узла range «0…1 → дБ»: 1 — «Имя», 2 — «Действие», 3 — «Сопоставить входной диапазон … с целевым диапазоном …», 4 — «Округлять результат до ближайшего целого числа?», 5 — «Свойство»

Поля окна (номера — как на снимке; в самом окне «Свойство» стоит первым, а «Имя» — последним):

  1. «Имя» — подпись на вкладке.

  2. «Действие»: «Масштабировать msg-свойство»; «Масштабировать и ограничить целевым диапазоном»; «Масштабировать и обернуть в целевой диапазон»; «Scale, but drop msg if outside input range» (подпись английская).

  3. «Сопоставить входной диапазон от … до … с целевым диапазоном от … до …» — откуда и куда пересчитываем.

  4. «Округлять результат до ближайшего целого числа?» — отметка.

  5. «Свойство» — какое свойство сообщения пересчитывается.

Пример на «Демо-зале». range «0…1 → дБ» переводит значение payload.value из диапазона 0…1 в −60…0 с ограничением по краям и округлением до целого. Два других range («Зал: дБ → %», «ВКС: дБ → %») делают обратное: переводят −60…0 в 0…100 для ползунка.

../../_images/flow-function-range.png

Цепочка примера: ui - switch «Звук» → range «0…1 → дБ» → function «Элемент → команда звука» → device - command «Звук: команда» (остальные выходы «Звук» идут сразу в function)

filter: пропустить, только если значение изменилось

Зачем. Устройство опрашивают раз в несколько секунд, а реагировать нужно только тогда, когда ответ изменился. filter пропускает сообщение, только если значение изменилось (по умолчанию) или изменилось на заданную величину. Один вход, один выход. Подписи в окне английские, кроме «Свойство».

../../_images/node-filter.png

Окно узла filter «Звонок изменился?» в режиме «block if value change is greater or equal to»: 1 — «Name», 2 — «Mode», 3 — число и «compared to…», 4 — «Start value», 5 — «Свойство», 6 — «Apply mode separately for each topic»

Поля окна (номера — как на снимке; в самом окне «Name» стоит последним). Поля 3 и 4 показаны не всегда: в режиме по умолчанию их нет. Поле 3 появляется в режимах с порогом (все, кроме двух первых), поле 4 — только в режимах «block if value change…»; на снимке выбран один из них.

  1. «Name» — подпись на вкладке.

  2. «Mode» — когда пропускать: «block unless value changes» (по умолчанию: пропускать, только если значение изменилось), «block unless value changes (ignore initial value)», «block unless value change is greater or equal to», «block unless value change is greater than», «block if value change is greater or equal to», «block if value change is greater than».

  3. Число и список «compared to last valid output value» или «last input value» — порог изменения и то, с чем сравнивать: с последним пропущенным значением или с последним пришедшим.

  4. «Start value» — начальное значение для сравнения; если оставить поле пустым, берётся первое пришедшее значение.

  5. «Свойство» — какое свойство сообщения сравнивается.

  6. «Apply mode separately for each topic» — отметка: сравнивать отдельно по каждой теме msg.topic. В окне подпись обрезана до «…for each», под ней поле msg.topic.

Пример на «Демо-зале». filter «Звонок изменился?» проверяет payload.inCall. Кодек опрашивают раз в 5 секунд, а следующая ветка должна работать только тогда, когда звонок начался или закончился, а не при каждом одинаковом ответе.

../../_images/flow-function-filter.png

Цепочка примера: «Кодек: ответы» → filter «Звонок изменился?» → switch «Идёт звонок?» → два change («Идёт разговор», «Нет звонка»)

цикл: повторить часть программы

Зачем. Одно и то же нужно сделать несколько раз: отправить команду трём устройствам, пройти по списку элементов. цикл повторяет часть программы: заданное число раз, пока выполняется условие или для каждого элемента списка. Один вход, два выхода: 1 — «конец цикла», 2 — «проход цикла». Подпись по умолчанию «Цикл счетчика». Сообщение на входе с msg.command, равным break или restart, останавливает цикл или запускает его заново.

../../_images/node-cycle.png

Окно узла цикл «Три прохода» (тип «счетчик»): 1 — «Имя», 2 — «Тип», 3 — «Количество проходов», 4 — «Лимит времени», 5 — «Полезная нагрузка цикла», 6 — «Конечная нагрузка»

Поля окна (номера — как на снимке; поля «Начальное значение» и «Шаг» на снимке без стрелок):

  1. «Имя» — подпись на вкладке.

  2. «Тип»: «счетчик», «условие» или «перечисление» (от типа зависят следующие поля).

  3. Для счётчика — «Количество проходов», «Начальное значение» (по умолчанию 1), «Шаг» (по умолчанию 1). Для условия — «Условие» (JavaScript, JSONata или регулярное выражение) и «Проверять» — «до» или «после». Для перечисления — «Перечисление»: откуда брать список (msg., flow., global., JSON или строка).

  4. «Лимит времени» — в миллисекундах.

  5. «Полезная нагрузка цикла»: не изменять, исходная нагрузка, индекс (по умолчанию), значение или ключ.

  6. «Конечная нагрузка»: «последняя нагрузка» или «исходная нагрузка».

На учебных вкладках цикл не использован; цепочка примера — на снимке в начале раздела «Короткие узлы».

calculator: посчитать значение

Зачем. Нужно сложить, усреднить, округлить или найти остаток, не пользуясь выражением. calculator считает одно значение и записывает результат в выбранное свойство. Один вход, один выход. Подписи в окне английские. Подпись под узлом на вкладке — название выбранной операции, а пока она не выбрана — «Calculator».

../../_images/node-calculator.png

Окно узла calculator «Прибавить 1»: 1 — «Name», 2 — «Input field», 3 — «Output field», 4 — «Operation», 5 — «Constant», 6 — «Round result to N decimals»

Поля окна (номера — как на снимке; в самом окне «Name» стоит последним):

  1. «Name» — подпись на вкладке.

  2. «Input field» — откуда брать число (по умолчанию msg.payload).

  3. «Output field» — куда записать результат (по умолчанию msg.payload).

  4. «Operation» — что посчитать, например: Sum, Subtract, Multiply, Divide, Modulus (remainder), Average, Maximum, Minimum, Increment, Decrement, Absolute value, Random, Integer part (truncate), Round upwards, Round downwards, Nearest integer, Round decimal places, Truncate decimal places.

  5. «Constant» — число; на снимке для операции Sum стоит 1.

  6. Отметки «Round result to N decimals» и «Truncate result to N decimals» — округлить результат или отбросить лишние знаки после запятой; рядом с каждой — число знаков.

На учебных вкладках calculator не использован; цепочка примера — на снимке в начале раздела «Короткие узлы».

process - stat: нагрузка на программу

Зачем. Посмотреть, сколько ресурсов занимает U-Logic и как давно она работает. process - stat выдаёт сообщение со сведениями в msg.payload: memory (память), cpu (процессор) и uptime (время работы). Один вход, один выход.

На учебных вкладках process - stat не использован; цепочка примера — на снимке в начале раздела «Короткие узлы».

Для тех, кто программирует: function

Для новичка function не нужен: всё из раздела «Связь интерфейса с программой» делается узлами change и switch. Берите function, когда подготовка сообщения сложнее «взять по ключу»: проверка нескольких условий, выбор из нескольких источников, предупреждение пользователю вместо команды. В function вы пишете код на JavaScript, который получает сообщение msg, меняет его и возвращает.

../../_images/node-function.png

Окно узла function «Позвонить выбранному», вкладка «Функция»: 1 — «Имя», 2 — вкладка «Setup», 3 — вкладки кода, 4 — поле кода

Окно узла (номера — как на снимке):

  1. «Имя» — подпись на вкладке: опишите, что делает код.

  2. Вкладка «Setup» со значком шестерёнки — «Выходы» (по умолчанию 1), «Время ожидания» в секундах.

  3. Вкладки кода: «Настройка» — код, который выполняется один раз при запуске; «Функция» — код на каждое сообщение, открыта по умолчанию (в нём сначала стоит return msg;, то есть сообщение уходит дальше без изменений); «Закрытие» — код при остановке узла.

  4. Поле кода выбранной вкладки.

Что возвращать:

  • return msg; — отправить сообщение дальше;

  • return [a, b]; — отправить a на первый выход, b на второй (число выходов задаётся в «Setup»);

  • return null; — ничего не отправлять.

Если return забыт, дальше ничего не уйдёт.

Пример на «Демо-зале». Кнопка «Позвонить» выполнена двумя функциями. «Выбор строки → кому звоним» запоминает выбранную в списке строку в переменной вкладки (flow.set). «Позвонить выбранному» читает её (flow.get) и, если ничего не выбрано, предупреждает об этом вместо команды (подробнее — «Команды устройствам и ответы»).

../../_images/flow-function-function.png

Цепочка примера: ui - switch «ВКС» → function «Выбор строки → кому звоним» → «Кому звоним»; ui - switch «ВКС» → function «Позвонить выбранному» → device - command «Кодек: команда»

Советы. Дайте узлу понятное имя. В комментарии в начале кода напишите, что узел принимает и что выдаёт («вход / выход»). Если логика целиком состоит из кода, подумайте о скриптере: он собирает такую логику в одном узле.

Частые ошибки. Забыли return; вернули не msg, а число или текст (дальше по цепочке ожидается сообщение-объект); прочитали из flow. то, что записано в global..

Все возможности узла function — во встроенной справке.