Skip to content

Commit

Permalink
Add Modbus protocol support to port/Load RPC (#805)
Browse files Browse the repository at this point in the history
  • Loading branch information
KraPete authored Sep 12, 2024
1 parent adfaf68 commit c122344
Show file tree
Hide file tree
Showing 32 changed files with 1,504 additions and 1,137 deletions.
58 changes: 58 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ It's designed to be used on [Wiren Board](https://wirenboard.com/en/) family of
- [Диаграмма таймаутов цикла опроса](#диаграмма-таймаутов-цикла-опроса)
- [Объединенное чтение регистров и его авто-отключение](#объединенное-чтение-регистров-и-его-авто-отключение)
- [Прямое чтение и запись в порт](#прямое-чтение-и-запись-в-порт)
- [Чтение и запись по протоколу Modbus](#чтение-и-запись-по-протоколу-modbus)
- [Протоколы](#протоколы)
- [Поддержка различных протоколов на одной шине](#поддержка-различных-протоколов-на-одной-шине)
- [Широковещательные сообщения](#широковещательные-сообщения)
Expand Down Expand Up @@ -963,6 +964,63 @@ It's designed to be used on [Wiren Board](https://wirenboard.com/en/) family of
RPC Client <- {"error":{"code":-32600,"data":"Request handler is not responding @ src/rpc_handler.cpp:179","message":"Request timeout"},"id":1,"result":null}
```

### Чтение и запись по протоколу Modbus

Существует возможность выполнить запись и чтение регистров произвольного устройства по протоколу Modbus посредством MQTT RPC запроса. Выполнение запроса встраивается в цикл опроса устройств таким образом, что запрос выполнится с высоким приоритетом сразу после окончания текущего цикла опроса.
Для упрощенного использования данного функционала написана [Python-библиотека](https://github.com/wirenboard/python-mqtt-rpc/). Также по [ссылке](https://github.com/wirenboard/modbus-utils-rpc) доступна утилита для работы с modbus-устройствами при помощи RPC-функционала wb-mqtt-serial.
Для выполнения запроса необходимо отправить в топик `wb-mqtt-serial/port/Load/client_id`, где client_id - произвольное имя клиента, посылающего запрос, сообщение типа JSON со следующими параметрами:

#### Параметры

|Параметр |Тип |Значение по умолчанию |Описание |
|------------------|-------------|----------------------|---------|
|`protocol` |обязательный |`modbus` |протокол обмена с устройством
|`slave_id` |обязательный | |адрес устройства
|`function` |обязательный | |код Modbus-команды
|`address` |обязательный | |адрес первого Modbus-регистра
|`count` |опциональный | 1 |число Modbus-регистров
|`msg` |опциональный | |только данные Modbus-запроса, если необходимо
|`format` |опциональный |`STR` |при указании значения `STR` содержимое параметра `msg` интерпретируется как строка и передается в порт как есть. При указании значения `HEX` содержимое `msg` интерпретируется как шестнадцатеричная строка и перед отправкой в порт преобразуется в массив байт
|`response_timeout`|опциональный |500 ms |таймаут чтения первого байта в миллисекундах
|`frame_timeout` |опциональный |20 ms |таймаут чтения каждого последующего байта в миллисекундах
|`total_timeout` |опциональный |10000ms |таймаут выполнения RPC-запроса в миллисекундах

##### Обязательные параметры запроса в последовательный порт
|Параметр |Описание |
|-----------|---------|
|`path` |путь к последовательному порту, в который будет отправлено сообщение
|`baud_rate`|скорость порта
|`parity` |чётность - N, O или E
|`data_bits`|количество бит данных
|`stop_bits`|количество стоп-бит

##### Обязательные параметры запроса в TCP порт
|Параметр |Описание |
|---------|---------|
|`ip` |IP-адрес клиента, которому будет отправлено сообщение
|`port` |номер порта на указанном адресе клиента

В качестве ответа в топике `wb-mqtt-serial/port/Load/client_id/reply` будет опубликовано сообщение типа JSON со следующими параметрами:

|Параметр | Описание|
|---------|---------|
|`result`|В случае неуспешного выполнения запроса содержит `null`. В случае успешного выполнения содержит в себе поле `response` или `exception`. Если при запросе в поле `format` было указано `STR`, значение поля `response` представляет собой только данные ответа, и передается запрашивающей стороне как есть. В случае значения `HEX` содержимое поля представляет собой шестнадцатеричную строку. Если устройство вернуло ответ с ошибкой, то передаётся поле `exception`, содержащее структуру из двух полей `code` и `msg`. Где `code` - код Modbus-исключения, `msg` - его текстовая расшифровка.
|`id`| Порядковый номер запроса|
|`error`|В случае успешного выполнения запроса содержит значение `null`. В ином случае содержит параметры, приведенные в таблице ниже

|Параметр|Описание|
|--------|--------|
|`message`|Строка с кратким описанием ошибки|
|`code`| Код ошибки. Возможные коды ошибок приведены в таблице ниже|
|`data`| Строка с подробным описанием места и условий возникновения ошибки|

|Код ошибки|Описание|
|----------|--------|
|`-32700`|Ошибка разбора JSON запроса|
|`-32000`|Ошибка выполнения запроса|
|`-32600`|Таймаут выполнения запроса|


### Прямая установка параметров связи устройства

Существует возможность выполнить прямую установку параметров связи Modbus-устройства Wiren Board с помощью MQTT RPC запроса. Выполнение запроса встраивается в цикл опроса устройств таким образом, что запрос выполнится с высоким приоритетом сразу после окончания текущего цикла опроса.
Expand Down
6 changes: 6 additions & 0 deletions debian/changelog
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
wb-mqtt-serial (2.141.0) stable; urgency=medium

* Add Modbus protocol support to port/Load RPC

-- Petr Krasnoshchekov <[email protected]> Wed, 11 Sep 2024 12:38:24 +0500

wb-mqtt-serial (2.140.0) stable; urgency=medium

* Add WB-MAO4-20mA support
Expand Down
2 changes: 0 additions & 2 deletions src/devices/modbus_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,6 @@ void TModbusDevice::WriteRegisterImpl(PRegister reg, const TRegisterValue& value
Modbus::WriteRegister(*ModbusTraits,
*Port(),
SlaveId,
0,
*reg,
value,
ModbusCache,
Expand All @@ -92,7 +91,6 @@ void TModbusDevice::WriteSetupRegisters()
Modbus::WriteSetupRegisters(*ModbusTraits,
*Port(),
SlaveId,
0,
SetupItems,
ModbusCache,
DeviceConfig()->RequestDelay,
Expand Down
1 change: 1 addition & 0 deletions src/devices/modbus_device.h
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
#include <stdint.h>
#include <string>

#include "serial_config.h"
#include "serial_device.h"

#include "modbus_common.h"
Expand Down
2 changes: 0 additions & 2 deletions src/devices/modbus_io_device.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,6 @@ void TModbusIODevice::WriteRegisterImpl(PRegister reg, const TRegisterValue& val
Modbus::WriteRegister(*ModbusTraits,
*Port(),
SlaveId,
0,
*reg,
value,
ModbusCache,
Expand All @@ -102,7 +101,6 @@ void TModbusIODevice::WriteSetupRegisters()
Modbus::WriteSetupRegisters(*ModbusTraits,
*Port(),
SlaveId,
0,
SetupItems,
ModbusCache,
DeviceConfig()->RequestDelay,
Expand Down
Loading

0 comments on commit c122344

Please sign in to comment.