Wb-mqtt-serial templates: различия между версиями

Материал из Wiren Board
м (A.Degtyarev переименовал страницу Драйвер wb-mqtt-serial:Примеры написания шаблонов в Wb-mqtt-serial templates без оставления перенаправления: Часть переводимой страницы Драйвер wb-mqtt-serial:Примеры написания шаблонов.)
м (Обновил статью, требует правок)
Строка 1: Строка 1:
<languages/>
{{DISPLAYTITLE: Драйвер wb-mqtt-serial: шаблоны}}
== Описание ==
<translate>
Использование шаблонов позволяет один раз описать устройство и использовать созданное описание для любого числа устройств на одном или нескольких serial-портах.
=== Опрос устройства Modbus вручную перед написанием шаблона ===
Перед тем как писать шаблон, нужно вручную проверить, что устройство правильно подключено, и с него удаётся получить данные. Для этого потребуется документация на устройство, включающая его параметры последовательного порта (скорость, чётность, количество стоп-бит) и список его Modbus-регистров с описанием их возможных значений. После этого нужно подключить устройство и, используя эту информацию, попробовать вручную получить из него данные с помощью утилиты [[Modbus-client | modbus_client]].


=== Общая структура шаблона устройства === <!--T:1-->
Предустановленные шаблоны находятся в папке <code>/usr/share/wb-mqtt-serial/templates</code>.


<!--T:2-->
Пользовательские шаблоны для [[Wb-mqtt-serial driver | wb-mqtt-serial]] версии 2.6.3 и выше рекомендуем хранить в папке <code>/etc/wb-mqtt-serial.conf.d/templates</code>, более ранних версий используйте путь по умолчанию. В каждом файле, размещенном в папке <code>templates</code> находится описание одного типа устройств.
Файл шаблона устройств представляет собой структуру [https://ru.wikipedia.org/wiki/JSON JSON], описывающую параметры устройства. Шаблон допускает наличие комментариев.
JSON-структура записывается внутри пространства между открывающей и закрывающей фигурной скобкой: <code>{ ... }</code>.


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


<!--T:3-->
Подключите устройство к контроллеру и прочитайте значение одного из его modbus-регистров. Описание адресов modbus-регистров и параметры подключения можно найти в документации на подключаемое устройство, а для чтения информации из устройства можно использовать утилиту [[Modbus-client | modbus_client]].
Общая структура шаблона устройства выглядит следующим образом:
 
<syntaxhighlight lang="JSON">
== Базовая структура шаблона ==
//Шаблон устройства
 
<syntaxhighlight lang="javascript">
{  
{  
"device": {
"device": {
Строка 21: Строка 20:
     "Параметр 2 устройства":"значение",  
     "Параметр 2 устройства":"значение",  
     ...
     ...
     "channels": [ {Параметры канала 1}, {Параметры канала 2}, ...]
 
    "setup": [
        // секция инициализации устройства
        ...
    ]
     "channels": [  
        {
            Параметры канала 1
            },  
        {
            Параметры канала 2
            },
        ...
        ]
     }
     }
}</syntaxhighlight>
}
 
</syntaxhighlight>
<!--T:4-->
Здесь '''device''' — устройство, подключаемое к контроллеру, '''канал''' — источник данных: обычно Modbus-регистр с описанием типа данных, частоты опроса, преобразования значений и проч.
Подробное описание смотрите в следующих разделах. Файлы шаблонов, поставляемые в составе пакета, хранятся на контроллере в директории <pre>/usr/share/wb-mqtt-serial/templates</pre>
Для версий '''wb-mqtt-serial''', начиная с '''2.6.3''', шаблоны, созданные вами для нового устройства, следует сохранять в директорию <pre>/etc/wb-mqtt-serial.conf.d/templates</pre>
Для более старых версий  - в <code>/usr/share/wb-mqtt-serial/templates</code>.


В наших шаблонах мы используем отступы по 4 пробела на уровень, что обеспечивает удобочитаемость кода шаблона, и рекомендуем писать новые шаблоны с такими же отступами.
В наших шаблонах мы используем отступы по 4 пробела на уровень, что обеспечивает хорошую читаемость кода. Новые шаблоны мы рекомендуем создавать с такими же отступами.


=== Параметры устройства (device) === <!--T:5-->
=== Параметры устройства (device) ===
В начале шаблона задаются параметры устройства в виде набора пар ''ключ:значение''.
В начале шаблона задаются параметры устройства в виде набора пар ключ:значение.
Обязательными параметрами являются ключи "device_type" и "device".


<!--T:7-->
* device_type — тип устройства, строка.
Ключ '''device_type''' задает уникальное название типа устройства в виде строки, например:
* name — отображаемое имя устройства. Публикуется как <code>.../meta/name</code> в MQTT.
<syntaxhighlight lang="JSON">"device_type":"WB-MAP12H", </syntaxhighlight>.
* id — уникальный идентификатор устройства в MQTT. Каждый элемент в <code>devices</code> должен иметь уникальный id.
* slave_id — идентификатор устройства. Если не задан — используется широковещательный запрос.
* enabled — включает или выключает опрос устройства. Доступные значения: ''true'', ''false''. По умолчанию — ''true''.
* protocol — протокол передачи данных, если не указан — используется modbus. Возможные варианты:
**modbus,
**uniel,
**milur,
**mercury230,
**ivtm,
**s2k,
**modbus_io,
**pulsar,
**mercury200,
**lls,
**neva,
**energomera_iec.
* max_reg_hole — максимальное количество считываемых «пустых» регистров. Параметр поддерживается только modbus-устройствами.
* max_bit_hole — аналог max_reg_hole для битовых регистров: ''coils'' и ''discrete inputs''.
* max_read_registers — максимальное количество регистров в одной пакетной операции чтения.
* poll_interval —  минимальный интервал опроса регистров данного устройства в миллисекундах.
* response_timeout_ms — максимальное время ответа устройства в миллисекундах
* frame_timeout_ms — минимально необходимая задержка между посылками в миллисекундах.
* guard_interval_us — дополнительная задержка перед каждой отправкой данных в порт в микросекундах.
* device_timeout_ms — интервал, по истечении которого (а также ''device_max_fail_cycles'') устройство будет помечено отключенным и будет опрашиваться в ограниченном режиме.
* device_max_fail_cycles — количество неудачных циклов опроса устройства.
* password — пароль для доступа к устройству, массив байт.
* access_level — уровень доступа при опросе устройства.
* channels — список каналов устройств, задается в виде массива <code>[...]</code>, каждый из элементов которого — это описание отдельного канала. Подробнее читайте ниже.


<!--T:8-->
Обязательно нужно указать параметры ''device_type'' и ''device''. Остальные параметры можно опустить, в этом случае будут подставлены значения по умолчанию.
Значение ключа '''device''' — составная структура, описывающее конкретные параметры устройства:


<!--T:9-->
Изменять параметры устройства можно и в веб-интерфейсе, для этого найдите нужное устройство и откройте свойства объекта '''Device''' → '''Properties'''.
<syntaxhighlight lang="JSON">
"device": {
        "name": "WB-MAP12H",
        "id": "wb-map12h",
        "channels": [...]
        }</syntaxhighlight>


=== Каналы устройства (channels) ===


<!--T:10-->
Структура:
* '''name''' — отображаемое имя устройства. Публикуется как <code> .../meta/name в mqtt</code>. Имя устройства используется при отображении web-интерфейсе, хранится в топике <code>"id" + " " + "slave_id"</code>. Пример для устройства с modbus-адресом 5 (slave_id) и значением <code>"name":"WB-MAP12H (basic)"</code> <code>/devices/wb-map12h_5/meta/name WB-MAP12H (basic)</code>.
<syntaxhighlight lang="javascript">
 
<!--T:11-->
* '''id''' — уникальный идентификатор устройства в MQTT. Каждый элемент в devices должен иметь уникальный id. mqtt-topic'и, относящиеся в MQTT к данному устройству, имеют общий префикс /devices/<идентификатор топика>/... Также по умолчанию берется из шаблона с добавлением slave_id: <code>"id" + "_" + slave_id</code>
<!--* '''slave_id''' — Modbus-адрес устройства. Задается в виде <code>"slave_id" : slaveID,</code>. Необязательный параметр для шаблона, slave_id задается при конкурировании устройства и уже с этим параметром включается в конфигурационный файл <cоde>/etc/wb-mqtt-serial.conf</cоde>.-->
 
<!--T:12-->
* '''channels''' — список каналов устройств, задается в виде массива <code>[...]</code>, каждый из элементов которого представляет описание отдельного канала.
 
<!--T:13-->
Остальные параметры устройства либо добавляются в раздел при включении шаблона в общую конфигурацию wb-mqtt-serial, либо используются значения по умолчанию. Полный список можно найти в [https://github.com/wirenboard/wb-mqtt-serial/blob/master/README.md примере конфигурационного файла]. В онлайн редакторе смотрите свойства объекта <code>"device" -> "properties"</code>.
 
=== Каналы устройства === <!--T:14-->
Описание канала представляет собой структуру
 
<!--T:15-->
<syntaxhighlight lang="JSON">
"channels": [
"channels": [
         {
         {
Строка 84: Строка 95:
</syntaxhighlight>
</syntaxhighlight>


<!--T:16-->
Структура содержит набор полей:
Структура содержит следующий набор полей.
* name — уникальное для устройства имя канала.
* id — имя MQTT контрола для канала, публикуется как <code>/devices/<идентификатор устройства>/controls/<ID канала></code> Если не задан, то используется значение ''name''.
* enabled — включает или выключает опрос канала. Доступные значения: ''true'', ''false''. По умолчанию — ''true''.
* reg_type — тип modbus-регистра. Возможные значения:
** coil,
** discrete,
** holding,
** holding_single,
** holding_multi,
** input,
** direct.
* address — адрес регистра.
* type — тип контрола: виртуального элемента для представления данных в веб-интерфейсе контроллера.
* format — тип переменной, описывающей значение.
* word_order — порядок 16-битных слов для каналов, имеющих размер больше 16 бит. Доступные значения:
** big_endian — <code>[0xAA 0xBB] [0xCC 0xDD] => 0xAABBCCDD</code>. Значение по умолчанию.
** little_endian — <code>[0xAA 0xBB] [0xCC 0xDD] => 0xCCDDAABB</code>.
* poll_interval — минимальный интервал опроса регистра в миллисекундах.
* unsupported_value — значение, получаемое при последовательном чтении диапазона регистров, если устройство не поддерживает запрашиваемый регистр. Используется некоторыми протоколами для определения доступности регистров устройства.
* max — максимальное значение регистра, используется для построения. Используется в веб-интерфейсе.
* scale — коэффициент, на который умножается значение регистра перед публикацией в MQTT.
* offset — значение, которое прибавляется к значению регистра перед публикацией в MQTT.
* round_to — порядок, до которого будет округляться значение после всех преобразований. Например, <code>0.1</code> — округлять до десятых.
* readonly —  установка флага запрешает изменение значения в веб-интерфейсе или по MQTT. Возможные значения: ''true'', ''false''. По умолчанию — '''false'''.
* on_value — значение, которое будет записано в регистр, при записи единицы в mqtt-топик канала.
* error_value — полученное из устройства значение регистра, обозначающее ошибку.


<!--T:17-->
Обязательно нужно указать поля ''name'', ''reg_type'', ''address'' и ''type''. Остальные параметры можно опустить, в этом случае будут подставлены значения по умолчанию.
[[File:Vartype_properties_mqtt_serial.png|450px|thumb|right|формат представления данных в Modbus-регистрах, описывается в wb-mqtt-serial.schema.json (подготовлено в [http://www.bodurov.com/JsonFormatter/ Collapsible JSON Formatter])]]


<!--T:18-->
==== Доступные типы контролов (type) ====
* '''name''' имя канала, уникальное для устройство имя канала
* atmospheric_pressure атмосферное давление, millibar (100 Pa).
* '''reg_type''' тип Modbus-регистра, одно из "coil", "discrete", "holding", "holding_single", "holding_multi", "input", "direct"
* concentration концентрация, ppm.
* '''address''' адрес Modbus-регистра, связанного с каналом.
* current — ток, отображается как value.
* '''type''' тип контрола -- виртуального элемента для представления данных в Web-интерфейсе контроллера: "switch", "pushbutton", "range", "rgb" и другие; полностью перечислены в схеме wb-mqtt-serial.schema.json.
* dimmer — диммер, отображается как value.
* '''readonly''' "true", если значения можно только считывать.
* heat_energy — тепловая энергия, Gcal.
* '''format''' тип переменной, описывающей значение, см. рис.
* heat_power — расход тепловой энергии, Gcal/h.
* lux — освещенность.
* power — мощность, W.
* power_consumption энергопотребление, kWh.
* pressure давление, bar
* pushbutton — кнопка.
* rainfall — осадки, mm/h.
* range — ползунок.
* rel_humidity — влажность, %, RH.
* resistance — сопротивление, Ohm.
* rgb — rgb.
* sound_level — уровень звука.
* switch — переключатель положений ON/OFF.
* temperature — температура, °C.
* text — текстовая строка.
* value неформатированное значение.
* voltage — напряжение, V.
* water_consumption потребление воды, m<sup>3</sup>.
* water_flow — поток воды m<sup>3</sup>/h
* wind_speed — скорость ветра, m/s.
* wo-switch — переключатель положений ON/OFF.
==== Доступные типы переменных (format) ====
* s16 — Signed 16-bit integer.
* u16 — Unsigned 16-bit integer.
* s8 — Signed 8-bit integer.
* u8 — Unsigned 8-bit integer.
* s24 — Signed 24-bit integer.
* u24 — Unsigned 24-bit integer.
* s32 — Signed 32-bit integer.
* u32 — Unsigned 32-bit integer.
* s64 — Signed 64-bit integer.
* u64 — Unsigned 64-bit integer.
* bcd8 — 8-bit BCD.
* bcd16 — 16-bit BCD.
* bcd24 — 24-bit BCD.
* bcd32 — 32-bit BCD.
* float — IEEE754 32-bit float.
* double — IEEE754 64-bit float (double).
* char8 — 8-bit ASCII char.


<!--T:19-->
=== Секция инициализации (setup-секция) ===
В простейшем случае достаточно полей "name", "reg_type", "address" и "type". Описания остальных типов параметров полностью перечислены в [https://github.com/wirenboard/wb-mqtt-serial/blob/master/README.md примере конфигурационного файла].
Секция инициализации содержит перечень параметров, которые передаются устройству при перезапуске <code>wb-mqtt-serial</code> или при восстановлении связи с устройством.  


=== Примеры шаблонов устройств === <!--T:20-->
В шаблоне можно перечислить параметры и задать их значения по умолчанию. Пользователь может изменять значения параметров в веб-интерфейсе.


<!--T:21-->
Важно! Чтение параметров из устройства не предусмотрено.
Ниже приведены примеры файлов шаблонов для некоторых устройств Wiren Board, охватывающие основной список используемых параметров при создании шаблонов.


<!--T:22-->
В секции доступны параметры:
----
* title — наименование параметра, будет отображен в веб-интерфейсе.
* address — адрес регистра, в который нужно записать параметр.
* enum — массив числовых значений, которые можно записать в регистр.
* enum_titles — массив текстовых описаний значений, указанных в ''enum''.
* default — значение по умолчанию. Записывается в регистр, если пользователь не выбрал свое.
* value — фиксированное значение. Если у регистра указать фиксированное значение, то пользователь не сможет его изменить через веб-интерфейс.


==== WB-MS-THLS v.2 ==== <!--T:23-->
Значения ''address'', ''enum'', ''value'' и ''default'' можно указывать в десятичной или шестнадцатеричной системе счисления.


<!--T:24-->
Пример setup-секции:
Устройство [[WB-MS_Modbus_Sensor|WB-MS-THLS]] — универсальный комбинированный Modbus-датчик температуры, влажности, освещённости и звукового давления. Устройство предоставляет доступ к данным через input-регистры Modbus. Первоначальные настройки устройства записаны в holding-регистры, но не используются для получения данных и управления устройством, поэтому в шаблон не входят.
<syntaxhighlight lang="javascript">
По ссылке "Expand" можно увидеть полный код шаблона.
"setup": [
    {
        "title": "s12",
        "address": 20000,
        "value": "0xfff2"
    },   
    {
        "title": "Sound value",
        "address": 0x00,
        "default": 0x0a,
        "min": 0,
        "max": 100       
    },
    {
        "title": "Fan mode",
        "address": 3,
        "enum": [ 0, 1, 2, 4 ],        
        "enum_titles": [
          "off",  
          "slow",
          "middle",  
          "fast"
        ],              
        "default": 1
    }
]
</syntaxhighlight>
 
=== Вложенные устройства (subdevices) ===
В секции ''subdevices'' можно описать вложенные устройства, которые могут иметь свои setup-секции и каналы.


<!--T:25-->
Для каждого канала можно указать, что это вложенное устройство и задать список вложенных устройств, которые поддерживает канал.
<div class="mw-collapsible mw-collapsed"  style="width:500px; overflow: hidden;" >
 
<syntaxhighlight lang="JSON" highlight="6,7,14-16">
Адреса регистров вложенных устройств расчитываются как <code>base + shift + address + stride * register_size</code>, где:
* base — адрес начала секции регистров родительского канала;
* shift — смещение относительно родительсокго канала;
* address — адрес, заданный в описании регистра;
* stride — номер шага, заданный в настройках канала;
* register_size — размер регистра.
 
Пример описания вложенных устройств:
 
<syntaxhighlight lang="javascript">
{
{
     "device_type": "WB-MS-THLS v.2",
    // Название типа устройства, оно указывается в поле device_type в файле настроек
     "device_type": "Device type name",
 
    // Название типа устройства, которое будет отображаться в онлайн-конфигураторе.
    // Необязательный параметр. Если не указан, используется device_type.
    "title": "Device",
 
     "device": {
     "device": {
         "name": "WB-MS / WB-MSW",
         // отображаемое имя устройства. Публикуется как
         "id": "wb-ms-thls-v2",
        // .../meta/name в MQTT
        "name": "New device",
       
        // Остальные параметры устройства описанные ранее, кроме slave_id
        ...
 
        // список каналов устройства
        "channels": [
            // Пример канала, описывающий данные одного регистра
            {
                "name": "Temperature",
                "reg_type": "input",
                "format": "s32",
                "address": "0x0504"
            },
 
            // Канал - вложенное устройство
            {
                "name": "Sub",
                "device_type": "subdevice1"
            },
 
            // Канал - вложенное устройство.
            // В интерфейсе веб-интерфейса будет предложен выбор конкретного типа
            {
                "name": "Sub2",
               
                // Список типов вложенных устройств, которые можно выбрать для канала
                "oneOf": [ "subdevice1", "subdevice2" ],
 
                // Устройство, выбранное по умолчанию
                "device_type": "subdevice1",
 
                // Смещение регистров канала относительно родительского канала
                "shift": 100,
 
                // Номер шага регистров
                "stride": 1
            }
        ],
        // Список вложенных устройств
        "subdevices": [
            {
                // Имя вложенного устройства,
                // которое будет использоваться в поле device_type канала
                "device_type": "subdevice1",
 
                // Название вложенного устройства,
                // которое будет отображаться в онлайн-конфигураторе.
                // Необязательный параметр. Если не указан, используется device_type.
                "title": "Sub1",
 
                "device": {
                    "channels": [
                        // Вложенные устройства могут иметь свои каналы
                        {
                            "name": "c11",
                            "reg_type": "input",
                            "format": "s32",
                            "address": "0x0501"
                        },
 
                        // Вложенные устройства также могут иметь
                        // каналы с вложенными устройствами
                        {
                            "name": "c2",
                            "device_type": "subdevice2"
                        }
                    ]
                }
            },
            {
                "device_type": "subdevice2",
                "device": {
                    // Вложенные устройства могут иметь
                    // собственную секцию с настройками
                    "setup": [
                        {
                            "title": "s12",
                            "address": 20000,
                            "value": "0xfff2"
                        },
 
                        // Если конкретное значение настройки не задано, то его можно
                        // задать в файле конфигурации или через веб-интерфейс
                        {
                            "title": "s22",
                            "address": 9992,
 
                            // Список возможных значений
                            "enum": [1, 2, 3],
 
                            // Надписи в списке выбора в веб-интерфейсе
                            "enum_titles": ["one", "two", "three" ],
 
                            // Минимально возможное значение
                            "min": 1,
 
                            // Максимально возможное значение
                            "max": 3
                        }
                    ],
                    "channels": [
                        {
                            "name": "c2",
                            "device_type": "subdevice2"
                        }
                    ]
                }
            }
        ]
    }
}
</syntaxhighlight>
 
== Примеры шаблонов ==
 
Хорошим источником примеров могут служить [[#Описание | предустановленные шаблоны]] драйвера wb-mqtt-serial.
 
Ниже мы рассмотрим несколько примеров подробнее.
 
=== WB-MSW3 ===
Датчик [[WB-MSW v.3 | WB-MSW3]] в базовой комплектации может измерять температуру и влажность. Еще мы можем получить из датчика величину напряжения питания, серийный номер и управлять встроенной пищалкой.
 
Пример шаблона:
<syntaxhighlight lang="javascript">
{
    "device_type": "WB-MSW v.3 (base)",
    "device": {
        "name": "WB-MSW v.3",
         "id": "wb-msw-v3",
         "max_read_registers": 0,
         "max_read_registers": 0,
         "response_timeout_ms": 1,
         "response_timeout_ms": 1,
        "frame_timeout_ms": 12,
         "channels": [
         "channels": [
             {
             {
Строка 142: Строка 395:
                 "scale": 0.1,
                 "scale": 0.1,
                 "error_value": "0xFFFF"
                 "error_value": "0xFFFF"
            },
            {
                "name": "Illuminance",
                "reg_type": "input",
                "address": 2,
                "type": "lux"
            },
            {
                "name": "Sound Level",
                "reg_type": "input",
                "address": 3,
                "scale": 0.01,
                "type": "sound_level"
             },
             },
             {
             {
Строка 164: Строка 404:
             },
             },
             {
             {
                 "name": "External Sensor 1",
                 "name": "Serial",
                 "type": "temperature",
                 "type": "text",
                 "reg_type": "input",
                 "reg_type": "input",
                 "address": "6",
                 "address": 270,
                 "format": "s16",
                 "format": "u32"
                "scale": 0.0625,
                "error_value": "0x7FFF"
             },
             },
             {
             {
                 "name": "External Sensor 2",
                 "name": "Buzzer",
                 "type": "temperature",
                 "type": "switch",
                 "reg_type": "input",
                 "reg_type": "coil",
                 "address": "7",
                 "address": 0
                "format": "s16",
                "scale": 0.0625,
                "error_value": "0x7FFF"
             }
             }
         ]
         ]
     }
     }
}
}
</syntaxhighlight>
</div>
<!--T:26-->
В настройках устройства интересен параметр <syntaxhighlight lang="JSON">    "max_read_registers": 0,</syntaxhighlight> Этот параметр описывает максимальное количество регистров, считываемых с устройства при запросе. Значение по умолчанию — 1, в нашем случае мы указываем считывать все регистры за один проход (bulk read).
Параметр <code>response_timeout_ms</code> задаёт время ожидания ответа от устройства в миллисекундах. Если в течение этого времени ответ не будет получен, будет продолжен опрос других регистров и устройств.
В настройках канала "Temperature" имеются три параметра, на которые стоит обратить внимание:
<syntaxhighlight lang="JSON">
    "format": "s16",
    "scale": 0.1,
    "error_value": "0x7FFF"
</syntaxhighlight>
</syntaxhighlight>
Параметр '''"format": "s16"''' указывает на то, что число в регистрах представлено в виде знакового 16-битного целого, '''"scale": 0.1''' — говорит о том, что полученное из регистров значение следует домножить на коэффициент масштабирования 0,1 для получения значения температуры, а параметр '''"error_value": "0x7FFF"''' задает значение, получаемое из регистра, указывающее на то, что при опросе датчика произошла ошибка. Такой параметр будет выделен красным цветом в Web-интерфейсе контроллера. Применять такой параметр следует, если вы знаете, какое значение выдает ваше устройство в случае ошибки.


<!--T:27-->
Описание параметров смотрите в [[#Базовая структура шаблона | описании базовой структуры шаблона]].
----


==== WB-MRGBW-D ==== <!--T:28-->
=== WB-MRGBW-D ===
Устройство [[WB-MRGBW-D|WB-MRGBW-D]] — четырехканальный диммер для управления светодиодными лентами. Может управлять лентой RGB+W либо независимо четырьмя одноцветными лентами.  
Устройство [[WB-MRGBW-D|WB-MRGBW-D]] — четырехканальный диммер для управления светодиодными лентами. Может управлять лентой RGB+W либо независимо четырьмя одноцветными лентами.  
Настройки яркости хранятся в holding-регистрах; шаблон описывает, какие регистры можно менять для получения нужной яркости каналов, отслеживать нажатия на кнопки диммера и получать значения количества нажатий.По ссылке "Expand" можно увидеть полный код шаблона.
Настройки яркости хранятся в holding-регистрах. Шаблон описывает, какие регистры можно менять для получения нужной яркости каналов, отслеживать нажатия на кнопки диммера и получать значения количества нажатий.


<!--T:29-->
<div class="mw-collapsible mw-collapsed"  style="width:500px; overflow: hidden;" >
<syntaxhighlight lang="JSON" highlight="8-25">
<syntaxhighlight lang="JSON" highlight="8-25">
{
{
Строка 294: Строка 513:
}
}
  </syntaxhighlight>
  </syntaxhighlight>
</div>
 
В этом шаблоне составной канал RGB задает одновременно яркости трех цветовых компонентов ленты, хранящихся в трех holding-регистрах и описывается следующим образом:   
В этом шаблоне составной канал RGB задает одновременно яркости трех цветовых компонентов ленты, хранящихся в трех holding-регистрах и описывается следующим образом:   
<syntaxhighlight lang="JSON">
<syntaxhighlight lang="JSON">
Строка 317: Строка 536:
</syntaxhighlight>
</syntaxhighlight>


<!--T:30-->
Канал белого цвета управляется отдельно,  
Канал белого цвета управляется отдельно,  
<syntaxhighlight lang="JSON">
<syntaxhighlight lang="JSON">
Строка 330: Строка 548:
Здесь указано максимальное значение, которое можно установить для ползунка яркости белого — 255:<syntaxhighlight lang="JSON">"max": 255</syntaxhighlight>
Здесь указано максимальное значение, которое можно установить для ползунка яркости белого — 255:<syntaxhighlight lang="JSON">"max": 255</syntaxhighlight>


<!--T:31-->
Серийный номер устройства (канал «Serial NO») считывается как беззнаковое 32-битное целое: <syntaxhighlight lang="JSON">"format": "u32"</syntaxhighlight>
Серийный номер устройства (канал "Serial NO") считывается как беззнаковое 32-битное целое: <syntaxhighlight lang="JSON">"format": "u32"</syntaxhighlight>
 
<!--T:32-->
----


==== WBIO-DO-R10A-8 ==== <!--T:33-->
=== WBIO-DO-R10A-8 ===
Устройство [[WBIO-DO-R10A-8_Relay_Module|WBIO-DO-R10A-8]] — релейный боковой модуль, который подключается непосредственно к WBIO-разъему контроллера, и не управляется по Modbus. Но при подключении его через устройство расширения WB-MIO или WB-MIO-E становится полноценным Modbus-устройством, для которого имеется соответствующий шаблон.
Устройство [[WBIO-DO-R10A-8_Relay_Module|WBIO-DO-R10A-8]] — релейный боковой модуль, который подключается непосредственно к WBIO-разъему контроллера, и не управляется по Modbus. Но при подключении его через устройство расширения WB-MIO или WB-MIO-E становится полноценным modbus-устройством, для которого есть соответствующий шаблон.  
По ссылке "Expand" можно увидеть полный код шаблона.


<!--T:34-->
<div class="mw-collapsible mw-collapsed"  style="width:500px; overflow: hidden;" >
<syntaxhighlight lang="JSON" highlight="6-15">
<syntaxhighlight lang="JSON" highlight="6-15">
{
{
Строка 442: Строка 653:
}
}
  </syntaxhighlight>
  </syntaxhighlight>
</div>


<!--T:35-->
В этом шаблоне следует обратить внимание на следующие параметры устройства.
В этом шаблоне следует обратить внимание на следующие параметры устройства.
<syntaxhighlight lang="JSON">
<syntaxhighlight lang="JSON">
Строка 455: Строка 663:
</syntaxhighlight>
</syntaxhighlight>


<!--T:36-->
Параметр '''"protocol": "modbus_io"''' указывает, что устройство подключается оп специальному протоколу к модулю расширения. Параметры '''"stride": 1000''' и '''"shift": 500''' задают сдвиг регистров в зависимости от того, в каком порядке подключены модули к модулю расширения.  
Параметр '''"protocol": "modbus_io"''' указывает, что устройство подключается оп специальному протоколу к модулю расширения. Параметры '''"stride": 1000''' и '''"shift": 500''' задают сдвиг регистров в зависимости от того, в каком порядке подключены модули к модулю расширения.  


<!--T:37-->
Сдвиг регистров (число, которое нужно добавить к базовому номеру регистра) вычисляется по формуле: <syntaxhighlight lang="C++">Shift = (((SlaveId.Secondary - 1) % 4) + 1) * DeviceConfig()->Stride + DeviceConfig()->Shift;</syntaxhighlight> Здесь stride — ''DeviceConfig()->Stride'', a shift — ''DeviceConfig()->Shift''. Каждое подключенное устройство имеет порядковый номер (''SlaveId.Secondary''), начинающийся с 1 для первого устройства. (Здесь знаком "%" обозначается деление по модулю.)
Сдвиг регистров (число, которое нужно добавить к базовому номеру регистра) вычисляется по формуле: <syntaxhighlight lang="C++">Shift = (((SlaveId.Secondary - 1) % 4) + 1) * DeviceConfig()->Stride + DeviceConfig()->Shift;</syntaxhighlight> Здесь stride — ''DeviceConfig()->Stride'', a shift — ''DeviceConfig()->Shift''. Каждое подключенное устройство имеет порядковый номер (''SlaveId.Secondary''), начинающийся с 1 для первого устройства. (Здесь знаком "%" обозначается деление по модулю.)


<!--T:38-->
Например, подставляя значения shift и stride в формулу, получаем: <syntaxhighlight lang="C++">Shift = ((( 1 - 1) % 4) + 1) * 500 + 1000 = (0 + 1) * 500 + 1000 = 1500</syntaxhighlight> То есть ко всем регистрам, указанным в шаблоне, надо добавить 1500.
Например, подставляя значения shift и stride в формулу, получаем: <syntaxhighlight lang="C++">Shift = ((( 1 - 1) % 4) + 1) * 500 + 1000 = (0 + 1) * 500 + 1000 = 1500</syntaxhighlight> То есть ко всем регистрам, указанным в шаблоне, надо добавить 1500.


<!--T:39-->
Еще один важный параметр — setup-секция, массив  
Еще один важный параметр — setup-секция, массив  
<syntaxhighlight lang="JSON">
<syntaxhighlight lang="JSON">
Строка 477: Строка 681:
Он описывает регистры и значения, которые однократно заносятся в эти регистры при инициализации устройства (при запуске или перезапуске wb-mqtt-serial). Его можно использовать для конфигурирования устройств для работы в каком-то определенном режиме, задавать изначальные значения яркости, положения сервоприводов, состояния реле, режима работы с входами релейных модулей и т. п.
Он описывает регистры и значения, которые однократно заносятся в эти регистры при инициализации устройства (при запуске или перезапуске wb-mqtt-serial). Его можно использовать для конфигурирования устройств для работы в каком-то определенном режиме, задавать изначальные значения яркости, положения сервоприводов, состояния реле, режима работы с входами релейных модулей и т. п.


<!--T:40-->
=== WB-MAP3H ===
----


==== WB-MAP3H ==== <!--T:41-->
Устройство [[WB-MAP3H_Power_Meter|WB-MAP3H]] — трехканальный счетчик электроэнергии. Он измеряет большое количество параметров электрической сети. Поскольку опрос всех регистров такого устройства может занять достаточно много времени, есть несколько шаблонов, содержащих оптимальный набор параметров для решения текущей задачи. Мы рассмотрим базовый шаблон.


<!--T:42-->
Устройство [[WB-MAP3H_Power_Meter|WB-MAP3H]] — трехканальный счетчик электроэнергии. Он измеряет большое количество параметров электрической сети. Поскольку опрос всех регистров такого устройства может занять достаточно много времени, имеется несколько шаблонов, содержащих оптимальный набор параметров для решения текущей задачи. Мы рассмотрим базовый шаблон. По ссылке "Expand" можно увидеть полный код шаблона.
<!--T:43-->
<div class="mw-collapsible mw-collapsed"  style="width:500px; overflow: hidden;" >
<syntaxhighlight lang="JSON" highlight="6,162-171">
<syntaxhighlight lang="JSON" highlight="6,162-171">
{
{
Строка 894: Строка 1092:
}
}
  </syntaxhighlight>
  </syntaxhighlight>
</div>


<!--T:44-->
На что следует обратить внимание в этом шаблоне? В первую очередь в параметрах устройства мы указываем, что одновременно следует считывать не более 60 регистров, чтобы не останавливать надолго опрос остальных устройств: <code>"max_read_registers": 60</code>.  
На что следует обратить внимание в этом шаблоне? В первую очередь в параметрах устройства мы указываем, что одновременно следует считывать не более 60 регистров, чтобы не останавливать надолго опрос остальных устройств: '''"max_read_registers": 60'''.  
Также показательным является параметр, описывающий накопленную реактивную энергию по фазе L1:
Также показательным является параметр, описывающий накопленную реактивную энергию по фазе L1:
<syntaxhighlight lang="JSON">
<syntaxhighlight lang="JSON">
Строка 912: Строка 1108:
</syntaxhighlight>  
</syntaxhighlight>  


<!--T:45-->
Здесь стоит обратить внимание на то, что адрес регистра может задаваться и в шестнадцатеричном виде: <code>"address": "0x1224"</code>, вещественный коэффициент масштабирования можно задавать в экспоненциальной записи: <code>"scale": 3.125e-05</code>, при считывании значения округлять его до нужного порядка: <code>"round_to": 0.0001</code>, а также учитывать, что число в modbus-регистрах хранится в порядке от младшего к старшему: <code>"word_order": "little_endian"</code>.   
Здесь стоит обратить внимание на то, что адрес регистра может задаваться и в шестнадцатеричном виде: '''"address": "0x1224"''', вещественный коэффициент масштабирования можно задавать в экспоненциальной записи: '''"scale": 3.125e-05''', при считывании значения округлять его до нужного порядка: '''"round_to": 0.0001''', а также учитывать, что число в Modbus-регистрах хранится в порядке от младшего к старшему: '''"word_order": "little_endian"'''.   
Форматы хранения для 16-битных Modbus регистров описываются следующим образом:
Форматы хранения для 16-битных Modbus регистров описываются следующим образом:
<pre>
<pre>
Строка 919: Строка 1114:
         little-endian : ( [0xAA 0xBB] [0xCC 0xDD] => 0xCCDDAABB )
         little-endian : ( [0xAA 0xBB] [0xCC 0xDD] => 0xCCDDAABB )
</pre>
</pre>
По умолчанию предполагается формат big-endian.
По умолчанию предполагается формат ''big-endian''.
 
<!--T:46-->
Типы переменных, используемых в шаблонах, перечислены в следующей таблице:
{| class="wikitable"
! Обозначение !! Тип
|-
| s16 || Signed 16-bit integer
|-
|  u16 ||  Unsigned 16-bit integer
|-
|  s8 ||  Signed 8-bit integer
|-
|  u8 ||  Unsigned 8-bit integer
|-
|  s24 ||  Signed 24-bit integer
|-
|  u24 ||  Unsigned 24-bit integer
|-
|  s32 ||  Signed 32-bit integer
|-
|  u32 ||  Unsigned 32-bit integer
|-
|  s64 ||  Signed 64-bit integer
|-
|  u64 ||  Unsigned 64-bit integer
|-
|  bcd8 ||  8-bit BCD
|-
|  bcd16 ||  16-bit BCD
|-
|  bcd24 || 24-bit BCD
|-
|  bcd32 ||  32-bit BCD
|-
|  float ||  IEEE754 32-bit float
|-
|  double ||  IEEE754 64-bit float (double)
|-
|  char8 ||  8-bit ASCII char
|}


=== Источники информации === <!--T:47-->
== Полезные ссылки ==
В этой статье описаны основные правила создания шаблонов устройств для контроллеров Wiren Board. Информация изменяется и дополняется по мере обновления ПО и выходу новых продуктов. Самая полная и актуальная информация может быть найдена в следующих источниках:
* [[Wb-mqtt-serial driver| Описание драйвера wb-mqtt-serial в нашей вики]]
* в описании сервиса [https://github.com/contactless/wb-mqtt-serial/ wb-mqtt-serial] на GitHub;
* [https://github.com/wirenboard/wb-mqtt-serial/blob/master/README.md Описание драйвера в репозитории на Github]
* в файлах самих шаблонов.
* [https://github.com/wirenboard/wb-mqtt-serial/tree/master/wb-mqtt-serial-templates Шаблоны из стандартной поставки драйвера]
* в файле [https://github.com/contactless/wb-mqtt-serial/blob/master/wb-mqtt-serial.schema.json wb-mqtt-serial.schema.json] на GitHub.
* [https://github.com/wirenboard/wb-mqtt-serial/blob/master/wb-mqtt-serial.schema.json Описание файла wb-mqtt-serial.schema.json]
</translate>

Версия 19:32, 1 февраля 2021

Описание

Использование шаблонов позволяет один раз описать устройство и использовать созданное описание для любого числа устройств на одном или нескольких serial-портах.

Предустановленные шаблоны находятся в папке /usr/share/wb-mqtt-serial/templates.

Пользовательские шаблоны для wb-mqtt-serial версии 2.6.3 и выше рекомендуем хранить в папке /etc/wb-mqtt-serial.conf.d/templates, более ранних версий используйте путь по умолчанию. В каждом файле, размещенном в папке templates находится описание одного типа устройств.

Подготовка

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

Подключите устройство к контроллеру и прочитайте значение одного из его modbus-регистров. Описание адресов modbus-регистров и параметры подключения можно найти в документации на подключаемое устройство, а для чтения информации из устройства можно использовать утилиту modbus_client.

Базовая структура шаблона

{ 
"device": {
    "Параметр 1 устройства":"значение", 
    "Параметр 2 устройства":"значение", 
    ...

    "setup": [
        // секция инициализации устройства
        ...
    ]
    "channels": [ 
        {
            Параметры канала 1
            }, 
        {
            Параметры канала 2
            },
         ...
        ]
    }
}

В наших шаблонах мы используем отступы по 4 пробела на уровень, что обеспечивает хорошую читаемость кода. Новые шаблоны мы рекомендуем создавать с такими же отступами.

Параметры устройства (device)

В начале шаблона задаются параметры устройства в виде набора пар ключ:значение.

  • device_type — тип устройства, строка.
  • name — отображаемое имя устройства. Публикуется как .../meta/name в MQTT.
  • id — уникальный идентификатор устройства в MQTT. Каждый элемент в devices должен иметь уникальный id.
  • slave_id — идентификатор устройства. Если не задан — используется широковещательный запрос.
  • enabled — включает или выключает опрос устройства. Доступные значения: true, false. По умолчанию — true.
  • protocol — протокол передачи данных, если не указан — используется modbus. Возможные варианты:
    • modbus,
    • uniel,
    • milur,
    • mercury230,
    • ivtm,
    • s2k,
    • modbus_io,
    • pulsar,
    • mercury200,
    • lls,
    • neva,
    • energomera_iec.
  • max_reg_hole — максимальное количество считываемых «пустых» регистров. Параметр поддерживается только modbus-устройствами.
  • max_bit_hole — аналог max_reg_hole для битовых регистров: coils и discrete inputs.
  • max_read_registers — максимальное количество регистров в одной пакетной операции чтения.
  • poll_interval — минимальный интервал опроса регистров данного устройства в миллисекундах.
  • response_timeout_ms — максимальное время ответа устройства в миллисекундах
  • frame_timeout_ms — минимально необходимая задержка между посылками в миллисекундах.
  • guard_interval_us — дополнительная задержка перед каждой отправкой данных в порт в микросекундах.
  • device_timeout_ms — интервал, по истечении которого (а также device_max_fail_cycles) устройство будет помечено отключенным и будет опрашиваться в ограниченном режиме.
  • device_max_fail_cycles — количество неудачных циклов опроса устройства.
  • password — пароль для доступа к устройству, массив байт.
  • access_level — уровень доступа при опросе устройства.
  • channels — список каналов устройств, задается в виде массива [...], каждый из элементов которого — это описание отдельного канала. Подробнее читайте ниже.

Обязательно нужно указать параметры device_type и device. Остальные параметры можно опустить, в этом случае будут подставлены значения по умолчанию.

Изменять параметры устройства можно и в веб-интерфейсе, для этого найдите нужное устройство и откройте свойства объекта DeviceProperties.

Каналы устройства (channels)

Структура:

"channels": [
        {
            "name": "Имя канала 1",
            ...
        },
        {
            "name": "Имя канала 2",
            ...
        },
        ...
    ]

Структура содержит набор полей:

  • name — уникальное для устройства имя канала.
  • id — имя MQTT контрола для канала, публикуется как /devices/<идентификатор устройства>/controls/<ID канала> Если не задан, то используется значение name.
  • enabled — включает или выключает опрос канала. Доступные значения: true, false. По умолчанию — true.
  • reg_type — тип modbus-регистра. Возможные значения:
    • coil,
    • discrete,
    • holding,
    • holding_single,
    • holding_multi,
    • input,
    • direct.
  • address — адрес регистра.
  • type — тип контрола: виртуального элемента для представления данных в веб-интерфейсе контроллера.
  • format — тип переменной, описывающей значение.
  • word_order — порядок 16-битных слов для каналов, имеющих размер больше 16 бит. Доступные значения:
    • big_endian — [0xAA 0xBB] [0xCC 0xDD] => 0xAABBCCDD. Значение по умолчанию.
    • little_endian — [0xAA 0xBB] [0xCC 0xDD] => 0xCCDDAABB.
  • poll_interval — минимальный интервал опроса регистра в миллисекундах.
  • unsupported_value — значение, получаемое при последовательном чтении диапазона регистров, если устройство не поддерживает запрашиваемый регистр. Используется некоторыми протоколами для определения доступности регистров устройства.
  • max — максимальное значение регистра, используется для построения. Используется в веб-интерфейсе.
  • scale — коэффициент, на который умножается значение регистра перед публикацией в MQTT.
  • offset — значение, которое прибавляется к значению регистра перед публикацией в MQTT.
  • round_to — порядок, до которого будет округляться значение после всех преобразований. Например, 0.1 — округлять до десятых.
  • readonly — установка флага запрешает изменение значения в веб-интерфейсе или по MQTT. Возможные значения: true, false. По умолчанию — false.
  • on_value — значение, которое будет записано в регистр, при записи единицы в mqtt-топик канала.
  • error_value — полученное из устройства значение регистра, обозначающее ошибку.

Обязательно нужно указать поля name, reg_type, address и type. Остальные параметры можно опустить, в этом случае будут подставлены значения по умолчанию.

Доступные типы контролов (type)

  • atmospheric_pressure — атмосферное давление, millibar (100 Pa).
  • concentration — концентрация, ppm.
  • current — ток, отображается как value.
  • dimmer — диммер, отображается как value.
  • heat_energy — тепловая энергия, Gcal.
  • heat_power — расход тепловой энергии, Gcal/h.
  • lux — освещенность.
  • power — мощность, W.
  • power_consumption — энергопотребление, kWh.
  • pressure — давление, bar
  • pushbutton — кнопка.
  • rainfall — осадки, mm/h.
  • range — ползунок.
  • rel_humidity — влажность, %, RH.
  • resistance — сопротивление, Ohm.
  • rgb — rgb.
  • sound_level — уровень звука.
  • switch — переключатель положений ON/OFF.
  • temperature — температура, °C.
  • text — текстовая строка.
  • value — неформатированное значение.
  • voltage — напряжение, V.
  • water_consumption — потребление воды, m3.
  • water_flow — поток воды m3/h
  • wind_speed — скорость ветра, m/s.
  • wo-switch — переключатель положений ON/OFF.

Доступные типы переменных (format)

  • s16 — Signed 16-bit integer.
  • u16 — Unsigned 16-bit integer.
  • s8 — Signed 8-bit integer.
  • u8 — Unsigned 8-bit integer.
  • s24 — Signed 24-bit integer.
  • u24 — Unsigned 24-bit integer.
  • s32 — Signed 32-bit integer.
  • u32 — Unsigned 32-bit integer.
  • s64 — Signed 64-bit integer.
  • u64 — Unsigned 64-bit integer.
  • bcd8 — 8-bit BCD.
  • bcd16 — 16-bit BCD.
  • bcd24 — 24-bit BCD.
  • bcd32 — 32-bit BCD.
  • float — IEEE754 32-bit float.
  • double — IEEE754 64-bit float (double).
  • char8 — 8-bit ASCII char.

Секция инициализации (setup-секция)

Секция инициализации содержит перечень параметров, которые передаются устройству при перезапуске wb-mqtt-serial или при восстановлении связи с устройством.

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

Важно! Чтение параметров из устройства не предусмотрено.

В секции доступны параметры:

  • title — наименование параметра, будет отображен в веб-интерфейсе.
  • address — адрес регистра, в который нужно записать параметр.
  • enum — массив числовых значений, которые можно записать в регистр.
  • enum_titles — массив текстовых описаний значений, указанных в enum.
  • default — значение по умолчанию. Записывается в регистр, если пользователь не выбрал свое.
  • value — фиксированное значение. Если у регистра указать фиксированное значение, то пользователь не сможет его изменить через веб-интерфейс.

Значения address, enum, value и default можно указывать в десятичной или шестнадцатеричной системе счисления.

Пример setup-секции:

"setup": [
    {
        "title": "s12",
        "address": 20000,
        "value": "0xfff2"
    },    
    {
        "title": "Sound value",
        "address": 0x00,
        "default": 0x0a,
        "min": 0,
        "max": 100         
    },
    {
        "title": "Fan mode",
        "address": 3,
        "enum": [ 0, 1, 2, 4 ],          
        "enum_titles": [ 
          "off", 
          "slow", 
          "middle", 
          "fast"
        ],               
        "default": 1
    }
]

Вложенные устройства (subdevices)

В секции subdevices можно описать вложенные устройства, которые могут иметь свои setup-секции и каналы.

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

Адреса регистров вложенных устройств расчитываются как base + shift + address + stride * register_size, где:

  • base — адрес начала секции регистров родительского канала;
  • shift — смещение относительно родительсокго канала;
  • address — адрес, заданный в описании регистра;
  • stride — номер шага, заданный в настройках канала;
  • register_size — размер регистра.

Пример описания вложенных устройств:

{
    // Название типа устройства, оно указывается в поле device_type в файле настроек
    "device_type": "Device type name",

    // Название типа устройства, которое будет отображаться в онлайн-конфигураторе.
    // Необязательный параметр. Если не указан, используется device_type.
    "title": "Device",

    "device": {
        // отображаемое имя устройства. Публикуется как
        // .../meta/name в MQTT
        "name": "New device",
        
        // Остальные параметры устройства описанные ранее, кроме slave_id
        ...

        // список каналов устройства
        "channels": [
            // Пример канала, описывающий данные одного регистра
            {
                "name": "Temperature",
                "reg_type": "input",
                "format": "s32",
                "address": "0x0504"
            },

            // Канал - вложенное устройство
            {
                "name": "Sub",
                "device_type": "subdevice1"
            },

            // Канал - вложенное устройство.
            // В интерфейсе веб-интерфейса будет предложен выбор конкретного типа
            {
                "name": "Sub2",
                
                // Список типов вложенных устройств, которые можно выбрать для канала
                "oneOf": [ "subdevice1", "subdevice2" ],

                // Устройство, выбранное по умолчанию
                "device_type": "subdevice1",

                // Смещение регистров канала относительно родительского канала
                "shift": 100,

                // Номер шага регистров
                "stride": 1
            }
        ],
        // Список вложенных устройств
        "subdevices": [
            {
                // Имя вложенного устройства,
                // которое будет использоваться в поле device_type канала
                "device_type": "subdevice1",

                // Название вложенного устройства,
                // которое будет отображаться в онлайн-конфигураторе.
                // Необязательный параметр. Если не указан, используется device_type.
                "title": "Sub1",

                "device": {
                    "channels": [
                        // Вложенные устройства могут иметь свои каналы
                        {
                            "name": "c11",
                            "reg_type": "input",
                            "format": "s32",
                            "address": "0x0501"
                        },

                        // Вложенные устройства также могут иметь
                        // каналы с вложенными устройствами
                        {
                            "name": "c2",
                            "device_type": "subdevice2"
                        }
                    ]
                }
            },
            {
                "device_type": "subdevice2",
                "device": {
                    // Вложенные устройства могут иметь
                    // собственную секцию с настройками
                    "setup": [
                        {
                            "title": "s12",
                            "address": 20000,
                            "value": "0xfff2"
                        },

                        // Если конкретное значение настройки не задано, то его можно
                        // задать в файле конфигурации или через веб-интерфейс
                        {
                            "title": "s22",
                            "address": 9992,

                            // Список возможных значений
                            "enum": [1, 2, 3],

                            // Надписи в списке выбора в веб-интерфейсе
                            "enum_titles": ["one", "two", "three" ],

                            // Минимально возможное значение
                            "min": 1,

                            // Максимально возможное значение
                            "max": 3
                        }
                    ],
                    "channels": [
                        {
                            "name": "c2",
                            "device_type": "subdevice2"
                        }
                    ]
                }
            }
        ]
    }
}

Примеры шаблонов

Хорошим источником примеров могут служить предустановленные шаблоны драйвера wb-mqtt-serial.

Ниже мы рассмотрим несколько примеров подробнее.

WB-MSW3

Датчик WB-MSW3 в базовой комплектации может измерять температуру и влажность. Еще мы можем получить из датчика величину напряжения питания, серийный номер и управлять встроенной пищалкой.

Пример шаблона:

{
    "device_type": "WB-MSW v.3 (base)",
    "device": {
        "name": "WB-MSW v.3",
        "id": "wb-msw-v3",
        "max_read_registers": 0,
        "response_timeout_ms": 1,
        "frame_timeout_ms": 12,
        "channels": [
            {
                "name": "Temperature",
                "reg_type": "input",
                "address": 0,
                "type": "temperature",
                "format": "s16",
                "scale": 0.1,
                "error_value": "0x7FFF"
            },
            {
                "name": "Humidity",
                "reg_type": "input",
                "address": 1,
                "type": "rel_humidity",
                "scale": 0.1,
                "error_value": "0xFFFF"
            },
            {
                "name": "Input Voltage",
                "reg_type": "input",
                "address": 121,
                "scale": 0.001,
                "type": "voltage"
            },
            {
                "name": "Serial",
                "type": "text",
                "reg_type": "input",
                "address": 270,
                "format": "u32"
            },
            {
                "name": "Buzzer",
                "type": "switch",
                "reg_type": "coil",
                "address": 0
            }
        ]
    }
}

Описание параметров смотрите в описании базовой структуры шаблона.

WB-MRGBW-D

Устройство WB-MRGBW-D — четырехканальный диммер для управления светодиодными лентами. Может управлять лентой RGB+W либо независимо четырьмя одноцветными лентами. Настройки яркости хранятся в holding-регистрах. Шаблон описывает, какие регистры можно менять для получения нужной яркости каналов, отслеживать нажатия на кнопки диммера и получать значения количества нажатий.

{
    "device_type": "WB-MRGBW-D", 
    "device": {
        "name": "WB-MRGBW-D", 
        "id": "wb-mrgbw-d", 
        "max_read_registers": 0, 
        "channels": [
            {
                "name": "RGB", 
                "type": "rgb", 
                "consists_of": [
                    {
                        "reg_type": "holding", 
                        "address": 1
                    }, 
                    {
                        "reg_type": "holding", 
                        "address": 0
                    }, 
                    {
                        "reg_type": "holding", 
                        "address": 2
                    }
                ]
            }, 
            {
                "name": "White", 
                "reg_type": "holding", 
                "address": 3, 
                "type": "range", 
                "max": 255
            }, 
            {
                "name": "Button 1", 
                "reg_type": "holding", 
                "readonly": true, 
                "address": 6, 
                "type": "switch"
            }, 
            {
                "name": "Button 2", 
                "reg_type": "holding", 
                "readonly": true, 
                "address": 7, 
                "type": "switch"
            }, 
            {
                "name": "Button 3", 
                "reg_type": "holding", 
                "readonly": true, 
                "address": 8, 
                "type": "switch"
            }, 
            {
                "name": "Button 1 counter", 
                "reg_type": "holding", 
                "readonly": true, 
                "address": 32, 
                "type": "value"
            }, 
            {
                "name": "Button 2 counter", 
                "reg_type": "holding", 
                "readonly": true, 
                "address": 33, 
                "type": "value"
            }, 
            {
                "name": "Button 3 counter", 
                "reg_type": "holding", 
                "readonly": true, 
                "address": 34, 
                "type": "value"
            }, 
            {
                "name": "Serial NO", 
                "type": "text", 
                "reg_type": "holding", 
                "address": 270, 
                "format": "u32"
            }
        ]
    }
}

В этом шаблоне составной канал RGB задает одновременно яркости трех цветовых компонентов ленты, хранящихся в трех holding-регистрах и описывается следующим образом:

    {
        "name": "RGB", 
        "type": "rgb", 
        "consists_of": [
            {
                "reg_type": "holding", 
                "address": 1
            }, 
            {
                "reg_type": "holding", 
                "address": 0
            }, 
            {
                "reg_type": "holding", 
                "address": 2
            }
        ]
    },

Канал белого цвета управляется отдельно,

    {
        "name": "White", 
        "reg_type": "holding", 
        "address": 3, 
        "type": "range", 
        "max": 255
    },

Здесь указано максимальное значение, которое можно установить для ползунка яркости белого — 255:

"max": 255

Серийный номер устройства (канал «Serial NO») считывается как беззнаковое 32-битное целое:

"format": "u32"

WBIO-DO-R10A-8

Устройство WBIO-DO-R10A-8 — релейный боковой модуль, который подключается непосредственно к WBIO-разъему контроллера, и не управляется по Modbus. Но при подключении его через устройство расширения WB-MIO или WB-MIO-E становится полноценным modbus-устройством, для которого есть соответствующий шаблон.

{
    "device_type": "WBIO-DO-R10A-8",
    "device": {
        "name": "WBIO-DO-R10A-8",
        "id": "wb-mio-gpio",
        "protocol": "modbus_io",
        "stride": 1000,
        "shift": 500,
        "max_read_registers": 0,
        "setup": [
            {
                "title": "IODIR",
                "address": 10000,
                "value": "0x0000"
            },
            {
                "title": "IPOL",
                "address": 10001,
                "value": "0x0000"
            },
            {
                "title": "GPINTEN",
                "address": 10002,
                "value": "0xffff"
            },
            {
                "title": "DEFVAL",
                "address": 10003,
                "value": "0x0000"
            },
            {
                "title": "INTCON",
                "address": 10004,
                "value": "0x0000"
            },
            {
                "title": "IOCON",
                "address": 10005,
                "value": "0x4444"
            },
            {
                "title": "FLAG",
                "address": 9999,
                "value": 1
            }
        ],
        "channels": [
            {
                "name": "K1",
                "reg_type": "coil",
                "address": 0,
                "type": "switch"
            },
            {
                "name": "K2",
                "reg_type": "coil",
                "address": 1,
                "type": "switch"
            },
            {
                "name": "K3",
                "reg_type": "coil",
                "address": 2,
                "type": "switch"
            },
            {
                "name": "K4",
                "reg_type": "coil",
                "address": 3,
                "type": "switch"
            },
            {
                "name": "K5",
                "reg_type": "coil",
                "address": 4,
                "type": "switch"
            },
            {
                "name": "K6",
                "reg_type": "coil",
                "address": 5,
                "type": "switch"
            },
            {
                "name": "K7",
                "reg_type": "coil",
                "address": 6,
                "type": "switch"
            },
            {
                "name": "K8",
                "reg_type": "coil",
                "address": 7,
                "type": "switch"
            }
        ]
    }
}

В этом шаблоне следует обратить внимание на следующие параметры устройства.

    "protocol": "modbus_io",
    "stride": 1000,
    "shift": 500,
    "max_read_registers": 0,
    "setup": [

Параметр "protocol": "modbus_io" указывает, что устройство подключается оп специальному протоколу к модулю расширения. Параметры "stride": 1000 и "shift": 500 задают сдвиг регистров в зависимости от того, в каком порядке подключены модули к модулю расширения.

Сдвиг регистров (число, которое нужно добавить к базовому номеру регистра) вычисляется по формуле:

Shift = (((SlaveId.Secondary - 1) % 4) + 1) * DeviceConfig()->Stride + DeviceConfig()->Shift;

Здесь stride — DeviceConfig()->Stride, a shift — DeviceConfig()->Shift. Каждое подключенное устройство имеет порядковый номер (SlaveId.Secondary), начинающийся с 1 для первого устройства. (Здесь знаком "%" обозначается деление по модулю.) Например, подставляя значения shift и stride в формулу, получаем:

Shift = ((( 1 - 1) % 4) + 1) * 500 + 1000 = (0 + 1) * 500 + 1000 = 1500

То есть ко всем регистрам, указанным в шаблоне, надо добавить 1500.

Еще один важный параметр — setup-секция, массив

     "setup": [    {
             "title": "IODIR",
             "address": 10000,
             "value": "0x0000"
         },
     {},
     ...]

Он описывает регистры и значения, которые однократно заносятся в эти регистры при инициализации устройства (при запуске или перезапуске wb-mqtt-serial). Его можно использовать для конфигурирования устройств для работы в каком-то определенном режиме, задавать изначальные значения яркости, положения сервоприводов, состояния реле, режима работы с входами релейных модулей и т. п.

WB-MAP3H

Устройство WB-MAP3H — трехканальный счетчик электроэнергии. Он измеряет большое количество параметров электрической сети. Поскольку опрос всех регистров такого устройства может занять достаточно много времени, есть несколько шаблонов, содержащих оптимальный набор параметров для решения текущей задачи. Мы рассмотрим базовый шаблон.

{
 "device_type": "WB-MAP3H (basic)", 
 "device": {
  "name": "WB-MAP3H (basic)", 
  "id": "wb-map3h", 
  "max_read_registers": 60, 
  "channels": [
   {
    "name": "Urms L1", 
    "reg_type": "input", 
    "address": "0x10d9", 
    "type": "voltage", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "THDN U L1", 
    "reg_type": "input", 
    "address": "0x10f1", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "Urms L2", 
    "reg_type": "input", 
    "address": "0x10da", 
    "type": "voltage", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "THDN U L2", 
    "reg_type": "input", 
    "address": "0x10f2", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "Urms L3", 
    "reg_type": "input", 
    "address": "0x10db", 
    "type": "voltage", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "THDN U L3", 
    "reg_type": "input", 
    "address": "0x10f3", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "Frequency", 
    "reg_type": "input", 
    "address": "0x10f8", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "Voltage angle L1", 
    "reg_type": "input", 
    "address": "0x10fd", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.1, 
    "round_to": 0.01
   }, 
   {
    "name": "Voltage angle L2", 
    "reg_type": "input", 
    "address": "0x10fe", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.1, 
    "round_to": 0.01
   }, 
   {
    "name": "Voltage angle L3", 
    "reg_type": "input", 
    "address": "0x10ff", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.1, 
    "round_to": 0.01
   }, 
   {
    "name": "Irms L1", 
    "reg_type": "input", 
    "address": "0x10dd", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.001, 
    "round_to": 0.01
   }, 
   {
    "name": "THDN I L1", 
    "reg_type": "input", 
    "address": "0x10f5", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "P L1", 
    "reg_type": "input", 
    "address": "0x1302", 
    "type": "power", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "Q L1", 
    "reg_type": "input", 
    "address": "0x130a", 
    "type": "value", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "S L1", 
    "reg_type": "input", 
    "address": "0x1312", 
    "type": "value", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "PF L1", 
    "reg_type": "input", 
    "address": "0x10bd", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.001, 
    "round_to": 0.01
   }, 
   {
    "name": "AP energy L1", 
    "reg_type": "input", 
    "address": "0x1204", 
    "type": "power_consumption", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "RP energy L1", 
    "reg_type": "input", 
    "address": "0x1224", 
    "type": "value", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "Irms L2", 
    "reg_type": "input", 
    "address": "0x10de", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.001, 
    "round_to": 0.01
   }, 
   {
    "name": "THDN I L2", 
    "reg_type": "input", 
    "address": "0x10f6", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "P L2", 
    "reg_type": "input", 
    "address": "0x1304", 
    "type": "power", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "Q L2", 
    "reg_type": "input", 
    "address": "0x130c", 
    "type": "value", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "S L2", 
    "reg_type": "input", 
    "address": "0x1314", 
    "type": "value", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "PF L2", 
    "reg_type": "input", 
    "address": "0x10be", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.001, 
    "round_to": 0.01
   }, 
   {
    "name": "AP energy L2", 
    "reg_type": "input", 
    "address": "0x1208", 
    "type": "power_consumption", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "RP energy L2", 
    "reg_type": "input", 
    "address": "0x1228", 
    "type": "value", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "Irms L3", 
    "reg_type": "input", 
    "address": "0x10df", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.001, 
    "round_to": 0.01
   }, 
   {
    "name": "THDN I L3", 
    "reg_type": "input", 
    "address": "0x10f7", 
    "type": "value", 
    "format": "u16", 
    "scale": 0.01, 
    "round_to": 0.01
   }, 
   {
    "name": "P L3", 
    "reg_type": "input", 
    "address": "0x1306", 
    "type": "power", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "Q L3", 
    "reg_type": "input", 
    "address": "0x130e", 
    "type": "value", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "S L3", 
    "reg_type": "input", 
    "address": "0x1316", 
    "type": "value", 
    "format": "s32", 
    "scale": 1.52588e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "PF L3", 
    "reg_type": "input", 
    "address": "0x10bf", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.001, 
    "round_to": 0.01
   }, 
   {
    "name": "AP energy L3", 
    "reg_type": "input", 
    "address": "0x120c", 
    "type": "power_consumption", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "RP energy L3", 
    "reg_type": "input", 
    "address": "0x122c", 
    "type": "value", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "Total P", 
    "reg_type": "input", 
    "address": "0x1300", 
    "type": "power", 
    "format": "s32", 
    "scale": 6.10352e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "Total Q", 
    "reg_type": "input", 
    "address": "0x1308", 
    "type": "value", 
    "format": "s32", 
    "scale": 6.10352e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "Total S", 
    "reg_type": "input", 
    "address": "0x1310", 
    "type": "value", 
    "format": "s32", 
    "scale": 6.10352e-05, 
    "round_to": 0.01
   }, 
   {
    "name": "Total PF", 
    "reg_type": "input", 
    "address": "0x10bc", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.001, 
    "round_to": 0.01
   }, 
   {
    "name": "Total AP energy", 
    "reg_type": "input", 
    "address": "0x1200", 
    "type": "power_consumption", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "Total RP energy", 
    "reg_type": "input", 
    "address": "0x1220", 
    "type": "value", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   }, 
   {
    "name": "Phase angle L1", 
    "reg_type": "input", 
    "address": "0x10f9", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.1, 
    "round_to": 0.01
   }, 
   {
    "name": "Phase angle L2", 
    "reg_type": "input", 
    "address": "0x10fa", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.1, 
    "round_to": 0.01
   }, 
   {
    "name": "Phase angle L3", 
    "reg_type": "input", 
    "address": "0x10fb", 
    "type": "value", 
    "format": "s16", 
    "scale": 0.1, 
    "round_to": 0.01
   }
  ]
 }
}

На что следует обратить внимание в этом шаблоне? В первую очередь в параметрах устройства мы указываем, что одновременно следует считывать не более 60 регистров, чтобы не останавливать надолго опрос остальных устройств: "max_read_registers": 60. Также показательным является параметр, описывающий накопленную реактивную энергию по фазе L1:

   {
    "name": "RP energy L1", 
    "reg_type": "input", 
    "address": "0x1224", 
    "type": "value", 
    "format": "u64", 
    "scale": 3.125e-05, 
    "round_to": 0.0001, 
    "word_order": "little_endian"
   },

Здесь стоит обратить внимание на то, что адрес регистра может задаваться и в шестнадцатеричном виде: "address": "0x1224", вещественный коэффициент масштабирования можно задавать в экспоненциальной записи: "scale": 3.125e-05, при считывании значения округлять его до нужного порядка: "round_to": 0.0001, а также учитывать, что число в modbus-регистрах хранится в порядке от младшего к старшему: "word_order": "little_endian". Форматы хранения для 16-битных Modbus регистров описываются следующим образом:

        big-endian    : ( [0xAA 0xBB] [0xCC 0xDD] => 0xAABBCCDD ) 
        little-endian : ( [0xAA 0xBB] [0xCC 0xDD] => 0xCCDDAABB )

По умолчанию предполагается формат big-endian.

Полезные ссылки