UNPKG

@gapit/node-red-contrib-gapit-modbus

Version:

A Node-RED node witch reads Modbus registers based on gapit code JSON schema

311 lines (267 loc) 11.2 kB
# node-red-contrib-gapit-modbus The _gapit-modbus_ <a href="http://nodered.org" target="_new">Node-RED</a> node reads modbus register and decode modbus registers acording to data types specified in the _Gapit code_. The _Gapit code_ structures and names data, preparing it for insertion into a database. The complementary _gapit-results-to-influx-batch_ node transforms the output of this node to the format required by the _influx batch_ node (from `node-red-contrib-influxdb`). So to read a standard set of data and insert it into InfluxDB, a flow like this is all you need: ![Example Flow](images/example_flow.png) Here's a fragment of a _Gapit code_: ```json { "objects": [ { "group_name": "EB Current Bar", "read_priority": 0, "address_type": "dec", "register_type": "holding", "group": [ { "address": 8200, "description": "Breaker 1", "scaling_factor": 1, "unit": "A", "byte_type": "SINT16" }, { "address": 8201, "description": "Breaker 2", "scaling_factor": 0.1, "unit": "A", "byte_type": "SINT32" } ] } ] } ``` This would get inserted into a InfluxDB measurement called "EB Current Bar" (from the _group_name_ field), with fields called "Breaker 1" and "Breaker 2" (from the _description_ field). The output of `gapit-modbus`, which is parsed by `gapit-results-to-influx-batch`, is `msg.gapit_results`. This has the same structure as the _Gapit code_, except with `.value` added for each address. ### Other destinations/databases? If you want to insert the data into a different database, you can parse the `msg.gapit_results` structure, and transform it into the required format. ### gapit-results-to-influx-batch node The gapit-results-to-influx-batch node is packaged as a separate module, `node-red-contrib-gapit-results`, which is automatically installed with this module. It is a packaged as a separate module to enable sharing with other nodes which yield results in the same `msg.gapit_results` structure. The `node-red-contrib-gapit-results` module may be expanded with new nodes in the future. ## Installation ### Install from the Node-RED interface Install using _Manage palette_ -> _Install_. You need to refresh your browser for the `gapit-results-to-influx-batch` node to be available in the node palette. If you are running Node-RED 1.2 or older, you will need to restart Node-RED for it to be visible. If you are using an ancient version of NPM, you will need to manually install `node-red-contrib-gapit-results`. ### Install using the command line Run the following command in your Node-RED user directory - typically `~/.node-red` npm install @gapit/node-red-contrib-gapit-modbus and then restart Node-RED. ## Usage ### Example flow This is the JSON for the flow pictured above. ```json [ { "id": "4baf4f334b779050", "type": "tab", "label": "gapit modbus", "disabled": false, "info": "" }, { "id": "738d78ca6f672b59", "type": "influxdb batch", "z": "4baf4f334b779050", "influxdb": "99e22e92c3be98de", "precision": "", "retentionPolicy": "", "name": "", "database": "modbus", "precisionV18FluxV20": "ms", "retentionPolicyV18Flux": "", "org": "organisation", "bucket": "bucket", "x": 1240, "y": 280, "wires": [] }, { "id": "f1a98ce54346cd03", "type": "gapit-modbus", "z": "4baf4f334b779050", "name": "", "host": "nodered", "port": "502", "deviceName": "123-123-123", "deviceNameDbTag": "uid", "unitId": "1", "gapitCode": "{\"objects\":[{\"group_name\":\"EB Current Bar\",\"read_priority\":0,\"address_type\":\"dec\",\"register_type\":\"holding\",\"group\":[{\"address\":8200,\"description\":\"Breaker 1\",\"scaling_factor\":1,\"unit\":\"A\",\"byte_type\":\"SINT16\"},{\"address\":8201,\"description\":\"Breaker 2\",\"scaling_factor\":0.1,\"unit\":\"A\",\"byte_type\":\"SINT32\"}]}]}", "customTags": "{\"foo\":\"test\",\"baar\":10}", "scalingType": "general", "x": 420, "y": 280, "wires": [["d32ef3b037c73222", "3438922f9c6b25ca"]] }, { "id": "c80bd9f665e8a5b9", "type": "debug", "z": "4baf4f334b779050", "name": "", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "payload", "targetType": "msg", "statusVal": "", "statusType": "auto", "x": 1010, "y": 220, "wires": [] }, { "id": "d32ef3b037c73222", "type": "debug", "z": "4baf4f334b779050", "name": "", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 590, "y": 220, "wires": [] }, { "id": "3438922f9c6b25ca", "type": "gapit-results-to-influx-batch", "z": "4baf4f334b779050", "use_timestamp_from_msg": false, "timestamp_property": "ts", "name": "", "x": 760, "y": 280, "wires": [["738d78ca6f672b59", "c80bd9f665e8a5b9"]] }, { "id": "28060540b4b95271", "type": "inject", "z": "4baf4f334b779050", "name": "", "props": [], "repeat": "1", "crontab": "", "once": false, "onceDelay": 0.1, "topic": "", "x": 170, "y": 280, "wires": [["f1a98ce54346cd03"]] }, { "id": "99e22e92c3be98de", "type": "influxdb", "hostname": "127.0.0.1", "port": "8086", "protocol": "http", "database": "database", "name": "modbus-test", "usetls": false, "tls": "8b3094b6.5fc088", "influxdbVersion": "1.8-flux", "url": "http://influx:8086", "rejectUnauthorized": false }, { "id": "8b3094b6.5fc088", "type": "tls-config", "name": "", "cert": "", "key": "", "ca": "", "certname": "GapitBroker.crt", "keyname": "", "caname": "", "servername": "", "verifyservercert": false } ] ``` ### Supported data types The _Gapit-modbus_ supports these data types. | Parameter | Description | | --------- | ------------------------------------------------------------------------------------------------------ | | BIT1 | Decodes a single bit register to integer value | | BIT16 | Decodes a single bit register to integer value depending on witch bit is selected in the gapit code | | BIT16-SW | Decodes a single bit SW register to integer value depending on witch bit is selected in the gapit code | | BIT32 | Decodes a single bit register to integer value depending on witch bit is selected in the gapit code | | BIT32-SW | Decodes a single bit SW register to integer value depending on witch bit is selected in the gapit code | | UINT8 | Decodes a 8 bit register to unsigned integer value | | UINT16 | Decodes a 16 bit register to unsigned integer value | | UINT32 | Decodes a 32 bit register to unsigned integer value | | UINT64 | Decodes a 16 bit register to unsigned integer value | | SINT16 | Decodes a 16 bit register to signed integer value | | SINT32 | Decodes a 32 bit register to signed integer value | | SINT64 | Decodes a 16 bit register to signed integer value | | FLOAT32 | Decodes a 32 bit register to floating point value | | FLOAT64 | Decodes a 64 bit register to floating point value | | DUMMY16 | Skipping a 16 bit register | | DUMMY32 | Skipping a 32 bit register | | DUMMY64 | Skipping a 64 bit register | | HEX | Decodes a register depending on length specified in the gapit code to a hex decimal value | | ASCII | Decodes a register depending on length specified in the gapit code to a ASCII value | | ASCII-SW | Decodes a SW register depending on length specified in the gapit code to a ASCII value | ### Gapit codes A library of ready-made _Gapit codes_ is forthcoming. ### gapit-modbus The node needs to be configured with, at a minimum: - MODBUS config (IP address, port, Unit ID etc.) - Gapit code | Parameter | Description | | ------------------ | ------------------------------------------------------------------ | | Name | Node name | | Host | Modbus host | | Port | Modbus port | | Device name | The device name database records will be tagged with (e.g. "ups1") | | Device name db-tag | The database tag for device name (e.g. "devname") | | Unit ID | The ID modbus uses to select which unit to read | | Custom tags | Extra tags to add to database records, see below | | Gapit code | The Gapit code JSON | | Scaling | _Specify scaling type_ | #### Custom tags Add database tags, formatted as JSON with `tag_name: value`. Example: ```json { "floor": "1", "room": "101" } ``` ### gapit-results-to-influx-batch To use a Node-RED timestamp with influxdb (enabled by default), add a property containing a timestamp in your inject node. The default name is `msg.ts`. | Parameter | Description | | -------------------------- | -------------------------------------------------------------- | | Name | Node name | | Use timestamp from Message | Use a timestamp injected in the flow (_default on_) | | Timestamp property | The `msg` property to get the timestamp from (_default: "ts"_) | #### N.B.! Check the InfluxDB time precision If using timestamps from Node-RED, note that while this works "out-of-the-box" with InfluxDB v2, you will have to set the `influx batch` node to match the millisecond resolution of Node-RED if you're using InfluxDB v1. You can do this by checking `Advanced Query Options` on the `influx batch` node, and then choosing `Milliseconds (ms)` from the `Time Precision` popup menu.