|
|
Строка 1: |
Строка 1: |
| {{Draft}} | | {{Draft}} |
| == Создание шаблона ==
| |
| Рассказать драйверу wb-mqtt-serial, который в контроллере работает с Modbus-устройствами можно двумя способами:
| |
| # Добавить регистры устройства прямо в веб-интерфейсе контроллера по [[RS-485:Configuration_via_Web_Interface#without-template|инструкции]]. Этот способ удобен для быстрой проверки работы.
| |
| # Создать шаблон, который описывает регистры устройства, их тип и другие параметры. Этот способ удобен для масштабирования: просто копируете шаблон на другой контроллер и в нём появляется поддержка вашего устройства.
| |
|
| |
|
| Здесь мы рассмотрим создание простого шаблона. Упрощённо шаблон устройства выглядит так:
| | Определено, как File, не работает [[File:test.pdf]] |
| <syntaxhighlight lang="json">
| |
| {
| |
| "device_type": "my-relay", // тип устройства — уникальный идентификатор
| |
| "title": "My Relay", // отображаемое название
| |
| "group": "g-relay", // группа, в которой будет отображаться шаблон. Список групп в документации
| |
| "device": {
| |
| "name": "MY-RELAY", // имя устройства, используется в MQTT
| |
| "id": "my-relay",
| |
| "groups": [ ], // группы параметров и каналов
| |
| "channels": [ ], // каналы, доступно в скриптах и на вкладке Устройства
| |
| "parameters": [ ], // параметры, можно менять в настройках устройства
| |
| "translations": { } // переводы
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
| Полное описание смотрите в [https://github.com/wirenboard/wb-mqtt-serial документации драйвера wb-mqtt-serial].
| |
|
| |
|
| Допустим, у нас есть одноканальное Modbus-реле, у которого таблица регистров, показанная ниже.
| | Определено, как Media, работает [[Media:test.pdf]] |
| {| border="1" class="wikitable"
| |
| ! Адрес || Тип || Название || Назначение
| |
| |-
| |
| | 0 || Discrete Input || Input 1 || Состояние входа устройства
| |
| |-
| |
| | 1 || Input Register || Input 1 Counter || Значение счётчика входов
| |
| |-
| |
| | 3 || Coil || Relay 1 || Состояние выхода и управление им
| |
| |-
| |
| | 10 || Holding || Input Mode || Выбор режима взаимодействия входов с выходами
| |
| |-
| |
| |}
| |
| | |
| В таком случае шаблон будет выглядеть так:
| |
| <syntaxhighlight lang="json">
| |
| {
| |
| "device_type": "my-relay",
| |
| "title": "My Relay",
| |
| "group": "g-relay",
| |
| "device": {
| |
| "name": "MY-RELAY",
| |
| "id": "my-relay",
| |
| "groups": [
| |
| {
| |
| "title": "Channels",
| |
| "id": "channels",
| |
| "order": 0
| |
| },
| |
| {
| |
| "title": "Settings",
| |
| "id": "settings",
| |
| "order": 1
| |
| }
| |
| ],
| |
| "channels": [
| |
| {
| |
| "name": "Input 1",
| |
| "reg_type": "discrete",
| |
| "address": 1,
| |
| "type": "switch",
| |
| "group": "channels"
| |
| },
| |
| {
| |
| "name": "Input 1 Counter",
| |
| "reg_type": "input",
| |
| "address": 2,
| |
| "type": "value",
| |
| "group": "channels"
| |
| },
| |
| {
| |
| "name": "Relay 1",
| |
| "reg_type": "coil",
| |
| "address": 3,
| |
| "type": "switch",
| |
| "group": "channels"
| |
| }
| |
| ],
| |
| "parameters": [
| |
| {
| |
| "id": "input1",
| |
| "title": "Input Mode",
| |
| "reg_type": "input",
| |
| "address": 10,
| |
| "format": "s8",
| |
| "enum": [
| |
| 1,
| |
| 2
| |
| ],
| |
| "enum_titles": [
| |
| "Switch Relay",
| |
| "Not used"
| |
| ],
| |
| "default": 1
| |
| }
| |
| ],
| |
| "translations": {
| |
| "ru": {
| |
| "Channels": "Каналы",
| |
| "Settings": "Настройки",
| |
| "Input 1": "Вход 1",
| |
| "Input 1 Counter": "Вход 1 счетчик",
| |
| "Relay 1": "Реле 1",
| |
| "Input Mode": "Режим входа"
| |
| }
| |
| }
| |
| }
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| == Загрузка шаблона на контроллер ==
| |
| Когда шаблон готов, его надо загрузить на контроллер:
| |
| # Сохраните шаблон в файл, например, <code>my-relay.json</code> и загрузите его на контроллер в папку <code>/etc/wb-mqtt-serial.conf.d/templates</code> по [[View_controller_files_from_your_computer|инструкции]].
| |
| # Проверьте шаблон на синтаксические ошибки командой:
| |
| #:<syntaxhighlight lang="bash">
| |
| # wb-mqtt-serial -g
| |
| <3>ERROR: [serial config] Failed to parse /etc/wb-mqtt-serial.conf.d/templates/my-best-template.json
| |
| Failed to parse JSON /etc/wb-mqtt-serial.conf.d/templates/my-best-template.json:* Line 12, Column 5
| |
| Missing ',' or '}' in object declaration
| |
| </syntaxhighlight>
| |
| #: в примере в шаблоне ''my-best-template.json'' в строке 12, символ 5 ожидается <code>,</code> or <code>}</code>, а находится что-то другое.
| |
| # Если с шаблоном всё в порядке, то перейдите в настройки драйвера и выберите ваш шаблон — [[RS-485:Configuration_via_Web_Interface|инструкция]].
| |
| | |
| == Решение возможных проблем ==
| |
| === Обмен с устройствами происходит с ошибками ===
| |
| В первую очередь, проверьте качество физического подключения устройств и только потом следуйте советам ниже.
| |
| | |
| Стандартом Modbus RTU предусмотрен обязательный интервал тишины в 3.5 символа между фреймами данных (под символом подразумевается посылка, состоящая из стартового бита, битов данных, бита четности и стоп-битов).
| |
| | |
| Для ускорения опроса устройств Wiren Board мы соблюдаем этот интервал только перед первым запросом к следующему в цикле опроса устройству (параметр ''frame_timeout_ms'' в шаблонах устройств).
| |
| | |
| Поэтому, чтобы соответствовать требованиям протокола Modbus-RTU, нужно для сторонних устройств задавать параметр ''guard_interval_us''. Этот параметр задает задержку перед записью каждого запроса в порт.
| |
| | |
| Нужное значение рассчитывается по формуле:
| |
| <syntaxhighlight lang="bash">
| |
| guard_interval_us = (3.5*11*106)/(скорость в бит/с).
| |
| </syntaxhighlight>
| |
| Например, для скорости 9600 бит/с <code>guard_interval_us = (3.5*11*106)/9600 = 4000 мкс</code>. При проблемах с подключением стороннего устройства для теста это значение можно увеличить (например до 100000 мкс), так как сторонние устройства иногда работают не совсем корректно.
| |
| | |
| === Нарушения стандарта в сторонних устройствах ===
| |
| Иногда в сторонних устройствах встречаются грубые нарушения стандарта:
| |
| # В некоторые регистры можно только писать информацию, но нельзя считывать.
| |
| #. Один и тот же параметра может читаться по одному адресу, а записываться по другому.
| |
| | |
| Для того, чтобы драйвер работал с такими устройствами без ошибок, мы добавили параметр '''write_address'''.
| |
| | |
| ==== Писать можно, читать нельзя ====
| |
| Допустим, в нашем устройстве есть такой регистр только для записи.
| |
| | |
| {| border="1" class="wikitable"
| |
| ! Адрес || Тип || Название || Назначение
| |
| |-
| |
| | 20 || Coil || Relay 1 Switch || Управление выходом. Только для записи.
| |
| |-
| |
| |}
| |
| | |
| В этом случае канал надо описывать так:
| |
| <syntaxhighlight lang="json">
| |
| {
| |
| "name": "Relay 1 Switch",
| |
| "write_address": "20",
| |
| "reg_type": "holding",
| |
| "type": "pushbutton",
| |
| "format": "u16",
| |
| "group": "channels",
| |
| "on_value": 1 // определяет, что записывать в регистр при нажатии
| |
| }
| |
| </syntaxhighlight>
| |
| | |
| ==== Писать в один регистр, читать из другого====
| |
| Допустим, в нашем устройстве команда записывается в один регистр, а читается из другого.
| |
| | |
| {| border="1" class="wikitable"
| |
| ! Адрес || Тип || Название || Назначение
| |
| |-
| |
| | 20 || Coil || Relay 1 Switch|| Управление выходом. Только для записи.
| |
| |-
| |
| | 21 || Discrete Input || Relay 1 State|| Состояние выхода. Только для чтения.
| |
| |-
| |
| |}
| |
| | |
| В этом случае канал надо описывать так — у нас будет один контрол, а при работе с устройством, записываться будет один регистр, а читаться другой:
| |
| <syntaxhighlight lang="json">
| |
| {
| |
| "name": "Relay 1",
| |
| "write_address": "20", // адрес, куда мы записываем команды
| |
| "address": "21", // адрес, по которому мы читаем состояние
| |
| "reg_type": "holding",
| |
| "type": "switch",
| |
| "format": "u16",
| |
| "group": "channels"
| |
| }
| |
| </syntaxhighlight>
| |