Connecting & Integrating a Modbus/TCP Server

How to connect a Modbus/TCP server to Connectware.

This guide walks you through connecting a Modbus/TCP server to Connectware. You will learn how to:

  1. Identify relevant Modbus datapoints.

  2. Create a service commissioning file.

  3. Install the service using the Connectware Admin UI.

  4. Verify your data in the Data Explorer.

By the end, you will be able to collect live data from your Modbus-enabled device and publish it to MQTT topics for integration with other systems.

The example service commissioning files used in this guide are available in the Example Files Repository on GitHub.

Prerequisites

To follow this guide, you will need the following:

Example Setup

For this example, we assume that you have a device of the type Janitza UMG 604-EP PRO installed on your Ethernet network. This device measures and analyzes electric power quality and is equipped with a Modbus/TCP server.

Step 1 - Identify the Datapoints

The UMG 604-EP PRO provides thousands of Modbus address points. For this example, we will retrieve:

  • The current day of the month

  • Real power values for L1, L2, L3

  • Utility frequency

From the Modbus address list for UMG 604-PRO, we find the following date and time registers:

Address
Format
Designation
Unit
Remarks

0

long64

_REALTIME

2 ns

Time (UTC)

4

int

_SYSTIME

sec

Time (UTC)

6

short

_DAY

Day (1 .. 31)

7

short

_MONTH

Month (0=Jan, .. 11=Dec)

8

short

_YEAR

Year

9

short

_HOUR

h

Hour (1 .. 24)

10

short

_MIN

min

Minute (1 .. 59)

11

short

_SEC

s

Second (1 .. 59)

12

short

_WEEKDAY

Weekday , (0=Sun .. 6=Sat)

And these electrical measurements:

Address
Format
Designation
Unit
Remarks

19000

float

_G_ULN[0]

V

Voltage L1-N

19002

float

_G_ULN[1]

V

Voltage L2-N

19004

float

_G_ULN[2]

V

Voltage L3-N

19006

float

_G_ULL[0]

V

Voltage L1-L2

19008

float

_G_ULL[1]

V

Voltage L2-L3

19010

float

_G_ULL[2]

V

Voltage L3-L1

19012

float

_G_ILN[0]

A

Apparent current, L1-N

19014

float

_G_ILN[1]

A

Apparent current, L2-N

19016

float

_G_ILN[2]

A

Apparent current, L3-N

19018

float

_G_I_SUM3

A

Vector sum; IN=I1+I2+I3

19020

float

_G_PLN[0]

W

Real power L1-N

19022

float

_G_PLN[1]

W

Real power L2-N

19024

float

_G_PLN[2]

W

Real power L3-N

19026

float

_G_P_SUM3

W

Psum3=P1+P2+P3

19028

float

_G_SLN[0]

VA

Apparent power L1-N

19030

float

_G_SLN[1]

VA

Apparent power L2-N

19032

float

_G_SLN[2]

VA

Apparent power L3-N

19034

float

_G_S_SUM3

VA

Sum; Ssum3=S1+S2+S3

19036

float

_G_QLN[0]

var

Reactive power L1 (fundamental comp.)

19038

float

_G_QLN[1]

var

Reactive power L2 (fundamental comp.)

19040

float

_G_QLN[2]

var

Reactive power L3 (fundamental comp.)

19042

float

_G_Q_SUM3

var

Qsum3=Q1+Q2+Q3 (fundamental comp.)

19044

float

_G_COS_PHI[0]

-

CosPhi; UL1 IL1 (fundamental comp.)

19046

float

_G_COS_PHI[1]

-

CosPhi; UL2 IL2 (fundamental comp.)

19048

float

_G_COS_PHI[2]

-

CosPhi; UL3 IL3 (fundamental comp.)

19050

float

_G_FREQ

Hz

Measured frequency

The documentation includes a table defining the size and range of data types used in the Format column, which we need for specifying our endpoints:

Type
Size
Minimum
Maximum

char

8 bit

0

255

byte

8 bit

-128

127

short

16 bit

-2^15

2^15-1

int

32 bit

-2^31

2^31-1

uint

32 bit

0

2^32-1

long64

64 bit

-2^63

2^63-1

float

32 bit

IEEE 754

IEEE 754

double

64 bit

IEEE 754

IEEE 754

Step 2 - Creating the Service Commissioning File

The service commissioning file contains parameters that describe the resources necessary to collect and provide data for our application. It includes information about connections, data endpoints, and mappings that Connectware reads. For more information on the structure of service commissioning files, see Service Commissioning Files.

To get started, open a text editor and create a new file, e.g., modbus-example-commissioning-file.yml. The service commissioning file uses YAML format, which is readable by both humans and machines. We'll define the following required sections:

  • Description

  • Metadata

  • Parameters

  • Resources

Description and Metadata

These sections contain general information about the service commissioning file. You can provide a short description and add metadata. For metadata, only the name is required while the rest is optional. We'll use the following information for this guide:

description: >
  Modbus/TCP Example Commissioning File
  How to connect and integrate a Modbus/TCP server
  https://docs.cybus.io/documentation/machine-connectivity/connecting-and-integrating-a-modbus-tcp-server

metadata:
  name: Modbus/TCP Example Commissioning File
  version: 1.0.0
  icon: https://www.cybus.io/wp-content/uploads/2019/03/Cybus-logo-Claim-lang.svg
  provider: cybus
  homepage: https://www.cybus.io

Parameters

Parameters allow users to customize service commissioning files for multiple use cases by referencing them within the file. Each time a service commissioning file is applied or reconfigured in Connectware, users are asked to enter custom values for the parameters or confirm the default values.

parameters:
  modbusHost:
    type: string
    description: Modbus/TCP Host
    default: 192.168.123.123

  modbusPort:
    type: integer
    description: Modbus/TCP Port
    default: 502

We're defining the host address details of our Modbus/TCP server as parameters, so they serve as defaults but can be customized to connect to different servers.

Resources

In the resources section, we declare every resource needed for our application. The first resource we need is a connection to the Modbus/TCP server.

resources:
  modbusConnection:
    type: Cybus::Connection
    properties:
      protocol: Modbus
      connection:
        host: !ref modbusHost
        port: !ref modbusPort

After naming our resource (modbusConnection), we define the resource type and its type-specific properties. For Cybus::Connection, we declare which protocol and connection parameters to use. For details about different resource types and available protocols, see Resources.

For the connection definition, we reference the previously declared parameters modbusHost and modbusPort using !ref.

Next, we need the data points selected earlier. Let's add those by extending our resources list with endpoints.

dayOfMonth:
  type: Cybus::Endpoint
  properties:
    protocol: Modbus
    connection: !ref modbusConnection
    subscribe:
      fc: 3
      length: 1
      interval: 2000
      address: 6
      dataType: int16BE

realPowerL1:
  type: Cybus::Endpoint
  properties:
    protocol: Modbus
    connection: !ref modbusConnection
    subscribe:
      fc: 3
      length: 2
      interval: 2000
      address: 19020
      dataType: floatBE

realPowerL2:
  type: Cybus::Endpoint
  properties:
    protocol: Modbus
    connection: !ref modbusConnection
    subscribe:
      fc: 3
      length: 2
      interval: 2000
      address: 19022
      dataType: floatBE

realPowerL3:
  type: Cybus::Endpoint
  properties:
    protocol: Modbus
    connection: !ref modbusConnection
    subscribe:
      fc: 3
      length: 2
      interval: 2000
      address: 19024
      dataType: floatBE

frequency:
  type: Cybus::Endpoint
  properties:
    protocol: Modbus
    connection: !ref modbusConnection
    subscribe:
      fc: 3
      length: 2
      interval: 2000
      address: 19050
      dataType: floatBE

Each Cybus::Endpoint resource requires a protocol definition and the connection it uses. You can easily reference the previously declared connection by name. We also need to define which Modbus address the endpoint should read from by specifying the function code fc, length, interval, address, and dataType.

Function Code

The function code fc defines the operation type. To learn about different codes and their purposes, consult resources like Simply Modbus. However, function code implementation may vary between manufacturers. Which function code to use depends on your device and its register addressing structure, so check your device documentation. For our example device, we can use function code 3 or 4 to read analog values, so we use 3.

Length

Length describes how many registers to read starting at the specified address. Modbus device registers are 16 bits long. For the day of month value in short format, the format table shows it's 16 bits, so we use length 1. For other endpoints, we use length 2 since float format is 32 bits, requiring two registers.

Interval

Optionally, we can define the poll interval in milliseconds, specifying how frequently values are requested from the server (default: 1000 ms). To reduce bandwidth, we set our endpoints' interval to 2000 ms.

Address

From the device's Modbus address list, we found datapoints for:

  • Day of month at address 6

  • Real power L1-L3 at addresses 19020, 19022, and 19024

  • Frequency at address 19050

Data Type

The dataType property is optional, but without it you'll receive buffer values that require manual parsing. To avoid this, we define data types for power values and frequency as floatBE (the address list indicates float format and Big-Endian byte sequence).

For the "dayOfMonth" endpoint, the format is short, which corresponds to a 16-bit integer according to the format table. We define this data type as int16BE. For all available Modbus data types, see Modbus Endpoint Properties.

MQTT Mapping

At this point, we can read values from the Modbus/TCP server and monitor them in the Data Explorer or on default MQTT topics. To achieve data flow that satisfies our integration requirements, we may need to add a mapping resource to publish data on topics matching our MQTT topic structure.

mapping:
  type: Cybus::Mapping
  properties:
    mappings:
      - subscribe:
          endpoint: !ref dayOfMonth
        publish:
          topic: 'janitza/status/day'
      - subscribe:
          endpoint: !ref realPowerL1
        publish:
          topic: 'janitza/measurement/realpower/1'
      - subscribe:
          endpoint: !ref realPowerL2
        publish:
          topic: 'janitza/measurement/realpower/2'
      - subscribe:
          endpoint: !ref realPowerL3
        publish:
          topic: 'janitza/measurement/realpower/3'
      - subscribe:
          endpoint: !ref frequency
        publish:
          topic: 'janitza/measurement/frequency'

This mapping defines which endpoint values are published on which MQTT topics. For write operations to your device, reverse the data flow and map from MQTT topic to the corresponding endpoint:

- subscribe:
    topic: 'janitza/control/setvalue'
  publish:
    endpoint: !ref valueToSet

You can then write to the endpoint by publishing to this MQTT topic. Write messages must be in JSON format containing the value:

{
  "value": true
}

This message has the mandatory value key, which can contain any data type (matching the endpoint):

  • Boolean values: true/false

  • Integers: 3

  • Decimals: 10.45

  • Strings: "quotes"

Step 3 - Installing and Enabling the Service

You can now install and enable the service.

  1. Install the service commissioning file. See Installing Services.

  2. Enable the service. See Enabling Services.

With a properly written service commissioning file, confirming the installation dialog will create a service that manages all defined resources:

  • Connection to the Modbus/TCP server

  • Endpoints collecting data from the server

  • Mappings controlling data access

After enabling this service, you can verify that everything works correctly.

Step 4 - Verifying the Data

Now that we have established a connection between the Modbus/TCP server and Connectware, go to the Data Explorer to see the tree structure of our newly created data points.

Data is provided on MQTT topics in JSON format containing timestamp and value keys, where the value represents data as received from the device:

{
  "value": "2020-07-14T11:43:06.632Z",
  "timestamp": 1594726986632
}

Summary

You have successfully:

  • Located relevant Modbus addresses from the device documentation.

  • Created a service commissioning file with parameters, connection, endpoints, and MQTT mapping.

  • Installed the service in Connectware.

  • Verified the data flow in the Data Explorer.

Your Modbus/TCP device is now fully integrated with Connectware, enabling real‑time data publishing over MQTT.

Last updated

Was this helpful?