Skip to content

Modbus Support

Modbus is an alternative data communication protocol commonly used by certain pieces of equipment like electric meters. Unlike BACnet, it has very limited support for complex data types or automatic discovery; generally, a device profile is required in order to interpret the data from a Modbus device.

A device profile specifies the data type for each Modbus register as well as provides a useful name. In order to integrate a Modbus device using Normal, you must first create a profile; then, you may create one or more connections to different devices using that profile.

Creating a Modbus Profile

A device profile contains a list of register addresses along with data types and associated human-readable names for these registers. Profiles may be created directly using the Modbus API; but most users will probably use nfcli, which supports importing profiles from csv files.

A profile is simply a CSV file with the required columns, as shown below. Additionally, some configuration variables such as the endianness may be set in the header.

# this file is named skylogger.csv
# uuid: d4a12bx8-03a9-11ed-a97c-a30ea19188b1
# profileName: 170321_skytron_ModbusList
# endianness: ENDIAN_BIG
# highWordFirst: true
Register Type,Name,Address,Data Type,Unit
3,Temp. Channel 1 "Module temperature",10,FLOAT32,°C
3,Temp. Channel 2 "Ambient temperature",12,FLOAT32,°C
3,Radiation Channel 1,20,FLOAT32,W/m2, 1
3,Radiation yield Channel 1,FLOAT32,Wh/m2
$ nfcli create-modbus-profile skylogger.csv

Once the profile has been created, you may create a connection to it; you can also see the currently installed profiles using nfcli list-modbus-profiles.

Devices usually come with documentation including the modbus register map for your device. You may also be able to fine one someone else has created and convert it to this format; for instance, Contemporary Controls publishes many maps in a similar format.

Connecting to a Modbus device

Once you have created a profile for device, you must create a connection for each instance of a device.

$ nfcli create-modbus-connection -p d4a12bb8-03a9-11ed-a97c-a30ea19188b1 -a tcp://192.168.103.190:502 -n "test"

In this example, the UUID must be the ID of a profile you have importted; and the url string is the address of the Modbus device. You may also provide a human readable name to help identify the connection.

Profile Format

A profile file consists of two sections: a header with commented lines; and a body consisting of a list of registers. The header allows configuration of several device parameters. Although the profiles are usually loaded to and from CSV files, the format is defined by CreateDeviceProfile.

Header parameter Description
uuid A uuid to uniquely identify this profile
profileName A user-friendly name for the profile
endianness The endianness to use when converting registers. Either ENDIAN_BIG (default) or ENDIAN_LITTLE.
highWordFirst When converting types which span multiple registers, if the first register contains the high word. Default true; or false

The body consists of a header, followed by zero or more registers. The possible column headers are:

Header Name Description
Register Type The type of modbus register: 1 (coil), 2 (discrete), 3 (holding), or 4 (input) register
Data Type The data type of the register data. Valid values are: INT16, UINT16, UINT32, INT32, FLOAT32, FLOAT64. Note that conversion for raw registers are controlled by the endianness and highWordFirst parameters in the header.
Address The Modbus register index
Scale Factor A floating-point scale factor to multiple the raw register value by. Default 1.0.
Offset An offset value to add to the raw value, after the scale factor has been applied. Default 0.0
Name A string providing a user-visible name for the register
Units A string containing an non-normalized units name.