Previous Topic

Next Topic

Book Contents

Book Index

Modbus Simulator JSON Configuration

Overview

On this page you will find explanation of how and what can be configured using the json configuration. This json configuration can be used to initialize the Modbus Slave Device Simulator, but in addition this configuration can be used to create a Modbus Device. Here is how a json configuration file would look like. Actually the following example shows basically everything that might be configured. From now on, by Discrete Object we will mean a coil, or discrete input, by Register we will mean input or holding register and by Modbus Object we will mean any Discrete Object or Register.

Simulator Configuration

{

"deviceConfiguration": {

    "id": "1234567890",

        "oidPrefix": "1.3.6.1.4.1.46863.218",

        "type": "Modbus",

        "connections": [{

            "type": "TCP_IP",

            "port": "502"

        }]

    },

    "sensors": [{

        "id": "101",

        "address": 10,

        "objectType": "inputRegister",

        "dataDefinition": {

            "dataType": "int16",

            "valueType": "Measurement Value",

            "initialValue": 1000,

            "min": 10,

            "max": 100

        },

        "automation": {

            "values": [10, 20, 30, 40, 50, 60]

        }

    }, {

        "id": "102",

        "address": 50,

        "objectType": "holdingRegister",

        "dataDefinition": {

            "dataType": "int16",

            "valueType": "Measurement Value",

            "min": 100,

            "max": 1000,

            "factor": 10,

            "offset": 100000

        },

        "automation": {

            "values": [100, 200, 300, 400, 500]

        }

    }, {

        "id": "103",

        "address": 51,

        "objectType": "holdingRegister",

        "dataDefinition": {

            "dataType": "int32",

            "valueType": "Notification Value"

        },

        "dataAccessChannels": [{

            "type": "Modbus_TCP",

            "refreshRate": 2,

            "minimalMeaningfulValueDifference": 0.5,

            

        }],

        "automation": {

            "values": [100000, 200000, 3000000, 40000000]

        }

    }, {

        "id": "104",

        "address": 10,

        "objectType": "coil",

        "dataDefinition": {

            "dataType": "bool",

            "valueType": "Alarm",

            "referenceObjectId": "103",

            "valueChangeNotificationCondition": "valueIncremented"

        },

        "automation": {

            "values": [1, 1, 0, 0, 1, 0]

        }

    }, {

        "id": "105",

        "address": 11,

        "objectType": "coil",

        "dataDefinition": {

            "dataType": "bool",

            "valueType": "Warning"

        },

        "automation": {

            "values": [3, 2, 1, 0]

        }

    }, {

        "id": "106",

        "address": 13,

        "objectType": "discreteInput",

        "dataDefinition": {

            "dataType": "bool",

            "valueType": "Measurement Value"

        },

        "automation": {

            "values": [1, 0, 1, 0, 1, 0]

        }

    }, {

        "id": "107",

        "address": 14,

        "objectType": "discreteInput",

        "dataDefinition": {

            "dataType": "bool",

            "valueType": "Notification Value"

        }

    }, {

        "id": "108",

        "address": 510,

        "objectType": "inputRegister",

        "initialValue": "hi",

        "dataDefinition": {

            "dataType": "char[10]",

            "valueType": "Notification Value"

        },

        "automation": {

            "values": ["hello", "world"]

        }

    }, {

        "id": "109",

        "address": 516,

        "objectType": "holdingRegister",

        "dataDefinition": {

            "dataType": "int16",

        },

        "automation": {

            "values": [15, 20, 25, 30, 35, 40, 45, 50],

            "interval": 10

        }

    }, {

        "id": "110",

        "address": 12,

        "objectType": "coil",

        "dataDefinition": {

            "dataType": "char[5]",

            "valueType": "Warning"

        },

        "automation": {

            "values": ["11100", "101010"]

        }

    }, {

        "id": "111",

        "address": 17,

        "objectType": "coil",

        "dataDefinition": {

            "dataType": "int8",

            "valueType": "Warning"

        },

        "automation": {

            "values": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20]

        }

    }, {

        "id": "112",

        "address": 25,

        "objectType": "coil",

        "dataDefinition": {

            "dataType": "char[1]",

            "valueType": "Warning"

        },

        "automation": {

            "values": ["1", "0", "0"]

        }

    }]

}

Configuration Description

Some of the items in the json configuration are used only when creating a Modbus Master Device with this configuration. In here we will describe only the ones used by the simulator.

We can split the configuration on two parts – the first one describes how the simulator can connect with the other devices and the second one describes the data model of the simulator.

  1. General Device Parameters:
  2. Sensors – This json array describes fully the data model of the simulator. The idea behind the sensors is simple. In a real slave device some sensors would track some physical activity and write this in the data model. In our simulator the physical activity can be actually automated, but the principle is the same. The sensor gets some data and writes it somewhere in the device memory. This part of the memory can be a group of Discrete Inputs, a group of Coils, a group of Input Registers, or a group of Holding Registers. The implementation supports 65535 coils, 65535 discrete inputs, 65535 input registers and 65535 holding registers. An important point is that two sensors can overlap.

Data Types

The Simulator does not actually make any difference between the data types. These data types are used when configuring a device to communicate with this simulator. The various data types are used exclusively to get the count of registers the sensor is going to occupy.

Here we will add detailed explanation of the supported data types.

Value to Modbus Objects Mapping

The simulator understands two types of Java objects – String and Long. The configuration parser converts the Double and Float values to Long value, and then provides these to the simulator. Here is how the Long and String values are converted to Registers and Discrete Objects.

Long Value

As Registers

The Least significant 16 bits are taken as an integer value and are written in the base address of the sensor, if the sensor occupies more than one Register, then the next 16-bit are taken and written in the nest register and so on, until all of the registers are filled.

As Discrete Object

The least significant bit is taken and written in the first Discrete Object, then the next bit is written in the next Discrete Object and so on, until all of the Discrete Objects assigned to this sensor are written.

String Value

As Registers

The first character is put as the most significant byte and the next one as the least significant byte of the first register. If the sensor spans on more than one register the next two characters are written in the next register and so on, until all of the registers are filled.

As Discrete Object

If the first character is '1' then the first Discrete Object is raised, i.e. 1 is written in it. otherwise it is a zero. If there is another discrete object, and another character they are processed in the same manner. If the length of the String value is less than the Discrete Objects count then these discrete objects are filled with zeroes. There is some small trick here. If the string itself equals "true" then all of the Discrete Objects will be filled with ones.