You are viewing an old version of this page. View the current version.

Compare with Current View Page History

« Previous Version 99 Next »

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 this design document we will be describing the implementation of the 3 main plugins configuration data models: protocol stack configuration (including application layer, transport layer and security layer), protocols translation configurationexchanged datapoints configuration and data processing/filtering rules.

FledgePOWER being built on top of Fledge, all the configuration will be described using JSON data structures using nested objects and will be sent to the gateway using the provided HTTP API.

Overview

Functional architecture

Configuration data categories

Protocol translation

Pivot object definition

Before diving into the details of the specification, it is useful to illustrate some use cases. They should help demonstrate how the specification is expected to be used and to help understand the benefits of a pivot object.

The objective of a gateway is to allow communication between different systems by providing some translation mechanisms from one means of communication to another one.

All translation mechanisms introduce a limitation of functionality in the translated space compared to the original space. The major challenge is to provide some correspondences between the two systems, with a limited impact to the original scope of features.

Use case 1: monitoring

Single Substation/RTU gateway

In this use case, monitoring data are acquired from a field device called RTU (Remote Terminal Unit) which acts as a IEC 104 server (slave) and are exposed to the central SCADA which acts as a ICCP TASE.2 client. Each incoming message from the RTU comes as an IEC 104 ASDU object. The south service plugin applies a first translation process which consists of (1) reading and checking the ASDU object using the IEC 104 data model and (2) mapping each data attribute to the corresponding pivot object data attribute. Once the message is converted to a pivot object, it can then be stored or consumed by the north or any other service. The north service plugin can then apply a second translation process which consists of (3) reading and checking the pivot object using the pivot data model and (4) mapping each data attribute to the corresponding TASE.2 data attribute. The resulting TASE.2 object can then be exposed to the TASE.2 client by the north service plugin.

Multiple Substation/RTU gateway

In this alternative scenario, the gateway is connected to multiple RTUs located in multiple substations. Each South plugin (IEC 104 client) is connected to an RTU (IEC 104 server) to collect data. The collected data flow then through the Storage and the North plugin (TASE.2) to expose data to the SCADA.

Use case 2: monitoring and control

Single Scada/single protocol

In this use case data flows in two directions: monitoring and control.

Monitoring data are acquired from a field device called IED (Intelligent Electronic Device) which acts as a 61850 MMS server and are exposed to the central SCADA which acts as a OPC UA client. Each incoming message from the IED comes as a 61850 MMS object. The south service plugin applies a first translation process which consists of (1) reading and checking the 61850 MMS object using the 61850 MMS data model and (2) mapping each data attribute to the corresponding pivot object data attribute. Once the message is converted to a pivot object, it can then be stored or consumed by the north or any other service. The north service plugin can then apply a second translation process which consists of (3) reading and checking the pivot object using the pivot object data model and (4) mapping each data attribute to the corresponding OPC UA data attribute. The resulting OPC UA object can then be exposed to the OPC UA client by the north service plugin.

Control data are received from the control center SCADA which acts as a OPC UA client and are sent to the IED which acts as a 61850 server. Each incoming message from the control center SCADA comes as an OPC UA object. The north service plugin applies a first translation process which consists of (1) reading and checking the OPC UA object using the OPC UA data model and (2) mapping each data attribute to the corresponding pivot object data attribute. Once the message is converted to a pivot object, it can then be stored or consumed by the south or any other service. The south service plugin can then apply a second translation process which consists of (3) reading and checking the pivot object using the pivot object data model and (4) mapping each data attribute to the corresponding 61850 MMS data attribute. The resulting 61850 MMS object can then be exposed to the 61850 client by the south service plugin.

Multiple Scadas/multiple protocols

In this alternative scenario, the gateway is connected to multiple SCADAs using two different protocols. The North plugin (TASE.2) exposes data to the TASE.2 SCADA and the North plugin OPC UA exposes data to the OPC UA SCADA. Instead of having a one to one translation process (61850 to TASE.2, 61850 to OPC UA, TASE.2 to 61850, OPC UA to 61850), we use the pivot object to transmit data from 61850 to both TASE.2 and OPC UA. The translation process is done only once for each protocol.

Benefits and challenges of a pivot object

Benefits

The main benefit of the pivot object is it allows decoupling the protocols data model from each other. Each south or north plugin deals with the complexity and the specifics of a given protocol without interfering with the core of the gateway or with another south/north plugin. Adding new protocol plugins or maintaining existing ones is then made much easier. This contributes in maintaining the whole gateway system at a low level of complexity thus minimizing the costs of new developments or maintenance.

Challenges

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.

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.

Pivot object model

The pivot object model is based on 61850 semantic.

Pivot model representing a Tele Measurement:

{
	"@xmlns:xs": "http://www.w3.org/2001/XMLSchema",
	"PIVOTTM": {
		"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 model representing a Tele Signal:

{
	"@xmlns:xs": "http://www.w3.org/2001/XMLSchema",
	"PIVOTTS": {
		"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 model representing a Tele Command:

{
	"@xmlns:xs": "http://www.w3.org/2001/XMLSchema",
	"PIVOTTC": {
		"GTIC": {
			"Beh": {
				"stVal": "on"
			},
			"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

Protocol translation configuration

{
   "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.

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 datapoint
Yes
datapoints.pivot_idunique identifier of the datapoint, this is used to create a pivot object
Yes
datapoints.pivot_typetype of Common Data Class (CDC), this is used to create a pivot objectSpsTyp, DpsTyp, MvTyp, SpcTyp, DpcTyp, etc...Yes
datapoints.protocolsarray of protocols that needs to be managed for a datapoint
Yes
datapoint.protocols.namename of the protocoliec104, tase2, hnz, 61850, opcua, etc...Yes
datapoint.protocols.addressaddress of the datapoint in the given protocol
Yes
datapoint.protocols.typeidtype id of the datapoint in the given protocol
Yes

Configuration JSON structure

{
   "exchanged_data":{
      "name":"SAMPLE",
      "version":"1.0",
      "datapoints":[
         {
            "label":"TS1",
            "pivot_id":"ID114562",
            "pivot_type":"SpsTyp",
            "protocols":[
               {
                  "name":"iec104",
                  "address":"45-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":"45-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

AttributeDescriptionExpected valuesMandatory
namethis identifies the protocol stackiec104client, iec104server, tase2client, tase2server, 61850client, 61850server, etc...Yes
versionversion number of the configuration file2 digits x.y => x = major change, y = minor changeYes
redundancy_groupsarray of redundancy groups
Yes
redundancy_groups.connectionsarray of connections of a given redundancy group
Yes
redundancy_groups.connections.srv_ipIP address to remote IEC 104 serverIP addressYes
redundancy_groups.connections.portport number to remote IEC 104 serverdefault = 2404No
redundancy_groups.connections.connestablish connection at startupTRUE, FALSE, default = TRUENo
redundancy_groups.connections.startstart data transfer at startupTRUE, FALSE, default = TRUENo
redundancy_groups.k_valueMaximum number of outstanding (unacknowledged) APDU's at a given timedefault = 12No
redundancy_groups.w_valueAcknowledge the reception latest after this number of APDU'sdefault = 8No
redundancy_groups.t0_timeouttime out of connection establishmentdefault = 10No
redundancy_groups.t1_timeouttime out for send or test APDU'sdefault = 15No
redundancy_groups.t2_timeouttime out for acknowledges in case of no data messages (t2 < t1)default = 10No
redundancy_groups.t3_timeouttime out for sending test framesdefault = 20No
redundancy_groups.rg_namethis identifies the redundancy group
Yes
redundancy_groups.tlsactivation of TLS (see tls configuration chapter for details)TRUE, FALSE, default = FALSENo
orig_addrOriginator Addressdefault = 0No
ca_asdu_sizesize of "Common Address of ASDU"default = 2 (byte)No
ioaddr_sizesize of 'Information Object Address'default = 3 (byte)No
startup_timetime to wait for startup completiondefault = 180 (seconds)No
asdu_size

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

default = 0 (byte)No
gi_timetime to wait for General Interrogation (GI) completiondefault = 0 (seconds)No
gi_cyclesend General Interrogation (GI) cyclicallyTRUE, FALSE, default = FALSENo
gi_all_casend a separate GI request to every CA; otherwise a broadcast GI request is usedTRUE, FALSE, default = FALSENo
gi_repeat_countrepeat GI for this number of times in case it is incompletedefault = 2No
disc_qualinformation object quality in case of interrupted connectionIV = Invalid, NT = Not Topical, default = NTNo
send_iv_timetime delay before infos are sent as invalid (0 = deactivated)default = 0No
tsivspecifies what to do with a time stamp marked as 'invalid'

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'

No
utc_timeUTC timezone (=TRUE) or local timezone (=FALSE) for time conversionTRUE, FALSE, default = FALSENo
comm_wttaguse commands with time tag (=TRUE) or without time tag (=FALSE)TRUE, FALSE, default = FALSENo
comm_parallelmaximum number of commands to be executed at in parallel (0 = unlimited)default = 0No
exec_cycl_testexecute cyclical test requests (C_TS_NA_1/C_TS_TA_1) in monitoring direction (=TRUE) or not (=FALSE)TRUE, FALSE, default = FALSENo
startup_statestartup in active mode (=TRUE) or in passive mode (=FALSE)TRUE, FALSE, default = TRUENo
reverseallow transmission of information objects in reverse direction (=TRUE) or only in standard direction (=FALSE)TRUE, FALSE, default = FALSENo
time_syncperform time synchronization (=TRUE)TRUE, FALSE, default = FALSENo

Configuration JSON structure

{
   "protocol_stack":{
      "name":"iec104client",
      "version":"1.0",
      "transport_layer":{
         "redundancy_groups":[
            {
               "connections":[
                  {
                     "srv_ip":"192.168.0.10",
                     "port":2404,
                     "conn":true,
                     "start":true
                  },
                  {
                     "srv_ip":"192.168.0.11",
                     "port":2404,
                     "conn":true,
                     "start":false
                  }
               ],
               "rg_name":"red-group-1",
               "tls":false,
               "k_value":12,
               "w_value":8,
               "t0_timeout":10,
               "t1_timeout":15,
               "t2_timeout":10,
               "t3_timeout":20
            },
            {
               "connections":[
                  {
                     "srv_ip":"192.168.0.12",
                     "port":2404,
                     "conn":false,
                     "start":false
                  },
                  {
                     "srv_ip":"192.168.0.13",
                     "port":2404,
                     "conn":false,
                     "start":false
                  }
               ],
               "rg_name":"red-group-2",
               "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,
         "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
      }
   }
}

IEC 104 datapoint representation

This is the Datapoint representation of an IEC 104 ASDU.

{
   "data_object":{
      "do_type":"type_id",
      "do_ca":"ca",
      "do_oa":"oa",
      "do_cot":"cot",
      "do_test":"istest",
      "do_negative":"isnegative",
      "do_ioa":"ioa",
      "do_value":"value",
      "do_quality":"quality_desc",
      "do_ts":"time_marker",
      "do_ts_qual":"isinvalid",
      "do_ts_sum_time":"isSummerTime"
   }
}

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.

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

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:

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

AttributeDescriptionExpected valuesMandatory
namethis identifies the protocol stackiec104client, iec104server, tase2client, tase2server, 61850client, 61850server, etc...Yes
versionversion number of the configuration file2 digits x.y => x = major change, y = minor changeYes
redundancy_groupsarray of redundancy groups
Yes
redundancy_groups.connectionsarray of connections of a given redundancy group
Yes
redundancy_groups.connections.clt_ipaddress to local IEC 104 clientIP addressYes
redundancy_groups.rg_namethis identifies the redundancy group
Yes
bind_on_ipbind on a dedicated local IP addressTRUE, FALSE, default = FALSENo
srv_ipServer IP addressIP address, machine's default IP for a given interfaceNo
portThis defines the TCP/IP port to be used by the server.default = 2404No
tlsactivation of TLS (see tls configuration chapter for details)TRUE, FALSE, default = FALSENo
k_valueMaximum number of outstanding (unacknowledged) APDU's at a given timedefault = 12No
w_valueAcknowledge the reception latest after this number of APDU'sdefault = 8No
t0_timeouttime out of connection establishmentdefault = 10No
t1_timeouttime out for send or test APDU'sdefault = 15No
t2_timeouttime out for acknowledges in case of no data messages (t2 < t1)default = 10No
t3_timeouttime out for sending test framesdefault = 20No
orig_addrOriginator Addressdefault = 0No
ca_asdu_sizesize of "Common Address of ASDU"default = 2 (byte)No
ioaddr_sizesize of 'Information Object Address'default = 3 (byte)No
asdu_size

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

default = 0 (byte)No
time_syncIf set on "TRUE" this parameter allows to synchronize the clock of the local computer by the server. If set on "FALSE", the clock is not synchronized.TRUE, FALSE, default = FALSENo
comm_exec_timeoutDefines the command execution monitoring timeout in milliseconds. The default setting is 20 seconds.default = 20 seconds (20 000 ms)No
comm_recv_timeoutThis parameter defines the highest allowable deviation of received command time tag and local clock. If the difference is too big, command is ignored.default = 0 (disabled)No
tsivspecifies what to do with a time stamp marked as 'invalid'

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

No
resetreset/restart the system on C_RP_NA_1 ASDU (=TRUE) or not (=FALSE)TRUE, FALSE, default = FALSENo
filter_origaccept commands only originated from an authorized originator (=TRUE) or accept all originators (=FALSE)TRUE, FALSE, default = FALSE
filter_listList of Authorized Originators
No

Configuration JSON structure

{
   "protocol_stack":{
      "name":"iec104server",
      "version":"1.0",
      "transport_layer":{
         "redundancy_groups":[
            {
               "connections":[
                  {
                     "clt_ip":"192.168.0.10"
                  },
                  {
                     "clt_ip":"192.168.0.11"
                  },
                  {
                     "clt_ip":"10.152.1.10"
                  },
                  {
                     "clt_ip":"10.152.1.11"
                  }
               ],
			   "rg_name":"red-group-1"
            },
            {
               "connections":[
                  {
                     "clt_ip":"192.168.0.10"
                  },
                  {
                     "clt_ip":"192.168.0.11"
                  },
                  {
                     "clt_ip":"192.168.0.12"
                  },
                  {
                     "clt_ip":"192.168.0.14"
                  },
                  {
                     "clt_ip":"10.152.1.10"
                  },
                  {
                     "clt_ip":"10.152.1.11"
                  },
                  {
                     "clt_ip":"10.152.1.12"
                  },
                  {
                     "clt_ip":"10.152.1.13"
                  }
               ],
			   "rg_name":"red-group-2"
            }
         ],
         "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_addr":1
            },
            {
               "orig_addr":2
            }
         ]
      }
   }
} 

IEC 104 datapoint representation

This is the Datapoint representation of an IEC 104 ASDU for a command.

{
   "command_object":{
      "co_type":"type_id",
      "co_ca":"ca",
      "co_oa":"oa",
      "co_cot":"cot",
      "co_test":"istest",
      "co_negative":"isnegative",
      "co_ioa":"ioa",
      "co_value":"value",
      "co_qu":"pulse",
      "co_se":"Select/Execute",
	  "co_ts":"time_marker"
   }
}
  • No labels