--- title: "Collector Modbus TCP" slug: "modbus-tcp-collector" tags: ["Modbus TCP", "Data Collection Module", "DCM"] updated: 2026-03-03T08:57:43Z published: 2026-03-03T08:57:43Z canonical: "kb.secomea.com/modbus-tcp-collector" stale: true --- > ## Documentation Index > Fetch the complete documentation index at: https://kb.secomea.com/llms.txt > Use this file to discover all available pages before exploring further. # Collector Modbus TCP The purpose of this article is to be a reference for the Modbus collector part of the full Data Collection Module documentation. The Modbus collector is used to collect samples (data points) from any Modbus enabled equipment, either by using a single collector or multiple collectors if collecting from multiple different devices. ## Config main The Config main (array of objects, mandatory) contain the following fields: | Function | Type | Importance | Description | | --- | --- | --- | --- | | **ConfigName** | string | mandatory | Unique name for this configuration file. Follows the rules for names. | | **ConfigDescription** | string | optional | text describing this configuration. | | **CheckpointInterval** | integer == 0 or >= 60 | optional | The interval with which all data from the internal datasample cache is saved to disk. The more unstable power that the SiteManager has, the more often data should be saved. Saving it often, however, will also cost performance and wear on the storage medium. A value of 0 means that it never checkpoints, otherwise it is an interval in seconds between saves. If not specified the value `900` (15 * 60sec = 15 minutes) is used. | | **AlarmsSaved** | integer >= 4 | optional | The number of alarms saved in the Store and Forward database. If this values is not specified, it will default to `32`. | | **WaitForNTP** | boolean | optional | Synchronize DCM data collection with NTP time. If this parameter is `true`, all DCM collectors will not begin collecting data until NTP is enabled and configured and NTP has synchronized date/time. If not specified, the value is `true`. | Since the JSON format itself doesn't define a comment notation, DCM accepts the field name **comment** with any type of value in any section. Example of comment: ``` "Comment": "Example of a comment for use in any section." ``` ## Modbus Collector main The Collectors (array of objects, mandatory) list elements contain the following fields: | Function | Type | Importance | Description | | --- | --- | --- | --- | | **CollectorName** | string | mandatory | Unique name (within this configuration file) of a device to collect data from (this is the name used in the agent configuration). Follows the normal rules for names. | | **CollectorDescription** | string | optional | Description of this collector. For your use, no system function. | | **CollectorIPAddr** | string | optional | Default IP address (or DNS name) for the device to be polled. The agent Target IP address will take precedence over this. | | **CollectorPortno** | integer > 0 and < 65535 | optional | Default port number for the device to be polled. The agent Target Port Number will take precedence over this. If neither **CollectorPortno** , nor agent Target Port Number, is specified, the appropriate port will be used, depending on the **Protocol** parameter value. | | **Alias** | string | optional | This is the **CollectorName** of another collector from which all the parameters (expect **CollectorName**, **CollectorDescription**, **CollectorIPAddr** and **CollectorPortno**) are copied. An alias cannot refer to another alias. | | **Protocol** | string-enum | mandatory | The protocol used to collect data. Possible values are: `OPC-UA/TCP`, `ModBus/TCP`, `Http/GET` and `Simulator`. | | **ConnectRetryMin** | integer > 0 | mandatory | The minimum number of seconds before trying to reestablish a connection to the device being sampled. An exponential backoff algorithm is used to retry connection establishment, starting after **ConnectRetryMin** and increasing to **ConnectRetryMax**. | | **ConnectRetryMax** | integer > 0 | mandatory | Maximum number of seconds before trying to reestablish a connection to the device being sampled. | | **ModbusAccess** | object | optional | Collection of parameters needed to access a given Modbus server. | | **SamplePoints** | array of objects | mandatory | List of samples to be collected, possibly aggregated and stored in the Store and Forward database. | Example of Modbus object: ``` { "CollectorName": "ModbusGOT", "CollectorDescription": "My first modbus", "Protocol": "ModBus/TCP", "ConnectRetryMin": 2, "ConnectRetryMax": 240, "ModbusAccess": { ... } ``` ## **ModbusAccess** The **ModbusAccess** objects contain the following elements: | Function | Type | Importance | Description | | --- | --- | --- | --- | | **ModbusFCs** | array of objects | mandatory | List of modbus function code (FCs) to be performed during collection of data if the **Protocol** is `ModBus/TCP`. | | **ModbusTimeout** | integer > 0 | optional | Timeout (in millisecs) for all modbus FC requests. If not present, the value `500` is used. | | **ModbusRegswap** | boolean | optional | If `true`, the 16bit register values retrieved will be byte-swapped before being used. If not specified the value is `false`. If `true`, a value of 0x12345678 becomes 0x34127856. | ## **ModbusFCs** The **ModbusFCs** objects contain the following elements: | Function | Type | Importance | Description | | --- | --- | --- | --- | | **ModbusFCID** | integer >= 0 | mandatory | Is a unique ID (within this Collectors element) for this entry. Used by the **SamplePoints** entries. | | **ModbusFCSlaveAddress** | integer >= 0 and <= 247 or 255 | optional | The Modbus Slave Address for this access. Note that this is only used in Modbus gateway devices (and should be between `0` and `247`), whereas true Modbus endpoint devices should use the value `255`. If this is not present, the value `255` is used. | | **ModbusFC** | string-enum | mandatory | Is the type of Modbus function code used when collecting data. Possible values are: `coils` (FC 1), `inputs` (FC 2), `holding-registers` (FC 3) and `input-registers` (FC 4). | | **ModbusFCStart** | integer >= 0 | mandatory | Start address on the Modbus for this access. | | **ModbusFCCount** | integer >= 0 and <= 125 | mandatory | Number of units (bits or registers) to read in one access. | | **ModbusFCSampleInterval** | integer >= 0 | mandatory | Number of seconds between each collection of data using this FC. If the interval is `0`, only event-driven polling is used. | | **ModbusFCTimeout** | integer > 0 | optional | Timeout (in milliseconds) for these Modbus FC requests. If not present, the value is that of **ModbusTimeout** referenced by the **ModbusFCID**. | | **ModbusFCRegswap** | boolean | optional | If `true`, the 16bit register values retrieved will be byte-swapped before being used. If not specified the value is that of the **ModbusRegswap** referenced by the **ModbusFC** ID. *This function has been deprecated in favor of **FCByteMap**, but is kept for backwards compatibility reasons.* | ## **Samplepoints** The **SamplePoints** objects contain the following elements: | Function | Type | Importance | Description | | --- | --- | --- | --- | | **SampleName** | string | mandatory | Name of this sampled value (sometimes called a tagname). Follows the normal rules for names. | | **SampleDescription** | string | optional | Is a text description of this sample value. | | **SampleUnit** | string | optional | Is a description of the unit measurement for this sample. | | **SampleGroup** | string | optional | Designates (in some datasrvs) that all samplepoints in that group should be handled (displayed) together. The DCM system itself places no meaning on this group affiliation. | | **SamplesSaved** | integer > 0 | optional | Is the number of values collected that is saved in the Store and Forward database even after the values have been sent to all dataservers. When `0` is specified, the value can be used in aggregators, but nothing is sent via dataservers to cloud system. If left unspecified, values are only saved in the Store and Forward database until they have been delivered to all dataservers. | | **OnlySaveOnChanged** | bool | optional | Specifies whether new sample values should be saved to the Store and Forward database only if the values have changed since last sample. Defaults to `false`. | | **ChangeLimit** | Integer/Double | optional | Only used if **OnlySaveOnChanged** is `true`. This describes a limit for what "changed" means. If a new sample value is this amount less or more than the previous sample value, it is considered the "same" value. This is a simple hysteresis to filter out inaccurate (jitter) measurements. | | **SampleDataType** | string-enum | mandatory | The type of data collected. The possible values are: `bool` (1 bit), `sbyte` (8 bit signed), `byte` (8 bit unsigned), `int16` (16 bit signed), `uint16` (16 bit unsigned), `int32` (32 signed), `uint32` (32 bit unsigned), `int64` (64 bit signed), `uint64` (64 bit unsigned), `float` (32 bit), `double` (64 bit), `string` (variable text up to 24575 bytes. Includes terminating NUL), `data` (variable data up to 24575 bytes). This collector might not support all **SampleDataType**s. | | **SampleLowerLimit** | integer/double | optional | The lower limit for the collected data. If the collected data value is less than **SampleLowerLimit** it is evaluated in accordance with **SampleLimitDiscard** and **SampleLimitAlarm**. | | **SampleUpperLimit** | integer/double | optional | The upper limit for the collected data. If the collected data value is more than **SampleUpperLimit** it is evaluated in accordance with **SampleLimitDiscard** and **SampleLimitAlarm**. | | **SampleLimitDiscard** | boolean | maybe-optional | Specifies whether samples that violates the sample limit should be discarded. Mandatory if either **SampleLowerLimit** or **SampleUpperLimit** is present. | | **SampleLimitAlarm** | boolean | maybe-optional | Specifies whether samples that violates the sample limits should generate an alarm. Mandatory if either **SampleLowerLimit** or **SampleUpperLimit** is present. | | **MQTTSample** | object | mandatory | Specification of the MQTT topic containing this sample value. | *Note*: The **SampleDataType**s `float` and `double` does not support masking (**FCDataMask**) and shifting (**FCDataShift**). *Note*: This collector does not support **SampleDataType**s of `string` and `data`. ## **ModbusValue** The **ModbusValue** object contains the following elements: | Function | Type | Importance | Description | | --- | --- | --- | --- | | **FCREF** | integer >= 0 | mandatory | This is a reference to the **ModbusFC**s element with the same value of its field **ModbusFCID**. | | **FCOffset** | integer >= 0 | mandatory | This is the addressing offset (relative to the element **ModbusFCStart** of the referenced **ModbusFC** object). It must be lower than **ModbusFCCount** field of the referenced **ModbusFC** object. | | **FCByteMap** | array of integer | optional | This array defines the mapping of incoming data from modbus to outgoing data to the sample value. The incoming data is referencing the index into the array, while the content of the array at that position determines the outgoing byte position. Example: `[0,1,2,3,4,5,6,7]` is the "identity" map, where no bytes changes position. `[2,3,0,1]` will swap the two 16-bit registers read, but keep the byte-order. `[7,6,5,4,3,2,1,0]` will reverse the byte-order of the 64-bit value constructed from 4 16-register read from Modbus. If not specified, the identity map will be used (i.e No swapping will take place). Note that once the bytes have been received and remapped, it is converted into the natural representation of the CPU, so that DCM aggregations can perform calculations on them. This means that the remapping should result in values in network-order (i.e Big Endian order), which is then converted into Little Endian on SiteManagers with CPUs that use Little Endian. (I.e. ARM, Intel-X86). Also note that **FCByteMap** is not allowed for samples with a **SampleDataType** of `data`, as this data type is used for raw variable length data. NOTE: As of release 9.5 of the SiteManager DCM code, the float values have changed conversion. All data types are now only using the **ModbusRegswap** and **FCByteMap**, so if you wish the float value to result in the same values as in older releases, you must use an **FCByteMap** with a value of `[3,2,1,0]` (the reverse map). | | **FCDataMask** | integer >= 0 | optional | This is the value that is bit-wise AND'ed with the collected value. **FCDataShift**. | | **FCDataShift** | integer | optional | This is the number of bits the collected value is shifted right to get the correct binary weight. | Together the **ModbusValue** fields performs the calculation: ``` datavalue = (FCvalue & FCDatamask) >> FCShift ``` This is traditionally called extracting a bit-field. ## Example configuration This example will collect: - 64 coils from 27 to 90 - 53 input registers from 3 to 55 - 33 holding registers from 100 to 132 ``` { "CollectorName": "Test1ModbusDevice", "CollectorDescription": "My first modbus", "Protocol": "ModBus/TCP", "ConnectRetryMin" : 2, "ConnectRetryMax" : 240, "ModbusAccess" : { "ModbusFCs": [ { "comment": "First set of data requested from the Modbus Master, Coils(bit)from coil address 27 to 90 (64 addresses)", "comment": "ModbusFCID is a reference number used in samplepoints", "ModbusFCID": 1, "ModbusFCSlaveAddress": 1, "ModbusFC": "coils", "ModbusFCStart": 27, "ModbusFCCount": 64, "ModbusFCSampleInterval": 5 }, { "ModbusFCID": 2, "ModbusFCSlaveAddress": 1, "ModbusFC": "inputs", "ModbusFCStart": 3, "ModbusFCCount": 53, "ModbusFCSampleInterval": 3 }, { "ModbusFCID": 3, "ModbusFCSlaveAddress": 1, "ModbusFC": "holding-registers", "ModbusFCStart": 100, "ModbusFCCount": 33, "ModbusFCSampleInterval": 2 } ], "ModbusTimeout" : 1000 }, "SamplePoints": [ { "SampleName": "test1", "SampleDescription": "First coil", "SamplesSaved": 10, "SampleDataType": "bool", "ModbusValue": { "FCREF": 1, "FCOffset": 0 }, "SampleLowerLimit": 0, "SampleUpperLimit": 1, "SampleLimitDiscard": false, "SampleLimitAlarm": false }, { "SampleName": "input1", "SampleDescription": "first input", "SamplesSaved": 10, "SampleDataType": "int16", "ModbusValue": { "FCREF": 2, "FCOffset": 0 }, "SampleLowerLimit": 0, "SampleUpperLimit": 1000, "SampleLimitDiscard": false, "SampleLimitAlarm": false }, { "SampleName": "Holding1", "SampleDescription": "first holding register", "SamplesSaved": 10, "SampleDataType": "int16", "ModbusValue": { "FCREF": 3, "FCOffset": 0 }, "SampleLowerLimit": 0, "SampleUpperLimit": 1000, "SampleLimitDiscard": true, "SampleLimitAlarm": true } ] } ```