Приложение F. Руководство по использованию функций API
Для обмена данными с протоколами не входящими в состав OrangeScada "из коробки", или при необходимости особенного
исполнения этих протоколов (например, опрос Modbus-устройств с удаленного коммутатора) можно воспользоваться встроенными
API-функциями. При помощи API возможен как обмен данными, так и полноценная настройка сети устройств: добавление,
редактирование, удаление узлов и оконечных устройств. Также возможно конфигурирование устройств при помощи свободно назначаемой
таблицы параметризации, синхронный опрос устройств по таймеру и асинхронная подписка по изменению.
Список и описание поддерживаемых API-функций
В таблице ниже приведен список API-функций универсального драйвера OrangeScada. Для подключения со стороны драйвера необходимо открыть
TCP-сокет с параметрами связи, указанными в меню приложения Настройки > Драйверы: порт, шифрование. Драйвер является инициатором соединения:
он первым отправляет команду на соединение с сервером после успешного выполнения которой сервер начинает коммуникацию. Обмен данными
осуществляется при помощи JSON-сериализированных пакетов с символом окончания строки '\n' в конце каждого.
В составе каждого JSON-объекта присутствует поле transID, содержащее номер транзакции. Для идентификации ответа на запрос сервера
необходимо указывать поле transID в объекте ответа с таким же значением, которое было сгенерировано сервером.
Для запросов, которые инициирует драйвер (connect и acyncTagsValues) значение transID генерируется драйвером произвольно. При
возникновении ошибки в объект ответа добавляются поля errorCode и errorTxt, содержащие соответственно код и текст ошибки.
Соединение с сервером
Запрос драйвер:
{"cmd":"connect", "uid":"MyDriver", "version":"1.2.3", "password":"password", "transID": tID}
cmd – Команда "connect"
uid – Уникальный идентификатор драйвера. Строка до 32 символов
version - Версия (не обязательно). Строка до 32 символов
password – Пароль (не обязательно). Строка до 32 символов. Должен совпадать с паролем в настройках драйвера Ответ сервер:
{"cmd":"connect", "errorCode":0, "errorTxt":"", "transID": tID}
errorCode – Код ошибки. При успешном соединении 0 или отсутствует это поле.
errorTxt – Текст ошибки. При успешном соединении отсутствует.
Пинг драйвера
Выполняется, если не происходило обмена данными в течение 10 сек.
Если в течение таймаута (1 минута) драйвер не отвечает, то соединение разрывается. Запрос сервер:
{"cmd":"pingDriver", "transID": tID} Ответ драйвер:
{"cmd":"pingDriver", "transID": tID}
Получение списка коммуникационных узлов
Сетевая модель драйвера может быть реализована как с использованием коммуникационных узлов: для случая, когда
у группы устройств есть общие параметры коммуникации, так и без использования коммуникационных узлов, когда устройства
содержат самодостаточный набор параметров коммуникации и иерархически не группируются в коммуникационный узел. Запрос сервер:
{"cmd":"getNodes", "transID": tID} Ответ драйвер:
{"cmd":"getNodes" , "transID": tID, "nodes":[{"uid":"nodeUid1","name":"nodeName1"}, .. {"uid":"nodeUidN","name":"nodeNameN"}]}
nodes - массив объектов с данными узлов
nodeUid1 .. nodeUidN - уникальные идентификаторы узлов
nodeName1 .. nodeNameN - названия узлов
Запрос сервер:
{"cmd":"getNode", "transID": tID, "uid":"uid1"}
uid - уникальный идентификатор узла. Если параметр uid отсутствует, то драйвер отдает шаблонный набор параметров для типового узла,
который можно использовать в мастере добавления нового узла Ответ драйвер:
{"cmd":"getNode", "name":"nodeName1", "transID": tID,
"options": [{"uid","optionUid1","name":"optionName1", "type": "number", "minValue": 1, "maxValue": 10, "currentValue":5} ..
{"uid":"optionUid2","name":"optionName3", "type":"select", "selectValues":[{"value":"value1","name":"valueName1"}, ..
{"value":"valueN","name":"valueNameN"}], "currentValue":"value1"}]}
name – название узла
options – настройки узла, массив объектов с опциями
name – название опции
uid – идентификатор опции
type – тип опции: bool – логический, number – число, varchar – строка, select – список
minValue, maxValue – для типа "number" минимальное и максимальное значение (необязательно)
selectValues - для типа "select" массив объектов возможных значений/названий списка выбора {value: значение, name: название}
currentValue – текущее значение опции
Сохранить настройки узла
Запрос сервер:
{"cmd":"setNode", "transID": tID, "uid":"nodeUid1", "name":"nodeName1", "options":[{"uid1","value1"}..{"uidN":"valueN"}]}
uid – идентификатор узла
name – название узла
options – массив с объектами опций {uid: идентификатор опции, value: значение опции} Ответ драйвер:
{"cmd":"setNode", "transID": tID}
Добавить узел
Запрос сервер:
{"cmd":"addNode", "transID": tID, "name":"nodeName1","options":[{"uid1","value1"}..{"uidN":"valueN"}]}
name – название узла
options – массив с объектами опций {uid: идентификатор опции, value: значение опции} Ответ драйвер:
{"cmd":"addNode", "transID": tID, "uid":"uid1"}
uid - идентификатор нового узла
Запрос сервер:
{"cmd":"getDevices", "transID": tID, "nodeUid":"nodeUid1"}
nodeUid - идентификатор узла, список устройств которого требуется вернуть. При отсутствии параметра возвращается полный список
устройств драйвера. Ответ драйвер:
{"cmd":"getDevices", "transID": tID, "devices":[{"name":"deviceName1", "uid":"deviceUid1", "nodeUid":"nodeUid1"} ..
{"name":"deviceNameN", "uid":"deviceUidN", "nodeUid":"nodeUidN"}]}
devices – массив объектов устройств
{uid: уникальный идентификатор устройства в пределах драйвера,
name: название,
nodeUid: идентификатор узла, содержащего устройство(может отсутствовать, если сетевая модель предполагает отсутствие узлов)}
Пинг устройства
Проверка статуса связи с устройством Запрос сервер:
{"cmd":"pingDevice", "transID": tID, "uid":"deviceUid1"}
uid - уникальный идентификатор устройства Ответ драйвер:
{"cmd":"pingDevice", "transID": tID, "active": true/false}
Получение настроек устройства
Запрос сервер:
{"cmd":"getDevice", "transID": tID, "uid":"uid1"}
uid - уникальный идентификатор устройства. Если параметр uid отсутствует, то драйвер отдает шаблонный набор параметров для типового устройства,
который можно использовать в мастере добавления нового устройства Ответ драйвер:
{"cmd":"getDevice", "name":"deviceName1", "transID": tID,
"options": [{"uid","optionUid1","name":"optionName1", "type": "number", "minValue": 1, "maxValue": 10, "currentValue":5} ..
{"uid":"optionUid2","name":"optionName3", "type":"select", "selectValues":[{"value":"value1","name":"valueName1"}, ..
{"value":"valueN","name":"valueNameN"}], "currentValue":"value1"}]}
name – название устройства
options – настройки устройства, массив объектов с опциями
name – название опции
uid – идентификатор опции
type – тип опции: bool – логический, number – число, varchar – строка, select – список
minValue, maxValue – для типа "number" минимальное и максимальное значение (необязательно)
selectValues - для типа "select" массив объектов возможных значений/названий списка выбора {value: значение, name: название}
currentValue – текущее значение опции
Сохранить настройки устройства
Запрос сервер:
{"cmd":"setDevice", "transID": tID, "uid":"deviceUid1", "nodeUid":"nodeUid1", "name":"deviceName1", "options":
[{"optionUid1":"value1"}..{ "optionUidN":"valueN"}]}
uid – идентификатор устройства
nodeUid – идентификатор узла (необязательно)
name – название устройства
options – массив с объектами опций {uid: идентификатор опции, value: значение опции} Ответ драйвер:
{"cmd":"setDevice", "transID": tID}
Добавить устройство
Запрос сервер:
{"cmd":"addDevice", "transID": tID, "nodeUid":"nodeUid1", "name":"deviceName1", "options":
[{"optionUid1":"value1"}…{ "optionUidN":" valueN"}]}
nodeUid – идентификатор узла (необязательно)
name – название устройства
options – массив с объектами опций {uid: идентификатор опции, value: значение опции} Ответ драйвер:
{"cmd":"addDevice", "transID": tID, "uid":"uid1"}
uid - идентификатор нового устройства
Запрос сервер:
{"cmd":"getTags", "transID": tID, "deviceUid":"deviceUid1", "isOptions":true}
deviceUid – Идентификатор устройства
isOptions – получить настройки тегов, если isOptions = false, то драйвер не отдает поле options Ответ драйвер:
{"cmd":"getTags", "transID": tID, "tags": [{"name":"tagName1", "uid":"tagUid1", "address":1, "type":"int", "read": true, "write": true,
options:{"optionUid1": "value1".. "optionUidN": "valueN"}}..{}]}
Драйвер возвращает массив объектов:
name – название тега
uid – уникальный идентификатор тега в пределах устройства
address – адрес, используется для сортировки тега в списке (необязательно, по умолчанию 0)
type – тип переменной: bool – логический false/true (0/1), int – целое число, float – дробное число,
datetime – дата/время (количество мс от 01.01.1970), string - строка
read – разрешение на чтение переменной (по умолчанию true)
write – разрешение на запись переменной (по умолчанию true)
options – настройки: объект {"название опции": "значение"}
Получение настроек тега
Запрос сервер:
{"cmd":"getTag", "transID": tID, "deviceUid":"deviceUid1", "uid":"tagUid1"}
deviceUid – идентификатор устройства
uid - уникальный идентификатор тега. Если параметр uid отсутствует, то драйвер отдает шаблонный набор параметров для типового тега,
который можно использовать в мастере добавления нового тега Ответ драйвер:
{"cmd":"getTag", "transID": tID, "name":"tagName1", "address":1, "type":"int", "read": true, "write": true,
"options": [{"uid":"optionUid1","name":"optionName1", "type": "number", "minValue": 1, "maxValue": 10, "currentValue":"value"} ..
{"uid":"optionUid2","name":"optionName2", "type":"select", "values":[{"value":"value1","name":"name1"} .. {"value":"valueN","name":"nameN"}]}
address – адрес, используемый для сортировки тегов в списке
type – тип переменной: bool – логический false/true (0/1), int – целое число,
float – дробное число, datetime – дата/время (количество мс от 01.01.1970), string - строка
read – разрешение на чтение переменной (по умолчанию true)
write – разрешение на запись переменной (по умолчанию true)
options – настройки тега, массив объектов с опциями
name – название опции
uid – идентификатор опции
type – тип опции: bool – логический, number – число, varchar – строка, select – список
minValue, maxValue – для типа "number" минимальное и максимальное значение (необязательно)
selectValues - для типа "select" массив объектов возможных значений/названий списка выбора {value: значение, name: название}
currentValue – текущее значение опции
Сохранить настройки тега
Запрос сервер:
{"cmd":"setTag", "transID": tID, "deviceUid":"deviceUid1" ,"uid":"tagUid1", "name":"tagName1", "address":1, "type":"int",
"read": true, "write": true, "options":[{"uid1":"value1"}..{"uidN":"valueN"}]}
deviceUid – идентификатор устройства
uid – идентификатор тега
name – название тега
address – адрес, используемый для сортировки тегов в списке
type – тип переменной: bool – логический false/true (0/1), int – целое число,
float – дробное число, datetime – дата/время (количество мс от 01.01.1970), string - строка
read – разрешение на чтение переменной (false/true)
write – разрешение на запись переменной (false/true)
options – настройки тега, массив объектов {"идентификатор настройки":"значение"} с опциями Ответ драйвер:
{"cmd":"setTag", "transID": tID}
Добавить тег
Запрос сервер:
{"cmd":"addTag", "transID": tID, "deviceUid":"deviceUid1", "name":"tagName1", "address":1, "type":"int", "read": true, "write": true,
"options":[ {"uid1":"value1"}..{"uidN":"valueN"}]}
deviceUid – идентификатор устройства
name – название тега
address – адрес, используемый для сортировки тегов в списке
type – тип переменной: bool – логический false/true (0/1), int – целое число,
float – дробное число, datetime – дата/время (количество мс от 01.01.1970), string - строка
read – разрешение на чтение переменной (false/true)
write – разрешение на запись переменной (false/true)
options – настройки тега, массив объектов {"идентификатор настройки":"значение"} с опциями Ответ драйвер:
{"cmd":"addTag", "transID": tID, "uid":"uid1"}
uid - идентификатор нового тега
Синхронный режим предполагает выполнение сервером периодических запросов на каждый из которых
драйвер возвращает текущие значения тегов. В асинхронном режиме (см. ниже) сервер выполняет подписку на
нужные ему теги, при изменении которых драйвер присылает пакет данных автоматически. Запрос сервер:
{"cmd":"getTagsValues", "transID": tID, "deviceUid":"deviceUid1", "tags": ["tagUid1".. "tagUidN"]}
deviceUid – идентификатор устройства
tags – массив идентификаторов тегов Ответ драйвер:
{"cmd":"getTagsValues", "transID": tID, "values": ["tagValue1".."tagValueN"]}
values - массив со значениями запрошенных тегов, значения идут строго в том порядке в котором они были в запросе сервера,
если значение тега не удалось получить от оконечного оборудования, возвращается null
Чтение значения тегов в асинхронном режиме (подписка)
В асинхронном режиме сервер выполняет подписку на нужные ему теги, при изменении которых драйвер присылает пакет данных автоматически.
Для изменения списка подписанных тегов необходимо выполнить запрос еще раз: предыдущая подписка отменяется. Для анулирования всей подписки
необходимо прислать запрос с пустым массивом tags Запрос сервер:
{"cmd": "setTagsSubscribe", "transID": tID, "deviceUid": "deviceUid1", "tags":["tagUid1".. "tagUidN"]}
deviceUid – идентификатор устройства
tags – массив идентификаторов тегов Ответ драйвер:
{"cmd": "setTagsSubscribe", "transID": tID}
Чтение значения тегов в асинхронном режиме (сработка по изменению)
При изменении значения тегов на которые сервер выполнил подписку, драйвер автоматически высылает серверу запрос Запрос драйвер:
{"cmd":"acyncTagsValues", "transID": tID, "deviceUid":"deviceUid1", "values":
{"uid1":4,"uid2":7, "uid3": true, "uid4": null, ... ,"uidN": "stringValue"}}
deviceUid – идентификатор устройства
values – массив объектов {"идентификатор тега":"значение"}
Значение transID драйвер генерирует самостоятельно Ответ сервер:
{"cmd": "acyncTagsValues", "transID": tID}
Запись значения тегов
Запрос сервер:
{"cmd":"setTagsValues", "transID": tID, "deviceUid":"deviceUid1", "tags": [{"uid1":"value1"}.. "uidN":"valueN"}]}
deviceUid – идентификатор устройства
tags – массив объектов {"идентификатор тега":"значение для записи"} Ответ драйвер:
{"cmd": "setTagsValues", "transID": tID}
Пример реализации
В качестве примера работы с API в состав OrangeSCADA включены исходники на языке nodejs, которые Вы можете найти в папке APIExamples:
driver.js
Модуль, содержащий основные функции для работы с конфигурацией устройств и коммуникационных узлов:
добавление, удаление, редактирование. При использовании в своих проектах этот модуль можно использовать без изменений.
driverConfig.json
Файл с конфигурацией параметров для узлов и устройств, описание дерева устройств. Этот файл нужно адаптировать
под собственные параметры: секция driver для настроек соединения, секция optionsScheme для описания схемы шаблонных параметров для узлов(nodes),
устройств(devices) и тегов(tags). Секции, которые идут ниже описывают непосредственно структуру устройств и могут меняются при помощи
API-запросов. Nodes содержит текущие узлы и их параметры. Devices - текущие устройства, их принадлежность к nodes (параметр nodeUid).
Если nodeUid не указан, то устройство не принадлежит никакому узлу.
Tags, вложенные в devices описывают принадлежащие устройству теги и их параметры.
modbusTCPDriver.js
Файл, реализующий детали работы конкретного драйвера. В качестве примера приведена реализация драйвера
modbus TCP. При разработке собственного драйвера этот код нужно переработать. Методы, необходимые к реализации описаны в таблице ниже.
Перечень методов, необходимых к реализации в модуле драйвера (CustomDriver)
constructor
Конструктор класса. Входные параметры: deviceList - объект со списками узлов и устройств; subscribeHandler -
ссылка на метод обработки асинхронного изменения тега; getConfigHandler - ссылка на метод чтения конфигурации
(для драйверов, поддерживающих автоопределение списка тегов); setConfigHandler -
ссылка на метод записи конфигурации (для драйверов, поддерживающих автоопределение списка тегов)
getTagsValues
Метод для синхронного опроса значений тегов. Входные параметры: dataObj - объект, содержащий список тегов,
значения которых требуется обновить
setTagsValues
Метод для синхронной записи значений тегов. Входные параметры: dataObj - объект, содержащий список тегов,
и присваиваемых им значений
updateSubscribe
Метод вызывается при обновлении списка подписанных на изменение тегов
updateTagListFromDevice
Метод для автообновления списка тегов (если драйвер это позволяет)