(Optional) Creating a Modbus Device Interface (XIF) Definition (Release 3.1)

You can create a device interface (XIF) definition for a Modbus TCP or Modbus RTU device.  To create a Modbus XIF definition, you create a CSV file with a .mod extension that defines the device interface for a Modbus device interface (XIF).  The Modbus XIF specifies the Modbus device interface name, program ID, and manufacturer, and lists all the registers to be polled or updated by the SmartServer.  To create the file, you will need the manufacturer's documentation for the Modbus device register addresses and contents implemented by the device.  

This section consists of the following:

Creating a Modbus XIF File

The name of the Modbus XIF file, without the .mod extension, is the name of the Modbus XIF.  The extension must be .MOD or .mod.  You cannot use a compound extension name such as .mod.csv.  

A Modbus XIF file has the following three sections.

  • A file type specification that identifies the file as a Modbus XIF file.
  • A product details section that specifies the program ID, version, product name, and manufacturer for the Modbus device.
  • A datapoint list that specifies the datapoints on the device to be available to the SmartServer.  The first line of the datapoint list is a header with column headings for a datapoint list. 

The following figure illustrates the top portion of a Modus XIF file.

The following sections describe the Modbus XIF file sections.

File Type Specification

The file type specification for a Modbus XIF file is the following:

#filetype,Modbus_xif

If you open a CSV file with this line in Excel, it is displayed as two cells, one with #filetype and one with Modbus_xif.

Product Details

The product details identify the product specified by the Modbus XIF file.  The product details specification has the following contents:

#program_ID,<Program_ID>
#version,<Version>
#manufacturer,<Manufacturer>
#description,<Description>

If you open a CSV file with these lines in Excel, each line is displayed as two cells.

Specify the details as follows:

  • <Program_ID> – (required) a 64-bit hexadecimal number used for identifying resource definitions. An example Modbus RTU program_ID is 9FF4A2150040DB00. The program ID can optionally have colon and hyphen separators.  You can create a program ID using the SPIDCalculator as described in Device Type Definition.

  • <Version> – (optional) version of the device.
  • <Manufacturer> – (optional) manufacturer of the device.
  • <Description> – (optional) name of the device. This value can match the name of the .mod file.

Following is an example product details specification for a Schneider PM5563 Modbus meter:

#program_ID,900014153503DB00
#version, v0.0.0
#manufacturer,Schneider-Electric
#description,PowerLogic 5563 Power Meter

Following is an example product details specification for an Advantech Adam 4150 DIO module:

#program_ID,9F0096052804DB00
#version, v0.0.0
#manufacturer,Advantech
#description,Adam 4150 DIO module

Datapoint List

The datapoint list that specifies the datapoints on the device to be available to the SmartServer.  The first line of the datapoint list is a header with column headings for a datapoint list.  Following is an example datapoint list with a single datapoint defined:

Point Name,Presentation Type,Modbus Datatype,Function Code,Address,Direction,A',B',C',Range Min,Range Max,Block Name,inFeedback,Marker Value,Description (optional)
DI_0,SNVT_count,BIT,FC01,0,R,1,0,0,0,1,DI,FALSE,"",Input CH0

The following table describes the column contents for the datapoint list: 

ParameterRequired/
Optional
Description

Point Name

Required

Name of the datapoint.  You can provide a descriptive name to identify the datapoint.  The name is required, and must be unique for block containing the datapoint (see Block Name below).

Presentation TypeRequired

IAP type that identifies how the data appears in the SmartServer.  You can select a data type at www.lonmark.org/nvs/.

Word OrderOptionalSpecifies the 16-bit word ordering within multi-word values.  Values can be blank, big, or little. big or blank specify big-endian word ordering. little specifies little-endian, 16-bit word ordering.
Byte OrderOptional

Specifies the 8-bit byte ordering within multi-byte values. Values can be blank, big, or little. big or blank specifies big-endian ordering. little specifies little-endian ordering.  Byte ordering specification controls the ordering of bytes within the entire value if the Word Order value is blank, and controls byte ordering within each 16-bit word if the Word Order value is specified as big or little. 

Bit OrderOptionalSpecifies the bit ordering within each byte.  Values can be blank, big, or little. big specifies big-endian bit ordering. little or blank specifies little-endian.
Modbus DatatypeRequired

Specifies how the data is encoded in the Modbus registers.  Select a value based on the Modbus register type and encoding as follows:

  • For Modbus coil outputs and discrete inputs, specify BIT
  • For Modbus input registers and holding output registers, select UINT8, UINT16, SINT16, UINT32, SINT32, FLOAT, MOD10_2, MOD10_3, or MOD10_4
Function CodeRequired

Specifies the read function code of the datapoint.  Enter one of the following values:

Do not specify the FC05, FC06, FC15, and FC16 write function codes.  The SmartServer automatically determines the write function code based on the read function code.

AddressRequired

The Modbus register address in the device.  Specify Modbus 0-based addressing without a block number.  Some devices specify thei addresses using Modicon addressing with 5 or 6 digits, where the first digit of Modicon addressing represents the memory block, and the remaining digits representing the register address offset by 1.  The memory blocks are 0 for coils, 1 for discrete inputs, 3 for input registers, and 4 for holding registers.  Do not include the memory block in the address specification, and subtract the offset.  For example, if the Modicon register address is 400001, do not include the 4, and subtract 1 from the address of 1.  The resulting address is 0.

DirectionRequired

Specifies if a datapoint is read-only (R) or read-write (RW).

Datapoints with function codes FC02 and FC04 are required read-only registers and must specify R in this column.

Datapoints with function codes FC01 and FC03 are read-write points; however, their writability may be disabled. To do so, fill the column with R, otherwise, enter  RW.

A', B', C'Required

Specifies the scaling parameters for a datapoint, such that the scaled value = A' * 10^B' * (raw value + C').

For example, if the the Modbus register value is a UINT16 encoded value with a resolution of .01 and is to be presented as a floating point value, select an IAP type using based on a float base type and use 1,-2, 0 as the scaling values.  For this example, if the register value is 6000, the converted value is 60: 1 * 10^-2 *(6000 + 0).

If scaling is not required enter 1, 0, 0 as scaling values.

Range MinOptional

Specifies the minimum scaled value for the datapoint.  If the scaled value of the datapoint is less than the specified value, an error is logged.

Range MaxOptional

Specifies the maximum scaled value for the datapoint.  If the scaled value of the datapoint is greater than the specified value, an error is logged.

Block IndexOptionalSpecifies a numeric block index, starting with index 0. You can use the block index to create multiple blocks of the same type.  For example if you have a device with 8 digital outputs, you can define 8 blocks, each named DO, using indexes 0 through 7.  Block index 0 is used if you do not specify an index value.  (This is available with SmartServer 2.8 and higher)
Block NameOptionalSpecifies the block name for the datapoint. You can use blocks to group related datapoints together. You can provide a descriptive name to identify the block.  You can specify the same block for multiple datapoints to specify that those datapoints are members of the same block. (This is available with SmartServer 2.8 and higher)
inFeedbackRequired

Specifies whether the block in which the datapoint belongs to must be published on the feedback channel along with a publication of the datapoint to the monitor service.  You can specify TRUE or FALSE. This is typically set to FALSE.

Marker ValueOptional

Supports Modbus device discovery. The Modbus protocol does not support automatic discovery of devices.  The SmartServer discovers Modbus devices by probing each Modbus address for marker values that you specify.  A marker is a fixed datapoint value that the SmartServer identify the device type for a device.  For example, if a device type includes a datapoint with a model name or model number, the datapoint can be used as a marker for the device type. If a Modbus device manufacturer sells a line of devices, Model number 23854, and embeds that number in a datapoint at the same register address in each device, but then also has a datapoint with the number of phases supported by the particular meter, the marker for each meter type can consist of two datapoints, one with the model name and one with the number of phases. Both values must match the marker values in the device interface definition. 

(This parameter is available with SmartServer 2.8 and higher)

DescriptionOptional

Provides a description of the datapoint.

Defining the Modbus Program ID

Each Modbus device interface definition requires a unique program ID.  Create a Modbus program ID for the Modbus XIF as defined in Device Type Definition.

Application Examples

Example 1 - EasyIO FC-20 BMS Controller

Following are examples of the manufacturer's documentation for the Modbus registers in an EasyIO FC-20.  This example specifies two datapoints per memory block and three for the holding register.

Discrete Input

Coil Output

Input Register

Holding Register

  • Point Name = Register Name

  • Presentation Type = Select best the IAP type from IzoT Resource Editor standard list that represents the Modbus datatype.

  • Modbus Datatype = Type field in Input Register and Holding Register. Coil Output or Discrete Input is always BIT.

  • Function Code = Register is clearly labeled for each datapoint in the Easy IO registry map.


  • Address = Easy IO documentation specifies it is 1-base addressing, with 5 digits.

    If the first digit is:

0 = use FC01
1 = use FC02
3 = use FC04
4 = use FC03

For the next 4 digits, subtract 1 to get register address as shown in the following examples:

40001 in Easy IO = FC03 0000 in MOD file
30001 in Easy IO = FC04 0000 in MOD file

  • Direction = Depends on whether registry allows for read/write options, based on the function code for the datapoint, you can use the following direction:

  • A`, B`, C` = Refer to the scaling example provided above, and to be used if the way the data is presented needs to be a different resolution.

  • Range Min/Max = (Optional) Enter a scaled value that is out-of-range for the datapoint. 

  • Poll Rate (sec) = This value is user-defined.

  • Description = Description field in Easy IO register map.

Example 2 - Schneider PM5563 Power Meter

Following is an example of the manufacturer's documentation for the Modbus registers in a Schneider PM5563.

  • Point Name = Description field

  • Presentation Type = Select best the IAP type from IzoT Resource Editor standard list that represents the Modbus datatype.

  • Modbus Datatype = Data-Type field; Input Register and Holding Register. Coil Output or Discrete Input is always BIT.

  • Function Code = Use the function code based on the memory block where the data is located.

  • Address = The PM55XX series register index is a spreadsheet with tabs for registers and coils.

    The datapoints in the Register List tab will have a function code of FC03 or FC04 depending on the memory block where the data is stored. The datapoints in the Coils tab will have a function code of FC01 or FC02 depending on the coil where the data is stored.

    Since the Register column values represent the raw address value, both raw address and raw address minus 1 were tried. It was determined that the raw value minus 1 returned the correct data.
    • Minute = 1841 = Subtract 1 from the address to convert it to 0-base addressing
    • VT_Primary = 2026 = Subtract 1 from the address to convert it to 0-base addressing

  • Direction = Access Field. Depending on whether the registry allows for read/write options, based on the function code for the datapoint, use the following direction:

  • A`, B`, C` = Refer to the scaling example provided above, and to be used if the way the data is presented needs to be a different resolution.

  • Range Min/Max = (Optional) Enter a scaled value that is out-of-range for the datapoint. 

  • Poll Rate (sec) = This value is user-defined.

  • Description = Description field in register map.

Following is the Modbus XIF file for the PM5563.

#filetype,Modbus_xif
#program_ID,900014153503DB00
#manufacturer,Schneider-Electric
#description,PowerLogic 5563 Power Meter
Point Name,Presentation Type,Modbus Datatype,Word Order,Function Code,Address,Direction,A',B',C',Range Min,Range Max,Block Index,Block Name,inFeedback,Description
Serial_Number,SNVT_count,UINT32,,FC03,129,R,1,0,0,,20,0,Dev-specific,false,serial_number
Firmware_Version,SNVT_count,UINT16,,FC03,1636,R,1,0,0,,20,0,Dev-specific,false,firmware_version
Year,SNVT_count,UINT16,,FC03,1836,R,1,0,0,,20,0,Time-and-date,false,year
Month,SNVT_count,UINT16,,FC03,1837,R,1,0,0,,20,0,Time-and-date,false,month
Day,SNVT_count,UINT16,,FC03,1838,R,1,0,0,,20,1,Time-and-date,false,day
Hour,SNVT_count,UINT16,,FC03,1839,R,1,0,0,,20,1,Time-and-date,false,hour
Minute,SNVT_count,UINT16,,FC03,1840,R,1,0,0,,20,1,Time-and-date,false,minute
Second,SNVT_count,UINT16,,FC03,1841,R,1,0,0,,20,1,Time-and-date,false,second
Number_of_Phases,SNVT_count,UINT16,,FC03,2013,RW,1,0,0,,20,0,configurable,false,single_phase_equals_1
Number_of_Wires,SNVT_count,UINT16,,FC03,2014,RW,1,0,0,,20,0,configurable,false,wiring_pair_equals_2
Power_System_Configuration,SNVT_count,UINT16,,FC03,2015,RW,1,0,0,,20,0,configurable,false,1ph_2wire_LN_equals_0
Nominal_Frequency,SNVT_freq_hz,UINT16,,FC03,2016,RW,1,0,0,,20,0,configurable,false,either_50_or_60
Number_VTs,SNVT_count,UINT16,,FC03,2024,RW,1,0,0,,20,0,configurable,false,number_of_voltage_transformers
VT_Primary,SNVT_count_f,FLOAT,,FC03,2025,RW,1,0,0,,20,0,configurable,false,voltage_transformer_primary
VT_Secondary,SNVT_count_f,FLOAT,,FC03,2027,RW,1,0,0,,20,0,configurable,false,voltage_transformer_secondary
Number_CTs,SNVT_count,UINT16,,FC03,2028,RW,1,0,0,,20,0,configurable,false,number_of_current_transformers
CT_Primary,SNVT_count,UINT16,,FC03,2029,RW,1,0,0,,20,0,configurable,false,current_transformer_primary
CT_Secondary,SNVT_count,UINT16,,FC03,2030,RW,1,0,0,,20,0,configurable,false,current_transformer_secondary
Apparent_Energy_Delivered,SNVT_power_f,FLOAT,,FC03,2715,R,1,0,0,,20,0,energy,false,forward_apparent kVAh
Apparent_Energy_Received,SNVT_power_f,FLOAT,,FC03,2717,R,1,0,0,,20,0,energy,false,reverse_apparent kVAh
Current_Phase_A,SNVT_amp_f,FLOAT,,FC03,2999,R,1,0,0,,20,0,current,false,L1_current
Current_Phase_B,SNVT_amp_f,FLOAT,,FC03,3001,R,1,0,0,,20,0,current,false,L2_current
Current_Phase_C,SNVT_amp_f,FLOAT,,FC03,3003,R,1,0,0,,20,0,current,false,L3_current
Current_N,SNVT_amp_f,FLOAT,,FC03,3005,R,1,0,0,,20,0,current,false,neutral_current
Current_Avg,SNVT_amp_f,FLOAT,,FC03,3009,R,1,0,0,,20,0,current,false,average_current
Voltage_A-B,SNVT_volt_f,FLOAT,,FC03,3019,R,1,0,0,,20,0,voltage,false,L1L2_voltage
Voltage_B-C,SNVT_volt_f,FLOAT,,FC03,3021,R,1,0,0,,20,0,voltage,false,L2L3_voltage
Voltage_C-A,SNVT_volt_f,FLOAT,,FC03,3023,R,1,0,0,,20,0,voltage,false,L1L3_voltage
Voltage_L-L_Avg,SNVT_volt_f,FLOAT,,FC03,3025,R,1,0,0,,20,0,voltage,false,average_L_L_voltage
Voltage_A-N,SNVT_volt_f,FLOAT,,FC03,3027,R,1,0,0,,20,0,voltage,false,L1N_voltage
Voltage_B-N,SNVT_volt_f,FLOAT,,FC03,3029,R,1,0,0,,20,0,voltage,false,L1N_voltage
Voltage_C-N,SNVT_volt_f,FLOAT,,FC03,3031,R,1,0,0,,20,0,voltage,false,L1N_voltage
Voltage_L-N_Avg,SNVT_volt_f,FLOAT,,FC03,3033,R,1,0,0,,20,0,voltage,false,average_L_N_voltage
Active_Power_A,SNVT_power_kilo,FLOAT,,FC03,3053,R,1,0,0,,20,0,power,false,L1_forward_power
Active_Power_B,SNVT_power_kilo,FLOAT,,FC03,3055,R,1,0,0,,20,0,power,false,L2_forward_power
Active_Power_C,SNVT_power_kilo,FLOAT,,FC03,3057,R,1,0,0,,20,0,power,false,L3_forward_power
Active_Power_Total,SNVT_power_f,FLOAT,,FC03,3059,R,1,0,0,,20,0,power,false,forward_active kW
Reactive_Power_A,SNVT_power_kilo,FLOAT,,FC03,3061,R,1,0,0,,20,1,power,false,
Reactive_Power_B,SNVT_power_kilo,FLOAT,,FC03,3063,R,1,0,0,,20,1,power,false,
Reactive_Power_C,SNVT_power_kilo,FLOAT,,FC03,3065,R,1,0,0,,20,1,power,false,
Reactive_Power_Total,SNVT_power_f,FLOAT,,FC03,3067,R,1,0,0,,20,1,power,false,reverse_active kW
Apparent_Power_A,SNVT_amp_f,FLOAT,,FC03,3069,R,1,0,0,,20,2,power,false,L1_net_power
Apparent_Power_B,SNVT_amp_f,FLOAT,,FC03,3071,R,1,0,0,,20,2,power,false,L2_net_power
Apparent_Power_C,SNVT_amp_f,FLOAT,,FC03,3073,R,1,0,0,,20,2,power,false,L3_net_power
Apparent_Power_Total,SNVT_power_f,FLOAT,,FC03,3075,R,1,0,0,,20,2,power,false,net_active kVA
Power_Factor_A,SNVT_pwr_fact,FLOAT,,FC03,3077,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Power_Factor_B,SNVT_pwr_fact,FLOAT,,FC03,3079,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Power_Factor_C,SNVT_pwr_fact,FLOAT,,FC03,3081,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Power_Factor_Total,SNVT_pwr_fact,FLOAT,,FC03,3083,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Displacement_Power_Factor_A,SNVT_pwr_fact,FLOAT,,FC03,3085,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Displacement_Power_Factor_B,SNVT_pwr_fact,FLOAT,,FC03,3087,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Displacement_Power_Factor_C,SNVT_pwr_fact,FLOAT,,FC03,3091,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Displacement_Power_Factor_Total,SNVT_pwr_fact,FLOAT,,FC03,3093,R,1,0,0,-2,,20,0,,false,4Q_FP_PF_encoded
Frequency,SNVT_freq_f,FLOAT,,FC03,3109,R,1,0,0,,20,0,,false,frequency_hertz
Reactive_Energy_Received,SNVT_power_f,SINT64,,FC03,3223,R,1,0,0,,20,0,energy,false,net_reactive VARh
thd_Current_A,SNVT_lev_percent,FLOAT,,FC03,21309,R,1,0,0,0,20,0,current,false,current_thd
thd_Current_B,SNVT_lev_percent,FLOAT,,FC03,21311,R,1,0,0,0,20,0,current,false,current_thd
thd_Current_C,SNVT_lev_percent,FLOAT,,FC03,21313,R,1,0,0,0,20,0,current,false,current_thd
thd_Current_N,SNVT_lev_percent,FLOAT,,FC03,21315,R,1,0,0,0,20,0,current,false,current_thd
thd_Current_G,SNVT_lev_percent,FLOAT,,FC03,21317,R,1,0,0,0,20,0,current,false,current_thd
thd_Voltage_A-B,SNVT_lev_percent,FLOAT,,FC03,21339,R,1,0,0,0,20,0,voltage,false,voltage_thd
thd_Voltage_B-C,SNVT_lev_percent,FLOAT,,FC03,21341,R,1,0,0,0,20,0,voltage,false,voltage_thd
thd_Voltage_C-A,SNVT_lev_percent,FLOAT,,FC03,21343,R,1,0,0,0,20,0,voltage,false,voltage_thd
thd_Voltage_L-L,SNVT_lev_percent,FLOAT,,FC03,21345,R,1,0,0,0,20,0,voltage,false,voltage_thd
thd_Voltage_A-N,SNVT_lev_percent,FLOAT,,FC03,21347,R,1,0,0,0,20,0,voltage,false,voltage_thd
thd_Voltage_B-N,SNVT_lev_percent,FLOAT,,FC03,21349,R,1,0,0,0,20,0,voltage,false,voltage_thd
thd_Voltage_C-N,SNVT_lev_percent,FLOAT,,FC03,21351,R,1,0,0,0,20,0,voltage,false,voltage_thd
thd_Voltage_L-N,SNVT_lev_percent,FLOAT,,FC03,21355,R,1,0,0,0,20,0,voltage,false,voltage_thd
BACnet_Device_ID,SNVT_count_32,UINT32,big,FC03,64482,RW,1,0,0,,20,0,Dev-specific,false,BACnet_device_id
BACnet_UDP_Port,SNVT_count,UINT16,,FC03,64484,RW,1,0,0,,20,0,Dev-specific,false,BACnet_UDP_port

Example 3 - Simpson Amik 201 Power Meter

Following is an example Modbus XIF for a Simpson Amik Power Meter.

#filetype,Modbus_xif
#program_ID,9FF4A2150004DB00
#manufacturer,Simpson Electric
#description,AMIK201RTU
Point Name,Presentation Type,Modbus Datatype,Function Code,Address,Direction,A',B',C',Range Min,Range Max,Block Name,Block Index,Marker Value,inFeedback,Description
Volts_1,SNVT_volt_f,FLOAT,FC04,0,R,1,0,0,-300,300,Volts 1,1,,false,
Freq,SNVT_freq_f,FLOAT,FC04,70,R,1,0,0,0,1000,Freq,36,,false,
Password,SNVT_count_f,FLOAT,FC03,70,RW,1,0,0,,,,87,1,false,

Example 4 - Advantech Adam 4150 DIO Module

Following is an example Modbus XIF for an Advantech Adam 4150.

#filetype,Modbus_xif
#program_ID,9B0096052804DB00
#manufacturer,Advantech
#description,Adam 4150 DIO module
Point Name,Presentation Type,Modbus Datatype,Function Code,Address,Direction,A',B',C',Range Min,Range Max,Block Name,inFeedback,Marker value,Description (optional)
DI_0,SNVT_count,BIT,FC01,0,R,1,0,0,0,1,DI,FALSE,"",Input CH0
DI_1,SNVT_count,BIT,FC01,1,R,1,0,0,0,1,DI,FALSE,"",Input CH1
DI_2,SNVT_count,BIT,FC01,2,R,1,0,0,0,1,DI,FALSE,"",Input CH2
DI_3,SNVT_count,BIT,FC01,3,R,1,0,0,0,1,DI,FALSE,"",Input CH3
DI_4,SNVT_count,BIT,FC01,4,R,1,0,0,0,1,DI,FALSE,"",Input CH4
DI_5,SNVT_count,BIT,FC01,5,R,1,0,0,0,1,DI,FALSE,"",Input CH5
DI_6,SNVT_count,BIT,FC01,6,R,1,0,0,0,1,DI,FALSE,"",Input CH6
DO_0,SNVT_count,BIT,FC01,16,RW,1,0,0,0,1,DO,FALSE,"",Output CH0
DO_1,SNVT_count,BIT,FC01,17,RW,1,0,0,0,1,DO,FALSE,"",Output CH1
DO_2,SNVT_count,BIT,FC01,18,RW,1,0,0,0,1,DO,FALSE,"",Output CH2
DO_3,SNVT_count,BIT,FC01,19,RW,1,0,0,0,1,DO,FALSE,"",Output CH3
DO_4,SNVT_count,BIT,FC01,20,RW,1,0,0,0,1,DO,FALSE,"",Output CH4
DO_5,SNVT_count,BIT,FC01,21,RW,1,0,0,0,1,DO,FALSE,"",Output CH5
DO_6,SNVT_count,BIT,FC01,22,RW,1,0,0,0,1,DO,FALSE,"",Output CH6
DO_7,SNVT_count,BIT,FC01,23,RW,1,0,0,0,1,DO,FALSE,"",Output CH7
ModuleName-1,SNVT_count,UINT16,FC04,210,R,1,0,0,"","",Dev,FALSE,16270,Model 0x4150