Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

Table of Contents

Introduction

Being able to configure the way a protocol plugin will manage the communication with the remote servers or clients using the protocol stack parameters, whether communication is secured or not, how the messages attributes are translated from the input protocol data model to the output protocol data model and what kind of rules (filters, math, routing, etc..) to apply to the messages that are exchanges with the remote systems are key features of any protocol translation gateway.

...

In order to reach the goal of simplicity we want to achieve, the main challenge is to be able to build a pivot object that is technically independent from the protocols. The data model should also be neutral regarding protocols data models. The protocol translation should not imply a loss or degradation of the source information, especially in the case where the input and output protocols are identical.

Pivot object model

The pivot object model is based on 61850 semantic.

Example: LN GTIS to represent a Single Point Signal:

Code Block
languagejs
titlepivot_format_data_model
{
   "PIVOT":{
      "GTIS":{
         "Cause":{
            "stVal":3
         },
         "ComingFrom":"104",
         "Confirmation":{
            "stVal":false
         },
         "SpsTyp":{
            "q":{
               "Source":"not substituted",
               "Validity":"good",
               "operatorBlocked":false,
               "test":false
            },
            "stVal":true,
            "t":{
               "FractionOfSecond":1,
               "SecondSinceEpoch":1647957078,
               "TimeQuality":{
                  "clockFailure":false,
                  "clockNotSynchronized":false,
                  "leapSecondKnown":false,
                  "timeAccuracy":1
               }
            }
         },
         "Identifier":"S_114562"
      }
   }
}

Example: LN GTIS to represent a Double Point Signal:

Code Block
languagejs
titlepivot_format_data_model
{
   "PIVOT":{
      "GTIS":{
         "Cause":{
            "stVal":3
         },
         "ComingFrom":"104",
         "Confirmation":{
            "stVal":false
         },
         "DpsTyp":{
            "q":{
               "Source":"not substituted",
               "Validity":"good",
               "operatorBlocked":true,
               "test":true
            },
            "stVal":"on",
            "t":{
               "FractionOfSecond":1,
               "SecondSinceEpoch":1648799401
            }
         },
         "Identifier":"S_244978"
      }
   }
}

Example: LN GTIM to represent a Measured Value:

Code Block
languagejs
titlepivot_format_data_model
{
   "PIVOT":{
      "GTIM":{
         "Cause":{
            "stVal":1
         },
         "ComingFrom":"104",
         "Confirmation":{
            "stVal":false
         },
         "Identifier":"M_114618",
         "MvTyp":{
            "mag":{
               "f":-0.199982
            },
            "q":{
               "DetailQuality":{
                  "overflow":true
               },
               "Source":"not substituted",
               "Validity":"good",
               "operatorBlocked":false,
               "test":false
            }
         }
      }
   }
}

Protocol translation process

...

Protocol translation configuration

Code Block
languagejs
{
   "protocol_translation":{
      "name":"SAMPLE",
      "version":"1.0",
      "mapping_rules":[
         {
            "input_type":"M_SP_TB_1",
            "output_type":"SpsTyp",
            "mapping_rule":"104toP_1"
         },
         {
            "input_type":"M_DP_TB_1",
            "output_type":"DpsTyp",
            "mapping_rule":"104toP_2"
         },
         {
            "input_type":"M_ME_NA_1",
            "output_type":"MvTyp",
            "mapping_rule":"104toP_3"
         },
         {
            "input_type":"M_ME_NC_1",
            "output_type":"MvTyp",
            "mapping_rule":"104toP_4"
         },
         {
            "input_type":"SpsTyp",
            "output_type":"M_SP_TB_1",
            "mapping_rule":"Pto104_1"
         },
         {
            "input_type":"DpsTyp",
            "output_type":"M_DP_TB_1",
            "mapping_rule":"Pto104_2"
         },
         {
            "input_type":"MvTyp",
            "output_type":"M_ME_NA_1",
            "mapping_rule":"Pto104_3"
         },
         {
            "input_type":"MvTyp",
            "output_type":"M_ME_NC_1",
            "mapping_rule":"Pto104_4"
         },
         {
            "input_type":"SpsTyp",
            "output_type":"Data_StateQTimeTagExtended",
            "mapping_rule":"PtoT2_1"
         },
         {
            "input_type":"DpsTyp",
            "output_type":"Data_DiscreteQTimeTagExtended",
            "mapping_rule":"PtoT2_2"
         },
         {
            "input_type":"MvTyp",
            "output_type":"Data_RealQ",
            "mapping_rule":"PtoT2_3"
         }
      ]
   }
}

Exchanged data configuration

In this chapter we will describe the configuration of the exchanged data. This configuration allow to specify a list of supported data objects. The protocol plugin is expected to make some controls against each entry of the configuration to check:

  • if CA of ASDU is known otherwise throw an error message.
  • if IOA is known otherwise throw an error message.
  • if type of ASDU is known otherwise an error message.
  • The label attribute shall be used to populate the Fledge's DataPoint Asset Name attribute.

Configuration JSON file structure

Code Block
languagejs
{
   "exchanged_data":{
      "name":"SAMPLE",
      "version":"1.0",
      "datapoints":[
         {
            "label":"TS1",
            "pivot_id":"ID114562",
            "pivot_type":"SpsTyp",
            "protocols":[
               {
                  "name":"iec104",
                  "address_ca":"45",
                  "address_ioa":"672",
                  "typeid":"M_SP_TB_1"
               },
               {
                  "name":"tase2",
                  "address":"S_114562",
                  "typeid":"Data_StateQTimeTagExtended"
               }
            ]
         },
         {
            "label":"TM1",
            "pivot_id":"ID99876",
            "pivot_type":"DpsTyp",
            "protocols":[
               {
                  "name":"iec104",
                  "address_ca":"45",
                  "address_ioa":"984",
                  "typeid":"M_ME_NA_1"
               },
               {
                  "name":"tase2",
                  "address":"S_114562",
                  "typeid":"Data_RealQ"
               }
            ]
         }
      ]
   }
}

IEC 104 south plugin (client/master)

IEC 104 Protocol stack configuration

The IEC 104 protocol stack configuration specifies communication parameters and is a collection of entries containing information about OSI Transport and OSI Application layers objects.

Each entry is comprised of attributes that describe the object. All the configuration data are structured using JSON.

Each entry shall be mapped with the corresponding configuration function in the chosen implementation protocol library.

Attributes definition

...

IP address, machine's default IP for a given interface

...

maximum ASDU size in transmission direction, if set to "0" => maximum possible value is automatically used.

...

remove, process, default = remove

remove: the time stamp will be removed from the information object

process: the time stamp will be processed on regular basis and additionally marked as 'not synchronized'

...

Global process from data acquisition to data exposition

This is an illustration with IEC 104 as input protocol and IEC 104, TASE.2 and OPC UA as output protocols.

We have defined here 3 data processing pipelines (see Fledge documentation about Data processing for more details.)

IEC 104 to IEC 104 direct translation : (1) => (5)

IEC 104 to TASE.2 protocols conversion : (1) => (2) => (3) => (6)

IEC 104 to OPCUA protocols conversion: (1) => (2) => (4) => (7) 

Process steps:

(1) IEC 104 ASDU acquisition using the iec104 south plugin, the output is a Datapoint representing the input message.

(2) From IEC 104 to Pivot conversion using the 104toPivot filter plugin, the output is a Datapoint representing a Pivot object of a specific datatype.

(3) Pivot To Tase2 conversion using the PivotToTase2 filter plugin, the output is a Datapoint representing a TASE.2 object of a specific datatype.

(4) Pivot To Opcua conversion using the PivotToOpcua filter plugin, the output is a Datapoint representing a OPCUA object of a specific datatype.

(5) IEC 104 ASDU exposition using the iec104 north plugin, the output is a IEC 104 ASDU.

(6) TASE.2 exposition using the tase2 north plugin, the output is a TASE.2 indication point.

(7) OPCUA exposition using the opcua north plugin, the output is a OPCUA object.

draw.io Diagram
bordertrue
diagramNameprotocol_conversion_process
simpleViewerfalse
width
linksauto
tbstyletop
lboxtrue
diagramWidth1421
revision2

Pivot object model

The pivot object model is based on 61850 semantic.

PIVOT TM model, representation of a tele measurement

AttributeDescriptionExpected valuesMandatory
PIVOT.GTIM.Beh.stVal?

PIVOT.GTIM.Cause.stValCause of transmission COT Cause of Transmission - FledgePower - LF EnergyYes
PIVOT.GTIM.ChgValCnt.stVal?

PIVOT.GTIM.ComingFromSource protocol nameIEC103, IEC104, TASE.2, OPCUA, 61850, etc...Yes
PIVOT.GTIM.Confirmation.stValIndicates positive or negative confirmation of activationtrue, false, DEFAULT=false
PIVOT.GTIM.IdentifierUnique identifier of the pivot objectAny non-empty stringYes
PIVOT.GTIM.{CDC}Common Data Class representing the information object

MVTyp

Common Data Classes - FledgePower - LF Energy

Yes
PIVOT.GTIM.NormalSrc.stVal?

PIVOT.GTIM.NormalVal.stVal?

PIVOT.GTIM.TmOrg.stValTimestamp origin, genuine = source otherwise substitutedgenuine, substituted, DEFAULT = genuineYes
PIVOT.GTIM.TmValidity.stValTimestamp validityvalid, invalid, DEFAULT = validYes

Example of a pivot model instance representing a Tele Measurement:

Code Block
languagejs
{
	"@xmlns:xs": "http://www.w3.org/2001/XMLSchema",
	"PIVOT": {
		"GTIM": {
			"Beh": {
				"stVal": "on"
			},
			"Cause": {
				"stVal": 1
			},
			"ChgValCnt": {
				"stVal": 1
			},
			"ComingFrom": "String",
			"Confirmation": {
				"stVal": true
			},
			"Identifier": "String",
			"MvTyp": {
				"mag": {
					"f": 0.1,
					"i": 1
				},
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"NormalSrc": {
				"stVal": "TELEMETERED"
			},
			"NormalVal": {
				"stVal": "NORMAL"
			},
			"Origin": {
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": "String",
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"TmOrg": {
				"stVal": "genuine"
			},
			"TmValidity": {
				"stVal": "VALID"
			}
		}
	}
}

PIVOT TS model, representation of a tele signal

AttributeDescriptionExpected valuesMandatory
PIVOT.GTIS.Beh.stVal?

PIVOT.GTIS.Cause.stValCause of transmission COT Cause of Transmission - FledgePower - LF EnergyYes
PIVOT.GTIS.ChgValCnt.stVal?

PIVOT.GTIS.ComingFromSource protocol nameIEC103, IEC104, TASE.2, OPCUA, 61850, etc...Yes
PIVOT.GTIS.Confirmation.stValIndicates positive or negative confirmation of activationtrue, false, DEFAULT=false
PIVOT.GTIS.IdentifierUnique identifier of the pivot objectAny non-empty stringYes
PIVOT.GTIS.{CDC}Common Data Class representing the information object

SPSTyp, DPSTyp, BSCTyp

Common Data Classes - FledgePower - LF Energy

Yes
PIVOT.GTIS.NormalSrc.stVal?

PIVOT.GTIS.NormalVal.stVal?

PIVOT.GTIS.TmOrg.stValTimestamp origin, genuine = source otherwise substitutedgenuine, substituted, DEFAULT = genuineYes
PIVOT.GTIS.TmValidity.stValTimestamp validityvalid, invalid, DEFAULT = validYes

Example of a pivot model instance representing a Tele Signal:

Code Block
languagejs
{
	"@xmlns:xs": "http://www.w3.org/2001/XMLSchema",
	"PIVOT": {
		"GTIS": {
			"Beh": {
				"stVal": "on"
			},
			"Cause": {
				"stVal": 1
			},
			"ChgValCnt": {
				"stVal": 1
			},
			"ComingFrom": "String",
			"Confirmation": {
				"stVal": true
			},
			"DpsTyp": {
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": "intermediate-state",
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"Identifier": "String",
			"NormalSrc": {
				"stVal": "TELEMETERED"
			},
			"NormalVal": {
				"stVal": "NORMAL"
			},
			"Origin": {
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": "String",
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"SpsTyp": {
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": true,
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"TmOrg": {
				"stVal": "genuine"
			},
			"TmValidity": {
				"stVal": "VALID"
			}
		}
	}
}

PIVOT TC model, representation of a tele command

AttributeDescriptionExpected valuesMandatory
PIVOT.GTIC.Beh.stVal

defines different behaviours of a control object:

- Direct control with normal security: dct-ctl-wns
- Direct control with enhanced security: dct-ctl-wes
- SBO (Select Before Operate) control with normal security: sbo-ctl-wns
- SBO (Select Before Operate) control with enhanced security: sbo-ctl-wes 

enum: dct-ctl-wns, dct-ctl-wes, sbo-ctl-wns, sbo-ctl-wes, DEFAULT = dct-ctl-wesNo
PIVOT.GTIC.Cause.stValCause of transmission COT Cause of Transmission - FledgePower - LF EnergyNo
PIVOT.GTIC.ComingFromSource protocol nameIEC103, IEC104, TASE.2, OPCUA, 61850, etc...Yes
PIVOT.GTIC.DevId.name?
No
PIVOT.GTIC.{CDC}Common Data Class representing the information object

SPCTyp, DPCTyp, INCTyp, APCTyp, BSCTyp

Common Data Classes - FledgePower - LF Energy

Yes
PIVOT.GTIC.IdentifierUnique identifier of the pivot objectAny non-empty stringYes
PIVOT.GTIC.Qu.stVal?
No
PIVOT.GTIC.ServiceType.stVal?
No
PIVOT.GTIC.Tag.stVal?
No
PIVOT.GTIC.TagClass?
No
PIVOT.GTIC.TaggedReason?
No
PIVOT.GTIC.TmOrgTimestamp origin, genuine = source otherwise substitutedgenuine, substituted, DEFAULT = genuineNo
PIVOT.GTIC.TmStampTimestamp
No

Example of a pivot model instance representing a Tele Command:

Code Block
languagejs
{
	"@xmlns:xs": "http://www.w3.org/2001/XMLSchema",
	"PIVOT": {
		"GTIC": {
			"Beh": {
				"stVal": "dct-ctl-wes"
			},
			"Cause": {
				"stVal": 1
			},
			"ComingFrom": "String",
			"DevId": {
				"name": "String"
			},
			"DevSt": {
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": true,
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"DpcTyp": {
				"ctlVal": true,
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": "intermediate-state",
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"Identifier": "String",
			"Qu": {
				"stVal": 1
			},
			"ServiceType": {
				"stVal": "select"
			},
			"SpcTyp": {
				"ctlVal": true,
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": true,
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"Tag": {
				"stVal": "NO-TAG"
			},
			"TagClass": {
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": true,
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			},
			"TaggedReason": "String",
			"TmOrg": {
				"stVal": "genuine"
			},
			"TmStamp": {
				"q": {
					"DetailQuality": {
						"badReference": true,
						"failure": true,
						"inconsistent": true,
						"innacurate": true,
						"oldData": true,
						"oscillatory": true,
						"outOfRange": true,
						"overflow": true
					},
					"Source": "process",
					"Validity": "good",
					"operatorBlocked": true,
					"test": true
				},
				"stVal": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				},
				"t": {
					"FractionOfSecond": 1,
					"SecondSinceEpoch": 1,
					"TimeQuality": {
						"clockFailure": true,
						"clockNotSynchronized": true,
						"leapSecondKnown": true,
						"timeAccuracy": 1
					}
				}
			}
		}
	}
}

Protocol translation process

draw.io Diagram
bordertrue
diagramNameprotocols_conversion_process
simpleViewerfalse
linksauto
tbstyletop
lboxtrue
diagramWidth1061
revision11

Exchanged data configuration

In this chapter we will describe the configuration of the exchanged data. This configuration allow to specify a list of supported data objects. The protocol plugin is expected to make some controls against each entry of the configuration to check:

  • if protocol message address or reference is known otherwise throw an error message.
  • if protocol type of message is known otherwise throw an error message.
  • The label attribute shall be used to populate the Fledge's DataPoint Asset Name attribute.

Attributes definition

AttributeDescriptionExpected valuesMandatory
namethis identifies the exchanged data configuration
Yes
versionthis is the version number of the configurationx.y where x represents a major version and y a minor changeYes
datapointsarray of datapoints that needs to be managed by the instance of the gateway
Yes
datapoints.labellabel of the datapointany non empty stringYes
datapoints.pivot_idunique identifier of the datapoint, this is used to create a pivot objectany non empty stringYes
datapoints.pivot_typetype of Common Data Class (CDC), this is used to create a pivot objectenum SpsTyp | DpsTyp | MvTyp | SpcTyp | DpcTyp | ...Yes
datapoints.pivot_subtypesarray of additional types of the pivot object[transient, ...]No
datapoints.tfididentifies the math function to transform the input valueenum "normal" | "square_root"  |  "quadratic"  |  "transparent"No
datapoints.paramsarray of parameters for the math functionarray of float 32 [a, b, c, ...]No
datapoints.deadbandband of input values where the output is zeroarray of 2 float 32 [min, max]No
datapoints.protocolsarray of protocols that needs to be managed for a datapoint
Yes
datapoints.protocols.namename of the protocolenum "iec104" | "iec103" | "tase2" | "hnz" | "61850" | "opcua" | ...Yes
datapoints.protocols.addressaddress of the datapoint in the given protocolany non empty stringYes
datapoints.protocols.typeidtype id of the datapoint in the given protocolany non empty string representing a valid protocol type idYes
datapoints.protocols.gi_groups

GI request status for north plugins, if "station" then datapoint is send

for south plugins, it determines whether a datapoint is expected in the GI response

enum station | 1 | 2 | ...No
datapoints.protocols.alternate_mapping_ruleAlternate mapping rule to convert datapoint from protocol model to pivot or pivot to protocol model, if not specified then default conversion rule is appliedany non empty string representing a function nameNo
datapoints.operationsarray of operations applied to produce a value for the current datapoint out of one or more input datapoints
No
datapoints.operations.operationtype of operation to performenum "or"No
datapoints.operations.inputarray of Pivot ID of datapoints to use as inputs for the operationarray of Pivot ID stringsNo

Configuration JSON structure

Code Block
languagejs
{
   "exchanged_data":{
      "name":"SAMPLE",
      "version":"1.0",
      "datapoints":[
         {
            "label":"TS1",
            "pivot_id":"ID114562",
            "pivot_type":"SpsTyp",
            "pivot_subtypes":[
               "transient"
            ],
			"operations":[
				{
              		"operation":"or",
					"input":[
						"ID114562",
						"ID114563"
					]
				}
            ],
            "protocols":[
               {
                  "name":"iec104",
                  "address":"45-672",
                  "typeid":"M_SP_TB_1",
                  "gi_groups":"station",
                  "alternate_mapping_rule":"func_name_1"
               },
               {
                  "name":"tase2",
                  "address":"S_114562",
                  "typeid":"Data_StateQTimeTagExtended"
               },
               {
                  "name":"opcua",
                  "address":"ID114562",
                  "typeid":"opcua_sps"
               },
               {
                  "name":"iec61850",
                  "address":"simpleIOGenericIO/GGIO1.Ind1",
                  "typeid":"SPS"
               }
            ]
         },
         {
            "label":"TM1",
            "pivot_id":"ID99876",
            "pivot_type":"MVTyp",
            "tfid":"square_root",
            "params":[
               2.0,
               49.5
            ],
            "deadband":[
               -0.02,
               0.02
            ],
            "protocols":[
               {
                  "name":"iec104",
                  "address":"45-984",
                  "typeid":"M_ME_NA_1"
               },
               {
                  "name":"tase2",
                  "address":"S_114562",
                  "typeid":"Data_RealQ"
               },
               {
                  "name":"opcua",
                  "address":"ID99876",
                  "typeid":"opcua_mvf"
               },
               {
                  "name":"iec61850",
   

Configuration JSON file structure

Code Block
languagejs
{
   "protocol_stack":{
      "name":"iec104client",
      "version":"1.0",
      "transport_layer":{
         "connection":{
            "path":[
               {
                  "srv_ip":"192.168.0.10",
                  "clt_ip":"",
                  "port":2404
               },
               {
                  "srv_ip":"192.168.0.11",
                  "clt_ip":"",
                  "port":2404
               }
            ],
            "tls":false
         },
         "k_value":12,
         "w_value":8,
         "t0_timeout":10,
         "t1_timeout":15,
         "t2_timeout":10,
         "t3_timeout":20,
         "conn_all":true,
         "start_all":false,
         "conn_passv":false
      },
      "application_layer":{
         "orig_addr":0,
         "ca_asdu_size":2,
         "ioaddr_size":3,
         "startup_time":180,
         "asdu_size":0,
         "gi_time":60,
         "gi_cycle":false,
         "gi_all_ca":false,
         "gi_repeat_count":2,
         "disc_qual":"NT",
         "send_iv_time":0,
         "tsiv":"REMOVE",
         "utc_time":false,
         "comm_wttag":false,
         "comm_parallel":0,
         "exec_cycl_test":false,
         "startup_state":true,
         "reverse":false,
         "time_sync":false
      }
   }
}

Path exploration

...

In redundant network configuration or generally in cases where several communication paths exist between one client and one server, the path checking exploration mechanism allows the client to try all the paths one by one without making any difference between them. The client uses the first available path. On disconnection this procedure starts again from the beginning.

TLS configuration

The CS 104 standard can also be used with TLS to realize secure and authenticated connections.

3 parameters are needed to set up the TLS secured connection:

  • private key file
  • server certificate
  • root certificate (CA)

Fledge's certificate store allows certificates to be stored and used by the south plugins.

Code Block
languagejs
{
  "tls_conf:": {
    "private_key": "server-key.pem",
    "server_cert": "server.cer",
    "ca_cert": "root.cer"
  }
}

IEC 104 exchanged ASDU configuration

In this chapter we will describe the configuration of the exchanged ASDU. This configuration allow to specify a list of supported ASDU types and a list of ASDU objects. The protocol plugin is expected to make some controls against each entry of the configuration to check:

  • if CA of ASDU is known otherwise throw an error message.
  • if IOA is known otherwise throw an error message.
  • if type of ASDU is known otherwise an error message.
  • The label attribute shall be used to populate the Fledge's DataPoint Asset Name attribute.

Configuration JSON file structure

IEC 104 north plugin (server/slave)

IEC 104 redundancy server modes

Multiple redundancy groups

The MZ Automation lib60870 server provides 3 different modes regarding the support of redundant connections and events queue handling:

  • The default mode (CS104_MODE_SINGLE_REDUNDANCY_GROUP) allows only a single active client connection.
  • The second mode (CS104_MODE_CONNECTION_IS_REDUNDANCY_GROUP) allows multiple active client connections.
  • The third mode (CS104_MODE_MULTIPLE_REDUNDANCY_GROUPS) allows multiple active client connections while preserving events when no client is connected.

In the case of this design, the south plugin will be implemented with CS104_MODE_MULTIPLE_REDUNDANCY_GROUPS server mode.

This mode allows multiple active client connections while preserving events when no client is connected. In this mode clients can be assigned to specific redundancy groups. The assignment is based on the IP address of the client. A redundancy group can have multiple simultaneous connections but only one of these connections can be active. The number of activated connections is restricted by the number of redundancy groups. Each redundancy group has a dedicated event queue.

It can be set with the CS104_Slave_setServerMode function:

Code Block
languagecpp
CS104_Slave_setServerMode(slave, CS104_MODE_MULTIPLE_REDUNDANCY_GROUPS);

Multiple redundancy groups example

...

In this example, 2 control centers, center A and B, are establishing communication with the server.

Both centers have an active and a stand-by gateway for failover management. 

Center A has two simultaneous connections, one active and one stand-by, assigned to redundancy group 1.

Center B has only one active connection, assigned to redundancy group 2.

IEC 104 Protocol stack configuration

The IEC 104 protocol stack configuration specifies communication parameters and is a collection of entries containing information about OSI Transport and OSI Application layers objects.

Each entry is comprised of attributes that describe the object. All the configuration data are structured using JSON.

Each entry shall be mapped with the corresponding configuration function in the chosen implementation protocol library.

Attributes definition

...

maximum ASDU size in transmission direction, if set to "0" => maximum possible value is automatically used.

...

ignore, process, default = ignore

ignore: the time stamp quality 'not synchronized' will be ignored and the time stamp will be processed on regular basis. IV-bit will remain 0

process: the time stamp will be send with IV-bit set to 1

...

Configuration JSON file structure

Code Block
languagejs
{
   "protocol_stack":{
      "name":"iec104server",
      "version":"1.0",
      "transport_layer":{
         "bind_on_ip":false,
         "srv_ip":"0.0.0.0",
         "port":2404,
         "tls":false,
         "k_value":12,
         "w_value":8,
         "t0_timeout":10,
         "t1_timeout":15,
         "t2_timeout":10,
         "t3_timeout":20
      },
      "application_layer":{
         "orig_addr":"0",
         "ca_asdu_size":2,
         "ioaddr_size":3,
         "asdu_size":0,
         "time_sync":false,
         "comm_exec_timeout":20000,
         "comm_recv_timeout":5000,
         "tsiv":"IGNORE",
         "reset":false,
         "filter_orig":false,
         "filter_list":[
            {
               "orig_addraddress":1"simpleIOGenericIO/GGIO1.AnIn1",
            },
            {"typeid":"MV"
               "orig_addr":2}
            }]
         ]}
      }]
   }
}


Warning

Do not use the name "IEC104Command" as a datapoint name in the exchanged data configuration. Doing so could potentially lead to conflicts when trying to read readings from both the South and Dispatcher components.