Wb-mqtt-serial driver: различия между версиями
Строка 447: | Строка 447: | ||
== Примеры файла конфигурации == | == Примеры файла конфигурации == | ||
В примерах мы описывали устройства в самом файле конфигурации, но при их большом количестве | В примерах мы описывали устройства в самом файле конфигурации, но при их большом количестве описание устройств можно вынести в [[Драйвер wb-mqtt-serial:Примеры написания шаблонов | шаблоны]]. | ||
=== Одно устройство на шине RS-485 === | === Одно устройство на шине RS-485 === |
Версия 16:57, 28 января 2021
ВНИМАНИЕ: Драйвер wb-mqtt-serial ранее назывался wb-homa-modbus, а конфигурационный файл /etc/wb-mqtt-serial.conf
как /etc/wb-homa-modbus.conf
. Учитывайте это, если используете устаревшие прошивки.
Описание
Драйвер wb-mqtt-serial
отвечает за работу с подключенными по RS-485 устройствами в контроллере Wiren Board. Он обеспечивает работу с устройствами через систему MQTT-сообщений.
Полное описание драйвера смотрите в репозитории на Github.
Поддерживаемые устройства
Поддерживается работа с:
- Периферийными устройствами Wiren Board с интерфейсом Modbus: модули реле, диммеры, счётчики импульсов, датчики и т.п.
- Устройствами сторонних производителей, работающих по протоколу Modbus.
- Некоторыми устройствами, использующими протоколы ADICON, A-BUS, Uniel, Милур, ИВТМ, Пульсар, Меркурий 230, Энергомера ГОСТ МЭК 61107, НЕВА МТ 32х ГОСТ МЭК 61107. Полный список поддерживаемых устройств можно посмотреть в таблице Протестированные устройства сторонних производителей.
Поддержка устройств различных протоколов на одной шине
Использовать устройства с разными протоколами на одной шине возможно, но необходимо учитывать особенности конкретных протоколов.
Например, фреймы устройств Unitel начинаются с байта 0xff
, а устройств ИВТМ — с байта 0x24
. В случае с протоколами Modbus, Меркурий 230 и Милур первым байтом фрейма является идентификатор slave, поэтому при совмещении таких устройств нужно внимательно подходить к выбору slave id.
У устройств Милур slave id по умолчанию равен 0xff
, что приведет к конфликту с устройствами Unitel. Также устройства Милур требуют дополнительных задержек при опросе и при использовании на одной шине с другими устройствами могут снизить скорость опроса.
Иногда устройства, работающие на разных протоколах могут конфликтовать между собой: устройства с поддержкой протокола A-BUS не могут работать на одной шине с устройствами Unitel.
Рекомендуем придерживаться проверенной формулы комбинации протоколов на одной шине: Modbus + Милур (slave_id != 0xff) + Uniel
. Учитывайте, что сторонние производители устройств могут вносить недокументированные изменения в протокол, поэтому перед покупкой устройства желательно убедиться в работоспособности выбранного решения.
Доработка драйвера для поддержки новых устройств
Вы можете самостоятельно добавить поддержку новых modbus-устройств при помощи шаблонов.
Если у вас возникли проблемы с составлением шаблона или выбранное вами устройство имеет свой протокол обмена данными — свяжитесь с нами и мы постараемся помочь.
Управление драйвером
Обычно драйвер запускается автоматически при загрузке контроллера и перезапускается при изменении файла конфигурации в веб-интерфейсе.
Также можно управлять драйвером в ручном режиме — это может быть полезно для поиска ошибок в конфигурационном файле или если вам нужно освободить порт для использования modbus_client.
Для выполнения команд подключитесь к контроллеру по SSH. Доступны команды:
service wb-mqtt-serial stop #остановить драйвер
service wb-mqtt-serial start #запустить драйвер
service wb-mqtt-serial restart #перезапустить драйвер
wb-mqtt-serial -c /etc/wb-mqtt-serial.conf -d #запустить драйвер в отладочном режиме с указанием пути к конфигурационному файлу
Файл конфигурации драйвера
Перед использованием драйвер нужно настроить. Конфигурация драйвера хранится в файле /etc/wb-mqtt-serial.conf
.
Структура файла
Файл /etc/wb-mqtt-serial.conf
имеет структуру порты (ports)
→ устройства (devices)
→ каналы (channels)
: в файле есть описание физических портов контроллера, внутри них — список устройств подключенных к этому порту, а внутри устройств описаны каналы.
Для каждого порта указываются настройки: скорость, чётность и т.п., а также протокол: Modbus, RTU и т.п.
Для каждого устройства обязательно указывается его уникальный адрес на шине — slave_id
. Все доступные параметры и варианты значений перечислены в примере файла /etc/wb-mqtt-serial.conf
:
{
// опция debug включает или выключает отладочную печать.
// Опция -d командной строки wb-mqtt-serial также
// включает отладочную печать и имеет приоритет над
// данной опцией.
"debug": false,
// Задаёт интервал в секундах, в течение которого неизменяющиеся значения не будут публиковаться в MQTT.
// По истечении интервала полученное значение будет опубликовано, даже если оно не изменилось.
// Если установлен 0, каждое полученное от устройств значение будет опубликовано в MQTT.
// Если установлено отрицательное значение, то значения будут публиковаться только при изменении. Это поведение по умолчанию.
"max_unchanged_interval": -1,
// список портов
"ports": [
{
// тип порта:
// - "serial": последовательные порты RS-485 или RS-232. Это значение выбирается по умолчанию.
// - "tcp": serial over TCP/IP. Пакеты, формируемые для работы с последовательными портами, передаются без изменений через TCP/IP.
// - "modbus tcp": передача по MODBUS TCP. В секции устройств с таким типом порта могут использоваться только те, что поддерживают MODBUS.
"port_type": "serial",
// устройство, соответствующее порту RS-485 (если выбран тип порта serial)
"path" : "/dev/ttyNSC0",
// IP адрес или имя хоста (если выбран тип порта TCP или MODBUS TCP)
"address": "127.0.0.1",
// TCP порт (если выбран тип порта TCP или MODBUS TCP)
"port": 3000,
// скорость порта
"baud_rate": 9600,
// паритет - N, O или E (по умолчанию - N)
"parity": "N",
// количество бит данных (по умолчанию - 8)
"data_bits": 8,
// количество стоп-бит
"stop_bits": 2,
// Минимальный интервал опроса каждого регистра
// по-умолчанию для устройств, подключенных к порту,
// в миллисекундах
"poll_interval": 10,
// Максимальное время ответа устройств, подключенных к этому порту, в миллисекундах
// Если не установлено, то принимается равным 500 мс
// Этот параметр задан в шаблонах описания устройств, переопределять его можно только в случае некорректной работы с устройствами
"response_timeout_ms": 100,
// Дополнительная задержка перед каждой отправкой данных в порт в микросекундах
"guard_interval_us": 1000,
// Таймаут соединения (только для TCP или MODBUS TCP порта).
// Если в течение указанного времени ни по одному устройству на порту не поступило данных (а также истек "connection_max_fail_cycles"),
// TCP соединение будет разорвано и произойдет попытка переподключения
"connection_timeout_ms": 5000,
// Количество неудачных циклов опроса (только для TCP или MODBUS TCP порта)
// Если в течение указанного количества циклов опроса ни по одному устройству на порту не поступило данных (а также истек "connection_timeout_ms"),
// TCP соединение будет разорвано и произойдет попытка переподключения
"connection_max_fail_cycles": 2,
// включить/выключить порт. В случае задания
// "enabled": false опрос порта и запись значений
// каналов в устройства на данном порту не происходит.
// По умолчанию - true.
"enabled": true,
// список устройств на данном порту
"devices" : [
{
// тип устройства, в системе должен быть корректный шаблон для этого типа
"device_type": "MSU34+TLP",
// отображаемое имя устройства. Публикуется как
// .../meta/name в MQTT
"name": "MSU34+TLP",
// уникальный идентификатор устройства в MQTT.
// каждое элемент в devices должен иметь уникальный id
// topic'и, относящиеся в MQTT к данному устройству,
// имеют общий префикс /devices/<идентификатор топика>/...
"id": "msu34tlp",
// идентификатор устройства.
// Если не указан или указана пустая строка, то используются широковещательные запросы
"slave_id": 2,
// включить/выключить устройство. В случае задания
// "enabled": false опрос устройства и запись значений
// его каналов не происходит. По умолчанию - true.
"enabled": true,
// протокол передачи устройства, если не задан, то используется "modbus"
"protocol": "modbus",
// максимальное количество считываемых "пустых" регистров.
// Драйвер в целях оптимизации может считывать регистры
// "пачкой". При этом, если какие-либо регистры не
// были включены в конфигурацию, но в целях ускорения
// опроса (чтобы не разрывать "пачку") их всё-таки
// можно считывать, можно указать значение max_hole_size
// больше 0. В данный момент поддерживается только
// устройствами Modbus.
"max_reg_hole": 10,
// то же самое, что max_reg_hole, но для однобитовых
// регистров (coils и discrete inputs в Modbus). В данный
// момент поддерживается только устройствами Modbus.
"max_bit_hole": 80,
// максимальное количество регистров в одной пакетной операции
// чтения. В данный момент поддерживается только устройствами
// Modbus.
"max_read_registers": 10,
// Минимальный интервал опроса регистров данного устройства в миллисекундах
"poll_interval": 10,
// Максимальное время ответа устройства в миллисекундах.
// Если не установлено, то принимается равным 500 мс.
// Если значение этого параметра, установленное для порта, больше указанного здесь, используется значение порта.
// Этот параметр задан в шаблонах описания устройств, переопределять его можно только в случае некорректной работы с устройством.
"response_timeout_ms": 100,
// Минимально необходимая задержка между посылками в миллисекундах.
// Используется в некоторых протоколах для определения границ посылок.
// Этот параметр задан в шаблонах описания устройств, переопределять его можно только в случае некорректной работы с устройством.
// По умолчанию 20 мс
"frame_timeout_ms": 100,
// Дополнительная задержка перед каждой отправкой данных в порт в микросекундах.
// Если не установлено, то используется значение, заданное в соответствующем параметре порта.
"guard_interval_us": 0,
// (При возникновении ошибки) Интервал после последнего успешного обмена данными с устройством,
// по истечении которого (а также "device_max_fail_cycles") устройство будет помечено отключенным и будет опрашиваться в ограниченном режиме
"device_timeout_ms": 3000,
// Количество неудачных циклов опроса устройства
// Если в течение указанного количества полных циклов опроса ни по одному регистру устройства не поступило данных (а также истек "device_timeout_ms"),
// устройство будет помечено отключенным и будет опрашиваться в ограниченном режиме
"device_max_fail_cycles": 2,
// пароль для доступа к устройству, массив байт
"password": [1, 2, 3],
// уровень доступа при опросе устройства,
// используется для обмена с счётчиками электроэнергии
"access_level": 1,
// список каналов устройства
"channels": [
{
// имя канала. topic'и, соответствующие каналу,
// публикуются как
// /devices/<идентификатор канала>/controls/<имя канала>
"name" : "Temp 1",
// тип регистра
// возможные значения для Modbus:
// "coil" - 1 бит, чтение/запись
// "discrete" - 1 бит, только чтение
// "holding" - 16 бит, чтение/запись, код функции на запись выбирается автоматически, в зависимости от размера
// "input" - 16 бит, только чтение
// "holding_single" - то же что и holding однако регистры записываются всегда по одному, кодом 06
// "holding_multi" - то же что и holding однако регистры записываются всегда кодом 16
"reg_type" : "input",
// адрес регистра
"address" : 0,
// тип элемента управления, например,
// "temperature", "text", "switch"
// Тип wo-switch задаёт вариант switch,
// для которого не производится опрос регистра -
// для таких каналов возможна только запись.
"type": "temperature",
// формат канала. Задаётся для регистров типа
// "holding" и "input". Возможные значения:
// "u16" - беззнаковое 16-битное целое
// (используется по умолчанию)
// "s16" - знаковое 16-битное целое
// "u8" - беззнаковое 8-битное целое
// "s8" - знаковое 8-битное целое
// "u32" - беззнаковое 32-битное целое (big-endian).
// (занимает 2 регистра, начиная с указанного)
// "s32" - знаковое 32-битное целое (big-endian).
// (занимает 2 регистра, начиная с указанного)
// "s64" - знаковое 64-битное целое (big-endian).
// (занимает 4 регистра, начиная с указанного)
// "u64" - беззнаковое 64-битное целое (big-endian).
// (занимает 4 регистра, начиная с указанного)
//
// "float" - число с плаваяющей точкой IEEE 754. 32 bit. (big-endian).
// (занимает 2 регистра, начиная с указанного)
// "double" - число с плаваяющей точкой двойной точности IEEE 754. 64 bit. (big-endian).
// (занимает 4 регистра, начиная с указанного)
// "char8" - однобайтовый символ в кодировке ASCII
"format": "s8",
// Порядок 16-битных слов для каналов, имеющих размер больше 16 бит.
// Возможные значения:
// "big_endian" (по-умолчанию): [0xAA 0xBB] [0xCC 0xDD] => 0xAABBCCDD
// "little_endian": [0xAA 0xBB] [0xCC 0xDD] => 0xCCDDAABB
"word_order" : "big_endian",
// для регистров типа coil и discrete
// с типом отображения switch/wo-swich
// также допускается задание on_value -
// числового значения, соответствующего
// состоянию "on" (см. ниже)
// минимальный интервал опроса данного регистра в миллисекундах
"poll_interval": 10,
// значение, получаемое при последовательном чтении диапазона регистров, если устройство не поддерживает запрашиваемый регистр.
// Этот параметр используется некоторыми протоколами, чтобы определить доступность регистров устройства.
"unsupported_value": "0xFFFE",
// максимальное значение регистра, используется для построения интерфейса онлайн-конфигуратора
"max": 100,
// коэффициент, на который умножается значение регистра перед публикацией в MQTT
"scale": 0.5,
// значение, которое прибавляется к значению регистра перед публикацией в MQTT
"offset": -12.5,
// порядок, до которого будет округляться значение после всех преобразований
"round_to": 0.1,
// доступен ли канал для записи через MQTT
"readonly": true,
// значение, которое будет записано в регистр, при записи единицы в on-топик в MQTT
"on_value": "0xFF",
// значение регистра, полученное от устройства, которое обозначает ошибку
"error_value": "0xAA"
},
{
// Ещё один канал
"name" : "Illuminance",
"reg_type" : "input",
"address" : 1,
"type": "text"
},
{
"name" : "Pressure",
"reg_type" : "input",
"address" : 2,
"type": "text",
"scale": 0.075
},
{
"name" : "Temp 2",
"reg_type" : "input",
"address" : 3,
"type": "temperature",
"format": "s8"
}
]
},
{
// ещё одно устройство на канале
"name": "DRB88",
"id": "drb88",
"enabled": true,
"slave_id": 22,
// секция инициализации
"setup": [
{
// название регистра (для отладки)
// Выводится в случае включённой отладочной печати.
"title": "Input 0 type",
// адрес holding-регистра
"address": 1,
// значение для записи
"value": 1
},
{
"title": "Input 0 module",
"address": 3,
"value": 3 // was: 11
}
],
"channels": [
{
"name" : "Relay 1",
"reg_type" : "coil",
"address" : 0,
"type": "switch"
},
{
"name" : "Relay 2",
"reg_type" : "coil",
"address" : 1,
"type": "switch"
},
// ...
{
"name" : "Input 2",
"reg_type" : "input",
"address" : 1,
"type": "switch",
// значение, соответствующее состоянию "on"
"on_value": 101
},
{
"name" : "Input 3",
"reg_type" : "input",
"address" : 2,
"type": "switch",
"on_value": 101
},
// ...
]
}
]
},
{
// ещё один порт со своим набором устройств
"path" : "/dev/ttyNSC1",
"baud_rate": 9600,
"parity": "N",
"data_bits": 8,
"stop_bits": 1,
"poll_interval": 100,
"enabled": true,
"devices" : [
{
"name": "tM-P3R3",
"id": "tmp3r3",
"enabled": true,
"slave_id": 1,
"channels": [
{
"name" : "Relay 0",
"reg_type" : "coil",
"address" : 0,
"type": "switch"
},
// ...
]
},
// ...
]
}
]
}
Редактирование через веб-интерфейс
Мы рекомендуем изменять конфигурацию драйвера через веб-интерфейс. Процедура настройки подробно описана в статье RS-485:Настройка через веб-интерфейс.
Внесение изменений вручную
Будьте внимательны при редактировании файла конфигурации вручную — в отличие от редактирования через веб-интерфейс, вы можете допустить синтаксическую ошибку и драйвер не запустится.
- Ознакомьтесь с инструкцией Просмотр файлов контроллера с компьютера и выберите удобный для вас способ.
- Впишите конфигурацию для портов и подключенных устройств в файл. Смотрите примеры.
- Чтобы описанные в файле устройства появились в веб-интерфейсе, перезагрузите контроллер или выполните команду:
service wb-mqtt-serial restart
- Если устройство не появилось, то можно узнать причину — выполните команду
systemctl status wb-mqtt-serial
и в последних двух строчках ответа будет подсказка. В примере файл содержит синтаксическую ошибку во второй строке на 14 позиции:~# systemctl status wb-mqtt-serial ● wb-mqtt-serial.service - MQTT Driver for serial devices Loaded: loaded (/lib/systemd/system/wb-mqtt-serial.service; enabled; vendor preset: enabled) Active: inactive (dead) since Thu 2021-01-28 15:10:51 +04; 4s ago Process: 23682 ExecStart=/usr/bin/wb-mqtt-serial (code=exited, status=0/SUCCESS) Main PID: 23682 (code=exited, status=0/SUCCESS) Jan 28 15:10:47 wirenboard-A6XXXT2R systemd[1]: Started MQTT Driver for serial devices. Jan 28 15:10:51 wirenboard-A6XXXT2R wb-mqtt-serial[23682]: ERROR: [serial] Failed to parse JSON /etc/wb-mqtt-serial.conf:* Line 2, Column 14 Jan 28 15:10:51 wirenboard-A6XXXT2R wb-mqtt-serial[23682]: Syntax error: value, object or array expected.
Примеры файла конфигурации
В примерах мы описывали устройства в самом файле конфигурации, но при их большом количестве описание устройств можно вынести в шаблоны.
Одно устройство на шине RS-485
Выведем среднеквадратичное значение напряжения на фазе L1 со счетчика WB-MAP3E fw2. В примере счетчик подключен к serial-порту /dev/ttyRS485-1
, работает по протоколу Modbus и имеет адрес 142
.
{
// отладка выключена
"debug" : false,
// список портов
"ports" :
[
{
// тип порта
"port_type" : "serial",
// устройство, соответствующее порту RS-485 (если выбран тип порта serial)
"path" : "/dev/ttyRS485-1",
// скорость порта
"baud_rate" : 9600,
// количество бит данных
"data_bits" : 8,
// количество стоп-бит
"stop_bits" : 2,
// паритет - N, O или E
"parity" : "N",
// включить опрос устройства
"enabled" : true,
// минимальный интервал опроса каждого регистра в миллисекундах
"poll_interval" : 10,
// список устройств на порту /dev/ttyRS485-1
"devices" :
[
{
// отображаемое имя устройства
"name" : "WB-MAP3E fw2",
// протокол передачи устройства
"protocol" : "modbus",
// идентификатор устройства на шине
"slave_id" : "142",
// список каналов устройства
"channels" :
[
{
// адрес регистра
"address" : "0x1410",
// формат канала
"format" : "u32",
// имя канала
"name" : "Urms L1",
// тип регистра
"reg_type" : "input",
// порядок, до которого будет округляться значение после всех преобразований
"round_to" : 0.001,
// коэффициент, на который умножается значение регистра перед публикацией в MQTT
"scale" : 1.52588e-07,
// тип элемента управления
"type" : "voltage"
}
]
}
]
}
]
}
Несколько подключенных устройств
Выведем среднеквадратичное значение напряжения на фазе L1 со счетчика WB-MAP3E fw2 и температуру с датчика MSW3.
В примере устройства работают по протоколу Modbus: счетчик WB-MAP3E подключен к serial-порту /dev/ttyRS485-1
с адресом 142
, а датчик MSW3 подключен к serial-порту /dev/ttyRS485-2
и имеет адрес 22
.
{
// отладка выключена
"debug" : false,
// список портов
"ports" :
[
{
// тип порта
"port_type" : "serial",
// устройство, соответствующее порту RS-485 (если выбран тип порта serial)
"path" : "/dev/ttyRS485-1",
// скорость порта
"baud_rate" : 9600,
// количество бит данных
"data_bits" : 8,
// количество стоп-бит
"stop_bits" : 2,
// четность - N, O или E
"parity" : "N",
// включить опрос устройства
"enabled" : true,
// минимальный интервал опроса каждого регистра в миллисекундах
"poll_interval" : 10,
// список устройств на порту /dev/ttyRS485-1
"devices" :
[
{
// отображаемое имя устройства
"name" : "WB-MAP3E fw2",
// протокол передачи устройства
"protocol" : "modbus",
// идентификатор устройства на шине
"slave_id" : "142",
// список каналов устройства
"channels" :
[
{
// адрес регистра
"address" : "0x1410",
// формат канала
"format" : "u32",
// имя канала
"name" : "Urms L1",
// тип регистра
"reg_type" : "input",
// порядок, до которого будет округляться значение после всех преобразований
"round_to" : 0.001,
// коэффициент, на который умножается значение регистра перед публикацией в MQTT
"scale" : 1.52588e-07,
// тип элемента управления
"type" : "voltage"
}
]
}
]
},
{
// тип порта
"port_type" : "serial",
// устройство, соответствующее порту RS-485 (если выбран тип порта serial)
"path" : "/dev/ttyRS485-2",
// скорость порта
"baud_rate" : 9600,
// количество бит данных
"data_bits" : 8,
// количество стоп-бит
"stop_bits" : 2,
// четность - N, O или E
"parity" : "N",
// включить опрос устройства
"enabled" : true,
// минимальный интервал опроса каждого регистра в миллисекундах
"poll_interval" : 10,
// список устройств на порту /dev/ttyRS485-2
"devices" :
[
{
// отображаемое имя устройства
"name" : "MSW3",
// протокол передачи устройства
"protocol" : "modbus",
// идентификатор устройства на шине
"slave_id" : "22",
// список каналов устройства
"channels" :
[
{
// адрес регистра
"address" : "0x0000",
// формат канала
"format" : "s16",
// имя канала
"name" : "Temp",
// тип регистра
"reg_type" : "input",
// порядок, до которого будет округляться значение после всех преобразований
"round_to" : 0.5,
// коэффициент, на который умножается значение регистра перед публикацией в MQTT
"scale" : 0.1,
// тип элемента управления
"type" : "temperature"
}
]
}
]
}
]
}
Включение отладки
Иногда нужно включить отладочный режим драйвера. Это можно сделать из командной строки или через веб-интерфейс.
Включение отладки через веб-интерфейс:
- Зайдите в веб-интерфейс Settings → Configs → Serial Device Driver Configuration
- Установите флажок Enable debug logging
- Нажмите на кнопку Save, чтобы сохранить настройки.
Теперь в файл /var/log/messages
будут записываться отправленные и принятые драйвером пакеты.
ВНИМАНИЕ: при включенной отладке лог-файл будет быстро расти, поэтому не забудьте отключить отладку, когда необходимость в ней отпадет.