A simple modbus (RTU) UDP proxy.
Requires Node.js.
npm install
npm start
This was specifically designed to integrate modbus systems with the
eibPort but can be used for
other purposes as well. The proxy sends periodic updates for certain modbus
registers over UDP. It also listens for commands over UDP. Valid commmands
areread
(to manually request a register update) and write
(to write data).
It is possible to connect to multiple modbus networks if you have more than one rs485 adapters connected.
The important part is in the config.json, here's an example of that file with inline comments. Note that this is not a valid configuration because of its comments (proper json can't have comments).
{
"localport": 51100, // Port used to listen for commands
"host": "192.168.1.250", // Host of remote client
"port": 51100, // Port of remote client
"defaultPoll": "00 * * * * *", // Cron pattern for default poll interval
"modbusNetworks": [ // Array of modbus networks, one per serial adapter
{
"name": "ftx", // Identifies the modbus network
"serialport": "/dev/rs485",
"options": {
"baudrate": 9600,
"parity": "none"
},
"registers": [{ // Array of register objects
"id": "temp_setpoint", // Identifies the register, use only [a-zA-Z0-9_] characters
"slaveid": 1, // The modbus slave owning the register
"type": "holding", // Type of register (holding, input, coil, discrete)
"address": 0, // Register address
"converter": "tenths", // [Optional] Converter method to use on the input data, see separate section in Readme.
"length": 1, // [Optional] Defaults to 1 but some modbus slaves use two or more registers per value
}
]
},
{
"name": "alpha",
"serialport": "/dev/ttyUSB3",
"options": {
"baudrate": 9600,
"parity": "even"
},
"registers": [{
"id": ["dhw_time", "dhw_setpoint"], // In case you want to read multiple adjacents registers, identify them in an array
"slaveid": 3,
"type": "input",
"address": 206, // This is now the starting address (of dhw_time in this case), dhw_Setpoint will be 207, etc.
"writeOnAllChanges": true // [Optional] Will write all requests (default to only if value has changed)
}, {
"id": ["import_wh", "_", // _ can be used as name for registers that should be ignored
"export_wh"],
"slaveid": 4,
"type": "input",
"address": 72,
"length": 2,
"converter": "float32" // Again, see separate section in Readme for converter methods.
}
]
}
]
}
The proxy listens for incoming UDP messages on the specified port. The format is [register id] [command] [parameter]
. E.g. temp_setpoint write 20
. Valid commands are write
for writing values and read
for manually requesting a register value. Read has no parameters, temp_setpoint read
.
The proxy sends register values to the specified host and port using UDP. The format is [register id] [value]
, e.g. temp_setpoint 21
. Proxy polls modbus registers using the crontab pattern specified in defaultPoll
. It can also poll a single specific register manually when receiving the read
command over UDP.
In case you want to read multiple adjacent registers you can do so by specifying their identifiers in an array, see example json above. Not only does it make your configuration smaller, it's also a performance optimization since the proxy is able to read multiple registers in one single modbus request.
The length
key is optional and defaults to 1. I.e. a value is stored in one (2 byte) register. Sometimes slaves stores values using two or more registers. E.g. a 4 byte value can be stored in two registers. Use length
to specify how many registers are used per value.
Often it is required for register values to be converted before sending them off to the receiver. Currently there are two converter methods. tenths
for dividing the input with 10. E.g. if a register would represent a temperature value like 10.5 (°C) as 105. float32
is used to convert two registers into a floating point value. This needs to be used in conjunction with length: 2
since it requires 4 bytes for certain modbus slaves.
Do you need a certain converter method for you slave? Create an issue.
This proxy was written specifically for eibPort although it can be used for other purposes as well. eibPort is a device that connects to your smart home and offers visualization and logical functions. It does not communicate directly with modbus, however it has support for receiving and transmitting UDP messages. modbus-udp integrates modbus networks with the eibPort.