Создание обработчика

Для создания нового обработчика перейдите на вкладку Обработчики. Добавьте обработчик, нажав на плюсик.

Заполните следующие поля:

  • имя — наименование обработчика;
  • описание — подробная характеристика обработчика, заполняется при необходимости;
  • параметры по умолчанию — поведение обработчика при получении пакета данных, в котором нет нужных входных аргументов:
    • брать последнее присланное значение — в качестве значений недостающих в пакете параметров будет подставлено последнее полученное значение по этим параметрам.
      Например, в обработчике вы рассчитываете эффективную температуру на базе двух входных значений: температура и влажность, однако они приходят не в одном пакете, а в разных, последовательно. Тогда при получении только температуры обработчик сам возьмет последнее полученное значение влажности для расчета, и наоборот.
    • заменять на «null» — в качестве значений недостающих в пакете параметров будет подставлен “null”.

Например, в обработчике вы рассчитываете среднее значение скорости на базе последних десяти значений. Однако скорость вы получаете не в каждом пакете. Если вы выберете режим “брать последнее присланное значение”, то при получении пакета без скорости обработчик возьмет последнее значение скорости и проведет для него расчет. Вы получите некорректную выходную величину. Если же вы выберете режим “заменять на “null”, то такую ситуацию вы можете обработать и не проводить расчет:

if (speed === null) {
   return {};
 }

Нажмите кнопку Создать. Перед вами откроется готовый шаблон с небольшим кодом для расчета суммы двух входных значений. Используйте его в качестве наглядного примера того, каким образом может быть реализован обработчик.

1 — Сохранить: Сохранить изменения обработчика. Если ранее обработчик был запущен на объектах, он продолжит работать уже в обновленной версии

2 — Тестировать: Открыть окно тестирования, в котором можно ввести входные параметры и проверить получившиеся выходные значения

3 — Download .js: Экспортировать обработчик в файл формата JSON

4 — В данной части комментария указывается дополнительное описание обработчика

5 — В данной части комментария указывается логин автора обработчика

6 — В данной части комментария указываются входные аргументы в следующем формате

* @param {<тип данных>} <имя> <описание>

Пример:

* @param {string} rawData input data in base64 format

7 — В круглых скобках указываются имена входных аргументов в следующем формате

function process(rawData)

8 — Код обработчика, работающий с входными аргументами по заданному алгоритму

9 — В фигурных скобках после слова return указываются имена выходных аргументов в следующем формате

return {<аргумент 1>, <...>, <аргумент n>};

Пример:

return {time, hypotenuse};

Подсказка: Входных и выходных аргументов может быть несколько.

Встроенные библиотеки и модули

Обработчики поддерживают стандарт ECMAScript вплоть до версии языка ES2019. Также в них имеются все стандартные объекты JavaScript:

Посмотрите на пример использования некоторых встроенных стандартных библиотек. Работа с ними производится без подключения каких-либо дополнительных модулей.

Во время проектирования процесса обработки данных и создания обработчика у вас может возникнуть потребность в подключении и использовании вспомогательных функций. Помимо стандартных библиотек в архитектурный слой обработки данных добавлен объект ric, включающий в себя дополнительные методы:

  • генерация событий;
  • декодирование Base64;
  • организация локального хранилища.
declare var ric: {
 events: {
   gen<T>(event: string, payload?: T): void;
 };
 base64: {
   decode(payload: string): DataView;
 };
 localStore: {
   forObject: RicLocalStore;
   forHandler: RicLocalStore;
 };
};
 
type RicLocalStore<U = unknown> = {
 initWith<T = U>(initial: T): RicLocalStore<T>;
 reduce<T = U>(reducer: (prev: T) => T, initial?: T): T;
};
Генерация событий

Следующий код обработчика позволяет генерировать событие при срабатывании указанного критерия для суммы двух входных параметров.

/**
* @param {number} a sample param 1
* @param {number} b sample param 2
*/
function process(a, b) {
 const sum = a + b;
 
 if (sum > 25) {
   ric.events.gen("model-event-01", { sum });
 }
 
 return { sum };
}
Декодирование Base64

Следующий код обработчика позволяет получить параметры { lat, lon } из восьмибайтного буфера. ric.base64.decode принимает строку Base64 и возвращает JavaScript DataView.

/**
* Parse { lat, lon } params from binary
*
* ```       
*   +----------+----------+
*   |   lat    |   lon    |
*   +----------+----------+
*   | 32bit be | 32bit be |
*   | ieee 754 | ieee 754 |
*   +----------+----------+
* ```
* @param {string} payload base64 encoded bytes
*/
function process(payload) {
 const buf = ric.base64.decode(payload);
 return {
   lat: buf.getFloat32(0 * 32/8),
   lon: buf.getFloat32(1 * 32/8),
 };
}
 
// test Ql8Z6EIWn/M=
Локальное хранилище

Если вам нужно работать с параметрами устройства, которые приходили от него в прошлых пакетах, вы можете сохранять их в локальное хранилище и затем использовать. Следующий код обработчика позволяет хранить последние десять полученных параметров и возвращать их количество, сумму и среднее значение.

/**
* Calc average of last 10 a's
*
* @param {number} a sample param
*/
function process(a = 0) {
 /* init local store with default values (if empty)
  * and reduce it with fresh values */
 const { counter, last10 } = ric.localStore
   .forObject
   .initWith({
     counter: 0,
     last10: [a],
   })
   .reduce((prev) => ({
     counter: prev.counter + 1,
     last10: [...prev.last10, a].slice(-10),
   }));
 
 /* calc sum and avg of last 10 values */
 const sum = last10.reduce((acc, val) => acc + val, 0);
 const avg = sum / last10.length;
 
 return {
   counter,
   sum,
   avg,
 };
}

Подсказка: При разработке большого и сложного кода пользуйтесь дополнительными возможностями, список которых можно открыть, кликнув правой кнопкой мыши в области кода обработчика. Например, там есть функция автоформатирования кода.