Skip to content

Instantly share code, notes, and snippets.

@dirkjanfaber
Last active April 21, 2023 13:13
Show Gist options
  • Save dirkjanfaber/c54f2b4e3cb525d3232018c6144cbd12 to your computer and use it in GitHub Desktop.
Save dirkjanfaber/c54f2b4e3cb525d3232018c6144cbd12 to your computer and use it in GitHub Desktop.
Victron Modbus

This subflow tries to make it easier to use modbus tcp to query and modify Victron Energy equipment via modbus tcp. By default the subflow will try to connect to 127.0.0.1.

Victron Modbus flow

It requires the following node to be added to the palette before installing the subflow:

Installing the subflow is a matter of copying the flow below and pasting it via the Import menu. (ctrl-i)

Unit ID

The Unit ID of the device you want to query can be found via the Remote Console under Settings -> Modbus TCP devices -> Devices.

Attribute

Copy and paste the object you want to retrieve (or set) from the attributes.csv file from the GitHub site of the dbus_modbustcp project.

For example com.victronenergy.system,/Serial,s,,800,string[6],1,R for retrieving the serial code of the device.

Writing

Check the write box to write instead of query a value. In case of a string value, you can just inject the value to write. E.g. "Open" or "Closed" for a relay.

[
{
"id": "7742727e898dc6b9",
"type": "subflow",
"name": "Victron Modbus",
"info": "# Victron Modbus\n\nThis subflow tries to make it easier to use modbus tcp to query and modify _Victron Energy_ equipment via modbus tcp. By default the subflow will try to connect to `venus.local`.\n\n# Unit ID\n\nThe Unit ID of the device you want to query can be found via the Remote Console under _Settings -> Modbus TCP devices -> Devices_. \n\n# Attribute\n\nCopy and paste the object you want to retrieve (or set) from the [attributes.csv](https://github.com/victronenergy/dbus_modbustcp/blob/master/attributes.csv) file from the GitHub site of the `dbus_modbustcp` project.\n\nFor example `com.victronenergy.system,/Serial,s,,800,string[6],1,R` for retrieving the serial code of the device.\n\n# Writing\n\nCheck the _write_ box to write instead of query a value. In case of a string value, you can just inject the value to write. E.g. \"Open\" or \"Closed\" for a relay. ",
"category": "",
"in": [
{
"x": 320,
"y": 100,
"wires": [
{
"id": "1b2eeae9df886105"
}
]
}
],
"out": [
{
"x": 1100,
"y": 60,
"wires": [
{
"id": "15838f3ecd0abad4",
"port": 0
}
]
},
{
"x": 1080,
"y": 140,
"wires": [
{
"id": "fa1dd608a1f582ad",
"port": 1
},
{
"id": "3b847bba50de7eb2",
"port": 1
}
]
}
],
"env": [
{
"name": "Unit ID",
"type": "num",
"value": "100",
"ui": {
"icon": "font-awesome/fa-id-card-o",
"type": "input",
"opts": {
"types": [
"num"
]
}
}
},
{
"name": "Attributes",
"type": "str",
"value": "com.victronenergy.system,/Serial,s,,800,string[6],1,R",
"ui": {
"icon": "font-awesome/fa-dot-circle-o",
"type": "input",
"opts": {
"types": [
"str"
]
}
}
},
{
"name": "Write",
"type": "bool",
"value": "false",
"ui": {
"type": "checkbox"
}
}
],
"meta": {
"module": "Victron Modbus",
"version": "0.0.1",
"author": "Dirk-Jan Faber <dfaber@victronenergy.com>",
"desc": "Query Victron Equipment via Modbus",
"keywords": "victron,modbus",
"license": "GPL-3.0"
},
"color": "#3FADB5",
"icon": "@victronenergy/node-red-contrib-victron/victronenergy.svg"
},
{
"id": "1b2eeae9df886105",
"type": "function",
"z": "7742727e898dc6b9",
"name": "Pre process",
"func": "//\"com.victronenergy.temperature,/Humidity,u,%,3306,uint16,10,R\"\n\nvar a = env.get('Attributes').split(',')\nvar quantity = 1;\nvar value = msg.payload;\n\nif (a[5].match(/string/)) {\n quantity = parseInt(a[5].replace(/\\D+/g, ''))\n}\n\nif (a[5].match(/32/)) {\n quantity = 2\n}\n\nmsg.type = a[5].replace(/\\[[0-9]\\]/, '');\nmsg.scalefactor = a[6];\nmsg.unit = a[3];\nmsg.topic = env.get('Unit ID') + ': ' + a[1];\n\nif (typeof(msg.payload) == 'string') {\n var enums = {}\n msg.unit.split(';').forEach((e) => {\n let b = e.split('=');\n enums[b[1]] = b[0]\n });\n value = enums[msg.payload]\n}\n\n\nmsg.payload = {\n value: value,\n 'fc': 3,\n 'unitid': env.get('Unit ID'),\n 'address': parseInt(a[4]),\n 'quantity': quantity }\n\n\nif (env.get('write')) {\n return [ null, msg ];\n} else {\n return [ msg, null ];\n}",
"outputs": 2,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 470,
"y": 100,
"wires": [
[
"fa1dd608a1f582ad"
],
[
"3b847bba50de7eb2"
]
]
},
{
"id": "15838f3ecd0abad4",
"type": "function",
"z": "7742727e898dc6b9",
"name": "Process result",
"func": "msg.raw = msg.payload;\n\nswitch (msg.type) {\n case 'int16':\n msg.payload = msg.payload[0]\n if ((msg.payload & 0x8000) > 0) {\n msg.payload -= 0x10000;\n }\n break;\n case 'uint16':\n msg.payload = msg.payload[0]\n break;\n case 'int32':\n msg.payload = msg.payload[0] << 16 | msg.payload[1];\n if ((msg.payload & 0x8000) > 0) {\n msg.payload -= 0x10000;\n }\n break;\n case 'uint32':\n msg.payload = msg.payload[0] << 16 | msg.payload[1];\n break;\n case 'string':\n var b = ''\n msg.payload.forEach(x => {\n b += String.fromCharCode(x >> 8)\n b += String.fromCharCode(x & 0xff)\n })\n msg.payload = b;\n break;\n default:\n node.warn('unknown type '+msg.type)\n}\n\nif (msg.type !== 'string' && msg.scalefactor) {\n msg.payload = msg.payload / msg.scalefactor;\n}\n\nif (msg.unit.match(/;/)) {\n var enums = {}\n msg.unit.split(';').forEach((e) => {\n let b = e.split('=');\n enums[b[0]] = b[1]\n });\n msg.payload = enums[msg.payload];\n}\n\nreturn msg;",
"outputs": 1,
"noerr": 0,
"initialize": "",
"finalize": "",
"libs": [],
"x": 980,
"y": 60,
"wires": [
[]
]
},
{
"id": "fa1dd608a1f582ad",
"type": "modbus-flex-getter",
"z": "7742727e898dc6b9",
"name": "Modbus device",
"showStatusActivities": false,
"showErrors": true,
"showWarnings": true,
"logIOActivities": false,
"server": "c6a81cdc28c37a68",
"useIOFile": false,
"ioFile": "",
"useIOForPayload": false,
"emptyMsgOnFail": false,
"keepMsgProperties": true,
"delayOnStart": false,
"startDelayTime": "",
"x": 700,
"y": 80,
"wires": [
[
"15838f3ecd0abad4"
],
[]
]
},
{
"id": "3b847bba50de7eb2",
"type": "modbus-flex-write",
"z": "7742727e898dc6b9",
"name": "",
"showStatusActivities": false,
"showErrors": false,
"showWarnings": true,
"server": "c6a81cdc28c37a68",
"emptyMsgOnFail": false,
"keepMsgProperties": false,
"x": 710,
"y": 140,
"wires": [
[
"15838f3ecd0abad4"
],
[]
]
},
{
"id": "c6a81cdc28c37a68",
"type": "modbus-client",
"z": "7742727e898dc6b9",
"name": "localhost",
"clienttype": "tcp",
"bufferCommands": true,
"stateLogEnabled": false,
"queueLogEnabled": false,
"failureLogEnabled": true,
"tcpHost": "127.0.0.1",
"tcpPort": "502",
"tcpType": "DEFAULT",
"serialPort": "/dev/ttyUSB",
"serialType": "RTU-BUFFERD",
"serialBaudrate": "9600",
"serialDatabits": "8",
"serialStopbits": "1",
"serialParity": "none",
"serialConnectionDelay": "100",
"serialAsciiResponseStartDelimiter": "0x3A",
"unit_id": "1",
"commandDelay": "1",
"clientTimeout": "1000",
"reconnectOnTimeout": true,
"reconnectTimeout": "2000",
"parallelUnitIdsAllowed": true
},
{
"id": "a32304237dc6af7e",
"type": "subflow:7742727e898dc6b9",
"z": "5c28b5b5a1eb9c0b",
"name": "Serial ID",
"x": 640,
"y": 200,
"wires": [
[
"815d928bbf9e0369"
],
[]
]
}
]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment