Создание обработчика
Для создания нового обработчика перейдите на вкладку Обработчики. Добавьте обработчик, нажав на плюсик.
Заполните следующие поля:
-
имя — наименование обработчика;
-
описание — подробная характеристика обработчика, заполняется при необходимости;
-
параметры по умолчанию — поведение обработчика при получении пакета данных, в котором нет нужных входных аргументов:
-
брать последнее присланное значение — в качестве значений недостающих в пакете параметров будет подставлено последнее полученное значение по этим параметрам.
Например, в обработчике вы рассчитываете эффективную температуру на базе двух входных значений: температура и влажность, однако они приходят не в одном пакете, а в разных, последовательно. Тогда при получении только температуры обработчик сам возьмет последнее полученное значение влажности для расчета, и наоборот. -
заменять на “null” — в качестве значений недостающих в пакете параметров будет подставлен “null”. Например, в обработчике вы рассчитываете среднее значение скорости на базе последних десяти значений. Однако скорость вы получаете не в каждом пакете. Если вы выберете режим “брать последнее присланное значение”, то при получении пакета без скорости обработчик возьмет последнее значение скорости и проведет для него расчет. Вы получите некорректную выходную величину. Если же вы выберете режим “заменять на “null”, то такую ситуацию вы можете обработать и не проводить расчет:
if (speed === null) { return {}; }
-
Нажмите кнопку Создать. Перед вами откроется готовый шаблон с небольшим кодом для расчета суммы двух входных значений. Используйте его в качестве наглядного примера того, каким образом может быть реализован обработчик.
- Сохранить: Сохранить изменения обработчика. Если ранее обработчик был запущен на объектах, он продолжит работать уже в обновленной версии
- Тестировать: Открыть окно тестирования, в котором можно ввести входные параметры и проверить получившиеся выходные значения
- Download .js: Экспортировать обработчик в файл формата JSON
- В данной части комментария указывается дополнительное описание обработчика
- В данной части комментария указывается логин автора обработчика
- В данной части комментария указываются входные параметры в следующем формате
* @param {<тип_данных>} <имя> <описание>
Пример:
* @param {string} rawData input data in base64 format
- В круглых скобках указываются имена входных параметров в следующем формате
function process(параметр_1, параметр_2, ..., параметр_n)
Пример:
function process(rawData)
-
Код обработчика, работающий с входными параметрами по заданному алгоритму
-
В фигурных скобках после слова return указываются имена выходных параметров в следующем формате
return {параметр_1, параметр_2, ..., параметр_n};
Пример:
return { time, hypotenuse };
Подсказка: Входных и выходных параметров может быть несколько.
Встроенные библиотеки и модули
Обработчики поддерживают стандарт ECMAScript вплоть до версии языка ES2019. Также в них имеются все стандартные объекты JavaScript:
- JSON (opens in a new tab)
- Date (opens in a new tab)
- Math (opens in a new tab)
- и другие (opens in a new tab)
Посмотрите на пример использования некоторых встроенных стандартных библиотек. Работа с ними производится без подключения каких-либо дополнительных модулей.
Во время проектирования процесса обработки данных и создания обработчика у вас может возникнуть потребность в подключении и использовании вспомогательных функций. Помимо стандартных библиотек в архитектурный слой обработки данных добавлен объект ric, включающий в себя дополнительные методы:
- генерация событий;
- декодирование Base64;
- организация локального хранилища.
Генерация событий
Следующий код обработчика позволяет генерировать событие при срабатывании указанного критерия для суммы двух входных параметров.
/**
* @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 (opens in a new tab).
/**
* 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),
lon: buf.getFloat32(4),
};
}
// 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,
};
}
При разработке большого и сложного кода пользуйтесь дополнительными возможностями, список которых можно открыть, кликнув правой кнопкой мыши в области кода обработчика. Например, там есть функция автоформатирования кода.
Сторонние библиотеки и модули
Помимо использования уже встроенных возможностей обработчиков, вы можете подключить сторонние библиотеки по ссылке. Сама библиотека должна быть написана на языке JavaScript и соответствовать спецификации ESM (EcmaScript modules) (opens in a new tab).
Ограничения на подключаемые библиотеки:
-
максимальный размер библиотеки — 65 Кбайт;
-
в коде должны использоваться только стандартные объекты JavaScript (opens in a new tab). Если библиотека использует какие-то расширенные API (например, Buffer из Node.js), или их встроенные модули (например, fs, path), или браузерные API (fetch, WebSocket), то она не заработает.
В случае нарушения ограничений обработчик не будет сохранен.
Для импорта из npm уже имеющихся библиотек можно воспользоваться сервисами:
Подключение Javascript модуля
В качестве примера возьмем с GitHub простой Javascript модуль (opens in a new tab), который считает сумму двух чисел
export function sum(a, b) {
return a + b;
}
Подсказка: Можно использовать не только GitHub репозиторий, но и любые другие интернет-адреса, по которым доступно содержимое необходимого для импорта модуля.
Следующий код обработчика позволяет суммировать два числа при помощи использования импортированной функции из модуля.
import { sum } from "https://raw.githubusercontent.com/rightech/ric-examples/master/handlers/lib/example.js";
function process(a, b) {
const res = sum(a, b);
return { sum: res };
}
Важно: Обратите внимание, что при импорте модулей с GitHub репозитория необходимо использовать их “raw” версию, т.к. иначе сервер GitHub будет отдавать HTML страницу для просмотра, а не само содержимое файла. Для получения нужного адреса ссылки нажмите кнопку Raw в интерфейсе GitHub.
Подсказка: Если вас смущает, что слово process при подключении сторонних библиотек становится бледным, добавьте слово export перед словом function.
Подключение библиотеки из npm
В качестве примера возьмем пакет gps (opens in a new tab) c сервиса Skypack (opens in a new tab).
Следующий код обработчика позволяет разбирать строку, полученную в формате NMEA, и извлекать из нее координаты.
import GPS from "https://cdn.skypack.dev/gps@0.6.1";
function process(nmea) {
const gps = new GPS();
let lat = 0;
let lon = 0;
gps.on("data", (parsed) => {
lat = parsed.lat;
lon = parsed.lon;
});
gps.update(nmea);
return { lat, lon };
}
Подсказка: Загрузка и импорт кода библиотеки происходит в момент сохранения обработчика, поэтому желательно сразу указывать её рабочую версию для избежания проблем, связанных с обновлением импортируемого пакета.