Wolkabout / WolkGatewayModule-Modbus

WolkGateway module for connecting Modbus devices to WolkAbout IoT Platform by communicating with WolkGateway.

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

WolkGateway Module Modbus

WolkGateway module for connecting Modbus devices to WolkAbout IoT Platform by communicating with WolkGateway.

Supported protocol(s):

  • Wolkabout Protocol

Installing from source

This repository must be cloned from the command line using:

git clone --recurse-submodules https://github.com/Wolkabout/WolkGatewayModule-Modbus.git

Prerequisite

Following tools/libraries are required in order to build WolkGateway Module Modbus

  • cmake - version 3.5 or later
  • autotools
  • automake
  • autoconf
  • g++
  • m4
  • zlib1g-dev
  • libtool
  • openssl

Former can be installed on Debian based system from terminal by invoking:

sudo apt-get install automake g++ autotools-dev autoconf m4 zlib1g-dev cmake libtool libssl-dev

Afterwards dependencies are built, and Makefile build system is generated by invoking:

./configure

Generated build system is located inside out directory To build the module, invoke:

cd out
make -j$(nproc)
sudo make install

Installing will place the application in PATH, and create a systemctl unit, which you can use with:

sudo service modbus_module status/start/stop/restart

The configuration files used are placed in /etc/modbusModule/, which you should configure before you start your service. If you don't know how to configure the module, continue on to the next part.

Configuring Module

Module configuration consists of 2 configurations files

  • moduleConfiguration.json
  • devicesConfiguration.json

Below are sections describing each of these configuration files that need to be edited with the parameters of your modbus devices before running the application. These files are located in out directory, and are passed to Modbus module executable in following manner:

./modbusModule moduleConfiguration.json devicesConfiguration.json

moduleConfiguration.json

Module configuration file contains settings that relate to communication with WolkGateway, and outgoing Modbus connection, reading period time and response timeout.

{
  "mqttHost": "tcp://localhost:1883",
  // Address of local MQTT broker (connection with WolkGateway) 
  "connectionType": "SERIAL/RTU",
  // Modbus connection type, choice between "SERIAL/RTU" and "TCP/IP" 
  "tcp/ip": {
    // TCP/IP connection properties (ignored if connectionType is "SERIAL/RTU")
    "host": "192.168.x.x",
    // IP address of Modbus server (mandatory if connectionType is "TCP/IP") 
    "port": 502
    // Port of Modbus server (default is 502, if not stated)
  },
  "serial/rtu": {
    // Serial/RTU connection properties (ignored if connectionType is "TCP/IP") 
    "serialPort": "SERIAL_PORT",
    // Serial port location such as /dev/ttyS0 (mandatory if connection type is "SERIAL/RTU")
    "baudRate": 115200,
    // Baud rate for serial connection (default is 115200, if not stated)
    "dataBits": 8,
    // DataBits for Modbus RTU (default is 8, if not stated) 
    "stopBits": 1,
    // StopBits for Modbus RTU (default is 1, if not stated)
    "bitParity": "NONE"
    // BitParity for Modbus RTU, can be "NONE", "EVEN", "ODD" (default is "NONE", if not stated)
  },
  "responseTimeoutMs": 200,
  // Wait time for respond from slaves/servers (default is 200, if not stated)
  "registerReadPeriodMs": 500
  // Period of reading all registers/devices (default is 500, if not stated) 
}

devicesConfiguration.json

Devices configuration file contains information necessary to define templates, which include registers that bind to Wolkabout IoT Platform sensors/actuators/alarms/configurations, and then devices, with their information, and a template. This is the guide by which the module will register devices, and then send data for.

You define templates, that are described by their name, and mappings.

{
  "templates": [
    {
      "name": "<TEMPLATE_NAME>",
      "mappings": [
        // define mappings
      ]
    }
  ]
}

After doing so, you define all the mappings inside a template.

Single mapping includes one or more Modbus registers that produce a single sensor/actuator/alarm/configuration on a device, on the platform. They're characterized by a name, and a reference key, used to identify them, by their register type (necessary), data type (necessary), operation type (necessary for some output types), and mapping type.

Register types:

  • Read & Write:

    • COIL
    • HOLDING_REGISTER
  • Read Only:

    • INPUT_REGISTER
    • INPUT_CONTACT
  • Data types:

    • UINT16/INT16
    • BOOL
    • UINT32/INT32 (with merge operations)
    • FLOAT (with merge operation)
    • STRING (with stringify operations)
  • Operation types:

    • MERGE_BIG_ENDIAN or MERGE_LITTLE_ENDIAN (in combination with "dataType": "UINT32/INT32")
    • MERGE_FLOAT (in combination with "dataType": "FLOAT")
    • TAKE_BIT (in combination with "dataType": "BOOL")
    • STRINGIFY_ASCII or STRINGIFY_UNICODE (in combination with "dataType": "STRING")

Mappings are by default registered as:

  • Sensors for read only types
  • Actuator for read & write types

You can override this behaviour by adding a field to the mapping, stating one of the next types ("mappingType"):

  • SENSOR
  • ACTUATOR
  • ALARM - only for INPUT_CONTACT
  • CONFIGURATION - only for COIL and HOLDING_REGISTER_ACTUATOR
{
  // Inside of a template
  "name": "<TEMPLATE_NAME>",
  "mappings": [
    {
      "name": "mappingName",
      // Register name
      "reference": "mappingReference",
      // Unique reference used to differ register on WolkAbout IoT Platform
      "minimum": -32768,
      // Minimum value that can be held in register. Required for visualization on WolkAbout IoT Platform
      "maximum": 32767,
      // Maximum value that can be held in register. Required for visualization on WolkAbout IoT Platform
      "address": 0,
      // Register address
      "registerType": "INPUT_REGISTER",
      // Register type - "INPUT_REGISTER" or "HOLDING_REGISTER_ACTUATOR" or "HOLDING_REGISTER_SENSOR" or "INPUT_CONTACT" or "COIL"
      "dataType": "INT16"
      // Data type stored in register - "INT16" or "UINT16" or "REAL32" for "INPUT_REGISTER"/"HOLDING_REGISTER_ACTUATOR"/"HOLDING_REGISTER_SENSOR" register type, and "BOOL" for "COIL"/"INPUT_CONTACT"
    },
    {
      "name": "mappingName2",
      "reference": "mappingReference2",
      "minimum": -4000,
      "maximum": 4000,
      "address": 1,
      "registerType": "HOLDING_REGISTER",
      "dataType": "FLOAT",
      "deadbandValue": 4.0,
      // Optional - Indicates a change in value of the mapping that is insignificant data. Applicable to numeric mappings.
      "frequencyFilterValue": 250
      // Optional - When register changes value often, disregard changes until X milliseconds pass since last accepted value.
    },
    {
      "name": "mappingName3",
      "reference": "mappingReference3",
      "address": 1,
      "registerType": "INPUT_CONTACT",
      "dataType": "BOOL",
      "mappingType": "ALARM"
      // This is where for the first time, we override the default Mapping type
    },
    {
      "name": "mappingName4",
      "reference": "mappingReference4",
      "address": 2,
      "registerType": "HOLDING_REGISTER",
      "operationType": "MERGE_BIG_ENDIAN",
      "dataType": "UINT32",
      "mappingType": "CONFIGURATION"
    },
    {
      "name": "mappingReference5",
      "reference": "mappingReference5",
      "address": 3,
      "registerType": "COIL",
      "dataType": "BOOL",
      "writeOnly": true
      // If the mapping needs to be Write-Only, you put this attribute.
    },
    {
      "name": "mappingReference6",
      "reference": "mappingReference6",
      "address": 10,
      "addressCount": 10,
      "registerType": "HOLDING_REGISTER",
      "dataType": "STRING",
      "operationType": "STRINGIFY_ASCII"
    },
    {
      "name": "mappingReference7",
      "reference": "mappingReference7",
      "address": 8,
      "bitIndex": 0,
      "registerType": "INPUT_REGISTER",
      "operationType": "TAKE_BIT",
      "dataType": "BOOL"
    }
  ]
}

After you completely defined a template, you can list a device.

{
  "devices": [
    {
      "name": "<DEVICE_NAME>",
      // User readable device name, necessary to register a device
      "key": "<DEVICE_KEY>",
      // Unique device key
      "slaveAddress": 1,
      // Slave address (obligatory if connection type is "SERIAL/RTU"), must be unique in this list 
      "template": "<TEMPLATE_NAME>"
      // Name of defined template 
    }
    // other devices
  ]
  // templates
}

In "TCP/IP" mode, device count is maxed at 1, and you don't need to state a slaveAddress for the device.

If the user happens to enter an invalid template name, the device won't be created. Module will function if at least one device is valid. If there are no devices that have been inputted correctly, the module will exit out, and used will be notified.

About

WolkGateway module for connecting Modbus devices to WolkAbout IoT Platform by communicating with WolkGateway.

License:Apache License 2.0


Languages

Language:C++ 86.9%Language:Shell 7.7%Language:CMake 4.2%Language:Dockerfile 1.2%