Client - Report Control Blocks (Unbuffered, Buffered)
This sample shows how to use the report control block instances for buffered and unbuffered reports (Unbuffered/Buffered Report Control Blocks: URCB, BRCB). This includes activating and deactivating reports or activating the general interrogation (GI).
Download TwinCAT XAE Project (*.zip): Sample03.zip
The example described here uses the state machine that is described in the "General Client project structure" chapter. The States 0, 1, 11 and 100 are identical to the state machine described there. Other states were modified for the example or new states were also added.
The Report Control Blocks (RCBs) configure and control the sending of buffered or unbuffered report messages. Reports are configured and controlled via read/write accesses to the corresponding attribute values of a Report Control Block. For example, some attribute values configure the content of the information contained in the report, while other attribute values enable or disable the sending of reports. So it is theoretically possible to configure and control a RCB only with the help of the client methods: "GetDataValuesReq" and "SetDataValuesReq". This requires a more detailed knowledge of how the RCBs work since not every attribute may be accessed at all times. Some attribute values only allow read access, while others also allow write access. Some attribute values allow write access only when the RCB is in a certain state. The general interrogation (GI) commands may only be executed when the RCB is in the enabled state. To simplify handling, the TwinCAT IEC 61850 implementation offers even more options for configuring and controlling the RCBs. All available options (methods) are briefly described below.
Basically the RCB attributes are initialized with initial values that have been preconfigured in TwinCAT Telecontrol Configurator for TrgOps, OptFlds, IntgPd, RptID, DatSet etc. after downloading the PLC program (PLC not yet running or no boot project active). If the configuration originates from an ICD file, then TwinCAT Telecontrol Configurator takes the initial values from the ICD file. The client projects are designed in such a way that after starting the PLC they first establish a connection to the server and then read all server data into the client. After that, the client side has the data values that are also present on the server. If the server data differs from the initial values on the client side, then it will be overwritten with the server data. This includes the attributes of the RCBs. The reading of all values is controlled in the client projects via two Boolean variables: "bGetAllServerValues" and "_bReadAllData". If "_bReadAllData" is TRUE then all server data are always read once after the connection is established or restored. Via a rising edge at "bGetAllServerValues" the values can also be read in again at any time. If both Boolean variables are set to FALSE, the data will not be matched. This depends on the application.
Basically, it makes sense to compare the client data with the server after the connection is established. However, the initial values configured in the TwinCAT Telecontrol Configurator are not lost. The application can still access these values through the Config properties of the data attributes. Each data attribute has a property: eConfig or iConfig or nConfig, bConfig (depending on the base type of the data attribute) etc. with the original initial value. In this sample project, among other things, initial values configured in the TwinCAT Telecontrol Configurator are also used when configuring and enabling the RCBs.
The RCB instances used in this sample attach to the Logical Node instance: LLN0. The configuration values exported by the TwinCAT Telecontrol Configurator for report trigger options (TrgOps) or optional report data fields (OptFlds) are also located there, for example.
FUNCTION_BLOCK FB_LN_IED_LD1_LLN0 EXTENDS FB_AcsiCommonLogicalNodeClass
VAR_INPUT
NamPlt: FB_DO_IED_LD1_LLN0_NamPlt := (sClass:='LPL', bLinkResult:=THIS^.AddDataToContainer(ipData:=NamPlt));
Beh: FB_DO_IED_LD1_LLN0_Beh := (sClass:='ENS', bLinkResult:=THIS^.AddDataToContainer(ipData:=Beh));
Health: FB_DO_IED_LD1_LLN0_Health := (sClass:='ENS', bLinkResult:=THIS^.AddDataToContainer(ipData:=Health));
Mod_: FB_DO_IED_LD1_LLN0_Mod := (sObjectName:='Mod', sClass:='ENC', bLinkResult:=THIS^.AddDataToContainer(ipData:=Mod_));
DS1: FB_DS_IED_LD1_LLN0_DS1 := (bLinkResult:=THIS^.AddDataSetToContainer(ipDataSet:=DS1));
DS2: FB_DS_IED_LD1_LLN0_DS2 := (bLinkResult:=THIS^.AddDataSetToContainer(ipDataSet:=DS2));
DS3: FB_DS_IED_LD1_LLN0_DS3 := (bLinkResult:=THIS^.AddDataSetToContainer(ipDataSet:=DS3));
urcb101: FB_ScsmUrCBImplClass := (RptID:=(sValue:='IEDLD1/LLN0.urcb101'),
DatSet:=(sValue:='IEDLD1/LLN0.DS1'),
ConfRev:=(nValue:=1),
OptFlds:=(SequenceNumber:=TRUE, ReportTimeStamp:=TRUE, ReasonForInclusion:=TRUE, DataSetName:=TRUE, DataReference:=TRUE, BufferOverflow:=FALSE, EntryID:=FALSE, ConfRevision:=TRUE),
TrgOps:=(DataChange:=TRUE, QualityChange:=TRUE, DataUpdate:=FALSE, Integrity:=TRUE, GeneralInterrogation:=TRUE),
IntgPd:=(nValue:=2000),
bLinkResult:=THIS^.AddUnbufferedReportControlBlockToContainer(ipUnbufferedReportControlBlock:=urcb101));
urcb201: FB_ScsmUrCBImplClass := (RptID:=(sValue:='IEDLD1/LLN0.urcb201'),
DatSet:=(sValue:='IEDLD1/LLN0.DS2'),
ConfRev:=(nValue:=1),
OptFlds:=(SequenceNumber:=TRUE, ReportTimeStamp:=TRUE, ReasonForInclusion:=TRUE, DataSetName:=TRUE, DataReference:=FALSE, BufferOverflow:=FALSE, EntryID:=FALSE, ConfRevision:=TRUE),
TrgOps:=(DataChange:=TRUE, QualityChange:=TRUE, DataUpdate:=TRUE, Integrity:=TRUE, GeneralInterrogation:=TRUE),
IntgPd:=(nValue:=5000),
bLinkResult:=THIS^.AddUnbufferedReportControlBlockToContainer(ipUnbufferedReportControlBlock:=urcb201));
urcb301: FB_ScsmUrCBImplClass := (RptID:=(sValue:='IEDLD1/LLN0.urcb301'),
DatSet:=(sValue:='IEDLD1/LLN0.DS3'),
ConfRev:=(nValue:=1), OptFlds:=(SequenceNumber:=TRUE, ReportTimeStamp:=TRUE, ReasonForInclusion:=TRUE, DataSetName:=TRUE, DataReference:=FALSE, BufferOverflow:=FALSE, EntryID:=FALSE, ConfRevision:=TRUE),
TrgOps:=(DataChange:=TRUE, QualityChange:=TRUE, DataUpdate:=TRUE, Integrity:=TRUE, GeneralInterrogation:=TRUE),
IntgPd:=(nValue:=5000),
bLinkResult:=THIS^.AddUnbufferedReportControlBlockToContainer(ipUnbufferedReportControlBlock:=urcb301));
brcb101: FB_ScsmBrCBImplClass := (RptID:=(sValue:='IEDLD1/LLN0.brcb101'),
DatSet:=(sValue:='IEDLD1/LLN0.DS1'),
ConfRev:=(nValue:=1),
OptFlds:=(SequenceNumber:=TRUE, ReportTimeStamp:=TRUE, ReasonForInclusion:=TRUE, DataSetName:=TRUE, DataReference:=TRUE, BufferOverflow:=TRUE, EntryID:=TRUE, ConfRevision:=TRUE),
TrgOps:=(DataChange:=TRUE, QualityChange:=TRUE, DataUpdate:=FALSE, Integrity:=TRUE, GeneralInterrogation:=TRUE),
IntgPd:=(nValue:=2000),
bLinkResult:=THIS^.AddBufferedReportControlBlockToContainer(ipBufferedReportControlBlock:=brcb101));
brcb201: FB_ScsmBrCBImplClass := (RptID:=(sValue:='IEDLD1/LLN0.brcb201'),
DatSet:=(sValue:='IEDLD1/LLN0.DS2'),
ConfRev:=(nValue:=1), OptFlds:=(SequenceNumber:=TRUE, ReportTimeStamp:=TRUE, ReasonForInclusion:=TRUE, DataSetName:=TRUE, DataReference:=FALSE, BufferOverflow:=TRUE, EntryID:=TRUE, ConfRevision:=TRUE),
TrgOps:=(DataChange:=TRUE, QualityChange:=TRUE, DataUpdate:=TRUE, Integrity:=TRUE, GeneralInterrogation:=TRUE),
IntgPd:=(nValue:=5000),
bLinkResult:=THIS^.AddBufferedReportControlBlockToContainer(ipBufferedReportControlBlock:=brcb201));
brcb301: FB_ScsmBrCBImplClass := (RptID:=(sValue:='IEDLD1/LLN0.brcb301'),
DatSet:=(sValue:='IEDLD1/LLN0.DS3'),
ConfRev:=(nValue:=1),
OptFlds:=(SequenceNumber:=TRUE, ReportTimeStamp:=TRUE, ReasonForInclusion:=TRUE, DataSetName:=TRUE, DataReference:=FALSE, BufferOverflow:=TRUE, EntryID:=TRUE, ConfRevision:=TRUE),
TrgOps:=(DataChange:=TRUE, QualityChange:=TRUE, DataUpdate:=TRUE, Integrity:=TRUE, GeneralInterrogation:=TRUE),
IntgPd:=(nValue:=5000),
bLinkResult:=THIS^.AddBufferedReportControlBlockToContainer(ipBufferedReportControlBlock:=brcb301));
END_VAR
VAR
END_VAR
Report configuration/control with the methods: GetDataValuesReq, SetDataValuesReq
These are the basic methods to configure and control the RCBs. They provide full control over the behavior of the RCB, but require more detailed knowledge of how RCBs work and more programming effort. You may need to implement a more complex state machine yourself in which you perform multiple read/write accesses to various RCB attribute values using these methods. Use these methods, for example, when you need a behavior that does not conform to the default. In this sample, the use of these methods to configure and control the RCBs will not be discussed further. However, the following steps are necessary, for example, to activate the sending of reports of an unbuffered RCB:
- Read current configuration and status information of the RCB. The values of all attributes: "RptEna", "Resv", "OptFlds", "DatSet", "TrgOps", ..., etc. are read with the method: "GetDataValuesReq".
- Write new configuration values if necessary. New values are written into the attributes "OptFlds", "DatSet" or "TrgOps", ... etc. with the method: "SetDataValuesReq".
- Write the value: "TRUE" into the attribute: "Resv". The RCB is reserved for use with the client.
- Write the value: "TRUE" into the attribute: "RptEna". The sending of the reports is then enabled.
The following steps are necessary, for example, to disable the sending of reports of an unbuffered RCB:
- Write the value "FALSE" into the attribute "RptEna". The sending of reports is disabled.
- Write the value "FALSE" into the attribute "Resv". The reservation for using the RCB with the client is removed.
Report configuration/control with the methods: GetUrCBValuesReq, SetUrCBValuesReq, GetBrCBValuesReq, SetBrCBValuesReq
These methods allow reading all or writing one or more attribute values with a single method call. The methods: "GetUrCBValuesReq" or "GetBrCBValuesReq" read all attribute values of a RCB. In this case, if successful, all attribute values of an RCB are transferred from the server to the client and copied to the TwinCAT IEC 61850 data model.
The methods: "SetUrCBValuesReq" and "SetBrCBValuesReq" allow writing one or more attribute values of a RCB. When enabling/disabling the reports, the order in which the attribute values are written plays an important role. Most RCB configuration values can only be written when reports are not active. For unbuffered reports, for example, the attribute value "Resv" must first be set to "TRUE" before the attribute value "RptEna" can be set to "TRUE" (to enable the reports). When disabling the reports, these attribute values must be set to "FALSE" in the reverse order. I.e. first "RptEna" and then "Resv". The Set method parameter "stSet" determines which attribute values are to be written. The new values to be written are first written into the data model, then the corresponding attributes are selected via the "stSet" parameter and the Set method is called. On success, the data is transferred from the IEC 61850 client data model to the server.
Report configuration/control using the methods of the RCB client object
The easiest way to configure and control the buffered or unbuffered reports is to use the client function block below the report control block instance. The client function block has properties to configure the RCB and methods to enable or disable the transmission of reports. For example, in the image below, the IntelliSense shows the available methods and properties with a buffered RCB:

Some methods and properties in unbuffered RCB:

The following table lists the main methods and properties of the client function block at the report control block instance. The client function block works with predefined default values for trigger options, optional data fields and max. time between Integrity Reports unless configured otherwise. The default values can be changed individually for each client instance by writing to the appropriate properties. The new values are first transferred to the server before enabling the report, if they are different from those of the server side, and only then the report is enabled.
Method/property | Description | Initial value |
---|---|---|
EnableReq | Enables the sending of the reports | - |
DisableReq | Disables (stops) the sending of the reports | - |
GIReq | Enabless the general interrogation command | - |
PurgeBufReq (only for buffered RCBs) | Enables the command to reset the buffer | - |
ResyncReq (only for buffered RCBs) | Enables the command for resynchronization of the buffered data | - |
Clear | Resets the function block | - |
cOptFlds | Configures the data fields contained in the report | Unbuffered RCBs: all data fields enabled except the "DataReference", "BufferOverflow" and "EntryID". Buffered RCBs: all data fields enabled except the "DataReference" |
cTrgOps | Configures the trigger options for a report | All enabled ("DataUpdate", "DataChange", "QualityChange", "GeneralInterrogation", "Integrity") |
iResvTms | OPTIONAL: configures the time for reserving the RCB for a specific client. | 60 if present |
nBufTm | Max. report buffer time in milliseconds | 0 |
nIntgPd | Max. time between integrity reports in milliseconds | 5000 |
sRptID | Report ID | Empty string. A new value, if set, will be transmitted to the server only if it is not an empty string and if it is different from the current server value. |
When a method is enabled, the current status of the RCB is first queried internally by the server. Next, depending on the selected method, some properties are then transferred to the server. The set values of the properties are transferred to the server only if the value in the property differs from the respective value of the corresponding attribute in the data model. Finally, the status information is queried again internally from the server. Some methods require additional parameters. For example, the "EnableReq" method requires the interface pointer to the connection instance and the DataSet.
The client function block has a structured output variable with the name: "stInfo". This variable contains RCB status information and information about the last report received. However, this status information is only updated if the client function block was also used to configure and enable the reports. The client function block does not update its status information when the other methods described above (SetUrCBValuesReq, SetBrCBValuesReq or SetDataValuesReq, etc.) are used to configure or enable the reports.

In online mode, the status information of the client function block can be used for simple diagnostics.
Parameter list for configuring the default values of the RCB client object
The default values of all client instances can be changed system-wide, if necessary, by changing the parameter list: Param_Scsm (in the Tc3_iec61850_8_1 PLC library).
VAR_GLOBAL CONSTANT
cBrCB_OptFlds : ST_AcsiOptionalFields:=(SequenceNumber:=1, ReportTimeStamp:=1, ReasonForInclusion:=1, DataSetName:=1, DataReference:=0, BufferOverflow:=1, EntryID:=1, ConfRevision:=1, Segmentation:=0);
cBrCB_TrgOps : ST_AcsiTriggerConditions:=(DataChange:=1, QualityChange:=1, DataUpdate:=1, Integrity:=1, GeneralInterrogation:=1);
cBrCB_IntgPd : DWORD:=5000;
cUrCB_OptFlds : ST_AcsiOptionalFields:=(SequenceNumber:=1, ReportTimeStamp:=1, ReasonForInclusion:=1, DataSetName:=1, DataReference:=0, BufferOverflow:=0, EntryID:=0, ConfRevision:=1, Segmentation:=0);
cUrCB_TrgOps : ST_AcsiTriggerConditions:=(DataChange:=1, QualityChange:=1, DataUpdate:=1, Integrity:=1, GeneralInterrogation:=1);
cUrCB_IntgPd : DWORD:=5000;
cBrCB_iResvTms : INT(-1..3600):=60;
END_VAR
Sample project
The unbuffered "urcb101" and the buffered RCB "brcb101" can be controlled in two ways in the sample project. Once with the help of the methods: "GetUrCBValuesReq", "GetBrCBValuesReq", "SetUrCBValuesReq" and "SetBrCBValuesReq". The other option involves the methods at the client function block below the report control block instance. The Boolean and Enum variables described further below can be found in the implementation of the function block: "FB_IEDClient". There is also an ICD file in the project archive. This file describes the IEC 61850 data model used in the sample project. For example, you can use this file in a third-party software and simulate a server.
Test with Get/Set methods
A rising edge at the Boolean variable: "bGetUrCBValues_urcb101" or "bGetBrCBValues_brcb101" enables the reading of all attribute values of the RCB: "urcb101" or "brcb101". By changing the value at the enumeration variable "eSetUrCBValues_urcb101_Resv" and "eSetUrCBValues_urcb101_RptEna" or "eSetBrCBValues_brcb101_RptEna" the Boolean value of the data attributes "Resv" or "RptEna" can be set to "True" or "False". Ideally, if all other RCB attribute values are already preconfigured and these values are already on the server side, the RCB: "urcb101" can be enabled in the following way:
the value "Enable" written to the variable: "eSetUrCBValues_urcb101_Resv" describes the attribute: "Resv" with the value "TRUE". The value "Enable" written to the variable: "eSetUrCBValues_urcb101_RptEna" describes the attribute: "RptEna" with the value "TRUE". After that the transmission of the unbuffered reports of "urcb101" is enabled.
The RCB: "brcb101" can be enabled in the following way:
the value "Enable" written in the variable: "eSetBrCBValues_brcb101_RptEna" describes the attribute: "RptEna" with the value "TRUE". After that the transmission of the buffered reports of "brcb101" is enabled.
…
(*===================================================================================================================================*)
(* Write "IEDLD1/LLN0.urcb101.Resv" data attribute value: True|False *)
ELSIF eSetUrCBValues_urcb101_Resv <> E_CtlBool.None THEN (* Example => execute SetUrCBValuesReq() command *)
memset(ADR(stSet_urcb), 0, SIZEOF(stSet_urcb)); (* Clear all URCB attribute selection flags *)
stSet_urcb.Resv:= TRUE; (* Select URCB->Resv attribute to be written *)
fbIED.IEDLD1.LLN0.urcb101.Resv.bValue:= SEL(eSetUrCBValues_urcb101_Resv = E_CtlBool.Enable, FALSE, TRUE); (* Set new data attribute value to be written *)
bSuccess:= fbConnection.SetUrCBValuesReq(ipUrCB:=fbIED.IEDLD1.LLN0.urcb101, stSet:=stSet_urcb, hUser:=0, ipSink:=0, nInvokeID=>nInvokeID, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
eSetUrCBValues_urcb101_Resv:= E_CtlBool.None; (* Reset enum value to recognize next write request *)
(*===================================================================================================================================*)
(* Write "IEDLD1/LLN0.urcb101.RptEna" data attribute value: True|False *)
ELSIF eSetUrCBValues_urcb101_RptEna <> E_CtlBool.None THEN (* Example => execute SetUrCBValuesReq() command *)
memset(ADR(stSet_urcb), 0, SIZEOF(stSet_urcb)); (* Clear all URCB attribute selection flags *)
stSet_urcb.RptEna:= TRUE; (* Select URCB->RptEna attribute to be written *)
fbIED.IEDLD1.LLN0.urcb101.RptEna.bValue:= SEL(eSetUrCBValues_urcb101_RptEna = E_CtlBool.Enable, FALSE, TRUE); (* Set new data attribute value to be written *)
bSuccess:= fbConnection.SetUrCBValuesReq(ipUrCB:=fbIED.IEDLD1.LLN0.urcb101, stSet:=stSet_urcb, hUser:=0, ipSink:=0, nInvokeID=>nInvokeID, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
eSetUrCBValues_urcb101_RptEna:= E_CtlBool.None; (* Reset enum value to recognize next write request *)
…
(*==================================================================================================================================*)
(* Write "IEDLD1/LLN0.brcb101.RptEna" data attribute value *)
ELSIF eSetBrCBValues_brcb101_RptEna <> E_CtlBool.None THEN (* Example => execute SetBrCBValuesReq() command *)
memset(ADR(stSet_brcb), 0, SIZEOF(stSet_brcb)); (* Clear all BRCB attribute selection flags *)
stSet_brcb.RptEna:= TRUE; (* Select BRCB->RptEna attribute to be written *)
fbIED.IEDLD1.LLN0.brcb101.RptEna.bValue:= SEL(eSetBrCBValues_brcb101_RptEna = E_CtlBool.Enable, FALSE, TRUE); (* Set new data attribute value to be written *)
bSuccess:= fbConnection.SetBrCBValuesReq(ipBrCB:=fbIED.IEDLD1.LLN0.brcb101, stSet:=stSet_brcb, hUser:=0, ipSink:=0, nInvokeID=>nInvokeID, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
eSetBrCBValues_brcb101_RptEna:= E_CtlBool.None; (* Reset enum value to recognize next write request *)
…
To stop the transmission of the unbuffered reports, first the value "Disable" must be written into the variable: "eSetUrCBValues_urcb101_RptEna" and then into the variable: "eSetUrCBValues_urcb101_Resv". This sets the values of the data attributes "RptEna" and "Resv" to FALSE.
To stop the transmission of the buffered reports, the value "Disable" must be written to the variable "eSetBrCBValues_brcb101_RptEna". This sets the value of the data attribute "RptEna" to FALSE.
Test with client methods on report control block instance
To consider all states of a RCB, an enum is used here to enable "urcb101" or "brcb101" control commands. As soon as the enum "eControl_IEDLD1_LLN0_urcb101" or "eControl_IEDLD1_LLN0_brcb101" is not "E_AcsiCtlReport.None", the corresponding command is enabled at the RCB.
The "ipResult" output of the function block can be used to query the status of the processing of the last command. Since the execution of the methods takes longer than one cycle, the state machine is set to State 11. There the method "Execute" of the interface pointer "ipResult" must be called until "ipResult.IsBusy()" returns the value "FALSE". If this is currently processing the function, "IsBusy()" is returned as "TRUE" and the state machine remains in State 11. The state machine is reset to State 0 as soon as the command has been successfully executed. The instances "urcb101" and "brcb101" are enabled in this sample with the values for "TrgOps", "OptFlds" and "IntgPd". These values were configured in the TwinCAT Telecontrol Configurator.
…
(*=======================================================================================================================================*)
(* Control unbuffered reports using "IEDLD1/LLN0.urcb101.Client" function block instance *)
ELSIF eControl_IEDLD1_LLN0_urcb101 <> E_AcsiCtlReport.None THEN
IF eControl_IEDLD1_LLN0_urcb101 = E_AcsiCtlReport.Enable THEN (* Example => enable reporting *)
(* Changing default properties of "Client" function block configures reporting behaviour and content of report message data.
The "Client" function block writes the new property values to the server and enables RCB.
In this example we use configuration values that were defined in the TwinCAT Telecontrol Configurator to control "urcb101".*)
(* Configures "RptID" (report ID) to be used in report message *)
fbIED.IEDLD1.LLN0.urcb101.Client.sRptID:= fbIED.IEDLD1.LLN0.urcb101.RptID.sConfig;(* => "IEDLD1/.LLN0.urcb101" *)
(* Configures "TrgOps" (trigger options) to be used to trigger new report messages *)
fbIED.IEDLD1.LLN0.urcb101.Client.cTrgOps:= fbIED.IEDLD1.LLN0.urcb101.TrgOps.cConfig;(* => All enabled except "DataUpdate" *)
(* Configures "OptFlds" (optional fields) to be used in report message *)
fbIED.IEDLD1.LLN0.urcb101.Client.cOptFlds:= fbIED.IEDLD1.LLN0.urcb101.OptFlds.cConfig;(* => All enabled except "BufferOverflow" and "EntryID" *)
(* Configures "IntgPd" (period in milliseconds used to generate integrity report) *)
fbIED.IEDLD1.LLN0.urcb101.Client.nIntgPd:= fbIED.IEDLD1.LLN0.urcb101.IntgPd.nConfig;(* => 2000ms *)
(* Configures "BufTm" (max. report message buffer time in milliseconds) *)
fbIED.IEDLD1.LLN0.urcb101.Client.nBufTm:= fbIED.IEDLD1.LLN0.urcb101.BufTm.nConfig;(* => 0ms *)
(* Write properties and enable RCB *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb101.Client.EnableReq(ipClient:=fbConnection, ipDataSet:=fbIED.IEDLD1.LLN0.DS1, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_urcb101 = E_AcsiCtlReport.Disable THEN (* Example => disable reporting *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb101.Client.DisableReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_urcb101 = E_AcsiCtlReport.GI THEN (* Example => execute general interrogation *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb101.Client.GIReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
END_IF
eControl_IEDLD1_LLN0_urcb101:= E_AcsiCtlReport.None; (* Reset enum value to recognize next write request *)
…
(*=======================================================================================================================================*)
(* Control buffered reports using "IEDLD1/LLN0.brcb101.Client" function block instance *)
ELSIF eControl_IEDLD1_LLN0_brcb101 <> E_AcsiCtlReport.None THEN
IF eControl_IEDLD1_LLN0_brcb101 = E_AcsiCtlReport.Enable THEN (* Example => enable reporting using *)
(*
Changing default properties of "Client" function block configures reporting behaviour and content of report message data.
The "Client" function block writes the new property values to the server and enables RCB.
In this example we use configuration values that were defined in the TwinCAT Telecontrol Configurator to control "brcb101".
*)
(* Configures "RptID" to be used in report message *)
fbIED.IEDLD1.LLN0.brcb101.Client.sRptID:= fbIED.IEDLD1.LLN0.brcb101.RptID.sConfig;(* => "IEDLD1/LLN0.brcb101" *)
(* Configures "TrgOps" (trigger options) to be used to trigger new report messages *)
fbIED.IEDLD1.LLN0.brcb101.Client.cTrgOps:= fbIED.IEDLD1.LLN0.brcb101.TrgOps.cConfig;(* => All enabled except "DataUpdate" *)
(* Configures "OptFlds" (option fields) to be used in report message *)
fbIED.IEDLD1.LLN0.brcb101.Client.cOptFlds:= fbIED.IEDLD1.LLN0.brcb101.OptFlds.cConfig;(* => All enabled *)
(* Configures "IntgPd" (period in milliseconds used to generate integrity report) *)
fbIED.IEDLD1.LLN0.brcb101.Client.nIntgPd:= fbIED.IEDLD1.LLN0.brcb101.IntgPd.nConfig;(* => 2000ms *)
(* Configures "BufTm" (max. report message buffer time in milliseconds) *)
fbIED.IEDLD1.LLN0.brcb101.Client.nBufTm:= fbIED.IEDLD1.LLN0.brcb101.BufTm.nConfig;(* => 0ms *)
(* Write properties and enable RCB *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb101.Client.EnableReq(ipClient:=fbConnection, ipDataSet:=fbIED.IEDLD1.LLN0.DS1, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb101 = E_AcsiCtlReport.Disable THEN (* Example => disable reporting *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb101.Client.DisableReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb101 = E_AcsiCtlReport.GI THEN (* Example => execute general interrogation *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb101.Client.GIreq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb101 = E_AcsiCtlReport.PurgeBuf THEN (* Example => execute purge buffer *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb101.Client.PurgeBufReq(ipClient:=fbConnection, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb101 = E_AcsiCtlReport.Resync THEN (* Example => execute resync *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb101.Client.ResyncReq(ipClient:=fbConnection, nEntryID:=Last_Rx_brcb101_nEntryID, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
END_IF
eControl_IEDLD1_LLN0_brcb101:= E_AcsiCtlReport.None;(* Reset enum value to recognize next write request *)
…
For demonstration purposes, however, the instances "urcb201" and "brcb201" are not enabled with the values for "TrgOps", "OptFlds", "IntgPd" etc. configured and exported in the TwinCAT Telecontrol Configurator. Instead, the default values of the "client" instance are used when the report is enabled.
…
(*=======================================================================================================================================*)
(* Control unbuffered reports using "IEDLD1/LLN0.urcb201.Client" function block instance *)
ELSIF eControl_IEDLD1_LLN0_urcb201 <> E_AcsiCtlReport.None THEN
IF eControl_IEDLD1_LLN0_urcb201 = E_AcsiCtlReport.Enable THEN (* Example => enable reporting *)
(*
Changing default properties of "Client" function block configures reporting behaviour and content of report message data (optional).
The "Client" function block writes the new property values to the server and enables RCB.
In this example we use the standard configuration values of the function block "Client" to control the "urcb201":
"fbIED.IEDLD1.LLN0.urcb201.Client.sRptID":= Empty string. Property "sRptID" is written if <> '' and differs from server value.
"fbIED.IEDLD1.LLN0.urcb201.Client.cTrgOps":= All trigger options are enabled
"fbIED.IEDLD1.LLN0.urcb201.Client.cOptFlds":= All options are enabled except "DataReference", "BufferOverflow" and "EntryID"
"fbIED.IEDLD1.LLN0.urcb201.Client.nIntgPd":= Set to 5000ms
"fbIED.IEDLD1.LLN0.urcb201.Client.nBufTm":= Set to 0ms
*)
(* Write properties and enable RCB *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb201.Client.EnableReq(ipClient:=fbConnection, ipDataSet:=fbIED.IEDLD1.LLN0.DS2, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_urcb201 = E_AcsiCtlReport.Disable THEN (* Example => disable reporting *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb201.Client.DisableReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_urcb201 = E_AcsiCtlReport.GI THEN (* Example => execute general interrogation *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb201.Client.GIReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
END_IF
eControl_IEDLD1_LLN0_urcb201:= E_AcsiCtlReport.None; (* Reset enum value to recognize next write request *)
…
(*=======================================================================================================================================*)
(* Control buffered reports using "IEDLD1/LLN0.brcb201.Client" function block instance *)
ELSIF eControl_IEDLD1_LLN0_brcb201 <> E_AcsiCtlReport.None THEN
IF eControl_IEDLD1_LLN0_brcb201 = E_AcsiCtlReport.Enable THEN (* Example => enable reporting *)
(*
Changing default properties of "Client" function block configures reporting behaviour and content of report message data (optional).
The "Client" function block writes the new property values to the server and enables RCB.
In this example we use the standard configuration values of the function block "Client" to control the "brcb201":
"fbIED.IEDLD1.LLN0.brcb201.Client.sRptID":= Empty string. Property "sRptID" is only written if <> '' and differs from server value
"fbIED.IEDLD1.LLN0.brcb201.Client.cTrgOps":= All trigger options are enabled
"fbIED.IEDLD1.LLN0.brcb201.Client.cOptFlds":= All options are enabled except "DataReference"
"fbIED.IEDLD1.LLN0.brcb201.Client.nIntgPd":= Set to 5000ms
"fbIED.IEDLD1.LLN0.brcb201.Client.nBufTm":= Set to 0ms
*)
(* Write properties and enable RCB *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb201.Client.EnableReq(ipClient:=fbConnection, ipDataSet:=fbIED.IEDLD1.LLN0.DS2, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb201 = E_AcsiCtlReport.Disable THEN (* Example => disable reporting *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb201.Client.DisableReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb201 = E_AcsiCtlReport.GI THEN (* Example => execute general interrogation *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb201.Client.GIreq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb201 = E_AcsiCtlReport.PurgeBuf THEN (* Example => execute purge buffer *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb201.Client.PurgeBufReq(ipClient:=fbConnection, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb201 = E_AcsiCtlReport.Resync THEN (* Example => execute resync *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb201.Client.ResyncReq(ipClient:=fbConnection, nEntryID:=Last_Rx_brcb201_nEntryID, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
END_IF
eControl_IEDLD1_LLN0_brcb201:= E_AcsiCtlReport.None; (* Reset enum value to recognize next write request *)
…
The "urcb301" and "brcb301" instances are in turn enabled with user-defined values for "TrgOps", "OptFlds" and "IntgPd".
…
(*=======================================================================================================================================*)
(* Control unbuffered reports using "IEDLD1/LLN0.urcb301.Client" function block instance *)
ELSIF eControl_IEDLD1_LLN0_urcb301 <> E_AcsiCtlReport.None THEN
IF eControl_IEDLD1_LLN0_urcb301 = E_AcsiCtlReport.Enable THEN (* Example => enable reporting *)
(*
Changing default properties of "Client" function block configures reporting behaviour and content of report message data.
The "Client" function block writes the new property values to the server and enables RCB.
In this example we use configuration values that were defined by application/user to control the "urcb301".
*)
(* Configures "RptID" (report ID) to be used in report message *)
fbIED.IEDLD1.LLN0.urcb301.Client.sRptID:= 'IEDLD1/LLN0.RP.urcb301';
(* Configures "TrgOps" (trigger options) to be used to trigger new report messages *)
usrTrgOps.DataChange:= TRUE;
usrTrgOps.DataUpdate:= FALSE;
usrTrgOps.QualityChange:= FALSE;
usrTrgOps.Integrity:= TRUE;
usrTrgOps.GeneralInterrogation:= TRUE;
fbIED.IEDLD1.LLN0.urcb301.Client.cTrgOps:= usrTrgOps;
(* Configures "OptFlds" (option fields) to be used in report message *)
usrOptFlds.ConfRevision:= TRUE;
usrOptFlds.DataReference:= FALSE;
usrOptFlds.DataSetName:= FALSE;
usrOptFlds.ReasonForInclusion:= TRUE;
usrOptFlds.ReportTimeStamp:= FALSE;
usrOptFlds.SequenceNumber:= TRUE;
usrOptFlds.BufferOverflow:= FALSE;
usrOptFlds.EntryID:= FALSE;
fbIED.IEDLD1.LLN0.urcb301.Client.cOptFlds:= usrOptFlds;
(* Configures "IntgPd" (period in milliseconds used to generate integrity report) *)
fbIED.IEDLD1.LLN0.urcb301.Client.nIntgPd:= 1000;
(* Configures "BufTm" (max. report message buffer time in milliseconds) *)
fbIED.IEDLD1.LLN0.urcb301.Client.nBufTm:= 500;
(* Write properties and enable RCB *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb301.Client.EnableReq(ipClient:=fbConnection, ipDataSet:=fbIED.IEDLD1.LLN0.DS3, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_urcb301 = E_AcsiCtlReport.Disable THEN (* Example => disable reporting *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb301.Client.DisableReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_urcb301 = E_AcsiCtlReport.GI THEN (* Example => execute general interrogation *)
bSuccess:= fbIED.IEDLD1.LLN0.urcb301.Client.GIReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
END_IF
eControl_IEDLD1_LLN0_urcb301:= E_AcsiCtlReport.None; (* Reset enum value to recognize next write request *)
…
(*=======================================================================================================================================*)
(* Control buffered reports using "IEDLD1/LLN0.brcb301.Client" function block instance *)
ELSIF eControl_IEDLD1_LLN0_brcb301 <> E_AcsiCtlReport.None THEN
IF eControl_IEDLD1_LLN0_brcb301 = E_AcsiCtlReport.Enable THEN (* Example => enable reporting using *)
(*
Changing default properties of "Client" function block configures reporting behaviour and content of report message data.
The "Client" function block writes the new property values to the server and enables RCB.
In this example we use configuration values that were defined by application/user to control the "brcb301".
*)
(* Configures "RptID" (report ID) to be used in report message *)
fbIED.IEDLD1.LLN0.brcb301.Client.sRptID:= 'IEDLD1/LLN0.BR.brcb301';
(* Configures "TrgOps" (trigger options) to be used to trigger new report messages *)
usrTrgOps.DataChange:= TRUE;
usrTrgOps.DataUpdate:= FALSE;
usrTrgOps.QualityChange:= FALSE;
usrTrgOps.Integrity:= TRUE;
usrTrgOps.GeneralInterrogation:= TRUE;
fbIED.IEDLD1.LLN0.brcb301.Client.cTrgOps:= usrTrgOps;
(* Configures "OptFlds" (option fields) to be used in report message *)
usrOptFlds.ConfRevision:= TRUE;
usrOptFlds.DataReference:= FALSE;
usrOptFlds.DataSetName:= FALSE;
usrOptFlds.ReasonForInclusion:= TRUE;
usrOptFlds.ReportTimeStamp:= FALSE;
usrOptFlds.SequenceNumber:= TRUE;
usrOptFlds.BufferOverflow:= TRUE;
usrOptFlds.EntryID:= TRUE;
fbIED.IEDLD1.LLN0.brcb301.Client.cOptFlds:= usrOptFlds;
(* Configures "IntgPd" (period in milliseconds used to generate integrity report) *)
fbIED.IEDLD1.LLN0.brcb301.Client.nIntgPd:= 10000;
(* Configures "BufTm" (max. report message buffer time in milliseconds) *)
fbIED.IEDLD1.LLN0.brcb301.Client.nBufTm:= 500;
(* Write properties and enable RCB *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb301.Client.EnableReq(ipClient:=fbConnection, ipDataSet:=fbIED.IEDLD1.LLN0.DS3, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb301 = E_AcsiCtlReport.Disable THEN (* Example => disable reporting *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb301.Client.DisableReq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb301 = E_AcsiCtlReport.GI THEN (* Example => execute general interrogation *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb301.Client.GIreq(ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb301 = E_AcsiCtlReport.PurgeBuf THEN (* Example => execute purge buffer *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb301.Client.PurgeBufReq(ipClient:=fbConnection, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
ELSIF eControl_IEDLD1_LLN0_brcb301 = E_AcsiCtlReport.Resync THEN (* Example => execute resync *)
bSuccess:= fbIED.IEDLD1.LLN0.brcb301.Client.ResyncReq(ipClient:=fbConnection, nEntryID:=Last_Rx_brcb301_nEntryID, ipResult=>ipResult); (* Activation of command execution *)
state:= SEL(bSuccess, 100, 11); (* If command activation succeeded then wait for command completion else report an error *)
END_IF
eControl_IEDLD1_LLN0_brcb301:= E_AcsiCtlReport.None; (* Reset enum value to recognize next write request *)
…
![]() | This is just one example of the implementation of the Report Control Block function in the TwinCAT PLC. |