Общее описание

Документ описывает сервер для автономного сбора данных с устройств IoT и управления этими устройствами, а также протокол взаимодействия с IoT сервером через доступные для управления каналы связи.

Конфигурационный файл сервера

Настройки сервера хранятся в конфигурационном ini-файле /etc/wliotproxyd.ini. При установке в конфигурационном файле присутствует описание всех параметров. Дополнительно используется файл /var/lib/wliotproxyd/devices.ini, но его ручное редактирование не обязательно.

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

  1. Локальный UNIX-сокет "/tmp/wliotproxyd"

  2. Tcp порт 4083 с поддержкой ssl шифрования. При подключении по tcp обязательна аутентификация с ключем, указанным в файле.

Описание протокола

Протокол взаимодействия между устройствами на шине практически полностью основан на протоколе взаимодействия с единичным устройством. Для организации взаимодействия устройств на шине дополнительно вводятся следующие правила:

  1. Аргументы каждого сообщения-команды от клиента к серверу начинаются с идентификаторы вызова — числа, которое сервер также указывает в начале аргументов ответного сообщения, в том числе в сообщениях ok, err и cmdata. В сообщениях, не предполагающих ответа, таких как info или уведомления от сервера клиенту, идентификатор вызова не указывается.

Базовые типы сообщений

  1. Информационное сообщение. Заголовок — info. Предназначено для передачи информации, не требующей специальной обработки (например, отладочная информация) и предназначенной для передачи ее человеку. Аргументы сообщения — текстовые строки, содержащие информацию, предназначенную для прочтения человеком.

  2. Сообщение с данными для клиента (или от клиента). Заголовок — cmdata. Первый аргумент всегда — идентификатор вызова, в описании конкретных команд ниже по тексту опущен. Предназначено для передачи данных между клиентом и сервером при обработке команд.

Команды серверу

Общее

  1. Команда аутентификации. Заголовок — authenticate. Параметры — имя пользователя и пароль. Команда необходима для подключения к удаленному серверу по tcp.

  2. Идентификация сервера. Заголовок — identify. Сервер возвращает уникальный идентификатор в формате UUID и свое имя.

Управление устройствами

  1. Перечисление всех имеющихся в системе TTY устройств. Заголовок — list_tty. Аргументы отсутствуют. Список устройств передается на клиент сообщениями cmdata, содержащими следующие аргументы: имя порта, серийный номер, производитель, usb vendor id (число), usb product id (число). Если устройство идентифицировано, дополнительно передаются два аргумента — идентификатор и имя устройства.

  2. Идентификация TTY устройства. Заголовок — indentify_tty. Аргумент — имя порта. В случае успешной идентификации клиенту в ответ возвращаются идентификатор устройства, имя устройства и опционально идентификатор типа устройства (в ответном ok сообщении)

  3. Идентификация TCP устройства. Заголовок — indentify_tcp. Аргумент — IP адрес или имя хоста. В случае успешной идентификации клиенту в ответ возвращаются идентификатор устройства, имя устройства и опционально идентификатор типа устройства (в ответном ok сообщении).

  4. Перечисление идентифицированных устройств. Заголовок — list_identified. Аргументы отсутствуют. На клиент передаются сообщения cmdata со следующими аргументами: идентификатор устройства, имя устройства, идентификатор типа устройства, порт или сетевой адрес устройства.

  5. Перечисление датчиков устройства. Заголовок — list_sensors. Агрумент — идентификатор или имя устройства. Список портов передается на клиент в ответном ok сообщении, содержащим аргумент — xml описание сенсоров.

  6. Запрос описания интерфейса управления. Заголовок — list_controls. Агрумент — идентификатор или имя устройства. Описание интерфейса управления передается на клиент в ответном ok сообщении, содержащим аргумент — xml описание интерфейса управления.

  7. Отправка команды устройству. Заголовок — exec_command. Аргументы — идентификатор или имя устройства, команда, далее аргументы команды. В случае ожидания возвращаемого значения на клиент в аргументах сообщения ok будут переданы аргументы, возвращенные устройством.

  8. Управление конфигурацией устройств. Заголовок — devices_config. Содержит вложенные команды. Управление конфигурацией устройств подробно описано ниже. Конфигурация устройств определяет, какие устройства сервер будет обнаруживать и идентифицировать самостоятельно при запуске.

  9. Запрос идентификатора устройства. Заголовок — device_id. Аргумент — идентификатор или имя устройства. Сервер ищет устройство в списке идентифицированных устройств или в базе хранилищ и возвращает его идентификатор. Если устройство не найдено или найдено несколько с одинаковым именем, возвращается ошибка. Эта команда позволяет получить

 

Управление конфигурацией устройств

Управление конфигурацией устройств на сервере производится с помощью сообщения с заголовком devices_config. Аргументы сообщения содержат вложенную команду и ее собственные аргументы. Пример:

"devices_config|get_tty_by_port_name\n"

Ниже приведено описание доступных команд.

  1. Запрос списка фильтров tty устройств по имени порта. Команда — get_tty_by_port_name. Аргументы отсутствуют. Возвращает список фильтров по имени tty порта в виде регулярных выражений UNIX, разделенных запятой. Пример:
    "ttyACM*,ttyUSB0,ttyUSB2,ttyS0"

  2. Установка списка фильтров tty устройств по имени порта. Команда — set_tty_by_port_name. Аргумент — список фильтров по имени tty порта в виде регулярных выражений UNIX, разделенных запятой.

  3. Запрос списка фильтров tty устройств по VIP и PID USB устройства (для преобразователей USB-COM). Команда — get_tty_by_vid_pid. Аргументы отсутствуют. Возвращает список фильтров по VID и PID USB устройства, разделенных запятой. Каждый фильтр — пара VID:PID или только VID, все в нижнем регистре. Пример:
    "
    1111:2222,3333,4444:5555"

  4. Установка списка фильтров tty устройств по VIP и PID USB устройства. Команда — set_tty_by_vid_pid. Аргумент — список фильтров фильтров по VID и PID USB устройства, разделенных запятой.

  5. Запрос списка адресов tcp устройств. Команда — get_tcp_by_address. Аргументы отсутствуют. Возвращает список адресов tcp устройств (IP-адрес или DNS имя хоста), разделенных запятой. Пример:
    "
    192.168.1.1,example.com"

  6. Установка списка адресов tcp устройств. Команда — set_tcp_by_address. Аргумент — список адресов tcp устройств (IP-адрес или DNS имя хоста), разделенных запятой.

  7. Включение/выключение автоматического поиска устройств в локальной сети. Команда set_detect_tcp_devices. Аргумент — true|false или 1|0. Если "true" или "1" — сервер регулярно рассылает в сеть широковещательные запросы, устройства определяют адрес сервера и подключаются к нему.

 

Управление хранилищами для данных сенсоров

  1. Перечисление хранилищ. Заголовок — list_storages. Аргументы отсутствуют. Список хранилищ передается на клиент сообщениями cmdata, содержащими следующие аргументы:

    1. идентификатор устройства

    2. имя устройства

    3. имя датчика

    4. тип значений датчика

    5. атрибуты датчика в виде "key1=value1;key2=value2"

    6. тип хранилища (continuous, auto_sessions, last_n_values,memory)

    7. правило преобразования временной метки (dont_touch, add_gt, drop_time)

    8. тип хранимых значений (зависит от правила преобразования временной метки)

  2. Добавление датчика в базу. Заголовок — add_storage. Аргументы: идентификатор или имя устройства, название датчика, тип хранилища (continuous, auto_sessions, last_n_values, memory), правило преобразования временной метки (dont_touch, add_global_time, drop_time). Для хранилища типа last_n_values и memory дополнительно передается параметр N — число хранимых значений. При создании хранилища устройство с датчиком должно быть подключено и идентифицировано.

  3. Удаление сенсора из базы. Заголовок — remove_storage. Аргументы: идентификатор или имя устройства, название датчика.

  4. Привязка сенсора к внешнему IoT сервису. Заголовок — storage_add_data_export. Аргументы: имя или идентификатор устройства, название датчика, название сервиса. Далее идут параметры для сервиса в формате ключ:значение. Если параметры отсутствуют, привязка удаляется.

  5. Запрос привязки сенсора к внешнему IoT сервису. Заголовок — storage_get_data_export. Аргументы: имя или идентификатор устройства, название датчика, название сервиса. Если хранилище привязано к внешнему сервису, возвращаются параметры в формате ключ:значение, в противном случае возвращается ошибка.

  6. Запрос списка внешних сервисов, в которые экспортируются данные из хранилища. Заголовок — storage_get_data_export_list. Возвращается список названий сервисов.

  7. Запрос списка доступных внешних сервисов для экспорта. Заголовок — available_data_export_services. Возвращается список названий сервисов.

  8. Установка и получение атрибута хранилища. Заголовки — storage_get_attr, storage_set_attr. Аргументы: имя или идентификатор устройства, название датчика, название атрибута, значение атрибута (для set). Get возвращает значение атрибута.

  9. Перечисление сессий для сессионного хранилища. Заголовок — session_list. Аргументы — идентификатор или имя устройства и название датчика. Список сессий передается сообщениями cmdata, содержащими два параметра — идентификатор и название сессии.

  10. Перечисление атрибутов сессии для сессионного хранилища. Заголовок — session_list_attrs. Аргументы — идентификатор или имя устройства, название датчика и идентификатор сессии. Список атрибутов сессий передается сообщениями cmdata, содержащими два параметра — ключ и значение атрибута.

  11. Получения атрибута сессии для сессионного хранилища. Заголовок — session_get_attr. Аргументы — идентификатор или имя устройства, название датчика, идентификатор сессии и название атрибута. В ответ возвращается значение атрибута.

  12. Установка атрибута сессии для сессионного хранилища. Заголовок — session_set_attr. Аргументы — идентификатор или имя устройства, название датчика, идентификатор сессии, название атрибута и значение атрибута. Значение атрибута опционально, если отсутствует — атрибут удаляется.

  13. Создание новой сесии. Заголовок — session_create. Аргументы — идентификатор или имя устройства, название датчика и название сессии. В ответ возвращается идентификатор созданной сессии.

  14. Запуск ручной сессии. Заголовок — session_start. Аргументы — идентификатор или имя устройства, название датчика и идентификатор сессии. Сессия открывается на запись и начинается сбор данных.

  15. Остановка ручной сессии. Заголовок — session_stop. Аргументы — идентификатор или имя устройства и название датчика. Останавливает открытую для записи сессию.

  16. Удаление сессии. Заголовок — session_remove. Аргументы — идентификатор или имя устройства, название датчика и идентификатор сессии.

  17. Продолжение ручной сессии. Заголовок — session_continue. Аргументы — идентификатор или имя устройства, название датчика и идентификатор сессии. Открывает для дальнейшей записи ранее созданную сессию.

  18. Запрос идентификатора открытой для записи сессии. Заголовок — session_get_write_id. Аргументы — идентификатор или имя устройства и название датчика. Если есть открытая для записи сессия, возвращает ее идентификатор.

Обработка данных

  1. Перечисление списка javascript-программ. Заголовок — js_list. Возвращает список javascript-файлов на стороне сервера.

  2. Остановка, запуск и перезапуск javascript-программы для обработки данных. Заголовки — js_start, js_stop и js_restart. Аргумент — имя файла скрипта (с расширением .js).

  3. Запрос количества данных в локальном хранилище. Заголовок — get_samples_count. Аргументы — идентификатор или имя устройства, имя датчика, для сессионного хранилища дополнительно идентификатор сессии. Возвращается количество отсчетов в хранилище.

  4. Запрос данных из локального хранилища. Заголовок — get_samples. Аргументы — идентификатор устройства, имя датчика, для сессионного хранилища дополнительно идентификатор сессии, начальный индекс (начинается с 0), количество отсчетов. Дополнительный аргумент — шаг (для прореживания данных, может отсутствовать). Отсчеты возвращаются в сообщениях cmdata, по одному отсчету на сообщение. Данные передаются в том же формате, как и в сообщениях от устройства (meas).

  5. Запрос данных из локального хранилища в бинарном. Заголовок — get_samples_bin. Аргументы — идентификатор устройства, имя датчика, для сессионного хранилища дополнительно идентификатор сессии, начальный индекс (начинается с 0), количество отсчетов. Дополнительный аргумент — шаг (для прореживания данных, может отсутствовать). Отсчеты возвращаются в сообщениях cmdata, по одному отсчету на сообщение. Данные передаются в том же формате, как и в сообщениях от устройства (measb).

  6. "Подключение" виртуального устройства. Заголовок — register_virtual_device. Аргументы — идентификатор устройства, имя устройства и опционально идентификатор типа устройства.

  7. Подписка/отписка на данные от датчика из хранилища. Заголовки — subscribe/unsubscribe. Аргументы — идентификатор или имя устройства и название датчика. Если клиент подписан на датчик из хранилища, то появлении нового измерения в хранилище клиенту будет передано сообщение meas, содержащее идентификатор устройства, название датчика и значение в том же формате, как и от устройства.

Уведомления от сервера клиенту

  1. Идентификация устройства. Заголовок — device_identified. Аргументы — идентификатор устройства, имя устройства, опционально идентификатор типа устройства.

  2. Отключение устройства. Заголовок — device_lost. Аргумент — идентификатор устройства.

  3. Добавление хранилища для датчика — storage_created. Агрументы:

    1. идентификатор устройства

    2. имя устройства

    3. имя датчика

    4. тип значений датчика

    5. ограничения значений в виде "key1=value1;key2=value2"

    6. тип хранилища (continuous, auto_sessions, last_n_values,memory)

    7. правило преобразования временной метки (dont_touch, add_gt, drop_time)

    8. тип хранимых значений (зависит от правила преобразования временной метки)

  4. Удаление хранилища для датчика — storage_removed. Агрументы — идентификатор устройства и название датчика.

  5. Изменение состояния устройства — statechanged. Аргументы аналогичны аргументам сообщения statechanged от устройства серверу (см. описание протокола взаимодействия между устройствами), но в начале добавлен идентификатор устройства.

  6. Уведомление о необходимости перезагрузить список устройств и хранилищ. Заголовок — reload_devices_and_storages. Сообщает о необходимости перезагрузить список устройств и хранилищ на стороне клиента, например, при изменении политики доступа к устройствам.

  7. Синхронизация виртуального устройства. Для виртуальных устройств, зарегистрированных клиентом, сервер регулярно передает сообщение vdev_sync, в ответ клиент должен в течении 4 секунд вернуть сообщение syncr. Аргумент обоих сообщений — идентификатор виртуального устройства.

Обработка сообщений для виртуальных устройств

Когда клиент регистрирует виртуальное устройство на сервере, необходимо передавать клиенту сообщения, предназначенные для виртуального устройства, и получать от него сообщения, "исходящие" от виртуального устройства. Для этого сообщения (такие же, как для обычных устройств), "упаковываются" в сообщение с заголовком vdev. Например, в случае выполнения команды на обычном устройстве сервер использует сообщение

call|1|command\n

и получает в ответ сообщение

ok|1\n

Для виртуального устройства сервер пошлет клиенту сообщение

vdev|{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}|call|1|command\n

и получит в ответ

vdev|{xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx}|ok|1\n

Широковещательные уведомления устройствам

Если в настройках сервера включено автоматическое обнаружение устройств в IP сетях, то сервер будет регулярно рассылать широковещательное сообщение через UDP порт 4081. Заголовок сообщения — server_ready, аргументы — идентификатор и имя сервера.

Поддерживаемые внешние IoT сервисы

Название сервиса

Описание

Параметры

iotkit-agent

Сервис для интернета вещей от Intel (https://github.com/enableiot/iotkit-agent)

sensor_name — имя сенсора для программы iotkit-agent, под которым будут передаваться данные

alterozoom

IoT сервис Alterozoom

email — user email in Alterozoom (use wliotproxy-alterozoom-auth util to authentificate user and get token to send data)

thingspeak

ThingSpeak service (https://thingspeak.com)

api_key — write api key for a channel (see https://www.mathworks.com/help/thingspeak/writedata.html)

 

Обработка данных на языке javascript

Скрипты для обработки данных располагаются в директории "/var/lib/wliotproxyd/js_data_processing". Каждый скрипт выполняется независимо. Внутри скрипта доступна по-умолчанию стандартная математическая библиотека и набор дополнительных объектов, описанный ниже. Так же для отладки можно использовать метод Console.log().

Объект script

Глобальный объект скрипта, аналог window в браузерных скриптах.

Свойства:

Объект script.SensorsDatabase

Объект, предоставляющий доступ к базе хранилищ датчиков.

Методы

Сигналы

Объект Devices

Объект, предоставляющий доступ к управлению устройствами.

Методы

Сигналы

Объект Storage

Объект, предоставляющий доступ к хранилищу данных датчика

Методы

Сигналы

Дополнительные методы для сессионных хранилищ

//TODO

Объект Device

Объект, предоставляющий доступ к подключенным устройствам

Методы

Сигналы

Объект VirtualDevice

Объект, позволяющий организовать виртуальное устройство, управляемое из скрипта. Является наследником Device.

Методы

Сигналы

Объект SensorValue

Свойства