0% found this document useful (0 votes)
16 views

ProgrammingReference_20241023

SEL PROGRAMING REFERRNCE

Uploaded by

Muath
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
0% found this document useful (0 votes)
16 views

ProgrammingReference_20241023

SEL PROGRAMING REFERRNCE

Uploaded by

Muath
Copyright
© © All Rights Reserved
Available Formats
Download as PDF, TXT or read online on Scribd
You are on page 1/ 1306

Programming Reference

for ACSELERATOR RTAC


SEL-5033 Software

20241023
© 2023–2024 Schweitzer Engineering Laboratories, Inc. All rights reserved.

Content subject to change without notice. Unless otherwise agreed in writing, all SEL product sales are subject to SEL's terms and conditions
located here: https://selinc.com/company/termsandconditions/.

Programming Reference Date Code 20241023


Table of Contents
Section 1: Command Line Interface
Command Line Interface Basics..................................................................................................... 1
Usage........................................................................................................................................ 1
Behavior.................................................................................................................................... 2
Command List............................................................................................................................ 3
Command Line Example Usage....................................................................................................41

Section 2: Library Extensions Installer


Description............................................................................................................................... 43
Installing ACSELERATOR RTAC Extension Packages........................................................................ 43
Bulk Installation of .library, .compiled-library, and .rext Files............................................................. 44
Logging and Debugging.............................................................................................................. 44
Return Value............................................................................................................................. 45
Notes and Exceptions................................................................................................................. 45

Section 3: AnalogConditioning
Introduction.............................................................................................................................. 47
Supported Firmware Versions.......................................................................................................47
Global Parameters...................................................................................................................... 47
Interface Definitions................................................................................................................... 47
Classes..................................................................................................................................... 49
Benchmarks.............................................................................................................................. 57
Examples.................................................................................................................................. 58

Section 4: ChannelMonitoring
Introduction.............................................................................................................................. 65
Supported Firmware Versions.......................................................................................................66
Enumerations............................................................................................................................ 67
Functions.................................................................................................................................. 68
Function Blocks......................................................................................................................... 69
Classes..................................................................................................................................... 80
Benchmarks.............................................................................................................................. 88
Examples.................................................................................................................................. 93

Section 5: ConditionMonitoring
Introduction............................................................................................................................. 103
Supported Firmware Versions..................................................................................................... 103
Enumerations........................................................................................................................... 103
Structures................................................................................................................................ 105
Interfaces................................................................................................................................ 107
Classes................................................................................................................................... 110

Section 6: CrossTaskData
Introduction............................................................................................................................. 159
Supported Firmware Versions..................................................................................................... 160
Global Parameters.................................................................................................................... 160
Function Blocks....................................................................................................................... 160
Benchmarks.............................................................................................................................162
Examples................................................................................................................................ 163

Date Code 20241023 Programming Reference


iv

Section 7: DescriptiveData
Introduction............................................................................................................................. 167
Supported Firmware Versions..................................................................................................... 167
Enumerations........................................................................................................................... 167
Structures................................................................................................................................ 168
Classes................................................................................................................................... 169
Examples................................................................................................................................ 192

Section 8: Dictionaries
Introduction............................................................................................................................. 207
Supported Firmware Versions..................................................................................................... 208
Global Parameters.................................................................................................................... 208
Functions................................................................................................................................ 208
Aliases................................................................................................................................... 209
Structure Definitions................................................................................................................. 209
Classes................................................................................................................................... 209
Benchmarks.............................................................................................................................214
Examples................................................................................................................................ 216

Section 9: DynamicDisturbanceRecorder
Introduction............................................................................................................................. 221
Supported Firmware Versions..................................................................................................... 224
Enumerations........................................................................................................................... 225
Special Considerations for COMTRADE Logging..........................................................................225
Classes................................................................................................................................... 226
Benchmarks.............................................................................................................................258
Examples................................................................................................................................ 260

Section 10: DynamicVectors


Introduction............................................................................................................................. 267
Supported Firmware Versions..................................................................................................... 267
Global Parameters.................................................................................................................... 268
Enumerations........................................................................................................................... 268
Functions................................................................................................................................ 268
Interfaces................................................................................................................................ 270
Classes................................................................................................................................... 272
Benchmarks.............................................................................................................................288
Examples................................................................................................................................ 292

Section 11: Email


Introduction............................................................................................................................. 297
Supported Firmware Versions..................................................................................................... 297
Enumerations........................................................................................................................... 298
Function Blocks....................................................................................................................... 298
Classes................................................................................................................................... 300
Benchmarks.............................................................................................................................310
Examples................................................................................................................................ 317
Troubleshooting....................................................................................................................... 321

Section 12: EmailPlus


Introduction............................................................................................................................. 323
Supported Firmware Versions..................................................................................................... 325
Enumerations........................................................................................................................... 326
Classes................................................................................................................................... 327
Troubleshooting....................................................................................................................... 345

Programming Reference Date Code 20241023


v

Examples................................................................................................................................ 345

Section 13: FTPSync


Introduction............................................................................................................................. 351
Supported Firmware Versions..................................................................................................... 351
Structures................................................................................................................................ 351
Enumerations........................................................................................................................... 352
Classes................................................................................................................................... 352
Examples................................................................................................................................ 355

Section 14: FallingConductorProtection


Introduction............................................................................................................................. 359
Supported Firmware Versions..................................................................................................... 359
Global Constants...................................................................................................................... 359
Enumerations........................................................................................................................... 359
Structures................................................................................................................................ 361
Classes................................................................................................................................... 365
Examples................................................................................................................................ 385

Section 15: FaultLocation


Introduction............................................................................................................................. 391
Supported Firmware Versions..................................................................................................... 391
Enumerations........................................................................................................................... 391
Structures................................................................................................................................ 392
Classes................................................................................................................................... 393
Examples................................................................................................................................ 400

Section 16: FileIO


Introduction............................................................................................................................. 405
Supported Firmware Versions..................................................................................................... 405
Global Parameters.................................................................................................................... 406
Enumerations........................................................................................................................... 406
Structures................................................................................................................................ 409
Functions................................................................................................................................ 414
Classes................................................................................................................................... 425
Benchmarks.............................................................................................................................488
Examples................................................................................................................................ 497

Section 17: GridConnect


Introduction............................................................................................................................. 517
Supported Firmware Versions..................................................................................................... 518
Operational Modes................................................................................................................... 519
Enumerations........................................................................................................................... 552
Function Blocks....................................................................................................................... 555
Simulator................................................................................................................................ 577
Examples................................................................................................................................ 589
Glossary................................................................................................................................. 595

Section 18: IPAliasRedundancy


Introduction............................................................................................................................. 597
Supported Firmware Versions..................................................................................................... 601
Function Blocks....................................................................................................................... 601
Examples................................................................................................................................ 603

Date Code 20241023 Programming Reference


vi

Section 19: JSON_Utilities_SL


Introduction............................................................................................................................. 609
Supported Firmware Versions..................................................................................................... 609
Global Parameters.................................................................................................................... 609
Enumerations........................................................................................................................... 609
Structures................................................................................................................................ 611
Unions....................................................................................................................................611
Functions................................................................................................................................ 611
Interfaces................................................................................................................................ 612
Function Blocks....................................................................................................................... 618
Classes................................................................................................................................... 621
Examples................................................................................................................................ 624

Section 20: MQTT_Client_SL


Introduction............................................................................................................................. 627
Supported Firmware Versions..................................................................................................... 627
Global Parameters.................................................................................................................... 627
Enumerations........................................................................................................................... 627
Functions................................................................................................................................ 629
Classes................................................................................................................................... 630
Function Blocks....................................................................................................................... 632
Examples................................................................................................................................ 634

Section 21: MathComplex


Introduction............................................................................................................................. 637
Supported Firmware Versions..................................................................................................... 637
Structures................................................................................................................................ 637
Functions................................................................................................................................ 637
Benchmarks.............................................................................................................................642
Examples................................................................................................................................ 643

Section 22: MathMatrix


Introduction............................................................................................................................. 645
Supported Firmware Versions..................................................................................................... 646
Enumerations........................................................................................................................... 646
Functions................................................................................................................................ 646
Classes................................................................................................................................... 655
Benchmarks.............................................................................................................................691
Examples................................................................................................................................ 694

Section 23: PacketEncoding


Introduction............................................................................................................................. 699
Supported Firmware Versions..................................................................................................... 699
Enumerations........................................................................................................................... 699
Structures................................................................................................................................ 701
Functions................................................................................................................................ 701
Classes................................................................................................................................... 716
Benchmarks.............................................................................................................................718
Examples................................................................................................................................ 721

Section 24: PowerMetering


Introduction............................................................................................................................. 727
Supported Firmware Versions..................................................................................................... 727
Function Blocks....................................................................................................................... 727
Benchmarks.............................................................................................................................733

Programming Reference Date Code 20241023


vii

Examples................................................................................................................................ 735
Retain Variables....................................................................................................................... 744

Section 25: PowerSystemAutomation


Introduction............................................................................................................................. 745
Supported Firmware Versions..................................................................................................... 745
Enumerations........................................................................................................................... 745
Function Blocks....................................................................................................................... 746
Examples................................................................................................................................ 759

Section 26: PowerSystemModel


Introduction............................................................................................................................. 767
Supported Firmware Versions..................................................................................................... 770
Enumerations........................................................................................................................... 771
Structures................................................................................................................................ 771
Classes................................................................................................................................... 772
Benchmarks.............................................................................................................................808
Examples................................................................................................................................ 809
Log File Format....................................................................................................................... 829

Section 27: PowerSystemProtection


Introduction............................................................................................................................. 831
Supported Firmware Versions..................................................................................................... 831
Enumerations........................................................................................................................... 831
Function Blocks....................................................................................................................... 832
Benchmarks.............................................................................................................................854
Examples................................................................................................................................ 855

Section 28: Queue


Introduction............................................................................................................................. 863
Supported Firmware Versions..................................................................................................... 864
Global Parameters.................................................................................................................... 864
Enumerations........................................................................................................................... 864
Functions................................................................................................................................ 865
Interfaces................................................................................................................................ 866
Classes................................................................................................................................... 870
Benchmarks.............................................................................................................................916
Examples................................................................................................................................ 922

Section 29: Quicksort


Introduction............................................................................................................................. 927
Supported Firmware Versions..................................................................................................... 927
Functions................................................................................................................................ 927
Interfaces................................................................................................................................ 934
Benchmarks.............................................................................................................................936
Examples................................................................................................................................ 938

Section 30: RecordingTriggers


Introduction............................................................................................................................. 939
Supported Firmware Versions..................................................................................................... 939
Enumerations........................................................................................................................... 939
Structures................................................................................................................................ 939
Function Blocks....................................................................................................................... 940
Benchmarks.............................................................................................................................946
Examples................................................................................................................................ 947

Date Code 20241023 Programming Reference


viii

Section 31: ReportGenerator


Introduction............................................................................................................................. 953
Supported Firmware Versions..................................................................................................... 953
Enumerations........................................................................................................................... 953
Classes................................................................................................................................... 954

Section 32: SELEthernetController


Introduction............................................................................................................................. 959
Supported Firmware Versions..................................................................................................... 960
Enumerations........................................................................................................................... 960
Aliases................................................................................................................................... 960
Functions................................................................................................................................ 960
Classes................................................................................................................................... 962
Benchmarks.............................................................................................................................977
Examples................................................................................................................................ 980

Section 33: SELRand


Introduction............................................................................................................................. 989
Supported Firmware Versions..................................................................................................... 989
Functions................................................................................................................................ 989
Benchmarks.............................................................................................................................991
Examples................................................................................................................................ 992

Section 34: SELServerSimulators


Introduction............................................................................................................................. 995
Supported Firmware Versions..................................................................................................... 995
Enumerations........................................................................................................................... 996
Structures................................................................................................................................ 996
Interfaces................................................................................................................................ 997
Classes..................................................................................................................................1000
Examples.............................................................................................................................. 1007

Section 35: SELString


Introduction........................................................................................................................... 1011
Supported Firmware Versions................................................................................................... 1011
Global Parameters...................................................................................................................1012
Functions.............................................................................................................................. 1012
Classes..................................................................................................................................1016
Benchmarks........................................................................................................................... 1042
Examples.............................................................................................................................. 1051

Section 36: SELUtils


Introduction........................................................................................................................... 1063
Supported Firmware Versions................................................................................................... 1063
Enumerations......................................................................................................................... 1063
Structures.............................................................................................................................. 1066
Global Constants.................................................................................................................... 1066
Functions.............................................................................................................................. 1067
Function Blocks..................................................................................................................... 1128
Benchmarks........................................................................................................................... 1145
Examples.............................................................................................................................. 1147

Section 37: SVPplus


Introduction........................................................................................................................... 1157
Supported Firmware Versions................................................................................................... 1159
Global Constants.................................................................................................................... 1159

Programming Reference Date Code 20241023


ix

Structure Definitions............................................................................................................... 1160


Classes..................................................................................................................................1160
Benchmarks........................................................................................................................... 1163
Examples.............................................................................................................................. 1164

Section 38: SnmpLite


Introduction........................................................................................................................... 1169
Supported Firmware Versions................................................................................................... 1171
Enumerations......................................................................................................................... 1171
Structures.............................................................................................................................. 1172
Classes..................................................................................................................................1172
Benchmarks........................................................................................................................... 1179
Examples.............................................................................................................................. 1180

Section 39: SyslogCollector


Introduction........................................................................................................................... 1183
Supported Firmware Versions................................................................................................... 1183
Structures.............................................................................................................................. 1183
Enumerations......................................................................................................................... 1184
Function Blocks..................................................................................................................... 1185
Examples.............................................................................................................................. 1186

Section 40: TrendRecorder


Introduction........................................................................................................................... 1189
Special Considerations............................................................................................................. 1189
Supported Firmware Versions................................................................................................... 1190
Usage................................................................................................................................... 1190
Function Blocks..................................................................................................................... 1192
Recorder Operation................................................................................................................. 1195
Benchmarks........................................................................................................................... 1198

Section 41: Web_Client_SL


Introduction........................................................................................................................... 1201
Supported Firmware Versions................................................................................................... 1201
Global Constants.................................................................................................................... 1201
Global Parameters...................................................................................................................1203
Enumerations......................................................................................................................... 1203
Structures.............................................................................................................................. 1204
Functions.............................................................................................................................. 1205
Interfaces...............................................................................................................................1209
Function Blocks..................................................................................................................... 1210
Classes..................................................................................................................................1214
Examples.............................................................................................................................. 1216

Section 42: Web_Socket_Client_SL


Introduction........................................................................................................................... 1221
Supported Firmware Versions................................................................................................... 1221
Enumerations......................................................................................................................... 1221
Structures.............................................................................................................................. 1222
Interfaces...............................................................................................................................1223
Function Blocks..................................................................................................................... 1224
Classes..................................................................................................................................1226
Examples.............................................................................................................................. 1228

Date Code 20241023 Programming Reference


x

Section 43: XML_Utility_SL


Introduction........................................................................................................................... 1231
Supported Firmware Versions................................................................................................... 1231
Global Parameters...................................................................................................................1232
Enumerations......................................................................................................................... 1232
Structures.............................................................................................................................. 1233
Function Blocks..................................................................................................................... 1234
Examples.............................................................................................................................. 1240

Appendix A: Release Notes


Libraries................................................................................................................................1243
Extensions............................................................................................................................. 1265

Appendix B: Developer Mode


Introduction........................................................................................................................... 1273
Library Manager.....................................................................................................................1274
Exporting a User-Created Library.............................................................................................. 1279
Classes and Methods............................................................................................................... 1280
Access Modifiers.................................................................................................................... 1284
Attribute Pragmas................................................................................................................... 1285

Programming Reference Date Code 20241023


List of Figures
Figure 3.1 A Digital Filter Using Three (3) Coefficients for A(z) and Five (5) for B(z)....................................50
Figure 3.2 class_LimitedSplpfStepToDefault With a Time Constant of 1000 ms............................................. 59
Figure 3.3 class_LimitedSplpfRampToDefault With a Time Constant of 1000 ms........................................... 60
Figure 3.4 Plot of Total Signal and Filtered Output of the Low-Pass Filter.................................................... 63
Figure 4.1 An Excursion Defined by the Absolute Channel Difference Equaling or Exceeding the Threshold
Value for the Excursion Time Generates an Alert..................................................................................... 65
Figure 4.2 An Excursion Defined by the Indicator Equaling a TRUE Value for the Excursion Time Generates
an Alert............................................................................................................................................. 65
Figure 4.3 Multiple Excursions Defined by the Absolute Channel Difference Equaling or Exceeding the
Threshold Value Within the Excursion Time Generates an Alert (Chatter Count = 3)....................................... 66
Figure 4.4 Multiple Excursion Defined by the Indicator Equaling a TRUE Value Within the Excursion Time
Generates an Alert (Chatter Count = 3)...................................................................................................66
Figure 4.5 Relative Time Alignment (All Expected Data Received)............................................................. 81
Figure 4.6 Relative Time Alignment (Some Missing Data)........................................................................ 81
Figure 5.1 Redundant Source and Load-Side CT Monitoring Group on a Single Feeder Line.......................... 117
Figure 5.2 CT Monitoring Group With Applied Scaling for Transformer Low-Side CTs................................. 118
Figure 5.3 PT Monitoring Group for a Two-Branch Breaker-and-a-Half Scheme.......................................... 118
Figure 5.4 Warning/Alarm Pickup/Dropout Behavior...............................................................................121
Figure 5.5 Graphical Depiction of Output CSV File Format..................................................................... 143
Figure 5.6 Example IED Report Excerpt............................................................................................... 144
Figure 5.7 Example Output File.......................................................................................................... 145
Figure 8.1 A Binary Search Tree Holding Integer Values......................................................................... 210
Figure 8.2 An Unbalanced Binary Search Tree.......................................................................................210
Figure 8.3 A Balanced Binary Search Tree Node................................................................................... 210
Figure 9.1 Sample RTAC SOE Logger Entries....................................................................................... 265
Figure 9.2 Sample Contents of an SOE Harvester CSV Log File............................................................... 265
Figure 13.1 Copying the RTAC Host SSH Key...................................................................................... 357
Figure 13.2 Locating the RTAC Hostname............................................................................................ 358
Figure 13.3 Example of Prepared Host Key...........................................................................................358
Figure 14.1 Detection Method Accumulation......................................................................................... 366
Figure 14.2 Trip Control Point Logic................................................................................................... 366
Figure 14.3 Detection Blocking Logic.................................................................................................. 367
Figure 14.4 Faulty Sensor Logic..........................................................................................................368
Figure 14.5 Breaker Status Transited Logic........................................................................................... 369
Figure 14.6 Blocking Fault Alarm Logic...............................................................................................370
Figure 14.7 Logic Evaluated to Determine a Blown Fuse Condition........................................................... 371
Figure 14.8 Falling Conductor Protection Switch Availability Logic...........................................................371
Figure 14.9 Parent Zone Reference Example......................................................................................... 372
Figure 14.10 Voltage Change Method (dV/dt) Logic to Determine Falling Conductor Criteria......................... 374
Figure 14.11 Zero- and Negative-Sequence Voltage Magnitude (|V0| and |V2|) Method Logic for Determining
Falling Conductor Criteria...................................................................................................................375
Figure 14.12 Zero- and Negative-Sequence Voltage Angle (ÐV0 and ÐV2) Method Logic for Determining
Falling Conductor Criteria...................................................................................................................376
Figure 14.13 Primary Decision Tree Used to Perform Logic in the Run Method........................................... 383
Figure 14.14 Falling Conductor Protection Applied on a Two-Zone Circuit................................................. 385
Figure 15.1 Recording Group Multimodule Fault Analysis....................................................................... 402
Figure 17.1 Power Factor Control Mode Models.................................................................................... 527
Figure 17.2 VAR Control Mode Models............................................................................................... 528
Figure 17.3 Voltage Control Mode Models............................................................................................ 529
Figure 17.4 Voltage Compensation Curve..............................................................................................531

Date Code 20241023 Programming Reference


xii

Figure 17.5 Voltage Compensation Mode Models................................................................................... 532


Figure 17.6 Advanced Power Mode Logic............................................................................................ 537
Figure 17.7 Constant PCC Power Logic................................................................................................538
Figure 17.8 Frequency Regulation Curve.............................................................................................. 551
Figure 17.9 GridConnect Simulator Connecting to GridConnect Elements...................................................577
Figure 17.10 fb_PCCSim System Accumulation..................................................................................... 578
Figure 17.11 fb_PVInverterSim Real Power Evaluation System................................................................ 579
Figure 17.12 fb_PVInverterSim Reactive Power Evaluation System........................................................... 580
Figure 17.13 fb_BessSim Real Power Evaluation System.........................................................................582
Figure 17.14 fb_BessSim Reactive Power Evaluation System................................................................... 582
Figure 17.15 Generator Real Power Start Stop....................................................................................... 584
Figure 17.16 Generator Real Power..................................................................................................... 585
Figure 17.17 Generator Reactive Power................................................................................................ 585
Figure 17.18 Solar Facility One-Line Diagram....................................................................................... 590
Figure 18.1 Ethernet Listening Access Point.......................................................................................... 604
Figure 18.2 Interface Control in CFC................................................................................................... 605
Figure 18.3 Ethernet Listening Access Point.......................................................................................... 605
Figure 18.4 Interface Control in CFC................................................................................................... 606
Figure 18.5 Ethernet Listening Access Point for PortControlRTAC1.......................................................... 607
Figure 18.6 Ethernet Listening Access Point for PortControlRTAC2.......................................................... 607
Figure 18.7 InterfaceControlWithSerialCheck in CFC............................................................................. 608
Figure 25.1 Synchronism-Check Without Circuit Breaker Close Time Compensation.................................... 747
Figure 25.2 Synchronism-Check With Circuit Breaker Close Time Compensation........................................ 747
Figure 25.3 Disconnect Switch Close Logic.......................................................................................... 753
Figure 25.4 Disconnect Switch Open Logic........................................................................................... 754
Figure 25.5 Disconnect Switch Alarm Logic......................................................................................... 754
Figure 25.6 Disconnect Switch in Transition..........................................................................................755
Figure 25.7 Breaker Open Logic......................................................................................................... 757
Figure 25.8 Breaker Close Logic......................................................................................................... 758
Figure 25.9 Synchronism Check Using Axion AC Input Modules..............................................................760
Figure 26.1 Differing Levels of Observability........................................................................................ 767
Figure 26.2 High-Voltage End of a Substation....................................................................................... 768
Figure 26.3 High-Voltage Components Identified................................................................................... 769
Figure 26.4 Model Tied Together With Connectivity Nodes..................................................................... 769
Figure 26.5 Tied Model With Measurement Points Identified....................................................................770
Figure 26.6 All Objects Defined for One Side of the Substation................................................................ 770
Figure 26.7 Example Substation Model................................................................................................ 809
Figure 26.8 Distribution Network of Interest......................................................................................... 816
Figure 26.9 Ring of Network of Interest............................................................................................... 824
Figure 27.1 Loss-of-Potential Logic..................................................................................................... 839
Figure 27.2 Overvoltage Logic............................................................................................................ 840
Figure 27.3 Undervoltage Logic.......................................................................................................... 841
Figure 27.4 Overfrequency Logic........................................................................................................ 847
Figure 27.5 Underfrequency Logic.......................................................................................................848
Figure 27.6 Voltage Supervision Logic................................................................................................. 852
Figure 36.1 Block Diagram of a PID Control System............................................................................ 1129
Figure 36.2 Manual/Automatic and Ramp-to-Set Point Operation............................................................ 1132
Figure 36.3 Direct-Acting and Reverse-Acting Processes....................................................................... 1134
Figure 36.4 Integral Windup............................................................................................................. 1136
Figure 36.5 Block Diagram of the PID Instruction................................................................................ 1138
Figure 36.6 CascadeControl Function Block........................................................................................ 1138
Figure 36.7 fb_PADM Function Block................................................................................................ 1140
Figure 36.8 PID Configuration in CFC............................................................................................... 1150
Figure 36.9 Cascade Control Example................................................................................................ 1151
Figure 36.10 Cascade Configuration................................................................................................... 1154

Programming Reference Date Code 20241023


xiii

Figure 36.11 Angle_Difference_Tracking_Example_CFC....................................................................... 1155


Figure 37.1 Ring Buffer Used to Store Samples in Modal Analysis Object................................................ 1158
Figure 39.1 UDP Incoming Access Point............................................................................................ 1187
Figure 39.2 prg_SyslogCollector in CFC Form..................................................................................... 1187
Figure 40.1 Example Recorder Usage................................................................................................. 1192
Figure B.1 Enable Developer Mode....................................................................................................1273
Figure B.2 Create Project as Library.................................................................................................. 1274
Figure B.3 POUs Tab.......................................................................................................................1274
Figure B.4 Adding Library Manager...................................................................................................1275
Figure B.5 Navigating to Placeholder Page.......................................................................................... 1276
Figure B.6 Selecting Placeholder Library............................................................................................ 1277
Figure B.7 Adding Placeholder Name................................................................................................. 1278
Figure B.8 Completed Library With Placeholder Reference.................................................................... 1278
Figure B.9 Library Reference Example............................................................................................... 1279
Figure B.10 Summary Tab for Project Information................................................................................ 1279
Figure B.11 Properties Tab for Project Information............................................................................... 1280
Figure B.12 Save POUs as .compiled-library........................................................................................1280
Figure B.13 Select a POU to Add a Class........................................................................................... 1281
Figure B.14 Select Function Block and Name...................................................................................... 1281
Figure B.15 Base Function Block Example..........................................................................................1282
Figure B.16 Extended Function Block Example....................................................................................1282
Figure B.17 Adding a Method to Function Block or Program..................................................................1284
Figure B.18 Configuring a Method to Function Block or Program........................................................... 1284
Figure B.19 Internal Access Modifier Example.................................................................................... 1285
Figure B.20 Hide Attribute Definition.................................................................................................1285
Figure B.21 Hide Attribute Usage During Logic Engine Runtime: Implementation Section........................... 1286
Figure B.22 Hide Attribute Usage During Logic Engine Runtime: Declaration Section................................ 1286
Figure B.23 Hide Attribute for Entire POU..........................................................................................1286
Figure B.24 Hide All Locals Attribute for Entire POU...........................................................................1287
Figure B.25 Hide All Locals Attribute During Runtime......................................................................... 1287

Date Code 20241023 Programming Reference


This page intentionally left blank
List of Tables
Table 1.1 Exit Code Statuses.................................................................................................................. 3
Table 1.2 Advanced Sending Options...................................................................................................... 8
Table 1.3 Convert RTAC Types.............................................................................................................10
Table 1.4 importxml RTAC Types......................................................................................................... 23
Table 1.5 Advanced Reading Options.....................................................................................................31
Table 17.1 Master Plant Controller Control Mode Parameters................................................................... 519
Table 17.2 Frequency Regulation Parameters......................................................................................... 550
Table 23.1 Special Bit Patterns for Reals.............................................................................................. 708
Table 27.1 IEC Equations Associated With Predefined Inverse-Time Overcurrent Function Blocks...................836
Table 27.2 U.S. Equations Associated With Predefined Inverse-Time Overcurrent Function Blocks.................. 836
Table 36.1 ..................................................................................................................................... 1066
Table 36.2 Relationship Between DNP3 Register Encoding and Event Descriptions.................................... 1126
Table 36.3 PID Equations................................................................................................................. 1130
Table 36.4 Parameters of the PID Equations........................................................................................ 1130
Table 36.5 Error Calculation............................................................................................................. 1134
Table 36.6 Cascade Operating Modes................................................................................................. 1153

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 1

Command Line Interface


Command Line Interface Basics
The ACSELERATOR RTAC® SEL-5033 Software command line interface (CLI)
is a built-in feature providing both interactive and script-based automation of
core functionalities of ACSELERATOR RTAC via a text-based console.
Uses of the command line interface includes the following:

➤ Automated deployment and auditing of ACSELERATOR RTAC projects


and firmware upgrades
➤ Automated build verification testing of firmware releases on networked
RTAC devices
➤ Programmatic functional test execution
➤ Mechanisms to restrict users to subsets of ACSELERATOR RTAC
functionality
The command console is a simple command interpreter, accepting text
commands that are then dispatched to ACSELERATOR RTAC.

Usage
Command Structure
The command line interface is made available through a command prompt or
shell window. During installation, the RTAC installation folder will be added
to the user's %PATH% variable to ensure that commands can be executed.
Commands are case insensitive. Commands can then be issued via the command
prompt in the following form:
AcRtacCmd command [options] <values>

where:
command is the main argument that must always appear first after
AcRtacCmd.

options are specified with a short (e.g., -f) or long (e.g., --file) name.

When options for a command are given wrapped in square brackets, they are
not required for the command. An option can be Boolean (in which case only
the flag is required in the command) or it can require the flag to be followed
by a bound value as an option specifier. Omitted Boolean options are treated as
FALSE. For example:
AcRtacCmd command -v

would set the short name option -v to TRUE, while


AcRtacCmd command

Date Code 20241023 Programming Reference


2 Command Line Interface
Behavior

sets the -v option to FALSE.

The following would be an invalid setting for a Boolean option:

AcRtacCmd command -v true

Options can be placed in any order (even between unbound values).

values are another type of argument you can use. There are two types of
values: bound and unbound.

➤ Bound values are specifying arguments that follow a non-Boolean option


flag. They must be given directly following the corresponding flag. For
example, in the command AcRtacCmd command -f <file>, -f is the
option flag and <file> is its bound value. If the -f option is followed by
anything other than a valid file name, the command would be invalid.
➤ Unbound values are arguments that are required for the command to
work. They must be given in the order shown in the synopsis because
they are processed from left to right.

Mutually Exclusive Options and Values


Some values and options either conflict or have a similar meaning and therefore
only one is needed for the command to work. Option and values separated
by '|' (vertical line) are mutually exclusive, and providing both options to the
command results in a bad syntax error.

For example:

[-a <alias> | -i <pid>]

denotes that only one of the list options can be specified in a single command.

Behavior
Commands are dispatched serially to ACSELERATOR RTAC. They are required
not to return until termination.

All commands will return an error status code and print a machine-parsable
string to stdout. See Command Returns on page 3 for more details.

Behavioral Requirements
The way that commands are processed includes the following constraints:

➤ Commands do not return until termination. This preserves the order of a


list of commands and prevents commands from being sent when an RTAC
is still busy.
➤ All commands return error codes and print to stdout when complete. The
user may rely on these outputs to programmatically determine command
success or failure and to synchronize further input.
➤ An error description shall be displayed to the user for invalid parameters
and failed commands.

Programming Reference Date Code 20241023


Command Line Interface 3
Command List

➤ Parallel invocation of commands may cause a race condition and should


not be used. One such example of this would be invoking commands
from two separate console instances accessing the same local database
and/or devices. However, commands shall be executed in the order
received regardless of what console instances window the command was
issued from.
➤ All future commands must obey these serial requirements.

Command Returns
All commands will return an exit code and print to stdout in the following
format:
command:exitcode:"exit code description"

Table 1.1 lists the exit code status and their descriptions.
Table 1.1 Exit Code Statuses

Exit Code Description

0 success

1 failure

2 bad syntax

127 command not found

Help
All commands implement a help option that prints a human-readable description
of valid parameters and syntax for the command. For example, the following
command outputs the help file for the importxml command:
AcRtacCmd importxml --help

Startup Switches
As an advanced feature, you can modify the shortcut to ACSELERATOR RTAC
to include various startup runtime switches. These switches provide features not
available in the software in normal run mode. See start on page 36 for more
information.

Command List
The syntax of available commands are as follows.

Commands
check
close
connect
convert
delete

Date Code 20241023 Programming Reference


4 Command Line Interface
Command List

disablepassword
disconnect
exportexp
exportlibrary
exportxml
help
importexp
importxml
info
list
login
lsproc
open
read
rename
rtacinfo
setpassword
start
stop
unlock
upgradefirmware

check
Initiates a build run of all objects in the POUs window.

Synopsis
AcRtacCmd check [-a <alias> | -i <pid>] [-j
<project_password>] [- n <name>]

Remarks
➤ This command is used for test purposes when creating a library project.
It causes a build run of all objects currently available in the POUs
window. Only the objects in the POU window will be checked for syntax
errors. This command is the same as check all POOL objects in
ACSELERATOR RTAC.
➤ No compilation code will be generated.
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.
➤ If the specified project is not open when using this command, the project
will be opened before processing and closed when complete. The process
of opening and closing the project automatically increases the time this
command takes to complete.
➤ This command is only supported on project version R132 or later.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

Programming Reference Date Code 20241023


Command Line Interface 5
Command List

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-j, --project_password <project_password>

The ACSELERATOR RTAC project password.

-n, --name <name>

The name of the project to build.

Examples
Feature: Verifying library code POU's
Before a library can be created and saved, the check command is used to verify the
library code in the POU's section.

Scenario: Check the POU's in a project with name "CheckExample"


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "CheckExample" exists as a 3530 project in the db
And the project "CheckExample" is unlocked
And the project "CheckExample" is open
When the argument string "check" is passed to AcRtacCmd.exe
Then "check:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Check the POU's in a project with name "CheckExample" that has invalid settings
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "CheckExample" exists as a 3530 project in the db
And the project "CheckExample" is unlocked
And the project "CheckExample" is open
When the argument string "check" is passed to AcRtacCmd.exe
Then "check:1:failure" can be found in the output
And the error level returned is: "1"

close
Closes the currently open project.

Synopsis
AcRtacCmd close [-a <alias> | -i <pid>]

Remarks
➤ If no project is open, this command will not do anything and will return
without error.
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.

Date Code 20241023 Programming Reference


6 Command Line Interface
Command List

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: Opening and closing AcSELerator RTAC projects.
Once a process is logged into a database, the open and close commands are used to access
the projects within a database.

Scenario: Open the project 'OpenTest' with a process using the alias 'LoginTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process named "LoginTest"
And admin has logged in with password TAIL
And the project "OpenTest" exists as a 3530 project in the db
And the project "OpenTest" is unlocked
When the argument string "open OpenTest -a LoginTest" is passed to AcRtacCmd.exe
Then "open:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Close the project 'OpenTest' with a process using the alias 'LoginTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process named "LoginTest"
And admin has logged in with password TAIL
And the project "OpenTest" exists as a 3530 project in the db
And the project "OpenTest" is unlocked
And the project "OpenTest" is open
When the argument string "close -a LoginTest" is passed to AcRtacCmd.exe
Then "close:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Open the project 'OpenTest' with the last started process
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "OpenTest" exists as a 3530 project in the db
And the project "OpenTest" is unlocked
When the argument string "open OpenTest" is passed to AcRtacCmd.exe
Then "open:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to open a project without entering the project name


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
When the argument string "open" is passed to AcRtacCmd.exe
Then "open:1:failure" can be found in the output
And the error level returned is: "1"

connect
This command is the same as Go Online in ACSELERATOR RTAC.

Synopsis
AcRtacCmd connect [options] <ipaddress> <username>

Programming Reference Date Code 20241023


Command Line Interface 7
Command List

Remarks
➤ The default for this command is to only log in to a device at <ipaddress>
with <username> and <password>.
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.
➤ If the -s option is specified, the current project will be sent to the RTAC.
This command does not prompt before overwriting project settings.
➤ The -n option must be specified if the project is not open. This will open
the project before executing the command. The process of opening the
project increases the time this command takes to complete. The project
will not close when the command is complete.
➤ The user may also send advanced project settings (listed in Table 1.2).
➤ When in non-visual mode, the process will stay connected to the specified
RTAC until one of the following occur: the disconnect command is used,
the project is closed, or the process is stopped. The online time-out setting
only applies when in non-visual mode.

Values
<ipaddress>

RTAC IPv4 address


<username>

Remote RTAC account username with which to log in.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.


-r, --reinit

Reinitialize retain variables.


-n, --name <name>

The name of the project to send.


-p, --password <password>

Login password of remote RTAC. If not given, the command will


attempt to read from stdin. No prompt for a password will occur.
-s, --send

In addition to going online with the given RTAC, also send the specified
project from option -n or current open project.
Sends complete project.

Date Code 20241023 Programming Reference


8 Command Line Interface
Command List

Updates all settings.


Restarts your RTAC.
Retains all settings through a restart.
Stores changes for future project reads.
-j, --project_password <project_password>

The ACSELERATOR RTAC project password.


--retain-password-vault

Update the Retain Password Vault with the given password parameters.
-b, --databaseport <databaseport>

The database port number.


-e, --rteport <rteport>

The rte port number.

Advanced Options
The following are additional settings that can be in a project:
-v, --advanced <key>

Allows specifying advanced options for sending projects. The <key> is a


comma-separated list of advanced settings shown in Table 1.2.
Table 1.2 Advanced Sending Options

Name Description

all All available project settings

Ethernet-settings Project Ethernet settings

user-accounts Project user account setting

event-logs Project sequence of events report

website-settings Project website settings

x509-certs Project x509 certificate

LDAP Project lightweight directory access protocol settings

Hosts Project Host settings

CA-certs Project certificate authority settings

HMI-diagrams Project HMI diagrams

event-collection Project event collection logs

SSH-authorized-keys Project SSH-authorized-keys

SSH-host-keys Project SSH host key settings

Examples
Feature: Connecting, disconnecting, and sending projects.
The connect and disconnect commands are used to send settings to a device.

Programming Reference Date Code 20241023


Command Line Interface 9
Command List

Scenario: Send the project 'Connectexample' with a process using the alias 'ConnectTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "ConnectTest"
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
When the argument string "connect 197.201.80.255 SEL -p SEL -s -a ConnectTest"
is passed to AcRtacCmd.exe
Then "connect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Disconnect from "RTAC Identifier" connected with the project 'Connectexample'
with a process using the alias 'ConnectTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "ConnectTest"
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
And the project "Connectexample" is sent to the provided RTAC
When the argument string "disconnect -a ConnectTest" is passed to AcRtacCmd.exe
Then "disconnect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Send the project 'Connectexample' with a process without an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
When the argument string "connect 197.201.80.255 SEL -p SEL -s"
is passed to AcRtacCmd.exe
Then "connect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Disconnect from "RTAC Identifier" connected with the project 'Connectexample'
with a process using the alias 'ConnectTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
And the project "Connectexample" is sent to the provided RTAC
When the argument string "disconnect" is passed to AcRtacCmd.exe
Then "disconnect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to send a project without opening or specifying the project name
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
When the argument string "connect 197.201.80.255 SEL -p SEL -s"
is passed to AcRtacCmd.exe
Then "connect:1:failure" can be found in the output
And the error level returned is: "1"

Date Code 20241023 Programming Reference


10 Command Line Interface
Command List

convert
Converts a project to the version specified by <version> or to the RTAC type
specified by <type>.

Synopsis
AcRtacCmd convert [-a <alias> | -i <pid>] [-d] [-n
<new_name>] <name> <type | version>

Remarks
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.
➤ Projects can only be converted from earlier to later firmware versions.

Values
<name>

The name of a project to convert

<version>

The r-number / RTAC firmware version.

<type>

The type of RTAC. Valid RTAC types are shown in Table 1.3.
Table 1.3 Convert RTAC Types

Type Description

3530, 2241 RTAC type for an SEL-3530, SEL-3530-4, or SEL-2241.

3505 RTAC type for an SEL-3505 or SEL-3505-3 Communications Gateway.

3532, 3354, 3351, 3332, 1102 This RTAC type is for an SEL-3532, SEL-3354, SEL-3351, SEL-3332, or SEL-1102
Embedded Automation Computing Platform.

3555 RTAC type for an SEL-3555 Real-Time Automation Controller.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-n, --new_name <new_name>

The new name for the converted project. If no name is provided, a new
name will be generated automatically.

Programming Reference Date Code 20241023


Command Line Interface 11
Command List

-d, --delete

Remove original project.

Examples
Feature: Converting an AcRtac project to another version or device type
Because projects are locked to a device type and firmware version, the
convert command is needed.

Scenario: Convert an existing project from 3530 to 3555 device


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "convert Xmlexample 3555" is passed to AcRtacCmd.exe
Then "convert:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Convert an existing project from R135 to R136 version


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a R135 project in the db
And the project "Xmlexample" is unlocked
When the argument string "convert Xmlexample R136" is passed to AcRtacCmd.exe
Then "convert:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to Convert a project from 3530 to 3555 device when the
project does not exist
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
When the argument string "convert NoProject 3555" is passed to AcRtacCmd.exe
Then "convert:1:failure" can be found in the output
And the error level returned is: "1"

delete
Removes an ACSELERATOR RTAC project with <name> from the ACSELERATOR
RTAC database.

Synopsis
AcRtacCmd delete [-a <alias> | -i <pid>] <name>

Remarks
➤ If * is used in place of a project name, then all projects will be removed
from the ACSELERATOR RTAC Database.
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.

Values
<name>

The name of the project to delete.

Date Code 20241023 Programming Reference


12 Command Line Interface
Command List

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: Deleting AcSELerator RTAC projects from the database.
Once a process is logged into a database, the delete command is used to
remove projects from the database.

Scenario: Delete the project 'DeleteTest' with a process using the alias 'DeleteTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process named "DeleteTest"
And admin has logged in with password TAIL
And the project "DeleteTest" exists as a 3530 project in the db
And the project "DeleteTest" is unlocked
When the argument string "delete OpenTest -a LoginTest" is passed to AcRtacCmd.exe
Then "delete:0:success" can be found in the output
And the error level returned is: "0"
And the project "DeleteTest" does not exists as a 3530 project in the db

Scenario: Delete the project 'DeleteTest' with a process without an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "DeleteTest" exists as a 3530 project in the db
And the project "DeleteTest" is unlocked
When the argument string "delete OpenTest" is passed to AcRtacCmd.exe
Then "delete:0:success" can be found in the output
And the error level returned is: "0"
And the project "DeleteTest" does not exists as a 3530 project in the db

Scenario: Attempt to delete a project without entering the project name


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
When the argument string "delete" is passed to AcRtacCmd.exe
Then "delete:2:syntax error" can be found in the output
And the error level returned is: "2"

disablepassword
Disables the password on a project.

Synopsis
AcRtacCmd disablepassword [-a <alias> | -i <pid>] [-n
<name>]

Remarks
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.

Programming Reference Date Code 20241023


Command Line Interface 13
Command List

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-n, --name <name>

The name of the project to disable the password on.

Examples
Feature: Disable the password on a project.

Scenario: Disable the password on a project


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And a project with the name Test_Project exists in the database
And the Test_Project is locked with the password 1_Quick_Fox
When the argument string "disablepassword -n Test_Project 1_Quick_Fox"
is passed to AcRtacCmd.exe
Then "disablepassword:0:success" can be found in the output
And the error level returned is: "0"
And the project no longer shows "Password On" in the status column of the database

Scenario: Attempt to disable wrong password on project fails


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process named "lsprocTest"
And a project with the name Test_Project exists in the database
And the Test_Project is locked with the password 1_Quick_Fox
When the argument string "disablepassword -n Test_Project thisisapassword" is passed
to AcRtacCmd.exe
Then "disablepassword:1:failure" can be found in the output
And the error level returned is: "1"
And the output message is displayed which indicates that the provided password is invalid

disconnect
Disconnect from currently connected device. This is the same as Go offline in
ACSELERATOR RTAC.

Synopsis
AcRtacCmd disconnect [-a <alias> | -i <pid>]

Remarks
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.

Date Code 20241023 Programming Reference


14 Command Line Interface
Command List

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: Connecting, disconnecting, and sending projects.
The connect and disconnect commands are used to send settings to a device.

Scenario: Send the project 'Connectexample' with a process using the alias 'ConnectTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "ConnectTest"
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
When the argument string "connect 197.201.80.255 SEL -p SEL -s -a
ConnectTest" is passed to AcRtacCmd.exe
Then "connect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Disconnect from "RTAC Identifier" connected with the project 'Connectexample'
with a process using the alias 'ConnectTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "ConnectTest"
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
And the project "Connectexample" is sent to the provided RTAC
When the argument string "disconnect -a ConnectTest"
is passed to AcRtacCmd.exe
Then "disconnect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Send the project 'Connectexample' with a process without an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
When the argument string "connect 197.201.80.255 SEL -p SEL -s" is passed to AcRtacCmd.exe
Then "connect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Disconnect from "RTAC Identifier" connected with the project 'Connectexample' with
a process using the alias 'ConnectTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And the project "Connectexample" is open
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available

Programming Reference Date Code 20241023


Command Line Interface 15
Command List

And the project "Connectexample" is sent to the provided RTAC


When the argument string "disconnect" is passed to AcRtacCmd.exe
Then "disconnect:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to send a project without opening or specifying the project name
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker process
And admin has logged in with password TAIL
And the project "Connectexample" exists as a 3530 project in the db
And the project "Connectexample" is unlocked
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL" is available
When the argument string "connect 197.201.80.255 SEL -p SEL -s"
is passed to AcRtacCmd.exe
Then "connect:1:failure" can be found in the output
And the error level returned is: "1"

exportexp
Export a project with <name> as a .exp file.

Synopsis
AcRtacCmd exportexp [-a <alias> | -i <pid>] [-f <file>]
<name>

Remarks
➤ By default, the name of the created file is <name>.exp. The file will be
saved in the same directory from which this command is executed.
➤ This command will overwrite the file if it already exists on the system.
➤ Use -f <file> to specify the path and name of the file to export. For
example, to save the export in a directory called MyProjects on the local
C: drive, as the file project1, set <file> to C:\MyProjects\project1.
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.

Values
<name>

The name of the project to export.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-f, --file <file>

Name of file to export the project. Use this to specify the path to where
the export will be saved and/or to export the project with a different
name than the project name.

Date Code 20241023 Programming Reference


16 Command Line Interface
Command List

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: Importing and Exporting projects as .exp file

Scenario: Import a new project from .exp file using an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "expTest"
And admin has logged in with password TAIL
When the argument string "importexp ../../FTProjects/expexample.exp -a
expTest" is passed to AcRtacCmd.exe
Then "importexp:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Export an existing project named expexample to .exp file using


an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "expTest"
And admin has logged in with password TAIL
And the project "expexample" exists as a 3530 project in the db
And the project "expexample" is unlocked
When the argument string "exportexp expexample -a expTest" is passed to
AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Import a new project from .exp file without an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importexp ../../FTProjects/expexample.exp" is
passed to AcRtacCmd.exe
Then "importexp:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Export an existing project named expexample to .exp file


without an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "expexample" exists as a 3530 project in the db
And the project "expexample" is unlocked
When the argument string "exportexp expexample" is passed to
AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to import an xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importexp" is passed to AcRtacCmd.exe
Then "importxml:1:failure" can be found in the output
And the error level returned is: "1"

Scenario: Attempt to export an xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL

Programming Reference Date Code 20241023


Command Line Interface 17
Command List

When the argument string "exportexp" is passed to AcRtacCmd.exe


Then "exportxml:1:failure" can be found in the output
And the error level returned is: "1"

exportlibrary
Export a project with <name> as a .compiledlibrary.

Synopsis
AcRtacCmd exportlibrary [-a <alias> | -i <pid>]
[-j <project_password>] [-f <file>] [-n <name>]

Remarks
➤ By default, the name of the created file is <name>.compiledlibrary and
will be saved in the same directory from which this command is executed.
➤ This command will overwrite the file if it already exists on the system.
➤ Use -f <file> to specify the path and name of the file to export. For
example, to save the export in a directory called MyProjects on the local
C: as the file mylibrary.compiledlibrary, set <file> to C:\MyProjects
\mylibrary.compiledlibrary.
➤ The -n option must be specified if the project is not open. This will open
the project before executing the command and close it upon completion.
The process of opening and closing the project automatically will increase
the time this command takes to complete.
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.
➤ This command is only supported on project version R132 or later.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-f, --file <file>

Name of file to export the project. Use this to specify the path to where
the export will be saved and/or to export the project with a different
name than the project name.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-n, --name <name>

The name of the project to export.

-j, --project_password <project_password>

The ACSELERATOR RTAC project password.

Date Code 20241023 Programming Reference


18 Command Line Interface
Command List

Examples
Feature: Export a project to a .compiled-library file

Scenario: Export an existing project named Xmlexample to .compiled-library


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "exportlibrary -n Xmlexample" is passed to
AcRtacCmd.exe
Then "exportlibrary:0:success" can be found in the output
And the error level returned is: "0"
And a .compiled-library is created in "the calling directory"

Scenario: Export an existing project named Xmlexample to


.compiled-library to a specific directory
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "exportlibrary -n Xmlexample -f
c:\test\testlibrary" is passed to AcRtacCmd.exe
Then "exportlibrary:0:success" can be found in the output
And the error level returned is: "0"
And a .compiled-library is created in "c:\test\testlibrary"

Scenario: Attempt to export a nonexisting project to .compiled-library


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "exportlibrary -n nonexisting" is passed
to AcRtacCmd.exe
Then "exportlibrary:1:failure" can be found in the output
And the error level returned is: "1"

exportxml
Export the current project as an XML directory structure at <directory>.

Synopsis
AcRtacCmd exportxml [-a <alias> | -i <pid>]
[-j <project_password>] [-n <name>]

<directory>

Remarks
➤ This command will overwrite the file if it already exists on the system.
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.

Programming Reference Date Code 20241023


Command Line Interface 19
Command List

➤ The -n option must be specified if the project is not open. This will open
the project before executing the command and close it upon completion.
The process of opening and closing the project automatically will increase
the time this command takes to complete.
➤ This command is only supported on project version R132 or later.

Values
<directory>

The directory to place the XML file structure export. If destination


directory does not exist; it will be created.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-n, --name <name>

The name of the project to export.

-j, --project_password <project_password>

The ACSELERATOR RTAC project password.

Examples
Feature: Importing and Exporting projects into XML directory structure

Scenario: Import a new project named Xmlexample for a 3530 using version
R136 from xml structure using an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "XmlTest"
And admin has logged in with password TAIL
When the argument string "importxml 3530 R136 ../../FTProjects/XmlFT -n
Xmlexample -a XmlTest" is passed to AcRtacCmd.exe
Then "importxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Export an existing project named Xmlexample to xml structure


using an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "XmlTest"
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "exportxml -n Xmlexample -a XmlTest
../../FTProjects/exportxml" is passed to AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Import a new project named Xmlexample for a 3530 using version

Date Code 20241023 Programming Reference


20 Command Line Interface
Command List

R136 from xml structure without an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importxml 3530 R136 ../../FTProjects/XmlFT -n
Xmlexample" is passed to AcRtacCmd.exe
Then "importxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Export an existing project named Xmlexample to xml structure


without an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "exportxml -n Xmlexample
../../FTProjects/exportxml" is passed to AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to import an xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importxml" is passed to AcRtacCmd.exe
Then "importxml:1:failure" can be found in the output
And the error level returned is: "1"

Scenario: Attempt to export and xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "exportxml" is passed to AcRtacCmd.exe
Then "exportxml:1:failure" can be found in the output
And the error level returned is: "1"

help
Prints out a list of commands.

Synopsis
AcRtacCmd help

Examples
Feature: Viewing Help Output
The AcRtacCmd help can be obtained by passing the --help argument.
If no argument is passed in, the help is displayed by default.

Scenario: Run the AcRtacCmd with the --help from CLI and obtain help
information
Given AcRtacCmd is in the system path
When the command "AcRtacCmd --help" is issued in a console
Then "--help" can be found in the output
And the error level returned is: "0"

Scenario: Running AcRtacCmd without any options also shows the help

Programming Reference Date Code 20241023


Command Line Interface 21
Command List

information
Given AcRtacCmd is in the system path
When the command "AcRtacCmd" is issued in a console
Then "--help" can be found in the output
And the error level returned is: "0"

importexp
Creates a new project from a .exp file with name <file> and stores it in the local
database.

Synopsis
AcRtacCmd importexp [-a <alias> | -i <pid>] [-n <name>]
<file>

Remarks
➤ The -n option allows the project name to be specified.
➤ This command will print the name of the project created to stdout.

Values
<file>

Path to file to import.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

<name>

The name of the new project.

Examples
Feature: Importing and Exporting projects as .exp file

Scenario: Import a new project from .exp file using an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "expTest"
And admin has logged in with password TAIL
When the argument string "importexp ../../FTProjects/expexample.exp -a
expTest" is passed to AcRtacCmd.exe
Then "importexp:0:success" can be found in the output
And the error level returned is: "0"

Date Code 20241023 Programming Reference


22 Command Line Interface
Command List

Scenario: Export an existing project named expexample to .exp file using


an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "expTest"
And admin has logged in with password TAIL
And the project "expexample" exists as a 3530 project in the db
And the project "expexample" is unlocked
When the argument string "exportexp expexample -a expTest" is passed to
AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Import a new project from .exp file without an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importexp ../../FTProjects/expexample.exp" is
passed to AcRtacCmd.exe
Then "importexp:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Export an existing project named expexample to .exp file


without an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "expexample" exists as a 3530 project in the db
And the project "expexample" is unlocked
When the argument string "exportexp expexample" is passed to
AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to import an xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importexp" is passed to AcRtacCmd.exe
Then "importxml:1:failure" can be found in the output
And the error level returned is: "1"

Scenario: Attempt to export an xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "exportexp" is passed to AcRtacCmd.exe
Then "exportxml:1:failure" can be found in the output
And the error level returned is: "1"

importxml
Creates a new project with the default project name from an XML folder
structure at <directory> and stores it in the local database.

Synopsis
AcRtacCmd importxml [-a <alias> | -i <pid>] [-n <name>]
[-l] <type> <version> <directory>

Programming Reference Date Code 20241023


Command Line Interface 23
Command List

Remarks
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.
➤ The -n option allows the project name to be specified.
➤ This command will print the name of the project created to stdout.
➤ This command is only supported on project version R132 or later.

Values
<directory>

The location on the disk of the XML directory root.


<type>

The type of RTAC. Valid RTAC types are shown in Table 1.4.
Table 1.4 importxml RTAC Types

Type Description

3530, 2241 RTAC type for an SEL-3530, SEL-3530-4, or SEL-2241.

3505 RTAC type for an SEL-3505 or SEL-3505-3 Communications Gateway.

3532, 3354, 3351, 3332, 1102 This RTAC type is for an SEL-3532, SEL-3354, SEL-3351, SEL-3332 or SEL-1102
Embedded Automation Computing Platform.

3555 RTAC type for an SEL-3555 Real-Time Automation Controller.

<version>

The r-number / RTAC firmware version.


-l, --library

Create imported project as library.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.


-n, --name <name>

The name to create the new project with. This will be used instead of the
default name.

Examples
Feature: Importing and Exporting projects into XML directory structure

Scenario: Import a new project named Xmlexample for a 3530 using version
R136 from xml structure using an alias
Given AcRtacCmd is in the system path

Date Code 20241023 Programming Reference


24 Command Line Interface
Command List

And "AcRtacCmd.exe start" has been executed to create a worker process


named "XmlTest"
And admin has logged in with password TAIL
When the argument string "importxml 3530 R136 ../../FTProjects/XmlFT -n
Xmlexample -a XmlTest" is passed to AcRtacCmd.exe
Then "importxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Export an existing project named Xmlexample to xml structure


using an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "XmlTest"
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "exportxml -n Xmlexample -a XmlTest
../../FTProjects/exportxml" is passed to AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Import a new project named Xmlexample for a 3530 using version
R136 from xml structure without an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importxml 3530 R136 ../../FTProjects/XmlFT -n
Xmlexample" is passed to AcRtacCmd.exe
Then "importxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Export an existing project named Xmlexample to xml structure


without an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "exportxml -n Xmlexample
../../FTProjects/exportxml" is passed to AcRtacCmd.exe
Then "exportxml:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to import an xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "importxml" is passed to AcRtacCmd.exe
Then "importxml:1:failure" can be found in the output
And the error level returned is: "1"

Scenario: Attempt to export an xml structure without using parameters


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "exportxml" is passed to AcRtacCmd.exe
Then "exportxml:1:failure" can be found in the output
And the error level returned is: "1"

Programming Reference Date Code 20241023


Command Line Interface 25
Command List

info
Displays state information relating to an RTAC process.

Synopsis
AcRtacCmd info [-a <alias> | -i <pid>]

Remarks
➤ This command prints to stdout in the following format:
|database|project|connection|
–––––––––––––––––––––––––––––
<name of connected database>:<name of open
project>:<online/offline>
The database field will be NONE if no database is open.
The project field will be NONE if no project is open.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: Get status of AcSELerator RTAC processes.
To allow for better recovery of AcSELerator RTAC processes, the info
command returns the status of AcSELerator RTAC process.

Scenario: Get the status of an AcSELerator RTAC process with an alias


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "InfoTest"
And admin has logged in with password TAIL
When the argument string "info -a InfoTest" is passed to AcRtacCmd.exe
Then "info:0:success" can be found in the output
And the error level returned is: "0"
And "RTAC:NONE:offline" can be found in the output

Scenario: Get the status of an AcSELerator RTAC process using the last
started process
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "info" is passed to AcRtacCmd.exe
Then "info:0:success" can be found in the output
And the error level returned is: "0"
And "RTAC:NONE:offline" can be found in the output

Scenario: Get the status of an AcSELerator RTAC process without logging in

Date Code 20241023 Programming Reference


26 Command Line Interface
Command List

Given AcRtacCmd is in the system path


And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
When the argument string "info" is passed to AcRtacCmd.exe
Then "NONE:NONE:offline" can be found in the output
And "info:0:success" can be found in the outputs
And the error level returned is: "0"

list
List all projects in an ACSELERATOR RTAC database.

Synopsis
AcRtacCmd list [-a <alias> | -i <pid>]

Remarks
➤ This command requires being logged into the ACSELERATOR RTAC
database to work.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: List projects in AcSELerator RTAC database
The list command is used to query the AcSELerator RTAC database for
projects and show what is stored.

Scenario: Show all projects in database


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "list" is passed to AcRtacCmd.exe
Then "list:0:success" can be found in the output
And the error level returned is: "0"
And A list of projects can be found in the output in the format
"name:type:version"

Scenario: Attempt to list the projects stored in the database without


being logged into the database
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
When the argument string "list" is passed to AcRtacCmd.exe
Then "list:1:failure" can be found in the output
And the error level returned is: "1"

Programming Reference Date Code 20241023


Command Line Interface 27
Command List

login
Log into the ACSELERATOR RTAC database.

Synopsis
AcRtacCmd login [options] <username>

Values
<username>

The login username of the database account.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-d, --database <database>

Name of the database to log into. Default: RTAC.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-n, --port <port>

Port number to use when connecting to a database. Default: 5433

-p, --password <password>

Login password of database. If not given, the command will attempt to


read from stdin. No prompt for a password will occur.

-s, --server <server>

IP address of server on which the database is stored. Default:


localhost.

Examples
Feature: Login to AcSELerator RTAC database
After the AcSELerator RTAC worker process has started, it must
authenticate against the RTAC database before any meaningful work
can be done.

Scenario: Login to the AcSELerator RTAC database with default account


Given "AcRtacCmd.exe start" has been executed to create an unnamed
worker process
When the argument string "login admin -p TAIL" is passed to
AcRtacCmd.exe
Then "login:0:success" can be found in the output
And the error level returned is: "0"

Date Code 20241023 Programming Reference


28 Command Line Interface
Command List

Scenario: Attempt to login without providing a correct username and


password
Given "AcRtacCmd.exe start" has been executed to create an unnamed
worker process
When the argument string "login notarealuser -p badpassword" is passed
to AcRtacCmd.exe
Then "login:1:failure" can be found in the output
And the error level returned is: "1"

lsproc
List all RTAC processes.

Synopsis
AcRtacCmd lsproc

Remarks
➤ This command will list all running RTAC.exe processes.
➤ Processes without an alias will only list their process ID.
➤ The list will print out in the following format:
:1255
MyRTAC:6943
...
lsproc:0:success

Examples
Feature: Get list of AcSELerator RTAC processes.
lsproc returns a list of running RTAC processes. This list contains
both the alias and PID that can be used to issue commands to a
specific RTAC.exe instance.

Scenario: Get a list of all running AcSELerator RTAC processes when one
unnamed process is running
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
When the argument string "lsproc" is passed to AcRtacCmd.exe
Then "lsproc:0:success" can be found in the output
And the error level returned is: "0"
And ":1234" can be found in the output

Scenario: Get a list of all running AcSELerator RTAC processes when one
process is running with alias "lsprocTest"
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "lsprocTest"
When the argument string "lsproc" is passed to AcRtacCmd.exe
Then "lsproc:0:success" can be found in the output
And the error level returned is: "0"
And "lsprocTest:2468" can be found in the output

Programming Reference Date Code 20241023


Command Line Interface 29
Command List

open
Opens a project in ACSELERATOR RTAC database with name <name>.

Synopsis
AcRtacCmd open [-a <alias> | -i <pid>] [-j
<project_password>] <name>

Remarks
➤ While some commands will automatically open a project when required,
it is recommended to first open a project with this command if multiple
commands on the same project will be executed. This will save time by
not opening and closing a project repeatedly during command execution.

Values
<name>

The name of the project to open.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-j, --project_password <project_password>

The ACSELERATOR RTAC project password.

Examples
Feature: Opening and closing AcSELerator RTAC projects.
Once a process is logged into a database, the open and close commands
are used to access the projects within a database.

Scenario: Open the project 'OpenTest' with a process using the alias
'LoginTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "LoginTest"
And admin has logged in with password TAIL
And the project "OpenTest" exists as a 3530 project in the db
And the project "OpenTest" is unlocked
When the argument string "open OpenTest -a LoginTest" is passed to
AcRtacCmd.exe
Then "open:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Close the project 'OpenTest' with a process using the alias
'LoginTest'

Date Code 20241023 Programming Reference


30 Command Line Interface
Command List

Given AcRtacCmd is in the system path


And "AcRtacCmd.exe start" has been executed to create a worker process
named "LoginTest"
And admin has logged in with password TAIL
And the project "OpenTest" exists as a 3530 project in the db
And the project "OpenTest" is unlocked
And the project "OpenTest" is open
When the argument string "close -a LoginTest" is passed to AcRtacCmd.exe
Then "close:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Open the project 'OpenTest' with the last started process
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "OpenTest" exists as a 3530 project in the db
And the project "OpenTest" is unlocked
When the argument string "open OpenTest" is passed to AcRtacCmd.exe
Then "open:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to open a project without entering the project name


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "open" is passed to AcRtacCmd.exe
Then "open:1:failure" can be found in the output
And the error level returned is: "1"

read
Reads a project into the active local database from a remote RTAC.

Synopsis
AcRtacCmd read [-a <alias> | -i <pid>] [options]
<ipaddress> <username>

Remarks
➤ Note that after a successful read, if the overwrite option (-o, –overwrite)
is specified, an existing project with the same name will be renamed and
then deleted. If this overwrite process fails, the existing project or the
read-in project may reflect their temporary names.
➤ If the overwrite option is not specified, the name may be an incremented
version of the remote project if the project name already exists.
➤ The user may also send advanced read settings (listed in Table 1.5).

Values
<ipaddress>

RTAC IPv4 address


<username>

Remote RTAC account username with which to log in.

Programming Reference Date Code 20241023


Command Line Interface 31
Command List

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-d, --disable

You can choose to disable your RTAC before reading to speed up read
time. Note that this is only beneficial when the device contains more than
10,000 tags.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.


-o, --overwrite <overwrite>

Overwrites the existing project with the same name.


-n, --name <name>

The name of the new project.


-b, --databaseport <databaseport>

The database port number.


-p, --password <password>

Login password of remote RTAC. If not given, the command will


attempt to read from stdin. No prompt for a password will occur.

Advanced Options
The following are additional settings that can be in a project:
-v, --advanced <key>

Allows specifying advanced options for reading projects. The <key> is a


comma-separated list of advanced settings shown in Table 1.5.
Table 1.5 Advanced Reading Options

Name Description

all All available project settings

Ethernet-settings Project Ethernet settings

user-accounts Project user account setting

event-logs Project sequence of events report

website-settings Project website settings

x509-certs Project x509 certificate

LDAP Project lightweight directory access protocol settings

Hosts Project Host settings

CA-certs Project certificate authority settings

HMI-diagrams Project HMI diagrams

Date Code 20241023 Programming Reference


32 Command Line Interface
Command List

Name Description

event-collection Project event collection logs

SSH-authorized-keys Project SSH-authorized-keys

SSH-host-keys Project SSH host key settings

Examples
Feature: Reading project settings from a RTAC.

Scenario: Read project settings from a RTAC


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL"
is available
And the RTAC is running "SampleProject"
When the argument string "read 197.201.80.255 SEL -p SEL" is passed to
AcRtacCmd.exe
Then "read:0:success" can be found in the output
And the error level returned is: "0"
And "SampleProject" can be found as a project in the local database

Scenario: Attempt to read project settings from a RTAC with invalid


credentials
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And a RTAC at "197.201.80.255" with username "SEL" and password "SEL"
is available
And the RTAC is running "SampleProject"
When the argument string "read 197.201.80.255 SEL -p badpassword" is
passed to AcRtacCmd.exe
Then "read:1:failure" can be found in the output
And the error level returned is: "1"

rename
Renames a project to <name>.

Synopsis
AcRtacCmd rename [-a <alias> | -i <pid>] [-n <name>]
<new_name>

Remarks
➤ Use the -n option to rename an unopened project.
➤ This command fails if the name already exists.

Values
<new_name>

New project name.

Programming Reference Date Code 20241023


Command Line Interface 33
Command List

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-n, --name <name>

The name of the project to rename. This must be specified if the project
is not open.

Examples
Feature: Rename an AcRtac project
Rename is used to change the name of a project in the database.

Scenario: Rename an existing project from "Xmlexample" to "RenameProject"


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "rename RenameProject -n Xmlexample" is
passed to AcRtacCmd.exe
Then "rename:0:success" can be found in the output
And the error level returned is: "0"
And the project "RenameProject" exists as a project in the db

Scenario: Attempt to Rename a project without opening or giving the


project name
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "Xmlexample" exists as a 3530 project in the db
And the project "Xmlexample" is unlocked
When the argument string "rename Xmlexample" is passed to AcRtacCmd.exe
Then "rename:1:failure" can be found in the output
And the error level returned is: "1"

rtacinfo
Displays information associated with an RTAC.

Synopsis
AcRtacCmd rtacinfo [-a <alias> | -i <pid>] [-p
<password>] [-b <databaseport>] <ipaddress> <username>

Date Code 20241023 Programming Reference


34 Command Line Interface
Command List

Remarks
➤ This command requires the username and password be provided.
➤ This command prints to stdout in the following format:
|project|mot|fid|status|
––––––––––––––––––––––––
<name of project>:<MOT string of RTAC>:<FID string of
RTAC>:<Status of RTAC>

Values
<ipaddress>

IP address of the remote RTAC.


<username>

username of the remote RTAC.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.


-p, --password <password>

Login password of remote RTAC. If not given, the command will


attempt to read from stdin. No prompt for a password will occur.
-b, --databaseport <databaseport>

The database port number.

Examples
Feature: Display information associated with an RTAC.

Scenario: Get info from a connected RTAC using password parameter


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And an RTAC is connected with an IP of 192.168.16.44 and username of
OTTER and password of TAIL
When the argument string "rtacinfo -p TAIL 192.168.16.44 OTTER" is
passed to AcRtacCmd.exe
Then "rtacinfo:0:success" can be found in the output
And the error level returned is: "0"
And the project, mot, fid, and status are found in the output

Scenario: Connection to RTAC without password parameter fails


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "lsprocTest"
And an RTAC is connected with an IP of 192.168.16.44 and username of
OTTER and password of TAIL

Programming Reference Date Code 20241023


Command Line Interface 35
Command List

When the argument string "rtacinfo 192.168.16.44 OTTER" is passed to


AcRtacCmd.exe
Then "rtacinfo:1:failure" can be found in the output
And the error level returned is: "1"
And the output message is displayed which indicates the password is
required

setpassword
Sets the password on a project.

Synopsis
AcRtacCmd setpassword [-a <alias> | -i <pid>] [-n
<name>] <project_password>

Remarks
➤ This command requires the provided password conforms with the same
password requirements enforced when a password is set using the user
interface.

Values
<project_password>

New password to be set for the given project.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.


-n, --name <name>

The name of the project to set the password on.

Examples
Feature: Set the password on a project.

Scenario: Set the password on a project


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And a project with the name Test_Project exists in the database
When the argument string "setpassword -n Test_Project 1_Quick_Fox" is
passed to AcRtacCmd.exe
Then "setpassword:0:success" can be found in the output
And the error level returned is: "0"
And the project now shows "Password On" in the status column of the
database

Date Code 20241023 Programming Reference


36 Command Line Interface
Command List

Scenario: Setting a weak password fails


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "lsprocTest"
And a project with the name Test_Project exists in the database
When the argument string "setpassword -n Test_Project thisisapassword"
is passed to AcRtacCmd.exe
Then "setpassword:1:failure" can be found in the output
And the error level returned is: "1"
And the output message is displayed which indicates the provided
password is invalid

start
Starts a new RTAC.exe process.

Synopsis
AcRtacCmd start [-a <alias>] [-s <startup switch>] [-v]

Remarks
➤ The last started process will be the active process to which all other
commands will be directed to unless otherwise specified in the command.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-v, --visual

Opens the ACSELERATOR RTAC GUI when starting RTAC.exe.


Commands will still be accepted through the command line and the open
window will reflect changes made by commands.

Startup Switches
-s, --switch <startup switch>

Starts RTAC.exe with additional options. The options are given as a


comma-separated list.

Examples
Feature: Starting and stopping AcSELerator RTAC processes.
Before any work can be done using the AcRtacCmd.exe tool, an instance of
AcSELerator RTAC must be launched to do that actual work requested. This
process should be stopped after the desired work is completed so that it
does not continue to run in the background and consume computing
resources. If no alias is provided, the process can only be identified by
PID afterwards. However, a reference to the last started process is
retained, so if "stop" is issued without an alias, it will stop the last
AcSELerator RTAC worker that was started.

Scenario: Run AcRtacCmd.exe from CLI with the argument "start" and an

Programming Reference Date Code 20241023


Command Line Interface 37
Command List

alias
Given AcRtacCmd is in the system path
When the command "AcRtacCmd start -a NewAcRtacProcess" is issued in a
console
Then "start:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Run AcRtacCmd from CLI to stop the started process with an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "NewAcRtacProcess"
When the command "AcRtacCmd stop -a NewAcRtacProcess" is issued in a
console
Then "stop:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Run AcRtacCmd.exe from CLI with the argument "start" but
without an alias
Given AcRtacCmd is in the system path
When the command "AcRtacCmd start" is issued in a console
Then "start:0:success" can be found in the output
And the error level returned is: "0"
And "AcRtacCmd stop" can be issued in a console to clean up

Scenario: Run AcRtacCmd to stop a process without any processes running


Given AcRtacCmd is in the system path
When the command "AcRtacCmd stop" is issued in a console
Then "stop:1:failure" can be found in the output
And the error level returned is: "1"

stop
Stops the last started RTAC.exe.

Synopsis
AcRtacCmd stop [-a <alias> | -i <pid>]

Remarks
➤ Use the options below to specify which RTAC.exe to close.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.
-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: Starting and stopping AcSELerator RTAC processes.
Before any work can be done using the AcRtacCmd.exe tool, an instance of
AcSELerator RTAC must be launched to do that actual work requested. This
process should be stopped after the desired work is completed so that it
does not continue to run in the background and consume computing
resources. If no alias is provided, the process can only be identified by

Date Code 20241023 Programming Reference


38 Command Line Interface
Command List

PID afterwards. However, a reference to the last started process is


retained, so if "stop" is issued without an alias, it will stop the last
AcSELerator RTAC worker that was started.

Scenario: Run AcRtacCmd.exe from CLI with the argument "start" and an
alias
Given AcRtacCmd is in the system path
When the command "AcRtacCmd start -a NewAcRtacProcess" is issued in a
console
Then "start:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Run AcRtacCmd from CLI to stop the started process with an alias
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "NewAcRtacProcess"
When the command "AcRtacCmd stop -a NewAcRtacProcess" is issued in a
console
Then "stop:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Run AcRtacCmd.exe from CLI with the argument "start" but
without an alias
Given AcRtacCmd is in the system path
When the command "AcRtacCmd start" is issued in a console
Then "start:0:success" can be found in the output
And the error level returned is: "0"
And "AcRtacCmd stop" can be issued in a console to clean up

Scenario: Run AcRtacCmd to stop a process without any processes running


Given AcRtacCmd is in the system path
When the command "AcRtacCmd stop" is issued in a console
Then "stop:1:failure" can be found in the output
And the error level returned is: "1"

unlock
Unlocks a project.

Synopsis
AcRtacCmd unlock [-a <alias> | -i <pid>] <name>

Remarks
➤ The user may pass '*' to unlock all projects in the database, which
provides a useful testing precondition.

Values
<name>

The name of the project to unlock.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

Programming Reference Date Code 20241023


Command Line Interface 39
Command List

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

Examples
Feature: Unlocking AcSELerator RTAC projects.
Once a project is opened, the project is locked in the AcSELerator RTAC
database. If the project was not properly closed, it will remain locked.
The unlock command allows the project to be accessed again.

Scenario: Unlock the project 'ExampleProject' with a process using the


alias 'UnlockTest'
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create a worker process
named "UnlockTest"
And admin has logged in with password TAIL
And the project "ExampleProject" exists as a 3530 project in the db
And the project "ExampleProject" is locked
When the argument string "unlock ExampleProject -a UnlockTest" is
passed to AcRtacCmd.exe
Then "unlock:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Unlock the project 'ExampleProject' with the last started


process
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And the project "ExampleProject" exists as a 3530 project in the db
And the project "ExampleProject" is locked
When the argument string "unlock ExampleProject" is passed to
AcRtacCmd.exe
Then "unlock:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to unlock a project that does not exist


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
When the argument string "unlock nonExistent" is passed to AcRtacCmd.exe
Then "unlock:1:failure" can be found in the output
And the error level returned is: "1"

upgradefirmware
Upgrades the firmware of a target device with the provided .upg or .zip firmware
upgrade file.

Synopsis
AcRtacCmd upgradefirmware [options] <ipaddress>
<username> <file>

Values
<ipaddress>

RTAC IPv4 address.

Date Code 20241023 Programming Reference


40 Command Line Interface
Command List

<username>

Remote RTAC account username to login with.

<file>

Path to firmwareupgrade file.

Options
-a, --alias <alias>

Executes command on specified RTAC.exe process with given <alias>.


If not given, executes in the last started RTAC.exe process.

-i, --pid <pid>

Same as -a but takes a process ID instead of process name.

-p, --password <password>

Login password of remote RTAC. If not given, the command will


attempt to read from stdin. No prompt for a password will occur.

-b, --databaseport <databaseport>

The database port number.

Examples
Feature: Upgrade firmware on an RTAC

Scenario: Change "3555" RTAC firmware to "R135"


Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And a "3555" RTAC at "197.201.80.255" with username "SEL" and password
"SEL" is available
And an RTAC firmware image is available at "c:\RTAC\3555_R135.upg"
When the argument string "upgradefirmware 197.201.80.255 SEL -p SEL
c:\RTAC\3555_R135.upg" is passed to AcRtacCmd.exe
Then "upgradefirmware:0:success" can be found in the output
And the error level returned is: "0"

Scenario: Attempt to Change "3555" RTAC firmware to "R135" with "3530"


firmware image
Given AcRtacCmd is in the system path
And "AcRtacCmd.exe start" has been executed to create an unnamed worker
process
And admin has logged in with password TAIL
And a "3555" RTAC at "197.201.80.255" with username "SEL" and password
"SEL" is available
And an RTAC firmware image is available at "c:\RTAC\3530_R135.upg"
When the argument string "upgradefirmware 197.201.80.255 SEL -p SEL
c:\RTAC\3530_R135.upg" is passed to AcRtacCmd.exe
Then "upgradefirmware:1:failure" can be found in the output
And the error level returned is: "1"

Programming Reference Date Code 20241023


Command Line Interface 41
Command Line Example Usage

Command Line Example Usage


Convert .exp to .xml From Command Line
This example provides step-by-step instructions on how to import a project from
a .exp file and export it to a .xml file/folder system.

Assumptions
The following must be true for this example to work:

➤ The user has a working directory at C:\TestConvertExpToXml\


➤ This working directory has a folder C:\TestConvertExpToXml
\MyProject
➤ The default database account "admin" uses the default password "TAIL"
➤ The filename of the .exp file is MyProject.exp
➤ The name of the project in the .exp file is "MyProject"
➤ The exported file/folder system will exist within the working directory in
a subfolder \MyProject

Procedure
Step 1. Place the MyProject.exp file into the directory
C:\TestConvertExpToXml\.
Step 2. Start a new AcRtacCmd session by entering AcRtacCmd start -a
session1.
Step 3. The command will respond as follows (note that the PID may be
different than shown in this example):
AcRtacCmd start -a session1
session1:1234
start:0:success
Step 4. Log into the Database with the command AcRtacCmd login
admin -p TAIL.

Note that your username and password should be used in place of


"admin" and "TAIL" above.
Step 5. The command will respond as follows:
AcRtacCmd login admin -p TAIL
login:0:success
Step 6. Now, to import a .exp file, use the command AcRtacCmd importexp
"C:\TestConvertExpToXml\MyProject.exp"
Step 7. The command will respond as follows:
AcRtacCmd importexp C:\TestConvertExpToXml
\MyProject.exp
importexp:MyProject
importexp:0:success
Step 8. Then enter the command below to export to .xml the project that
was just imported. Note that because you did not open the project
first, this command will open, export, and then close the project.

Date Code 20241023 Programming Reference


42 Command Line Interface
Command Line Example Usage

AcRtacCmd exportxml "C:\TestConvertExpToXml


\MyProject" -n MyProject
Step 9. When complete, the command should return as follows:

AcRtacCmd exportxml "C:\TestConvertExpToXml


\MyProject" -n MyProject
.
.
.
exportxml:0:success
Step 10. Ensure the RTAC process is stopped before completing the session
as follows:

AcRtacCmd stop -a session1


stop:0:success

Expected Result
The project definition should now exist in the following folder:
C:\TestConvertExpToXml\MyProject\.

Programming Reference Date Code 20241023


S E C T I O N 2

Library Extensions Installer


This section details the expected usage and outputs of the Library Extension
Installer executable distributed with ACSELERATOR RTAC® SEL-5033 Software.
This interface is provided such that additional functionality can be deployed to
the ACSELERATOR RTAC software to extend the feature set.

Description
LibraryExtensionInstaller.exe is a standalone executable installed as part of
ACSELERATOR RTAC in the RTAC subdirectory ./SEL/AcSELerator/RTAC,
relative to the ACSELERATOR RTAC installation location (by default, C:/
Program Files (x86)/).

Installing ACSELERATOR RTAC Extension Packages


In addition to installing CODESYS libraries, this command line interface can
be used to install all of the content required for a new ACSELERATOR RTAC
Extension. This content is expected to be in a .rext file, which is a zipped folder
with the following layout:

.rext
╠═ <folder with a version of the extension X.X.X.X>
║ ╠═ <ExtensionPy>.py
║ ╠═ <ExtensionXML>.xml
║ ╠═ <ExtensionPy>.sig
║ ╚═ <ExtensionXML>.sig
╠═ <CODESYSLibraryA>.compiled-library (optional)
╚═ <CODESYSLibraryB>.library (optional)

Note that each ACSELERATOR RTAC Extension can contain zero or


more .compiled-library or .library files.

The .xml files in the .rext file will be parsed, and the content of the first tag:

<RTACModule><CustomApplicationDefinition><Name>

is used as the name of the ACSELERATOR RTAC Extension.

Usage
To install the extension content, call the installer and pass in the .rext file
containing the extension as an argument, as in the following command line
example:

> cd /Program Files (x86)/SEL/AcSELerator/RTAC


> LibraryExtensionInstaller.exe C:/Users/Alice/Desktop/
myExtensions/Extension1.rext

Date Code 20241023 Programming Reference


44 Library Extensions Installer
Bulk Installation of .library, .compiled-library, and .rext Files

Behavior
➤ The command line application will attempt to install all .library
and .compiled-library files found in the .rext file, whether or not they are
already installed in the library repository. This means existing libraries
will be overwritten.
➤ Files inside the versioned folders will be added to ACSELERATOR RTAC
so that they are exposed as a new entry in the Extensions menu in the
project configuration screen the next time ACSELERATOR RTAC is
launched.
➤ Subfolders inside the version folder are ignored.
➤ No package signing validation is done at install time.

Bulk Installation of .library, .compiled-library, and .rext


Files
In order to expedite the installation of many libraries or extensions, you can pass
into the service a folder containing a combination of .library, .compiled-library,
and .rext files.

Usage
From within the RTAC subdirectory ./SEL/AcSELerator/RTAC, the installer
can be provided a folder that contains various types of packages. For example:

> cd /Program Files (x86)/SEL/AcSELerator/RTAC


> LibraryExtensionInstaller.exe C:/Users/Alice/Desktop/
myExtensions

Behavior
➤ Only files present at the top level of the library folder will be installed
(the installer will not search recursively for library files).
➤ The installer will attempt to install all IEC 61131 CODESYS libraries
(.library and .compiled-library files), allowing those libraries to be
included in projects. Any existing libraries with the same name and
version will be overwritten.
➤ Any .rext packages that are discovered in the root of the folder will
be installed as described in Installing ACSELERATOR RTAC Extension
Packages on page 43.

Logging and Debugging


The installer outputs to the human-readable log file
LibraryExtensionInstaller.txt, which is contained in the directory C:/
Users/<username>/Documents/AcSELerator RTAC/Logs. The file is not
structured, but will indicate complete for each successful library installation,

Programming Reference Date Code 20241023


Library Extensions Installer 45
Return Value

listing the name of the library on the same line. A successful installation of all
libraries will be indicated by All libraries installed successfully
near the end of the file. Errors and failures may be found by searching for the
words "fail" or "error".
Code Snippet 2.1 Example Log File Output
[Begin] Initializing logic engine
[End] Initializing logic engine
Installing DynamicVectorsFT... complete.
Installing CompiledMathMatrixFT... complete.
All libraries installed successfully.
[Begin] Shutting down logic engine
[End] Shutting down logic engine

Return Value
The installer will return 0 only if all extensions within the .rext file were copied,
all libraries installed successfully, and no errors were encountered during
execution. Otherwise, it will return a value of –1.

If the return value is not 0, consult the log file to obtain particular details about
the error source of failure. Such errors may include a missing or incorrect
command line parameter, libraries that failed to install due to corruption, or
other exceptions.

Notes and Exceptions


LibraryExtensionInstaller.exe currently requires the
LibraryExtensionInstaller.exe .config XML file, which directs the executable
where to probe for certain required assemblies. The .config file should have
been installed along with ACSELERATOR RTAC and should not be modified.

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 3

AnalogConditioning
Introduction
This library contains classes that allow for simplified processing of analog
quantities within applications. Generally, measured analog quantities require
filtering and checks before being used. This library provides this filtering via
encapsulated classes.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.1.1 and earlier can be used on RTAC firmware version R132 and
later.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_p_MaxFilterOrder UINT 4 The maximum order of the filter for class_ArmaFilter. This determines the
maximum number of coefficients and the maximum delay, in samples, for
the filter.

Interface Definitions
This section outlines the various interfaces defined within this library.

I_Filter
Classes implementing this interface provide a filter for analog values.

ConditionValue (Method)
This method takes inputValue as the next input for the filter and provides an
output for the new conditioned value.

Date Code 20241023 Programming Reference


48 AnalogConditioning
Interface Definitions

Inputs
Name IEC 61131 Type Description

inputValue REAL The new raw input to the filter.

Outputs
Name IEC 61131 Type Description

conditionedValue REAL The filtered output.

Return Value
IEC 61131 Type Description

BOOL True when filter windup is complete and conditionedValue output is


fully filtered.

Reset (Method)
This method resets the filter and clears any internal state.

I_LimitedSplpf
This interface extends the I_Filter interface described in I_Filter on page 47,
meaning that classes implementing this interface also implement the I_Filter
methods. This interface is implemented by classes that condition analog values
through a limited, single-pole, low-pass filter (SPLPF).
Classes implementing this interface provide the following features:
➤ Conditioning of the raw input through a low-pass filter controlled by a
time constant defined in the object.
➤ Controlled output if the class is in Alarm. In the event that the
conditioning class is in alarm, the class provides a result which
approaches a predefined default value.
➤ Output bounded by the limits defined in the object.
➤ An out-of-bounds alarm which asserts if the input exceeds the high limit
or falls below the low limit.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Alarm BOOL R/W Sets an alarm when true. Clears the


alarm state if FALSE.

OutOfBoundsAlarm (Method)
Provides the out-of-bounds state of the ConditionValue() input.

Programming Reference Date Code 20241023


AnalogConditioning 49
Classes

Return Value
IEC 61131 Type Description

BOOL Returns true if the input value is out of the boundaries specified in the
object's constructor.

Classes
This section contains the basic definitions, descriptions, and public methods for
the public classes that can be instantiated by the user.

class_PassThroughFilter
This class implements a simple pass-through, where conditionedValue is set
directly to inputValue. It is meant to be used in place of a filter during testing
phases of development where it may be desirable to bypass a filtering stage.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_Filter

class_ArmaFilter
This class implements an AutoRegressive Moving Average (ARMA) filter,
generally used to filter oscillating signals. This implementation provides either
Infinite Impulse Response (IIR) or Finite Impulse Response (FIR) behavior,
depending on the coefficients provided. The filter implements the form:

where:

Obtaining the coefficients for low-pass, high-pass, band-pass, or band-stop


filters is made relatively simple using tools like MATLAB or OCTAVE, but
the mathematical methods for obtaining these values are outside the scope of
this document; the user of this library should be aware that many filter designs
used to obtain coefficients for this filter can produce numerical instability. See
Filtering With class_ArmaFilter on page 60 for a brief discussion on how to
determine if the filter is numerically stable or not.
Once the coefficients b0 to bN and a1 to aM are determined, they are loaded as
initialization inputs to the class. These coefficients must be normalized, as the
leading 1 in A(z) is assumed in this class; in other words, a0 is always assumed
to be exactly 1.

Date Code 20241023 Programming Reference


50 AnalogConditioning
Classes

Figure 3.1 shows how the filter works when three (3) coefficients for A(z)
and five (5) coefficients for B(z) are provided. Note how the depth of the
filter is normalized so that there are as many A(z) branches as there are B(z)
branches. Because there is one less coefficient in the A(z) array (when including
the assumed a0 = 1) than in the B(z) coefficient array, the coefficient of the
last branch a4 is set to zero (0). In this particular example, there are five
B(z) coefficients, and because each z value is shifted in time, four previous
intermediate values must be stored in the filter. This means that the filter is
not sufficiently primed until the 5th input value is provided. For this set of
coefficients, the first four calls to ConditionValue() will yield a partially
filtered output value, and the method will return FALSE. The 5th call of the
method, and all subsequent calls, will return true.

Figure 3.1 A Digital Filter Using Three (3) Coefficients for A(z) and Five (5) for
B(z)

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Filter

Initialization Inputs

Name IEC 61131 Type Description

aCoefficients ARRAY [1..g_p_MaxFilterOrder] OF REAL Coefficients for A(z). The coefficients must be
normalized, as the leading 1 is assumed and should
not be entered in this array.

bCoefficients ARRAY [0..g_p_MaxFilterOrder] OF REAL Coefficients for B(z).

numACoefficients UINT(1..g_p_MaxFilterOrder) The number of coefficients within the aCoefficients


array.

numBCoefficients UINT(1..g_p_MaxFilterOrder + 1) The number of coefficients within the bCoefficients


array.

Programming Reference Date Code 20241023


AnalogConditioning 51
Classes

class_ArmaFilter_LREAL
This class implements an AutoRegressive Moving Average (ARMA) filter,
generally used to filter oscillating signals. This implementation provides either
Infinite Impulse Response (IIR) or Finite Impulse Response (FIR) behavior,
depending on the coefficients provided. The filter implements the form:

where:

The implementation of this filter is the same as the class_ArmaFilter,


class_ArmaFilter on page 49, but it retains greater precision internally. This
allows for greater stability.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Filter

Initialization Inputs

Name IEC 61131 Type Description

aCoefficients ARRAY [1..g_p_MaxFilterOrder] OF LREAL Coefficients for A(z). The coefficients must be
normalized, as the leading 1 is assumed and should
not be entered in this array.

bCoefficients ARRAY [0..g_p_MaxFilterOrder] OF LREAL Coefficients for B(z).

numACoefficients UINT(1..g_p_MaxFilterOrder) The number of coefficients within the aCoefficients


array.

numBCoefficients UINT(1..g_p_MaxFilterOrder + 1) The number of coefficients within the bCoefficients


array.

class_LimitedSplpfStepToDefault
Instantiate this class when a single-pole low-pass filter that has an imposed
range of accept-able values is desired. When in alarm, this class will cause the
output to step, in a single time step, to the defaultOutput set in the constructor
method for the class.

Date Code 20241023 Programming Reference


52 AnalogConditioning
Classes

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_LimitedSplpf

LimitedSplpfStepToDefault (Method)
This method acts as the constructor and must be called before the class can
operate. It initializes the characteristics of the filter.

Inputs
Name IEC 61131 Type Description

highLimit REAL The largest valid value for the input variable.

lowLimit REAL The smallest valid value for the input variable.

defaultOutput REAL The conditioned output defaults to this value if the input is out of
range or the alarm is high.

timeConstant UINT Range: 100–60000 ms. The time constant to use for the low-pass
filter within this method.

Return Value
IEC 61131 Description

POINTER TO STRING Return a pointer to an error message if an error occurred. Return zero if no errors exist.

Processing
This method:
➤ Sets defaultOutput as the initial output and input to the filter in order to
eliminate "wind-up" during the first few scans.
➤ Returns a pointer to an error message if lowLimit exceeds highLimit.
➤ Returns a pointer to an error message if defaultOutput is less than
lowLimit or greater than highLimit.

bootstrap_SetInitialValue (Method)
This method may be called at startup if the user desires a value different than
the defaultOutput (set previously in the constructor method call) as the initial
output.

Inputs
Name IEC 61131 Type Description

initialValue REAL Range: lowLimit ≤ initialValue ≤ highLimit. Sets the initial value to
be used by the filter at startup.

Programming Reference Date Code 20241023


AnalogConditioning 53
Classes

Return Value

IEC 61131 Type Description

POINTER TO STRING Return a pointer to an error message if an error occurred. Return zero if no errors exist.

Processing
This method:

➤ Bypasses all internal filtering and changes both the input and conditioned
output to be equal to initialValue.
➤ Returns a pointer to an error message if the constructor has not been
called.
➤ Returns a pointer to an error message if initialValue is less than lowLimit
or greater than highLimit set in the constructor.

Processing of Interface Methods


This section provides specifics regarding the implementation of the methods
required by the implemented interface(s).

I_LimitedSplpf—ConditionValue
This describes the behavior of this class when the ConditionValue() method
is called.

➤ When the constructor has not yet been called, then this method returns
FALSE and sets the method output conditionedValue to zero (0).
➤ The time between calls is limited to a minimum of 1 ms and a
maximum of 60000 ms. This section references the limited value as
timeElapsedLimited.
➤ The time constant used in calculating the output value,
timeConstantUsed, is limited such that it must exceed or equal five times
the elapsed time between calls of this method, timeElapsed.
➤ When the inputValue is less than lowLimit, set in the constructor, then the
input is limited to lowLimit and the out-of-bounds internal flag is set.
➤ When inputValue exceeds highLimit, set in the constructor, then the input
is limited to highLimit and the out-of-bounds internal flag is set.
➤ When inputValue is within the limits outlined in the constructor, the input
is filtered through a low-pass filter in order to provide the output and the
out-of-bounds internal flag is reset.
➤ When all of the following conditions are met:
➢ inputValue is less than highLimit
➢ inputValue is greater than the lowLimit
➢ Alarm property is false
this method computes the conditionedValue output equivalent to:
((inputValue – lastConditionedValue) • 0.632 • •
timeElapsedLimited) + lastConditionedValue

Date Code 20241023 Programming Reference


54 AnalogConditioning
Classes

where:
➢ inputValue is the current input to ConditionValue()
➢ lastConditionedValue is the input to ConditionValue() from the
previous scan
➢ timeConstantUsed is the range limited time constant
➢ timeElapsedLimited is the range limited elapsed time since the last
scan
➤ When the input is out of range, it is limited to the corresponding range
value, and on a subsequent call where the input is within the specified
range, the conditioned output ramps to that value from the limit where it
was being held.
➤ When the input is in alarm, the output, input, and any internal filtering
values are set to defaultOutput. Once the alarm is removed, the input
is no longer overridden and the output value ramps to the input value
through the filter, i.e., steps to defaultOutput when in alarm and ramps
from defaultOutput back to inputValue after the alarm is removed.

class_LimitedSplpfRampToDefault
Instantiate this class when single-pole low-pass filter that has an imposed range
of acceptable values is desired. When in alarm, this class ramps the conditioned
value to defaultOutput, set in the constructor method, at the same rate it would
any other input.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_LimitedSplpf

LimitedSplpfRampToDefault (Method)
This method acts as the constructor and must be called before the class can
operate. It initializes the characteristics of the filter.

Inputs

Name IEC 61131 Type Description

highLimit REAL The largest valid value for the input variable.

lowLimit REAL The smallest valid value for the input variable.

defaultOutput REAL The conditioned output defaults to this value if the input is out of
range or the alarm is high.

timeConstant UINT Range: 100–60000 ms. The time constant to use for the low-pass
filter within this method.

Programming Reference Date Code 20241023


AnalogConditioning 55
Classes

Return Value

IEC 61131 Type Description

POINTER TO STRING Return a pointer to an error message if an error occurred. Return zero if no errors exist.

Processing
This method:

➤ Sets defaultOutput as the initial output and input to the filter in order to
eliminate "wind-up" during the first few scans.
➤ Returns a pointer to an error message if lowLimit exceeds highLimit.
➤ Returns a pointer to an error message if defaultOutput is less than
lowLimit or greater than highLimit.

bootstrap_SetInitialValue (Method)
This method may be called at startup if the user desires a value different than
the defaultOutput (set previously in the constructor method call) as the initial
output.

Inputs

Name IEC 61131 Type Description

initialValue REAL Range: lowLimit ≤ initialValue ≤ highLimit. Sets the initial value to
be used by the filter at startup.

Return Value

IEC 61131 Type Description

POINTER TO STRING Return a pointer to an error message if an error occurred. Return zero if no errors exist.

Processing
This method:

➤ Bypasses all internal filtering and changes both the input and conditioned
output to be equal to initialValue.
➤ Returns a pointer to an error message if the constructor has not been
called.
➤ Returns a pointer to an error message if initialValue is less than lowLimit
or greater than highLimit set in the constructor.

Processing of Interface Methods


This section provides specifics regarding the implementation of the methods
required by the implemented interface(s).

Date Code 20241023 Programming Reference


56 AnalogConditioning
Classes

I_LimitedSplpf—ConditionValue
This describes the behavior of this class when the ConditionValue() method
is called.

➤ When the constructor has not yet been called, then this method returns
FALSE and sets the method output conditionedValue to zero (0).
➤ The time between calls is limited to a minimum of 1 ms and a
maximum of 60000 ms. This section references the limited value as
timeElapsedLimited.
➤ The time constant used in calculating the output value,
timeConstantUsed, is limited such that it must exceed or equal five times
the elapsed time between calls of this method, timeElapsed.
➤ When the inputValue is less than lowLimit, set in the constructor, then the
input is limited to lowLimit and the out-of-bounds internal flag is set.
➤ When inputValue exceeds highLimit, set in the constructor, then the input
is limited to highLimit and the out-of-bounds internal flag is set.
➤ When inputValue is within the limits outlined in the constructor, the input
is filtered through a low-pass filter in order to provide the output and the
out-of-bounds internal flag is reset.
➤ When all of the following conditions are met:
➢ inputValue is less than highLimit
➢ inputValue is greater than the lowLimit
➢ Alarm property is false
this method computes the conditionedValue output equivalent to:
((inputValue – lastConditionedValue) • 0.632 • •
timeElapsedLimited) + lastConditionedValue
where:
➢ inputValue is the current input to ConditionValue()
➢ lastConditionedValue is the input to ConditionValue() from the
previous scan
➢ timeConstantUsed is the range limited time constant
➢ timeElapsedLimited is the range limited elapsed time since the last
scan
➤ When the input is out of range, it is limited to the corresponding range
value, and on a subsequent call where the input is within the specified
range, the conditioned output ramps to that value from the limit where it
was being held.
➤ When the input is in alarm, the input is overridden and set to
defaultOutput. This allows the output value to ramp to defaultOutput
through the filter. Once the alarm is removed, the input is no longer
overridden and the output value ramps to the input value through the
filter, i.e., ramps to defaultOutput through the filter when in alarm and
ramps from defaultOutput back to inputValue after the alarm is removed.

Programming Reference Date Code 20241023


AnalogConditioning 57
Benchmarks

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms:
➤ SEL-3530
➢ R134 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V1 firmware
➤ SEL-3505
➢ R134 firmware

Benchmark Test Descriptions


Any time less than one microsecond was rounded up to one microsecond for this
report.

class_LimitedSplpfStepToDefault—ConditionValue
The posted time is the average execution time of 100 consecutive calls.

class_LimitedSplpfRampToDefault—ConditionValue
The posted time is the average execution time of 100 consecutive calls.

class_ArmaFilter—ConditionValue
The posted time is the average execution time of 100 consecutive calls.

class_ArmaFilter_LREAL—ConditionValue
The posted time is the average execution time of 100 consecutive calls.

class_PassThroughFilter—ConditionValue
The posted time is the average execution time of 100 consecutive calls.

Benchmark Results
ConditionValue Timing Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

class_LimitedSplpfStepToDefault 15 11 2

class_LimitedSplpfRampToDefault 17 5 1

Date Code 20241023 Programming Reference


58 AnalogConditioning
Examples

Platform (time in μs)


Operation Tested
SEL-3505 SEL-3530 SEL-3555

class_ArmaFilter 1 1 1

class_ArmaFilter_LREAL 1 1 1

class_PassThroughFilter 1 1 1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Filtering With class_LimitedSplpfStepToDefault


The example code shown in Code Snippet 3.1 demonstrates a very simple use of
this library. This code instantiates a simple filter with the following attributes:

1. The filter output has a range of 0–100 inclusive.


2. If the filter input goes out of range or the Alarm property is set, the output
steps to the default value of 50.
3. The filter time constant is 1000 ms.
4. The filter has an initial value of zero.

This code filters rawValue normally for 100 time steps. After 100 time steps,
Alarm is set to true.
Code Snippet 3.1 prg_FilterStepToDefault
PROGRAM prg_FilterStepToDefault
VAR
initialized : BOOL := FALSE;
filter : class_LimitedSplpfStepToDefault;
rawValue : REAL := 75;
filteredValue : REAL;
step : UINT;
END_VAR

IF NOT initialized THEN // Only initialize the filter once.


// Initialize the filter with a range of 0-100, a default output
// of 50, and a time constant of 1000 ms.
filter.LimitedSplpfStepToDefault(highLimit := 100, lowLimit := 0,
defaultOutput := 50, timeConstant := 1000);
// Start the filter with an initial value of zero.
filter.bootstrap_SetInitialValue(0);
initialized := TRUE;
END_IF

IF step < 100 THEN


// Filter normally for 100 time steps.
filter.ConditionValue(rawValue, conditionedValue => filteredValue);
step := step + 1;
ELSE
// After 100 time steps, set the Alarm property.
filter.Alarm := TRUE;

Programming Reference Date Code 20241023


AnalogConditioning 59
Examples

filter.ConditionValue(rawValue, conditionedValue => filteredValue);


END_IF

When this code is executed, the filteredValue will start at zero and move towards
the input value of 75 with each time step, according to the filter and time
constant. After 100 time steps, the output steps directly to the default value of 50
because the Alarm property was set. Figure 3.2 shows an example of the filtered
output plotted against time, where each step is 100 ms.

Figure 3.2 class_LimitedSplpfStepToDefault With a Time Constant of 1000 ms

Filtering With class_LimitedSplpfRampToDefault


The example code shown in Code Snippet 3.2 demonstrates a simple use of this
library. This code instantiates a simple filter with the following attributes:

1. The filter output has a range of 0–100 inclusive.


2. If the filter input goes out of range or the Alarm property is set, the output
will ramp to the default value of 50.
3. The filter time constant is 1000 ms.
4. The filter has an initial value of zero.

This code filters rawValue normally for 100 time steps. After 100 time steps,
Alarm is set to true.
Code Snippet 3.2 prg_FilterRampToDefault
PROGRAM prg_FilterRampToDefault
VAR
initialized : BOOL := FALSE;
filter : class_LimitedSplpfRampToDefault;
rawValue : REAL := 75;
filteredValue : REAL;
step : UINT;
END_VAR

Date Code 20241023 Programming Reference


60 AnalogConditioning
Examples

IF NOT initialized THEN // Only initialize the filter once.


// Initialize the filter with a range of 0-100, a default output
// of 50, and a time constant of 1000 ms.
filter.LimitedSplpfRampToDefault(highLimit := 100,
lowLimit := 0,
defaultOutput := 50, timeConstant := 1000);
// Start the filter with an initial value of zero.
filter.bootstrap_SetInitialValue(0);
initialized := TRUE;
END_IF

IF step < 100 THEN


// Filter normally for 100 time steps.
filter.ConditionValue(rawValue, conditionedValue => filteredValue);
step := step + 1;
ELSE
// After 100 time steps, set the Alarm property.
filter.Alarm := TRUE;
filter.ConditionValue(rawValue, conditionedValue => filteredValue);
END_IF

When this code is executed, the filteredValue will start at zero and move towards
the input value of 75 with each time step, according to the filter and time
constant. After 100 time steps, the output ramps to the default value of 50
because the Alarm property was set. Figure 3.3 shows an example of the filtered
output plotted against time, where each step is 100 ms.

Figure 3.3 class_LimitedSplpfRampToDefault With a Time Constant of 1000


ms

Filtering With class_ArmaFilter


The ARMA filter is best suited to filtering oscillating signals, and depending on
the coefficients used, provides a high-pass, low-pass, band-pass, or band-stop
filter. This example shows a specific implementation of the ARMA filter, but
the basic approach described is general, and can be used to provide whatever
filtering the user of this library requires.

Programming Reference Date Code 20241023


AnalogConditioning 61
Examples

Objective
An oscillating signal can be run through a low-pass filter to remove high-
frequency noise, leaving only the lower frequency signals of interest.

Assumptions
The signal provided to the filter is generated in IEC 61131 code by adding a
high-frequency component, a low-frequency component, and a mid-frequency
component. This signal is then sent through an ARMA filter, with coefficients
set using the Butterworth method to remove the high-frequency component,
leaving the mid- and low-range frequencies.
The signal sent to the filter is comprised using the following equations:

Sample1n = 0.25 x COS((1/10) x 2πn)

Sample2n = 2 x SIN((1/100) x 2πn)

Sample3n = SIN((1/1000) x 2πn)

where n is the sample number.


These equations will provide one sample each time n is increased, and these
discrete samples are described as follows:

Sample1n will have a period of 10 samples (high-frequency), a ratio


of 0.1, be offset by 90 degrees from the other two waves and a magnitude of
1/8 of the primary frequency.
Sample2n is the primary frequency. It will have a period of 100 samples
(mid-frequency) and a ratio of 0.01.

Sample3n will have a period of 1000 samples (low-frequency), a


ratio of 0.001 and a magnitude that is half of the primary frequency.
The sum of these three sine waves is fed into the low-pass filter.

FilterInputn = Sample1n + Sample2n + Sample3n

Solution
Coefficients for a Butterworth low-pass filter (http://octave.sourceforge.net/
signal/function/butter.html), which will filter out the high-frequency noise
with a filter depth of three (3), are determined using OCTAVE (http://octave-
online.net/), by entering the equation defined in Code Snippet 3.3.
Code Snippet 3.3 OCTAVE Code to Design a Butterworth Filter
octave:1>[B,A] = butter(3, 0.05)
B =
4.1655 e -04 1.2496 e -03 1.2496 e -03 4.1655 e -04

A =
1.00000 –2.68616 2.41966 –0.73017

The number of coefficients required for a low-pass filter with depth three (3) is
four (4), so the global parameter g_p_MaxFilterOrder must be set to three (3) or
greater, allowing coefficients 0–3 to be provided.

Date Code 20241023 Programming Reference


62 AnalogConditioning
Examples

NOTE
An unstable filter will not cause the filter to crash, but it will cause the filtered
output to become Infinity. Because of the way the ARMA model is constructed,
the next output after infinity is reached will be NaN (Not a Number). Once this
happens, all future outputs of the filter will be NaN until the filter is reset.

This Butterworth filter is shown to be stable by checking that the roots of the
A coefficients have an absolute value less than 1. This can be done using the
OCTAVE code shown in Code Snippet 3.4.
Code Snippet 3.4 OCTAVE Code to Check Stability of Filter
octave:1> abs(roots([1.00000 -2.68616 2.41966 –0.73017]))
ans =
0.92455
0.92455
0.85420

The program shown in Code Snippet 3.5 generates the signals, passes the sum of
these signals into the low-pass filter, and provides the outputs into an array.
Code Snippet 3.5 prg_LowpassFilterDemo
PROGRAM prg_LowPassFilterDemo
VAR CONSTANT
c_Steps : UDINT := 1000;
c_Acoeff : ARRAY[1..g_p_MaxFilterOrder] OF REAL :=
[-2.68616, 2.41966, -0.73017];
c_Bcoeff : ARRAY[0..g_p_MaxFilterOrder] OF REAL :=
[4.1655e-04, 1.2496e-03, 1.2496e-03, 4.1655e-04];
END_VAR
VAR
Filter : class_ArmaFilter(c_Acoeff, c_Bcoeff, 3, 4);
Signals : ARRAY[1..3] OF ARRAY[1..c_Steps] OF REAL;
DesiredSignals : ARRAY[1..c_Steps] OF REAL;
TotalSignal : ARRAY[1..c_Steps] OF REAL;
FilterOutput : ARRAY[1..c_Steps] OF REAL;
Stage : UDINT := 0;
END_VAR
VAR_TEMP
i : UDINT;
END_VAR

CASE Stage OF
0:
;// Do nothing on the first scan
1:
FOR i := 1 TO c_Steps DO
(* Calculate the samples used to create a compound signal *)
Signals[1][i] := 0.25 * COS(0.1*UDINT_TO_REAL(i)*2*PI);
Signals[2][i] := 2 * SIN(0.01*UDINT_TO_REAL(i)*2*PI);
Signals[3][i] := SIN(0.001*UDINT_TO_REAL(i)*2*PI);

(* Add the low and mid frequency components together to compare


against filtered output for accuracy. *)
DesiredSignals[i] := Signals[2][i] + Signals[3][i];

(* Add the high-frequency component to this signal to observe that


the Butterworth low-pass filter removes it, leaving just
the desired signal. *)
TotalSignal[i] := DesiredSignals[i] + Signals[1][i];

(* Pass the entire signal into the filter. *)


Filter.ConditionValue(TotalSignal[i],
conditionedValue => FilterOutput[i]);
END_FOR
2:
;// Add a way to print out the results to a file here if desired

Programming Reference Date Code 20241023


AnalogConditioning 63
Examples

ELSE
;// Done
END_CASE
Stage := Stage + 1;

When this code is executed, the low-pass filter removes the high-frequency
components imposed on the samples, leaving the desired Sample2n and
Sample3n low-frequency components alone.

The plot in Figure 3.4 shows the three waveforms added together and the result
of the filter. The resulting wave is shifted in time; this time delay is expected
from a filter.

Figure 3.4 Plot of Total Signal and Filtered Output of the Low-Pass Filter

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 4

ChannelMonitoring
Introduction
This library provides function blocks for performing data channel processing
and supervision. The function blocks provide an alert that some aspect of a
channel or indicator has deviated from the parameters defined by the user.
Example applications include detecting maintenance conditions in a 3-phase CT/
PT, alerting on an IED hardware failure, monitoring transformer through-fault
current, or detecting protection communication channel failures.
The fb_MultiChannelAlert, fb_ChannelAlert, and fb_IndicatorAlert blocks
focus on channel supervision. Each adheres to the same principles of operation.
An alert is generated when a sustained excursion occurs or when repeated
excursions are detected. An excursion is defined as a channel, indicator, or
function block output exceeding the threshold limit. For function blocks that
accept a Boolean data type input, an excursion begins with a transition from a
FALSE to TRUE state. For function blocks that accept measured values (MV)
or REAL data type inputs, the absolute difference is calculated between the
instantaneous values of two channels or a channel and a reference value. An
excursion in this context is when the absolute difference exceeds a threshold
value. The excursion time is used to define when an alert occurs. If a single
excursion is sustained for a length of time defined by the excursion time, an alert
is generated (Figure 4.1 and Figure 4.2). If multiple excursions are detected
equal to the chatter count within the excursion time, an alert is generated
(Figure 4.3 and Figure 4.4).
Each function block can be used to provide simple alerting or can be combined
into more complex monitoring schemes.

Figure 4.1 An Excursion Defined by the Absolute Channel Difference Equaling


or Exceeding the Threshold Value for the Excursion Time Generates an Alert

Figure 4.2 An Excursion Defined by the Indicator Equaling a TRUE Value for
the Excursion Time Generates an Alert

Date Code 20241023 Programming Reference


66 ChannelMonitoring
Supported Firmware Versions

Figure 4.3 Multiple Excursions Defined by the Absolute Channel Difference


Equaling or Exceeding the Threshold Value Within the Excursion Time Generates
an Alert (Chatter Count = 3)

Figure 4.4 Multiple Excursion Defined by the Indicator Equaling a TRUE Value
Within the Excursion Time Generates an Alert (Chatter Count = 3)

Special Considerations
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).
➤ Copying classes from this library causes unwanted behavior. This means
the following:

1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_fb_MultiChannelAlertObject"
myfb_MultiChannelAlertObject :=
otherfb_MultiChannelAlertObject;

// This is fine
someVariable := myfb_MultiChannelAlertObject.value;
// As is this
pt_myfb_MultiChannelAlertObject :=
ADR(myfb_MultiChannelAlertObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.0.0 and earlier can be used on RTAC firmware version R132 and
later.

Programming Reference Date Code 20241023


ChannelMonitoring 67
Enumerations

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_AlertType
This enumeration defines the type of events returned by the function block status
output. This enumeration can be used interchangeably with DINT data types.

Enumeration Value Description

NO_DEVIATION 0 No alerts detected

CHATTER 1 Multiple excursions occurred within the


excursion time

EXPIRATION 2 A sustained excursion equaled or exceeded the


excursion time

EXCURSION 3 An instantaneous excursion. Used where


ExcursionTime input is not applicable.

BAD_QUALITY 4 Minimum number of inputs do not have good


quality

RESET 5 Reset input is currently asserted

ERROR 6 Function block was unable to activate because


of limited memory resources

COMPLETE 7 Operation complete

enum_ChannelAlert
This enumeration is used to define the channels responsible for a status alert
and/or quality alert. This enumeration can be used interchangeably with DINT
data types.

Enumeration Value Description

NO_ALERTS 0 No alerts detected

CHANNEL_1_ALERT 1 Channel 1 is the responsible channel

CHANNEL_2_ALERT 2 Channel 2 is the responsible channel

CHANNEL_1_2_ALERT 3 Channel 1 and 2 are the responsible channels

CHANNEL_3_ALERT 4 Channel 3 is the responsible channel

CHANNEL_1_3_ALERT 5 Channel 1 and 3 are the responsible channels

CHANNEL_2_3_ALERT 6 Channel 2 and 3 are the responsible channels

MULTIPLE_CHANNEL_ALERT 7 All available channels are responsible

Date Code 20241023 Programming Reference


68 ChannelMonitoring
Functions

Functions
fun_GetAlertString
This function takes the status returned by the function blocks in this library as an
input and returns a string value that can be used for logging.

Inputs
Name IEC 61131 Type Description

alert enum_AlertType Function block status value

Return Value
IEC 61131 Type Description

STRING Value matching the enum_AlertType

Processing
➤ If the status is valid, the function returns a string corresponding to the
enum_AlertType.
➤ If the supplied status is not valid, the function returns Invalid Input.

fun_GetChannelString
This function takes as an input the alert returned by the fb_MultiChannel
function block and returns a string value that can be used for logging.

Inputs
Name IEC 61131 Type Description

status enum_ChannelAlert Function block alert value

Return Value
IEC 61131 Type Description

STRING String value matching the enum_ChannelAlert

Processing
➤ If status is valid, the function returns a string corresponding to the
enum_ChannelAlert.
➤ If the supplied status is not valid, the function returns Invalid Input.

Programming Reference Date Code 20241023


ChannelMonitoring 69
Function Blocks

Function Blocks
fb_MultiChannelAlert
Compare two to three measured value (MV) tags to determine if one or more
channels deviate outside a threshold value for a time period or if repeated
deviations occur within a time period. This function block requires a minimum
of two input channels.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable the function block

Channel_1 MV Data to monitor

Channel_2 MV Data to monitor

Channel_3 MV Data to monitor

ExcursionThreshold REAL Limit at which a deviation is detected

ChatterCount UDINT Number of deviations allowed within a time period defined by the
ExcursionTime

ExcursionTime TIME Maximum time a sustained deviation is allowed

LatchAlarm BOOL Defaults to true. If true, Alert will stay asserted until Reset is
asserted.

Reset BOOL Reset function block to default conditions

Outputs
Name IEC 61131 Type Description

ENO BOOL Indication that the function block is enabled

Alert SPS Alert condition and associated metadata

Status enum_AlertType Enumeration describing the function block state

ChannelStatus enum_ChannelAlert Enumeration describing the channels that generated the status alert

QualityAlert BOOL Channel quality alert

QualityStatus enum_ChannelAlert Enumeration describing the channels that generated the quality
alert

Processing
➤ ChatterCount, ExcursionTime, and LatchAlarm are set the first time the
function block is called. They cannot be altered after that time.
➤ On a rising edge of ENO, the tracked chatter count and excursion time are
reset to zero.
➤ Disabling the function block by setting EN to FALSE does not clear the
function block Alert.
➤ When ENO is FALSE or Reset is TRUE, the Alert SPS quality is invalid.

Date Code 20241023 Programming Reference


70 ChannelMonitoring
Function Blocks

➤ The function block adheres to the following processing if ENO is TRUE.


➤ Good channel quality is required for input processing. This
is determined by the input channel validity_t structure, i.e.,
AnalogQuantity.q.validity = good.
➤ If a channel has bad quality, it is excluded from the excursion calculations
and a QualityAlert is generated.
➤ Compare the instantaneous values of the input channels to determine if
any channel deviates from any other available channel.
➤ If a QualityAlert is generated, the QualityStatus reports the offending
channels as described in enum_ChannelAlert.
➤ If the minimum number of channels do not have good quality, Status is
BAD_QUALITY as defined in the enum_AlertType.
➤ If a channel deviates by more than ExcursionThreshold from any other
channel for a sustained period given by ExcursionTime, an Alert is
generated.
➤ If a channel repeatedly deviates by more than ExcursionThreshold from
any other channel and the number of deviations exceeds ChatterCount
within a period given by ExcursionTime, an Alert is generated.
➤ If Alert is asserted, Status identifies the cause of the alert as described in
enum_ AlertType.
➤ If an Alert is generated, ChannelStatus identifies the offending channels
as described in enum_ChannelAlert.
➤ IF LatchAlarm is TRUE the outputs are fixed when an alert condition is
detected and will be held constant until a Reset is issued.
➤ If Reset is asserted, the function block does not process any inputs and
Status is RESET as defined in enum_AlertType.
➤ A falling edge of Reset returns the function block to a default state.

fb_ChannelAlert
Compare one measured value (MV) tag against a reference value to determine
if the channel deviates outside a threshold value for a time period or if repeated
deviations occur within a time period.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable the function block

Channel MV Data to monitor

ChannelReference REAL Channel reference value

ExcursionThreshold REAL Limit at which a deviation is detected

ChatterCount UDINT Number of deviations allowed within a time period defined by the
ExcursionTime

ExcursionTime TIME Maximum time a sustained deviation is allowed

LatchAlarm BOOL Defaults to true. If true, Alert will stay asserted until Reset is
asserted

Reset BOOL Reset function block to default conditions

Programming Reference Date Code 20241023


ChannelMonitoring 71
Function Blocks

Outputs
Name IEC 61131 Type Description

ENO BOOL Indication that the function block is enabled

Alert SPS Alert condition and associated metadata

Status enum_AlertType Enumeration describing the function block state

QualityAlert BOOL Channel quality alert

Processing
➤ ChatterCount, ExcursionTime, and LatchAlarm are set the first time the
function block is called. They cannot be altered after that time.
➤ On a rising edge of ENO, the tracked chatter count and excursion time are
reset to zero.
➤ Disabling the function block by setting EN to FALSE does not clear the
function block Alert.
➤ When ENO is FALSE or Reset is TRUE, the Alert SPS quality reports as
invalid.
➤ The function block adheres to the following processing if ENO is TRUE.
➤ Good channel quality is required for input processing. This
is determined by the input channel validity_t structure, i.e.,
AnalogQuantity.q.validity = good.
➤ If Channel has bad quality, no excursion calculation occurs and
QualityAlert is asserted.
➤ Compare the instantaneous values of Channel and ChannelReference to
determine if an excursion occurred.
➤ If QualityAlert is asserted, Status is BAD_QUALITY, as defined in the
enum_AlertType.
➤ If Channel deviates by more than ExcursionThreshold from the reference
for a sustained period given by ExcursionTime, an Alert is generated.
➤ If Channel repeatedly deviates from the reference by more than
ExcursionThreshold and the number of deviations exceeds ChatterCount
within a period given by ExcursionTime, an Alert is generated.
➤ If Alert is asserted, Status identifies the cause of the alert as described in
enum_AlertType.
➤ IF LatchAlarm is TRUE the outputs are fixed when an alert condition is
detected and will be held constant until a Reset is issued.
➤ If Reset is asserted, the function block does not process any inputs and
Status is RESET as defined in enum_AlertType.
➤ A falling edge of Reset returns the function block to a default state.

fb_IndicatorAlert
Monitors one Boolean value for a sustained or chattering TRUE value.

Date Code 20241023 Programming Reference


72 ChannelMonitoring
Function Blocks

Inputs
Name IEC 61131 Type Description

EN BOOL Enable the function block

Indicator BOOL Data to monitor

ChatterCount UDINT Number of deviations allowed within a time period defined by the
ExcursionTime

ExcursionTime TIME Maximum time a sustained deviation is allowed

Reset BOOL Reset function block to default conditions

Outputs
Name IEC 61131 Type Description

ENO BOOL Indication that the function block is enabled

Alert SPS Alert condition and associated metadata

Status enum_AlertType Enumeration describing the function block state

Processing
➤ ChatterCount and ExcursionTime are set the first time the function block
is called. They cannot be altered after that time.
➤ On a rising edge of ENO, the tracked chatter count and excursion time are
reset to zero.
➤ Disabling the function block by setting EN to FALSE does not clear the
function block Alert.
➤ When ENO is FALSE or Reset is TRUE and an alert condition is not
detected, the Alert SPS quality is invalid.
➤ The function block adheres to the following processing if ENO is TRUE.
➤ Monitor Indicator for a TRUE value.
➤ If Indicator is TRUE for a sustained period given by ExcursionTime, an
alert is generated.
➤ If Indicator repeatedly switches between FALSE and TRUE and the
number of deviations exceed ChatterCount within a period given by
ExcursionTime, an Alert is generated.
➤ If Alert is asserted, Status identifies the cause of the alert as described in
enum_AlertType.
➤ Once an Alert is generated, the function block maintains its state at the
time of the alert until issued a reset.
➤ If Reset is asserted, the function block does not process any inputs and
Status is RESET as defined in enum_AlertType.
➤ A falling edge of Reset returns the function block to a default state.

Programming Reference Date Code 20241023


ChannelMonitoring 73
Function Blocks

fb_ChannelDerivative
Calculates the time derivative (rate-of-change) of a channel using finite
difference approximation and alerts upon excursion beyond a user-settable
threshold.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable the function block

Reset BOOL Reset function block to a default state

Channel MV Input signal to differentiate

DerivativeThreshold REAL Threshold, over which the absolute value of Derivative will assert
Alert. Must be greater than or equal to 0.

PeriodicProcessing BOOL Set to TRUE to process Channel on a fixed interval. Set to FALSE
to process Channel based on changes in the Channel time stamp.

Period TIME Channel evaluation period when PeriodicProcessing = TRUE.


Should be greater than or equal to and equally divisible by the
RTAC task time.

FilterLength INT The number of calculated derivatives to be averaged in order to


update the Derivative output. Can be any odd integer between 1
and 21.

Outputs
Name IEC 61131 Type Description

ENO BOOL Indication that the function block is enabled

Alert SPS Indication of derivative excursion beyond threshold

Status enum_AlertType Enumeration describing the function block state

QualityAlert BOOL Channel quality alert

Derivative MV Average derivative of Channel over ConditionedFilterLength


+ 1 Channel samples

ConditionedFilterLength INT Adjusted FilterLength to ensure the filter length used is an odd
number bounded by 1 and 21.

Processing
➤ The Derivative output is given in units of X per second where X is the
units of the Channel.instMag input.
➤ PeriodicProcessing and FilterLength are set the first time the function
block is called, regardless of the state of the EN input. They cannot be
altered after that time.
➤ ENO is true when EN = TRUE and the function block initialization is
completed successfully.
➤ Successful function block initialization is dependent on user input
validation. If the function block fails to initialize, Status is set to ERROR.

Date Code 20241023 Programming Reference


74 ChannelMonitoring
Function Blocks

➤ If DerivativeThreshold represents a floating point value of NAN, Inf, or


-Inf when the function block is first called, the function block fails to
initialize.
➤ Disabling the function block by setting EN to FALSE does not clear the
Alert function block output variable.
➤ While the Reset input is asserted, all internal variables and outputs are set
to a default value. The Status output is set to RESET.
➤ When EN is FALSE or Reset is TRUE, the Alert SPS quality is invalid.
➤ If the State output equals EXCURSION, Channel is not processed. The
outputs are held at their current state until a rising edge of the Reset input
is detected.
➤ The FilterLength input is evaluated against the requirements specified in
the Inputs table. If FilterLength does not conform to the requirements,
ConditionedFilterLength becomes a bounded version of FilterLength and
is used for processing the Channel input.
➤ For PeriodicProcessing = FALSE, Channel processing is triggered
by changes in the Channel.t.value time stamp. For this mode, the
incremental derivative is defined as the change in Channel.instMag
divided by the change in the Channel.t.value time stamp between the
current Channel sample (k) and previously processed Channel sample
(k - 1). The incremental derivative is assigned a time stamp equal to
the k sample t.value time stamp. This mode can be useful for real-time
streaming data sources such as IEEE C37.118 synchrophasors or off-line
processing of data sets containing time-stamped samples.
➤ For PeriodicProcessing = TRUE, the Channel state is evaluated
periodically at the interval specified by the Period input. The timer runs
while EN = TRUE AND Reset = FALSE. In this mode, the incremental
derivative is defined as the change in Channel.instMag between the
k and k - 1 samples divided by the Period input. The incremental
derivative is assigned a time stamp equal to the RTAC system time of
processing the k sample. This mode can be useful for real-time processing
of deadbanded data sources where no Channel update is meant to be
interpreted as a derivative of zero. When using this mode, the applied
Period setting should be greater than or equal to, and equally divisible by,
the RTAC task time.
➤ The function block maintains a buffer of the ConditionedFilterLength
most recent incremental derivative results. The Derivative output
represents the average of the buffered results. The Derivative
output updates only when the buffer is full. The buffer is full once
ConditionedFilterLength plus one Channel samples are processed.
➤ While EN = FALSE, Channel is not processed. The cached k – 1
sample is not updated.
➤ While Channel.instMag represents a floating point value of NAN, Inf, or
–Inf, Channel is not processed. The Status is set to ERROR. The cached k
- 1 sample is not updated.
➤ Negative time-stamp differences between consecutive Channel samples
are ignored when PeriodicProcessing = FALSE. Channel is not
processed. However, the cached k - 1 sample is updated to avoid a
negative calculated sample interval on the next incremental derivative
calculation. Status equals ERROR until a positive time-stamp difference is
detected or Reset is asserted.

Programming Reference Date Code 20241023


ChannelMonitoring 75
Function Blocks

➤ While Channel is not being processed, the output Derivative value and
time stamp are held at the last calculated result.
➤ As previously noted, Channel is not processed when EN = FALSE,
Channel.instMag represents an invalid REAL quantity, or when a
negative time-stamp difference is detected while PeriodicProcessing
= FALSE. However, the buffer is not cleared in these cases. The next
Channel sample that is processed causes the buffer to be updated
with the derivative between the current sample and the cached k
- 1 sample. While the resultant Derivative update in this case still
represents the average derivative over ConditionedFilterLength plus
one samples, it may not accurately portray the average derivative over
ConditionedFilterLength plus one expected sample intervals. It is the
responsibility of the user to clear the buffer by asserting Reset if Channel
processing is inhibited for a duration deemed unacceptable.
➤ The output Derivative.t structure is set equal to the time stamp of the
incremental derivative result at the center position of the buffer. This is
done for derivative approximation accuracy.
➤ The output Derivative is assigned a quality that represents the lowest
quality indicators of all Channel samples processed in the calculation of
the output derivative value.
➤ If the Derivative.q.validity does not equal good then the output
QualityAlert is asserted.
➤ If the absolute value of the output Derivative.instMag exceeds
the absolute value of DerivativeThreshold, Alert.stVal is asserted.
Alert.t is set equal to the RTAC system time. Status is set to
EXCURSION.

fb_ChannelIntegral
Calculates the area under the input channel magnitude and above a user-defined
integration bound using trapezoidal approximation between samples.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable the function block

Reset BOOL Reset the function block to default conditions

Channel MV Signal to integrate

SetPoint REAL Channel threshold used to initiate integration.

PeriodicProcessing BOOL Set to TRUE to process Channel on a fixed interval. Set to FALSE
to process Channel based on changes in the Channel time stamp.

Period TIME Channel evaluation period when PeriodicProcessing = TRUE.


Should be greater than or equal to and equally divisible by the
RTAC task time.

LowerBound REAL Lower bound used in calculation of Integral. Must be less than or
equal to SetPoint.

DebounceTime TIME Time required for channel to be above or below SetPoint in order
for the associated SetPoint excursion time to be considered the
beginning or end of an integration period.

Date Code 20241023 Programming Reference


76 ChannelMonitoring
Function Blocks

Outputs
Name IEC 61131 Type Description

ENO BOOL Indication that the function block is enabled

Alert SPS Indication of a completed integration period

Status enum_AlertType Enumeration describing the function block state

QualityAlert BOOL Asserts when channel quality is bad or integral output accuracy is
suspect

ExcursionTimeOn dateTime_t Time stamp marking the start of an integration period

ExcursionTimeOff dateTime_t Time stamp marking the end of an integration period

Integral MV The integral of Channel below Channel.instMag and


above LowerBound, bounded by ExcursionTimeOn and
ExcursionTimeOff

Peak MV Peak value of Channel between ExcursionTimeOn and


ExcursionTimeOff

Processing
➤ The Integral output is given in units of X*seconds where X is the units
of the Channel.instMag input.
➤ Period and PeriodicProcessing are set the first time the function block is
called, regardless of the state of the EN input. They cannot be altered after
that time.
➤ ENO is true when EN = TRUE and the function block initialization is
completed successfully.
➤ Successful function block initialization is dependent on user input
validation. If the function block fails to initialize, Status is set to ERROR.
➤ If any of the following conditions are true during the first call of the
function block, the function block fails to initialize.
➢ SetPoint represents a floating point value of NAN, Inf, or -Inf.
➢ LowerBound represents a floating point value of NAN, Inf, or -Inf or is
a defined number greater than SetPoint.
➢ PeriodicProcessing = TRUE and Period is less than or equal to
zero.
➢ DebounceTime is less than zero.
➤ All inputs other than Period and PeriodicProcessing can be modified
during runtime. However, SetPoint, LowerBound, and DebounceTime are
held static while State = EXCURSION or EXPIRATION. While not
held static, these inputs shall be validated against the previously stated
conditions.
➤ While Channel.instMag represents a floating point value of NAN,
Inf, or -Inf or any variable input is deemed invalid, the Status is set to
ERROR. The cached k - 1 sample is not updated.
➤ Deasserting EN during integration will pause integration calculations.
Outputs will retain their state and the cached k - 1 sample will be
discarded. Re-asserting EN will resume integration using newly received
data.

Programming Reference Date Code 20241023


ChannelMonitoring 77
Function Blocks

➤ While Reset is TRUE, Alert.q.validity, Integral.q.validity,


and Peak.q.validity are set to invalid.
➤ While the Reset input is asserted, all outputs are reset to default values.
The Status output is set to RESET. A falling edge of the Reset input
returns Status to NO_DEVIATION.
➤ While Alert.stVal = TRUE and Status is COMPLETE, the function
block halts data processing. Outputs are frozen until Reset is asserted.
➤ The function block adheres to the following processing if ENO is TRUE
and Status is not COMPLETE.
➤ For PeriodicProcessing = FALSE, Channel processing is triggered
by changes in the Channel.t.value time stamp. This mode can be
useful for real-time streaming data sources such as IEEE C37.118
synchrophasors or off-line processing of data sets containing time-
stamped samples.
➤ For PeriodicProcessing = TRUE, the Channel state is evaluated
periodically at the interval specified by the Period input. The timer
runs while EN = TRUE AND Reset = FALSE. In this mode, the input
Channel is assigned time stamps from the RTAC system clock. This
mode can be useful for real-time processing of deadbanded data sources
where no time-stamp update is meant to be interpreted as a repeated
value. When PeriodicProcessing = TRUE, the applied Period setting
should be greater than and equally divisible by the RTAC task time.
➤ The incremental update to the Integral output is defined as the area of
the trapezoid bound by the following two points and the line defined by
LowerBound:
➢ Channel.instMag at Channel.t time for the most recently
processed sample (k).
➢ Channel.instMag at the Channel.t time for the previously
processed sample (k - 1).
➤ Negative time-stamp differences between consecutive Channel samples
are ignored. In this scenario, the Channel sample is not used in the
integral approximation. However, the cached k - 1 sample is updated
to avoid a negative calculated sample interval on the next incremental
update to the Integral output. Status equals ERROR until a positive time-
stamp difference is detected or Reset is asserted.
➤ The integration period begins when Channel.instMag is in excess of
SetPoint. At this time Status is set to EXCURSION.
➤ Channel.instMag must exceed SetPoint for a minimum time equal to
DebounceTime in order for integration to complete.
➤ If Channel.instMag is in excess of SetPoint, but becomes equal to or
less than SetPoint before DebounceTime is reached, the function block is
reset on the first task cycle for which Channel.instMag is not in excess
of SetPoint.
➤ If Channel.instMag exceeds SetPoint for a duration equal to
DebounceTime, Status is set to EXPIRATION and ExcursionTimeOn is
assigned as described below.
➤ While Status is set to EXPIRATION integration will continue
until Channel.instMag falls below SetPoint for time equal to
DebounceTime.

Date Code 20241023 Programming Reference


78 ChannelMonitoring
Function Blocks

➤ If the preceding debounce time condition is met, Alert.stVal asserts,


Alert.t.value is set equal to the RTAC system time. Status is set to
COMPLETE and ExcursionTimeOff is assigned as described below.
➤ ExcursionTimeOn and ExcursionTimeOff, respectively, are assigned a
derived time stamp that is between the time stamp values associated
with the two processed Channel samples that straddle SetPoint. More
specifically, this time stamp coincides with the intersection of the line
drawn between the .instMag values of these two samples and SetPoint.
➤ Integral.t.value is set equal to ExcursionTimeOn and will not be
updated until the function block is reset.
➤ The Integral output represents the area under Channel.instMag and
over LowerBound between ExcursionTimeOn and ExcursionTimeOff as
shown in Equation 4.1.

Equation 4.1

where ChannelProcess(t) is the physical process being measured and


represented by Channel.instMag measurements.
➤ The function block updates the Integral output continuously during the
integration period. This enables external evaluation the current integral
result against an auxiliary excursion threshold.
➤ The Peak output contains the magnitude, quality and time-stamp
information from the Channel sample in which Channel.instMag was
at a maximum value over the integration period. For repeated maximums,
the most recent maximum Channel value is applied to Peak.
➤ During integration, the Integral output is assigned a quality that
represents the lowest quality indicators of all Channel samples used in the
integration calculation.
➤ If the Integral.q.validity does not equal good then the output
QualityAlert is asserted.
➤ If Channel.instMag is already in excess of SetPoint when EN is
asserted or after a manual reset, ExcursionTimeOn is assigned the time
stamp of the first processed Channel sample. This time stamp is not
expected to represent the approximate time of SetPoint crossing. In this
instance, the output QualityAlert is asserted.

fb_IndicatorTimeDelta
Monitors the time-stamp difference between the assertions of two Single Point
Status (SPS) indicators and alerts upon time-difference excursion beyond a user-
defined threshold.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable the function block

Reset BOOL Reset the function block to default conditions

Indicator1 SPS Indicator anticipated to assert first

Programming Reference Date Code 20241023


ChannelMonitoring 79
Function Blocks

Name IEC 61131 Type Description

Indicator2 SPS Indicator anticipated to assert second

TimeDiffThreshold REAL Absolute time-stamp difference at which alert condition is


triggered. Must be greater than 0. Units are in seconds.

WaitTime TIME Maximum time allowed between indicator .stVal assertions


before internal variables are cleared. Must be greater than
TimeDiffThreshold.

Outputs
Name IEC 61131 Type Description

ENO BOOL Indication that the function block is enabled

Alert SPS Indication that the calculated TimeDifference has exceeded


TimeDiffThreshold

QualityAlert BOOL Indicator quality alert

TimeDifference REAL Signed time-stamp difference: Indicator2.t.value minus


Indicator1.t.value. Units are in seconds

Status enum_AlertType Enumeration describing the function block state

Processing
➤ TimeDiffThreshold and WaitTime inputs are held static on the first task
cycle. Therefore, they cannot be changed during runtime.
➤ ENO is true when EN = TRUE and the function block initialization is
completed successfully.
➤ Successful function block initialization is dependent on user input
validation. If the function block fails to initialize, Status is set to ERROR.
➤ If any of the following conditions are true during the first call of the
function block, the function block fails to initialize.
➢ WaitTime is less than TimeDiffThreshold.
➢ TimediffThreshold is less than zero seconds.
➤ The function block can be reset either from a user asserted RESET or an
internal reset because of the expiration of WaitPeriod. If reset, outputs
return to a default state. Outputs are held in this state while RESET is
TRUE.
➤ Disabling the function block by setting EN to FALSE does not clear the
function block Alert.
➤ When ENO is FALSE or Reset is TRUE, the Alert SPS quality is set to
invalid.
➤ The function block adheres to the following processing if ENO is TRUE.
➤ Good Indicator quality is required for input processing. This
is determined by the input indicator validity_t structure, i.e.,
SPS.q.validity = good.
➤ If either input indicator has bad quality, processing is halted, QualityAlert
is asserted, Status is set to BAD_QUALITY, and Alert.q.validity is
set to invalid. Note that this does not trigger a reset, nor does it require a
reset to clear.

Date Code 20241023 Programming Reference


80 ChannelMonitoring
Classes

➤ If Status is EXPIRATION, input processing stops until a user-initiated


RESET is executed.
➤ The WaitPeriod timer is initiated by the rising edge of
Indicator1.stVal or Indicator2.stVal while the other indicator's
.stVal is deasserted.
➤ If the WaitPeriod timer expires before the remaining indicator .stVal
asserts, a reset is initiated and the function block returns to normal
operation.
➤ If the remaining indicator .stVal asserts before the WaitPeriod timer
has elapsed, the signed time difference between the input indicators is
calculated and assigned to TimeDifference.
➤ TimeDifference is defined as Indicator2.t.value minus
Indicator1.t.value, where each respective time stamp is recorded at
the rising edge of the indicators' .stVal.
➤ The TimeDifference output is accurate to within plus or minus 500
microseconds.
➤ If Indicator2.stVal asserts before Indicator1.stVal, the output
TimeDifference represents a negative time difference.
➤ If ABS(TimeDifference) > TimeDiffThreshold, Alert.stVal
asserts and Alert.t is set equal to the RTAC system time.
➤ If Alert.stVal is TRUE, Status is set to EXPIRATION.

Classes
class_TimeAlignment (Class)
This class implements a relative time-alignment algorithm in the RTAC logic
engine for the purpose of grouping measurements from various data sources
by time stamp. This guarantees time-coherence of data that are passed on to
subsequent user logic.

Time alignment groups channel samples based on two qualifiers:

1. Time of Arrival. Time alignment employs a wait window, allowing


samples with similar time stamps to arrive at the RTAC at different times.
Relative time alignment dictates that a wait window for a given time
stamp opens upon the receipt of the first sample with that time stamp.
A time-aligned data set is made available when all expected data arrive
within the wait window or if the wait time reaches the user-settable
maximum.
2. Time Stamp Value. Time alignment employs time-stamp rounding to
group time stamps whose values differ by less than a defined amount.

Figure 4.5 depicts a relative time alignment scenario where samples with
matching time stamps arrive within the wait window.

Programming Reference Date Code 20241023


ChannelMonitoring 81
Classes

Figure 4.5 Relative Time Alignment (All Expected Data Received)

Figure 4.6 depicts a relative time alignment scenario where most samples with
matching time stamps arrive within the wait window and one sample with the
matching time stamp arrives after the window has closed.

Figure 4.6 Relative Time Alignment (Some Missing Data)

This time alignment implementation includes the following guarantees and


limitations:

➤ Output channels are updated with a data set whose original sample time
stamps vary from each other by no more than 1/MaximumRate.
➤ Output channels are updated with a data set whose original samples were
received at the RTAC within MaximumWaitTime from the receipt of the
first received sample for that set.

Date Code 20241023 Programming Reference


82 ChannelMonitoring
Classes

➤ Output channels share the same time stamp and consecutive output time
stamp updates differ by no less than 1/MaximumRate.
➤ A maximum of 8000 individual tags can be time-aligned per instance of
class_TimeAlignment.

NOTE
For additional information on time alignment, see IEEE C37.247-2019, Standard
for Phasor Data Concentrators for Power Systems—Section 4.1 and Annexes D,
E, and F.

This class should be operated via the following sequence:

1. Call the BootstrapChannelSet methods to specify the input channels and


corresponding output channels.
2. Once all desired channel sets have been bootstrapped, call Run() as
frequently or faster than the input channel update rate.
3. Call GetDataSet() while NumDataSetsAvailable is greater than
zero to update output channels.

Inputs
Name IEC 61131 Type Description

MaximumRate UDINT (1–24000) Samples/second: Maximum time alignment rate.

MaximumWaitTime UDINT (4–5000) Milliseconds: The amount of time that the class waits to receive all
expected samples for a given time stamp. Values less than the task
cycle time are rounded up to the task cycle time.

Outputs
Name IEC 61131 Type Description

NumDataSetsAvailable UDINT The number of available time-aligned data sets.

Error BOOL Indicates an internal error.

ErrorMessage STRING(255) Description of the current error state.

BootstrapChannelSet_MV (Method)
This method adds an input/output set of MV channels for monitoring and
updating respectively.

Inputs/Outputs

Name IEC 61131 Type Description

InputChannel MV The input channel.

OutputChannel MV The output channel.

Programming Reference Date Code 20241023


ChannelMonitoring 83
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after the first call to Run().
➤ Returns FALSE if the maximum bootstrapped tag limit (8000) has been
reached.

BootstrapChannelSet_CMV (Method)
This method adds an input/output set of CMV channels for monitoring and
updating respectively.

Inputs/Outputs

Name IEC 61131 Type Description

InputChannel CMV The input channel.

OutputChannel CMV The output channel.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after the first call to Run().
➤ Returns FALSE if the maximum bootstrapped tag limit (8000) has been
reached.

BootstrapChannelSet_INS (Method)
This method adds an input/output set of INS channels for monitoring and
updating respectively.

Inputs/Outputs

Name IEC 61131 Type Description

InputChannel INS The input channel.

OutputChannel INS The output channel.

Date Code 20241023 Programming Reference


84 ChannelMonitoring
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after the first call to Run().
➤ Returns FALSE if the maximum bootstrapped tag limit (8000) has been
reached.

BootstrapChannelSet_SPS (Method)
This method adds an input/output set of SPS channels for monitoring and
updating respectively.

Inputs/Outputs
Name IEC 61131 Type Description

InputChannel SPS The input channel.

OutputChannel SPS The output channel.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after the first call to Run().
➤ Returns FALSE if the maximum bootstrapped tag limit (8000) has been
reached.

Run (Method)
Call this method once per scan, or faster, after completing all necessary calls to
the BootstrapChannel methods.

Processing
Input Validation and General Processing
➤ The first call to Run() validates and locks the MaximumRate,
MaximumWaitTime, inputs to the current value.
➤ After the first call to Run(), any calls to the BootstrapChannel methods
are ignored.
➤ If Run() is called before any calls to the BootstrapChannel methods,
Error is asserted and ErrorMessage indicates a failure to initialize.

Programming Reference Date Code 20241023


ChannelMonitoring 85
Classes

➤ If any user input does not conform to the specified limits, Error is
asserted and ErrorMessage indicates the invalid input.
➤ Processing is halted while Error is true.
➤ While Error is true, ErrorMessage provides additional information
about current error condition. Otherwise, ErrorMessage is empty.
➤ Input channels are monitored for changes in time stamp. Changes in data
value are ignored if not accompanied by a time stamp change.

General Time Alignment


➤ Under ideal conditions, time alignment receives one sample from each
input channel per time stamp.
➤ The receipt of a qualifying time stamp opens a time-alignment wait
window. A qualifying time stamp is generally greater than the time stamp
of the most recently opened wait window by at least 1 / MaximumRate.
See Typical Scenarios and Expected Output for exceptions.
➤ A wait window remains open for a duration no greater than
MaximumWaitTime to receive an expected sample from each input
channel, starting with the arrival time of the first sample with that time
stamp.
➤ An "expected sample" for a given wait window contains a time stamp that
is within plus or minus 0.5 / MaximumRate from the wait window time
stamp.
➤ If multiple samples from a single channel contain time stamps that are
eligible for inclusion in an active wait window, the most recently received
sample is used.
➤ A given wait window closes when expected samples from all input
channels are received or when the wait time equals MaximumWaitTime.
➤ NumDataSetsAvailable increments by one or more when the wait
window with the oldest time stamp closes.
➤ If a wait window closes before all expected samples are received,
the .q.validity attribute of the missing channels within the time aligned
data set are set to invalid and the channel value is set equal to the
following:
➢ REAL : 0.000
➢ DINT : 0
➢ BOOL : FALSE
➤ Sample time stamp quality is passed from input to output channel without
modification.
➤ Samples from a given channel that are received out of order (in regard to
the time stamp values) will not result in out-of-order time-aligned output
updates.
➤ The number of cached time aligned data sets represented
by NumDataSetsAvailable, will not exceed
2*(MaximumWaitTime/1000)*MaximumRate. If
NumDataSetsAvailable equals this number, the oldest cached data sets
are discarded when new data sets are made available.
➤ MaximumRate defines the minimum time stamp difference between
consecutive output channel updates. This setting can be useful when up-
or down-scaling input channel rates to a desired rate.

Date Code 20241023 Programming Reference


86 ChannelMonitoring
Classes

Typical Scenarios and Expected Output

➤ Ideal: A sample for each channel arrives with the same time stamp at
the same time or at slightly different times within the wait window. The
NumDataSetsAvailable output is incremented and the resulting data
set contains no missing data indicators.
➤ Some Late Data: A sample for each channel arrives with the same
time stamp, but one or more arrive after the wait time has reached
MaximumWaitTime. The NumDataSetsAvailable output is
incremented and the resultant data set contains missing data indicators for
the late data.
➤ No Data: If no data arrive for any channel, no work is done and the
outputs will not update.
➤ A Majority of ChannelsUndergo a Large Jump Forward or Backward in
Time Stamp: Starting with the ideal case, if a simple majority of channels
jump forward or backward in time stamp (within the same task cycle) by
an amount that is more than two times the greater of 1 / MaximumRate
or MaximumWaitTime (typically due to a clock shift resulting from a
settings change or reset), output data sets contain some missing data
indicators for the majority group until all wait windows from the old time
reference are closed. At that point, the output data sets contain missing
data indicators for all minority group channels until the time stamps of the
two groups reconverge.
➤ A Minority of ChannelsUndergo a Large Jump Forward or Backward in
Time Stamp: Starting with the ideal case, if a simple minority of channels
jump forward or backward in time stamp (within the same task cycle) by
an amount that is more than two times the greater of 1 / MaximumRate
or MaximumWaitTime (typically due to a clock shift resulting from a
settings change or reset), output data sets contain missing data indicators
for the minority channel group until the time stamps of the two groups
reconverge.
➤ All Channels Undergo a Large Jump Forward or Backward in Time
Stamp: Starting with the ideal case, if all channels jump forward or
backward in time stamp (within the same task cycle) by an amount
that is more than two times the greater of 1 / MaximumRate or
MaximumWaitTime (typically due to a clock shift resulting from a settings
change or reset), output data sets contain some missing data indicators
until all wait windows from the old time reference are closed.
➤ Tie Condition: If exactly half of the channels undergo a large jump
forward or backward in time stamp by more than two times the greater
of 1 / MaximumRate or MaximumWaitTime (typically due to a clock
shift resulting from a settings change or reset), the tie is broken based
on the .quality.clockNotSynchronized and .quality.accuracy attributes
of the time stamps. If a tie condition still persists, the group with time
stamps nearest the pre-jump time reference is favored. If both groups are
equidistant from the pre-jump time reference, the group with time stamps
further in the future is favored. The time-aligned data set contains missing
data indicators for the non-favored channel group.

Programming Reference Date Code 20241023


ChannelMonitoring 87
Classes

➤ Down-Conversion: If any input channel updates in time stamp at a rate


that is greater than MaximumRate, the channel rate is down-converted to
MaximumRate by discarding the extra samples.
➤ Up-Conversion: Channels that update at less than MaximumRate are
represented by missing data indicators within some of the outgoing
data sets. This assumes that at least one input channel updates at
MaximumRate. The time-alignment class waits a full MaximumWaitTime
before completing a time-aligned data set that contains missing data
indicators.

GetDataSet (Method)
This method updates the output channels with the oldest available set of time-
aligned data.

Outputs

Name IEC 61131 Type Description

MissingData BOOL One or more output channels were updated


with missing data indicators.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
The following steps are executed if class_TimeAlignment output
NumDataSetsAvailable is greater than zero. Otherwise, no work is done and
returns FALSE.

➤ Updates all output channels with the oldest available time-aligned data
set.
➤ If any channel within the data set contains missing data indicators, sets
MissingData to TRUE.
➤ Decrements class_TimeAlignment output: NumDataSetsAvailable.

Date Code 20241023 Programming Reference


88 ChannelMonitoring
Benchmarks

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3530
➢ R135-V1 firmware
➤ SEL-3505
➢ R135-V1 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R135-V1 firmware

Benchmark Test Descriptions


Each benchmarking test is performed 1000 times and the average run time is
recorded here. Each test is intended to give insight into the expected cost of
running the given command.

fun_GetAlertString
The cost of a call to fun_GetAlertString.

fun_GetChannelString
The cost of a call to fun_GetChannelString.

fb_MultiChannelAlert No Alert
The cost of a call to fb_MultiChannelAlert when all channels are active and no
alert is generated.

fb_MultiChannelAlert 1 Channel Timed


The cost of a call to fb_MultiChannelAlert when all channels are active and one
channel differs from the others long enough to generate an alert. This is the run
time on the scan the alert begins.

fb_MultiChannelAlert All Channel Timed


The cost of a call to fb_MultiChannelAlert when all channels are active and all
three channels differ from each other long enough to generate an alert. This is
the run time on the scan the alert begins.

Programming Reference Date Code 20241023


ChannelMonitoring 89
Benchmarks

fb_MultiChannelAlert 1 Channel Chatter


The cost of a call to fb_MultiChannelAlert when all channels are active and one
channel differs from the others often enough to generate an alert. This is the run
time on the scan the alert begins.

fb_MultiChannelAlert All Channel Chatter


The cost of a call to fb_MultiChannelAlert when all channels are active and all
three channels differ from each other often enough to generate an alert. This is
the run time on the scan the alert begins.

fb_ChannelAlert No Alert
The cost of a call to fb_ChannelAlert when no alert is generated.

fb_ChannelAlert Timed
The cost of a call to fb_ChannelAlert when the input differs from the reference
long enough to generate an alert. This is the run time on the scan the alert
begins.

fb_ChannelAlert Chatter
The cost of a call to fb_ChannelAlert when the input differs from the reference
often enough to generate an alert. This is the run time on the scan the alert
begins.

fb_IndicatorAlert No Alert
The cost of a call to fb_IndicatorAlert when no alert is generated.

fb_IndicatorAlert Timed
The cost of a call to fb_IndicatorAlert when the input is true long enough to
generate an alert. This is the run time on the scan the alert begins.

fb_IndicatorAlert Chatter
The cost of a call to fb_IndicatorAlert when the input is true often enough to
generate an alert. This is the run time on the scan the alert begins.

fb_ChannelDerivative Active Periodic


The cost of a call to fb_ChannelDerivative during active derivative calculation
on a Channel input while in periodic processing mode (PeriodicProcessing
= TRUE).

Date Code 20241023 Programming Reference


90 ChannelMonitoring
Benchmarks

fb_ChannelDerivative Active Not Periodic


The cost of a call to fb_ChannelDerivative during active derivative
calculation on a Channel input while in not in periodic processing mode
(PeriodicProcessing = FALSE). In this mode sample processing is
triggered by Channel time-stamp changes.

fb_ChannelDerivative Alert
The cost of a call to fb_ChannelDerivative while Status = EXCURSION and
Alert.stVal = TRUE.

fb_ChannelIntegral No Deviation Periodic


The cost of a call to fb_ChannelIntegral while it is in an idle state, and while it is
in periodic processing mode (PeriodicProcessing = TRUE).

fb_ChannelIntegral No Deviation Not Periodic


The cost of a call to fb_ChannelIntegral during an idle state while not in periodic
processing mode (PeriodicProcessing = FALSE). In this mode sample
processing is triggered by Channel time-stamp changes.

fb_ChannelIntegral Active Periodic


The cost of a call to fb_ChannelIntegral during an active integration state while
in periodic processing mode (PeriodicProcessing = TRUE).

fb_ChannelIntegral Active Not Periodic


The cost of a call to fb_ChannelIntegral during an active integration state while
not in periodic processing mode (PeriodicProcessing = FALSE). In this
mode sample processing is triggered by Channel time-stamp changes.

fb_ChannelIntegral Complete Periodic


The cost of a call to fb_ChannelIntegral during a Status = COMPLETE state
while in periodic processing mode (PeriodicProcessing = TRUE).

fb_ChannelIntegral Complete Not Periodic


The cost of a call to fb_ChannelIntegral during a Status = COMPLETE state
while not in periodic processing mode (PeriodicProcessing = FALSE). In
this mode sample processing is triggered by Channel time-stamp changes.

fb_IndicatorTimeDelta No Deviation
The cost of a call to fb_IndicatorTimeDelta while it is in a Status =
NO_DEVIATION state (Both indicators' inputs are deasserted).

Programming Reference Date Code 20241023


ChannelMonitoring 91
Benchmarks

fb_IndicatorTimeDelta Bad Quality


The cost of a call to fb_IndicatorTimeDelta during a Status = BAD_QUALITY
state (either indicator input has .q.validity that is not equal to good).

fb_IndicatorTimeDelta Waiting for Second Indicator


The cost of a call to fb_IndicatorTimeDelta while one indicator input is asserted
and the function block is waiting for the second indicator input to assert.

fb_IndicatorTimeDelta Alert State


The cost of a call to fb_IndicatorTimeDelta during a Alert.stVal = TRUE
state (time difference has exceeded the threshold. Alert is held high until a user
reset).

class_TimeAlignment Benchmark Tests


Benchmark tests for class_TimeAlignment are divided into three main brackets
with varying amounts of loading, as described below:

Light Load
1. Time aligned channels : 40 (evenly divided among CMV, MV, INS, and
SPS channels)
2. Channel data rate : 10 (msg/sec)
3. MaximumWaitTime setting value : 200 (ms)

Medium Load
1. Time aligned channels : 800 (evenly divided among CMV, MV, INS, and
SPS channels)
2. Channel data rate : 50 (msg/sec)
3. MaximumWaitTime setting value : 1000 (ms)

Heavy Load
NOTE
The heavy load scenario is not recommended for SEL-3530 or SEL-3505
platforms.

1. Time aligned channels : 8000 (evenly divided among CMV, MV, INS, and
SPS channels)
2. Channel data rate : 50 (msg/sec)
3. MaximumWaitTime setting value : 1000 (ms)

For each bracket, the cost of calls to the Run and GetDataSet methods are
evaluated separately.

Date Code 20241023 Programming Reference


92 ChannelMonitoring
Benchmarks

For each bracket, and each evaluated class method, two additional operating
conditions are considered, as described below.

1. No missing data: This operating condition guarantees synchronized


time-stamp updates among all channels and that all channel time-
stamp values match at any given time. The incoming data streams are
already effectively time-aligned. The result of this operating condition
on class_TimeAlignment is that wait windows are opened and closed on
the same task cycle, such that the class instance operates in an effective
bypass mode.
2. Missing data: This operating condition is identical to the 'No missing data'
condition with one exception. One of the input channels never updates.
This forces the class instance to wait for the full MaximumWaitTime
before publishing a time-aligned data set with missing data indicators
for the non-updating channel. This worst-case scenario causes the class
instance to continually buffer the maximum amount of data.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3530 SEL-3505 SEL-3555

fun_GetAlertString 7 18 1

fun_GetChannelString 8 16 1

fb_MultiChannelAlert No Alert 16 22 2

fb_MultiChannelAlert 1 Channel Timed 21 30 4

fb_MultiChannelAlert All Channel Timed 21 30 4

fb_MultiChannelAlert 1 Channel Chatter 24 34 4

fb_MultiChannelAlert All Channel Chatter 24 39 4

fb_ChannelAlert No Alert 10 14 2

fb_ChannelAlert Timed 16 22 3

fb_ChannelAlert Chatter 18 26 3

fb_IndicatorAlert No Alert 8 10 2

fb_IndicatorAlert Timed 14 19 3

fb_IndicatorAlert Chatter 16 22 3

fb_ChannelDerivative Active Periodic 56 123 10

fb_ChannelDerivative Active Not Periodic 105 138 18

fb_ChannelDerivative Alert 6 8 1

fb_ChannelIntegral No Deviation Periodic 26 90 5

fb_ChannelIntegral No Deviation Not Periodic 22 41 3

fb_ChannelIntegral Active Periodic 31 111 4

fb_ChannelIntegral Active Not Periodic 28 78 3

fb_ChannelIntegral Complete Periodic 7 40 1

fb_ChannelIntegral Complete Not Periodic 7 8 1

Programming Reference Date Code 20241023


ChannelMonitoring 93
Examples

Platform (time in µs)


Operation Tested
SEL-3530 SEL-3505 SEL-3555

fb_IndicatorTimeDelta No Deviation 9 12 1

fb_IndicatorTimeDelta Bad Quality 7 35 1

fb_IndicatorTimeDelta Waiting For Second Indicator 11 44 2

fb_IndicatorTimeDelta Alert State 5 6 1

class_TimeAlignment-Run(): Heavy-Missing NA NA 22854

class_TimeAlignment-GetDataSet(): Heavy-Missing NA NA 617

class_TimeAlignment-Run(): Heavy-NoMissing NA NA 22519

class_TimeAlignment-GetDataSet(): Heavy-NoMissing NA NA 615

class_TimeAlignment-Run(): Medium-Missing 47477 27840 4447

class_TimeAlignment-GetDataSet(): Medium-Missing 3112 1959 61

class_TimeAlignment-Run(): Medium-NoMissing 46886 27050 4383

class_TimeAlignment-GetDataSet(): Medium-NoMissing 3097 1947 60

class_TimeAlignment-Run(): Light-Missing 559 276 13

class_TimeAlignment-GetDataSet(): Light-Missing 483 276 13

class_TimeAlignment-Run(): Light-NoMissing 469 164 9

class_TimeAlignment-GetDataSet(): Light-NoMissing 361 147 8

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Monitor Phase-A Measurements for a Maintenance Condition


Objective
Create a program to monitor and verify the measurements obtained from three
protective relays to determine if the components are functioning within expected
limits.

Date Code 20241023 Programming Reference


94 ChannelMonitoring
Examples

Solution
This solution uses the fb_ChannelAlert function block to monitor for differences
between CTs. The Phase A measurements are obtained from the relays and
compared against a reference measurement (see Code Snippet 4.1).
Code Snippet 4.1 prg_MonitorPhaseA_Components
PROGRAM prg_MonitorPhaseA_Components
VAR
(* Function block monitoring IED 1-3 *)
IED_1_PhA : fb_ChannelAlert;
IED_2_PhA : fb_ChannelAlert;
IED_3_PhA : fb_ChannelAlert;
(* Function block parameters *)
PhA_Reference : MV; Allowed_Deviation : REAL; Allowed_Chatter : UDINT;
AlertTime : TIME; MonitorReset : BOOL;
(* Criterion to enable the monitoring block *)
EnableMonitoring : BOOL;
(* Alert status *)
IED_1_Enabled : BOOL; IED_2_Enabled : BOOL; IED_3_Enabled : BOOL;
(* Placeholder for a data communications tag *)
IED_1_Data : MV; IED_2_Data : MV; IED_3_Data : MV;
(* Alert status *)
IED_1_Alert : SPS; IED_2_Alert : SPS; IED_3_Alert : SPS;
(* Alert condition *)
IED_1_Status : DINT; IED_2_Status : DINT; IED_3_Status : DINT;
(* Quality status *)
IED_1_Quality : BOOL; IED_2_Quality : BOOL; IED_3_Quality : BOOL;
END_VAR

(* Check the quality of the reference signal *)


EnableMonitoring := (PhA_Reference.q.validity = good);

(* Configure and monitor the function block parameters *)


IED_1_PhA(EN := EnableMonitoring, Channel := IED_1_Data,
ChannelReference := PhA_Reference.instMag,
ExcursionThreshold := Allowed_Deviation,
ChatterCount := Allowed_Chatter, ExcursionTime := AlertTime,
LatchAlarm := TRUE, Reset := MonitorReset,
ENO => IED_1_Enabled, Alert => IED_1_Alert,
Status => IED_1_Status, QualityAlert => IED_1_Quality);

IED_2_PhA(EN := EnableMonitoring, Channel := IED_2_Data,


ChannelReference := PhA_Reference.instMag,
ExcursionThreshold := Allowed_Deviation,
ChatterCount := Allowed_Chatter, ExcursionTime := AlertTime,
LatchAlarm := TRUE, Reset := MonitorReset,
ENO => IED_2_Enabled, Alert => IED_2_Alert,
Status => IED_2_Status, QualityAlert => IED_2_Quality);

IED_3_PhA(EN := EnableMonitoring, Channel := IED_3_Data,


ChannelReference := PhA_Reference.instMag,
ExcursionThreshold := Allowed_Deviation,
ChatterCount := Allowed_Chatter, ExcursionTime := AlertTime,
LatchAlarm := TRUE, Reset := MonitorReset,
ENO => IED_3_Enabled, Alert => IED_3_Alert,
Status => IED_3_Status, QualityAlert => IED_3_Quality);

Creating an Object to Verify and Monitor IED Operation


Objective
Create a program to monitor for deviations between phases on the generator and
load sides of a breaker.

Programming Reference Date Code 20241023


ChannelMonitoring 95
Examples

Solution
This solution uses the fb_MultiChannelAlert function block to monitor the three
phases of a CT. The phase measurements are obtained from the relays on both
the generator and load sides of a breaker. All the phases are compared against
each other to detect damage or a maintenance condition in CT/PT windings.
Code Snippet 4.2 prg_MonitorBreakerHighLoadSideComponents
PROGRAM prg_MonitorBreakerHighLoadSideComponents
VAR
(* Function block monitoring generator side of breaker *)
Gen_Monitor : fb_MultiChannelAlert;
(* Function block monitoring bus side of breaker *)
Bus_Monitor : fb_MultiChannelAlert;
(* Generator nominal current *)
GenNominal : REAL;
(* Actual generator output *)
GenOutput : REAL;
(* Set the limit the channels are allowed to deviate by *)
AllowedDeviation : REAL;
(* Criterion to enable the monitoring block *)
Enable_FB : BOOL;
(* Placeholder for a data communications tag *)
PhaseA_X_Terminal : MV; PhaseB_X_Terminal : MV; PhaseC_X_Terminal : MV;
(* Placeholder for a data communications tag *)
PhaseA_Y_Terminal : MV; PhaseB_Y_Terminal : MV; PhaseC_Y_Terminal : MV;
(* Clear the alert condition and restore block to default condition *)
FB_Reset : BOOL;
(* Function block successfully enabled *)
GenFB_Enabled : BOOL; BusFB_Enabled : BOOL;
(* Gen_FB alert information *)
GenAlert : SPS; GenFB_Status : enum_AlertType; GenAlertCause : enum_ChannelAlert;
GenQualityAlert : BOOL; GenQualityCause : enum_ChannelAlert;
(* Bus_FB alert information *)
BusAlert : SPS; BusFB_Status : enum_AlertType; BusAlertCause : enum_ChannelAlert;
BusQualityAlert : BOOL; BusQualityCause : enum_ChannelAlert;
(* Detect an alert condition *)
Gen_Alert_Generated : R_TRIG; Bus_Alert_Generated : R_TRIG;
Gen_Status_Message : STRING; Bus_Status_Message : STRING;
Gen_Channel_Message : STRING; Bus_Channel_Message : STRING;
END_VAR

(* If the generator output exceeds 5% of nominal, enable the monitoring blocks *)


Enable_FB := (GenOutput >= 0.05 * GenNominal);

(* Function block monitoring the X terminal - high side *)


Gen_Monitor(EN := Enable_FB, Channel_1 := PhaseA_X_Terminal,
Channel_2 := PhaseB_X_Terminal, Channel_3 := PhaseC_X_Terminal,
ExcursionThreshold := AllowedDeviation, ChatterCount := 3,
ExcursionTime := T#1M, LatchAlarm := TRUE, Reset := FB_Reset,
ENO => GenFB_Enabled, Alert => GenAlert, Status => GenFB_Status,
ChannelStatus => GenAlertCause, QualityAlert => GenQualityAlert,
QualityStatus => GenQualityCause);

(* Function block monitoring the Y terminal - load side *)


Bus_Monitor(EN := Enable_FB, Channel_1 := PhaseA_Y_Terminal,
Channel_2 := PhaseB_Y_Terminal, Channel_3 := PhaseC_Y_Terminal,
ExcursionThreshold := AllowedDeviation, ChatterCount := 3,
ExcursionTime := T#1M, LatchAlarm := TRUE, Reset := FB_Reset,
ENO => BusFB_Enabled, Alert => BusAlert, Status => BusFB_Status,
ChannelStatus => BusAlertCause, QualityAlert => BusQualityAlert,
QualityStatus => BusQualityCause);

// If an alert condition is detected, generate a message for logging


Gen_Alert_Generated(CLK := GenAlert.stVal);
Bus_Alert_Generated(CLK := BusAlert.stVal);

Date Code 20241023 Programming Reference


96 ChannelMonitoring
Examples

IF Gen_Alert_Generated.Q THEN
Gen_Status_Message := fun_GetAlertString(GenFB_Status);
Gen_Channel_Message := fun_GetChannelString(GenAlertCause);
END_IF

IF Bus_Alert_Generated.Q THEN
Bus_Status_Message := fun_GetAlertString(BusFB_Status);
Bus_Channel_Message := fun_GetChannelString(BusAlertCause);
END_IF

Creating an Object to Verify and Monitor Communications Channels


and Hardware Alarms
Objective
Monitor and verify that a communications channel is functioning properly and
that no hardware failures are detected for an IED.

Solution
This solution uses the fb_StatusAlert function block to detect a TRUE condition
in either a communications diagnostic or hardware indicator. An appropriate
communications channel diagnostic, such as the Offline bit in GOOSE, is
monitored for communications channel failure. The HALARM Relay Word bit
in an IED is monitored for hardware failures only if the communications channel
is online.
Code Snippet 4.3 prg_MonitorIED_Components
PROGRAM prg_MonitorIED_Components
VAR
(* Monitor the HALARM Relay Word bit *)
IED_1_HardwareMonitor : fb_IndicatorAlert;
(* Monitor a Mirrored Bits or GOOSE communications channel *)
ProtectionChannelMonitor : fb_IndicatorAlert;
(* Criterion to enable the monitoring block *)
EnableHardwareMonitoring : BOOL;
(* Reset after results are recorded *)
DailyReset : BOOL;
(* Placeholder for a data tag *)
HALARM : BOOL;
Communication_Client_Offline : BOOL;
ProtectionChannelDiagnostic : BOOL;
(* HALARM monitoring status *)
IED_1_HALARM_MonitorEnabled : BOOL;
IED_1_HALRM_Alert : SPS;
IED_1_HALRM_Status : DINT;
(* Protection monitoring status *)
ProtectionChannelMonitor_Enabled : BOOL;
(* Alert status *)
ProtectionChannel_Alert : SPS;
(* Alert condition *)
ProtectionChannel_Status : DINT;
END_VAR

(* If the offline status is false, monitor the HALARM Relay Word bit. Note that this is
a separate offline bit than that used in the ProtectionChannelMonitor *)
EnableHardwareMonitoring := NOT Communication_Client_Offline;

(* Configure and monitor the function block parameters *)


IED_1_HardwareMonitor(EN := EnableHardwareMonitoring, Indicator := HALARM,
ChatterCount := 1, ExcursionTime := T#10S, Reset := DailyReset,
ENO => IED_1_HALARM_MonitorEnabled, Alert => IED_1_HALRM_Alert,

Programming Reference Date Code 20241023


ChannelMonitoring 97
Examples

Status => IED_1_HALRM_Status);

ProtectionChannelMonitor(EN := TRUE, Indicator := ProtectionChannelDiagnostic,


ChatterCount := 2, ExcursionTime := T#5S, Reset := DailyReset,
ENO => ProtectionChannelMonitor_Enabled,
Alert => ProtectionChannel_Alert, Status => ProtectionChannel_Status);

Creating an Object to Calculate Kilowatt-Hours Delivered During a Peak


Demand Period
Objective
Calculate kilowatt-hours delivered during a period of peak demand.

Solution
This solution uses the fb_ChannelIntegral function block to monitor a measured
power quantity and calculate the integral over time while the power is in excess
of a user-defined peak-demand threshold. This example assumes the following:

1. Power measurements are received from an SEL-351 Modbus client, using


a holding register named "KW3DI" (type = APC), polling interval of two
seconds.
2. A virtual tag list called HMI_Controls was created for program control
and status outputs. Virtual tag list tags shown in this example are defined
as the following data types.
➤ Aggregation_Complete: SPS
➤ Aggregator_Reset: SPC
➤ Demand_Threshold: MV (Analog Control)
➤ KWH_During_Peak: MV
➤ MaxKWDuringPeak: MV
➤ Monitor_Enabled: SPS
➤ Monitor_Quality_Alert: SPS
➤ Peak_End_Time: STR
➤ Peak_Start_Time: STR
➤ Peak_Time_Active: SPS
Code Snippet 4.4 prg_KWH_Track
(* This example demonstrates the calculation of kilowatt-hours over a
period of high demand, given a power measurement in units of kilowatts.

This program sets the PeriodicProcessing input of the fb_ChannelIntegral


instance to TRUE because the Modbus source will not update the
Channel.t.value time stamp on its own. The Period input is set to
two seconds, which corresponds with the Modbus holding register poll
interval.

Kilowatts integrated over time will produce a result in units of joules,


where one joule = one watt-second. To convert joules to kilowatt-hours,
the result must be divided by (3600 seconds/hour * 1000 watts/kiloWatts)
= 3,600,000 watt-seconds/kilowatt-hour. *)

PROGRAM prg_KWH_Track
VAR
Enable : BOOL;

Date Code 20241023 Programming Reference


98 ChannelMonitoring
Examples

Aggregator : fb_ChannelIntegral;
Joules_to_KWH : REAL := 3600000;
KWH_During_Peak : REAL;
Peak_Start_Time : dateTime_t;
Peak_End_Time : dateTime_t;
QualityAlert : BOOL;
END_VAR

// Determine Enable condition


Enable := NOT SEL_351_1_MODBUS_POU.Offline
AND SEL_351_1_MODBUS.KW3DI.status.q.validity = good;

// Run the Integrator function block


Aggregator( EN := Enable,
Reset := HMI_Controls.Aggregator_Reset.operSet.ctlVal,
Channel := SEL_351_1_MODBUS.KW3DI.status,
SetPoint := HMI_Controls.Demand_Threshold.oper.setMag,
PeriodicProcessing := TRUE,
Period := T#2S, // Set to 2 seconds to match the Holding Register poll interval.
LowerBound := 0,
DebounceTime := T#10S);

// Load monitor status variables


HMI_Controls.Monitor_Enabled.stVal := Aggregator.ENO;
HMI_Controls.Monitor_Quality_Alert.stVal := Aggregator.QualityAlert;
HMI_Controls.Peak_Time_Active.stVal := Aggregator.Status = EXPIRATION
OR Aggregator.Status = EXCURSION;
HMI_Controls.Aggregation_Complete := Aggregator.Alert;

// Load outputs
KWH_During_Peak := Aggregator.Integral.instMag / Joules_to_KWH;
HMI_Controls.KWH_During_Peak := Aggregator.Integral;
HMI_Controls.KWH_During_Peak.instMag := KWH_During_Peak;
HMI_Controls.KWH_During_Peak.mag := KWH_During_Peak;
HMI_Controls.MaxKWDuringPeak := Aggregator.Peak;

// Update Peak demand on and Peak demand off time-stamps


HMI_Controls.Peak_Start_Time.strVal := DT_TO_STRING(Aggregator.ExcursionTimeOn.dateTime);
HMI_Controls.Peak_End_Time.strVal := DT_TO_STRING(Aggregator.ExcursionTimeOff.dateTime);

// Force good quality on tags with no other quality source.


HMI_Controls.Peak_End_Time.q.validity := good;
HMI_Controls.Peak_Start_Time.q.validity := good;
HMI_Controls.Aggregator_Reset.status.q.validity := good;
HMI_Controls.Demand_Threshold.status.q.validity := good;
HMI_Controls.Monitor_Enabled.q.validity := good;
HMI_Controls.Monitor_Quality_Alert.q.validity := good;
HMI_Controls.Peak_Time_Active.q.validity := good;

Creating an Object to Monitor a Client's Go-Online Time Delay


Objective
Calculate the time delta between RTAC runtime initiation and the deassertion of
a communication client Offline POU pin. Assert an alert if the time delta exceeds
a user-settable threshold.

Programming Reference Date Code 20241023


ChannelMonitoring 99
Examples

Solution
This solution uses the fb_IndicatorTimeDelta function block to monitor the state
of the Offline POU output pin of an SEL client. If a user-settable time period
elapses before the Offline pin deasserts, the function block will output an alert.
This example assumes that an SEL-735 SEL client named SEL_735_2_SEL was
previously added to the RTAC project.
Code Snippet 4.5 prg_Go_Online_Timer
PROGRAM Go_online_timer
VAR
TimeTracker : fb_IndicatorTimeDelta;
Control : SPS;
OfflineTrack : SPS;
MaxAllowedTime : REAL := 30; // In seconds
TimeToGoOnline : REAL;
GoOnlineTimerAlert : BOOL;
END_VAR

// Set control variable


Control.q.validity := good;
Control.t := SYS_TIME();
Control.stVal := TRUE; // Control should always be true to ensure that the timer starts
// on the first cycle.

// Load variable to be monitored


OfflineTrack.q.validity := good;
OfflineTrack.stVal := NOT SEL_735_2_SEL_POU.Offline;
OfflineTrack.t := SYS_TIME();

// Run fb_IndicatorTimeDelta function block


TimeTracker(EN := TRUE,
RESET := FALSE,
Indicator1 := Control,
Indicator2 := OfflineTrack,
TimeDiffThreshold := MaxAllowedTime,
WaitTime := T#5M); // If OfflineTrack.stVal hasn't asserted after 5 minutes,
// assume something else is wrong and stop the timer.

// If client has gone online, load the outputs


IF NOT SEL_735_2_SEL_POU.Offline THEN
TimeToGoOnline := TimeTracker.TimeDifference;
GoOnlineTimerAlert := TimeTracker.Alert.stVal;
END_IF

Creating an Object to Monitor the Rate of Remote Access Failures


Objective
Monitor the number of failed attempts to log into the RTAC and assert an HMI
alarm if there have been more than five failed attempts within one minute.

Date Code 20241023 Programming Reference


100 ChannelMonitoring
Examples

Solution
This solution uses the fb_Derivative function block to monitor the
Number_Of_Logon_Errors system tag and set an alarm if the rate-of-change in
logon errors exceeds a settable threshold. This example assumes the following:

1. A virtual tag list called HMI_Controls was created for program control
and status outputs. Virtual tag list tags shown in this example are defined
as the following data types.
➤ RemoteAccessTracker_Reset: operSPC
➤ RemoteAccessAlarm: SPS
➤ RemoteAccessAlarmDetails: STR
Code Snippet 4.6 prg_AuthenticationAlarm
PROGRAM prg_AuthenticationAlarm
VAR
LoginErrorRateTracker : fb_ChannelDerivative;
ErrorAccumulator : MV;
Threshold : REAL := 0.08333; // In units of login
//failures per second. Equals 5 login
//failures divided by 60 seconds.
END_VAR

// Load the input Channel MV


ErrorAccumulator.q.validity := good;
ErrorAccumulator.instMag := UDINT_TO_REAL(SystemTags.Number_Of_Logon_Errors.stVal);

// Run the fb_ChannelDerivative block


LoginErrorRateTracker(EN := TRUE,
Reset := HMI_Controls.RemoteAccessTracker_Reset.status.stVal,
Channel := ErrorAccumulator,
DerivativeThreshold := Threshold,
PeriodicProcessing := TRUE,
Period := T#60S,
FilterLength := 1
Alert => HMI_Controls.RemoteAccessAlarm);

// Display alarm details while in alarm state; otherwise, clear alarm details.
IF LoginErrorRateTracker.Alert.stVal THEN
HMI_Controls.RemoteAccessAlarmDetails := SystemTags.Unsuccessful_Log_On_Attempt;
ELSE
HMI_Controls.RemoteAccessAlarmDetails.strVal := '';
END_IF

Time Align C37.118 PMU, AXION PMU, and SEL Fast Message Phasor Tags
Objective
Time-align phasor quantities from several data sources to guarantee time-stamp
coherence for subsequent processing.

Programming Reference Date Code 20241023


ChannelMonitoring 101
Examples

Solution
This solution applies a single instance of class_TimeAlignment to time align the
three channels. This example assumes the following:

1. The RTAC project is of version R145 or later.


2. The project contains three clients with the following types/names:
➤ C37.118 : SEL_421_1_C37_118 : Station Name = 'PMU3'
➤ AXION PRCTPT Module : SEL_PRCTPT_1_ECAT
➤ SEL : SEL_351_1_SEL
3. The SystemTags: Data_Rate setting matches the message rate setting in
the remote C37.118 server.
Code Snippet 4.7 prg_MultiProtocolTimeAlignment
PROGRAM Example1
VAR CONSTANT
c_ImbalanceMagThreshold : REAL := 20;
END_VAR
VAR
TA1 : class_TimeAlignment := (MaximumRate := 1, MaximumWaitTime := 200);
RunOnce : BOOL := TRUE;
TimeAlignedAXIONPhasor : CMV;
TimeAlignedC37118Phasor : CMV;
TimeAlignedSELFMPhasor : CMV;
DataMissing : BOOL;
MagnitudeDiff : REAL;
END_VAR

IF RunOnce THEN
// Bootstrap the input channels.
TA1.BootstrapChannelSet_CMV(inputChannel := SEL_421_1_PMU3.Phasor0,
outputChannel := TimeAlignedC37118Phasor);
TA1.BootstrapChannelSet_CMV(inputChannel := SEL_PRCTPT_1_ECAT.VA_PM,
outputChannel := TimeAlignedAXIONPhasor);
TA1.BootstrapChannelSet_CMV(inputChannel := SEL_351_1_SEL.FM_INST_I0,
outputChannel := TimeAlignedSELFMPhasor);
RunOnce := FALSE;
END_IF

// Run the time-alignment class instance


TA1.Run();

// If time-aligned data sets are available, update the target tags once per task cycle.
IF TA1.NumDataSetsAvailable > 0 THEN
TA1.GetDataSet(MissingData => DataMissing);
// If a time-aligned data set was returned with no missing data,
// process time aligned samples
IF NOT DataMissing THEN
// In this contrived example, the SEL client zero-sequence magnitude is used to
// qualify the subsequent magnitude difference calculation.
IF TimeAlignedSELFMPhasor.instCVal.mag > c_ImbalanceMagThreshold THEN
MagnitudeDiff :=
ABS(TimeAlignedC37118Phasor.instCVal.mag -
TimeAlignedAXIONPhasor.instCVal.mag);
END_IF
END_IF
END_IF

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 5

ConditionMonitoring
Introduction
This library provides functionality to facilitate power system and industrial asset
management.

Special Considerations
Classes in this library have memory allocated inside them. As such, they
should only be created in environments of permanent scope (e.g., Programs,
GlobalVariable Lists, or VAR_STAT sections).

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R147 or later.

Enumerations
Enumerations make code more readably by allowing a specific number to have a
readable textual equivalent.

enum_CTPT_MonitorMode
This enumeration defines the operating method of the
class_StreamingCTPTMonitor.

Enumeration Description

RELATIVE_REFERENCE All monitored channels for a given phase are compared


against each other to identify the failing CT or PT.

DEFINED_REFERENCE A reference channel (per-phase) is specified, by which all


monitored channels will be compared in order to identify
failing CTs or PTs.

Date Code 20241023 Programming Reference


104 ConditionMonitoring
Enumerations

enum_GenericDataClass
This enumeration specifies a class of data and is intended for use by
class_CmReportWriter.

Enumeration Description

ANALOG Analog quantity (INT or Floating point)

BOOLEAN Bool quantity (BOOL)

STRINGVAL String quantity (up to STRING(255))

enum_PhaseID
This enumeration allows for the specification of a particular electrical phase.

Enumeration Description

PHASE_0 Zero-Sequence Component.

PHASE_1 Positive-Sequence Component.

PHASE_2 Negative-Sequence Component.

PHASE_A Electrical phase A.

PHASE_B Electrical phase B.

PHASE_C Electrical phase C.

PHASE_NA Phase not applicable.

enum_ReportContentType
This enumeration defines the general data structures found in ASCII reports. It
is used in coordination with regular expressions to aid in the formatting of the
output report file.

Enumeration Description

SEQUENCE Repeating data pattern consistent with table-formatted time-series


report data.

SUMMARY Single-instance data label from ASCII or CASCII response.

enum_87LDataPoint411L
This enumeration allows for association between a given logic engine tag
and an expected data point from an SEL-411L COM 87L report or associated
SER tags from the IED. The enumeration is labeled with a trailing data
type indicator to assist in assigning the appropriate optional input in the
class_87LCommMonitor411L.Bootstrap_MonitoredDataPoint()
method.

Enumeration Description

e_87HSB_SPS 87HSB Relay Word bit

e_87USAFE_SPS 87USAFE Relay Word bit

Programming Reference Date Code 20241023


ConditionMonitoring 105
Structures

Enumeration Description

e_87TOK_SPS 87TOK Relay Word bit

e_87BCH_SPS 87BCH Relay Word bit

e_87BLK_SPS 87BLK Relay Word bit

e_87LST_SPS 87LST Relay Word bit

e_87BLKL_SPS 87BLKL Relay Word bit

e_87SYNL_SPS 87SYNL Relay Word bit

e_87LSP_SPS 87LSP Relay Word bit

e_87ERR1_SPS 87ERR1 Relay Word bit

e_87ERR2_SPS 87ERR2 Relay Word bit

e_END_OF_SER_TAGS

e_24HR_LOST_PACKETS_INS 24-hour lost packet count from the COM 87L report

e_87L_PROTECTION_EN_STATUS_STR Enabled status from the COM 87L report

e_87L_SYNCH_STATUS_STR Synch status from the COM 87L report

e_87L_GENERAL_CHANNEL_ALARM_STR Channel Status from the COM 87L report

e_87L_PRIMARY_AVAILABILITY_MV Availability (in percent) of primary channel from the COM 87L report

e_87L_MAX_24HR_LOST_PACKETS_INS Maximum lost packets in a 24-hour period from the COM 87L report

e_87L_MAX_ROUND_TRIP_DELAY_MV Maximum round-trip delay from the COM 87L report

e_87L_MAX_TRANSMIT_DELAY_MV Maximum transmit delay from the COM 87L report

e_87L_MAX_RECEIVE_DELAY_MV Maximum receive delay from COM 87L report.

e_87L_MAX_ASYMMETRY_MV Maximum asymmetry from the COM 87L report

e_END_OF_ENUM

Structures
struct_CTPTGroupStatus
This structure contains status information relevant to all monitored assets of a
given class instance.

Name IEC 61131 Type Description

MonitorID STRING(255) The user-programmed ID string for the class instance.

Warning_SCADA BOOL Class instance warning indication using a fixed dropout time.

Warning_SOE BOOL Class instance warning indication using a dynamic dropout time.

Alert BOOL Class instance alarm indication.

AlertTimestamp dateTime_t Time stamp of Alarm assertion. Updates on AlertEdge.

AlertEdge BOOL Asserts for one task cycle on the rising edge of any monitored asset
Alert.stVal.

StatusDescription STRING(255) Information pertaining to the asserted state of Warning and/or Alarm.

Date Code 20241023 Programming Reference


106 ConditionMonitoring
Structures

Name IEC 61131 Type Description

AveMagPercentDeviation REAL Group average of the filtered magnitude percent deviation for all
bootstrapped monitored channels.

AveAngleDeviation REAL In degrees. Group average of the filtered angle deviation for all phases
and subgroups.

WarningSCADADropoutTimerActive BOOL TRUE if Warning_SCADA is being held TRUE by an associated


dropout timer.

WarningSOEDropoutTimerActive BOOL TRUE if Warning_SOE is being held TRUE by an associated dropout


timer.

AlertDropoutTimerActive BOOL TRUE if Alarm is being held TRUE by an associated dropout timer.

struct_CTPTStatusOutput
This structure contains the status information for a single monitored CT or PT.

Name IEC 61131 Type Description

CtPtID STRING(255) Asset identification string.

Phase enum_PhaseID Electrical phase of the asset.

MonitorEnabled BOOL The channel monitor for the specified CT or PT is enabled.

Alert SPS A non-latching, time-stamped asset health alert.

AlertMag REAL Snapshot of the monitored channel magnitude, taken on the rising edge of Alert.stVal.
Equals zero while Alert.stVal is FALSE.

PercentDeviation REAL Percent magnitude deviation of the monitored channel from the reference. Updates
continuously.

AngleDeviation REAL Angle deviation (degrees) of the monitored channel angle from the reference. Updates
continuously.

ReferenceMeasurement REAL Reference against which the monitored channel is compared.

QualityAlert BOOL Quality alarm for associated measurements.

NodeGroup STRING(255) List of node indexes associated with the assets' monitor group.

Status STRING(255) Description of the current monitor status.

struct_DetailColLabel
This structure specifies a label and data class for a given column in a Detail CSV
file.

Name IEC 61131 Type Description

Label STRING(255) Data point label.

DataClass enum_GenericDataClass Indication of how this data column should be interpreted by a receiving algorithm.

Programming Reference Date Code 20241023


ConditionMonitoring 107
Interfaces

struct_GenericDataPoint
This structure specifies a single value and associated data class.

Name IEC 61131 Type Description

AnalogVal REAL An analog quantity.

BoolVal BOOL A Boolean quantity.

StringVal STRING(255) A string quantity.

DataClass enum_GenericDataClass The class of data populated in this structure.

Interfaces
I_Cm (Interface)
This interface is implemented by any class in the ConditionMonitoring library
that requires specifically formatted data logging to CSV report files. This
interface is intended to be used with class_CmReportWriter. This interface
supports the logging of data for two use cases.

1. Human-readable CSV reports. Event-driven SOE and periodic summary


data.
2. Machine-readable CSV reports. Event-driven detail data.

This interface enables the CSV formatting for and transfer of three categories of
content.

1. Sequence of Event (SOE): Event-driven data for a single asset. Contains


top-level warnings/alarms and concise supporting data.
2. Summary: Periodically or trigger-based polled data. Expected to contain
current general status or summary of one or more assets.
3. Detail: Event-driven data for a single asset. Contains all relevant data
associated with the event.

These reports are described in detail in the class_CmReportWriter section.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

NumAvailableDetailRows UDINT R The number of rows of STRING(255)s available from the


implementing class, to be written to the Detail file.

NumAvailableSoeRows UDINT R The number of rows of STRING(255)s available from the


implementing class to be written to the SOE portion of the SOE/
Summary file.

NumAvailableSummaryRows UDINT R The number of rows of STRING(255)s available from the


implementing class to be written to the Summary portion of the
SOE/Summary file.

Date Code 20241023 Programming Reference


108 ConditionMonitoring
Interfaces

Name IEC 61131 Type Access Description

pt_History POINTER R/W Optional pointer to a DescriptiveData.class_CsvManager instance.


This is intended to provide the implementing class the ability to
retrieve its own historic data for processing and the generation of
new summary content.

ReportingBootstrapped BOOL R/W Indicates that an implementing class has been bootstrapped into an
application that processes the I_Cm interface.

SummaryOrder UINT(0–1) R Allows the implementing class to specify whether the summary
data should appear to the left (0) or right (1) of the SOE data in the
output SOE/Summary CSV file.

NewSoeFile BOOL R/W Indicates whether the next available SOE/Summary content should
be written to a new file.

NewDetailFile BOOL R/W Indicates whether the next available Detail content should be written
to a new file.

GetDetailColLabels (Method)
This method allows the implementing class to specify the column label
information that will appear for its columns in the Detail CSV file. A queue
object is provided for the implementing class to populate. An implementing
class can opt to bypass the generation/processing of the Detail file by
leaving this method implementation blank.

Inputs/Outputs

Name IEC 61131 Type Description

LabelQ Queue.class_Deque Double-ended queue with elementSize =


SIZEOF(struct_DetailColLabel)

GetSoeColLabels (Method)
This method allows the implementing class to specify the SOE column label
information that will appear for its columns in the SOE/Summary CSV
file. A queue object is provided for the implementing class to populate.
An implementing class can opt to bypass the generation/processing
of SOE content within the SOE/Summary file by leaving this method
implementation blank.

Inputs/Outputs

Name IEC 61131 Type Description

LabelQ Queue.class_Deque Double-ended queue with elementSize =


SIZEOF(STRING(255))

Programming Reference Date Code 20241023


ConditionMonitoring 109
Interfaces

GetSummaryColLabels (Method)
This method allows the implementing class to specify the Summary column
label information that will appear for its columns in the SOE/Summary CSV
file. A queue object is provided for the implementing class to populate.
An implementing class can opt to bypass the generation/processing of
Summary content within the SOE/Summary file by leaving this method
implementation blank.

Inputs/Outputs
Name IEC 61131 Type Description

labelQ Queue.class_Deque Double-ended queue with elementSize =


SIZEOF(STRING(255))

GetDetailRow (Method)
This method allows an implementing class to transfer a set of data points to be
represented on a single row of the Detail CSV file.

Inputs/Outputs
Name IEC 61131 Type Description

rowQ Queue.class_Deque Double-ended queue with elementSize =


SIZEOF(struct_GenericDataPoint)

Outputs
Name IEC 61131 Type Description

timeStamp sel_iec_types.timeStamp_t A time stamp to appear on the time-stamp


column for this row in the Detail CSV file.

Return Value
IEC 61131 Type Description

BOOL TRUE if the queue was populated successfully.

GetSoeRow (Method)
This method allows an implementing class to transfer a set of strings to be
represented in SOE columns on a single row of the SOE/CSV file. The order in
which strings are loaded into the provided queue should correspond to the queue
order in which SOE labels were provided via the GetSoeColLabels method.

Inputs/Outputs
Name IEC 61131 Type Description

rowQ Queue.class_Deque Double-ended queue with elementSize =


SIZEOF(STRING(255)).

Date Code 20241023 Programming Reference


110 ConditionMonitoring
Classes

Outputs
Name IEC 61131 Type Description

timeStamp sel_iec_types.timeStamp_t A time stamp to appear on the time-stamp


column for this row in the Detail CSV file.

assetID STRING(255) An identifier for the asset that the SOE content
pertains to.

Return Value
IEC 61131 Type Description

BOOL TRUE if the queue was populated successfully.

GetSummaryRow (Method)
This method allows an implementing class to transfer a set of strings to be
represented on a single row of the SOE/CSV file. The order in which strings are
loaded into the provided queue should correspond to the queue order in which
summary labels were provided via the GetSummaryColLabels method.

Inputs/Outputs
Name IEC 61131 Type Description

rowQ Queue.class_Deque Double-ended queue with elementSize =


SIZEOF(STRING(255))

Outputs
Name IEC 61131 Type Description

timeStamp sel_iec_types.timeStamp_t A time stamp that appears in the time-stamp


column for this row in the Detail CSV file.

assetID STRING(255) An identifier for the asset to which the SOE


content pertains.

Return Value
IEC 61131 Type Description

BOOL TRUE if the queue was populated successfully.

Classes
class_87LCommMonitor411L (Class)
This class implements a communications integrity monitor for differential
protection communications. This class is intended for use with SEL-411L clients
over the SEL protocol and supports the 87L Comm Monitor extension.

Programming Reference Date Code 20241023


ConditionMonitoring 111
Classes

This class should be operated via the following sequence:

➤ Call the Bootstrap_MonitoredDataPoint() method for each tag to


be monitored.
➤ Call Initialize().
➤ Call Run() once per scan.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface, all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Cm

Inputs
Name IEC 61131 Type Description

EnableSoeLogging BOOL Set to TRUE to log 87L Comm alerts to the RTAC SOE.

EnableReportContent BOOL Set to TRUE to enable Report Content Creation.

EnableRoundRobinPolling BOOL Set to TRUE to enforce serial Flex parse polling amongst multiple
class instances.

LostPacketCountThreshold24Hr UDINT The threshold at which the lost packet alert is asserted.

PrimaryAvailabilityThreshold REAL The threshold at which the primary channel availability alert will be
asserted.

COM87LPollPeriod UINT(0..24) The Com 87L report poll period in hours.

COM87LResetPeriod UDINT The COM 87L statistics reset period in hours. Set to zero for
triggered-only resets.

pt_COM87LPollTrigger POINTER TO The address of 87L Poll Trigger.


BOOL

pt_SendFlexParse_COM_87L POINTER TO The ddress of the IED Flex parse Send POU input pin for COM
BOOL 87L.

pt_FlexParseDone_COM_87L POINTER TO The address of the IED Flex parse Done POU output pin for COM
BOOL 87L.

pt_COM87LResetTrigger POINTER TO The address of the 87L Statistics Reset Trigger.


BOOL

pt_SendFlexParse_COM_87L_CR POINTER TO The address of the IED Flex parse Send POU input pin for COM
BOOL 87L C/R.

pt_FlexParseTag_E87CH POINTER TO The Address of the IED Flex parse STR tag containing the E87CH
sel_iec_types.STR setting value. The expected response is one of 2SS, 2SD, 3SS, 3SM,
E2, E3, or E4.

InstanceName STRING(255) The SEL-411L Client Identifier for logging.

Date Code 20241023 Programming Reference


112 ConditionMonitoring
Classes

Outputs
Name IEC 61131 Type Description

Error BOOL If TRUE, indicates an internal error.

StatusMessage STRING(255) A description of the current operational state.

Status87L STR The last reported 87L Monitor Alert Message.

Alert87L BOOL Pulses for one cycle if any monitored data point
enters an alert state.

Initialized BOOL TRUE if the class is initialized successfully.

Busy BOOL TRUE if the class has pulsed the Boolean at


pt_SendFlexParse_COM_87L and is waiting for
the SEL client to assert the associated "Done"
Boolean.

Implementation of the I_Cm Interface


This class supports the following I_Cm interface implementation.
➤ This class supports the SOE/Summary file, providing both event-driven
SOE data and summary information through the associated interface
methods and properties.
➤ The Detail file is not supported. Therefore, associated methods
and properties such as GetDetailColLabels(method) and
NewDetailFile(property) are not implemented.
➤ GetSoeRow().AssetID output is populated with the InstanceName class
input.
➤ SOE column labels:
➢ Alert Message
➢ Time-stamp From COM 87L Report
➤ The NumAvailableSoeRows property increments on the rising edge of any
alert condition for any bootstrapped data point and decrements upon a call
to GetSoeRow():
➤ The timeStamp output of the GetSoeRow() method is the time-stamp
value of the bootstrapped data point at the rising edge of the alert. If
NumAvailableSoeRows is zero, the time stamp is "epoch".
➤ The Alert Message column provides a detailed alert status for a given
bootstrapped data point that is in an alarm state.
➤ The Time-stamp From COM 87L Report column shall be populated
accordingly for the following two scenarios:
➢ For monitored data points with DataDefinition containing "MAX",
the string shall be the time-stamp string from the COM 87L report
associated with that maximum value.
➢ For all other monitored data points, the string shall be "NA".
➤ Summary column labels:
➢ Summary Status
➤ One summary row is available which presents the following:
➢ <InstanceName> - Alert assertions since last summary : <alert tally>
➢ Active alerts : <number of bootstrapped data points in an alert state>

Programming Reference Date Code 20241023


ConditionMonitoring 113
Classes

➤ When GetSummaryRow() is called, the <alert tally> is reset.


➤ The timeStamp output of the GetSummaryRow() method shall represent
the RTAC system time at the time of calling GetSummaryRow().
➤ SummaryOrder = 0 (indicating that summary data shall appear to the left
of the SOE data).

Bootstrap_MonitoredDataPoint (Method)
Bootstrap a logic engine tag and associated metadata for a data channel that
sources 87L communications status from an IED.

Inputs

Name IEC 61131 Type Description

ChannelNumber UINT(0..4) The 87L Comms channel to associate with the data point. Set to 0 to indicate a
globally applicable data point.

pt_OutputChannel POINTER TO SPS The address of the tag to receive the alert status for this monitored data point.

DataDefinition enum_87LDataPoint411L Associates the bootstrapped data point with a specific 87L Comms status
element from the IED.

pt_DataPointINS POINTER TO INS (Optional) The address of an INS tag to monitor. Should correspond with a
DataDefinition ending in _INS.

pt_DataPointMV POINTER TO MV (Optional) The address of an MV tag to monitor. Should correspond with a
DataDefinition ending in _MV.

pt_DataPointSPS POINTER TO SPS (Optional) The address of an SPS tag to monitor. Should correspond with a
DataDefinition ending in _SPS.

pt_DataPointSTR POINTER TO STR (Optional) The address of an STR tag to monitor. Should correspond with a
DataDefinition ending in _STR.

pt_SynchConfig POINTER TO STR (Optional) The address of an STR tag representing the synch status element
of a COM 87L IED report. Must be assigned when DataDefinition =
e_87L_SYNCH_STATUS.

pt_ChannelRole POINTER TO STR (Optional) The address of an STR tag representing the Channel Role element of
a COM 87L IED report. This input must be assigned when MonitoredPointType
= e_87L_PRIMARY_AVAILABILITY_MV.

pt_2sdRole POINTER TO STR (Optional) The address of an STR tag representing the 2SD Role element of a
COM 87L IED report. This input must be assigned when MonitoredPointType =
e_87L_PRIMARY_AVAILABILITY_MV.

pt_MaxTimestamp POINTER TO (Optional) The address of an STR tag representing a time-stamp string from a
sel_iec_types.STR COM 87L IED report. This string will be used as the time stamp for logging and
alerts for this monitored data point.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors are encountered.

Date Code 20241023 Programming Reference


114 ConditionMonitoring
Classes

Processing
Returns FALSE if any of the following conditions are true:
➤ Initialize() was called and returned TRUE prior to the call to
Bootstrap_MonitoredDataPoint().
➤ DataDefinition is an invalid enum_87LDataPoint411L value. (Valid
entries include all enum values except e_END_OF_SER_TAGS and
e_END_OF_ENUM.)
➤ There exists a data type mismatch between the assigned
pt_DataPointXXX and the data type indicated in the value of the
DataDefinition input.
➤ DataDefinition = e_87L_SYNCH_STATUS_STR and pt_SynchConfig
is not assigned or is assigned a value of 0.
➤ DataDefinition = e_87L_PRIMARY_AVAILABILITY_MV and either
pt_ChannelRole or pt_2sdRole are not assigned or are assigned a value of
0.
If the method returns FALSE, the class Error output will be asserted and the
class ErrorMessage will be updated accordingly.

Initialize (Method)
This method completes the initialization of the class and should be called after
all calls to Bootstrap_MonitoredDataPoint().

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if no errors are encountered.

Processing
Returns FALSE if any of the following conditions are true:
➤ Initialize() was already called and returned TRUE.
➤ No data points have been bootstrapped via
Bootstrap_MonitoredDataPoint().
➤ Class input pt_SendFlexParse_COM_87L is unassigned or equals zero.
➤ Class input pt_FlexParseDone_COM_87L is unassigned or equals zero.
➤ Class input pt_FlexParseTag_E87CH is unassigned or equals zero.
➤ Class input pt_SendFlexParse_COM_87L_CR is unassigned
or equals zero while either class input COM87LResetPeriod or
pt_COM87ResetTrigger is non-zero.
If the method returns FALSE, the class Error output will be asserted and the
class ErrorMessage will be updated accordingly.

Run (Method)
Call this method each processing interval after completing all necessary calls to
Bootstrap_MonitoredDataPoint() and Initialize().

Programming Reference Date Code 20241023


ConditionMonitoring 115
Classes

Processing
➤ Sets Initialized to TRUE if Initialize() was called and returned
TRUE followed by successful configuration, as described below (requires
subsequent calls to the Run() method):
➢ The COM 87L Flex parse response was received from the IED. The
87L operational mode is read from the associated STR tag pointed
to by pt_FlexParseTag_E87CH. Configuration is successful if the
associated string equals 2SS, 2SD, 3SS, 2SM, 2E, 3E, or 4E.
If a response is not received within 30 seconds, the Flex parse send will
be re-triggered. This process will repeat five times. If no response is
received, this method sets Error = TRUE and applies an associated
message to StatusMessage.
➤ If Initialized = TRUE, performs the following:
➢ The class will pulse the Boolean at pt_SendFlexParse_COM_87L
for one task cycle at the rate specified by the class input
COM87LPollPeriod and on the rising edge of the Boolean at
pt_COM87LPollTrigger.
➢ Once pt_SendFlexParse_COM_87L is pulsed, the class will set
Busy := TRUE. Upon reading an assertion of the associated Flex
parse Done Boolean, the class will assess the tags associated with the
given Flex parse message. The class then sets Busy := FALSE.
➢ Tags associated with an unsolicited SER source will be assessed
during each scan.
➢ If the EnableRoundRobinPolling class input is TRUE, the class
instance will wait to pulse the given Flex parse Send Boolean until
neither itself nor any other class instance has Busy = TRUE.
➢ The Status87L class output will be assigned the alert message for
the most recent alert condition. The .t attribute will be mapped
directly from the bootstrapped data point associated with the message
and .q.validity is set to good.
➢ The Alert87L Boolean will pulse for one task cycle if an alert is
asserted for any bootstrapped data point.
➢ If an alert is asserted for any bootstrapped data point, the SPS at
address Bootstrap_MonitoredDataPoint.pt_OutputChannel will
be updated as described in Additional Processing Information on
page 116.
➢ The class will pulse the Boolean at pt_SendFlexParse_COM_87L_CR
for one task cycle at the rate specified by the class input
COM87LResetPeriod and on the rising edge of the Boolean at
pt_COM87LResetTrigger.

Date Code 20241023 Programming Reference


116 ConditionMonitoring
Classes

Additional Processing Information


The class instance assesses all bootstrapped data points in accordance with the
following table.

Expected
enum_87LDataPoint411L Alert Condition TRUE When...
Source

e_87HSB_SPS Unsolicited SER This data point asserts greater than 5 times in 24 hours

e_87USAFE_SPS Unsolicited SER This data point asserts greater than 5 times in 1 hour

e_87TOK_SPS Unsolicited SER This data point deasserts

e_87BCH_SPS Unsolicited SER This data point asserts

e_87BLK_SPS Unsolicited SER This data point asserts

e_87LST_SPS Unsolicited SER This data point asserts

e_87BLKL_SPS Unsolicited SER This data point asserts

e_87SYNL_SPS Unsolicited SER This data point asserts

e_87LSP_SPS Unsolicited SER This data point asserts

e_87ERR1_SPS Unsolicited SER This data point asserts

e_87ERR2_SPS Unsolicited SER This data point asserts

e_24HR_LOST_PACKETS_INS Flex Parsea This data point exceeds the 24Hr Lost Packet Threshold
a
e_87L_PROTECTION_EN_STATUS_STR Flex Parse This data point contains "DISABLED" or "IN TEST"

e_87L_SYNCH_STATUS_STR Flex Parsea Value equals "Channel-based" and Synch Config value
equals "Ext-time-based".

e_87L_GENERAL_CHANNEL_ALARM_STR Flex Parsea This data point equals "ALARM"


a
e_87L_PRIMARY_AVAILABILITY_MV Flex Parse Value exceeds Primary Availability Threshold, 2sdRole is
"Primary", and ChannelRole is "In use".

e_87L_MAX_24HR_LOST_PACKETS_INS Flex Parsea A new maximum is observed

e_87L_MAX_ROUND_TRIP_DELAY_MV Flex Parsea A new maximum is observed


a
e_87L_MAX_TRANSMIT_DELAY_MV Flex Parse A new maximum is observed

e_87L_MAX_RECEIVE_DELAY_MV Flex Parsea A new maximum is observed


a
e_87L_MAX_ASYMMETRY_MV Flex Parse A new maximum is observed
a
Indicates a Flex parse message that includes the COM 87L command on the SEL-411L client.

Data points associated with certain enum_87LDataPoint411L values will


not be assessed during runtime, depending on the value of the string at
pt_FlexParseTag_E87CH as listed in the table below.

pt_FlexParseTag_E87CH^.strVal Data Points Not Assessed

2SS, 3SS e_87L_PRIMARY_AVAILABILITY_MV

2E, 3E, 4E e_87L_MAX_ROUND_TRIP_DELAY_MV,


e_87L_MAX_TRANSMIT_DELAY_MV,
e_87L_MAX_ASYMMETRY_MV

Programming Reference Date Code 20241023


ConditionMonitoring 117
Classes

The SPS tag at address Bootstrap_MonitoredDataPoint.pt_OutputChannel for a


given bootstrapped data point is updated as shown in the following table.

SPS Attribute Assignment Description

.q (quality_t) Direct mapping from the .q element of the Updates when the bootstrapped data point is
bootstrapped data point. assessed.

.t (timeStamp_t) Direct mapping from the .t element of the Updates when the bootstrapped data point is assessed
bootstrapped data point. If the bootstrapped data and the alert condition changes state.
point is a non-null pt_MaxTimestamp pointer, the
time stamp is interpreted from the associated time
stamp string.

.stVal (BOOL) TRUE/FALSE TRUE when the data point is assessed and the alert
condition is TRUE. FALSE when the data point is
assessed and the alert condition is FALSE.

Data points are evaluated conditionally depending on the associated data source.
The following table describes when data points of a given source are evaluated.

Data Source Associated tags are assessed...

Unsolicited SER At each call of the Run() method.

COM 87L Flex When Run() is called while the BOOL at pt_FlexParseDone_COM_87L
Parse is TRUE (about once per COM87lPollPeriod).

class_StreamingCTPTMonitor (Class)
This class implements a monitor for health assessment of power system CTs
and PTs through use of streaming data from connected IEDs. The method of
operation is rooted in sample-by-sample comparative analysis between recorded
measurements from a given CT or PT and a reference measurement. In this
way, notable differences in measurements among the redundant measurement
transformers can be flagged as a transformer malfunction. The following
diagram shows one example topology for which this monitoring system can be
applied.

Figure 5.1 Redundant Source and Load-Side CT Monitoring Group on a Single


Feeder Line

A scaling factor setting is provided in order to optionally incorporate CTs or


PTs into a redundant CT/PT group that would otherwise be excluded due to
separation via a power transformer. The following diagram depicts a three-
CT monitoring group whose low-side CT measurements must be scaled as a
condition for inclusion in the group.

Date Code 20241023 Programming Reference


118 ConditionMonitoring
Classes

Figure 5.2 CT Monitoring Group With Applied Scaling for Transformer Low-Side
CTs

For topology-dependent monitoring schemes, (e.g., all PTs in a breaker-and-a-


half scheme) breaker and disconnect switch information can be added via the
bootstrap_BreakerSwitch() method.

NOTE
It is assumed that all assets that are connected via the node ID values
produce measurements that are directly comparable to each other. It is the
responsibility of the user to program the appropriate node ID values when
calling the various bootstrap methods in order to satisfy this assumption.

➤ This excludes complex topology monitoring schemes for CTs because the
necessity of current summation violates this assumption.
➤ Breaker/switch information is only incorporated into the monitoring
scheme when Initialize.MonitorMode = RELATIVE_REFERENCE.

The following diagram shows an example for which breaker and switch status
information can be used by the class to dynamically assess changes in circuit
topology and create one or more monitor groups as needed.

Figure 5.3 PT Monitoring Group for a Two-Branch Breaker-and-a-Half Scheme

Programming Reference Date Code 20241023


ConditionMonitoring 119
Classes

This class should be operated via the following sequence:

1. Before calling any method, assign values to the class inputs if non-
default values are required. Note that class_StreamingCTPTMonitor will
monitor either by angle or by magnitude, depending on the value of the
InputTypeIsAngle class input.
2. If using enum_CTPT_MonitorMode = DEFINED_REFERENCE, call the
appropriate bootstrap method for the reference CT(s) or PT(s).
3. Call the appropriate bootstrap method for each monitored CT or PT for a
given power system asset.
4. If using breaker/switch status information for a dynamic topology
monitoring scheme, call the bootstrap_BreakerSwitch() method as
many times as needed.
5. Once all bootstrap operations are complete, call the Initialize()
method to assign the Global settings.
6. After Initialize() is called and returns TRUE, call Run() once per
task cycle.
7. The outputs assigned via the bootstrap method calls will be continuously
updated with CT/PT status information.

This class supports the following data types for delivery of CT/PT
measurements:

➤ CMV
➤ MV
➤ INS

This class supports the SPS data type for delivery of breaker/switch status
information.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Cm

Class I/O
Inputs
Name IEC 61131 Type Description

InputTypeIsAngle BOOL If TRUE, input measurements (MV.instMag and INS.stVal) will be monitored as an
angle in degrees. Similarly, CMV.instCVal.ang will be monitored. If FALSE, input
measurements (Mv.instMag and INS.stVal) will be monitored as magnitudes and
CMV.instCVal.mag will be monitored. Defaults to FALSE.

InstanceName STRING(255) Unique name of the class instance. Used for reporting purposes. Must conform to
sel_file naming requirements.

ChatterCountThreshold UDINT Limit of channel excursions beyond Initialize().AlarmThreshold within


Initialize().AlarmPickupTime before Alert.stVal asserts. Defaults to 1000.

Date Code 20241023 Programming Reference


120 ConditionMonitoring
Classes

Outputs

Name IEC 61131 Type Description

Error BOOL Indicates an internal error.

ErrorMessage STRING(255) Description of the current error state.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

GroupStatus struct_CtPtGroupStatus R Cumulative status of all bootstrapped monitored channels.

Implementation of the GroupStatus Property


This class provides a property of type struct_CtPtGroupStatus, called Status.
This property is populated as follows.

➤ MonitorID is populated with the user-specified class input


InstanceName.
➤ Warning_SCADA and Warning_SOE are asserted if any of the
following are true for the struct_CTPTStatusOutput for any monitored
asset on any phase. This is referenced below as the Warning condition.
1. MonitorEnabled = FALSE
2. QualityAlert = TRUE
➤ Warning_SCADA will remain asserted after an above warning
condition clears for a duration of 10 seconds. During this period,
WarningSCADADropoutTimerActive is asserted.
➤ Warning_SOE will remain asserted after an above warning condition
clears for a minimum of 10 seconds and a maximum of 60 minutes.
During this period, WarningSOEDropoutTimerActive is asserted.
If a new warning condition is observed within 10 seconds after the
deassertion of Warning_SOE, then the associated dropout time is doubled.
If no new warning condition is observed within 10 seconds after the
deassertion of Warning_SOE, the associated dropout time is set to 10
seconds. This dynamic dropout time logic is implemented to aid in
minimizing excess logging of chattering warning conditions and is
depicted in Figure 5.4.
➤ Warning_SOE and Warning_SCADA follow the status of the
Initialize.Enable input without delay, as depicted in Figure 5.4.
➤ Alert is asserted if any monitored asset on any phase has Alert.stVal
= TRUE.
➤ Alert will remain asserted after the above condition clears for a duration
of Initialize.AlarmPickupTime seconds. During this period.
AlarmDropoutTimerActive is asserted.

Programming Reference Date Code 20241023


ConditionMonitoring 121
Classes

➤ AlertTimestamp is populated with the t.value.dateTime attribute


of the struct_CTPTStatusOutput.Alert element of any monitored
channel that observes a struct_CTPTStatusOutput.Alert.stVal
assertion on the given task cycle.
➤ AlertEdge will pulse for one cycle on the rising edge of any monitored
channel struct_CTPTStatusOutput.Alert.stVal element.
The following figure depicts the pickup/dropout behavior of the Alarm/
Warning indicators.

Figure 5.4 Warning/Alarm Pickup/Dropout Behavior

➤ AveragePercentDeviation and AverageAngleDeviation represent


a group average of the approximated rolling averages of the
instantaneous struct_CTPTStatusOutput.PercentDeviation or
struct_CTPTStatusOutput.AngleDeviation values, respectively.
These indicators are intended to provide useful information about the
average group deviation from the reference with minimal influence by
outliers (channels in an alert state). The per-channel rolling average is
approximated via the following recursive calculation.

Equation 5.1

where:
➢ Ave(k–1) is initialized to 0 at the start of runtime.
➢ i is initialized to 1 at the start of runtime and increments once per
sample.
➢ i is gated at imax where imax is determined by the following equation.

Equation 5.2

where AveMessageRate is an approximation of the average of the last


20 inverse time differences between consecutive outputs of the time
alignment process.
Per-channel rolling averages are approximated while
struct_CTPTStatusOutput.Alert.stVal = FALSE for the given
channel. While in an alert state, the average is not updated.

Date Code 20241023 Programming Reference


122 ConditionMonitoring
Classes

These group averages (AveragePercentDeviation and


AverageAngleDeviation) represent all bootstrapped monitored channels
with the exception of any channel for which any of the following are true:
➢ struct_CTPTStatusOutput.Alert.stVal = TRUE and Status
indicates 'EXPIRATION'.
➢ struct_CTPTStatusOutput.MonitorEnabled = FALSE
➢ struct_CTPTStatusOutput.QualityAlert = TRUE
➤ StatusDescription is populated as follows:
➢ On the rising edge of Alert, StatusDescription is populated with
'Asset Alert :' followed by a comma-delimited list of CtPt indexes for
assets that satisfy the above Alert condition.
➢ If Alert = FALSE, then on the rising edge of Warning_SCADA or
Warning_SOE:
➣ If all assets in Warning report the same internal status string,
StatusDescription is populated with that string followed by a
comma-delimited list of CtPt index positions for assets that satisfy
the above Warning condition.
➣ If not all assets in Warning report the same internal status
string, StatusDescription is populated with 'Monitor disabled or
quality issue : ' followed by a comma-delimited list of CtPt index
positions for assets that satisfy the above Warning condition.

Implementation of the I_Cm Interface


This class supports the following I_Cm interface implementation.

1. GetSoeRow().AssetID format : <InstanceName>:<CtPtID>


2. The timeStamp output of GetDetailRow(), GetSoeRow(), and
GetSummaryRow() equals the return of SYS_TIME() at the time of
calling the associated method.
3. SOE column labels:
➤ Alert Mag
➤ Angle Deviation
➤ Percent Mag Deviation
➤ Reference Measurement
➤ Alert
➤ Monitor Disabled
➤ Quality Alert
➤ Status
➤ Monitor Group
4. SOE row entries shall include as many as 80 comma-delimited CtPt IDs,
starting at 'Monitor Group' column.
5. Summary column labels:
➤ Summary Element
➤ Summary Value

Programming Reference Date Code 20241023


ConditionMonitoring 123
Classes

6. Three summary rows will be made available.


➤ <InstanceName>:Status : Status category for the group (NOMINAL/
WARNING/ALERT).
➤ <InstanceName>:Status Description : Additional information
describing the group status.
➤ <InstanceName>:Ave Group <Magnitude Percent>
<or> <Angle Deviation> : The current value of
the GroupStatus.AveragePercentDeviation or
GroupStatus.AverageAngleDeviation.
7. Detail column label format per bootstrapped CtPt:
<InstanceName>:<CtPtID>:<Data- Label>, where <DataLabel> is
defined below:
➤ Alert Mag (ANALOG)
➤ Angle Deviation (ANALOG)
➤ Percent Mag Deviation (ANALOG)
➤ Reference Measurement (ANALOG)
➤ Status (STRING)
8. The content loaded into the rowQ variable by GetDetailRow(),
GetSoeRow(), and GetSummaryRow() is sourced from the
struct_CTPTStatusOutput structure for the given asset.
9. SummaryOrder = 0 (indicating that summary data shall appear to the left
of the SOE data).
10. The NumAvailableSoeRows property increments for any monitored
channel on either of the following conditions and will decrement upon a
call to GetSoeRow():
➤ Rising edge of Alert.stVal
➤ Rising edge of QualityAlert OR NOT MonitorEnabled
11. The NumAvailableDetailRows property increments for any monitored
channel on the following condition and will decrement upon a call to
GetDetailRow():
➤ Rising edge of Alert.stVal
12. The NumAvailableSummaryRows property is set to 3 and will decrement
upon a call to GetSummaryRow(). When this property equals 0, it is set
back to 3 after a 5-second dropout period.

Bootstrap Methods
The following methods initialize all measurement channels and associated
metadata for monitored CT/PTs, reference CT/PTs, and breakers/switches. A
bootstrap method should be called for each CT or PT to be monitored by the
class_StreamingCTPTMonitor instance. Several bootstrap methods are provided
to support the various data types through which CT/PT data may be delivered.

bootstrap_MonitoredCMV (Method)
Bootstrap a monitored CT or PT whose measurements are delivered as a
magnitude/angle pair via a CMV data type.

Date Code 20241023 Programming Reference


124 ConditionMonitoring
Classes

NOTE
When initialization input InputTypeIsAngle = TRUE, the .instCVal.ang
is used for monitoring. Otherwise, .instCVal.mag is used.

Inputs/Outputs

Name IEC 61131 Type Description

Channel CMV The CT or PT data channel to be monitored.

StatusOutput struct_CTPTStatusOutput The target structure to be updated with monitored status information for the given CT
or PT.

Inputs

Name IEC 61131 Type Description

CtPtID STRING(255) A string identifier for the CT or PT.

Phase enum_PhaseID The electrical phase represented by the channel.

ScaleFactor REAL Scale factor for transformer turns ratio compensation. Defaults to 1.0. Else defaults to 0.

RotationFactor REAL Angle rotation factor for transformer turns ratio compensation. Defaults to 0. Disregarded if
class input InputTypeIsAngle = FALSE.

NodeID UINT Topology node index (1–64) to which the asset is connected. Will be disregarded during
runtime if Initialize.MonitorMode = DEFINED_REFERENCE.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if NodeID is outside of the specified bounds.
➤ Returns FALSE if class input InputTypeIsAngle = TRUE and
RotationFactor is outside the range (–180 to 180).

bootstrap_MonitoredMV (Method)
Bootstrap a monitored CT or PT whose measurements are represented as an MV
data type.

NOTE
The .instMag portion the MV is used for monitoring.

Inputs/Outputs

Name IEC 61131 Type Description

Channel MV The CT or PT data channel to be monitored.

StatusOutput struct_CTPTStatusOutput The target structure to be updated with monitored status information for the given CT
or PT.

Programming Reference Date Code 20241023


ConditionMonitoring 125
Classes

Inputs

Name IEC 61131 Type Description

CtPtID STRING(255) A string identifier for the CT or PT.

Phase enum_PhaseID The electrical phase represented by the channel.

ScaleFactor REAL Scale factor for transformer turns ratio or angle rotation compensation. Defaults to 1.0 if class
input InputTypeIsAngle = FALSE. Else defaults to 0.

NodeID UINT Topology node index (1–64) to which the asset is connected. Will be disregarded during
runtime if Initialize.MonitorMode = DEFINED_REFERENCE.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if NodeID is outside of the specified bounds.
➤ Returns FALSE if class input InputTypeIsAngle = TRUE and
ScaleFactor is outside the range (–180 to 180).

bootstrap_MonitoredINS (Method)
Bootstrap a monitored CT or PT whose measurements are represented as an INS
data type.

Inputs/Outputs

Name IEC 61131 Type Description

Channel INS The CT or PT data channel to be monitored.

StatusOutput struct_CTPTStatusOutput The target structure to be updated with monitored status information for the given CT
or PT.

Inputs

Name IEC 61131 Type Description

CtPtID STRING(255) A string identifier for the CT or PT.

Phase enum_PhaseID The electrical phase represented by the channel.

ScaleFactor REAL Scale factor for transformer turns ratio or angle rotation compensation. Defaults to 1.0 if class
input InputTypeIsAngle = FALSE. Else defaults to 0.

NodeID UINT Topology node index (1–64) to which the asset is connected. Will be disregarded during
runtime if Initialize.MonitorMode = DEFINED_REFERENCE.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Date Code 20241023 Programming Reference


126 ConditionMonitoring
Classes

Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if NodeID is outside of the specified bounds.
➤ Returns FALSE if class input InputTypeIsAngle = TRUE and
ScaleFactor is outside the range (–180 to 180).

bootstrap_ReferenceCMV (Method)
Bootstrap a reference CT or PT whose measurements are delivered as a
magnitude/angle pair via a CMV data type.

NOTE
When initialization input InputTypeIsAngle = TRUE, the .instCVal.ang
is used for monitoring. Otherwise, .instCVal.mag is used.

When MonitorMode = DEFINED_REFERENCE has been passed into the


Initialize() method, all monitored CT/PTs for a given enum_PhaseID will
be evaluated against a reference with a matching enum_PhaseID.

Inputs/Outputs

Name IEC 61131 Type Description

Channel CMV The CT or PT data channel to be used as a reference for the specified phase.

Inputs

Name IEC 61131 Type Description

Phase enum_PhaseID The electrical phase represented by the channel.

ScaleFactor REAL Scale factor for transformer turns ratio or angle rotation compensation. Defaults to 1.0.

RotationFactor REAL Angle rotation factor for transformer turns ratio compensation. Defaults to 0. Disregarded if
class input InputTypeIsAngle = FALSE.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if a reference channel for the specified enum_PhaseID
was already bootstrapped.
➤ Returns FALSE if class input InputTypeIsAngle = TRUE and
RotationFactor is outside the range (–180 to 180).

bootstrap_ReferenceMV (Method)
Bootstrap a reference CT or PT whose measurements are represented as an MV
data type.

Programming Reference Date Code 20241023


ConditionMonitoring 127
Classes

NOTE
The .instMag portion of the MV is used for monitoring.

All monitored CT/PTs will be evaluated against the reference when


MonitorMode = DEFINED_REFERENCE has been passed into the
Initialize() method.

Inputs/Outputs

Name IEC 61131 Type Description

Channel MV The CT or PT data channel to be used as a reference for the specified phase.

Inputs

Name IEC 61131 Type Description

Phase enum_PhaseID The electrical phase represented by the channel.

ScaleFactor REAL Scale factor for transformer turns ratio or angle rotation compensation. Defaults to 1.0 if class
input InputTypeIsAngle = FALSE. Else defaults to 0.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if a reference channel for the specified enum_PhaseID
was already bootstrapped.
➤ Returns FALSE if class input InputTypeIsAngle = TRUE and
RotationFactor is outside the range (–180 to 180).

bootstrap_ReferenceINS (Method)
Bootstrap a reference CT or PT whose measurements are represented as an
INS data type. All monitored CT/PTs will be evaluated against the reference
when MonitorMode = DEFINED_REFERENCE has been passed into the
Initialize() method.

Inputs/Outputs

Name IEC 61131 Type Description

Channel INS The CT or PT data channel to be used as a reference for the specified phase.

Inputs

Name IEC 61131 Type Description

Phase enum_PhaseID The electrical phase represented by the channel.

ScaleFactor REAL Scale factor for transformer turns ratio or angle rotation compensation. Defaults to 1.0 if class
input InputTypeIsAngle = FALSE. Else defaults to 0.

Date Code 20241023 Programming Reference


128 ConditionMonitoring
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if a reference channel for the specified enum_PhaseID
was already bootstrapped.
➤ Returns FALSE if class input InputTypeIsAngle = TRUE and
ScaleFactor is outside the range (–180 to 180).

bootstrap_BreakerSwitch (Method)
Bootstrap a breaker or disconnect switch by specifying the status channel and
associated node IDs. The class uses breaker/switch status to dynamically assess
topology and create sub-groupings of monitored assets for relative reference
monitoring. Specify breaker information when monitoring PT schemes with
significant topology dependence (e.g., PTs across an entire breaker-and-a-half
scheme).

➤ Bootstrapped breakers/switches will only be incorporated during


runtime if MonitorMode = RELATIVE_REFERENCE is passed into the
Initialize() method.
➤ Breakers/switches are serial elements and require the specification of two
topology nodes.

Inputs

Name IEC 61131 Type Description

Phase enum_PhaseID The electrical phase associated with the breaker/switch.

NodeIdOne UINT Topology node (1–64) to which the asset is connected.

NodeIdTwo UINT Topology node (1–64) to which the asset is connected.

Inputs/Outputs

Name IEC 61131 Type Description

Status SPS Status element for the given breaker/switch. .stVal Interpreted as TRUE = closed.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if either node ID is outside of the specified range.

Programming Reference Date Code 20241023


ConditionMonitoring 129
Classes

Initialize (Method)
This method registers the global inputs for the class.

Inputs/Outputs

Name IEC 61131 Type Description

EN BOOL Global monitor enable.

MinimumMagnitude REAL Minimum CT or PT channel magnitude at which the monitor will enable. If class
input InputTypeIsAngle = TRUE, any bootstrapped CMV channels will have
their post-scaled instCval. mag values checked against this minimum.

AlertThreshold REAL Percentage deviation from the reference (for InputTypeIsAngle = FALSE) or
angle (degrees) deviation from the reference (for InputTypeIsAngle = TRUE)
at which an alert condition can occur.

Inputs

Name IEC 61131 Type Description

AlertPickupTime TIME Maximum time a sustained deviation beyond AlertThreshold is allowed. After
the initial deviation, momentary normalization is disregarded.

MonitorMode enum_CTPT_MonitorMode Relative or defined reference. If defined reference is selected, bootstrapped


breakers/switches will be ignored.

MaximumWaitTime UDINT Time-alignment wait time in milliseconds as specified by


ChannelMonitoring.class_TimeAlignment.

MaximumRate UDINT Time-alignment rate as specified by ChannelMonitoring.class_TimeAlignment.


Set to zero to bypass time alignment.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors were encountered.

Processing
➤ The following inputs are set on the first call to initialize() and
cannot be later modified:
➢ AlertPickupTime
➢ MonitorMode
➢ MaximumWaitTime
➢ MaximumRate
➤ The following inputs are allowed to change dynamically during runtime:
➢ EN
➢ MinimumMagnitude
➢ AlertThreshold

Date Code 20241023 Programming Reference


130 ConditionMonitoring
Classes

➤ When MonitorMode = DEFINED_REFERENCE, a given monitored CT/


PT phase must correspond to a reference phase specified by a call to the
respective Bootstrap_Reference method.
➤ Initialize() will return FALSE in any of the following scenarios:
➢ The MonitorMode input is not a valid enumeration element in the
enum_CTPT_MonitorMode enumeration.
➢ Initialize() is called again after a previous call to
Initialize() has already returned TRUE.
➢ MonitorMode = RELATIVE_REFERENCE and less than two
monitored CTs or PTs have been defined via the bootstrap methods.
In this scenario, the class output Error is TRUE and ErrorMessage
indicates that less than the minimum number of monitored CTs/PTs
were initialized.
➢ MonitorMode = DEFINED_REFERENCE and one or more
bootstrapped monitored CT or PTs have an enum_PhaseID that is
not represented among the bootstrapped reference CTs or PTs. In this
scenario, the class output Error is TRUE and ErrorMessage indicates
that one or more required reference CTs/PTs were not defined.
➢ MonitorMode = DEFINED_REFERENCE and less than one
monitored CT or PT has been defined via the bootstrap methods.
In this scenario, the class output Error is TRUE and ErrorMessage
indicates that less than the minimum number of monitored CTs/PTs
were initialized.

Monitor Mode Considerations


The MonitorMode input to the Initialize() method is provided to allow
for monitoring scheme flexibility. Advantages and limitations of each mode are
summarized below:

➤ MonitorMode = RELATIVE_REFERENCE
➢ General use-case: Each redundant CT or PT connected to a common
power system asset is monitored against each other.
➢ Advantages: No single point of failure.
➢ Limitations: This monitoring scheme is only capable of accurately
identifying simultaneous CT or PT failures in as many as (N / 2 – 1)
CTs/PTs for an even number of monitored CTs/PTs and (N – 1) / 2
CTs/PTs for an odd number of monitored CTs/PTs.
➤ MonitorMode = DEFINED_REFERENCE
➢ General use-case: One CT or PT is designated as a point-of-reference
for use in monitoring other CTs or PTs connected to a common power
system asset.
➢ Advantages: This monitoring scheme is capable of identifying
simultaneous CT or PT failures in as many as (N – 1) CTs or PTs
(where N is the number of monitored PTs or CTs).
➢ Limitations: This scheme is contingent on the reference CT or PT
continually operating within manufacturer specifications. Thus, the
reference CTs or PTs are single points of failure in this scheme.

Programming Reference Date Code 20241023


ConditionMonitoring 131
Classes

Monitor Groups
A Monitor Group is defined here as a collection of measurement channels
representing assets that are monitored against a shared reference. When dynamic
topology elements like breakers/switches have been bootstrapped, a given
monitor group may be a full set of bootstrapped monitored channels or a subset.
The number of operating monitor groups is allowed to change dynamically with
changes in topology.

➤ For MonitorMode = DEFINED_REFERENCE, all measurement channels


bootstrapped by the bootstrap monitored channel methods for a given
phase are considered members of a single static monitor group. Breaker/
switch status information is ignored.
➤ When MonitorMode = RELATIVE_REFERENCE and no breaker/
switches have been bootstrapped, a given monitor group is defined as a
collection of monitored channels with matching node IDs. This allows for
static sub-grouping of monitored channels.
➤ When MonitorMode = RELATIVE_REFERENCE and breaker/switches
have been bootstrapped, a given monitor group is defined as a collection
of monitored channels whose node IDs are represented among a set of
node-contiguous closed breakers/switches. (Note that each breaker/switch
is associated with two node IDs.) This group association only holds for
monitored channels and breaker/switches of identical phase.

Run (Method)
Call this method once per scan after completing all necessary calls to the
Bootstrap methods and Initialize().

Processing
➤ Evaluates the status of any bootstrapped breaker/switch. If any change is
detected, the monitor groups are recalculated.
➤ Applies the user-specified scaling factor to each monitored and reference
channel.
➤ Gates the absolute value of Initialize.MinimumMagnitude to a
minimum of 1.
1. If the class input InputTypeIsAngle = TRUE, the scaling factor
is added/subtracted from the channel quantity. (For CMV types, the
angle is used as the channel quantity.)
2. If the class input InputTypeIsAngle = FALSE, the channel
quantity is multiplied by the scaling factor. (For CMV types, the
magnitude is used as the channel quantity.)
➤ If Initialize.MaximumRate was greater than zero, executes time-
alignment on all bootstrapped CT/PT channels to be monitored in
addition to the reference CT/PT channels (if defined) using a single
instance of ChannelMonitoring.class_TimeAlignment.

NOTE
The application of time-alignment requires that the time stamp of each
bootstrapped tag updates continuously.

Date Code 20241023 Programming Reference


132 ConditionMonitoring
Classes

➤ If MonitorMode = RELATIVE_REFERENCE, calculates a reference


channel for each monitor group.
➤ Each monitored CT/PT is processed via an independent instance of the
ChannelMonitoring.fb_ChannelAlert function block.
➤ For MonitorMode = DEFINED_REFERENCE the Reference input to a
given ChannelMonitoring.fb_ChannelAlert instance is the bootstrapped
Reference CT/PT channel with enum_PhaseID matching that of the
monitored CT/PT channel.
➤ When MonitorMode = RELATIVE_REFERENCE and the number of CTs/
PTs in a given monitor group exceeds two, the Reference input to each
respective ChannelMonitoring.fb_ChannelAlert instance is automatically
calculated. In this scenario, the reference value is derived via statistical
analysis of all monitored CT/PT measurements with good quality for a
given phase, for a given time stamp. This is accomplished via an outlier-
removed approximation of the mean value across a given time-aligned
sample set, as expressed in the following equation.

Equation 5.3

where:
➢ N is the number of bootstrapped monitored CTs/PTs with
.q.validity = good.
➢ X1 is the post-scaled set of samples representing each bootstrapped
CT/PT for a given time stamp.
➢ Xm + 1 is the Xm sample set minus the greatest outlier of the Xm
sample set.
➢ M is the number of outliers to remove, where:
➣ M = (N / 2) - 1 for even values of N.
➣ M = (N - 1) / 2 for odd values of N.
For example, for the instantaneous sample set (50, 52, 10, 55, 900, 54, 51,
0):
➢ N=8
➢ M=3
➢ Reference sample = (50 + 52 + 55 + 54 + 51) / 5
➤ If less than two monitored CTs/PTs have .q.validity = good for the
given sample, then the reference measurement is set to '0' and is given
.q.validity = invalid.

Programming Reference Date Code 20241023


ConditionMonitoring 133
Classes

➤ When MonitorMode = RELATIVE_REFERENCE and the given


monitor group contains two monitored CT/PTs, both CT/PT data
channels will be compared directly against each other using a single
instance of ChannelMonitoring.fb_ChannelAlert. As a result, the output
struct_CTPTStatusOutput for each monitored CT/PT will contain
identical status information.
➤ Updates each struct_CTPTStatusOutput tags specified via the bootstrap
method as follows:
➢ CtPtID is fixed at the CtPtID passed into the associated bootstrap
method.
➢ Phase is fixed at the Phase passed into the associated bootstrap
method.
➢ MonitorEnabled is TRUE while:
➣ Initialize.EN is TRUE.
➣ QualityAlert is FALSE.
➣ The monitored CT/PT measurement was successfully time-
aligned. This condition is evaluated with a 10-second dropout
timer.
➣ The monitored CT/PT measurement has .q.validity = good.
This condition is evaluated with a 10-second dropout timer.
➣ For MonitorMode = DEFINED_REFERENCE the reference
measurement was successfully time-aligned. This condition is
evaluated with a 10-second dropout timer.
➣ The reference measurement has .q.validity = good. This
condition is evaluated with a 10-second dropout timer.
➣ For class input InputTypeIsAngle = FALSE:
⦁ The reference CT/PT measurement, after being scaled
via the specified ScaleFactor, equals or exceeds
Initialize.MinimumMagnitude. This condition is
evaluated with a 5-second pickup/dropout timer. For
MonitorMode = RELATIVE_REFERENCE, the reference
measurement is defined by Equation 5.3.
➣ For class input InputTypeIsAngle = TRUE:
⦁ If the monitored CT/PT channel is of type CMV,
the instCval.mag measurement, after being scaled
via the specified ScaleFactor, equals or exceeds
Initialize.MinimumMagnitude. This condition is
evaluated with a 5-second pickup/dropout timer.
⦁ If the monitored CT/PT channel is not of type
CMV, the channel value is not checked against
Initialize.MinimumMagnitude.
➣ Recall that the absolute value of
Initialize.MinimumMagnitude will be gated at a minimum
of 1.

Date Code 20241023 Programming Reference


134 ConditionMonitoring
Classes

➣ The number of members in the given monitor group is greater


than one. This condition is evaluated with a 10-second dropout
timer.
➣ All breakers/switches bootstrapped via
bootstrap_BreakerSwitch(), for the associated
enum_PhaseID have a status of SPS.q.validity = good. This
condition is evaluated with a 10-second dropout timer.
➢ Alert.stVal is TRUE if the following equations resolve to
TRUE for a duration equal to Initialize.AlertPickupTime
or momentarily evaluate to TRUE for a number of times equal
to the ChatterCountThreshold class input within a duration of
Initialize.AlertPickupTime.
➣ For class input InputTypeIsAngle = FALSE:

Equation 5.4
➣ For class input InputTypeIsAngle = TRUE:

Equation 5.5
where:
➣ Mon_CTPT is the monitored CT/PT data channel sample
after being scaled by ScaleFactor (or RotationFactor when
InputTypeIsAngle = TRUE).
➣ Ref is the reference data channel sample from the bootstrapped
reference CT/PT or the approximated reference from
Equation 5.3.
➢ After an alert condition clears, Alert.stVal will remain asserted for
a dropout duration of Initialize.AlertPickupTime.
➢ Alert.stVal is deasserted while MonitorEnabled is FALSE.
➢ Alert.q.validity = invalid if MonitorEnabled is FALSE.
➢ Alert.t updates with the RTAC system time upon a rising or falling
edge of Alert.stVal.
➢ While MonitorEnabled is FALSE, the alert pickup/dropout timer and
chatter count are reset to zero.
➢ QualityAlert is TRUE while any of the following conditions are met:
➣ The monitored CT/PT data channel has q.validity ≠ good.
➣ For MonitorMode = DEFINED_REFERENCE, the reference data
channel for the associated Phase has q.validity ≠ good.
➣ For MonitorMode = RELATIVE_REFERENCE, less than two
monitored CT/PT data channels have q.validity = good.
➢ AlertMag is updated with the instantaneous value of the monitored
channel on the rising edge of Alert.stVal and is set to zero on the
falling edge of Alert.stVal.

Programming Reference Date Code 20241023


ConditionMonitoring 135
Classes

➢ PercentDeviation is continuously updated with the signed


version of the left hand side of Equation 5.4 when class input
InputTypeIsAngle = FALSE. PercentDeviation is left blank when
InputTypeIsAngle = TRUE.
➢ AngleDeviation is continuously updated with the signed version of
the left side of Equation 5.5 when class input InputTypeIsAngle
= TRUE. AngleDeviation is left blank when InputTypeIsAngle =
FALSE.
➢ ReferenceMeasurement is continuously updated with the reference
measurements that the given CtPt is monitored against.
➢ NodeGroup is continuously updated with a list of node index values
associated with this group. This list may change dynamically for
scenarios where breakers/switches have been bootstrapped and
MonitorMode = RELATIVE_REFERENCE. Otherwise, the list will
include all CtPt node indexes for monitored channels that have been
bootstrapped for the given phase and will remain static.

class_CmReportWriter (Class)
This class supports the generation of reports useful for condition monitoring of
power system assets.

Special Considerations
➤ This class writes comma-delimited format files to the RTAC file system.
➤ This class provides file names in accordance with IEEE C37.232.
➤ This class writes files to the RTAC file system but does not manage the
target directory.
This class is intended to generate all reports necessary for an arbitrary number of
instances of a single class that implements the I_Cm interface. Thus, this class
assumes that all bootstrapped sources use the same implementation of I_Cm.
This class writes one to two types of report files, depending on the I_Cm
implementation of the bootstrapped sources.

Detail File
The Detail file provides one column per granular data element per asset. This
provides a simple format for machine processing and analytic generation. The
Detail file contains one required column. The first column always contains a
time stamp for the event. The column label is Timestamp. The time stamp format
is yyyy-mm-dd-hh:mm:ss.xxxxxx.
All other columns of the Detail file are defined by one or more
implementing class instances. The column labels take the form
<CustomLabel>:<DataTypeIdentifier>, where CustomLabel and
DataTypeIdentifier are provided via the GetDetailColLabels method.
DataTypeIdentifier takes on one of the following values:
1. A : Analog quantity (Floating point).
2. D : Boolean quantity (TRUE/FALSE).
3. S : String (maximum of 255 characters).

Date Code 20241023 Programming Reference


136 ConditionMonitoring
Classes

The DataTypeIdentifier is intended to provide context about the content of a


given column to assist in machine processing. For example, the following are
column labels 1–5 for a hypothetical Detail file.

Timestamp, Asset1.VA.Mag:A, Asset1.Alert:D, Asset2.VA.Mag:A,


Asset2.Alert:D

SOE/Summary File
The SOE/Summary file provides one column per data element category shared
by all assets. This file can contain either SOE or Summary content or both
depending on the given class's implementation of this interface. The SOE/
Summary file contains three required columns that will appear as the first three
columns in the file:

1. Column Label - 'Timestamp' : Time stamp displayed in yyyy-mm-dd-


hh:mm:ss.xxxxxx format
2. Column Label - 'Log Type' : Log descriptor ('Event' or 'Summary')
3. Column Label - 'Asset ID' : Asset descriptor

All other column labels of the SOE/Summary file are defined by


the first implementing class instance that has been bootstrapped into
class_CmReportWriter. All objects bootstrapped into class_CmReportWriter
must be instances of a single class. Therefore, it can be assumed that each
instance supports an identical set of SOE/Summary column labels. For
example, bootstrapping one instance of a class_StreamingCtPtMonitor and one
instance of a class_BreakerMonitor would be an invalid configuration.

This class should be operated in the following fashion:

1. Call Bootstrap_Source for all participating class instances of a single


class that implements the I_Cm interface.
2. Call Initialize once all sources have been bootstrapped.
3. If Initialize returns TRUE, call Run once per task cycle.

Inputs

Name IEC 61131 Type Description

SummaryPeriod TIME Interval between summary reports within the SOE/Summary file. Set to T#0s to
disable summary reporting.

SummaryTrigger BOOL Manual trigger for generating summary content within the SOE/Summary file.

Directory STRING(100) Target directory. Must conform to SEL sel_file limitations.

StationID STRING(16) Station ID string, used for IEEE C37.232 COMNAME formatting.

DeviceID STRING(16) Device ID string, used for IEEE C37.232 COMNAME formatting.

CompanyName STRING(16) Company name string, used for IEEE C37.232 COMNAME formatting.

FileNamePostFix STRING(16) Comma-separated additions to the given file name.

MaxSoeFileSize UDINT Maximum SOE file size in bytes before a new file is created.

MaxSoeFileDur UDINT Maximum SOE file duration in hours.

MaxDetailFileSize UDINT Maximum Detail file size in bytes before a new file is created.

Programming Reference Date Code 20241023


ConditionMonitoring 137
Classes

Name IEC 61131 Type Description

MaxDetailFileDur UDINT Maximum Detail file duration in hours

MaxRowsOfDetailHistory UDINT Maximum Number of Detail file rows cached in RAM for historical analysis. Set to
zero to disable.

RecordInUTC BOOL Record in UTC or local time.

Outputs
Name IEC 61131 Type Description

Initialized BOOL Class is initialized for report generation.

CurrentSoeFileSize UDINT Current size in bytes of the SOE/Summary file.

CurrentDetailFileSize UDINT Current size in bytes of the Detail file.

Error BOOL Indicates an internal error state.

ErrorMsg STRING(255) Message describing an internal error state.

File Name Format


The output file name(s) will take the following form:

Date,Time,TimeCode,StationID,DeviceID,CompanyName,
OutputFilePostfix,Type.csv

where each comma-separated element of the file name is described below.

1. Date: Format (yymmdd); corresponds to the date of the oldest time stamp
in the file.
2. Time: Format (hhmmssmmmuuu); corresponds to the time of the oldest
time stamp in the file.
3. Timecode: Offset from UTC time, set to 0 when RecordInUTC =
TRUE.
4. StationID: User-defined.
5. DeviceID: User-defined.
6. CompanyName: User-defined.
7. OutputFilePostfix: User-defined.
8. Type: 'SOE' for SOE/Summary files. 'DET' for Detail files.

Bootstrap_Source (Method)
Call this method to register a ConditionMonitoring class instance for report
generation.

Inputs
Name IEC 61131 Type Description

CmApplication I_Cm Instance of a class or FB that implements the I_Cm


interface.

Date Code 20241023 Programming Reference


138 ConditionMonitoring
Classes

Processing
➤ Sets CmApplication.pt_History to the address of the internal CSV
object manager.
➤ Sets CmApplication.ReportingBootstrapped = TRUE.
➤ Adds the address of the I_Cm interface implementation to a queue.

Initialize (Method)
Call this method to initialize the class.

Processing
1. Returns FALSE if any of the following are TRUE:
➤ No sources have been bootstrapped.
➤ Any of the class input file name elements do not pass
SelUtils.fun_IsValidFilename() with NameScheme =
SEL_FILEIO_IEEE_COMNAME.
2. Else sets the input file name components as static variables (cannot be
changed after Initialize returns TRUE).
3. If no errors were encountered, sets Initialized = TRUE.

Return Value
IEC 61131 Type Description

BOOL TRUE if no errors were encountered.

Run (Method)
Call this method once per scan.

Processing
1. If Initialized = TRUE and at least one source has been bootstrapped
via Bootstrap_Source():
➤ Opens any last-known SOE/Summary and/or Detail files for
continued logging.
2. Checks the bootstrapped sources for Summary content on the
SummaryPeriod interval.
3. Continuously checks the bootstrapped sources for SOE and Detail
content.
4. If SOE/Summary content found, writes directly to file.
5. If Detail content found, writes directly to file.
6. Prior to writing content to file, checks the file age. If in excess of max file
duration setting, writes content to a new file.
7. Prior to writing content to file, checks the state of the NewSoeFile and
NewDetailFile properties of the given bootstrapped sources. If either
property from any source is asserted, writes content to a new file and
deasserts the associated property.

Programming Reference Date Code 20241023


ConditionMonitoring 139
Classes

8. Checks size of SOE/Summary and Detail files every 30 seconds.


9. If file size exceeds associated max file size setting, a new file is created
the next time content is written to file.
10. If Detail content found and MaxRowsOfDetailHistory
> 0, writes row to an internal CSV object (instance of
DescriptiveData.class_CsvManager).

class_IedReportConverter (Class)
This class supports the conversion of ASCII and CASCII reports collected from
IEDs to standard format, machine-readable files.
This class is intended for use by the IED Report Manager extension but can be
used directly if a custom directory management scheme is required.

Special Considerations
➤ This class supports ASCII or CASCII input files.
➤ This class supports output files in CSV format.
➤ This class allows output file name configuration for compliance with
IEEE C37.232.
➤ This class writes files to the RTAC file system but does not manage the
target directory.
This class should be operated in the following fashion:
1. If a CSV-formatted output file is desired, call
Bootstrap_ReportRegExRule() for each regular expression
necessary to parse the desired content from the file. Otherwise, if a
copy of the original IED report file is desired, make no calls to the
Bootstrap_ReportRegExRule() method.
2. Call Bootstrap_Report() to initialize the application inputs for the
class.
3. Call Run() once per scan after Bootstrap_Report() returns TRUE.
4. Call RequestReportConversion() to initiate processing of the
original IED report file.
5. Make subsequent calls to RequestReportConversion() when the
original IED report file updates and Busy = FALSE.
Regular Expressions will be applied sequentially based on the order in
which they were Bootstrapped. Each parse operation will begin at the index
at which the previous operation ended.

Inputs
Name IEC 61131 Type Description

LogRuntimeErrors BOOL Default is FALSE. Set to TRUE to log runtime errors to the SOE log.

MaxCycleTimeUsage UDINT(10–10000) Milliseconds. Default is 10. Maximum time per task cycle that the Run method
will do work.

InstanceID STRING Identification string for the class instance. Used for SOE logging and internal file
management.

Date Code 20241023 Programming Reference


140 ConditionMonitoring
Classes

Outputs

Name IEC 61131 Type Description

Initialized BOOL TRUE if Bootstrap_Report() returns TRUE.

Busy BOOL While TRUE, the class will not accept report conversion requests.

ActiveFileName STRING(255) Name of the most recent file written to the file system.

Error BOOL Indicates an error condition.

ErrorMessage STRING(255) Description of the error condition.

Bootstrap_ReportRegExRule (Method)
Call this method to specify a regular expression and associated metadata
necessary to parse content from the original IED report.

Inputs

Name IEC 61131 Type Description

Type enum_ReportContentType Report content type to be parsed using RegEx.

Label STRING(252) Identifier for the data parsed by RegEx. This string will be used in the CSV-
formatted output file to label the respective data column(s). It does not need to
match the relay word label from the ASCII or CASCII response. Three bytes are
reserved for internally used metadata.

RegEx STRING(255) Regular expression characterization string. Must meet the Perl5 RegEx syntax
requirements. All JSON control characters must be escaped using the backslash (\)
character.

Instances UINT Number of times that RegEx will be applied to capture sequential data from the
original IED report file.

Formatting considerations
Type = SEQUENCE

Sequence content is described here as a repeating data pattern, which is


represented as rows and columns of space-separated or comma-separated
alphanumeric character sets preceded by a set of column labels where the
number of discrete character sets per row matches the number of column labels.

➤ Label should be formatted as a comma-separated list of column labels.


➤ RegEx should match no more than the entire row, excluding the trailing
newline and carriage return, using one or more capture groups.
➤ Instances should be set equal to the desired number of rows of column
data to be captured.

Type = SUMMARY

Programming Reference Date Code 20241023


ConditionMonitoring 141
Classes

Summary content is described here as a non-repeating data element from the


report.

➤ If Label contains the comma (0x2C) character, only characters preceding


the first instance of the comma will be passed to the output file.
➤ If RegEx contains more than one capture group, only the content matched
by the first capture group in the list will be passed to the output file.
➤ For this mode, Instances is forced to 1 and disregarded.

Return Value
IEC 61131 Type Description

BOOL TRUE if no errors were encountered.

Processing
1. Returns FALSE if Initialized is TRUE.
2. Else, returns TRUE.

Bootstrap_Report (Method)
Call this method to specify the necessary inputs to this class. This method
should be called once.

Inputs
Name IEC 61131 Type Description

InputFile STRING(255) The full file name of the original IED report. The character "/" delimits the folder path. This
path must begin with "/" and end with the full file name, including extension.

OutputDirectory STRING(164) The target directory for the formatted report. The character "/" delimits the folder path. Must
begin with "/". If the directory does not exist, it will be created.

OutputFilePostfix STRING(67) The string appended to the end of the file name, prior to the file format extension. Must
include the file extension.

ReportsPerFile UINT The number of formatted report data sets contained within the output file. A new file will be
created on the following call to RequestReportConversion() when the number of report
data sets in the current file reaches this number, the RTAC reboots, or new RTAC settings are
sent.

File name elements for Inputfile and OutputDirectory may contain all printable
ASCII characters between (space) and (tilde) except for ", ', :, <, %, >, ?, \, and |.
They cannot contain any file path manipulation variables (//, /./, /../).
File name elements for OutputFilePostfix may contain all printable ASCII
characters between (space) and (tilde) except for ", ', :, ;, <, %, >, [, ], $, {, }, ?, \,
and |.

Return Value
IEC 61131 Type Description

BOOL Returns FALSE if no errors were encountered.

Date Code 20241023 Programming Reference


142 ConditionMonitoring
Classes

Processing
1. Returns FALSE if Initialized is TRUE.
2. If InputFile, OutputDirectory, or OutputFilePostFix contain illegal
characters as specified above, returns FALSE, asserts Error, and
ErrorMessage indicates the use of illegal characters on the specified
input.
3. If ReportsPerFile is zero, returns FALSE, asserts Error, and
ErrorMessage indicates that ReportsPerFile must be non-zero.

RequestReportConversion (Method)
Call this method to initiate a conversion of the file specified by InputFile into a
formatted report.

Return Value

IEC 61131 Type Description

BOOL Returns FALSE if no errors were encountered.

Processing
1. Returns FALSE if Busy is TRUE.
2. Returns FALSE if Initialized is FALSE.
3. Else, executes the following:
a. Deasserts Error and clears ErrorMessage.
b. Asserts Busy.

Run (Method)
Call this method once each processing interval to handle all asynchronous
operations.

Processing
1. If Busy = FALSE and Initialized = TRUE and
RequestReportConversion() returns TRUE, executes the following:
➤ Asserts Error if the original IED report specified by InputFile was
not found within the FILES directory of the virtual file system or
the file could not be parsed using the specified regular expressions.
ErrorMessage specifies the error condition details.
➤ Deasserts Busy on rising edge of Error.
➤ Else, deasserts Busy when finished writing formatted file to
outputDirectory.
➤ If no regular expressions were registered via one or more calls to
Bootstrap_ReportRegexRule(), the original IED Report is
copied and written to the output file.

Programming Reference Date Code 20241023


ConditionMonitoring 143
Classes

CSV-Formatted Output File


When regular expressions are registered via calls to
Bootstrap_ReportRegexRule(), this class produces a file in CSV format.
The file content for a given report is formatted as follows:

➤ Row 1: Column labels for all summary and sequence data


➤ Row 2: Summary data points and first row of sequence data
➤ Subsequent rows: Blank cells for summary data columns and sequence
data for subsequent sequence data rows
➤ Columns are arranged from left to right in the order which the
given sequence or summary data were registered via calls to
Bootstrap_ReportRegexRule()

Each file can contain a user-configurable number of report data sets.


Reports appear with the newest at the bottom/end of the file. This format
is depicted below for a scenario where both summary data and sequence
data were extracted from the original IED report file and ReportsPerFile
= 2. In this scenario, the summary data were registered via calls to
Bootstrap_ReportRegexRule(), followed by the sequence data.

Figure 5.5 Graphical Depiction of Output CSV File Format

Output File Naming Convention


The output file name will take the following form:

Date,Time,TimeCode,outputFilePostfix

where each comma-separated element of the file name is described below.

1. Date: Format (yymmdd), UTC date, taken from the RTAC system time at
the time of RequestReportConversion() call.
2. Time: Format (hhmmssmmmuuu), UTC time taken from the RTAC
system time at the time of RequestReportConversion() call.
3. Timecode: Offset from UTC time, set to 0.
4. OutputFilePostfix: User-defined via the Bootstrap_Report()
method. This string must include the file extension.

Date Code 20241023 Programming Reference


144 ConditionMonitoring
Classes

Example Application of Bootstrap Methods to Parse Report Content


For the following example IED report excerpt:

Figure 5.6 Example IED Report Excerpt

The following example content passed into Bootstrap_ReportRegExRule()


demonstrates the necessary configuration for parsing the value of MaxCurrent
from the report.

➤ Bootstrap_ReportRegExRule
➢ Type: enum_ReportContentType.SUMMARY
➢ Label: "Max Current (A)"
➢ RegEx: "(?:MaxCurrent[\\x20-\\x2E\\x41-\\x7E]{1,})([0-9]{1,4})"
➢ Instances: 1

The following example content passed into Bootstrap_ReportRegExRule()


demonstrates the necessary configuration for parsing the 10 rows of sequence
data from the report.

➤ Bootstrap_ReportRegExRule
➢ Type:enum_ReportContentType.SEQUENCE
➢ Label:
"CYCLE,IA(A),IB(A),IC(A),IN(A),VAB(V),VBC(V),VCA(V),
TCURTR(%)"
➢ "RegEx: "[\\x0a]{1,1}[\\x20]{1,} ([\\x2e\\x20 \\x30-\\x39] {1,})(?=\
\x0d|\\x0a)"
➢ Instances: 10

Note that for this example, the noted Bootstrap_ReportRegExRule()


calls must be made in the same order in which they are listed above.

Programming Reference Date Code 20241023


ConditionMonitoring 145
Classes

The resultant formatted file for this example is shown below:

Figure 5.7 Example Output File

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.
Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Monitor SEL-411L COM 87 Data Points


Objective
Implement an 87L Communications monitoring system for an SEL-411L IED.
Log alarms to the RTAC SOE, generate CSV report files, and collect raw 87L
Reports from the IED.

Assumptions
This example assumes the following:
1. The RTAC project is configured with one SEL-411L client named
SEL_411L_1_SEL.
2. The client is configured with one Flex parse message named FP_01 with
Command String = 'COM 87L<CR><LF>' and Capture To File = True.
3. The Flex parse message is configured to capture the 24-hour lost packet
counters of channel 1 and 2.

Solution
The user can apply instancess of ConditionMonitoring classes
class_87LCommMonitor411L, class_CmReportWriter, and
class_IedReportConverter and FileIo class class_BasicDirectoryManager to
facilitate this monitoring scheme.
Code Snippet 5.1 prg_87LCommMonitor24HrLostPacket
PROGRAM prg_87LCommMonitor24HrLostPacket

VAR
Monitor87L : ConditionMonitoring.class_87LCommMonitor411L;
ReportWriter : ConditionMonitoring.class_CmReportWriter;
RawReportCollector : ConditionMonitoring.class_IedReportConverter;
DirManagers : ARRAY [1 .. 2] OF FileIo.class_BasicDirectoryManager;
RunOnce : BOOL := TRUE;
PollTrigger : BOOL;

Date Code 20241023 Programming Reference


146 ConditionMonitoring
Classes

SummaryTrigger : BOOL;
OutputDirectory : STRING := 'Com87L_Monitor';
OutputChannels : ARRAY [1 .. 2] OF SPS;
SubDirectory : STRING;
END_VAR

IF RunOnce THEN
// Initialize 87L Monitor
Monitor87L.COM87lPollPeriod := 1;
Monitor87L.EnableReportContent := TRUE;
Monitor87L.EnableRoundRobinPolling := TRUE;
Monitor87L.EnableSoeLogging := TRUE;
Monitor87L.InstanceName := 'SEL_411L_1';
Monitor87L.LostPacketCountThreshold24Hr := 5;
Monitor87L.PrimaryAvailabilityThreshold := 92;
Monitor87L.pt_COM87LPollTrigger := ADR(PollTrigger);
Monitor87L.pt_FlexParseDone_COM_87L := ADR(SEL_411L_1_SEL_POU.Send_Flex_Parse_Message_FP_01_DN);
Monitor87L.pt_SendFlexParse_COM_87L := ADR(SEL_411L_1_SEL_POU.Send_Flex_Parse_Message_FP_01);

// Bootstrap monitored data points


Monitor87L.Bootstrap_MonitoredDataPoint(ChannelNumber := 1,
pt_OutputChannel := ADR(outputChannels[1]),
DataDefinition := ConditionMonitoring.enum_87LDataPoint411L.e_24HR_LOST_PACKETS_INS,
pt_DataPointINS := ADR(SEL_411L_1_SEL.Ch1LostPackets24Hrs));
Monitor87L.Bootstrap_MonitoredDataPoint(ChannelNumber := 2,
pt_OutputChannel := ADR(outputChannels[1]),
DataDefinition := ConditionMonitoring.enum_87LDataPoint411L.e_24HR_LOST_PACKETS_INS,
pt_DataPointINS := ADR(SEL_411L_1_SEL.Ch2LostPackets24Hrs));
Monitor87L.Initialize();

// Initialize the CSV report writer


ReportWriter.CompanyName := 'CompanyA';
ReportWriter.DeviceID := 'RTAC';
ReportWriter.StationID := 'StationA';
ReportWriter.Directory := OutputDirectory;
ReportWriter.FileNamePostFix := '87L_COMS';
ReportWriter.MaxDetailFileDur := 24;
ReportWriter.MaxSoeFileDur := 24;
ReportWriter.MaxSoeFileSize := 1024;
ReportWriter.RecordInUTC := TRUE;
ReportWriter.SummaryPeriod := T#1H;
ReportWriter.pt_SummaryTrigger := ADR(SummaryTrigger);
ReportWriter.Bootstrap_Source(Monitor87L);
ReportWriter.Initialize();

// Initialize the IED Report Converter in pass-through mode


SubDirectory := CONCAT(OutputDirectory, '/RawCom87LReports');
RawReportCollector.InstanceID := 'Test 87L Comm Monitor - Raw Report Collector';
RawReportCollector.LogRuntimeErrors := TRUE;
RawReportCollector.Bootstrap_Report(
InputFile := '/FLEX_PARSE/SEL_411L_1_SEL/SEL_411L_1_SEL_FP_01.Capture',
OutputDirectory := SubDirectory,
OutputfilePostFix := 'CompanyA,RTAC,StationA,87LReport.txt',
ReportsPerFile := 1);

// Initialize the directory managers


DirManagers[1].bootstrap_SetDirectory(FolderName := OutputDirectory,
MaximumFolderSize := 102400,
MaximumNumfiles := 10,
MaximumNumDays := 10);
DirManagers[2].bootstrap_SetDirectory(folderName := SubDirectory,
MaximumFolderSize := 102400,
MaximumNumfiles := 10,
MaximumNumDays := 10);

RunOnce := FALSE;
END_IF

Programming Reference Date Code 20241023


ConditionMonitoring 147
Classes

IF SEL_411L_1_SEL_POU.Send_Flex_Parse_Message_FP_01_DN THEN
RawReportCollector.RequestReportConversion();
END_IF

Monitor87L.Run();
ReportWriter.Run();
RawReportCollector.Run();
DirManagers[1].Run();
DirManagers[2].Run();

Monitor CT Group in Defined-Reference Mode


Objective
CT1 and CT2 from Figure 5.2 are to be monitored against the reference, CT3.

Assumptions
This example assumes the following:
1. Two C37.118 protocol clients, IED1 and IED2, are added to the project.
2. A C37.118 data rate of 30 messages per second is used for IED1 and
IED2.
3. System topology matches that of Figure 5.2.
4. IED1 collects three-phase measurements from CT1 and CT3.
5. IED2 collects three-phase measurements from CT2.
6. CT1 is on the low-side of the transformer and associated current
measurements must be scaled down by the transformer ratio as a pre-
condition for inclusion in the monitoring group.
7. CT3 is used for reference measurements only.

Solution
The user can apply one instance of class_Streaming_CTPT_Monitor to facilitate
this monitoring scheme.
Code Snippet 5.2 prg_CTPTMonitorOneLine
PROGRAM prg_CTPTMonitorOneLine
VAR CONSTANT
c_NumberOfMonitoredAssets : UDINT := 2;
END_VAR
VAR
Monitor_Enable : BOOL;
MinimumAmps : REAL := 15; // Units of Amps for this example
AlarmThresh : REAL := 5; // In units of percent
TxfrmrTurnsRatio : REAL := 20;
CT_Monitor : ConditionMonitoring.class_StreamingCTPTMonitor;
CT_Status_Matrix : ARRAY [1 .. c_NumberOfMonitoredAssets,
enum_PhaseID.PHASE_A .. enum_PhaseID.PHASE_C] OF
struct_CTPTStatusOutput;
CT_Status_String_Matrix : ARRAY [1 .. c_NumberOfMonitoredAssets,
enum_PhaseID.PHASE_A .. enum_PhaseID.PHASE_C] OF STRING(255);
RunOnce : BOOL := TRUE;
Initialized : BOOL;
inc : UDINT; // incrementation variable
END_VAR

IF RunOnce THEN

Date Code 20241023 Programming Reference


148 ConditionMonitoring
Classes

// Bootstrap the reference CT phases (CT3)


CT_Monitor.bootstrap_ReferenceCMV(channel := IED1_IED1.CT3_IA,
phase := enum_PhaseID.PHASE_A, scaleFactor := 1);

CT_Monitor.bootstrap_ReferenceCMV(channel := IED1_IED1.CT3_IB,
phase := enum_PhaseID.PHASE_B, scaleFactor := 1);

CT_Monitor.bootstrap_ReferenceCMV(channel := IED1_IED1.CT3_IC,
phase := enum_PhaseID.PHASE_C, scaleFactor := 1);

// Bootstrap monitored CT phases (CT1, CT2)


// Bootstrap group 1
CT_Monitor.bootstrap_MonitoredCMV(channel := IED1_IED1.CT1_IA,
outputStatus := CT_Status_Matrix[1, enum_PhaseID.PHASE_A], ctPtId := 'CT1A',
phase := enum_PhaseID.PHASE_A, scaleFactor := 1/TxfrmrTurnsRatio);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED1_IED1.CT1_IB,
outputStatus := CT_Status_Matrix[1, enum_PhaseID.PHASE_B], ctPtId := 'CT1B',
phase := enum_PhaseID.PHASE_B, scaleFactor := 1/TxfrmrTurnsRatio);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED1_IED1.CT1_IC,
outputStatus := CT_Status_Matrix[1, enum_PhaseID.PHASE_C], ctPtId := 'CT1C',
phase := enum_PhaseID.PHASE_C, scaleFactor := 1/TxfrmrTurnsRatio);

// Bootstrap group 2
CT_Monitor.bootstrap_MonitoredCMV(channel := IED2_IED2.IA,
outputStatus := CT_Status_Matrix[2, enum_PhaseID.PHASE_A], ctPtId := 'CT2A',
phase := enum_PhaseID.PHASE_A, scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED2_IED2.IB,
outputStatus := CT_Status_Matrix[2, enum_PhaseID.PHASE_B], ctPtId := 'CT2B',
phase := enum_PhaseID.PHASE_B, scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED2_IED2.IC,
outputStatus := CT_Status_Matrix[2, enum_PhaseID.PHASE_C], ctPtId := 'CT2C',
phase := enum_PhaseID.PHASE_C, scaleFactor := 1);

// Now initialize the CT monitor


Initialized := CT_Monitor.Initialize(en := Monitor_Enable,
minimumMagnitude := MinimumAmps, alertThreshold := AlarmThresh,
alertPickupTime := T#60S,
monitorMode := enum_CTPTMonitorMode.DEFINED_REFERENCE, maximumWaitTime := 1000,
maximumRate := 30);

RunOnce := FALSE;
END_IF

IF Initialized THEN
// Update the monitor enable variable
Monitor_Enable := NOT (IED1_C37_118_POU.Offline OR
IED2_C37_118_POU.Offline);

// Run the monitor


CT_Monitor.Run();

// Assess the outputs and construct status strings.


FOR inc := 1 TO c_NumberOfMonitoredAssets DO
// Assess phase A for the given CT set
IF CT_Status_Matrix[inc, enum_PhaseID.PHASE_A].Alert.stVal THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_A] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_A].CtPtID),'is misoperational');
ELSIF CT_Status_Matrix[inc, enum_PhaseID.PHASE_A].QualityAlert THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_A] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc, enum_PhaseID.PHASE_A].CtPtID),'is disabled due to
insufficient measurement quality');

Programming Reference Date Code 20241023


ConditionMonitoring 149
Classes

ELSE
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_A] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc, enum_PhaseID.PHASE_A].CtPtID),'is operational');
END_IF

// Assess phase B for the given CT set


IF CT_Status_Matrix[inc, enum_PhaseID.PHASE_B].Alert.stVal THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_B] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_B].CtPtID),'is misoperational');
ELSIF CT_Status_Matrix[inc, enum_PhaseID.PHASE_B].QualityAlert THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_B] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc, enum_PhaseID.PHASE_B].CtPtID),'is disabled due to
insufficient measurement quality');
ELSE
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_B] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc, enum_PhaseID.PHASE_B].CtPtID),'is operational');
END_IF

// Assess phase C for the given CT set


IF CT_Status_Matrix[inc, enum_PhaseID.PHASE_C].Alert.stVal THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_C] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_C].CtPtID),'is misoperational');
ELSIF CT_Status_Matrix[inc, enum_PhaseID.PHASE_C].QualityAlert THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_C] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc, enum_PhaseID.PHASE_C].CtPtID),'is disabled due to
insufficient measurement quality');
ELSE
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_C] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_C].CtPtID),'is operational');
END_IF
END_FOR
END_IF

Monitor CT Group in Relative-Reference Mode


Objective
CT1 through CT4 from Figure 5.1 are to be monitored against each other.

Assumptions
This example assumes the following:
1. System topology matches that of Figure 5.1.
2. Four C37.118 protocol clients; IED1, IED2, IED3, and IED4; are added
to the project.
3. A C37.118 data rate of 30 messages per second is used for IED1, IED2,
IED3, and IED4.

Solution
The user can apply one instance of class_Streaming_CTPT_Monitor to facilitate
this monitoring scheme.
Code Snippet 5.3 prgFourCTMonitorOneLine
PROGRAM prg_FourCTMonitorOneLine

Date Code 20241023 Programming Reference


150 ConditionMonitoring
Classes

VAR CONSTANT
c_NumberOfMonitoredAssets: UDINT := 4;
END_VAR
VAR
Monitor_Enable : BOOL;
MinimumAmps : REAL := 15; // (300 * 0.05) Units of Amps for this example
AlarmThresh : REAL := 5; // In units of percent
RunOnce : BOOL := TRUE;
Initialized : BOOL;
inc : UDINT;
CT_Monitor : ConditionMonitoring.class_StreamingCTPTMonitor;
CT_Status_Matrix : ARRAY [1 .. c_NumberOfMonitoredAssets,
enum_PhaseID.PHASE_A .. enum_PhaseID.PHASE_C] OF
struct_CTPTStatusOutput;
CT_Status_String_Matrix : ARRAY [1 .. c_NumberOfMonitoredAssets,
enum_PhaseID.PHASE_A .. enum_PhaseID.PHASE_C] OF STRING(255);
END_VAR

IF RunOnce THEN
// Bootstrap A,B,C phase CTs for CT groups 1 - 4
// Bootstrap group 1
CT_Monitor.bootstrap_MonitoredCMV(channel := IED1_IED1.IA,
outputStatus := CT_Status_Matrix[1, enum_PhaseID.PHASE_A],
ctPtId := 'CT1A',
phase := enum_PhaseID.PHASE_A,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED1_IED1.IB,
outputStatus := CT_Status_Matrix[1, enum_PhaseID.PHASE_B],
ctPtId := 'CT1B',
phase := enum_PhaseID.PHASE_B,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED1_IED1.IC,
outputStatus := CT_Status_Matrix[1, enum_PhaseID.PHASE_C],
ctPtId := 'CT1C',
phase := enum_PhaseID.PHASE_C,
scaleFactor := 1);

// Bootstrap group 2
CT_Monitor.bootstrap_MonitoredCMV(channel := IED2_IED2.IA,
outputStatus := CT_Status_Matrix[2, enum_PhaseID.PHASE_A],
ctPtId := 'CT2A',
phase := enum_PhaseID.PHASE_A,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED2_IED2.IB,
outputStatus := CT_Status_Matrix[2, enum_PhaseID.PHASE_B],
ctPtId := 'CT2B',
phase := enum_PhaseID.PHASE_B,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED2_IED2.IC,
outputStatus := CT_Status_Matrix[2, enum_PhaseID.PHASE_C],
ctPtId := 'CT2C',
phase := enum_PhaseID.PHASE_C,
scaleFactor := 1);

// Bootstrap group 3
CT_Monitor.bootstrap_MonitoredCMV(channel := IED3_IED3.IA,
outputStatus := CT_Status_Matrix[3, enum_PhaseID.PHASE_A],
ctPtId := 'CT3A',
phase := enum_PhaseID.PHASE_A,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED3_IED3.IB,
outputStatus := CT_Status_Matrix[3, enum_PhaseID.PHASE_B],
ctPtId := 'CT3B',

Programming Reference Date Code 20241023


ConditionMonitoring 151
Classes

phase := enum_PhaseID.PHASE_B,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED3_IED3.IC,
outputStatus := CT_Status_Matrix[3, enum_PhaseID.PHASE_C],
ctPtId := 'CT3C',
phase := enum_PhaseID.PHASE_C,
scaleFactor := 1);

// Bootstrap group 4
CT_Monitor.bootstrap_MonitoredCMV(channel := IED4_IED4.IA,
outputStatus := CT_Status_Matrix[4, enum_PhaseID.PHASE_A],
ctPtId := 'CT4A',
phase := enum_PhaseID.PHASE_A,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED4_IED4.IB,
outputStatus := CT_Status_Matrix[4, enum_PhaseID.PHASE_B],
ctPtId := 'CT4B',
phase := enum_PhaseID.PHASE_B,
scaleFactor := 1);

CT_Monitor.bootstrap_MonitoredCMV(channel := IED4_IED4.IC,
outputStatus := CT_Status_Matrix[4, enum_PhaseID.PHASE_C],
ctPtId := 'CT4C',
phase := enum_PhaseID.PHASE_C,
scaleFactor := 1);

// Now initialize the CT monitor


Initialized := CT_Monitor.Initialize(en := Monitor_Enable,
minimumMagnitude := MinimumAmps,
alertThreshold := AlarmThresh,
alertPickupTime := T#60S,
monitorMode := enum_CTPTMonitorMode.RELATIVE_REFERENCE,
maximumWaitTime := 1000,
maximumRate := 30);

RunOnce := FALSE;
END_IF

IF Initialized THEN
// Update the monitor enable variable
Monitor_Enable := NOT (IED1_C37_118_POU.Offline
OR IED2_C37_118_POU.Offline
OR IED3_C37_118_POU.Offline
OR IED4_C37_118_POU.Offline);

// Run the monitor


CT_Monitor.Run();

// Assess the outputs and construct status strings.


FOR inc := 1 TO c_NumberOfMonitoredAssets DO
// Assess phase A for the given CT set
IF CT_Status_Matrix[inc, enum_PhaseID.PHASE_A].Alert.stVal THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_A] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_A].CtPtID),'is misoperational');
ELSIF CT_Status_Matrix[inc, enum_PhaseID.PHASE_A].QualityAlert THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_A] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_A].CtPtID),'is disabled due to
insufficient measurement quality');
ELSE
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_A] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_A].CtPtID),'is operational');
END_IF

// Assess phase B for the given CT set

Date Code 20241023 Programming Reference


152 ConditionMonitoring
Classes

IF CT_Status_Matrix[inc, enum_PhaseID.PHASE_B].Alert.stVal THEN


CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_B] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_B].CtPtID),'is misoperational');
ELSIF CT_Status_Matrix[inc, enum_PhaseID.PHASE_B].QualityAlert THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_B] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_B].CtPtID),'is disabled due to
insufficient measurement quality');
ELSE
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_B] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_B].CtPtID),'is operational');
END_IF

// Assess phase C for the given CT set


IF CT_Status_Matrix[inc, enum_PhaseID.PHASE_C].Alert.stVal THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_C] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_C].CtPtID),'is misoperational');
ELSIF CT_Status_Matrix[inc, enum_PhaseID.PHASE_C].QualityAlert THEN
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_C] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_C].CtPtID),'is disabled due to
insufficient measurementquality');
ELSE
CT_Status_String_Matrix[inc, enum_PhaseID.PHASE_C] :=
CONCAT(CONCAT('CT : ',
CT_Status_Matrix[inc,enum_PhaseID.PHASE_C].CtPtID),'is operational');
END_IF
END_FOR
END_IF

Monitor PT Group Over a Breaker-and-a-Half Scheme


Objective
PT1 through PT6 from Figure 5.3 are to be monitored against each other but are
allowed to break into sub-groups, contingent on the status of breakers 1 through
6 and disconnect switches 1 through 4. This example configuration implements
a monitoring system for Phase A only, for demonstration of the configuration.

Assumptions
This example assumes the following:

1. System topology matches that of Figure 5.3.


2. Three IEEE C37.118 protocol clients; IED1, IED2, and IED3 are added to
the project.
3. An IEEE C37.118 data rate of 30 messages per second is used for IED1,
IED2, and IED3.
4. IED1 takes measurements from PT1, PT2, Bk1, Bk2, and Sw1.
5. IED2 takes measurements from PT3, PT4, Bk3, Bk4, Sw2, and Sw3.
6. IED3 takes measurements from PT5, PT6, Bk5, Bk6, and Sw4.

Programming Reference Date Code 20241023


ConditionMonitoring 153
Classes

Solution
The user can apply one instance of class_Streaming_CTPT_Monitor to facilitate
this monitoring scheme.
Code Snippet 5.4 prgBkrAndHalfPtMon
PROGRAM prg_BkrAndHalfPtMon
VAR CONSTANT
c_NumberOfMonitoredAssets: UDINT := 6;
c_KvNominal : REAL := 38;
END_VAR
VAR
Monitor_Enable : BOOL;
MinimumKV : REAL := c_KvNominal*0.1;
AlarmThresh : REAL := 5; // In units of percent
RunOnce : BOOL := TRUE;
Initialized : BOOL;
inc : UDINT;
Monitor : ConditionMonitoring.class_StreamingCTPTMonitor :=
(InputTypeIsAngle := FALSE, InstanceName := 'Bkr-and-a-half-PT-mon');
Phase_A_Status_Matrix : ARRAY [1 .. c_NumberOfMonitoredAssets] OF
struct_CTPTStatusOutput;
Global_Status : ConditionMonitoring.struct_CTPTGroupStatus;
END_VAR

IF RunOnce THEN
////////// Bootstrap all assets monitored by IED1 //////////
// Bootstrap A phase PTs 1 and 2
Monitor.bootstrap_MonitoredCMV(CtPtID := 'PT1A',
phase := enum_PhaseID.PHASE_A,
ScaleFactor := 1.0,
NodeID := 1,
Channel := IED1_PMU1.VALPM,
OutputStatus := Phase_A_Status_Matrix[1]);

Monitor.bootstrap_MonitoredCMV(CtPtID := 'PT2A',
phase := enum_PhaseID.PHASE_A,
ScaleFactor := 1.0,
NodeID := 3,
Channel := IED1_PMU1.VAZPM,
OutputStatus := Phase_A_Status_Matrix[2]);

// Bootstrap Breaker 1
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 1,
NodeIdTwo := 2,
Status := IED1_PMU1._52AA1);
// Bootstrap Breaker 2
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 2,
NodeIdTwo := 4,
Status := IED1_PMU1._52AA2);
// Bootstrap disconnect switch 1
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 2,
NodeIdTwo := 3,
Status := IED1_PMU1.IN101);
////////// ////////// ////////// ////////// ////////// /////

////////// Bootstrap all assets monitored by IED2 //////////


// Bootstrap A phase PTs 3 and 4
Monitor.bootstrap_MonitoredCMV(CtPtID := 'PT3A',
phase := enum_PhaseID.PHASE_A,
ScaleFactor := 1.0,
NodeID := 5,
Channel := IED2_PMU1.VALPM,
OutputStatus := Phase_A_Status_Matrix[3]);

Date Code 20241023 Programming Reference


154 ConditionMonitoring
Classes

Monitor.bootstrap_MonitoredCMV(CtPtID := 'PT4A',
phase := enum_PhaseID.PHASE_A,
ScaleFactor := 1.0,
NodeID := 6,
Channel := IED2_PMU1.VAZPM,
OutputStatus := Phase_A_Status_Matrix[4]);

//Bootstrap Breaker 3
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 4,
NodeIdTwo := 6,
Status := IED2_PMU1._52AA1);
//Bootstrap Breaker 2
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 6,
NodeIdTwo := 7,
Status := IED2_PMU1._52AA2);
//Bootstrap disconnect switch 2
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 4,
NodeIdTwo := 5,
Status := IED2_PMU1.IN101);
//Bootstrap disconnect switch 3
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 7,
NodeIdTwo := 8,
Status := IED2_PMU1.IN102);
////////// ////////// ////////// ////////// ////////// /////

////////// Bootstrap all assets monitored by IED3 //////////


// Bootstrap A phase PTs 5 and 6
Monitor.bootstrap_MonitoredCMV(CtPtID := 'PT5A',
phase := enum_PhaseID.PHASE_A,
ScaleFactor := 1.0,
NodeID := 8,
Channel := IED3_PMU1.VALPM,
OutputStatus := Phase_A_Status_Matrix[5]);

Monitor.bootstrap_MonitoredCMV(CtPtID := 'PT6A',
phase := enum_PhaseID.PHASE_A,
ScaleFactor := 1.0,
NodeID := 10,
Channel := IED3_PMU1.VAZPM,
OutputStatus := Phase_A_Status_Matrix[6]);

// Bootstrap Breaker 5
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 7,
NodeIdTwo := 9,
Status := IED3_PMU1._52AA1);
// Bootstrap Breaker 6
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 1,
NodeIdTwo := 9,
Status := IED3_PMU1._52AA2);
// Bootstrap disconnect switch 4
Monitor.bootstrap_BreakerSwitch(Phase := enum_PhaseID.PHASE_A,
NodeIdOne := 9,
NodeIdTwo := 10,
Status := IED3_PMU1.IN101);
////////// ////////// ////////// ////////// ////////// /////

// Now initialize the CT monitor


Initialized := Monitor.Initialize(En := Monitor_Enable,
minimumMagnitude := MinimumKV,
alertThreshold := AlarmThresh,
alertPickupTime := T#60S,
monitorMode := enum_CTPTMonitorMode.RELATIVE_REFERENCE,

Programming Reference Date Code 20241023


ConditionMonitoring 155
Classes

maximumWaitTime := 1000,
maximumRate := 30);

RunOnce := FALSE;
END_IF

IF Initialized THEN
// Update the monitor enable variable
Monitor_Enable := NOT (IED1_C37_118_POU.Offline OR
IED2_C37_118_POU.Offline OR
IED3_C37_118_POU.Offline);

// Run the monitor


Monitor.Run();

// Update the global status structure


Global_Status := Monitor.GroupStatus;
END_IF

Converting an SEL-710-5 MSR Report to CSV


Objective
Convert an ASCII Motor Start Report (MSR) collected from an SEL-710-5 relay
to a comma-separated format file with an IEEE C37.232-compliant file name
and store the file in the RTAC virtual file system.

Assumptions
This example assumes the following:

1. The connected SEL-710-5 relay is using R100 firmware.


2. A client named SEL_710_5_1_SEL is added to the project.
3. The client is configured with a Flex parse message with the following
non-default settings applied:
➤ Flex Message Name : MSR
➤ Command String : MSR<CR><LF>
➤ Capture To File : True
4. The client POU input pin Send_Flex_Parse_Message_MSR is asserted on
demand by additional user logic.
5. The RTAC main task cycle time is 100 ms.

Solution
This solution uses a single instance of the class_IedReportConverter to convert
the content of the client report to a CSV file.
Code Snippet 5.5 Example SEL-710-5 MSR Report Conversion Program
PROGRAM prg_ConvertMSR
VAR CONSTANT
c_numRegEx : UDINT := 9;
END_VAR

VAR
ReportConverter : class_IedReportConverter :=
(LogRuntimeErrors := TRUE, MaxCycleTimeUsage := 50, InstanceID := 'SEL_710-5_1_MSR');

InputReportFile : STRING := '/FLEX_PARSE/SEL_710_5_1_SEL/SEL_710_5_1_SEL_MSR.capture';

Date Code 20241023 Programming Reference


156 ConditionMonitoring
Classes

OutDirectory : STRING := 'MSR_Reports';


OutputPostFix : STRING := 'Station_X,710-5_1,Company_Z,MSR.csv';
NumReports : UINT := 3;

InRegex :ARRAY [1 .. c_numRegex] OF STRING(255) :=


['([0-9]+:[0-9]+:[0-9]+[0-9]{1,3})',
// The preceding Regex matches the string following 'Time:'
'([0-9]+/[0-9]+/[0-9]{4,})',
// The preceding Regex matches the string following 'Start Date'
'([0-9]{2,}:[0-9]{2,}:[0-9]{2,}\\.[0-9]{1,})',
// The preceding Regex matches the string following 'Start Time'
'((?:[+-]{0,1}[0-9]{1,}[.]{0,1}[0-9]{0,3})|(?:[+-]{0,1}[.]{1,1}(?=[0-9])[0-9]{0,3}))',
// The preceding Regex matches the next REAL quantity, which appears after '# Starts'
'((?:[+-]{0,1}[0-9]{1,}[.]{0,1}[0-9]{0,3})|(?:[+-]{0,1}[.]{1,1}(?=[0-9])[0-9]{0,3}))',
// The preceding Regex matches the next REAL quantity, which appears after 'Start Time (s)'
'((?:[+-]{0,1}[0-9]{1,}[.]{0,1}[0-9]{0,3})|(?:[+-]{0,1}[.]{1,1}(?=[0-9])[0-9]{0,3}))',
// The preceding Regex matches the next REAL quantity, which appears after 'Start TCU (%)'
'((?:[+-]{0,1}[0-9]{1,}[.]{0,1}[0-9]{0,3})|(?:[+-]{0,1}[.]{1,1}(?=[0-9])[0-9]{0,3}))',
// The preceding Regex matches the next REAL quantity, which appears after 'MaxCurrent (A)'
'((?:[+-]{0,1}[0-9]{1,}[.]{0,1}[0-9]{0,3})|(?:[+-]{0,1}[.]{1,1}(?=[0-9])[0-9]{0,3}))',
// The preceding Regex matches the next REAL quantity, which appears after 'MinVoltage (V)'
'[\\x00-\\x2F\\x40-\\xFF]{1,}([\\x20\\x2E\\x30-\\x39]{1,})'];
// The preceding Regex matches an entire row of MSR sequence data

Labels : ARRAY [1 .. c_numRegex] OF STRING(255) :=


['Report Time',
'Start Date',
'Start Time',
'# Starts' ,
'Start Time (s)',
'Start TCU (%)',
'MaxCurrent (A)',
'MinVoltage (V)',
'CYCLE,IA,IB,IC,IN,VAB,VBC,VCA,TCURTR'];

Instances : ARRAY [1.. c_numRegex] OF UINT := [1,1,1,1,1,1,1,1,720];


ContentType : ARRAY [1 .. c_numRegex] OF enum_ReportContentType :=
[SUMMARY,SUMMARY,SUMMARY,SUMMARY,SUMMARY,SUMMARY,SUMMARY,SUMMARY,SEQUENCE];
i : UDINT;
ConverterError : BOOL;
ConverterErrorStatus : STRING(255);
InitializeAttempted : BOOL;
Tedge : R_TRIG;
END_VAR

Code Snippet 5.6 Example SEL-710-5 MSR Report Collection Code Body
IF NOT InitializeAttempted THEN
FOR i := 1 TO c_numRegEx DO
ReportConverter.Bootstrap_ReportRegexRule(ContentType[i], Labels[i],
Instances[i], InRegex[i]);
END_FOR

ReportConverter.Bootstrap_Report(InputFile := InputReportFile,
OutputDirectory := OutDirectory,
OutputFilePostFix := OutputPostFix,
ReportsPerFile := NumReports);

InitializeAttempted := TRUE;
END_IF

IF ReportConverter.Initialized THEN
Tedge(CLK := SEL_710_5_1_SEL_POU.Send_Flex_Parse_Message_MSR_DN);
IF Tedge.Q AND NOT ReportConverter.Busy THEN
ReportConverter.RequestReportConversion();
END_IF
END_IF

Programming Reference Date Code 20241023


ConditionMonitoring 157
Classes

ReportConverter.Run();

// Update the output status


ConverterError := ReportConverter.Error;
ConverterErrorStatus := ReportConverter.ErrorMessage;

Converting an SEL-710-5 FFT Report to CSV


Objective
Convert an ASCII Fast Fourier Transform (FFT) report collected from an
SEL-710-5 relay to a comma-separated format file with an IEEE C37.232-
compliant file name and store the file in the RTAC virtual file system.

Assumptions
This example assumes the following:

1. The connected SEL-710-5 relay is using R100 firmware.


2. A client named SEL_710_5_1_SEL is added to the project.
3. The client is configured with a Flex parse message with the following
non-default settings applied:
➤ Flex Message Name : FFT
➤ Command String : MET FFT<CR><LF>
➤ Capture To File : True
4. The client POU input pin Send_Flex_Parse_Message_FFT is asserted on
demand by additional user logic.
5. The RTAC main task cycle time is 100 ms.

Solution
This solution uses a single instance of the class_IedReportConverter to convert
the content of the client report to a CSV file.
Code Snippet 5.7 Example SEL-710-5 FFT Report Conversion Program
PROGRAM prg_ConvertFFT
VAR CONSTANT
c_numRegEx : UDINT := 8;
END_VAR

VAR
ReportConverter : class_IedReportConverter :=
(LogRuntimeErrors := TRUE,
MaxCycleTimeUsage := 50,
InstanceID := 'SEL_710-5_1_FFT');

InputReportFile : STRING :=
'/FLEX_PARSE/SEL_710_5_1_SEL/SEL_710_5_1_SEL_FFT.capture';

OutDirectory : STRING := 'FFT_Reports';


OutputPostFix : STRING := 'Station_X,710-5_1,Company_Z,FFT.csv';
NumReports : UINT := 3;

InRegex :ARRAY [1 .. c_numRegex] OF STRING(255) :=


['[\\x44\\x41\\x54\\x45\\x64\\x61\\x74\\x65\\x3A]{5,5}([\\x00-\\xFF]{0,11})',
// The preceding Regex matches the string following 'Date:'
'[\\x54\\x49\\x4d\\x45\\x74\\x69\\x6d\\x65\\x3A]{5,5}([\\x00-\\xFF]{0,14})',
// The preceding Regex matches the string following 'Time:'

Date Code 20241023 Programming Reference


158 ConditionMonitoring
Classes

'[\\x53\\x4F\\x55\\x52\\x43\\x45\\x73\\x6F\\x75\\x72\\x63\\x65\\x3A]{7,7}
([\\x00-\\xFF]{0,9})',
// The preceding Regex matches the string following 'Time Source:'
'[\\x43\\x48\\x41\\x4E\\x45\\x4C\\x63\\x68\\x61\\x6E\\x65\\x6C\\x3A]{8,8}
([\\x00-\\xFF]{1,3})',
// The preceding Regex matches the string following 'Selected Channel:'
'[\\x43\\x54\\x52\\x63\\x74\\x72\\x3A]{4,4}([\\x30-\\x39]{1,8})',
// The preceding Regex matches the string following 'CTR:'
'[\\x53\\x49\\x47\\x4E\\x41\\x4c\\x73\\x69\\x67\\x6E\\x61\\x6C]{6,6}([\\x20-\\xFF]{0,10})',
// The preceding Regex matches the string following 'Signal'
'[\\x0d|\\x0a]([\\x21-\\xFF]{1,}[\\x20-\\xFF]{1,})',
// The preceding Regex matches a single row of sequence data from the raw sample portion
// of the report
'[\\x0d|\\x0a]([\\x21-\\x39]{1,}[\\x20|\\x09]{1,}[\\x21-\\x39]{1,}[\\x20|\\x09]{1,}
[\\x21-\\x39]{1,})'];
// The preceding Regex matches a single row of sequence data from the FFT data portion of
// the report

Labels : ARRAY [1 .. c_numRegex] OF STRING(255) :=


['Report Date',
'Report Time',
'Time Source',
'Selected Channel' ,
'CTR',
'Units',
'Sample #,Channel Sample',
'Frequency(Hz),Magnitude(dB),Angle(deg)'
];

Instances : ARRAY [1.. c_numRegex] OF UINT := [1,1,1,1,1,1,19200,9599];


ContentType : ARRAY [1 .. c_numRegex] OF enum_ReportContentType :=
[SUMMARY,SUMMARY,SUMMARY,SUMMARY,SUMMARY,SUMMARY,SEQUENCE,SEQUENCE];
i : UDINT;
InitializeAttempted : BOOL;
Tedge : R_TRIG;
ConverterError : BOOL;
ConverterErrorStatus : STRING(255);
END_VAR

Code Snippet 5.8 Example 710-5 FFT Report Conversion Code Body
IF NOT InitializeAttempted THEN
FOR i := 1 TO c_numRegEx DO
ReportConverter.Bootstrap_ReportRegexRule(ContentType[i], Labels[i],
Instances[i], InRegex[i]);
END_FOR

ReportConverter.Bootstrap_Report(InputFile := InputReportFile,
OutputDirectory := OutDirectory,
OutputFilePostFix := OutputPostFix,
ReportsPerFile := NumReports);

InitializeAttempted := TRUE;
END_IF

IF ReportConverter.Initialized THEN
Tedge(CLK := SEL_710_5_1_SEL_POU.Send_Flex_Parse_Message_FFT_DN);
IF Tedge.Q AND NOT ReportConverter.Busy THEN
ReportConverter.RequestReportConversion();
END_IF
END_IF

ReportConverter.Run();

// Update the output status


ConverterError := ReportConverter.Error;
ConverterErrorStatus := ReportConverter.ErrorMessage;

Programming Reference Date Code 20241023


S E C T I O N 6

CrossTaskData
Introduction
The purpose of this library is to take a mutual exclusion (mutex) implementation
that uses the SysSem semaphore library and wrap it into single function block
calls to provide simple function blocks. Mutex data region creation depends
upon the size of a user-defined structure.

In computer science, mutex refers to a basic concurrency control requirement


that the critical sections of two concurrent processes cannot occur
simultaneously. This requirement prevents race conditions.

In this particular case, the mutex allows one task to write the data and another to
read the data. The mutex guarantees that the data remain intact. This is important
because Real-Time Automation Controller (RTAC) automation and main tasks
run with different priorities. To illustrate this, imagine a structure containing
a value "stVal" and a time stamp "t" and that a low-speed task is writing
periodically to this value and time stamp. Then imagine that a high-speed task
uses this information for some computation. If there were no mutex in place,
the lower priority main task may write only the "strVal" and be interrupted by
the higher priority automation task. The logic running on the automation task
would then be reading a newly updated "stVal" for which there is a "t" from the
previous "stVal" instead of the time stamp that should be associated with the
value. The mutex protects the integrity of the data, ensuring complete transfer of
information.

The library contains a preset number of reserved mutexes defined by a global


parameter. Each mutex has an identification number (ID) that is an integer
value between 1 and the number the global parameter defines. Writer function
blocks each claim one of the IDs, define the size of the mutex, and then set aside
memory for the mutex as necessary.

Initialization of the writer and reader function blocks results in verification to


ensure that only a single writer function block and a single reader function block
exist per mutex ID.

After initialization, the only input necessary for the function block is the address
of the data set that you want to read from and write to.

Special Considerations
The writer function block should never be instantiated in a method or a function.
Because memory allocation occurs in order to create the mutex, writer function
blocks must be instantiated in a program or global variable list. Declaring a
writer function block in either a function or a method causes undesired behavior.

Each mutex ID may be referenced by no more than one writer function block.

Date Code 20241023 Programming Reference


160 CrossTaskData
Supported Firmware Versions

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R150 or later.

Versions 3.5.1.0 and earlier can be used on RTAC firmware version R143 and
later.

Versions 3.5.0.3 and earlier can be used on RTAC firmware version R132 and
later.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_p_N_CrossTaskIDs UDINT 10 The number of mutexes available for


writer function blocks.

Function Blocks
fb_CrossTaskWrite
If data exist on one task to be shared with another, use this function block on the
task publishing the data. Only one writing function block may place data in a
given mutex.

Initialization Inputs
Name IEC 61131 Type Description

id UDINT The ID of the mutex that the writer will own (range
[1..g_p_N_CrossTaskIDs]).

sizeOfStruct UDINT The size of the structure, as returned by the SIZEOF()


function.

Inputs
Name IEC 61131 Type Description

pt_Struct DWORD The address of the variable from which to read, as


returned by the ADR() function.

Outputs
Name IEC 61131 Type Description

Error STRING(80) Any internal errors display here as a human-readable


string. The string is empty if no errors are present.

Programming Reference Date Code 20241023


CrossTaskData 161
Function Blocks

Processing
➤ You must call the function block body to obtain a lock on the mutex with
the ID specified.
➤ If the mutex is already locked (indicating another operation is in
progress), the operation waits until the lock is released and it obtains the
mutex.
➤ After obtaining the mutex, this function block copies the data referenced
by pt_Struct into protected, internal memory and the lock is released.

fb_CrossTaskRead
If data exist on one task to be shared with another, use this function block on the
task reading the data. More than one reading function blocks may pull data from
the same mutex.

Initialization Inputs
Name IEC 61131 Type Description

id UDINT The ID of the mutex from which this function block


reads (range [1..g_p_N_CrossTaskIDs]).

Inputs
Name IEC 61131 Type Description

pt_Struct DWORD The address of the variable to which the function block
writes the data, as returned by the ADR() function.

Outputs
Name IEC 61131 Type Description

Error STRING(80) Any internal errors display here as a human-readable


string. The string is empty if no errors are present.

Processing
➤ You must call the function block body to obtain a lock on the mutex with
the ID specified.
➤ If the mutex is already locked (indicating another operation is in
progress), the operation waits until the lock is released and it obtains the
mutex.
➤ After obtaining the mutex, the function block copies the data from
protected, internal memory into the location referenced by pt_Struct and
the lock is released.

Date Code 20241023 Programming Reference


162 CrossTaskData
Benchmarks

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms:

➤ SEL-3505
➢ R135-V2 firmware
➤ SEL-3530
➢ R135-V2 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R135-V2 firmware

Benchmark Test Descriptions


fb_CrossTaskWrite10
The posted time is the average execution time of 1000 calls in which a lock is
obtained and data are written into the mutex. This constitutes the worst case for
this call. The variable moved between tasks is an IEC 61131 dataset containing
10 UDINTs.

fb_CrossTaskRead10
The posted time is the average execution time of 1000 calls in which a lock is
obtained and data are read from the mutex. This constitutes the worst case for
this call. The variable moved between tasks is an IEC 61131 dataset containing
10 UDINTs.

fb_CrossTaskWrite10000
The posted time is the average execution time of 1000 calls in which a lock is
obtained and data are written into the mutex. This constitutes the worst case for
this call. The variable moved between tasks is an IEC 61131 dataset containing
10000 UDINTs.

fb_CrossTaskRead10000
The posted time is the average execution time of 1000 calls in which a lock is
obtained and data are read from the mutex. This constitutes the worst case for
this call. The variable moved between tasks is an IEC 61131 dataset containing
10000 UDINTs.

Programming Reference Date Code 20241023


CrossTaskData 163
Examples

Benchmark Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

fb_CrossTaskWrite10 13 8 1

fb_CrossTaskRead10 17 9 1

fb_CrossTaskWrite10000 800 450 4

fb_CrossTaskRead10000 780 450 4

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Moving Data From a High-Priority Task to a Low-Priority Task


Objective
You have a structure called dt_myAStruct containing data from a high-speed,
high-priority task. You want to copy this data to a slow-speed, low-priority task.

Assumptions
You have declared your IEC 61131 datatype, dt_myAStruct; here we use the
declaration found in Code Snippet 6.1.
Code Snippet 6.1 dt_myAStruct
TYPE dt_myAStruct :
STRUCT
a : UDINT;
b : BOOL;
END_STRUCT
END_TYPE

Date Code 20241023 Programming Reference


164 CrossTaskData
Examples

Solution
Create a writing program on the high-speed task, as shown in Code Snippet 6.2.
Code Snippet 6.2 prg_FastTask
PROGRAM prg_FastTask
VAR
_FastA : dt_myAStruct;
_FastWriter : fb_CrossTaskWrite (ID := 1, sizeOfStruct :=
SIZEOF(dt_myAStruct));
_ErrorA : STRING(80);
END_VAR

// Populate the variable "_FastA" here.


_FastA.a := 20;
_FastA.b := TRUE;

// Send the data to the mutex.


_FastWriter(pt_Struct := ADR(_FastA), Error => _ErrorA);

Create a reading program on the slow-speed task, as shown in Code Snippet 6.3.
Code Snippet 6.3 prg_SlowTask
PROGRAM prg_SlowTask
VAR
_SlowA : dt_myAStruct;
_SlowReader : fb_CrossTaskRead (ID := 1);
_ErrorA : STRING(80);
_TheAvar : UDINT;
_TheBvar : BOOL;
END_VAR

// First, read in all the data from the mutex to the local variable.
_SlowReader(pt_Struct := ADR(_SlowA), Error => _ErrorA);

// Now use _SlowA structure information as you wish.


_TheAvar := _SlowA.a;
_TheBvar := _SlowA.b;

Moving Data From a Low-Priority Task to a High-Priority Task


Objective
You have a structure called dt_myBStruct containing data from a low-speed,
low-priority task. You want to copy these data to a high-speed, high-priority
task.

Assumptions
You have declared your IEC 61131 datatype, dt_myBStruct; here we use the
declaration found in Code Snippet 6.4.
Code Snippet 6.4 dt_myBStruct
TYPE dt_myBStruct :
STRUCT
a : STRING(32);
b : INT;
c : REAL;
END_STRUCT
END_TYPE

Programming Reference Date Code 20241023


CrossTaskData 165
Examples

Solution
Create a writing program on the slow-speed task, as seen in Code Snippet 6.5.
Code Snippet 6.5 prg_SlowTask
PROGRAM prg_SlowTask
VAR
_SlowB : dt_myBStruct;
_SlowWriter : fb_CrossTaskWrite(ID := 2, sizeOfStruct :=
SIZEOF(dt_myBStruct));
_ErrorB : String(80);
END_VAR

// Populate the variable "_SlowB" here.


_SlowB.a := 'helloFastTask';
_SlowB.b := -5;
_SlowB.c := 6.25;

// Send the data to the mutex.


_SlowWriter(pt_Struct := ADR(_SlowB), Error => _ErrorB);

Create a reading program on the high-speed task, as seen in Code Snippet 6.6.
Code Snippet 6.6 prg_FastTask
PROGRAM prg_FastTask
VAR
_FastB : dt_myBStruct;
_FastReader : fb_CrossTaskRead(ID := 2);
_ErrorB : STRING(80);
_TheAvar : STRING(32);
_TheBvar : INT;
_TheCvar : REAL;
END_VAR

// First, read in all the data from the mutex to the local variable.
_FastReader(pt_Struct := ADR(_FastB), Error => _ErrorB);

// Now use _SlowB structure information as you wish.


_TheAvar := _FastB.a;
_TheBvar := _FastB.b;
_TheCvar := _FastB.c;

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 7

DescriptiveData
Introduction
The DescriptiveData library includes classes intended to interpret and manage
data structures formatted in common exchange formats.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_DescriptiveDataObject"
myDescriptiveDataObject := otherDescriptiveDataObject;

// This is fine
someVariable := myDescriptiveDataObject.value;
// As is this
pt_myDescriptiveDataObject := ADR(myDescriptiveDataObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).
➤ All data strings are limited to a fixed number of 255 characters in length.
Strings of greater length will be truncated to 255 characters.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R132 or later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Date Code 20241023 Programming Reference


168 DescriptiveData
Structures

enum_JsonType
Enumeration Description

BASE Outermost shell of JSON structure.

VALUE JSON element that describes an actual string value.

KEY JSON element describing key for key-value pair. The child node
of this key-value pair is not required to be a string, it may also be a
JSON LIST, MAP, or VALUE.

MAP JSON element wrapping structure of key-value pairs. Represents the


outer shell of a dictionary-like structure.

LIST JSON element wrapping multiple child JSON object nodes. Child
nodes may be JSON LIST, MAP, VALUE, or any combination of
these types.

enum_MatrixAccessMethod
Enumeration Description

e_NOT_SPECIFIED Initial enumeration state.

e_ROW Append or extract data sets on a per-row basis.

e_COLUMN Append or extract data sets on a per-column basis.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

struct_JsonElement
Name IEC 61131 Type Description

JSON_TYPE enum_JsonType Enumerated description of the JSON element's type.

INDEX UDINT Index marking the element's location in the internal vector managed
by class_JsonManager.

PARENT UDINT Index marking the location of the element's parent in internal vector
managed by class_JsonManager.

CHILD UDINT Index marking the location of the element's child in internal vector
managed by class_JsonManager.

PREVIOUS UDINT Index marking the location of the previous sibling element
(contained within either a LIST or MAP) in internal vector managed
by class_JsonManager.

NEXT UDINT Index marking the location of the next sibling element (contained
within either a LIST or MAP) in internal vector managed by
class_JsonManager.

LEVEL UDINT Depth of element in JSON structure tree stored within internal
vector managed by class_JsonManager.

Programming Reference Date Code 20241023


DescriptiveData 169
Classes

Name IEC 61131 Type Description

DATA STRING(255) Data string that serves to store either the key-string or the value-
string if the described element is either a KEY or VALUE,
respectively.

pt_CONTENT POINTER TO SELString.class_SELString Pointer to the class_SELString which stores the JSON contents,
either the key-string or the value-string if the described element is
either a KEY or VALUE.

Classes
This library provides the following classes as extensions of the IEC 61131
function block.

class_JsonManager (Class)
This class provides the necessary functionality to read JSON (JavaScript Object
Notation) data structures from any structure whose characters are accessible by
byte-wise operations (example structures include Dynamic Vectors, STRINGs,
and arrays of BYTEs). The JSON standard is fully described at json.org.
This class also provides functionality to create a new blank JSON structure and
then populate it with simple key-value pairs. The value portion must be a simple
string value and cannot contain a map, list, or nested key-value pair.
A purely fictitious example of a JSON structure is shown below.

1 {
2 "device": {
3 "fid": "SEL-3530-R146-V0-Z000002-D20200224",
4 "device name": "SEL-RTAC",
5 "licensed features": {
6 "features": [
7 {"hmi": true},
8 {"library": "fileio"},
9 {"library": "dynamicdisturbancerecorder"},
10 {"protocol": "IEC 61850 GOOSE"}
11 ]
12 },
13 "project": "Factory Default",
14 "users logged in": 1
15 }
16 }

The JSON format describes several data structure types, including key-value
pair structures and ordered lists. The official JSON format describes these two
structure types as being the foundational structures for the format as follows.
➤ Key-Value Pair Structures: A collection of name/value pairs. In various
languages, this is realized as an object, record, struct, dictionary, hash
table, keyed list, or associative array.
➤ Ordered List Structures: An ordered list of values. In most languages,
this is realized as an array, vector, list, or sequence.
The JSON standard defines support for various data types that may represent a
value, though in this class all value types are treated as strings and managed as
IEC 61131-3 STRING(255) objects. This means that although JSON defines the
ability to use Boolean, numeric, and null types directly without the requirement

Date Code 20241023 Programming Reference


170 DescriptiveData
Classes

of wrapping values in double quotes (i.e., the " character), this JSON class treats
all values as strings, and will not apply any type-specific conversions to generate
IEC 61131-3 compliant BOOL, INT, or REAL types. Such conversions are the
responsibility of the user.

The JSON standard defines an object to be an "unordered set of name/value


pairs," in essence, a dictionary. In the context of this class, JSON objects are
represented by the construction of MAP, KEY, and any child structure(s). These
various types are described and enumerated by enum_JsonType.

The MAP, LIST, and KEY types all support child structures, each of which may
subsequently be any of the aforementioned types. VALUE structures do not
support child structures because they are deemed to be the innermost structure in
the JSON hierarchy. All direct children of any MAP structure must be KEYs.

As per the JSON standard, this class will interpret all keys of key-value pairs
that are wrapped in double quotes (i.e., the " character). If keys in the JSON
structure being parsed are not wrapped in double quotes, an error will be thrown
to indicate parsing failure.

White space including horizontal tabs, linefeed characters, carriage returns, and
single spaces may separate delimiting characters and respective key or value
entries; backspace and form feed characters are not supported in such locations.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

HasParent BOOL R Returns TRUE if the currently visible JSON object


reference has a valid (not of type BASE) parent.

HasChild BOOL R Returns TRUE if the currently visible JSON object


reference has subsequent children.

HasNext BOOL R Returns TRUE if the currently visible JSON object


reference has subsequent relatives at the same JSON level;
this includes siblings that are described as either previous
or next.

IsTopLevel BOOL R Returns TRUE if the currently visible JSON object


references the top-level (highest-level) JSON structure.

Length UDINT R The number of JSON entries that are available in the
currently visible LIST or MAP. A Length of zero
corresponds to a structure without subsequent child
elements, a Length of one corresponds to a single
element.

Level UDINT R The zero-based level of the current scope within the JSON
structure. The outermost JSON level (BASE) is defined as
0.

NumSerializedBytes UDINT R The number of bytes of serialized data content produced


by a call to the SerializeJson() method. Indicates the
number of bytes available starting at pt_SerializedData.

StructSize UDINT R The number of JSON structure elements (represented


by struct_JsonElement) currently present in the
class_JsonManager.

Programming Reference Date Code 20241023


DescriptiveData 171
Classes

Name IEC 61131 Type Access Description

pt_KeysVector POINTER TO R Pointer to a BaseVector (sized appropriately to contain


DynamicVectors.class_BaseVector STRING(255) elements) which shall contain the valid
key-strings for the currently visible data structure, but not
the keys of any child data structures.

pt_SerializedData POINTER TO BYTE R Pointer to the first byte of serialized data produced by a
call to the SerializeJson() method.

Outputs
Name IEC 61131 Type Description

Error BOOL TRUE if the class is unable to parse a JSON data structure or a navigational or extraction
method fails due to an invalid JSON architecture.

ErrorDesc STRING(255) The last error encountered is described here and will only be displayed when Error is
TRUE.

Current struct_JsonElement The JSON structural element that is currently in scope. This structure describes all of
the relationships between the element currently in scope and all relatives (parent/child/
previous/ next).

ParseBytes (Method)
Call this method with an array of bytes that are desired to be parsed into an
equivalent JSON structure in the class_JsonManager.

Calling this method overwrites the JSON structure information parsed by


any previous calls. If more than one call per processing interval is expected,
instantiate a single class_JsonManager for each call.

Inputs

Name IEC 61131 Type Description

pt_byte POINTER TO BYTE Address of the first byte in an array of bytes that should be parsed into a JSON structure
interpretation by the class_JsonManager.

Length UDINT Number of bytes in the array of bytes that should be parsed and interpreted by the
class_JsonManager.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if JSON structure is parsed successfully.

Processing
➤ ParseBytes() call sets Error to FALSE and clears the ErrorDesc string.
➤ ParseBytes() iterates over array of bytes and generates representative
JSON structure in class_JsonManager to describe the input.

Date Code 20241023 Programming Reference


172 DescriptiveData
Classes

➤ ParseBytes() method enforces the maximum string value lengths for both
keys and values of JSON key-value pairs.
➤ ParseBytes() method enforces JSON structure formatting according to
JSON formatting guidelines provided by the JSON standard.

Down (Method)
Call this method to force the class_JsonManager to move down into a nested
data structure object (node) to reference the elements in that node's scope.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if class_JsonManager successfully navigates to nested


node.

Processing
➤ Down() call validates that child node exists. Returns FALSE if child node
does not exist.
➤ Down() sets class_JsonManager to view the scope of child node.

Next (Method)
Call this method to force the class_JsonManager to move to the next sibling data
structure object (node) in a series to reference the elements in that node's scope.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if class_JsonManager successfully navigates to next


node in series.

Processing
➤ Next() call validates that relative sibling node exists. Returns FALSE if
next sibling node does not exist.
➤ Next() call validates that relative sibling node is not self. Returns FALSE
if next sibling node's index is equal to current node's index.
➤ Next() sets class_JsonManager to scope of the next node in series.

Previous (Method)
Call this method to force the class_JsonManager to move to the previous sibling
data structure object (node) in a series to reference the elements in that node's
scope.

Programming Reference Date Code 20241023


DescriptiveData 173
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if class_JsonManager successfully navigates to


previous node in series.

Processing
➤ Previous() call validates that relative sibling node exists. Returns FALSE
if previous sibling node does not exist.
➤ Previous() call validates that relative sibling node is not self. Returns
FALSE if previous sibling node's index is equal to current node's index.
➤ Previous() sets class_JsonManager to scope of the previous node in
series.

Root (Method)
Call this method to direct the class_JsonManager to reset scope of the manager
class to the outermost, so-called root location, of the JSON structure. This
method provides a means for resetting the manager's view of the structure
following Get() method calls that enter the nesting of the JSON structure. As
the Get() method is called for entering nesting one JSON level at a time, the
Root() method is used to exit all nested levels in one step.

The JSON structure example shown below will observe the behavior described
immediately following the example upon a call to the Root() method at any
time during operation.

1 {
2 "device": {
3 "fid": "SEL-3530-R146-V0-Z000002-D20200224",
4 "device name": "SEL-RTAC",
5 "licensed features": {
6 "features": [
7 {"hmi": true},
8 {"library": "fileio"},
9 {"library": "dynamicdisturbancerecorder"},
10 {"protocol": "IEC 61850 GOOSE"}
11 ]
12 },
13 "project": "Factory Default",
14 "users logged in": 1
15 }
16 }

Calling the Root() method at any point while navigating the JSON structure
shown above will set the class_JsonManager's view to the outermost layer. In
essence, the very first curly bracket that is listed before device will be used
as the root location as it serves to describe the outermost MAP of the structure.
Upon such an operation, the root position would be of type MAP and show a
class_JsonManager index of 1, a parent element node index of 0, and a child
element node index of 2. The aforementioned child would logically be of type
KEY with a key name of "device".
The root location will never describe a next or previous index, and although it
may or may not describe a child element node index, it will always describe a
parent element node index, which will always be zero.

Date Code 20241023 Programming Reference


174 DescriptiveData
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if class_JsonManager successfully navigates to root.

Processing
➤ Root() sets class_JsonManager to scope of the root node in JSON
structure.

Up (Method)
Call this method to force the class_JsonManager to move up from a nested data
structure object (node) to reference the elements in that node's parent's scope.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if class_JsonManager successfully navigates to parent


node.

Processing
➤ Up() call validates that parent node is not base-level, returns FALSE
otherwise.
➤ Up() sets class_JsonManager to scope of the parent node.

Get (Method)
Call this method to obtain the available value from a keyed dictionary or ordered
list from the internally managed JSON structure. If the obtained value cannot be
represented as a string (i.e., the sub-structure is a list or dictionary), this method
will move the class_JsonManager reference to that sub-structure in preparation
for the next Get() method or the next navigational method (i.e., Up(), Down(),
Next(), Previous(), or Root()).

In order to facilitate both keyed and ordered data retrieval, this method accepts
an input as a STRING(255) that can materialize as either the key of a key-value
pair or a string representation of the zero-based index for an element in a list of
objects.

The Get() method utilizes a combination of both a method return value and
the class_JsonManager's Error and ErrorDesc outputs. This combination
is especially useful in providing feedback to the user regarding whether the
operation performed by the Get() method resulted in one of three states. These
three states are not a form of enumerated states, but rather a combination of
class and method outputs and method returns. These states are meant to describe
successful string extraction, successful structure extraction without a string,
or unsuccessful extraction where neither string nor child structure could be
extracted.

Programming Reference Date Code 20241023


DescriptiveData 175
Classes

When a string (VALUE) is successfully extracted from the JSON element, the
Get() method output is set with the string value, and the return value is set
to TRUE. In situations where the Get() method is able to find the keyed or
indexed structure, but no valid VALUE is associated with that element (i.e.,
the child is of type: MAP, LIST, or KEY) the output will be left unaltered as an
empty string, and the return value will be set to FALSE. If the particular key or
index requested with the Get() method cannot be found in the current scope,
the method will both return FALSE and indicate an error by use of the Error
and ErrorDesc outputs of the class_JsonManager.

In addition to setting the output string of the method to equal the VALUE of the
JSON element and setting the return value to TRUE, when the string extraction
is successful, the Get() method will set the class_JsonManager scope to the
element's parent entry. That is to say, if a VALUE is extracted from a key-value
pair, the parent KEY of that key-value pair will become the active scope of the
class_JsonManager. In this way, sequential iteration over a list of values, or map
of key-value pairs can be performed in a logical flow. Furthermore, upon such
successful extraction, the method returns TRUE and clears the class ErrorDesc
output while setting Error to FALSE.

In instances where this method cannot return a value directly (i.e., the child
is of type MAP, LIST, or KEY) but the particular key or index exists in the
class_JsonManager, the method will move as appropriate to the new scope of
this key or index and it will remain in this position to support continued nesting
and iteration for value extraction. This will result in the return value being set
to FALSE and the output being set to an empty string. In instances where this
method cannot find the key or index due to lack of its presence in the current
scope, the class_JsonManager will be reset to the root location (the outermost
JSON structure), the Error output will be set to TRUE, and ErrorDesc output
will indicate a failure to find the requested key or index in the current scope.

In situations where the class_JsonManager is referencing a MAP or LIST, this


method will automatically nest itself into the first child node of the MAP or
LIST to clearly interpret the keys or list entries of the structure and allow for
clear JSON navigation. Conversely, if the class_JsonManager references a JSON
element that is described as a non-valid JSON type (i.e., BASE), this method
will return FALSE and indicate error by means of the Error and ErrorDesc
outputs.

Shown below is an example of a JSON structure upon which the Get() method
can be called to extract various data points.

1 {
2 "fid": "SEL-3530-R146-V0-Z000002-D20200224",
3 "device name": "SEL-RTAC",
4 "licensed features": {
5 "features": [
6 {"hmi": true},
7 {"library": "fileio"},
8 {"library": "dynamicdisturbancerecorder"},
9 {"protocol": "IEC 61850 GOOSE"}
10 ]
11 },
12 "project": "Factory Default",
13 "users logged in": 1
14 }

Date Code 20241023 Programming Reference


176 DescriptiveData
Classes

Immediately following the parsing operation of the above data structure,


the Get() method will have access to retrieve the various structures of the
outermost keys. That is to say that the following strings would be valid
arguments for the Get() method at the root location.

[ "fid", "device name", "licensed features", "project", "users


logged in" ]

If a user is to use the Get() method to extract the structure related to the
"licensed features" key, the class_JsonManager will change scope to provide
access to a new set of valid keys as shown below.

[ "features" ]

Furthermore, if a user leverages the Get() method to extract the "features" key,
a new set of valid arguments will be allowed, but as these subsequent elements
are children of a LIST, they should be accessed by zero-based index. As such,
the valid arguments are now a set of strings as shown below.

[ "0", "1", "2", "3" ]

In summary, after parsing the above JSON data structure, and directly using the
Get() method to extract data associated with a particular key, a string value
will be output if the particular data structure associated with the key/index input
is of type VALUE. Thus, referencing a VALUE containing a valid string, the
return will be set TRUE and output loaded with the data string. Conversely, if
the particular structure is of any other JSON type and the key/index exists, the
class_JsonManager will navigate to the scope of that structure and return FALSE
without setting any error indication.

Inputs
Name IEC 61131 Type Description

KeyIndex STRING(255) String representing the particular key or index of the data that should be extracted.

Outputs
Name IEC 61131 Type Description

Value STRING(255) String representing the particular VALUE associated with its keyed or indexed parent.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if string value successfully extracted, FALSE if failure


occurs or if substructure is not of type VALUE.

Processing
➤ Get() call sets class error output to FALSE and sets error description
string output to an empty string (i.e., ' ').
➤ Get() call validates that current scope allows for extraction of values
associated with the particular key or index.

Programming Reference Date Code 20241023


DescriptiveData 177
Classes

➤ Get() performs nesting as necessary to enter the scope of either MAP or


LIST types.
➤ Get() iterates over the keys or indices currently visible in the JSON
structure and tests each key or index against the input KEY to identify the
appropriate value string to extract.
➤ Get() stores the extracted value in the output VALUE string if found
and sets the return value of the method to TRUE before setting the
class_JsonManager back to the value's parent location.
➤ Get() moves the class_JsonManager to the scope of the particular key or
index if found, sets the return value of the method to FALSE, and empties
the output string (i.e., sets the output value to ' ').
➤ Get() moves the class_JsonManager to the root location if the provided
key/index input is not found in the current scope. Additionally, the class
error flag and description string will be set to indicate such failure to
locate key or index.

GetSELString (Method)
Call this method to obtain the available value from a keyed dictionary or
ordered list as a SELString from the internally managed JSON structure. If the
obtained value cannot be represented as a string (i.e., the sub-structure is a list
or dictionary), this method will move the class_JsonManager reference to that
sub-structure in preparation for the next GetSELString() method or the next
navigational method (i.e., Up(), Down(), Next(), Previous(), or Root()).
This method has identical functionality and processing to the previously-
described Get() method, except a class_SELString is first cleared and if the key
or list index is valid is then populated with the Value.

Inputs
Name IEC 61131 Type Description

KeyIndex STRING(255) String representing the particular key or index of the data that should be extracted.

Inputs/Outputs
Name IEC 61131 Type Description

Value SELString.class_SELString SELString representing the particular VALUE associated with its keyed or
indexed parent.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if class_SELString value successfully extracted,


FALSE if failure occurs or if substructure is not of type VALUE.

DumpStructure (Method)
Call this method to obtain the data structure contained within the
class_JsonManager and store the structure in a vector appropriately sized to
contain struct_JsonElement elements.

Date Code 20241023 Programming Reference


178 DescriptiveData
Classes

Inputs/Outputs
Name IEC 61131 Type Description

StructVector DynamicVectors.class_BaseVector Dynamic vector object sized appropriately to contain struct_JsonElement


elements.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the full data structure is loaded successfully.

Processing
➤ DumpStructure() call clears StructVector.
➤ DumpStructure() call validates that current JSON vector is valid and not
empty; returns FALSE otherwise.
➤ DumpStructure() iterates over each element contained in JSON structure
and appends elements to StructVector.

GetNextValue (Method)
Call this method to obtain the next available value from a keyed dictionary or
ordered list in the current scope of the internally managed JSON structure.

Outputs
Name IEC 61131 Type Description

Value STRING(255) The value of next key if present scope is a MAP or


next list value if the present scope is a LIST.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the next element in the MAP or list was successfully
loaded into the Value Output.

Processing
➤ If current scope is the outermost element of a LIST or MAP, navigate
down into the list or map. After navigating down, if a value is present at
this scope (such as with a list), load this value into the Value output and
return.
➤ Navigate to the next element.
➤ If Current element is a KEY, navigate down until a VALUE can be
extracted and loaded into the Value output.
➤ If parent of Current element is a LIST, navigate down until a VALUE can
be extracted and loaded into the Value output.

Programming Reference Date Code 20241023


DescriptiveData 179
Classes

GoToIndex (Method)
Call this method to navigate to a specified element in the JSON structure and
load it to the current scope.

Inputs

Name IEC 61131 Type Description

NewIndex UDINT Index of the JSON vector which should be loaded


as the Current scope.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the specified element was successfully loaded as the
current scope.

Processing
➤ Validate that the JSON structure contains at least the BASE element and
an initial LIST or MAP entry.
➤ Validate that NewIndex is not 0 or a value greater than the size of the
JSON structure.
➤ Load the element specified by NewIndex into the Current scope of the
class_JsonManager.

Reset (Method)
Call this method to reset a JSON structure that had previously been populated by
calls to either ParseBytes() or AddKeyValuePair().

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the JSON structure was successfully reset.

Processing
➤ Resets and clears any existing content in the JSON structure.
➤ Resets and clears any previously serialized data.
➤ Clears any existing error conditions.
➤ Creates a single base element in the JSON structure representing the
outermost element of the structure.

Date Code 20241023 Programming Reference


180 DescriptiveData
Classes

AddKeyValuePair (Method)
Call this method to add a new key-value pair to a new JSON structure or one
that was previously re-initialized with the Reset() method. All Keys are added
sequentially as level 2 elements in a contiguous map that exists at level 1 of
the JSON structure. Values are added as single level 3 elements beneath their
respective Key. Values must be a simple string element and cannot contain a
map, list, or nested key-value pair.

A sample JSON structure that can be created with AddKeyValuePair() is shown


below:

1 {
2 "fid" : "SEL-3530-R148-V2-Z000015-D20210414",
3 "device name" : "SEL-RTAC",
4 "project" : "Factory Default",
5 "users logged in" : "1",
6 "hmi enabled" : "true",
7 "key" : "value"
8 }

Inputs

Name IEC 61131 Type Description

Key STRING(255) Specifies the name of the key.

Value STRING(255) Specifies the value to associate with the key.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the key-value pair was successfully added to the
JSON structure.

Processing
➤ Verifies if the JSON structure is empty and sets up the initial BASE
element if required.
➤ Verifies that the specified Key name is unique to any previously added
Keys. Will set the Error and ErrorDesc outputs and return FALSE if
the Key name already exists.
➤ If required, a MAP JSON element will be added to the JSON structure at
INDEX 1, LEVEL 1.
➤ Adds the new Key-Value pair to the end of the existing JSON structure.
➤ Updates the PREVIOUS and NEXT properties of the first and last Keys
in the JSON structure to link to the new Key element as their sibling.
➤ Updates the Current scope of the JSON manager to the root MAP
element.

Programming Reference Date Code 20241023


DescriptiveData 181
Classes

AddKeyValuePairSELString (Method)
Call this method to add a new key-value pair to new JSON structure or one that
was previously re-initialized with the Reset() method. The Value component of
the pair is assigned from a SELString variable.

This method has identical functionality and processing to the previously


described AddKeyValuePair() method, except the Value is assigned from a
class_SELString variable.

Inputs

Name IEC 61131 Type Description

Key STRING(255) Specifies the name of the key.

Inputs/Outputs

Name IEC 61131 Type Description

Value SELString.class_SELString Specifies the SELString value to associate with


the key.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the key-value pair was successfully added to the
JSON structure.

SerializeJson (Method)
Call this method to obtain the data structure contained within the
class_JsonManager and translate the contents into an array of BYTEs containing
JSON compliant ASCII formatting. A pointer to the array of bytes is available
via the pt_SerializedData property and the NumSerializedBytes property can be
used to determine the length of the array.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the JSON structure is successfully serialized.

Processing
➤ A SerializeBytes() call iterates over each item contained in the JSON
structure and writes out machine-formatted (no human-readable format
'helpers' such as carriage returns or tabulation is included) JSON-
compliant characters into the array of bytes specified at pt_Byte.
➤ The resulting serialized data is stored in an internal data array managed
by the class_JsonManager instance. A pointer to the array of data is
available via the pt_SerializedData property and the length of the array is
available via the NumSerializedBytes property.

Date Code 20241023 Programming Reference


182 DescriptiveData
Classes

class_CsvManager (Class)
This class provides the necessary functionality to write/read CSV (comma
separated value) content to/from the RTAC logic engine. This documentation
references a CSV object. This object is a two-dimensional data buffer that uses
dynamic memory allocation to adjust in size. This object serves as a prototype
CSV data set and allows CSV content to be read from an external buffer and/
or appended incrementally by row or column. The object can then be serialized
(written to a byte string) at the user's discretion for easy consumption by a file
writer.
This class can be configured to switch between various CSV composition modes
during runtime by calling the provided 'init' methods whenever a mode switch is
desired.

Inputs
Name IEC 61131 Type Description

LogRuntimeErrors BOOL If TRUE, the library logs runtime errors in the RTAC Sequence of Events (SOE) log.

Outputs
Name IEC 61131 Type Description

Initialized BOOL When TRUE, CsvManager is ready for append, extraction, or serialization operations. Default
is FALSE.

Busy BOOL When TRUE, CsvManager is actively processing. Default is FALSE.

CsvParsed BOOL Pulses for one cycle after completion of a CSV parse operation that was initiated via
InitReadWriteMode(). Default is FALSE.

PercentParsed REAL A number between 0 and 100 representing the completion percentage of the parse operation.
Default is 0.

CsvSerialized BOOL Pulses for one cycle after completion of a CSV serialization operation that was initiated via
SerializeCsv(). Default is FALSE.

PercentSerialized REAL A number between 0 and 100 representing the completion percentage of the serialize
operation. Default is 0.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

AppendMode enum_MatrixAccessMethod R Specifies the method by which content must be added to the CSV
object. Default is e_NOT_SPECIFIED

Error BOOL R TRUE if the class is unable to read/write CSV content. Default is
FALSE.

ErrorDesc STRING(255) R The last error encountered is described here and will only be
displayed when Error is TRUE. Default is an empty string (' ').

NumColumns UDINT R Current number of columns contained in the CSV object. Default
is 0.

Programming Reference Date Code 20241023


DescriptiveData 183
Classes

Name IEC 61131 Type Access Description

NumRows UDINT R Current number of rows contained in the CSV object. Default is
0.

pt_SerializedData POINTER TO BYTE R Pointer to the first byte of data available to be written to a
file. Useful as input to FileIO.class_FileWriter.AppendBytes()
method. Default is 0.

NumSerializedBytes UDINT R The number of bytes available to be written to a file. Useful as


input to FileIO.class_FileWriter.AppendBytes() method. Default
is 0.

InitReadWriteMode (Method)
This method initializes the CSV manager in read/write mode and initiates a CSV
parse operation.

➤ This mode allows existing CSV content to be parsed, modified, and


written.
➤ This mode forces AppendMode := e_ROW.
➤ CSV content to be parsed must contain a consistent number of comma-
delimited elements per line.

Inputs/Outputs

Name IEC 61131 Type Description

inVector DynamicVectors.class_ByteVector A byte vector loaded with CSV content via


FileIO.class_FileReader2.AppendToVector() or equivalent.

Return Value

IEC 61131 Type Description

BOOL Returns FALSE if InVector.Size = 0 or Busy = TRUE. Otherwise,


returns TRUE.

Processing
1. If InVector.Size = 0, returns FALSE.
2. If Busy = TRUE, returns FALSE.
3. Else does the following:
➤ Sets class outputs to default values.
➤ Clears the CSV object if not already clear.
➤ Sets AppendMode := e_ROW.
➤ Requests a parse operation to be executed by the Run() method.
➤ Sets Busy = TRUE.

Date Code 20241023 Programming Reference


184 DescriptiveData
Classes

InitWriteColumnMode (Method)
This method initializes the CSV manager with a blank CSV object.

➤ This mode allows for the creation of new CSV content via column append
operations.
➤ This mode forces AppendMode := e_COLUMN.

Return Value

IEC 61131 Type Description

BOOL Returns FALSE if Busy = TRUE. Otherwise, returns TRUE.

Processing
1. If Busy = TRUE, returns FALSE.
2. Else does the following:
➤ Sets class outputs to default values.
➤ Sets AppendMode := e_COLUMN.
➤ Clears the CSV object if not already clear.
➤ Sets Initialized := TRUE.

InitWriteRowMode (Method)
This method initializes the CSV manager with a blank CSV object and a fixed
label row.

➤ This mode allows for the creation of new CSV content via row append
operations.
➤ This mode forces AppendMode := e_ROW.

Inputs

Name IEC 61131 Type Description

pt_Labels POINTER TO STRING(255) A pointer to a contiguous memory space containing a collection of column labels.

numLabels UDINT The number of labels to append.

Return Value

IEC 61131 Type Description

BOOL Returns FALSE if Busy = TRUE or on invalid input. Otherwise,


returns TRUE.

Programming Reference Date Code 20241023


DescriptiveData 185
Classes

Processing
1. If Busy = TRUE, returns FALSE.
2. Checks the memory space defined by the inputs, if invalid, returns
FALSE.
3. Else does the following:
➤ Sets class outputs to default values.
➤ Sets AppendMode := e_ROW.
➤ Clears the CSV object if not already clear.
➤ Sets NumColumns = numLabels.
➤ Sets Initialized := TRUE.

SerializeCsv (Method)
This method initiates an asynchronous serialization of the CSV object into a
CSV formatted byte string.

Return Value

IEC 61131 Type Description

BOOL Returns FALSE if errors were encountered. Otherwise, returns


TRUE.

Processing
1. If Initialized = FALSE or Busy = TRUE, returns FALSE.
2. Else does the following:
➤ Sets Busy to TRUE.
➤ Sets PercentSerialized to 0.
➤ Requests a serialization operation to be conducted by the Run()
method.

SerializeRow (Method)
This method converts a memory-contiguous collection of STRING(255)
objects to a byte string that can be used for direct file writing via a
FileIO.FileWriter.AppendBytes() method call. This method can be used
independently from the other methods and does not require Initialized =
TRUE.

NOTE
This method does not affect the CsvSerialized or PercentSerialized class
outputs.

Date Code 20241023 Programming Reference


186 DescriptiveData
Classes

Inputs
Name IEC 61131 Type Description

pt_sourceData POINTER TO STRING(255) A pointer to a contiguous memory space containing the row content.

numElements UDINT Number of STRING(255) elements in the data set.

Outputs
Name IEC 61131 Type Description

pt_serializedRow POINTER TO BYTE Pointer to the first byte of serialized row data.

numSerializedBytes UDINT Number of serialized bytes.

Return Value
IEC 61131 Type Description

BOOL Returns FALSE if invalid input. Otherwise, returns TRUE.

Processing
1. Returns FALSE if any of the following are TRUE:
➤ pt_sourceData = 0
➤ numElements = 0
2. Else, does the following:
➤ Copies each STRING(255) (up to but not including the null byte) into
a contiguous memory space, separated by ASCII commas (,).
➤ Appends an ASCII newline followed by a carriage return to the end of
the serialized bytes.

AppendColumn (Method)
This method appends a new column to the CSV object.

Inputs
Name IEC 61131 Type Description

label STRING(255) Column label, to appear in row 1 of the CSV object.

pt_sourceData POINTER TO STRING(255) Pointer to the data.

numElements UDINT Number of elements in the data set.

appendToFront BOOL Set to TRUE to append data set as the first column of the CSV object. Set to
FALSE to append as the last column.

Return Value
IEC 61131 Type Description

BOOL Returns FALSE if invalid input. Otherwise, returns TRUE.

Programming Reference Date Code 20241023


DescriptiveData 187
Classes

Processing
1. Returns FALSE if any of the following are TRUE:
➤ Busy = TRUE
➤ Initialized = FALSE
➤ AppendMode = e_ROW
➤ The memory space defined by the inputs is invalid.
➤ numElements = 0
2. Else, does the following:
➤ Appends label to an internal buffer.
➤ Appends numElements of content from pt_sourceData to the CSV
object.
➤ Increments NumColumns by one.

AppendRow (Method)
This method appends a new row to the CSV object.

Inputs

Name IEC 61131 Type Description

pt_sourceData POINTER TO STRING(255) Pointer to the data.

numElements UDINT Number of elements in the data set.

appendToTop BOOL Set to TRUE to append data set as the first row of the CSV object. Set to
FALSE to append as the last row.

Return Value

IEC 61131 Type Description

BOOL Returns FALSE if invalid input. Otherwise, returns TRUE.

Processing
1. Returns FALSE if any of the following are TRUE:
➤ Busy = TRUE
➤ Initialized = FALSE
➤ AppendMode = e_COLUMN
➤ The memory space defined by the inputs is invalid.
➤ numElements = 0
➤ numElements <> NumColumns
2. Else, does the following:
➤ Else appends numElements of content from pt_sourceData to the CSV
object.
➤ Increments NumRows by one.

Date Code 20241023 Programming Reference


188 DescriptiveData
Classes

DeleteDataSets (Method)
This method deletes one or more columns or rows from the CSV object. For row
deletion operations, the label row is not eligible for deletion.

Inputs

Name IEC 61131 Type Description

deleteMode enum_MatrixAccessMethod Specify deletion by row or column.

numToDelete UDINT The number of columns or rows to delete.

deleteFromFront BOOL Set to TRUE to delete starting with the first row or column. Set to FALSE to
delete starting with the last row or column.

Return Value

IEC 61131 Type Description

BOOL Returns FALSE if invalid input. Otherwise, returns TRUE.

Processing
1. Returns FALSE if any of the following are TRUE:
➤ If Busy = TRUE
➤ Initialized = FALSE
➤ deleteMode is an invalid enumeration entry
➤ numToDelete is greater than NumColumns or NumRows (depends
on deleteMode)
2. Else, does the following:
➤ Removes numToDelete rows or columns from the CSV object.
➤ Decrements NumColumns or NumRows by numToDelete (depends
on deleteMode).

ExtractDataSetToQueue (Method)
This method copies one column or row from the CSV object into a designated
double-ended queue.

Inputs

Name IEC 61131 Type Description

extractMode enum_MatrixAccessMethod Specify extraction by row or column.

dataSetIndex UDINT A one-based row or column index for the data set to be extracted. Row index
one corresponds to the first row after the label row.

Programming Reference Date Code 20241023


DescriptiveData 189
Classes

Inputs/Outputs
Name IEC 61131 Type Description

targetQueue Queue.class_Deque Queue with elementSize := SIZEOF(STRING(255)) to contain the


extracted dataset.

Return Value
IEC 61131 Type Description

BOOL Returns FALSE if invalid input. Otherwise, returns TRUE.

Processing
1. Returns FALSE if any of the following are TRUE:
➤ If Busy = TRUE
➤ Initialized = FALSE
➤ extractMode is an invalid enumeration entry
➤ dataSetIndex is zero or greater than NumColumns or NumRows
(depends on extractMode)
2. Else, does the following:
➤ Calls Recycle() on TargetQueue.
➤ Copies row or column and pushes to the back of TargetQueue.

ExtractDataSetToVector (Method)
This method copies one column or row from the CSV object into a designated
dynamic vector.

Inputs
Name IEC 61131 Type Description

extractMode enum_MatrixAccessMethod Specify extraction by row or column.

dataSetIndex UDINT A one-based row or column index for the data set to be extracted. Row
index one corresponds to the first row after the label row.

Inputs/Outputs
Name IEC 61131 Type Description

targetVector DynamicVectors.class_BaseVector Dynamic vector with elementSize := SIZEOF(STRING(255)) to


contain the extracted dataset.

Return Value
IEC 61131 Type Description

BOOL Returns FALSE if invalid input. Otherwise, returns TRUE.

Date Code 20241023 Programming Reference


190 DescriptiveData
Classes

Processing
1. Returns FALSE if any of the following are TRUE:
➤ If Busy = TRUE
➤ Initialized = FALSE
➤ extractMode is an invalid enumeration entry
➤ dataSetIndex is zero or greater than NumColumns or NumRows
(depends on extractMode)
2. Else, does the following:
➤ Calls Recycle() on TargetVector.
➤ Copies row or column and pushes to the back of TargetVector.

ExtractCell (Method)
This method copies the contents of one cell of the CSV Object and returns the
STRING value.

Inputs

Name IEC 61131 Type Description

rowIndex UDINT The one-based row index of the target cell.

colIndex UDINT The one-based column index of the target cell.

isLabel BOOL When TRUE, the column label at colIndex is returned.


rowIndex is ignored.

Return Value

IEC 61131 Type Description

STRING(255) Returns the STRING value of the cell at rowIndex, colIndex.

Processing
1. Returns a null string if any of the following are TRUE:
➤ Busy = TRUE
➤ Initialized = FALSE
➤ rowIndex is zero or greater than NumRows while isLabel = FALSE
➤ colIndex is zero or greater than NumColumns

OverwriteCell (Method)
This method overwrites the contents of one cell of the CSV Object.

Programming Reference Date Code 20241023


DescriptiveData 191
Classes

Inputs

Name IEC 61131 Type Description

rowIndex UDINT The one-based row index of the target cell.

colIndex UDINT The one-based column index of the target cell.

newValue STRING(255) The content with which the cell will be overwritten.

isLabel BOOL When TRUE, the column label at colIndex is returned.


rowIndex is ignored.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if cell was overwritten.

Processing
1. Returns FALSE if any of the following are TRUE:
➤ Busy = TRUE
➤ Initialized = FALSE
➤ rowIndex is zero or greater than NumRows while isLabel = FALSE
➤ colIndex is zero or greater than NumColumns
2. Else, the original cell content will be deleted, any found ASCII commas
(,) within newValue will be removed and the result will be written to the
cell.

Run (Method)
This method must be called once per scan for handling all asynchronous
operations.

Processing
1. If Busy = FALSE and InitReadWriteCsv() was called prior to this call of
the Run() method:
➤ Parses the content specified by the inputs of InitReadWriteMode()
into the CSV object.
➤ ASCII comma characters as well as newline and carriage returns will
be discarded.
➤ 5 milliseconds per task cycle will be provided to the Run method for
CSV parse operations.
➤ NumRows, NumColumns, and PercentParsed will update
continuously.
➤ Once complete, sets Busy := FALSE.
➤ Once complete, CsvParsed is pulsed for one task cycle.
➤ Once complete, sets Initialized := TRUE.

Date Code 20241023 Programming Reference


192 DescriptiveData
Examples

If the byte vector passed into InitReadWriteCsv() contains any CSV rows
with a number of elements not equal to the number of elements found in
the first row, the offending lines will be disregarded.
2. IF Busy = FALSE and Initialized = TRUE and SerializeCsv() was
called prior to this call of the Run() method:
➤ 5 milliseconds per task cycle will be provided to the Run method for
CSV serialization operations.
➤ CSV object elements will be delimited by ASCII comma characters.
➤ Each CSV object row will be appended with a trailing ASCII newline
and carriage return.
➤ PercentSerialized will update continuously.
➤ Once complete, sets Busy = FALSE.
➤ Once complete, CsvSerialized is pulsed for one task cycle.
➤ Once complete, the pt_SerializedData and NumSerialized Bytes
properties can be used by a FileIO.class_FileWriter.AppendBytes
method.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Parsing JSON Keys From a String


Objective
You want to parse a JSON structure from a STRING(255), and you want to
extract the strings representing keys in the outermost MAP of the structure.

Assumptions
This example assumes that a JSON data structure defined by the user is to be
parsed. This JSON structure is to be defined as follows, with three keys in the
outermost MAP of the structure.

1 {
2 "fid": "SEL-3530-R146-V0-Z000002-D20200224",
3 "licensed features": {
4 "features": [
5 {"hmi": true},
6 {"library": "fileio"}
7 ]
8 },
9 "device name": "SEL-RTAC"
10 }

Programming Reference Date Code 20241023


DescriptiveData 193
Examples

Solution
In order to appropriately extract the keys from this JSON structure, the string
must first be parsed, and because the exact number of key-strings in the JSON
structure is known, the keys can be loaded into an array of STRING(255)s with
that exact number of elements. Note, however, this is not an advisable operation
when the number of keys is either unknown or could change.
Code Snippet 7.1 prg_ExtractJsonKeys
PROGRAM prg_ExtractJsonKeys
VAR
// Define JSON as a string, note that linewrapping is acceptable.
JsonString : STRING(255) := '{"fid":
"SEL-3530-R146-V0-Z000002-D20200224","licensed features": {
"features": [{"hmi": true}, {"library": "fileio"}]},
"device name": "SEL-RTAC"}}';

JsonKeys : ARRAY[0..2] OF STRING(255);


pt_Keys : POINTER TO
DynamicVectors.class_BaseVector(SIZEOF(STRING(255)), 3);
JsonParser : class_JsonManager;
index : INT;
RunOnce : BOOL := TRUE;
END_VAR

IF RunOnce THEN // Test if the JSON structure is empty.


JsonParser.ParseBytes(ADR(JsonString),
INT_TO_UDINT(LEN(JsonString)));
// Capture the pointer reference of the Keys vector.
pt_Keys := JsonParser.pt_KeysVector;
// Extract the keys from the JSON object to the array of strings.
FOR index:=0 TO 2 DO
pt_Keys^.PopTo( ADR(JsonKeys[index]) );
END_FOR
// Disable Parsing
RunOnce := FALSE;
END_IF

Extracting Keyed Values From a Dynamic Vector


Objective
You want to parse a JSON structure from a class_ByteVector, and you want to
extract two of the keyed values from the structure, one of which is nested in the
outermost MAP, the other more deeply nested in the structure.

Assumptions
This example assumes that a JSON data structure to be parsed by the user is
already stored in a globally accessible class_ByteVector. This particular object is
assumed to have a variable name of JsonInVector. This JSON structure is to be
defined as follows, with three keys in the outermost MAP of the structure, and
various nested structures contained within.

1 {
2 "fid": "SEL-3530-R146-V0-Z000002-D20200224",
3 "licensed features": {
4 "features": [
5 {"hmi": true},
6 {"library": "fileio"}
7 ]

Date Code 20241023 Programming Reference


194 DescriptiveData
Examples

8 },
9 "device name": "SEL-RTAC"
10 }

Solution
In order to appropriately extract the desired values from this JSON structure,
two STRING(255) variables must first be provisioned to contain the values
which will be extracted.
Code Snippet 7.2 prg_ExtractKeyedValues
PROGRAM prg_ExtractKeyedValues
VAR
DeviceFID : STRING(255);
HmiEnabled : STRING(255);
JsonParser : class_JsonManager;
RunOnce : BOOL := TRUE;
END_VAR

IF RunOnce THEN // Test if the JSON structure is empty.


JsonParser.ParseBytes(JsonInVector.pt_Data, JsonInVector.Size);
(* Extract the FID from the outermost MAP of the JSON object. *)
JsonParser.Get('fid', Value=>DeviceFID); (* Extracts the VALUE. *)
(* Previous extraction successful, internal iterator reset to
parent. *)
(* Extract the HMI Enabled information from the JSON structure. *)
JsonParser.Get('licensed features'); (* Nest in structure by key. *)
JsonParser.Get('features'); (* Nest in structure by key. *)
JsonParser.Get('0'); (* Nest in structure by index. *)
JsonParser.Get('hmi', Value=>HmiEnabled); (* Extracts the VALUE.*)
(* Disable Parsing and Extraction *)
RunOnce := FALSE;
END_IF

Dumping the Internal JSON Structure to Vector


Objective
After parsing a JSON structure, you would like to inspect the internal references
of the JSON system in an element-wise manner, extracting all elements to a
dynamic vector.

Assumptions
This example assumes that a JSON data structure defined by the user has
already been declared as an array of bytes accessible globally; this array will
be considered to be named g_ByteArray and will contain a number of bytes
recorded by g_ByteArrayLength.

1 {
2 "fid": "SEL-3530-R146-V0-Z000002-D20200224",
3 "licensed features": {
4 "features": [
5 {"hmi": true},
6 {"library": "fileio"}
7 ]
8 },
9 "device name": "SEL-RTAC"
10 }

Programming Reference Date Code 20241023


DescriptiveData 195
Examples

Considering the above listed JSON structure, the assumption will be made that
the maximum size of the internal JSON structure will be 128 struct_JsonElement
elements; as such, the initial number of vector elements will be set to 128 as an
arbitrary size.

Solution
Code Snippet 7.3 prg_DumpJson
PROGRAM prg_DumpJson
VAR
RunOnce : BOOL := TRUE;
JsonElems : DynamicVectors.class_BaseVector(
SIZEOF(struct_JsonElement), 128 );
JsonParser : class_JsonManager;
END_VAR

IF RunOnce THEN // Run only once.


// Parse the Structure
JsonParser.ParseBytes( ADR(g_ByteArray), g_ByteArrayLength);
// Dump internal structure to vector of elements.
JsonParser.DumpStructure( JsonElems );
// Stop Parsing
RunOnce := FALSE;
END_IF

Creating Arbitrary Key-Value Pairs in a JSON Structure, Writing to


JSON File
Objective
You have a collection of Keys and associated Values and would like to load
these into a JSON structure to be written to a JSON-formatted file. The Keys
in this example will be the names of various RTAC system statistic tags and
the Values will be their instantaneous value during the creation of the JSON
structure. The resulting JSON structure will be written to a file on the RTAC's
file system.

Assumptions
This example assumes that a JSON text file with the content such as the
following is the desired end-point. The FileIo library must be inserted into the
project in order to perform the file writer operation.

1 {
2 "SystemTags.FID" : "SEL-3530-R148-V2-Z000015-D20210414",
3 "SystemTags.CPU_Burden_Percent" : "5",
4 "SystemTags.SystemTags.Memory_KBytes_Remaining" : "123456",
5 "SystemTags.SystemTags.Memory_KBytes_Used" : "100000"
6 }

Solution
Code Snippet 7.4 prg_AddKeyValuePairsToJson
PROGRAM prg_AddKeyValuePairsToJson
VAR
PopulateJson : BOOL;
RunOnce : R_TRIG;
JsonParser : class_JsonManager;

Date Code 20241023 Programming Reference


196 DescriptiveData
Examples

FileWriter : fileio.class_FileWriter('/RTAC_statistics.json');
TempString : STRING(255);
TempSELString : class_SELString;
END_VAR

RunOnce( CLK := PopulateJson);


IF RunOnce.Q THEN // Run only once on rising edge.
// Re-Initialize the JSON Structure
JsonParser.Reset();

// Add Key-Value pairs


JsonParser.AddKeyValuePair( Key := 'SystemTags.FID', Value :=
SystemTags.FID.strVal );
JsonParser.AddKeyValuePair( Key := 'SystemTags.CPU_Burden_Percent',
Value := DINT_TO_STRING(SystemTags.CPU_Burden_Percent.stVal) );
JsonParser.AddKeyValuePair( Key :=
'SystemTags.Memory_KBytes_Remaining', Value :=
DINT_TO_STRING(SystemTags.Memory_KBytes_Remaining.stVal) );
TempString :=
DINT_TO_STRING(SystemTags.Memory_KBytes_Used.stVal);
TempSELString.FromString(TempString);
JsonParser.AddKeyValuePairSELString( Key :=
'SystemTags.Memory_KBytes_Used', Value := TempSELString );

// Serialize JSON structure to bytes


JsonParser.SerializeJson();

// Write the output file


FileWriter.AppendBytes( pt_data := JsonParser.pt_SerializedData,
numBytes := JsonParser.NumSerializedBytes);

END_IF
FileWriter.Run();

Composing a New CSV File by Row


Objective
Periodically collect a simple set of RTAC diagnostics and append the samples
as a new row to the top of a CSV object. Then write the content to a file using
FilleIo.class_FileWriter. The resultant file should display the oldest data at the
top of the file.

Solution
Code Snippet 7.5 prg_WriteRowCsv
PROGRAM prg_WriteRowCsv
VAR CONSTANT
c_fileName : STRING := 'TestCsvFile.csv';
c_numColumns : UDINT := 6;
c_columnLabels : ARRAY [1 .. c_numColumns] OF STRING(255) :=
['System Time' ,'CPU Burden' , 'Main Board Temp', 'Memory
Kbytes Used', 'Rail (5V)', 'IRIG OK'];
c_fileLength : UDINT := 60000; //Duration of the file in
milli-seconds
c_samplecollectionPeriod : TIME := T#1S;
END_VAR

VAR
csvManager : class_CsvManager := (LogRuntimeErrors := TRUE);
writer : FileIO.class_FileWriter(fileName := c_fileName);

//Sample collection variables


numRowsPerFile : UDINT;
sampleCollectionTimer : TI;

Programming Reference Date Code 20241023


DescriptiveData 197
Examples

sampleCollectionPeriod : TIME := T#1S;


systemTime : STRING(255);
sampleCpuBurden : STRING(255);
sampleMbTemp : STRING(255);
sampleKbUsed : STRING(255);
sample5vRail : STRING(255);
sampleIrigOK : STRING(255);
tempRow : DynamicVectors.class_BaseVector(elementSize :=
SIZEOF(STRING(255)), numElements := 0);

stage : UINT;
complete : BOOL;

//Status outputs
csvManagerInitialized : BOOL;
csvManagerError : BOOL;
csvManagerErrorDesc : STRING(255);
csvManagerNumRows : UDINT;
csvManagerNumColumns : UDINT;
END_VAR

CASE stage OF
0:
//Initialize the Csv Manager in row-write mode
IF csvManager.InitWriteRowMode(ADR(c_columnLabels), c_numColumns) THEN
//Calculate the number of rows per file
numRowsPerFile :=
c_fileLength/(TIME_TO_UDINT(c_sampleCollectionPeriod));
stage := stage + 1;
END_IF

1:
IF csvManager.NumRows < numRowsPerFile THEN
//collect a set of samples once the sample collection timer asserts
sampleCollectionTimer(IN := TRUE, PT := c_sampleCollectionPeriod);
IF sampleCollectionTimer.Q THEN
//Populate the local sample variables
systemTime :=
DT_TO_STRING(System_Time_Control_POU.System_Time.value.dateTime);
sampleCPUBurden :=
DINT_TO_STRING(SystemTags.CPU_Burden_Percent.stVal);
sampleMbTemp :=
REAL_TO_STRING(SystemTags.Mainboard_Temperature.instMag);
sampleKbUsed := DINT_TO_STRING(SystemTags.Memory_KBytes_Used.stVal);
sample5vRail :=
REAL_TO_STRING(SystemTags.Rail_Voltage_Pos_5V.instMag);
sampleIrigOK :=
BOOL_TO_STRING(SystemTags.POST_Irig_Controller_OK.stVal);

//Recycle the temp row


tempRow.Recycle();
//Push a copy of the samples on to the temp row vector
tempRow.Append(ADR(systemtime),1);
tempRow.Append(ADR(sampleCpuBurden),1);
tempRow.Append(ADR(sampleMbTemp),1);
tempRow.Append(ADR(sampleKbUsed),1);
tempRow.Append(ADR(sample5vRail),1);
tempRow.Append(ADR(sampleIrigOK),1);

//Pass the temp row vector to the csv manager, to be added to the
bottom of the internal CSV object.
//This should provide us with an ordering of samples from oldest at
the top to newest at the bottom.
csvManager.AppendRow(pt_sourceData := tempRow.pt_Data, numElements
:= tempRow.Size, appendToTop := FALSE);
END_IF

//If all rows have been added, move to the next stage
ELSE

Date Code 20241023 Programming Reference


198 DescriptiveData
Examples

stage := stage + 1;
END_IF

2:
//Initiate serialization of the CSV content
IF NOT csvManager.Busy AND_THEN csvManager.SerializeCsv() THEN
stage := stage + 1;
END_IF

3:
//When complete, push the content to the file writer buffer
IF csvManager.CsvSerialized THEN
writer.AppendBytes(pt_data := csvManager.pt_SerializedData,
numBytes := csvManager.NumSerializedBytes);
stage := stage + 1;
END_IF

4:
//When the file writer has completed the file write operation, assert the
'complete' indicator
IF writer.BytesLeft = 0 THEN
complete := TRUE;
END_IF
END_CASE

//Run the classes


csvManager.Run();
writer.Run();

//Update the status outputs (informational - not required for the basic
function of this example)
csvManagerInitialized := csvManager.Initialized;
csvManagerError := csvManager.Error;
csvManagerErrorDesc := csvManager.ErrorDesc;
csvManagerNumRows := csvManager.NumRows;
csvManagerNumColumns := csvManager.NumColumns;

Reading a CSV File and Modifying and Writing Modified Content to a


New File
Objective
Parse CSV content from a file, delete several rows from the top of the CSV
object, and append several new rows of data to the bottom. Once finished,
serialize the result and write to a new file.

Assumptions
This example assumes the following:
1. A CSV formatted file named TestCsvFile.csv exists in the RTAC's top
level of the file system (i.e., the /FILES folder).
2. TestCsvFile.csv contains 6 columns of data, with at least 11 rows of data.
3. The data represented by the six columns within TestCsvFile.csv can be
labeled as follows.
➤ column 1 : Timestamp
➤ column 2 : CPU Burden Percent
➤ column 3 : Main board temperature
➤ column 4 : Kbytes of memory used

Programming Reference Date Code 20241023


DescriptiveData 199
Examples

➤ column 5 : 5V rail measurement


➤ column 6 : IRIG OK status
A file that satisfies these assumptions is generated by the previous example.

Solution
Code Snippet 7.6 prg_ReadWriteCsv
PROGRAM prg_ReadWriteCsv
VAR CONSTANT
c_originalFileName : STRING := 'TestCsvFile.csv';
c_numRowsToDelete : UDINT := 10;
c_samplecollectionPeriod : TIME := T#1S;
END_VAR

VAR
csvManager : class_CsvManager := (LogRuntimeErrors := TRUE);
inputVector : DynamicVectors.class_ByteVector;
tempRow : DynamicVectors.class_BaseVector(elementSize :=
SIZEOF(STRING(255)), numElements := 0);

numRowsPerFile : UDINT;
sampleCollectionTimer : TI;
systemTime : STRING(255);
sampleCpuBurden : STRING(255);
sampleMbTemp : STRING(255);
sampleKbUsed : STRING(255);
sample5vRail : STRING(255);
sampleIrigOK : STRING(255);

reader : fileIO.class_FileReader2;
writer : fileIO.class_FileWriter(FileName :=
'TestCsvFile_Latest.csv');

stage : UINT;
complete : BOOL;

//Status outputs
csvManagerInitialized : BOOL;
csvManagerError : BOOL;
csvManagerErrorDesc : STRING(255);
csvManagerNumRows : UDINT;
csvManagerNumColumns : UDINT;
END_VAR

CASE stage OF
0:
//Read the CSV file into memory
reader.ReadFile(filename := c_originalFileName);
stage := stage + 1;

1:
//When complete, copy data into a vector and pass the vector to the
CSV manager
IF (reader.BytesInBuffer > 0) AND NOT csvManager.Busy THEN
//Copy the content into a vector
reader.AppendToVector(startByte := 0, vector := inputVector);
//Initialize CsvWriter in read/write mode and request a
parse operation
csvManager.InitReadWriteMode(inVector := inputVector);
stage := stage + 1;
END_IF

2:
//When the data has been parsed into the internal CSV object,
delete the oldest 10 rows
IF csvManager.CsvParsed THEN

Date Code 20241023 Programming Reference


200 DescriptiveData
Examples

//First, take note of how many rows the file should have at
the end of this operation
numRowsPerFile := csvManager.NumRows;
IF csvManager.NumRows > c_numRowsToDelete THEN
csvManager.DeleteDataSets(deleteMode :=
enum_MatrixAccessMethod.e_ROW,
numToDelete := c_numRowsToDelete,
deleteFromFront := TRUE);
stage := stage + 1;
END_IF
END_IF

3:
//Add new rows to the end until our total number of rows matches
the expected number
IF csvManager.NumRows < numRowsPerFile THEN

sampleCollectionTimer(IN := TRUE, PT := c_sampleCollectionPeriod);


IF sampleCollectionTimer.Q THEN

//Populate the local sample variables


systemTime :=
DT_TO_STRING(System_Time_Control_POU.System_Time.value.dateTime);
sampleCPUBurden :=
DINT_TO_STRING(SystemTags.CPU_Burden_Percent.stVal);
sampleMbTemp :=
REAL_TO_STRING(SystemTags.Mainboard_Temperature.instMag);
sampleKbUsed := DINT_TO_STRING(SystemTags.Memory_KBytes_Used.stVal);
sample5vRail :=
REAL_TO_STRING(SystemTags.Rail_Voltage_Pos_5V.instMag);
sampleIrigOK :=
BOOL_TO_STRING(SystemTags.POST_Irig_Controller_OK.stVal);

//Recycle tempRow
tempRow.Recycle();

//Push a copy of the samples on to the temp row vector


tempRow.Append(ADR(systemtime),1);
tempRow.Append(ADR(sampleCpuBurden),1);
tempRow.Append(ADR(sampleMbTemp),1);
tempRow.Append(ADR(sampleKbUsed),1);
tempRow.Append(ADR(sample5vRail),1);
tempRow.Append(ADR(sampleIrigOK),1);

//Now append the row to the top of the internal CSV object
csvManager.AppendRow(pt_sourceData := tempRow.pt_Data, numElements
:= tempRow.Size, appendToTop := FALSE);
END_IF
ELSE
stage := stage + 1;
END_IF

4:
//Now serialize the modified CSV object
IF NOT csvManager.Busy AND_THEN csvManager.SerializeCsv() THEN
stage := stage + 1;
END_IF

5:
//Once complete, append the serialized content to the file writer
buffer
IF csvManager.CsvSerialized THEN
writer.AppendBytes(pt_data := csvManager.pt_SerializedData,
numBytes := csvManager.NumSerializedBytes);
stage := stage + 1;
END_IF

6:
//Flag completion of file writing

Programming Reference Date Code 20241023


DescriptiveData 201
Examples

IF writer.BytesLeft = 0 THEN
complete := TRUE;
END_IF

END_CASE

//Run the classes


reader.Run();
csvManager.Run();
writer.Run();

//Update the status outputs (informational - not required for the


basic function of this example)
csvManagerInitialized := csvManager.Initialized;
csvManagerError := csvManager.Error;
csvManagerErrorDesc := csvManager.ErrorDesc;
csvManagerNumRows := csvManager.NumRows;
csvManagerNumColumns := csvManager.NumColumns;

Composing a Mixed-Format CSV File by Column


Objective
Construct a CSV file containing columns of RTAC diagnostic data over time as
well as a header row with single-instance summary data (firmware ID and part
number).

Solution
Code Snippet 7.7 prg_WriteMixedFormatCsv
PROGRAM prg_WriteMixedFormatCsv
VAR CONSTANT
c_fileName : STRING := 'MixedFormatCSV.csv';
c_fileLength : UDINT := 60000; //Duration of the file in
milli-seconds
c_samplecollectionPeriod : TIME := T#1S;
END_VAR

VAR
csvManager : class_CsvManager := (LogRuntimeErrors := TRUE);
writer : FileIO.class_FileWriter(fileName := c_fileName);

//Sample collection variables


numRowsPerfile : UDINT;
sampleCollectionTimer : TI;
sampleCollectionPeriod : TIME := T#1S;

systemFID : STRING(255);
systemPartNo : STRING(255);

systemTime : STRING(255);
sampleCpuBurden : STRING(255);
sampleMbTemp : STRING(255);
systemTimeVector : DynamicVectors.class_BaseVector(elementSize :=
SIZEOF(STRING(255)), numElements := 0);
cpuBurdenVector : DynamicVectors.class_BaseVector(elementSize :=
SIZEOF(STRING(255)), numElements := 0);
temperatureVector : DynamicVectors.class_BaseVector(elementSize :=
SIZEOF(STRING(255)), numElements := 0);

tempRow : DynamicVectors.class_BaseVector(elementSize :=

Date Code 20241023 Programming Reference


202 DescriptiveData
Examples

SIZEOF(STRING(255)), numElements := 0);

stage : UINT;
complete : BOOL;

//Status outputs
csvManagerInitialized : BOOL;
csvManagerError : BOOL;
csvManagerErrorDesc : STRING(255);
csvManagerNumRows : UDINT;
csvManagerNumColumns : UDINT;
END_VAR

CASE stage OF
0:
//Initialize the Csv Manager in column-write mode
IF csvManager.InitWriteColumnMode() THEN
numRowsPerFile :=
c_fileLength/(TIME_TO_UDINT(c_sampleCollectionPeriod));
stage := stage + 1;
END_IF

1:
//Accumulate data for the CSV file
systemPartNo := SystemTags.PARTNO.strVal;
systemFID := SystemTags.FID.strVal;

IF systemTimeVector.Size < numRowsPerFile THEN


//collect a set of samples once the sample collection timer asserts
sampleCollectionTimer(IN := TRUE, PT := c_sampleCollectionPeriod);
IF sampleCollectionTimer.Q THEN
//Populate the local sample variables
systemTime :=
DT_TO_STRING(System_Time_Control_POU.System_Time.value.dateTime);
sampleCPUBurden :=
DINT_TO_STRING(SystemTags.CPU_Burden_Percent.stVal);
sampleMbTemp :=
REAL_TO_STRING(SystemTags.Mainboard_Temperature.instMag);

//Push a copy of those samples into their respective vectors


systemTimeVector.Append(ADR(systemTime),1);
cpuBurdenVector.Append(ADR(sampleCpuBurden),1);
temperatureVector.Append(ADR(sampleMbTemp),1);
END_IF
ELSE
stage := stage + 1;
END_IF

2:
//Append columns
csvManager.AppendColumn(label := 'FID', pt_sourceData :=
ADR(systemFID), numElements := 1, appendToFront := FALSE);
csvManager.AppendColumn(label := 'Part Number', pt_sourceData :=
ADR(systemPartNo), numElements := 1, appendToFront := FALSE);
csvManager.AppendColumn(label := 'System Time', pt_sourceData :=
systemTimeVector.pt_Data, numElements := systemTimeVector.Size,
appendToFront := FALSE);
csvManager.AppendColumn(label := 'CPU Burden', pt_sourceData :=
cpuBurdenVector.pt_Data, numElements := cpuBurdenVector.Size,
appendToFront := FALSE);
csvManager.AppendColumn(label := 'Mainboard Temp', pt_sourceData :=
temperatureVector.pt_Data, numElements :=
temperatureVector.Size, appendToFront := FALSE);

//Advance stage
stage := stage + 1;

3:
//Initiate serialization of the CSV content

Programming Reference Date Code 20241023


DescriptiveData 203
Examples

IF NOT csvManager.Busy AND_THEN csvManager.SerializeCsv() THEN


stage := stage + 1;
END_IF

4:
//When complete, push the content to the file writer buffer
IF csvManager.CsvSerialized THEN
writer.AppendBytes(pt_data := csvManager.pt_SerializedData,
numBytes := csvManager.NumSerializedBytes);
stage := stage + 1;
END_IF

5:
//When the file writer has completed the file write operation,
assert the 'complete' indicator
IF writer.BytesLeft = 0 THEN
complete := TRUE;
END_IF

END_CASE

//Run the classes


csvManager.Run();
writer.Run();

//Update the status outputs (informational - not required for the basic
function of this example)
csvManagerInitialized := csvManager.Initialized;
csvManagerError := csvManager.Error;
csvManagerErrorDesc := csvManager.ErrorDesc;
csvManagerNumRows := csvManager.NumRows;
csvManagerNumColumns := csvManager.NumColumns;

Extracting Data From a Mixed Format CSV File


Objective
Parse a mixed format CSV file, extract the header data, and pass one column of
samples into the logic engine for processing.

Assumptions
This example assumes the following:

1. A CSV formatted file named ColumTestCsvFile.csv exists in the RTAC's


top level of the file system (i.e., the /FILES folder).
2. The data in the file is represented by five columns with the following
labels:
➤ column 1 : FID
➤ column 2 : Part Number
➤ column 3 : System Time
➤ column 4 : CPU Burden Percent
➤ column 5 : Mainboard Temp
3. Where columns 1 and 2 are considered header data and contain only a
single entry in the first row following the label row.

A file that satisfies these assumption is generated by the previous example.

Date Code 20241023 Programming Reference


204 DescriptiveData
Examples

Solution
Code Snippet 7.8 prg_ReadMixedFormatCsv
PROGRAM prg_ReadMixedFormatCsv
VAR CONSTANT
c_originalFileName : STRING := 'MixedFormatCSV.csv';
END_VAR

VAR
csvManager : class_CsvManager := (LogRuntimeErrors := TRUE);
inputVector : DynamicVectors.class_ByteVector;
reader : fileIO.class_FileReader2;

//Logic engine elements to load from the CSV file


FID : STRING(255);
PartNo : STRING(255);
averageCpuBurden : REAL;
firstRowVector : DynamicVectors.class_BaseVector(elementSize :=
SIZEOF(STRING(255)), numElements := 0);
cpuBurdenVector : DynamicVectors.class_BaseVector(elementSize :=
SIZEOF(STRING(255)), numElements := 0);

burdenSample : STRING(255);
burdenSum : REAL;
i : UDINT;
stage : UINT;
complete : BOOL;

//Status outputs
csvManagerInitialized : BOOL;
csvManagerError : BOOL;
csvManagerErrorDesc : STRING(255);
csvManagerNumRows : UDINT;
csvManagerNumColumns : UDINT;
END_VAR

CASE stage OF
0:
//Read the CSV file into memory
reader.ReadFile(filename := c_originalFileName);
stage := stage + 1;

1:
//When complete, copy data into a vector and pass the vector to the
CSV manager
IF (reader.BytesInBuffer > 0) AND NOT csvManager.Busy THEN
//Copy the content into a vector
reader.AppendToVector(startByte := 0, vector := inputVector);
//Initialize CsvWriter in read/write mode and request a
parse operation
csvManager.InitReadWriteMode(inVector := inputVector);
stage := stage + 1;
END_IF

2:
//When the data has been parsed into the internal CSV object, grab
the first row
//so that we can populate the FID and ParNo strings
IF csvManager.CsvParsed AND csvManager.NumRows >= 1 THEN
IF csvManager.ExtractDataSetToVector(extractMode :=
enum_MatrixAccessMethod.e_ROW,
dataSetIndex := 1, targetVector := firstRowVector)
THEN
firstRowVector.GetCopyOfElement(index := 0,
pt_destination := ADR(FID));
firstRowVector.GetCopyOfElement(index := 1,
pt_destination := ADR(PartNo));
stage := stage + 1;

Programming Reference Date Code 20241023


DescriptiveData 205
Examples

END_IF
END_IF

3:
//Now extract the entire column of cpu burden samples, which are
expected to reside in column 4
IF csvManager.NumColumns >= 4 THEN
IF csvManager.ExtractDataSetToVector(extractMode :=
enum_MatrixAccessMethod.e_COLUMN,
dataSetIndex := 4, targetVector := cpuBurdenVector)
THEN
//Sum the cpu burden samples
FOR i := 0 TO cpuBurdenVector.Size - 1 DO
cpuBurdenVector.GetCopyOfElement(index := i,
pt_destination := ADR(burdenSample));
burdenSum := burdenSum +
STRING_TO_REAL(burdenSample);
END_FOR
//Calculate the average burden over the sample set
averageCpuBurden := burdenSum /
UDINT_TO_REAL(cpuBurdenVector.Size);
stage := stage + 1;
END_IF
END_IF

4:
complete := TRUE;
END_CASE

//Run the classes


reader.Run();
csvManager.Run();

//Update the status outputs (informational - not required for the basic
function of this example)
csvManagerInitialized := csvManager.Initialized;
csvManagerError := csvManager.Error;
csvManagerErrorDesc := csvManager.ErrorDesc;
csvManagerNumRows := csvManager.NumRows;
csvManagerNumColumns := csvManager.NumColumns;

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 8

Dictionaries
Introduction
This library implements a collection of data structures for storing key value
pairs. This allows for storing of information indexed by a unique key string.

Determine which data structure to use by looking at the characteristics of the


available structures and choosing the one best suited to the job and environment
at hand.

This library supplies a single implementation. It is a self-balancing binary search


tree as described in class_BinaryTreeDictionary on page 209.

The iterators in this document all refer to being locked out. This refers to the
state of the object being such that a non-NULL(0) value cannot be retrieved
from Next() without a new call to Begin().

In addition to class_BinaryTreeDictionary, this library provides two factory


functions for creating Dictionaries: fun_NewBinaryTreeDictionary() and
fun_DeleteBinaryTreeDictionary(). Calling a factory function creates
a new object and returns a pointer to that object. For example, every call to
fun_NewBinaryTreeDictionary() returns a pointer to a newly created
class_BinaryTreeDictionary object.

Special Considerations
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, Global Variable Lists, or VAR_STAT sections).
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.
// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_Object"
myObject := otherObject;

// This is fine
someVariable := myObject.value;
// As is this
pt_myObject := ADR(myObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.

Date Code 20241023 Programming Reference


208 Dictionaries
Supported Firmware Versions

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.
Versions 3.5.0.1 and earlier can be used on RTAC firmware version R132 and
later.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_p_KeyStringLength UINT 80 The maximum string length for a key.

Functions
fun_NewBinaryTreeDictionary (Function)
This function creates a new class_BinaryTreeDictionary and returns a pointer to
the newly created dictionary. The returned POINTER TO BYTE must be cast to
the correct type before it is used. A dictionary created with this function must be
destroyed with fun_DeleteBinaryTreeDictionary() when it is no longer
needed.

Return Value
IEC 61131 Type Description

POINTER TO BYTE Pointer to the newly created dictionary. This pointer is 0 if the
dictionary could not be created.

Processing
➤ Creates a new dictionary and returns a pointer to the newly created
dictionary.
➤ Returns a null (0) pointer if the dictionary could not be created.

fun_DeleteBinaryTreeDictionary (Function)
This function deletes a dictionary created with
fun_NewBinaryTreeDictionary(). After deletion, any pointers to the
deleted dictionary are no longer valid.

Inputs
Name IEC 61131 Type Description

pt_BinaryTreeObj POINTER TO class_BinaryTreeDictionary The dictionary to delete.

Programming Reference Date Code 20241023


Dictionaries 209
Aliases

Return Value
IEC 61131 Type Description

BOOL TRUE if dictionary is successfully deleted. FALSE if an error occurs.

Aliases
This section lists aliases defined by this library.

DATA_VAL
ALIAS IEC 61131 Type

DATA_VAL __XWORD

Structure Definitions
This section lists structures defined by this library.

struct_KeyValuePair
This structure is a simple storage object for holding key-value pairs.

Name IEC 61131 Type Description

Key STRING(g_p_KeyStringLength) A key associated with a value.

Data DATA_VAL Data storage.

Classes
This section contains the basic definitions, descriptions, and public methods for
the public classes that can be instantiated by the user.

class_BinaryTreeDictionary
This class provides a self-balancing binary search tree that stores key-value
pairs. To allow this class to accommodate various data types, the value stored
is a DATA_VAL, which can store a single 32-bit value or a pointer to a user-
defined data structure.

A binary search tree ensures arrangement of all nodes in order by key such
that, given a node, all keys in the left subtree are less than the key of the given
node and all keys in the right subtree are greater than the key of the given node
(Figure 8.1).

Date Code 20241023 Programming Reference


210 Dictionaries
Classes

Figure 8.1 A Binary Search Tree Holding Integer Values

Binary search trees provide insert, search, and deletion times that are
related to the number of items in the tree(N) by log(N) on average. Under
some circumstances, the organization of the simple tree yields much worse
performance. Consider a tree created by inserting the keys C, K, and then L (as
shown in Figure 8.2).

Figure 8.2 An Unbalanced Binary Search Tree

Note that the nodes are arranged linearly, rather than as one parent with two
children. This causes the behavior of all operations to tend toward a linear
performance curve, as opposed to the log(N) described previously. To prevent
the performance degradation of an unbalanced tree, the binary tree supplied
implements a self-balancing algorithm. If inserting or deleting a node leaves
the tree unbalanced, the self-balancing tree performs rotations and moves of the
nodes in the tree to maintain balance (Figure 8.3).

Figure 8.3 A Balanced Binary Search Tree Node

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Size UDINT R The number of key-value pairs stored


in this tree.

Programming Reference Date Code 20241023


Dictionaries 211
Classes

GetData (Method)
This method provides the data associated with the provided key.

Inputs
Name IEC 61131 Type Description

key STRING(g_p_KeyStringLength) The key for the desired value.

Outputs
Name IEC 61131 Type Description

data DATA_VAL The value stored at this key. This value is only valid if the
return value is TRUE.

Return Value
IEC 61131 Type Description

BOOL TRUE if the key provided is found in the binary tree, FALSE
otherwise.

Processing
Returns the data associated with the provided key.

Insert (Method)
This method inserts a new value into the binary tree.

Inputs
Name IEC 61131 Type Description

key STRING(g_p_KeyStringLength) The key for the desired value.

data DATA_VAL Data to store in the binary tree.

Return Value
IEC 61131 Type Description

BOOL TRUE if the key-value pair was successfully added to the tree.
FALSE otherwise.

Processing
If key already exists in the tree, data replaces the data stored in key. If key does
not already exist in the tree, a new node that stores both key and data is inserted
into the tree. Depending on the state of the tree, the insertion may cause the tree
to rebalance.

Date Code 20241023 Programming Reference


212 Dictionaries
Classes

Delete (Method)
This method removes the key-value pair from the binary tree.

Inputs
Name IEC 61131 Type Description

key STRING(g_p_KeyStringLength) The key for the desired value.

Return Value
IEC 61131 Type Description

BOOL TRUE if the key-value pair was found and deleted.

Processing
This method deletes a key-value pair from the binary search tree. Depending on
the state of the tree after deletion, the tree may be rebalanced to maintain lookup
performance.

Clear (Method)
This method empties the binary tree.

Processing
This method completely empties the binary tree. It frees any memory allocated
to the binary tree. Upon completion of this method, the binary tree object is of
size zero and cannot be iterated over.

Begin (Method)
Use this method in conjunction with Next(), NextValue(), and NextKey().
This method places the internal iterator on the first key-value object.

Processing
After this method completes, the following are true:

➤ The iterator is not locked out.


➤ A subsequent Next() outputs the first key-value object.
➤ For an empty tree, Next() returns FALSE and leaves the iterator locked
out.

Next (Method)
Use this method in conjunction with Begin(). Next() returns the key-value
pair at the present internal iterator position and then increments the iterator.

Programming Reference Date Code 20241023


Dictionaries 213
Classes

Outputs
Name IEC 61131 Type Description

entry struct_KeyValuePair The key-value pair at the present iterator position.


If the end of the iterator has been reached, key is an
empty string and data is zero.

Return Value
IEC 61131 Type Description

BOOL TRUE if the key-value pair was found. FALSE otherwise.

NextKey (Method)
Use this method in conjunction with Begin(). NextKey() returns the key at
the present internal iterator position and then increments the iterator.

Outputs
Name IEC 61131 Type Description

key STRING(g_p_KeyStringLength) The key at the present iterator position. If


the end of the iterator has been reached,
key is an empty string.

Return Value
IEC 61131 Type Description

BOOL TRUE if the key-value pair was found. FALSE otherwise.

NextValue (Method)
Use this method in conjunction with Begin(). NextValue() returns the value
at the present internal iterator position and then increments the iterator.

Outputs
Name IEC 61131 Type Description

value DATA_VAL The value at the present iterator position. If the end of the
iterator has been reached value is zero.

Return Value
IEC 61131 Type Description

BOOL TRUE if the key-value pair was found. FALSE otherwise.

Size (Property)
This method provides the number of nodes within the tree.

Date Code 20241023 Programming Reference


214 Dictionaries
Benchmarks

Return Value

IEC 61131 Type Description

UDINT The number of nodes within the tree.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3530
➢ R134 firmware
➤ SEL-3354
➢ Intel Pentium 1.4 GHz
➢ 1 GB DDR ECC SDRAM
➢ SEL-3532 RTAC Conversion Kit
➢ R132 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V0 firmware

Benchmark Test Descriptions


Each of these tests is run on a tree of 1024 entries. The test attempts to make
an unbalanced tree by inserting values in order, forcing the tree to continually
rebalance itself. Each of the following tests is repeated 100 times, and the total
average of all samples is recorded.

For example, the test in Insert records the average of the 1024 • 100 insertions.

Insert
This records the average time taken to insert 1024 sorted key-value pairs into
the tree. The test is repeated 100 times and the average time taken for a single
execution of Insert() is recorded.

GetData
This test calls GetData() on each of 1024 entries in the tree. The test is
repeated 100 times and the average time taken for a single execution of
GetData() is recorded.

Programming Reference Date Code 20241023


Dictionaries 215
Benchmarks

Delete
This test calls Delete() 1024 times on a populated tree. The test is repeated
100 times and the average time taken for a single execution of Delete() is
recorded.

Clear
This test records the average time required to clear the tree populated with 1024
nodes. The test is repeated 100 times and the average time taken for a single
execution of Clear() is recorded.

Begin
This test records the time required to reset the iterator. Begin() is called 1024
times on a populated tree. The test is repeated 100 times and the average time
taken for a single execution of Begin() is recorded.

Next
This test iterates across a full tree of 1024 nodes. The test is repeated 100 times
and the average time taken for a single execution of Next() is recorded.

NextKey
This test iterates across a full tree of 1024 nodes. The test is repeated 100 times
and the average time taken for a single execution of NextKey() is recorded.

NextValue
This test iterates across a full tree of 1024 nodes. The test is repeated 100 times
and the average time taken for a single execution of NextValue() is recorded.

Benchmark Results
Values less than one microsecond have been rounded up.

Platform (time in µs)


Operation Tested
SEL-3530 SEL-3354 SEL-3555

GetData 14 2 1

Insert 796 59 47

Delete 799 53 42

Clear 779128 51891 42171

Begin 3 1 1

Next 2 1 1

NextKey 4 1 1

NextValue 1 1 1

Date Code 20241023 Programming Reference


216 Dictionaries
Examples

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Ordered Data Retrieval


A user has data that she needs to present in an ordered fashion. She can define
the order she needs through the keys, update the values as needed, and then
present the data, all while maintaining the same order.

Solution
First the user initializes the full tree. Later, she can iterate across the entire
structure to receive those data in key alphabetical order.
Code Snippet 8.1 prg_SortedLookup
PROGRAM prg_SortedLookup
VAR
MyBinaryLookupTree : class_BinaryTreeDictionary;
CurrentData : struct_KeyValuePair;
Initializing : BOOL := TRUE;
Check : BOOL := TRUE;
END_VAR

IF Initializing THEN
// First put the data into the tree as key value pairs
MyBinaryLookupTree.Insert('Boxes', 1250);
MyBinaryLookupTree.Insert('TapeRolls', 200);
MyBinaryLookupTree.Insert('Pallets', 13);
MyBinaryLookupTree.Insert('BubbleWrap', 75);
Initializing := FALSE;
ELSE
MyBinaryLookupTree.Begin();
WHILE Check DO
Check := MyBinaryLookupTree.Next(entry => CurrentData);
IF CurrentData.data <> 0 THEN
; // Do some meaningful work
END_IF
END_WHILE
END_IF

Creating a Quick Lookup Table


Objective
A user has a collection of data he desires to look up quickly based on unique
description strings. He needs to store it now and use parts of it later based on
system state.

Programming Reference Date Code 20241023


Dictionaries 217
Examples

Assumptions
This example assumes that there is a user-specified IEC 61131 data type that
is defined as shown in Code Snippet 8.2 and a function using that particular
structure as shown in Code Snippet 8.3.
Code Snippet 8.2 struct_JobDefinition
TYPE struct_JobDefinition:
STRUCT
JobName : STRING(32);
Duration : UDINT;
Input : REAL;
END_STRUCT
END_TYPE

Code Snippet 8.3 fun_DoWork


FUNCTION fun_DoWork : BOOL
VAR_IN_OUT
pt_currentCommand : POINTER TO struct_JobDefinition;
END_VAR

; // Program the work that should be done here

Solution
First the user initializes the full tree. Later, based on some request, the required
data can be retrieved.
Code Snippet 8.4 prg_BinaryTree
PROGRAM prg_BinaryTree
VAR
CurrentData : BOOL;
JobSelector : INT;
Initializing : BOOL := TRUE;
Working : BOOL := FALSE;

MyBinaryLookupTree : class_BinaryTreeDictionary;
CurrentJob : STRING(g_p_KeyStringLength);
pt_CurrentData : POINTER TO struct_JobDefinition;

Job1Data : struct_JobDefinition :=
(JobName := 'My First Job', Duration := 10, Input := 17.5);
Job2Data : struct_JobDefinition :=
(JobName := 'My Second Job', Duration := 5, Input := 31.75);
Job3Data : struct_JobDefinition :=
(JobName := 'My Third Job', Duration := 30, Input := 3.25);
IdleData : struct_JobDefinition :=
(JobName := 'No Current Job', Duration := 0, Input := 0);
END_VAR

IF Initializing THEN
// First put the data into the tree as key value pairs
MyBinaryLookupTree.Insert('Job1', ADR(Job1Data));
MyBinaryLookupTree.Insert('Job2', ADR(Job2Data));
MyBinaryLookupTree.Insert('Job3', ADR(Job3Data));
MyBinaryLookupTree.Insert('Idle', ADR(IdleData));
Initializing := FALSE;
Working := TRUE;
END_IF

CASE JobSelector OF
1: CurrentJob := 'Job1';
2: CurrentJob := 'Job2';
3: CurrentJob := 'Job3';

Date Code 20241023 Programming Reference


218 Dictionaries
Examples

ELSE
CurrentJob := 'Idle';
END_CASE

IF Working THEN
CurrentData := MyBinaryLookupTree.GetData(CurrentJob, data =>
pt_CurrentData);
fun_DoWork(pt_currentData);
END_IF

Creating class_BinaryTreeDictionary With


fun_NewBinaryTreeDictionary
Objective
A user desires to create class_BinaryTreeDictionary using the factory function
fun_NewBinaryTreeDictionary(). Code Snippet 8.5 shows the creation
of a dictionary with a factory and then some simple manipulation of the created
dictionary. These manipulations include inserting a key value pair, getting a
value based on a key, and deleting the created dictionary.

Solution
First, the user initializes n number of dictionaries. The user then adds key value
pairs to each dictionary and reads them back out. After that, the user deletes all
of the created dictionaries to free the unused allocated memory.
Code Snippet 8.5 prg_BinaryTreeDictionaryFactory
PROGRAM prg_BinaryTreeDictionaryFactory
VAR CONSTANT
c_NumDictionaries : USINT := 10;
END_VAR
VAR
// Flag to only initialize/fill once
initialized : BOOL := FALSE;
// Array to hold between 0 and 10 Binary Tree Dictionaries
dictionaries : ARRAY [0..c_NumDictionaries] OF POINTER TO class_BinaryTreeDictionary;
i : USINT;
(* This variable is here only to demonstrate the ability for the program to create
an arbitrary (n) amount of Binary Tree Dictionaries during program runtime. *)
n : USINT := c_NumDictionaries;
// Variable to hold the value we get out of the dictionary
valueOut : DATA_VAL;
(* Variable to check that our manipulations were successful, this can be used for
error handling *)
success : BOOL;
// Flag to only read/delete once
deleted : BOOL := FALSE;
END_VAR

// Initialize dictionary and fill each with key value pairs


IF NOT initialized THEN
(* Create n amount of dictionaries with the factory. fun_NewBinaryTreeDictionary()
creates the dictionary then returns the pointer which we put in an array *)
FOR i := 0 TO n DO
dictionaries[i] := fun_NewBinaryTreeDictionary();
END_FOR

// Fill each dictionary with the key value pair ('myKey', i)


FOR i := 0 TO n DO
(* This is how user data would be inserted into the dictionary. Success will be
TRUE if the value was inserted successfully. *)
success := dictionaries[i]^.Insert(key := 'myKey', data := i);

Programming Reference Date Code 20241023


Dictionaries 219
Examples

END_FOR
initialized := TRUE;
END_IF

// Read the values of the dictionaries then delete the dictionaries


IF NOT deleted THEN
(* We read out the value associated with the key 'myKey' and assign it to valueOut.
Success will be TRUE if the value was read successfully *)
FOR i := 0 TO n DO
success := dictionaries[i]^.GetData(key := 'myKey', data => valueOut);
END_FOR

(* We delete the binary tree here. This function also handles deleting the internal
memory. It is important to delete unused dictionaries to free the allocated memory.
Success will be true if the dictionary was deleted successfully. *)
FOR i := 0 TO n DO
success := fun_DeleteBinaryTreeDictionary(dictionaries[i]);
(* If we successfully deleted the dictionary, clear the pointer from our array *)
IF success THEN
dictionaries[i] := 0;
END_IF
END_FOR
deleted := TRUE;
END_IF

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 9

DynamicDisturbanceRecorder
Introduction
The DynamicDisturbanceRecorder library contains classes designed to simplify
the collection of data points from within the logic engine of the Real-Time
Automation Controller (RTAC). All data must be added to the logging object by
using the supported bootstrap methods and, as such, the data must originate from
a data structure supported by the logging object selected. The maximum rate at
which points are logged is dependent on the task cycle of the Main Task. See the
®
ACSELERATOR RTAC SEL-5033 Software Instruction Manual for more details
on configuring the task cycle.

Each object within the library stores the collected data into a file format specific
to that object. The four available file formats are listed below:

➤ Time-Aligned CSV: This format is an ASCII comma-separated value


(CSV) file that aligns all point values with a single time value that
represents the data. The order in which the data points are bootstrapped
determines the position of the data points in the log. A null entry in
this format is represented as a blank entry (no characters) delimited by
two commas. Supported data structures and simple types include BCR,
UDINT, CMV, REAL, DPS, INS, DINT, MV, SPS, BOOL, STR, and
STRING(80).
➤ SOE CSV: This format is an ASCII CSV file in which each log
represents the status value of a bootstrapped point and a time value.
The layout of the CSV file is designed for NERC PRC-002-2-compliant
Sequence of Events Recording (SER) data formatting. Additional
information in the log includes the time code (offset from UTC), station
name, and device name. Each detected change generates a log that is
a separate line in the file. Supported data structures and simple types
include: BCR, UDINT, CMV, REAL, DPS, INS, DINT, MV, SPS, BOOL,
STR, and STRING(80).
➤ COMTRADE: Two COMTRADE files are generated that adhere to IEC
60255-24:2013 and IEEE Std. C37.111-2013: a CFG file and a DAT file.
The CFG file is an ASCII file that includes information pertinent to the
interpretation of the DAT file. The maximum size of the CFG file cannot
exceed 10 MB. The DAT file contains the log entries and is a binary
file formatted in FLOAT32. Supported data structures and simple types
include CMV, MV, REAL, INS, DINT, SPS, and BOOL. The order of the
points in the DAT is the order in which the supported data structures are
listed above and then in the order the points are bootstrapped. Within each
data structure type, the order of the points is determined by the order in
which the points are bootstrapped. For the COMTRADE format, missing

Date Code 20241023 Programming Reference


222 DynamicDisturbanceRecorder
Introduction

data will be filled with hex value 0xFF7FFFFF in the binary DAT file for
analog points. For binary points, missing data will be represented as a
zero. See the referenced standards above for more detail pertaining to the
COMTRADE file format.
➤ SOE Harvester CSV: This format is an ASCII CSV file with formatting
that matches that of the standard SOE CSV record type, thus it is also
formatted to be NERC PRC-002-2-compliant. The file name is assigned
with IEEE C37.232-2011 (COMNAME) naming. RTAC SOE contents
are written to file based on a trigger derived from a configured time
reference or a periodic interval. The log file is configurable for a variable
number of triggered writes that append the SOE data, allowing for the
user to create a new log file with each trigger or append new records
to the previous log file a desired number of times. Use this class with
RTAC-generated SOE records (Local records) or apply it with SOE
records created by client devices performing SER collection and logging
from IEDs (Remote records). Presently, remote records can only be
retrieved and logged by SEL and Modbus client devices. These client
devices should be time synchronized and must produce SER records that
are created in the same time zone.

Each object also has specific triggering mechanisms that trigger the collection of
the bootstrapped points. The objects may contain one or more triggering options,
but only one trigger option can be used per instantiated object. When the trigger
condition is met, a log or log entry is created. The maximum log or log entry
size is 10 MB. The log will at minimum contain a time value and the status data
of the bootstrapped points. Additional data may also be present depending on
the file format chosen. These triggers are categorized into the following four
categories:

➤ Timestamp Change: Available file formats for the Timestamp Change


trigger include time-aligned CSV, COMTRADE, and SOE Harvester
CSV. This trigger method monitors the bootstrapped points for changes
in the dateTime_t data structure. A detected change in any dateTime_t
data structure within a bootstrap point creates a log with a time value.
Changes detected in simple data types do not generate logs because the
data do not contain a time stamp. Each log entry contains all the points
for which a time change was detected. By default, the first dateTime_t
data structure for which a time change is detected is the time reference
of the log entry. This is the time that is associated with the log entry. A
user can specify a timeStamp_t data structure that is used as the time
reference to better control when log entries are created and what time
stamp is associated with the log. Any detected change in the dateTime_t
data structure of the time reference generates a log and the time value
associated with that log is derived from the dateTime_t data structure
of the time reference. When used with the SOE Harvester CSV record
format, only an update to the time stamp of the tag specified as the time
reference will cause the buffered records to be written to the CSV file.
Time variance is an optional setting that allows users to set a window
around the time reference. If a time change is detected during the scan,
but the time value of that data point does not fall within the time window
relative to time reference, it will not be included in the log. Points that do

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 223
Introduction

not change or are outside the time window have a null entry. This entry
maintains the columnar position in the log entry as determined by the file
format. The exception is for simple types. All simple types are included in
any log generated.
➤ Data Change: The only file format available for the Data Change trigger
is SOE CSV. This trigger method monitors the bootstrapped points for
changes in the respective status value for the data structure. If a change
in the status is detected, a distinct log entry is created for that point that
reflects the time of change and data status. The time of change is derived
from the dateTime_t data structure of the bootstrapped point. In the case
of simple types, system time is assigned to each change in state.
NOTE
For MV and CMV data structures, the monitored quantity is the
deadbanded attribute. For example, for a CMV, the mag and ang
attributes are monitored.

➤ Periodic: Available file formats for the Periodic trigger include time-
aligned CSV, COMTRADE, and SOE Harvester CSV. This trigger
method periodically samples all points at the specified interval regardless
of whether the time value or the data status value of the bootstrapped
point changed. The time value for the log entry is the system time of the
RTAC at the time of the periodic interval. All data are sampled, so no
null entries are present. This is a snapshot of the points as they are in the
RTAC logic engine at the time of the periodic interval. At the expiration
of each periodic timer interval, buffered SOE Harvester CSV record
contents will be written to the text file.
➤ Trigger: Available file formats include time-aligned CSV and
COMTRADE. Triggered file records cannot exceed 10 MB in total
file size for the SEL-3530, SEL-3530-4, SEL-3505, SEL-3505-3, and
SEL-2241. For all other RTAC hardware variants, triggered file records
cannot exceed 50 MB. This trigger method monitors a Boolean value
specified by the user. When the Boolean trigger condition is evaluated
as TRUE, a file is generated that contains a configurable number of
pre-trigger and post-trigger log entries in addition to a log entry for the
time the trigger asserted. New log entries are created each task cycle;
the amount of time captured by an individual log can be calculated by
multiplying the number of scans (pre-trigger count, post-trigger count,
and the trigger scan) by the task cycle time setting of the RTAC. If a
trigger condition is detected before the minimum configured pre-trigger
cycles are met, a log will be created that contains the available pre-trigger
log entries plus the trigger and the post-trigger log entries. If a trigger
condition is detected before a previous trigger event is processed, it will
be ignored. Like the Periodic type trigger, a value is populated for each
bootstrapped point, regardless of change in data status or time stamp.
Each object is intended to be configured one time at program start. The
initial configuration determines the trigger behavior, file parameters, and file
management for the object. The type of object instantiated determines the format
of the logs in the saved file.
For optimal file system performance, each object must be configured such
that the rate of file generation does not exceed the ability of the file system
to process the created files. For example, if an object is configured to log
data at a fast rate or with a small maximum file size and this configuration
results in a file being created every 10 processing cycles, the file system

Date Code 20241023 Programming Reference


224 DynamicDisturbanceRecorder
Supported Firmware Versions

will not be able to process the files at a rate equal to the creation rate. When
configuring your object, ensure that files are not created more frequently than
every 100 processing cycles. This behavior is tuned by setting the MaxFileSize
appropriately for the application. To verify that the object is creating files at
an unsustainable rate, monitor the ActiveFileName output pin. If this name is
changing faster than once every 100 processing cycles, the object may encounter
issues when trying to create or delete files.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R148 or later.

Versions 3.5.4.0 and later can be used on RTAC firmware version R150 and
later.

Versions 3.5.3.0 and later can be used on RTAC firmware version R148 and
later.

Versions 3.5.2.0 and later can be used on RTAC firmware version R144 and
later.

Versions 3.5.0.0 and later can be used on RTAC firmware version R139 and
later.

To enable DynamicDisturbanceRecorder library support, the device


number of your RTAC must include the feature in its licensed options. You
cannot download projects that include this library to RTACs that do not
support the library. Use the SEL website part number configuration tools
(https://selinc.com/products/) to ensure that a particular part number has
DynamicDisturbanceRecorder support enabled.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_DynamicDisturbanceRecorderObject"
myDynamicDisturbanceRecorderObject :=
otherDynamicDisturbanceRecorderObject;

// This is fine
someVariable := myDynamicDisturbanceRecorderObject.value;
// As is this
pt_myDynamicDisturbanceRecorderObject :=
ADR(myDynamicDisturbanceRecorderObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, Global Variable Lists, or VAR_STAT sections).

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 225
Enumerations

➤ No more than four (4) of the classes contained in the


DynamicDisturbanceRecorder library should be used within a single
RTAC project.
➤ Each instance of DDR must be configured with a unique DirectoryPath
value.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_DataLogger
This enumeration defines the types of data loggers used to record data.

Enumeration Value Description

TIME_CHANGE 0 When a change is detected in the dateTime_t data structure of a bootstrapped point, a log is
generated.

DATA_CHANGE 1 When a change is detected in the respective data status value of a bootstrapped point, a log entry
generated.

PERIODIC 2 On a periodic interval, a log entry is generated.

TRIGGER_EVENT 3 When a trigger condition is detected, a log is generated.

Special Considerations for COMTRADE Logging


A Dynamic Disturbance Recorder instance configured for COMTRADE
record generation in a continuous recording application does bear some special
considerations for the configuration.

➤ As discussed in the Introduction, ensure that the MaxFileSize


parameter is tuned to prevent frequent and rapid generation of resultant
COMTRADE zip files. Rapidly generating COMTRADE zip files can
exceed the capabilities of the RTAC file system, possibly resulting in
COMTRADE data loss.
➤ If using tags from PrCtPt modules in the logged data, assign the EN
Enable Data Recording input pin equal to ECAT_POU.Client_State
= 5. This ensures that logging does not enable until the EtherCAT IO
network is up and running with all modules reporting data and avoids
erroneous invalid tag data being logged to the COMTRADE record on
RTAC project startup.
➤ Recorders creating COMTRADE records and sampling data at greater
than 60 samples per second (logging every 16.667 ms) can encounter
gaps in data between subsequent COMTRADE during times of system
burden.
➤ Phasor measurement tags (ending in _PM) from IEEE C37.118 clients
are not time-aligned with phasor measurement tags from PrCtPt Axion
modules before entering the logic engine. In order to maintain original
time stamp accuracy, segregate C37.118 and PrCtPt Axion phasor
measurement tags into dedicated instances of DDR.

Date Code 20241023 Programming Reference


226 DynamicDisturbanceRecorder
Classes

➤ When logging IEEE C37.118 client or PrCtPt module phasor


measurement tags and there are non-phasor tags also included in the
recorder configuration, if there is a desire to maintain the original time
stamp of the phasor tags then ensure RefTime is configured using the
_PM.t time-stamp component of one of those phasor tags to enforce the
use of those time stamps.
➤ If the channel configuration is changed (channels added or removed) on
an existing continuous recording COMTRADE instance, ensure that the
contents of the TEMP directory associated with that recorder are deleted
before the new settings are activated. If not, a logic engine restart may
result from the unexpected channel configuration.

Classes
class_TimeAlignedCsv (Function Block)
This class monitors and logs bootstrapped data points. Each time the Run
method is called, it scans the bootstrapped points for the trigger criteria
described by the DataLogType input setting. If a change is detected based on
that criteria, the information is formatted and written to a time-aligned CSV file.

The log is then written into the directory specified by DirectoryPath. A new
log will start after MaxFileSize is reached. The number of files stored in the
directory is dependent on the following two settings: MaxFolderSize and
MaxNumDays. So long as the cumulative size of the stored logs does not
exceed MaxFolderSize, the file system will store logs for MaxNumDays. If
the cumulative number of logs exceeds MaxFolderSize, the directory manager
will delete the oldest files until the number of logs is less than MaxFolderSize.
File names will begin with the start time of the log and will be appended with
FilePostFix. For the trigger condition mechanism, an additional instance number
will be appended to ensure uniqueness. This number will increment each time
a log is generated and will reset with a settings change or when the maximum
number of 65535 is reached.

For triggered records (DataLogType = TRIGGER_EVENT), the task cycle


time time consumed by servicing a full pre-trigger buffer will increase by
approximately 0.5 to 1 millisecond per 10 MB of the resultant file.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable data recording.

RecordTimeInUtc BOOL Convert log time into UTC time. Information in the timestamp_t of the log source is
used for this calculation.

RefTime timestamp_t Provides a time-stamp reference for log creation; ignored unless the DataLogType
input is configured for TIME_CHANGE triggers.

TimeVariance UDINT Time window in milliseconds applied to the time reference. If a change in the
dateTime_t structure for a bootstrapped point is detected and within the time window,
it is included in the log entry. Set to 0 to disable. Ignored unless the DataLogType
input is configured for TIME_CHANGE triggers.

DataLogType enum_DataLogger Specifies what trigger mechanism is used to create logs.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 227
Classes

Name IEC 61131 Type Description

DirectoryPath STRING(127) The full directory path at which files generated by this function block can be found.

FilePostfix STRING(16) The string appended after the time stamp in the generated file name. When configured
using TRIGGER_EVENT as the DataLogType, the FilePostfix will be limited to 8
characters. Any additional characters will be truncated.

MaxFolderSize LINT The maximum size, in bytes, for the specified directory path.

MaxFileSize DINT The maximum file size, in bytes, at which a new file will be created for subsequent
logging operations. Defaults to 10 MB for TRIGGER_EVENT records.

MaxNumDays DINT The maximum number of days for which log files are allowed to persist in a specified
directory path.

LoggingInterval TIME Time in milliseconds for cyclic recording; ignored unless the DataLogType input is
configured for PERIODIC triggers.

TriggerSignal BOOL Monitored variable that initiates a record, only for DataLogType TRIGGER_EVENT.

PreTriggerCycles UDINT Number of processing cycles prior to the trigger event for which data will be recorded;
ignored unless DataLogType TRIGGER_EVENT trigger. Minimum of 1 pre-trigger
cycle is required. If configured for less than the minimum, the setting will default to 1.

PostTriggerCycles UDINT Number of processing cycles after the trigger event for which data will be recorded;
ignored unless DataLogType TRIGGER_EVENT trigger. Minimum of 1 post-trigger
cycle is required. If configured for less than the minimum, the setting will default to 1.

StartNewFilePerDay BOOL If TRUE, a new log file will start at the beginning of a new day.

Outputs
Name IEC 61131 Type Description

ENO BOOL The logging block is enabled.

ActiveFileName STRING(255) Name of the file that logs are being written to.

ConsumedDirectorySize ULINT Size of all files in the monitored directory.

MonitoredPoints UDINT Total number of monitored points.

Error BOOL Something has prevented this block from successfully writing data to file. This can
indicate an out of space condition or that too many data points are being monitored for
the CPU of the RTAC to handle.

ErrorDesc STRING(255) Message describing the source of the Error flag.

bootstrap_MonitorBCR (Method)
A configuration method for adding BCR points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the BCR point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Date Code 20241023 Programming Reference


228 DynamicDisturbanceRecorder
Classes

Inputs/Outputs
Name IEC 61131 Type Description

data BCR The BCR point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the BCR point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorUDINT (Method)
A configuration method for adding UDINT points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the UDINT point
to be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data UDINT The UDINT point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the UDINT point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 229
Classes

bootstrap_MonitorCMV (Method)
A configuration method for adding CMV points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the CMV point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data CMV The CMV point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the CMV point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorREAL (Method)
A configuration method for adding REAL points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the REAL point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data REAL The REAL point to be included in the log files.

Date Code 20241023 Programming Reference


230 DynamicDisturbanceRecorder
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the REAL point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorDPS (Method)
A configuration method for adding DPS points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the DPS point to be
monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data DPS The DPS point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the DPS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorINS (Method)
A configuration method for adding INS points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the INS point to be
monitored if called before calling the function block itself.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 231
Classes

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data INS The INS point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the INS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorDINT (Method)
A configuration method for adding DINT points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the DINT point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data DINT The DINT point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the DINT point was added for logging.

Date Code 20241023 Programming Reference


232 DynamicDisturbanceRecorder
Classes

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorMV (Method)
A configuration method for adding MV points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the MV point to be
monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data MV The MV point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the MV point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return FALSE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorSPS (Method)
A configuration method for adding SPS points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the SPS point to be
monitored if called before calling the function block itself.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 233
Classes

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data SPS The SPS point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the SPS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorBOOL (Method)
A configuration method for adding BOOL points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the BOOL point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data BOOL The BOOL point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the BOOL point was added for logging.

Date Code 20241023 Programming Reference


234 DynamicDisturbanceRecorder
Classes

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorSTR (Method)
A configuration method for adding STR points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the STR point to be
monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data STR The STR point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the STR point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorSTRING (Method)
A configuration method for adding STRING points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the STRING point
to be monitored if called before calling the function block itself.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 235
Classes

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data STRING The STRING point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the STRING point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

Run (Method)
This method must be called every scan to ensure proper functionality, which
includes scanning data points and writing files.

Processing
➤ The first time the method is called, it blocks all future bootstrap methods
from adding new points.
➤ For DataLogType TIME_CHANGE, points are considered changed if the
dateTime_t data structure has changed since the previous scan and the
change falls within the window, relative to the time reference, specified
by TimeVariance. Changes in simple type values do not trigger a log but
are included in every log.
➤ For DataLogType PERIODIC, all points are considered changed if
LoggingInterval is reached.
➤ For DataLogType TRIGGER_EVENT, all points are considered changed
when logging data points during the pre- and post-trigger cycles.
➤ Scans all data points. If they have changed, the data are formatted for
logging.

Date Code 20241023 Programming Reference


236 DynamicDisturbanceRecorder
Classes

➤ If a log entry is generated, the class writes one line containing a time
value with millisecond precision and one comma-separated column for
each data point monitored. If the value of the data point changed since
the last scan, the new value is written to the log entry; otherwise, a null
entry is created. This ensures that the columnar position of all data points
is maintained.
➤ Manage the total size of the directory path folder to ensure that the
cumulative size of the logs does not exceed MaxDirectorySize.
➤ So long as MaxDirectorySize is not exceeded, the logs will be maintained
for MaxNumDays.
➤ If MaxDirectorySize is exceeded before MaxNumDays is reached, the
oldest file is deleted. This repeats until the cumulative directory size is
less than MaxDirectorySize.
➤ Starts a new file if the active log file exceeds the maximum file size, if the
project settings are changed, or if trigger condition is detected.
➤ The EN pin must be TRUE to scan and write new log entries.
➤ When EN is FALSE, no data point changes are detected.
➤ A rising edge on EN clears all pending logs so that only changes since the
EN toggling to TRUE will be written to future logs.
➤ Deleting metadata in the .RetainedState and .unsent files in the specified
directory may result in inconsistent logging behavior.

class_SoeCsv
This class monitors and logs bootstrapped data points. Each time the Run
method is called, it scans the bootstrapped points for the trigger criteria
described by the DataLogType input setting. The only supported trigger
mechanism for this class is DATA_CHANGE. If a change is detected based
on that criteria, the information is formatted and written to a comma-separated
value (CSV) file. The log is then written into the directory specified by
DirectoryPath. A new log starts after the MaxFileSize is reached or at the
beginning of a new day if StartNewLogPerDay is set to TRUE.

The number of files stored in the directory is dependent on two settings:


MaxFolderSize and MaxNumDays. So long as the cumulative size of the
stored logs does not exceed MaxFolderSize, the file system stores logs for
MaxNumDays. If the cumulative number of logs exceeds MaxFolderSize, the
directory manager deletes the oldest files until the cumulative log directory size
is less than MaxFolderSize. File names begin with the start time of the log and
are appended with FilePostFix.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable data recording.

RecordTimeInUtc BOOL Convert log time into UTC time. Information in the timestamp_t of the log source is used
for this calculation.

DirectoryPath STRING(127) The full directory path at which files generated by this function block can be found.

FilePostfix STRING(16) The string that is appended after the time stamp from the file name.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 237
Classes

Name IEC 61131 Type Description

MaxFolderSize ULINT The maximum size, in bytes, for the specified directory path.

MaxFileSize UDINT The maximum file size, in bytes, at which a new file will be created for subsequent
logging operations.

MaxNumDays UDINT The maximum number of days that log files are allowed to persist in a specified directory
path.

StartNewFilePerDay BOOL If TRUE, a new log file will start at the beginning of a new day.

Outputs
Name IEC 61131 Type Description

ENO BOOL The logging block is enabled.

ActiveFileName STRING(255) Name of the file that logs are being written to.

ConsumedDirectorySize ULINT Size of all files in the monitored directory.

MonitoredPoints UDINT Total number of monitored points.

Error BOOL Something has prevented this block from successfully writing data to file. This can
indicate an out of space condition or that too many data points are being monitored for
the CPU of the RTAC to handle.

ErrorDesc STRING(255) Message describing the source of the Error flag.

bootstrap_MonitorBCR (Method)
A configuration method for adding BCR points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the BCR point to
be monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data BCR The BCR point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the BCR point was added for logging.

Date Code 20241023 Programming Reference


238 DynamicDisturbanceRecorder
Classes

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorUDINT (Method)
A configuration method for adding UDINT points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the UDINT point
to be monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data UDINT The UDINT point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the UDINT point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorCMV (Method)
A configuration method for adding CMV points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the CMV point to
be monitored if called before calling the function block itself.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 239
Classes

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data CMV The CMV point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the CMV point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorREAL (Method)
A configuration method for adding REAL points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the REAL point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data REAL The REAL point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the REAL point was added for logging.

Date Code 20241023 Programming Reference


240 DynamicDisturbanceRecorder
Classes

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorDPS (Method)
A configuration method for adding DPS points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the DPS point to be
monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data DPS The DPS point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the DPS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorINS (Method)
A configuration method for adding INS points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the INS point to be
monitored if called before calling the function block itself.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 241
Classes

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data INS The INS point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the INS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorDINT (Method)
A configuration method for adding DINT points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the DINT point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data DINT The DINT point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the DINT point was added for logging.

Date Code 20241023 Programming Reference


242 DynamicDisturbanceRecorder
Classes

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorMV (Method)
A configuration method for adding MV points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the MV point to be
monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data MV The MV point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the MV point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorSPS (Method)
A configuration method for adding SPS points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the SPS point to be
monitored if called before calling the function block itself.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 243
Classes

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data SPS The SPS point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the SPS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorBOOL (Method)
A configuration method for adding BOOL points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the BOOL point to
be monitored if called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data BOOL The BOOL point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the BOOL point was added for logging.

Date Code 20241023 Programming Reference


244 DynamicDisturbanceRecorder
Classes

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorSTR (Method)
A configuration method for adding STR points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the STR point to be
monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs

Name IEC 61131 Type Description

data STR The STR point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the STR point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorSTRING (Method)
A configuration method for adding STRING points to be monitored by a time-
aligned CSV or SOE CSV object. This method will only add the STRING point
to be monitored if called before calling the function block itself.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 245
Classes

Inputs
Name IEC 61131 Type Description

channel STRING(62) Label describing the data source.

station STRING(62) The description to use when describing the grouping


of the data.

Inputs/Outputs
Name IEC 61131 Type Description

data STRING The STRING point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the STRING point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

Run (Method)
This method must be called every scan to ensure proper functionality, which
includes scanning data points and writing files.

Processing
➤ The first time the method is called, it blocks all future bootstrap methods
from adding new points.
➤ For DataLogType DATA_CHANGE, points are considered changed if the
respective data status value has changed since the previous scan.
➤ Scan all data points. If they have changed, then prepare the points for
logging.
➤ Write one line containing a time value with millisecond precision, time
code, station name, device name, and the data status value.
➤ Manage the total size of the directory path folder and the number of files
in the respective data path based on MaxDirectorySize.
➤ Start a new file if the active log file exceeds the maximum file size, if
NewFilePerDay is TRUE at the start of a new day, or if project settings
change.
➤ The logs will be maintained for MaxNumDays if the MaxDirectorySize is
not exceeded.
➤ If MaxDirectorySize is exceeded before MaxNumDays of logs is reached,
the oldest file is deleted. This repeats until the cumulative directory size is
less than MaxDirectorySize.

Date Code 20241023 Programming Reference


246 DynamicDisturbanceRecorder
Classes

➤ Start a new file if the active log file exceeds the maximum file size,
if the project settings are changed, or at the beginning of a new day if
StartNewFilePerDay is TRUE.
➤ The EN pin must be TRUE to scan and write new log entries.
➤ When EN is FALSE, no data point changes are detected.
➤ A rising edge on EN clears all pending logs so that only changes since the
EN toggling to TRUE will be written to future logs.
➤ Deleting metadata in the .RetainedState and .unsent files in the specified
directory may result in inconsistent logging behavior.

class_ComtradeFloat32 (Function Block)


This class monitors and logs bootstrapped data points. Each time the Run
method is called, it scans the bootstrapped points for the trigger criteria
described by the DataLogType input setting. If a change is detected based on
that criteria, the information is formatted and written to a COMTRADE record,
which is composed of a CFG and DAT file. The log is then written into the
directory specified by DirectoryPath. A subfolder is created that has the date and
time of the record to the millisecond, as well as FilePostFix. The date, time, and
postfix are separated by the "," character. A new log will start after MaxFileSize
is reached.
The number of files stored in the directory is dependent on two settings:
MaxFolderSize and MaxNumDays. So long as the cumulative size of the
stored logs does not exceed MaxFolderSize, the file system will store logs
for MaxNumDays. If the cumulative number of logs exceeds MaxFolderSize,
the directory manager will delete one day of records until the cumulative log
directory size is less than MaxFolderSize. File names will be in the same format
as the subfolder with either a CFG or DAT extension appended. Two additional
folders may be present in the directory. Do not delete or alter the contents of
these folders. Doing so may cause errors in the logging object.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable data recording.

RecordTimeInUtc BOOL Convert log time into UTC time. Information in the timestamp_t of the log source
is used for this calculation.

RefTime timestamp_t Provides a time stamp reference for log creation, ignored unless the DataLogType
input is configured for TIME_CHANGE triggers.

TimeVariance UDINT Time window in milliseconds applied to the time reference. If a change in the
dateTime_t structure for a bootstrapped point is detected and within the time
window it is included in the log entry. Set to 0 to disable. Ignored unless the
DataLogType input is configured for TIME_CHANGE triggers.

DataLogType enum_DataLogger Specifies which trigger mechanism is used to create logs.

DirectoryPath STRING(50) The full directory path at which files generated by this function block can be found.

FilePostfix STRING(50) The string appended after the time stamp from the file name.

MaxFolderSize ULINT The maximum size, in bytes, for the specified directory path.

MaxFileSize UDINT The maximum file size, in bytes, at which a new file will be created for subsequent
logging operations. Defaults to 10 MB for TRIGGER_EVENT records.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 247
Classes

Name IEC 61131 Type Description

MaxNumDays UDINT The maximum number of days log files are allowed to persist in a specified
directory path.

LoggingInterval TIME Time in milliseconds for cyclic recording; ignored unless the DataLogType input is
configured for PERIODIC triggers.

TriggerSignal BOOL Monitored variable that initiates a record; only for DataLogType
TRIGGER_EVENT.

PreTriggerCycles UDINT Number of processing cycles prior to the trigger event for which data will be
recorded; ignored unless DataLogType TRIGGER_EVENT trigger. Minimum 1
pre-trigger cycle is required. If configured for less than the minimum, the setting
will default to 1.

PostTriggerCycles UDINT Number of processing cycles post-trigger event for which data will be recorded;
ignored unless DataLogType TRIGGER_EVENT trigger. Minimum 1 post-trigger
cycle is required. If configured for less than the minimum, the setting will default to
1.

SystemFrequency DINT Primary frequency of the analog signal measured by the COMTRADE
oscillography.

SortNanoseconds UDINT Maximum allowed number of nanoseconds that the time stamp reordering
mechanism is allowed to run each scan. Default is 1,000,000 (1 millisecond).

Outputs
Name IEC 61131 Type Description

ENO BOOL The logging block is enabled.

ActiveFileName STRING(255) Name of the file that logs are being written to.

ConsumedDirectorySize ULINT Size of all files in the monitored directory.

AnalogPoints UDINT Total number of analog points.

DigitalPoints UDINT Total number of digital points.

Error BOOL Something has prevented this block from successfully writing data to file. This can
indicate an out of space condition or that too many data points are being monitored
for the CPU of the RTAC to handle.

ErrorDesc STRING(255) Message describing the source of the Error flag.

bootstrap_MonitorCMV (Method)
A configuration method for adding CMV points to be monitored by a
COMTRADE object. This method will only add the CMV point to be monitored
if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) The description to use when describing the data source.

station STRING(62) The description to use when describing the grouping of the data.

ph STRING(1) The description to use when describing the phase identifier for the data.

Date Code 20241023 Programming Reference


248 DynamicDisturbanceRecorder
Classes

Name IEC 61131 Type Description

component STRING(16) The description to use when describing the physical component that is represented
by the data.

unit STRING(16) The description to use when describing the engineering units to associate with the
data.

Inputs/Outputs

Name IEC 61131 Type Description

data CMV The CMV point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the CMV point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorREAL (Method)
A configuration method for adding REAL points to be monitored by a
COMTRADE object. This method will only add the REAL point to be
monitored if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) The description to use when describing the data source.

station STRING(62) The description to use when describing the grouping of the data.

ph STRING(2) The description to use when describing the phase identifier for the data.

component STRING(16) The description to use when describing the physical component that is represented
by the data.

unit STRING(16) The description to use when describing the engineering units to associate with the
data.

Inputs/Outputs

Name IEC 61131 Type Description

data REAL The REAL point to be included in the log files.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 249
Classes

Return Value

IEC 61131 Type Description

BOOL TRUE if the REAL point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorMV (Method)
A configuration method for adding MV points to be monitored by a
COMTRADE object. This method will only add the MV point to be monitored
if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) The description to use when describing the data source.

station STRING(62) The description to use when describing the grouping of the data.

ph STRING(2) The description to use when describing the phase identifier for the data.

component STRING(16) The description to use when describing the physical component that is represented
by the data.

unit STRING(16) The description to use when describing the engineering units to associate with the
data.

Inputs/Outputs

Name IEC 61131 Type Description

data MV The MV point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the MV point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

Date Code 20241023 Programming Reference


250 DynamicDisturbanceRecorder
Classes

bootstrap_MonitorINS (Method)
A configuration method for adding INS points to be monitored by a
COMTRADE object. This method will only add the INS point to be monitored
if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) The description to use when describing the data source.

station STRING(62) The description to use when describing the grouping of the data.

ph STRING(2) The description to use when describing the phase identifier for the data.

component STRING(16) The description to use when describing the physical component that is represented
by the data.

unit STRING(16) The description to use when describing the engineering units to associate with the
data.

Inputs/Outputs

Name IEC 61131 Type Description

data INS The INS point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the INS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorDINT (Method)
A configuration method for adding DINT points to be monitored by a
COMTRADE object. This method will only add the DINT point to be monitored
if called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) The description to use when describing the data source.

station STRING(62) The description to use when describing the grouping of the data.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 251
Classes

Name IEC 61131 Type Description

ph STRING(2) The description to use when describing the phase identifier for the data.

component STRING(16) The description to use when describing the physical component that is represented
by the data.

unit STRING(16) The description to use when describing the engineering units to associate with the
data.

Inputs/Outputs
Name IEC 61131 Type Description

data DINT The DINT point to be included in the log files.

Return Value
IEC 61131 Type Description

BOOL TRUE if the DINT point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorSPS (Method)
A configuration method for adding SPS points to be monitored by a
COMTRADE object. This method will only add the SPS to be monitored if
called before calling the function block itself.

Inputs
Name IEC 61131 Type Description

channel STRING(62) The description to use when describing the data source.

station STRING(62) The description to use when describing the grouping of the data.

ph STRING(1) The description to use when describing this data in files generated by the data
recorder class.

component STRING(16) The description to use when describing this data in files generated by the data
recorder class.

defaultState BOOL The default state.

Inputs/Outputs
Name IEC 61131 Type Description

data SPS The SPS point to be included in the log files.

Date Code 20241023 Programming Reference


252 DynamicDisturbanceRecorder
Classes

Return Value

IEC 61131 Type Description

BOOL TRUE if the SPS point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

bootstrap_MonitorBOOL (Method)
A configuration method for adding BOOL points to be monitored by a
COMTRADE object. This method will only add the BOOL to be monitored if
called before calling the function block itself.

Inputs

Name IEC 61131 Type Description

channel STRING(62) The description to use when describing the data source.

station STRING(62) The description to use when describing the grouping of the data.

ph STRING(1) The description to use when describing this data in files generated by the data
recorder class.

component STRING(16) The description to use when describing this data in files generated by the data
recorder class.

defaultState BOOL The default state.

Inputs/Outputs

Name IEC 61131 Type Description

data BOOL The BOOL point to be included in the log files.

Return Value

IEC 61131 Type Description

BOOL TRUE if the BOOL point was added for logging.

Processing
➤ Store a reference to the point and the associated metadata for future
logging and comparison.
➤ Return TRUE if the point will be monitored moving forward, FALSE
otherwise.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 253
Classes

Run (Method)
This method must be called every scan to ensure proper functionality, which
includes scanning data points and writing files.

Processing
➤ The first time the method is called, it blocks all future bootstrap methods
from adding new points.
➤ For DataLogType TIME_CHANGE, points are considered changed if the
dateTime_t data structure has changed since the previous scan and the
change falls within the window, relative to the time reference, specified
by TimeVariance. Changes in simple type values do not trigger a log but
are included in every log.
➤ For DataLogType PERIODIC, all points are considered changed if
LoggingInterval is reached.
➤ For DataLogType TRIGGER_EVENT, all points are considered changed
when logging points during the pre- and post-trigger cycles.
➤ Scan all data points. If they have changed, prepare them for logging.
➤ Write log entry containing the sample number and a time offset from the
beginning of the log with millisecond precision and the bootstrapped data.
Log entries are stored in the binary DAT file in the FLOAT32 format.
➤ The log entries and the CFG file information are written to a temporary
file until the log is completed. Once completed, the log is stored as a CFG
and DAT file in a subdirectory that has the same naming convention as
that of the CFG and DAT file.
➤ Manage the total size of the directory path folder and the number of files
in the respective data path based on the MaxDirectorySize.
➤ Start a new file if the active log file exceeds the maximum file size or if
project settings change or if trigger condition is detected.
➤ The logs will be maintained for the MaxNumDays if the
MaxDirectorySize is not exceeded.
➤ If MaxDirectorySize is exceeded before MaxNumDays of logs is reached,
files are deleted in day increments until the cumulative size of the logs is
less than MaxDirectorySize.
➤ The EN pin must be TRUE to scan and write new log entries.
➤ When EN is FALSE, no data point changes are detected.
➤ A rising edge on EN clears all pending logs so that only changes since the
EN toggling to true will be written to future logs.
➤ Deleting metadata in the TEMP and SHADOW directories in the
specified directory may result in inconsistent logging behavior.

class_SoeHarvesterCsv
This class monitors the RTAC SOE and logs entries from any bootstrapped
local or remote origin sources in a CSV file. When the Run method is called
each task cycle, the class will query the RTAC's SOE logger for new entries
upon a detection of a rising edge on the QueryRecords input and queue any that
are encountered. To ensure detection of new SOEs, ensure the QueryRecords
input is tied to a BOOL quantity that automatically pulses periodically such
as the output of an interval timer. Once new records are detected, the RTAC

Date Code 20241023 Programming Reference


254 DynamicDisturbanceRecorder
Classes

will continuously query for new records until there are none remaining; the
QueryingRecords output will be asserted during this time. Also, each time the
Run method is called, it checks for presence of the trigger criteria described
by the DataLogType input setting. The supported trigger mechanisms for this
class are TIME_CHANGE and PERIODIC. If a trigger is detected based on the
configured criteria, the queued information is formatted and written to a comma-
separated value (CSV) file, into the directory specified by DirectoryPath. A
new log file starts after TriggersPerFile is reached and a subsequent trigger is
encountered.

This class operates in one of two modes; detection of local (RTAC-generated)


SOE records or detection of remote (IED-generated) records. This mode
is selected by the first bootstrap call that is made to the class, either
bootstrap_RemoteSource or bootstrap_LocalSource. When in remote mode,
only SOE records in the Remote category and with an Origin field matching
a bootstrapped remote device name are formatted and queued to be written to
the log file. When in local mode, any local SOE records (Origin field equal to
SEL_RTAC) are logged to the CSV file.

The number of files stored in the directory is dependent on two settings:


MaxFolderSize and MaxNumDays. So long as the cumulative size of the
stored logs does not exceed MaxFolderSize, the file system stores logs for
MaxNumDays. If the cumulative number of logs exceeds MaxFolderSize, the
directory manager deletes the oldest files until the cumulative log directory size
is less than MaxFolderSize. File names are formatted for IEEE C37.232-2011
(COMNAME) and begin with the start time of the log and are appended with
FilePostFix. The total length of the combined DirectoryPath and FilePostFix
strings cannot exceed 230 characters.

A file named .StateTracker is maintained in the same directory as the CSV text
files. It contains the record ID for the most recent SOE content written to the
CSV text file and is used at startup to ensure the class does not retrieve and write
duplicate SOE entries into the CSV text files. If the record ID contained in the
.StateTracker file is ever cleared from the RTAC SOE database (via a manual
Delete Logs operation from the Web Interface, or the record aging out of the
database due to insertion of 30000 newer records) then the .StateTracker file is
automatically removed and the class enters an internal mode where it scans for
new records based on the bootstrapped criteria.

This class requires a minimum firmware RTAC version of R148 to operate.


Firmware versions less than R149 may produce CSV records with an additional
1 hour offset if the class is configured with RecordTimeInUtc equal to FALSE
while daylight-saving time is not active.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable data recording.

RecordTimeInUtc BOOL Convert file name time code and log entry time into UTC time. UTC_Offset information
contained in the time stamp of the RTAC SOE record is used for this calculation.

RefTime timestamp_t Provides a time stamp reference for log creation; input is ignored unless the
DataLogType input is configured for TIME_CHANGE triggers.

DataLogType enum_DataLogger Specifies what trigger mechanism is used to create logs. TIME_CHANGE and
PERIODIC are supported.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 255
Classes

Name IEC 61131 Type Description

DirectoryPath STRING(127) The full directory path at which files generated by this function block can be found.

FilePostfix STRING(127) The string appended after the time stamp from the file name.

MaxFolderSize ULINT The maximum size, in bytes, for the specified directory path.

MaxNumDays UDINT The maximum number of days log files are allowed to persist in a specified directory
path.

LoggingInterval TIME Time in milliseconds for cyclic recording; ignored unless the DataLogType input is
configured for PERIODIC triggers.

TriggersPerFile UDINT The maximum number of triggered writes to append to a single output CSV file before
creating a new one at the next trigger.

QueryRecords BOOL Assert to query the database for SOE records.

Outputs
Name IEC 61131 Type Description

ENO BOOL The logging block is enabled.

ActiveFileName STRING(255) Name of the file that logs are being written to.

ConsumedDirectorySize ULINT Size of all files in the monitored directory.

Error BOOL Something has prevented this block from successfully writing data to file. This can
indicate a file system error such as an out-of-space condition or the inability to write a
file.

ErrorDesc STRING(255) Message describing the source of the Error flag.

QueryingRecords BOOL The RTAC SOE Log is being actively queried for records.

bootstrap_LocalSource (Method)
A configuration method for specifying that local records (e.g., SEL_RTAC
origin) should be monitored in the RTAC's SOE Database.

Inputs
Name IEC 61131 Type Description

StationLabel STRING(255) The label used for the Station field in the resultant CSV text file.

Return Value
IEC 61131 Type Description

BOOL TRUE if the local source was successfully bootstrapped.

Processing
➤ Sets the class_SoeHarvester instance into local mode.
➤ Returns TRUE if the local RTAC SOE log entries that have an Origin
of SEL_RTAC are added to the SOE CSV file. Otherwise, it will return
FALSE.

Date Code 20241023 Programming Reference


256 DynamicDisturbanceRecorder
Classes

➤ Returns FALSE if the class_SoeHarvester was already configured for


remote mode by using a bootstrap_RemoteSource call.
➤ Subsequent calls to this method or calls after the first call of the Run()
method are ignored and return FALSE.

bootstrap_RemoteSource (Method)
A configuration method for adding a specific remote source to be monitored in
the RTAC's SOE Database.

Inputs
Name IEC 61131 Type Description

DeviceName STRING(255) Name of device expected to be present in the Origin field in the RTAC's SOE database.
Note that this name does not contain the trailing _SEL or _Modbus identifier that is
present in the device name in the ACSELERATOR RTAC project. E.g., a device in the
project named as SEL_351_1_SEL will be specified in this input value as SEL_351_1.

StationLabel STRING(255) Label used for Station field in the resultant CSV text file.

DeviceLabel STRING(255) Label prepended to SOE description before being placed in the Device field in the
resultant CSV text file.

TrimTrailingDescription BOOL Detect and remove additional descriptive text contained in parenthesis from the end of
the SOE description field, following the new state. Used by third party devices capable
of logging to RTAC SOE database. E.g., given an SOE message entry of "Latch Bit
1 Asserted (LT01)" from a bootstrapped origin source, the resulting CSV log entry is
written as: "<SOE log timestamp>,<UTC code>,<stationLabel>,<deviceLabel> Latch
Bit 1,Asserted"

Return Value
IEC 61131 Type Description

BOOL TRUE if the device was added for SOE Harvester CSV log file
generation.

Processing
➤ Sets the class_SoeHarvester instance into remote mode.
➤ Stores a reference to the specified device as a monitored Origin.
➤ Returns TRUE if the RTAC SOE log entries that have an Origin of the
specified deviceName are added to the SOE CSV file. Otherwise, it will
return FALSE.
➤ Returns FALSE if the class_SoeHarvester is configured for local mode by
using a bootstrap_LocalSource call.
➤ Calls after the first call of the Run() method are ignored and return
FALSE.

Run (Method)
This method should be called every scan to ensure proper functionality, which
includes scanning the RTAC SOE log for new contents and writing buffered
data to text files. This method should only be called after all of the desired
bootstrap_LocalSource or bootstrap_RemoteSource calls have been completed.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 257
Classes

Processing
➤ The first time the method is called, it blocks all future bootstrap methods
from adding new local or remote origin device sources.
➤ When operating in remote mode, for each new RTAC SOE record
matching a bootstrapped origin device source, write one line containing
a time value with millisecond precision, time code, station label, device
label, SOE message text and the final word of the SOE message text
as the data status value. The SOE Harvester CSV class assumes that
all SER records for an IED follow the message format of "My SER
Message <STATE>" where the "<STATE>" portion of the message
will be isolated as the final CSV component for the "value" column.
E.g., given an SOE message entry of "Latch Bit 1 Asserted" from a
bootstrapped origin source, the resulting CSV log entry is written as:
"<SOE log timestamp>,<UTC code>,<StationLabel>,<DeviceLabel>
Latch Bit 1,Asserted".
➤ When operating in local mode, for each new RTAC SOE record
matching an SEL_RTAC origin device source, write one line containing
a time value with millisecond precision, time code, station label,
tag name, and SOE message text. E.g., given an SOE tag name of
SEL_351_SEL.FM_INST_LT01 and message entry of "Latch Bit 1
Asserted" from a SEL_RTAC origin source, the resulting CSV log entry
is written as: "<SOE log timestamp> ,<UTC code>,<StationLabel>,
SEL_351_SEL.FM_INST_LT01, Latch Bit 1 Asserted".
➤ Upon a rising edge on the QueryRecords input, the SOE database is
scanned for new records matching bootstrapped criteria. Any new records
that are detected are added to an internal queue to be later written to file.
➤ If the trigger condition configured by the DataLogType, RefTime, and
LoggingInterval inputs is asserted, then queued SOE content is written to
the CSV log file.
➤ SOE Record content is written to the CSV log file in ascending order of
the records as they exist in the RTAC SOE database.
➤ Manage the total size of the directory path folder and the number of files
in the respective data path based on MaxDirectorySize.
➤ The CSV files will be maintained for MaxNumDays if the
MaxDirectorySize is not exceeded.
➤ If the MaxDirectorySize is exceeded before MaxNumDays of logs is
reached, the oldest file is deleted. This repeats until the cumulative
directory size is less than the MaxDirectorySize.
➤ Upon encountering a trigger condition, start a new CSV file if the number
of previously encountered triggers is equal to TriggersPerFile.
➤ The EN pin must be TRUE to scan for new SOE content and create CSV
text files.
➤ When EN is FALSE, no work is done.

Date Code 20241023 Programming Reference


258 DynamicDisturbanceRecorder
Benchmarks

➤ Following the first write to a CSV file, every 60 seconds a file


named .StateTracker is written in the directory specified by
DirectoryPath. This file tracks the record ID of the most recent SOE
record written to the CSV file.

NOTE
Deleting or otherwise modifying metadata in the .StateTracker file
in the specified directory may result in inconsistent CSV logging
behavior, causing either loss of data or extraneous record generation.

➤ A falling edge on EN clears all queued SOE content that has not
been written to a CSV text file. A rising edge of EN will read in
the .StateTracker information and use the content to re-queue any SOE
records that were not written to a CSV file.

NOTE
If a falling edge on EN occurs after SOE records have been written to
the CSV text file, but before the .StateTracker file has been updated at
its regular 60 second interval, these SOE records will be duplicated in
a new CSV text file upon the class re-enabling and a trigger condition
being encountered.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3505
➢ R134-V1 firmware
➤ SEL-3530
➢ R134-V1 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R139 firmware

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 259
Benchmarks

Benchmark Test Descriptions


class_TimeAlignedCSVManager Performance Tests
➤ Time-Aligned CSV TIME_CHANGE trigger: This test instantiates
one manager class, bootstraps it with two data points of each type, and
changes the time stamps of these data points ten times per second. The
RTAC has a task cycle time of 10 ms and the time required for the Run()
method is recorded. The average, maximum, minimum, and standard
deviation are recorded here.
➤ Time-Aligned CSV PERIODIC trigger: This test instantiates one
manager class, bootstraps it with two data points of each type, and sets
the period to 100 ms. The RTAC has a task cycle time of 10 ms and the
time required for the Run() method is recorded. The average, maximum,
minimum, and standard deviation are recorded here.
➤ Time-Aligned CSV TRIGGERED trigger: This test instantiates one
manager class, bootstraps it with two data points of each type, and
triggers once per second. The block is configured to store four pre-trigger
cycles and five post-trigger cycles. The RTAC has a task cycle time
of 10 ms and the time required for the Run() method is recorded. The
average, maximum, minimum, and standard deviation are recorded here.

class_SoeCsv Performance Tests


➤ Per-Point CSV DATA_CHANGE trigger: This test instantiates one
manager class, bootstraps it with two data points of each type, and
changes the data of these points ten times per second. The RTAC has a
task cycle time of 10 ms and the time required for the Run() method is
recorded. The average, maximum, minimum, and standard deviation are
recorded here.

class_Float32COMTRADE Performance Tests


➤ COMTRADE TIME_CHANGE trigger: This test instantiates one
manager class, bootstraps it with two data points of each type, and
changes the time stamps of these data points ten times per second. The
RTAC has a task cycle time of 10 ms and the time required for the Run()
method is recorded. The average, maximum, minimum, and standard
deviation are recorded here. This test waits for the first transition from
temporary data to CFG and DAT files to commence before running.
➤ COMTRADE PERIODIC trigger: This test instantiates one manager
class, bootstraps it with two data points of each type, and sets the period
to 100 ms. The RTAC has a task cycle time of 10 ms and the time
required for the Run() method is recorded. The average, maximum,
minimum, and standard deviation are recorded here. This test waits
for the first transition from temporary data to CFG and DAT files to
commence before running.
➤ COMTRADE TRIGGERED trigger: This test instantiates one manager
class, bootstraps it with two data points of each type, and triggers once
per second. The block is configured to store four pre-trigger cycles and
five post-trigger cycles. The RTAC has a task cycle time of 10 ms and the
time required for the Run() method is recorded. The average, maximum,
minimum, and standard deviation are recorded here.

Date Code 20241023 Programming Reference


260 DynamicDisturbanceRecorder
Examples

Benchmark Results
Platform (time in µs)
Operation Tested Metric
SEL-3505 SEL-3530 SEL-3555

class_SoeCsv

DATA_CHANGE Average 2540.4 1374.7 54.2


Maximum 10977.8 5904.3 321.1
Minimum 380.3 251.7 8.1
Std Deviation 2722.5 1366.7 55.9

class_Float32COMTRADE

TIME_CHANGE Average 314.6 204.9 16.7


Maximum 4636.9 1909.5 297.4
Minimum 102.1 76.5 3.8
Std Deviation 548.5 272.1 19.6

PERIODIC Average 276.9 171.9 12.7


Maximum 4845.8 1943.9 202.0
Minimum 66.3 32.2 2.0
Std Deviation 509.7 283.2 18.6

TRIGGERED Average 391.3 208.6 14.5


Maximum 3025.8 1297.5 102.9
Minimum 163.1 76.9 5.5
Std Deviation 399.2 227.8 14.8

class_TimeAlignedCSVManager

TIME_CHANGE Average 1057.1 631.8 29.2


Maximum 6555.3 3841.6 399.1
Minimum 245.9 275.3 4.1
Std Deviation 749.7 376.6 36.6

PERIODIC Average 1032.3 574.5 24.3


Maximum 6433.2 4206.8 398.1
Minimum 88.5 65.5 2.6
Std Deviation 734.2 369.9 35.2

TRIGGERED Average 1564.2 819.3 29.5


Maximum 5968.8 4456.6 341.6
Minimum 1000.0 667.5 21.1
Std Deviation 334.2 243.3 22.1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 261
Examples

Log Data Cyclically to a Time-Aligned CSV File


Objective
A user wishes to record three data points in a time-aligned CSV file format at a
one second periodic basis and does not want any log to exceed 100 KB. The user
wants to maintain the logs for a maximum of 10 days.

Assumptions
This example assumes that the data tags provided as inputs to the bootstrap
methods exist in the project.

Solution
For a periodic logger, the user can create a program as shown in Code
Snippet 9.2. The sample log output is shown in Code Snippet 9.1.
Code Snippet 9.1 Sample of a Time-Aligned Cyclic Log
PMU10:Point_INS1,PMU10:Point_SPS3
2017/03/14 22:14:25.899,3172.46,12.1414,123456,1
2017/03/14 22:14:26.900,9.11965E11,3330840.0,654321,0
2017/03/14 22:14:27.901,3172.46,12.1414,123456,1
2017/03/14 22:14:28.902,9.11965E11,3330840.0,654321,0
2017/03/14 22:14:29.903,3172.46,12.1414,123456,1
2017/03/14 22:14:30.904,9.11965E11,3330840.0,654321,0

Code Snippet 9.2 prg_CyclicCsvLogger


PROGRAM prg_CyclicCsvLogger
VAR
//Initialization variable
INIT : BOOL;
//Class initialization
MyCSVCyclic : class_TimeAlignedCsv := (EN := TRUE,
RecordTimeInUtc := FALSE,
TimeVariance := 0,
DataLogType := PERIODIC,
DirectoryPath := 'CSV_Cyclic_1',
FilePostfix := 'SubC.csv',
MaxFolderSize := 500000000,
MaxFileSize := 100000,
MaxNumDays := 10,
LoggingInterval := T#1S);
END_VAR

//Bootstrap the points for logging


IF NOT INIT THEN
MyCSVCyclic.bootstrap_MonitorCMV(channel := 'Point_CMV0',
station := 'PMU10', data := DataRecorderTags.Status_0000);
MyCSVCyclic.bootstrap_MonitorINS(channel := 'Point_INS1',
station := 'PMU10', data := DataRecorderTags.Status_0001);
MyCSVCyclic.bootstrap_MonitorSPS(channel := 'Point_SPS3',
station := 'PMU10', data := DataRecorderTags.Status_0002);

INIT := TRUE;
END_IF

//It is required to call the Run method every scan


MyCSVCyclic.Run();

Date Code 20241023 Programming Reference


262 DynamicDisturbanceRecorder
Examples

Log SOE Data to a CSV File


Objective
A user wishes to monitor and record any data status changes to four data points
in a SOE CSV file format and does not want any log to exceed 100 KB. The
user wants to maintain the logs for a maximum of 30 days.

Assumptions
This example assumes that the data tags provided as inputs to the bootstrap
methods exist in the project.

Solution
For an SOE logger, the user can create a program as shown in Code Snippet 9.3.
The sample log output is shown in Code Snippet 9.4.
Code Snippet 9.3 prg_SoeCsvLogger
PROGRAM prg_SoeCsvLogger
VAR
//Initialization variable
INIT : BOOL;
//Class initialization
MySOE : class_SoeCsv := (EN := TRUE,
RecordTimeInUtc := FALSE,
DirectoryPath := 'SOE Events 1',
FilePostfix := 'SubA.csv',
MaxFolderSize := 500000000,
MaxFileSize := 100000,
MaxNumDays := 30,
StartNewFilePerDay := FALSE);
END_VAR

//Bootstrap the points for logging


IF NOT INIT THEN
MySOE.bootstrap_MonitorCMV(channel := 'Point_CMV0', station := 'Breaker1'
, data := DataRecorderTags.Status_0000);
MySOE.bootstrap_MonitorINS(channel := 'Point_INS1', station := 'Breaker1',
data := DataRecorderTags.Status_0001);
MySOE.bootstrap_MonitorMV(channel := 'Point_MV2', station := 'Breaker1',
data := DataRecorderTags.Status_0003);
MySOE.bootstrap_MonitorSPS(channel := 'Point_SPS3', station := 'Breaker1',
data := DataRecorderTags.Status_0002);
INIT := TRUE;
END_IF

//It is required to call the Run method every scan


MySOE.Run();

Code Snippet 9.4 Sample of an SOE Log


Date,Time,Time Code,Station,Device,Value
03/15/2017,10:28:49.528,-7.0,Breaker1,Point_CMV0,[email protected]
03/15/2017,10:28:49.528,-7.0,Breaker1,Point_INS1,654321
03/15/2017,10:28:49.528,-7.0,Breaker1,Point_MV2,2.99882E-38
03/15/2017,10:28:49.528,-7.0,Breaker1,Point_SPS3,0
03/15/2017,10:28:50.529,-7.0,Breaker1,Point_CMV0,[email protected]
03/15/2017,10:28:50.529,-7.0,Breaker1,Point_INS1,123456
03/15/2017,10:28:50.529,-7.0,Breaker1,Point_MV2,1.07596E33
03/15/2017,10:28:50.529,-7.0,Breaker1,Point_SPS3,1

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 263
Examples

Log Data to a COMTRADE File


Objective
A user wishes to monitor and record any data updates for two data points, as
determined by the time stamp of the data point, in a COMTRADE file format.
The user does not want any log to exceed 10 MB and wants to maintain the logs
for a maximum of 10 days.

Assumptions
This example assumes that the data tags provided as inputs to the bootstrap
methods exist in the project.

Solution
For a COMTRADE time change logger, the user can create a program as shown
in Code Snippet 9.5. The sample log output is shown in Code Snippet 9.6.
Code Snippet 9.5 prg_COMTRADELogger
PROGRAM prg_COMTRADELogger
VAR
// Initialization variable
INIT : BOOL;
// Class initialization
MyCOMTRADETimeChange : class_ComtradeFloat32 := (EN := TRUE,
RecordTimeInUtc := FALSE,
TimeVariance := 0,
DataLogType := TIME_CHANGE,
DirectoryPath := 'CTRADE_Station1',
FilePostfix := 'Bay1',
MaxFolderSize := 500000000,
MaxFileSize := 1000000,
MaxNumDays := 10,
SystemFrequency := 60);
END_VAR

// Bootstrap the points for logging


IF NOT INIT THEN
MyCOMTRADETimeChange.bootstrap_MonitorCMV(channel := 'Point_CMV0',
station := 'PMU10', ph := 'A'
Component := 'Breaker1', Unit := 'V', data :=
DataRecorderTags.Status_0000);
MyCOMTRADETimeChange.bootstrap_MonitorINS(channel := 'Point_SPS39',
station := 'PMU10', ph := 'A',
Component := 'Breaker1', defaultState := FALSE, data :=
DataRecorderTags.Status_0002);
INIT := TRUE;
END_IF

// It is required to call the Run method every scan


MyCOMTRADETimeChange.Run();

Code Snippet 9.6 Sample of a COMTRADE 2013 CFG File


Bay1,RTAC_Archive,2013
5,4A,1D
1,PMU10:Point_CMV0_m,Am,Breaker1,V,1,0,0,-3.4028235E38,3.4028235E38,1,1,P
2,PMU10:Point_CMV0_a,Aa,Breaker1,V,1,0,0,-3.4028235E38,3.4028235E38,1,1,P
1,PMU10:Point_SPS39,A,Breaker1,0
60
1
1,40
15/03/2017,11:51:37.674722

Date Code 20241023 Programming Reference


264 DynamicDisturbanceRecorder
Examples

15/03/2017,11:51:37.674722
float32
1000
-7,-7
F,3

Log RTAC SOE Entries to a CSV File


Objective
A user wishes to monitor any specified RTAC SOE entries and record in a SOE
CSV file format 24 times per day and wants all records for a single day in 1 file.
The user wants to maintain the logs for a maximum of 90 days.

Assumptions
This example assumes that the devices provided to the bootstrap methods
(MySELClient and MyModbusClient) exist in the project and are configured to
retrieve SER data from the IED and store it in the RTAC's SOE Logger. These
devices are also time synchronized and generate SER records in the sample time
zone.

Solution
For an SOE Harvester CSV logger, the user can create a program as shown in
Code Snippet 9.7.
Code Snippet 9.7 prg_SoeCsvHarvesterLogger
PROGRAM prg_SoeCsvHarvesterLogger
VAR
// Initialization variable
INIT : BOOL;
// Class instantiation
MySOEHarvester : class_SoeHarvesterCsv := (EN := TRUE,
RecordTimeInUtc := FALSE,
DirectoryPath := 'SOE Harvested Events 1',
DataLogType := PERIODIC,
LoggingInterval := T#1H,
FilePostfix := 'HarvestedSOEs.csv',
MaxFolderSize := 500_000_000,
MaxNumDays := 90,
TriggersPerFile := 24);
QueryTimer : TI;
END_VAR

//Bootstrap the remote sources for logging


IF NOT INIT THEN
MySOEHarvester.bootstrap_RemoteSource(DeviceName := 'MySELClient',
StationLabel := 'Sub 1', DeviceLabel := 'Primary Relay',
TrimTrailingDescription := FALSE);
MySOEHarvester.bootstrap_RemoteSource(DeviceName := 'MyModbusClient',
StationLabel := 'Sub 1', DeviceLabel := 'Backup Relay',
TrimTrailingDescription := TRUE);
INIT := TRUE;
END_IF

// Query the SOE Database every 10 seconds


QueryTimer(PT := T#10S);
MySOEHarvester.QueryRecords := QueryTimer.Q;

// Call the Run method every scan

Programming Reference Date Code 20241023


DynamicDisturbanceRecorder 265
Examples

MySOEHarvester.Run();

Given entries in the RTAC SOE Logger such as those in Figure 9.1, the sample
log output is equivalent to that shown in Figure 9.2.

The RTAC SOE Log contains the following entries:

Figure 9.1 Sample RTAC SOE Logger Entries

The CSV File Contents contain:

Figure 9.2 Sample Contents of an SOE Harvester CSV Log File

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 1 0

DynamicVectors
Introduction
This library provides a vector data type for storing objects of various types,
including arbitrary user-created objects. In general, a vector is an array of
elements that is dynamically sized. As such, a vector allows elements to be
added or removed and can contain an arbitrary number of elements. A vector
also allows random access to its elements.

In addition to the vector classes, this library provides two factory functions
for creating vectors: fun_NewBaseVector() and fun_NewTypeVector().
Calling a factory function creates a new object and returns a pointer to that
object. For example, every call to fun_NewBaseVector() returns a pointer to
a newly created class_BaseVector object.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_VectorObject"
myVectorObject := otherVectorObject;

// This is fine
someVariable := myVectorObject.value;
// As is this
pt_myVectorObject := ADR(myVectorObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.1.0 and earlier can be used on RTAC firmware version R132 and
later.

Date Code 20241023 Programming Reference


268 DynamicVectors
Global Parameters

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_p_DefaultVectorSize UDINT 32 The default number of elements


that a vector can hold.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_DynamicVectorType
This enumeration is used for specifying the desired type of vector to the
fun_NewVector() function.

Enumeration Description

BYTE_VECTOR Enumeration for class_ByteVector.

WORD_VECTOR Enumeration for class_WordVector.

DWORD_VECTOR Enumeration for class_DwordVector.

LWORD_VECTOR Enumeration for class_LwordVector.

REAL_VECTOR Enumeration for class_RealVector.

LREAL_VECTOR Enumeration for class_LrealVector.

POINTER_VECTOR Enumeration for class_PointerVector.

Functions
fun_NewBaseVector (Function)
This function creates a new class_BaseVector and returns a pointer to the newly
created vector. The returned POINTER TO BYTE must be cast to the correct
type before it is used. A vector created with this function must be destroyed with
fun_DeleteVector() when it is no longer needed.

Inputs
Name IEC 61131 Type Description

elementSize UDINT The size of each element in the vector.

Programming Reference Date Code 20241023


DynamicVectors 269
Functions

Return Value
IEC 61131 Type Description

POINTER TO BYTE Pointer to the newly created vector. This pointer is null if the vector
could not be created.

Processing
➤ Creates a new vector with the specified elementSize and returns a pointer
to the newly created vector.
➤ Returns a null pointer if the vector could not be created.

fun_NewTypeVector (Function)
This function creates a new vector of the type specified and returns a pointer
to the newly created vector. The returned POINTER TO BYTE must be cast to
the correct type before it is used. A vector created with this function must be
destroyed with fun_DeleteVector() when it is no longer needed.

Inputs
Name IEC 61131 Type Description

vectorType enum_DynamicVectorType The desired type of vector.

Return Value
IEC 61131 Type Description

POINTER TO BYTE Pointer to the newly created vector. This pointer is null if the vector
could not be created.

Processing
➤ Creates a new vector of the type specified and returns a pointer to the
newly created vector.
➤ Returns a null pointer if the vector could not be created.

fun_DeleteVector (Function)
This function deletes a vector created with fun_NewBaseVector() or
fun_NewTypeVector(). After deletion, any pointers to the deleted vector are
no longer valid.

Inputs
Name IEC 61131 Type Description

vector I_Vector The vector to delete.

Date Code 20241023 Programming Reference


270 DynamicVectors
Interfaces

Return Value
IEC 61131 Type Description

BOOL TRUE if vector is successfully deleted. FALSE if an error occurs.

Interfaces
This library provides the following interface.

I_Vector
This interface is implemented by any class that provides a vector data type.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_BaseVector POINTER TO class_BaseVector R Pointer to the class_BaseVector used internally by this vector.

pt_Data POINTER TO BYTE R Pointer to the raw memory array used internally by this vector.

ElementSize UDINT R The number of bytes required for each element in the vector.

MaxSize UDINT R The number of elements this vector can currently hold before a
reallocation for additional memory is required.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Size UDINT R The number of elements in the vector.

Append (Method)
This method appends an array of elements to the end of the vector.

Inputs
Name IEC 61131 Type Description

pt_array POINTER TO BYTE Pointer to the first element to append to the


vector.

numElements UDINT The number of elements to copy from the


array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the elements are successfully appended to the vector.


FALSE if an error occurs.

Programming Reference Date Code 20241023


DynamicVectors 271
Interfaces

Processing
➤ If pt_array is null, the vector is not modified and this method returns
FALSE.
➤ If pt_array is valid and numElements is zero, the vector is not modified
and this method returns TRUE.
➤ If appending to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the
memory allocation fails, the vector is not modified and this method
returns FALSE.

Clear (Method)
Deallocates all memory associated with the vector. Call this method only if
the vector is instantiated with limited scope (i.e., if it is instantiated as a local
variable of a function or method).

Return Value
IEC 61131 Type Description

BOOL TRUE if the vector successfully deallocates its internal memory.


FALSE if an error occurs.

Recycle (Method)
This method removes all elements from the vector without modifying the
memory allocated to the vector.

Return Value
IEC 61131 Type Description

BOOL TRUE if the vector successfully removes all elements. FALSE if an


error occurs.

Processing
All elements are removed from the vector.

➤ After recycling, the Size property of the vector is zero.


➤ The MaxSize property is unchanged after a call to Recycle().
➤ This method neither allocates nor frees any memory.

Resize (Method)
This method resizes the vector so it can contain the number of elements
specified without requiring any additional memory allocations.

Date Code 20241023 Programming Reference


272 DynamicVectors
Classes

Inputs
Name IEC 61131 Type Description

newSize UDINT The desired number of elements for the resized vector
to contain without requiring a memory reallocation.

Return Value
IEC 61131 Type Description

BOOL TRUE if the vector is successfully resized. FALSE if an error occurs.

Processing
This method resizes the vector so it can contain the number of elements
specified without requiring any additional memory allocations.

➤ If the specified newSize is zero, then the vector is resized to


g_p_DefaultVectorSize or the present number of elements, whichever is
greater.
➤ If the specified newSize is greater than zero and less than the present
number of elements, the vector is resized to the present number of
elements.
➤ If the specified newSize is greater than the number of elements, the vector
is resized to the specified newSize.
➤ If the specified newSize equals the present maximum size of the vector,
the vector is not resized and the method returns TRUE.

Classes
class_BaseVector
This class implements a generic vector that internally handles dynamic
allocation of memory. This vector can handle objects of arbitrary size so long as
the number of bytes required for each element is the same. This vector stores its
internal data in a contiguous block of memory.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Vector

Programming Reference Date Code 20241023


DynamicVectors 273
Classes

Initialization Inputs

Name IEC 61131 Type Description

elementSize UDINT The number of bytes required for each element this
vector will hold. If zero, then default to one.

numElements UDINT The number of elements to account for initially. If


zero, then use the default.

GetCopyOfElement (Method)
This method copies the element at the zero-based index specified from the
vector to the destination pointer.

Inputs

Name IEC 61131 Type Description

index UDINT The index of the element to copy from the vector.

pt_destination POINTER TO A pointer to the destination to which the element is


BYTE copied.

Return Value

IEC 61131 Type Description

BOOL TRUE if the specified element is copied. FALSE if an error occurs.

Processing
If index or pt_destination is invalid, nothing is copied and FALSE is returned.

PopTo (Method)
This method copies the last element in the vector to the provided pointer
location and then deletes the last element.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO A pointer to the destination to which the element is


BYTE copied.

Return Value

IEC 61131 Type Description

BOOL TRUE if the last element is successfully copied and removed from the
vector. FALSE if an error occurs.

Date Code 20241023 Programming Reference


274 DynamicVectors
Classes

Processing
➤ Copies the last element in the vector to the provided pointer location.
➤ Removes the last element in the vector.
➤ If the vector does not contain any elements (i.e., the size is zero), the
method returns FALSE without modifying the vector.
➤ If pt_destination is invalid or the element cannot be copied, then the
vector is not modified and FALSE is returned.

PushFrom (Method)
Copies the bytes from the provided pointer location to a new element at the end
of the vector. Allocates additional memory if the vector does not have enough
memory to contain the new element.

Inputs

Name IEC 61131 Type Description

pt_source POINTER TO A pointer to the source from which the element is


BYTE copied.

Return Value

IEC 61131 Type Description

BOOL TRUE if the new element is added to the vector. FALSE if an error
occurs.

Processing
➤ Copies the element at pt_source to a new element at the end of the vector.
➤ If the vector Size is MaxSize before the addition of the new element,
the vector allocates additional memory. If the memory allocation fails,
FALSE is returned and the vector is not modified.
➤ If pt_source is invalid, FALSE is returned and the vector is not modified.

SetElement (Method)
This method sets the element in the vector, specified by the index (zero-based),
to the contents of the source pointer.

Inputs

Name IEC 61131 Type Description

index UDINT The index of the vector element to set.

pt_source POINTER TO A pointer to the source from which the element is


BYTE copied.

Programming Reference Date Code 20241023


DynamicVectors 275
Classes

Return Value

IEC 61131 Type Description

BOOL TRUE if the specified element is set. FALSE if an error occurs.

Processing
➤ Sets the element in the vector at index to the contents of pt_source.
➤ If index or pt_source is invalid, FALSE is returned and the vector is not
modified.

class_ByteVector
Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Vector

GetAt (Method)
Provides a copy of the element at the specified, zero-based index.

Inputs

Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Outputs

Name IEC 61131 Type Description

element BYTE The element at the specified index. If the return value
is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Date Code 20241023 Programming Reference


276 DynamicVectors
Classes

Outputs

Name IEC 61131 Type Description

element BYTE A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs

Name IEC 61131 Type Description

element BYTE The element to copy to the end of the vector.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully added to the vector. FALSE if an


error occurs.

Processing
If pushing element to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the memory
allocation fails, the vector is not modified and this method returns FALSE.

SetAt (Method)
This method provides write access to any element within the vector using a zero-
based index.

Inputs

Name IEC 61131 Type Description

index UDINT The index at which to set the value of an element.

value BYTE The new element value.

Programming Reference Date Code 20241023


DynamicVectors 277
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and FALSE is returned.

class_WordVector
Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Vector

GetAt (Method)
Provides a copy of the element at the specified, zero-based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Outputs
Name IEC 61131 Type Description

element WORD The element at the specified index. If the return value
is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Outputs
Name IEC 61131 Type Description

element WORD A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.

Date Code 20241023 Programming Reference


278 DynamicVectors
Classes

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs

Name IEC 61131 Type Description

element WORD The element to copy to the end of the vector.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully added to the vector. FALSE if an


error occurs.

Processing
If pushing element to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the memory
allocation fails, the vector is not modified and this method returns FALSE.

SetAt (Method)
This method provides write access to any element within the vector using a zero-
based index.

Inputs

Name IEC 61131 Type Description

index UDINT The index at which to set the value of an element.

value WORD The new element value.

Return Value

IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and FALSE is returned.

Programming Reference Date Code 20241023


DynamicVectors 279
Classes

class_DwordVector
Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Vector

GetAt (Method)
Provides a copy of the element at the specified, zero-based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Outputs
Name IEC 61131 Type Description

element DWORD The element at the specified index. If the return value
is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Outputs
Name IEC 61131 Type Description

element DWORD A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Date Code 20241023 Programming Reference


280 DynamicVectors
Classes

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs
Name IEC 61131 Type Description

element DWORD The element to copy to the end of the vector.

Return Value
IEC 61131 Type Description

BOOL TRUE if element is successfully added to the vector. FALSE if an


error occurs.

Processing
If pushing element to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the memory
allocation fails, the vector is not modified and this method returns FALSE.

SetAt (Method)
This method provides write access to any element within the vector using a zero-
based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index at which to set the value of an element.

value DWORD The new element value.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and FALSE is returned.

class_LwordVector
Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Vector

Programming Reference Date Code 20241023


DynamicVectors 281
Classes

GetAt (Method)
Provides a copy of the element at the specified, zero-based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Outputs
Name IEC 61131 Type Description

element LWORD The element at the specified index. If the return value
is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Outputs
Name IEC 61131 Type Description

element LWORD A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs
Name IEC 61131 Type Description

element LWORD The element to copy to the end of the vector.

Date Code 20241023 Programming Reference


282 DynamicVectors
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if element is successfully added to the vector. FALSE if an


error occurs.

Processing
If pushing element to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the memory
allocation fails, the vector is not modified and this method returns FALSE.

SetAt (Method)
This method provides write access to any element within the vector using a zero-
based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index at which to set the value of an element.

value LWORD The new element value.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and FALSE is returned.

class_RealVector
Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Vector

GetAt (Method)
Provides a copy of the element at the specified, zero-based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Programming Reference Date Code 20241023


DynamicVectors 283
Classes

Outputs

Name IEC 61131 Type Description

element REAL The element at the specified index. If the return value
is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Outputs

Name IEC 61131 Type Description

element REAL A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs

Name IEC 61131 Type Description

element REAL The element to copy to the end of the vector.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully added to the vector. FALSE if an


error occurs.

Date Code 20241023 Programming Reference


284 DynamicVectors
Classes

Processing
If pushing element to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the memory
allocation fails, the vector is not modified and this method returns FALSE.

SetAt (Method)
This method provides write access to any element within the vector using a zero-
based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index at which to set the value of an element.

value REAL The new element value.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and FALSE is returned.

class_LrealVector
Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Vector

GetAt (Method)
Provides a copy of the element at the specified, zero-based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Outputs
Name IEC 61131 Type Description

element LREAL The element at the specified index. If the return value
is FALSE, this value is undefined.

Programming Reference Date Code 20241023


DynamicVectors 285
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Outputs
Name IEC 61131 Type Description

element LREAL A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs
Name IEC 61131 Type Description

element LREAL The element to copy to the end of the vector.

Return Value
IEC 61131 Type Description

BOOL TRUE if element is successfully added to the vector. FALSE if an


error occurs.

Processing
If pushing element to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the memory
allocation fails, the vector is not modified and this method returns FALSE.

SetAt (Method)
This method provides write access to any element within the vector using a zero-
based index.

Date Code 20241023 Programming Reference


286 DynamicVectors
Classes

Inputs
Name IEC 61131 Type Description

index UDINT The index at which to set the value of an element.

value LREAL The new element value.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and FALSE is returned.

class_PointerVector
Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_Vector

GetAt (Method)
Provides a copy of the element at the specified, zero-based index.

Inputs
Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Outputs
Name IEC 61131 Type Description

element POINTER TO BYTE The element at the specified index. If the


return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Programming Reference Date Code 20241023


DynamicVectors 287
Classes

Outputs

Name IEC 61131 Type Description

element POINTER TO BYTE A copy of the former last element in the vector.
If the return value is FALSE, this value is
undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs

Name IEC 61131 Type Description

element POINTER TO BYTE The element to copy to the end of the vector.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully added to the vector. FALSE if an


error occurs.

Processing
If pushing element to the vector requires more memory than is currently
available in the vector, the library allocates additional memory. If the memory
allocation fails, the vector is not modified and this method returns FALSE.

SetAt (Method)
This method provides write access to any element within the vector using a zero-
based index.

Inputs

Name IEC 61131 Type Description

index UDINT The index at which to set the value of an


element.

value POINTER TO BYTE The new element value.

Date Code 20241023 Programming Reference


288 DynamicVectors
Benchmarks

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and FALSE is returned.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3530
➢ R134 firmware
➤ SEL-3354
➢ Intel Pentium 1.4 GHz
➢ 1 GB DDR ECC SDRAM
➢ SEL-3532 RTAC Conversion Kit
➢ R132 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134 firmware

Benchmark Test Descriptions


As benchmarks are designed to provide more information about speed of
operation in known environments, only tests on the five pre-configured vectors
are recorded here. Vectors on objects of varying sizes may have varying
performance.
All benchmark tests shall be performed 100 times with the average result
recorded here. In an attempt to allow other usage of system memory, only one
iteration of each test is run per scan.

Append
The time to append 1000 objects to the vector.

Clear
The time to clear a vector of 1000 objects.

GetAt
The worst case time for retrieving an arbitrary index out of a vector of length
1000.

Programming Reference Date Code 20241023


DynamicVectors 289
Benchmarks

SetAt
The worst case time for setting an arbitrary index in a vector of length 1000.

Push32
The performance of Push when Size = MaxSize = 32.

Push1024
The performance of Push when Size = MaxSize = 1024.

Pop
The performance of a pop of the 1000th element of a vector.

Recycle
The time to remove all data from a vector of 1000 objects.

Resize Down
The performance of a manual resize from 2048 elements to 32 elements.

Resize Up
The performance of a manual resize from 32 elements to 2048 elements.

NewVector
The performance of requesting a new vector of the desired type.

Benchmark Results
Platform (time in μs)
Operation Tested
SEL-3530 SEL-3354 SEL-3555

Append

Byte 67 9 6

Dword 58 6 3

Lreal 88 10 4

Lword 63 9 4

Pointer 44 5 3

Real 57 5 3

Word 43 5 3

Clear

Byte 41 4 3

Date Code 20241023 Programming Reference


290 DynamicVectors
Benchmarks

Platform (time in μs)


Operation Tested
SEL-3530 SEL-3354 SEL-3555

Dword 40 4 2

Lreal 40 4 2

Lword 43 4 2

Pointer 39 4 2

Real 39 4 2

Word 37 4 2

GetAt

Byte 17 2 1

Dword 6 2 1

Lreal 7 2 1

Lword 9 1 1

Pointer 6 1 1

Real 8 1 1

Word 6 2 1

New

Byte 73 23 10

Dword 43 6 4

Lreal 40 6 4

Lword 41 6 4

Pointer 37 6 4

Real 37 5 4

Word 42 6 4

Pop

Byte 4 1 1

Dword 5 1 1

Lreal 4 1 1

Lword 4 1 1

Pointer 4 1 1

Real 5 1 1

Word 4 1 1

Push1024

Byte 22 4 3

Dword 23 4 3

Lreal 36 5 3

Lword 33 5 3

Programming Reference Date Code 20241023


DynamicVectors 291
Benchmarks

Platform (time in μs)


Operation Tested
SEL-3530 SEL-3354 SEL-3555

Pointer 23 4 3

Real 22 4 3

Word 27 4 3

Push32

Byte 32 5 3

Dword 33 5 3

Lreal 33 5 3

Lword 35 5 3

Pointer 31 5 3

Real 30 5 3

Word 31 4 3

Recycle

Byte 2 1 1

Dword 2 1 1

Lreal 3 1 1

Lword 2 1 1

Pointer 2 1 1

Real 2 1 1

Word 2 1 1

ResizeDown

Byte 23 4 3

Dword 23 4 3

Lreal 23 4 3

Lword 21 4 3

Pointer 20 4 3

Real 22 4 3

Word 23 4 3

ResizeUp

Byte 35 5 3

Dword 35 4 3

Lreal 28 4 3

Lword 24 4 3

Pointer 24 4 3

Real 24 4 3

Word 30 5 3

Date Code 20241023 Programming Reference


292 DynamicVectors
Examples

Platform (time in μs)


Operation Tested
SEL-3530 SEL-3354 SEL-3555

SetAt

Byte 5 2 1

Dword 6 2 1

Lreal 7 1 1

Lword 5 2 1

Pointer 6 2 1

Real 7 1 1

Word 8 1 1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.
Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Creating and Using a class_ByteVector


Objective
This example shows how a basic class_ByteVector is instantiated and used.
Code Snippet 10.1 shows some simple manipulations of a byte vector. These
include appending an array to the vector, popping bytes off the end of the vector,
and checking the size of the vector.

Solution
To satisfy the objective, the user can create a program as shown in Code
Snippet 10.1.
Code Snippet 10.1 prg_ByteVector
PROGRAM prg_ByteVector
VAR
// Flag to only run the program once.
initialized : BOOL := FALSE;
// A dynamically sized vector of bytes.
byteVector : DynamicVectors.class_ByteVector();
// A fixed size array of bytes to append to the vector.
appendArray : ARRAY[1..5] OF BYTE := [1, 2, 3, 4, 5];
// A fixed size array of bytes to pop off the vector.
popArray : ARRAY[1..5] OF BYTE;
// The size of the vector after appending.
sizeAfterAppend : UDINT;
// The size of the vector after popping.
sizeAfterPop : UDINT;
// Loop counter.
i : UINT;
END_VAR

Programming Reference Date Code 20241023


DynamicVectors 293
Examples

// Only run the program once.


IF NOT initialized THEN
initialized := TRUE;

// Append the array to the empty vector.


byteVector.Append(ADR(appendArray), 5);
// The size after appending five bytes is five.
sizeAfterAppend := byteVector.Size;

// Pop all five elements off the vector and store in an array.
FOR i := 1 TO 5 DO
byteVector.Pop(element => popArray[i]);
END_FOR

// The size after popping the bytes off the vector is zero.
sizeAfterPop := byteVector.Size;
END_IF

Creating a class_ByteVector With fun_NewByteVector()


Objective
This example shows how a basic class_ByteVector is created when using the
factory function fun_NewTypeVector(). Code Snippet 10.2 shows some
simple manipulations of a byte vector created with a factory. These include
appending an array to the vector, popping bytes off the end of the vector,
checking the size of the vector, and deleting the byte vector.

Solution
To satisfy the objective, the user can create a program as shown in Code
Snippet 10.2.
Code Snippet 10.2 prg_ByteVectorFactory
PROGRAM prg_ByteVectorFactory
VAR
// Flag to only run once.
initialized : BOOL := FALSE;
// A pointer to a dynamically sized vector of bytes.
pt_byteVector : POINTER TO DynamicVectors.class_ByteVector();
// A fixed size array of bytes to append to the vector.
appendArray : ARRAY[1..5] OF BYTE := [1, 2, 3, 4, 5];
// A fixed size array of bytes to pop off the vector.
popArray : ARRAY[1..5] OF BYTE;
// The size of the vector after appending.
sizeAfterAppend : UDINT;
// The size of the vector after popping.
sizeAfterPop : UDINT;
// Loop counter.
i : UINT;
// A bool to store returned value from fun_DeleteVector
byteVectorDeleted : BOOL;
END_VAR

// Only run the program once.


IF NOT initialized THEN
initialized := TRUE;

(* Create the byte vector with the factory. fun_NewTypeVector creates a


* byte vector and returns a pointer to the new vector. *)
pt_byteVector := fun_NewTypeVector(BYTE_VECTOR);

// Append the array to the empty vector.


pt_byteVector^.Append(ADR(appendArray), 5);

Date Code 20241023 Programming Reference


294 DynamicVectors
Examples

// The size after appending five bytes is five.


sizeAfterAppend := pt_byteVector^.Size;

// Pop all five elements off the vector and store in an array.
FOR i := 1 TO 5 DO
pt_byteVector^.Pop(element => popArray[i]);
END_FOR

// The size after popping the bytes off the vector is zero.
sizeAfterPop := pt_byteVector^.Size;

(* Delete the byte vector. Fun_DeleteVector deletes a byte vector and returns a bool
* (TRUE if the vector was successfully deleted) *)
byteVectorDeleted := fun_DeleteVector(pt_byteVector^);
END_IF

Creating and Using a class_BaseVector


Objective
This example shows how a class_BaseVector is instantiated and used. Code
Snippet 10.4 shows some simple manipulations of a base vector. These include
appending an array to the vector, popping elements off the end of the vector, and
checking the size of the vector.

Assumptions
This example assumes that there is a user-specified IEC 61131 data type defined
as shown in Code Snippet 10.3.
Code Snippet 10.3 struct_UserObject
TYPE struct_UserObject :
STRUCT
name : STRING;
value : INT;
END_STRUCT
END_TYPE

Solution
To satisfy the objective, the user can create a program as shown in Code
Snippet 10.4.
Code Snippet 10.4 prg_BaseVector
PROGRAM prg_BaseVector
VAR
// Flag to only run once.
initialized : BOOL := FALSE;
(* A dynamically sized vector of struct_UserObects. This instantiates a vector of elements,
* where each element requires SIZEOF(struct_UserObject) bytes of memory and
* to reserve memory for 32 elements before a memory allocation is required. *)
baseVector : DynamicVectors.class_BaseVector(SIZEOF(struct_UserObject), 32);
// A fixed size array to append to the vector.
appendArray : ARRAY[1..5] OF struct_UserObject := [
(name := 'number 1', value := 1),
(name := 'number 2', value := 2),
(name := 'number 3', value := 3),
(name := 'number 4', value := 4),
(name := 'number 5', value := 5)
];
// A fixed size array to pop off the vector.

Programming Reference Date Code 20241023


DynamicVectors 295
Examples

popArray : ARRAY[1..5] OF struct_UserObject;


// The size of the vector after appending.
sizeAfterAppend : UDINT;
// The size of the vector after popping.
sizeAfterPop : UDINT;
// Loop counter.
i : UINT;
END_VAR

// Only run the program once.


IF NOT initialized THEN
initialized := TRUE;

// Append the array to the empty vector.


baseVector.Append(ADR(appendArray), 5);
// The size after appending five bytes is five.
sizeAfterAppend := baseVector.Size;

// Pop all five elements off the vector and store in an array.
FOR i := 1 TO 5 DO
baseVector.PopTo(ADR(popArray[i]));
END_FOR

// The size after popping the bytes off the vector is zero.
sizeAfterPop := baseVector.Size;
END_IF

Resizing a Vector
Objective
This example demonstrates resizing a vector. Resizing a vector changes how
much memory the vector reserves for the addition of new elements.

Addition of elements to a vector when it does not have space forces the vector
to allocate additional memory. Memory allocation is a relatively slow operation,
so it can be useful to have extra memory reserved by the vector to avoid
unnecessary memory allocations. If it is known how many elements the vector
will store, it can be resized once to avoid multiple slow memory allocations.

Resizing a vector is also useful for releasing memory from the vector. If a vector
contained 100 elements previously, but currently only contains 10, the vector
will still reserve memory for the previously removed 90 elements. If the vector
no longer needs to store 90 additional elements, that memory can be returned to
the system. A vector will not automatically release memory back to the system.

Code Snippet 10.5 shows the resizing of a vector to return memory to the
system.

Solution
To satisfy the objective, the user can create a program as shown in Code
Snippet 10.5.
Code Snippet 10.5 prg_VectorResize
PROGRAM prg_VectorResize
VAR
// Flag to only run once.
initialized : BOOL := FALSE;
// A dynamically sized vector of bytes.
byteVector : DynamicVectors.class_ByteVector();

Date Code 20241023 Programming Reference


296 DynamicVectors
Examples

// A fixed size array of bytes to append to the vector.


appendArray : ARRAY[1..5] OF BYTE := [1, 2, 3, 4, 5];
// A fixed size array of bytes to pop off the vector.
popArray : ARRAY[1..5] OF BYTE;
// The size of the vector after appending.
sizeAfterAppend : UDINT;
// The size of the vector after popping.
sizeAfterPop : UDINT;
// The maximum vector size before resizing.
maxSizeBeforeResize : UDINT;
// The maximum vector size after resizing.
maxSizeAfterResize : UDINT;
// Loop counter.
i : UINT;
END_VAR

// Only run the program once.


IF NOT initialized THEN
initialized := TRUE;
// Append the array to the empty vector.
byteVector.Append(ADR(appendArray), 5);
// The size after appending five bytes is five.
sizeAfterAppend := byteVector.Size;
// Pop all five elements off the vector and store in an array.
FOR i := 1 TO 5 DO
byteVector.Pop(element => popArray[i]);
END_FOR
// The size after popping the bytes off the vector is zero.
sizeAfterPop := byteVector.Size;
// The maximum size before resizing is 32 elements.
maxSizeBeforeResize := byteVector.MaxSize;
// Resize the vector so it can hold 10 bytes before a memory allocation is required.
byteVector.Resize(10);
(* The maximum size after resizing is 10 elements. The memory required for 22 elements
* is returned to the system, but if the vector needs to store more than 10 elements in
* the future, it will need to allocate additional memory. *)
maxSizeAfterResize := byteVector.MaxSize;
END_IF

Programming Reference Date Code 20241023


S E C T I O N 1 1

Email
Introduction
The Email library allows emails to be sent easily from a Real-Time Automation
Controller (RTAC) to a Simple Mail Transfer Protocol (SMTP) email server.
These emails can contain periodic information about process status, alert on-call
staff to process anomalies, or send collected event reports or other attachments
directly to email accounts or mobile devices.

Though this library does some parsing of the inputs provided, it is not meant to
fully support all features of SMTP. Test all emails to ensure that the formatting
of the arguments does not create an email the SMTP server receiving the request
will ignore.

This library uses the HELO message and local IP address to open each email.
This means that any features requiring the EHLO extensions, including user
authentication and encryption, are not supported.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error


such as:
// "C0328: Assignment not allowed for type
class_EmailClientObject"
myEmailClientObject := otherEmailClientObject;

// This is fine
someVariable := myEmailClientObject.value;
// As is this
pt_myEmailClientObject := ADR(myEmailClientObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Date Code 20241023 Programming Reference


298 Email
Enumerations

Versions 3.5.0.6 and earlier can be used on RTAC firmware version R132 and
later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_RecipientType
Enumeration Description

MAIL_TO This recipient will be a direct target of the email.

MAIL_CC This recipient will receive a copy of the email.

MAIL_BCC This recipient will receive a blind copy of the email.

Function Blocks
Function Blocks (FB), if declared in a program or a Global Variable List (GVL),
maintain their state from one processing scan to the next. They should be called
during each task cycle using their input pins to manage their behavior.

fb_SimpleEmailClient (Function Block)


This function block provides a simple triggered interface for sending email
to one or two recipients. It reads all inputs immediately upon receiving a
request that data be sent and ignores any further changes until the next trigger is
received.

Initialization Inputs
Name IEC 61131 Type Description

localIPAddr STRING(15) The IP address this RTAC should use to communicate with the email server. Set this to 0.0.0.0
to leave From IP information off of the message request and use an arbitrary interface for
communication.

mailServerIP STRING(15) The IP address of the email server.

Inputs
Name IEC 61131 Type Description

Send BOOL Initiate a new email communication.

Programming Reference Date Code 20241023


Email 299
Function Blocks

Inputs/Outputs
Name IEC 61131 Type Description

ToEmail STRING(254) The email address of the message recipient.

ToName STRING(255) The name of the email recipient.

CcEmail STRING(254) The email address to receive a copy of the message.

CcName STRING(255) The name of the copied recipient.

FromEmail STRING(254) The email address of the message sender.

FromName STRING(255) The name of the message sender.

Subject STRING(255) The subject of the message.

BodyStr STRING(255) The body of the message.

Outputs
Name IEC 61131 Type Description

Busy BOOL Indication that the function block is sending an


email.

SentMsg STRING(255) The first 255 characters of the last message the
function block sent to the SMTP server.

Error BOOL TRUE if the last attempt to send an email failed.

ErrorStr STRING(80) A description of why the last email transmission


failed.

Processing
The fb_SimpleEmailClient function block body does the following:

➤ Checks to see if a message is processing.


➤ Validates the email addresses provided. Allowed characters include all
alphanumeric characters, ., !, #, $, %, &, +, -, /, =, ?, ^, _, {, }, |, ~, and @.
➤ Replaces names containing double quotes with empty strings.
➤ Sends a new message to the defined recipients if the function block is not
busy and it detects a rising edge on Send.
➤ Works to complete the previously begun email transfer if the function
block is busy.
➤ Sets Busy to TRUE if it is waiting on the server to complete an email
request.

fb_SimpleEmailClient2 (Function Block)


This function block provides functionality and behavior that is identical to
fb_SimpleEmailClient (Function Block) on page 298, with the exception that
the user may define the outgoing and destination ports of the email client at
declaration. These inputs are described below.

Date Code 20241023 Programming Reference


300 Email
Classes

Initialization Inputs
Name IEC 61131 Type Description

localIPAddr STRING(15) The IP address this RTAC should use to communicate with the email server. Set this to 0.0.0.0
to leave From IP information off of the message request and use an arbitrary interface for
communication.

localPort UINT The outgoing client port from which emails shall be sent. Setting this to zero will allow the OS
to select an ephemeral port.

mailServerIP STRING(15) The IP address of the email server.

mailServerPort UINT The port number of the email server. For SMTP, this is should normally be set to 25, but the
user may set it otherwise if their server is configured accordingly.

Classes
Classes are a particular implementation of a function block. They provide
methods and properties, which normal function blocks do not provide.

class_EmailClient (Class)
This class provides the ability to craft an email message over time and
allows for multiple recipients, dynamic message body lengths, and vector
attachments. This class is identical to class_EmailClient2 with the exception
that class_EmailClient2 allows the client to define the outgoing and destination
ports for the client and server, respectively. By contrast, this class sets the
local port to 0, allowing the client OS to select an ephemeral port number. The
destination/server port is set to 25 (the standard SMTP interface port). As such,
this class can be used when there are no special requirements imposed on local
or destination port numbers.

Initialization Inputs
Name IEC 61131 Type Description

localIPAddr STRING(15) The IP address this RTAC should use to communicate with the email server. Set this to 0.0.0.0
to leave From IP information off of the message request and use an arbitrary interface for
communication.

mailServerIP STRING(15) The IP address of the email server.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Busy BOOL R Indication that the class is sending an email.

SentMsg STRING(255) R The first 255 characters of the last message the class sent to the SMTP
server.

ErrorStr STRING(80) R A description of any state that would prevent the attempt to send an email.

Programming Reference Date Code 20241023


Email 301
Classes

AddRecipient (Method)
This method adds a recipient for subsequent outgoing emails when they are sent.
This method may not be called and will return FALSE while Busy is TRUE and
the client is busy sending an email.

Inputs

Name IEC 61131 Type Description

recipientType enum_RecipientType To, Cc, or Bcc.

Inputs/Outputs

Name IEC 61131 Type Description

emailAddress STRING(254) The email address of the recipient.

name STRING(255) The name of the recipient.

Return Value

IEC 61131 Type Description

BOOL TRUE if emailAddress is valid and the recipient was added.

Processing
The AddRecipient() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Checks that the emailAddress contains only allowed characters. Allowed
characters include all alphanumeric characters, ., !, #, $, %, &, +, -, /, =, ?,
^, _, {, }, |, ~, and @.
➤ Verifies that names do not contain double quotes.
➤ Stores the email address and name to add to the recipient field defined by
recipientType of subsequent emails.
➤ Returns FALSE if the email address was not added.

AttachVector (Method)
This method allows the user to add a raw byte vector as an attachment. The
vector does not need to be encoded in base64-MIME because this will be
performed internally, nor will data be modified as a result of calling this
function. This method may not be called and will return FALSE while Busy is
TRUE and the client is busy sending an email.

Date Code 20241023 Programming Reference


302 Email
Classes

Inputs/Outputs
Name IEC 61131 Type Description

data class_ByteVector A byte vector of data to be attached when email is


sent.

name STRING The name for the attachment, as it shall appear in


each recipient's email.

Return Value
IEC 61131 Type Description

BOOL TRUE if data was successfully stored with name.

Processing
The AttachVector() method does the following:

➤ Verifies the client is not busy sending an email by checking that Busy is
FALSE.
➤ Verifies both data and name are non-empty.
➤ Copies and encodes data in base64-MIME format, storing the encoded
data as an attachment to be appended to an email.
➤ Returns FALSE if attachment was not added.

ClearAttachments (Method)
This method removes all stored attachments. Freeing large amounts of memory
is expensive, so this should be called infrequently. This method may not be
called and will return FALSE while Busy is TRUE and the client is busy sending
an email.

Processing
The ClearAttachments() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Deletes all email attachments stored by the email client object.

ClearRecipients (Method)
This method removes all stored recipients. This method may not be called and
will return FALSE while Busy is TRUE and the client is busy sending an email.

Processing
The ClearRecipients() method does the following:

➤ Verifies the class is not busy sending email by verifying Busy is FALSE.
➤ Deletes all stored email recipients.

Programming Reference Date Code 20241023


Email 303
Classes

Run (Method)
Main state machine, which must be called every task cycle. It handles
communication with the socket to send emails over multiple scans. This method
only performs work after Send() is called and Busy is TRUE; otherwise, the
call has no effect.

Processing
The Run() method does the following:
➤ Sits idle until Send() is called.
➤ Sets and clears the Busy state.
➤ Opens communication with the email server.
➤ Queues data for the email server.
➤ Closes the connection with the email server when the send is complete.

Send (Method)
This method sends the presently configured email. It does not clear any internal
state of the class, so the same email could be sent a second time by calling
Send() again.

Return Value
IEC 61131 Type Description

BOOL TRUE if the class will send the message to the email server.

Processing
The Send() method does the following:
➤ Verifies that the class is not already busy sending email.
➤ Verifies at least one recipient has been defined.
➤ Verifies the sender has been set.
➤ Sends a request to the email server to send the configured email.
➤ Returns FALSE if any check fails.

SetBodyBytes (Method)
Sets the content of the body of the email to the provided bytes. This method may
not be called and will return FALSE while Busy is TRUE and the client is busy
sending an email.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The bytes to use as the body of the email.

numBytes DINT The number of bytes to use as the body.

Date Code 20241023 Programming Reference


304 Email
Classes

Return Value

IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Processing
The SetBodyBytes() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Validates access to pt_data.
➤ Copies numBytes worth of data into internal storage.
➤ Replaces any periods beginning lines with two periods to prevent
incorrect body termination.
➤ Returns FALSE if the body construction failed.

SetBodySELString (Method)
Sets the body of the email to the content of the SELString provided. This
method may not be called and will return FALSE while Busy is TRUE and the
client is busy sending an email.

NOTE
See the SELString Library documentation for more details on class_SELString
objects.

Inputs/Outputs

Name IEC 61131 Type Description

data class_SELString The string to use as the body of the email.

Return Value

IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Processing
The SetBodySELString() method does the following:

➤ Verifies the class is not busy sending email by verifying Busy is FALSE.
➤ Copies the contents of data into internal storage.
➤ Replaces any periods beginning lines with two periods to prevent
incorrect body termination.
➤ Returns FALSE if the body construction failed.

Programming Reference Date Code 20241023


Email 305
Classes

SetBodyString (Method)
Sets the body of the email to the provided string. This method may not be called
and will return FALSE while Busy is TRUE and the client is busy sending an
email.

Inputs/Outputs

Name IEC 61131 Type Description

data STRING(255) The string to use as the body of the email.

Return Value

IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Processing
The SetBodyString() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Copies the contents of data into internal storage.
➤ Replaces any periods beginning lines with two periods to prevent
incorrect body termination.
➤ Returns FALSE if the body construction failed.

SetBodyVector (Method)
Sets the body of the email to the content of the vector provided. This method
may not be called and will return FALSE while Busy is TRUE and the client is
busy sending an email.

NOTE
See the DynamicVectors Library documentation for more details on the
I_Vector interface.

Inputs

Name IEC 61131 Type Description

data I_Vector The content to use as the body of the email.

Return Value

IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Date Code 20241023 Programming Reference


306 Email
Classes

Processing
The SetBodyVector() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Validates the data provided can be used.
➤ Copies the contents of data into internal storage.
➤ Replaces any periods beginning lines with two periods to prevent
incorrect body termination.
➤ Returns FALSE if the body construction failed.

SetSender (Method)
This method sets the sending email address for outgoing email. This method
may not be called and will return FALSE while Busy is TRUE and the client is
busy sending an email.

Inputs/Outputs

Name IEC 61131 Type Description

emailAddress STRING(254) The email address of the sender.

name STRING(255) The name of the sender.

Return Value

IEC 61131 Type Description

BOOL TRUE if emailAddress is valid and the sender was set.

Processing
The SetSender() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Checks that emailAddress contains only allowed characters. Allowed
characters include all alphanumeric characters, ., !, #, $, %, &, +, -, /, =, ?,
^, _, {, }, |, ~, and @.
➤ Sets emailAddress as the originating email address for outgoing emails.
➤ Returns FALSE if the sender was not set.

SetSubjectBytes (Method)
Sets the subject of the email to the provided bytes. This method may not be
called and will return FALSE while Busy is TRUE and the client is busy sending
an email.

Programming Reference Date Code 20241023


Email 307
Classes

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The bytes to use as the subject of the email.

numBytes DINT The number of bytes to use as the subject.

Return Value
IEC 61131 Type Description

BOOL TRUE if the subject content of the email was successfully populated.

Processing
The SetSubjectBytes() method does the following:
➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Validates access to pt_data.
➤ Copies numBytes worth of data into internal storage.
➤ Returns FALSE if the subject construction failed.

SetSubjectSELString (Method)
Sets the subject of the email to the content of the SELString provided. This
method may not be called and will return FALSE while Busy is TRUE and the
client is busy sending an email.

NOTE
See the SELString Library documentation for more details on class_SELString
objects.

Inputs/Outputs
Name IEC 61131 Type Description

data class_SELString The string to use as the subject of the email.

Return Value
IEC 61131 Type Description

BOOL TRUE if the subject content of the email was successfully populated.

Processing
The SetSubjectSELString() method does the following:
➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Copies the contents of data into internal storage.
➤ Returns FALSE if the subject construction failed.

Date Code 20241023 Programming Reference


308 Email
Classes

SetSubjectString (Method)
Sets the subject of the email to the provided string. This method may not be
called and will return FALSE while Busy is TRUE and the client is busy sending
an email.

Inputs/Outputs

Name IEC 61131 Type Description

data STRING(255) The string to use as the subject of the email.

Return Value

IEC 61131 Type Description

BOOL TRUE if the subject content of the email was successfully populated.

Processing
The SetSubjectString() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Copies the contents of data into internal storage.
➤ Returns FALSE if the subject construction failed.

SetSubjectVector (Method)
Sets the subject of the email to the content of the vector provided. This method
may not be called and will return FALSE while Busy is TRUE and the client is
busy sending an email.

NOTE
See the DynamicVectors Library documentation for more details on the
I_Vector interface.

Inputs

Name IEC 61131 Type Description

data I_Vector The content to use as the subject of the email.

Return Value

IEC 61131 Type Description

BOOL TRUE if the subject content of the email was successfully populated.

Programming Reference Date Code 20241023


Email 309
Classes

Processing
The SetSubjectVector() method does the following:

➤ Verifies the class is not busy sending email by verifying that Busy is
FALSE.
➤ Validates the data provided can be used.
➤ Copies the contents of data into internal storage.
➤ Returns FALSE if the subject construction failed.

class_EmailClient2 (Class)
The functionality, properties, and behavior of this class are identical to that
in class_EmailClient (Class) on page 300, with the exception of requiring
two additional variables in the class declaration: a local port number and a
destination email server port number. These inputs allow the user to define the
outgoing local port as well as the destination email server port. If the localPort
parameter is zero, then the operating system will select an ephemeral port
number. The SMTP email server port should normally be set to 25 but may be
set otherwise if the SMTP email server is configured accordingly.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_EmailClient

Initialization Inputs
These inputs are necessary during instantiation of the class.

Initialization Inputs

Name IEC 61131 Type Description

localPort UINT The outgoing client port from which emails shall be sent. Setting localPort to zero will allow
the OS to select an ephemeral port.

localIPAddr STRING(15) The IP address this RTAC should use to communicate with the email server. Set this to 0.0.0.0
to leave From IP information off of the message request and use an arbitrary interface for
communication.

mailServerPort UINT The port number of the email server. This is nearly always port 25 for SMTP, but the user may
set it otherwise if the server listening port is configured accordingly.

mailServerIP STRING(15) The IP address of the email server.

Date Code 20241023 Programming Reference


310 Email
Benchmarks

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.
➤ SEL-3505
➢ R134-V1 firmware
➤ SEL-3530
➢ R134-V1 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V1 firmware

Benchmark Test Descriptions


fb_SimpleEmailClient Average Busy Time
The posted time is the average execution time of 100 calls of the function block
body while the Busy output is high. This benchmark is run with all inputs using
maximum length strings.

fb_SimpleEmailClient Average Longest Scan Busy Time


It takes multiple calls to the function block to send an email and each call while
the function block is busy will take a varying length of time. The posted time
is the average time of the longest call of the function block body while the
function block is busy. The average is taken over 100 emails with all inputs
using maximum length strings.

fb_SimpleEmailClient2 Average Busy Time


The posted time is the average execution time of 100 calls of the function block
body while the Busy output is high. This benchmark is run with all inputs using
maximum length strings.

fb_SimpleEmailClient2 Average Longest Scan Busy Time


It takes multiple calls to the function block to send an email and each call while
the function block is busy will take a varying length of time. The posted time
is the average time of the longest call of the function block body while the
function block is busy. The average is taken over 100 emails with all inputs
using maximum length strings.

class_EmailClient.AddRecipient()
The posted time is the average execution time of 100 method calls adding a
recipient when the class is not busy. The email address and name strings are the
maximum length.

Programming Reference Date Code 20241023


Email 311
Benchmarks

class_EmailClient.AttachVector()
The posted time is the average execution time of 100 method calls attaching a
vector when the class is not busy. The attachment name string is the maximum
length and the content is 255 characters.

class_EmailClient.ClearAttachments()
The posted time is the average execution time of 100 method calls when clearing
10 file attachments. To ensure the most work possible, the attachments must
already be encoded as Base64 before they are cleared. The class is not busy
when the method is called.

class_EmailClient.ClearRecipients()
The posted time is the average execution time of 100 method calls when clearing
10 To recipients, 10 Cc recipients, and 10 Bcc recipients. The class is not busy
when the method is called.

class_EmailClient.Run() Average Busy Time


The posted time is the average execution time of 100 method calls while the
Busy output is high. The email message contains an 80-character subject with a
message body containing 255 characters.

class_EmailClient.Run() Average Busy Time With Event Report


The posted time is the average execution time of 100 method calls while the
Busy output is high. The email message contains an 80-character subject with a
message body containing a large event report.

class_EmailClient.Run() Average Longest Scan Time


It requires multiple calls to the Run() method to send an email and each call
while the class is busy will take a varying length of time. The posted time is the
average time of the longest call of the method while the method is busy. The
average is taken over 100 emails with an 80-character subject and a message
body containing 255 characters.

class_EmailClient.Run() Average Longest Scan Time With Event


Report
It requires multiple calls to the Run() method to send an email and each call
while the class is busy will take a varying length of time. The posted time is the
average time of the longest call of the method while the method is busy. The
average is taken over 100 emails with an 80-character subject and a message
body containing a large event report.

class_EmailClient.Send()
The posted time is the average execution time of 100 method calls. The class is
not busy when the method is called.

Date Code 20241023 Programming Reference


312 Email
Benchmarks

class_EmailClient.SetBodyBytes()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient.SetBodyBytes() With Event Report


The posted time is the average execution time of 100 method calls when setting
the email body to the contents of a large event report. The class is not busy when
the method is called.

class_EmailClient.SetBodySELString()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient.SetBodySELString With Event Report


The posted time is the average execution time of 100 method calls when setting
the email body to the contents of a large event report. The class is not busy when
the method is called.

class_EmailClient.SetBodyString()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient.SetBodyVector()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient.SetBodyVector() With Event Report


The posted time is the average execution time of 100 method calls when setting
the email body to the contents of a large event report. The class is not busy when
the method is called.

class_EmailClient.SetSender()
The posted time is the average execution time of 100 method calls when setting
a maximum length email address and name. The class is not busy when the
method is called.

class_EmailClient.SetSubjectBytes()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

Programming Reference Date Code 20241023


Email 313
Benchmarks

class_EmailClient.SetSubjectSELString()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

class_EmailClient.SetSubjectString()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

class_EmailClient.SetSubjectVector()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

class_EmailClient2.AddRecipient()
The posted time is the average execution time of 100 method calls adding a
recipient when the class is not busy. The email address and name strings are the
maximum length.

class_EmailClient2.AttachVector()
The posted time is the average execution time of 100 method calls attaching a
vector when the class is not busy. The attachment name string is the maximum
length and the content is 255 characters.

class_EmailClient2.ClearAttachments()
The posted time is the average execution time of 100 method calls when clearing
10 file attachments. To ensure the most work possible, the attachments must
already be encoded as Base64 before they are cleared. The class is not busy
when the method is called.

class_EmailClient2.ClearRecipients()
The posted time is the average execution time of 100 method calls when clearing
10 To recipients, 10 Cc recipients, and 10 Bcc recipients. The class is not busy
when the method is called.

class_EmailClient2.Run() Average Busy Time


The posted time is the average execution time of 100 method calls while the
Busy output is high. The email message contains an 80-character subject with a
message body containing 255 characters.

Date Code 20241023 Programming Reference


314 Email
Benchmarks

class_EmailClient2.Run() Average Busy Time With Event Report


The posted time is the average execution time of 100 method calls while the
Busy output is high. The email message contains an 80-character subject with a
message body containing a large event report.

class_EmailClient2.Run() Average Longest Scan Time


It requires multiple calls to the Run() method to send an email and each call
while the class is busy will take a varying length of time. The posted time is the
average time of the longest call of the method while the method is busy. The
average is taken over 100 emails with an 80-character subject and a message
body containing 255 characters.

class_EmailClient2.Run() Average Longest Scan Time With Event


Report
It requires multiple calls to the Run() method to send an email and each call
while the class is busy will take a varying length of time. The posted time is the
average time of the longest call of the method while the method is busy. The
average is taken over 100 emails with an 80-character subject and a message
body containing a large event report.

class_EmailClient2.Send()
The posted time is the average execution time of 100 method calls. The class is
not busy when the method is called.

class_EmailClient2.SetBodyBytes()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient2.SetBodyBytes() With Event Report


The posted time is the average execution time of 100 method calls when setting
the email body to the contents of a large event report. The class is not busy when
the method is called.

class_EmailClient2.SetBodySELString()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient2.SetBodySELString With Event Report


The posted time is the average execution time of 100 method calls when setting
the email body to the contents of a large event report. The class is not busy when
the method is called.

Programming Reference Date Code 20241023


Email 315
Benchmarks

class_EmailClient2.SetBodyString()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient2.SetBodyVector()
The posted time is the average execution time of 100 method calls when setting
the email body to contain 255 characters. The class is not busy when the method
is called.

class_EmailClient2.SetBodyVector() With Event Report


The posted time is the average execution time of 100 method calls when setting
the email body to the contents of a large event report. The class is not busy when
the method is called.

class_EmailClient2.SetSender()
The posted time is the average execution time of 100 method calls when setting
a maximum length email address and name. The class is not busy when the
method is called.

class_EmailClient2.SetSubjectBytes()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

class_EmailClient2.SetSubjectSELString()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

class_EmailClient2.SetSubjectString()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

class_EmailClient2.SetSubjectVector()
The posted time is the average execution time of 100 method calls when setting
the email subject to 255 characters. The class is not busy when the method is
called.

Date Code 20241023 Programming Reference


316 Email
Benchmarks

Benchmark Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

fb_SimpleEmailClient Busy Time 714 449 40

fb_SimpleEmailClient Longest Scan Busy Time 81 49 5

fb_SimpleEmailClient2 Busy Time 703 446 40

fb_SimpleEmailClient2 Longest Scan Busy Time 11 52 8

class_EmailClient.AddRecipient() 120 72 13

class_EmailClient.AttachVector() 1543 871 78

class_EmailClient.ClearAttachments() 836 335 24

class_EmailClient.ClearRecipients() 5 2 1

class_EmailClient.Run() Busy Time 178 98 17

class_EmailClient.Run() Busy Time w/ER 245 139 17

class_EmailClient.Run() Longest Scan Time 871 518 56

class_EmailClient.Run() Longest Scan Time w/ER 3839 1640 83

class_EmailClient.Send() 883 537 68

class_EmailClient.SetBodyBytes() 828 498 60

class_EmailClient.SetBodyBytes() w/ER 93158 51279 5579

class_EmailClient.SetBodySELString() 988 539 50

class_EmailClient.SetBodySELString w/ER 115792 61122 5855

class_EmailClient.SetBodyString() 861 581 60

class_EmailClient.SetBodyVector() 807 519 53

class_EmailClient.SetBodyVector() w/ER 93246 51173 5553

class_EmailClient.SetSender() 98 58 14

class_EmailClient.SetSubjectBytes() 49 31 9

class_EmailClient.SetSubjectSELString() 1091 498 48

class_EmailClient.SetSubjectString() 66 42 11

class_EmailClient.SetSubjectVector() 17 9 4

class_EmailClient2.AddRecipient() 118 72 12

class_EmailClient2.AttachVector() 1569 845 80

class_EmailClient2.ClearAttachments() 962 322 24

class_EmailClient2.ClearRecipients() 5 2 1

class_EmailClient2.Run() Busy Time 183 97 16

class_EmailClient2.Run() Busy Time w/ER 245 142 16

class_EmailClient2.Run() Longest Scan Time 925 526 49

class_EmailClient2.Run() Longest Scan Time w/ER 3874 1628 86

Programming Reference Date Code 20241023


Email 317
Examples

Platform (time in μs)


Operation Tested
SEL-3505 SEL-3530 SEL-3555

class_EmailClient2.Send() 936 540 73

class_EmailClient2.SetBodyBytes() 842 518 55

class_EmailClient2.SetBodyBytes() w/ER 95720 52103 5609

class_EmailClient2.SetBodySELString() 988 537 49

class_EmailClient2.SetBodySELString w/ER 118489 62911 5864

class_EmailClient2.SetBodyString() 890 506 58

class_EmailClient2.SetBodyVector() 854 497 52

class_EmailClient2.SetBodyVector() w/ER 95879 52390 5596

class_EmailClient2.SetSender() 95 59 14

class_EmailClient2.SetSubjectBytes() 48 31 8

class_EmailClient2.SetSubjectSELString() 1306 531 48

class_EmailClient2.SetSubjectString() 68 43 11

class_EmailClient2.SetSubjectVector() 17 10 2

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Sending an Alert Email After a Failure


Objective
A user wants to notify correct team members of events occurring in the field.

Assumptions
The user has in some way defined triggers that will set Alarm1 or Alarm2
to TRUE when appropriate events occur and allow them to return FALSE
afterwards.

Solution
The user can create a fb_SimpleEmailClient to provide brief notifications as
shown in Code Snippet 11.1.

Date Code 20241023 Programming Reference


318 Email
Examples

This example sends an email to different people determined by the alert received
and also sends a text message to an on-call telephone number using Short
Message Service (SMS).
Code Snippet 11.1 prg_EmailAlerts
PROGRAM prg_EmailAlerts
VAR
Emailer : fb_SimpleEmailClient( localIPAddr := '0.0.0.0',
mailServerIP := '192.168.176.99');
FromEmail : STRING(254) := '[email protected]';
FromName : STRING(255) := 'The automation RTAC';
//The number of the on call phone for an SMS message
OncallPhone : STRING(255) := '[email protected]';
DayEmail : STRING(254) := '[email protected]';
NightEmail : STRING(254) := '[email protected]';
ManagerEmail : STRING(254);
SubjectLine : STRING(255) := 'Plant on Backup Power';
BodyString : STRING(255);

Alarm1 : BOOL;
Alarm2 : BOOL;
END_VAR

IF Alarm1 THEN
ManagerEmail := DayEmail;
BodyString := 'The daytime plant has lost main power';
END_IF
IF Alarm2 THEN
ManagerEmail := NightEmail;
BodyString := 'The nighttime plant has lost main power';
END_IF
Emailer( Send := Alarm1 OR Alarm2,
ToEmail := OncallPhone, ToName := '',
CcEmail := ManagerEmail, CcName := '',
FromEmail := FromEmail, FromName := FromName,
Subject := SubjectLine, BodyStr := BodyString);

Forwarding a Text Report From the RTAC


Objective
After the RTAC receives confirmation of the completion of an automated task,
a user wants to receive a notice from the RTAC, including a log file of actions
taken.

Assumptions
The user has a task that runs and builds a readable log file "details.txt"
accessible through the File Manager features of the RTAC.

NOTE
See the FileIO Library documentation for details on how to access this area
programmatically.

The user has in some way defined a trigger that will set TaskDone to TRUE
when appropriate events occur and allow it to return FALSE afterwards.

The user has included FileIo and DynamicVectors in their project.

Programming Reference Date Code 20241023


Email 319
Examples

Solution
The user can create a class_EmailClient to provide brief notifications as seen in
Code Snippet 11.2.

This example sends an email containing the text of the log file to the user and a
manager.
Code Snippet 11.2 prg_DailyReport
PROGRAM prg_DailyReport
VAR
Emailer : class_EmailClient( localIPAddr := '0.0.0.0',
mailServerIP := '192.168.176.99');
FromEmail : STRING(254) := '[email protected]';
FromName : STRING(255) := 'The automation RTAC';
//Email addresses to receive the information.
SecretEmail : STRING(254) := '[email protected]';
DeveloperEmail : STRING(254) := '[email protected]';
SubjectLine : STRING(255) := 'The Numbers for the Day';

Initialized : BOOL := FALSE;


TaskDone : BOOL;
FileRead : BOOL;

FileBuffer : class_ByteVector;
LogFileReader : class_FileReader;
END_VAR

IF NOT Initialized THEN


Emailer.SetSender(FromEmail, FromName);
Emailer.AddRecipient(MAIL_BCC, SecretEmail, 'Head Honcho');
Emailer.AddRecipient(MAIL_TO, DeveloperEmail, '');
Emailer.SetSubjectString(SubjectLine);
Initialized := TRUE;
END_IF
IF TaskDone THEN
LogFileReader.ReadFile('/details.txt');
TaskDone := FALSE;
FileRead := FALSE;
END_IF
IF NOT FileRead AND LogFileReader.BytesInBuffer > 0 THEN
FileBuffer.Recycle();
LogFileReader.AppendToVector(startByte := 0, vector := FileBuffer);
Emailer.SetBodyVector(FileBuffer);
Emailer.Send();
FileRead := TRUE;
END_IF
Emailer.Run();
LogFileReader.Run();

Attaching Raw Data to Send


Objective
A user wishes to directly forward raw data on the RTAC device to various
technicians.

Assumptions
The user has configured Alarm to trigger on events of some manner, and has
also written data to ProcessControlData. The user has included DynamicVectors
in their project.

Date Code 20241023 Programming Reference


320 Email
Examples

Solution
The user can create a class_EmailClient to provide notifications with raw data
attachments as shown in Code Snippet 11.3.

This example sends an email with raw data attachments to various technicians or
other field personnel.
Code Snippet 11.3 prg_AttachData
PROGRAM prg_AttachData
VAR
Alarm : BOOL := FALSE;
Emailer : class_EmailClient( localIPAddr := '0.0.0.0',
mailServerIP := '192.168.176.7');
FromEmail : STRING(254) := '[email protected]';
FromName : STRING(255) := 'The automation RTAC';
Email : STRING(254) := '[email protected]';
AttachmentName : STRING(255) := 'procData.raw';
ProcessControlData : STRING(255) := '01110110101010';
ControlData : class_ByteVector;
SubjectLine : STRING(255) := 'Current Process Control Data';
BodyString : STRING(255) := 'Raw process control data attached.';
Initialized : BOOL := FALSE;
trigger : R_TRIG;
END_VAR

trigger(clk := Alarm OR Emailer.Busy);


//Send email when an alarm occurs and we have vector data to send.
IF trigger.Q AND (LEN(ProcessControlData) > 0) THEN
//Initializes the email parameters; assumes these do not change.
IF NOT Initialized THEN
Emailer.AddRecipient(MAIL_TO, Email, 'Lead Process Technicians');
Emailer.SetSender(FromEmail,FromName);
Emailer.SetBodyBytes(ADR(BodyString),LEN(BodyString));
Emailer.SetSubjectBytes(ADR(SubjectLine),LEN(SubjectLine));
Initialized := TRUE;
END_IF

// Clear any previous information from the vector


ControlData.Recycle();
// Append the new process information
ControlData.Append(ADR(ProcessControlData),
INT_TO_UDINT(LEN(ProcessControlData)));
// Clear any previous attachments and add the new data.
Emailer.ClearAttachments();
Emailer.AttachVector(ControlData,AttachmentName);

//Initiates the email send operation.


IF NOT Emailer.Busy THEN
Emailer.Send();
END_IF
END_IF

// Call Run() every scan to complete the email.


Emailer.Run();

Programming Reference Date Code 20241023


Email 321
Troubleshooting

Troubleshooting
As a communication module, this library depends several things:

1. Correct IP address entered for both the local host (either 0.0.0.0 or an IP
that can route to the mail server) and the mail server.
➤ If using 0.0.0.0 as the local IP address, ensure the network that can
reach the mail server is set as the primary gateway. This is set via the
RTAC web HMI.
➤ If the local IP address is set to the real IP address rather than 0.0.0.0,
the primary gateway does not need to be set.
2. Access to the mail server via port 25.
3. The mail server must be configured to allow email from the RTAC. This
may include but is not limited to: allowing the RTACs IP address to send
mail, permitting the "from name" that the RTAC uses, as well as the
"from email address."

For full information as to what is happening to a sent message, check the logs on
the mail server handling the request.

To quickly check the behavior of a given setup, one can manually test the
communications from a computer on the same subnet as the RTAC by opening a
raw TCP channel to the mail server on port 25 and issuing the same sequence of
commands issued by this library. All sections in teal should be replaced with
values from your environment. All new lines are represented by the ASCII for
carriage return followed by new line (many applications will insert this just by
pressing enter).

HELO RTAC_IP
MAIL FROM:<RTAC_EMAIL_ADDR>
RCPT TO:<TO_ADDR>
RCPT TO:<CC_ADDR>
DATA
From: "FROM_NAME"<RTAC_EMAIL_ADDR>
To: "TO_NAME"<TO_ADDR>
Cc: "CC_NAME"<CC_ADDR>
Subject: Email from RTAC

BODY OF MESSAGE
.
QUIT

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 1 2

EmailPlus
Introduction
The EmailPlus library provides SMTP client functionality. Emails can contain
plain text and attachments. The user can specify multiple recipients, including
carbon copy and blind carbon copy recipients. This library supports user
authentication, Transport Layer Security (TLS) encryption, and detailed logging
for each email sent. The EmailPlus library can be configured in three separate
behavior modes via the EmailType parameter in the Initialize method:

➤ TriggeredReport: Use AddRecipient, AddAttachment, and


AppendToBodyFromQueue/SELString/String/Vector during
runtime to manually define recipients, attachments and body content
before asserting the Send input and issuing an email.
➤ Monitored Alarm: Use Bootstrap_MonitoredAlarm and
BootStrap_GroupRecipient to define a set of monitored SPS
or BOOL tags along with a list of preconfigured recipients for each
configured group of tags. When the SPS or BOOL tags assert or deassert,
an "SOE-style" email will be issued to the recipients with the body
content containing a time stamp, a custom assert or deassert message, and
an optional message with accompanying analog value.
➤ Monitored Event: Use Bootstrap_EventSource and
BootStrap_GroupRecipient to define a set of inputs that constitute
a description of an SEL Protocol client device along with the available
tags from the History - New Event tab on that device. These tags will
be used to detect a new event and determine a time stamp of a CEV or
COMTRADE record to search for. Once the record is located, an event
summary email is constructed with the values available in the new event
tags (e.g., Fault Location) and an email is issued with those details and
the event record as an attachment.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_EmailPlusObject"
myEmailPlusObject := otherEmailPlusObject;

// This is fine
someVariable := myEmailPlusObject.value;
// As is this

Date Code 20241023 Programming Reference


324 EmailPlus
Introduction

pt_myEmailPlusObject := ADR(myEmailPlusObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).
➤ This library requires that all sender and recipient email addresses be
formatted as <local part>@<domain>, the total length of which must be
3–254 characters.
➢ <local part> must satisfy the following requirements:
➣ Allowed characters: alphanumeric, ., !, #, $, %, &, ', *, +, -, /, =, ?,
^, _, `, {, |, }, ~
➣ May not start or end with a "."
➣ May not contain ".."
➣ Must be 1–64 characters in length
➢ <domain> must satisfy the following requirements:
➣ Allowed characters: alphanumeric, ., -, with the exception of an
IPv4 address as the domain, which must be enclosed in square
brackets [ and ], (e.g., [1.2.3.4])
➣ May not start or end with a "."
➣ May not contain ".."
➣ Must be 1–252 characters in length
➤ Attachment file paths may contain alphanumeric characters, _
(underscore), (, ) (open and close parenthesis), - (dash), + (plus), . (dot), ,
(comma), @ (at), # (hash/pound), & (ampersand), and / (slash). They
cannot contain any path manipulation character sets (//, /./, /../).
➤ The SMTP server address may be a valid IPv4 address or a hostname.
➢ An IPv4 address must be formatted as a.b.c.d, where a, b, c, and d are
each numbers between 0 and 255.
➢ A hostname must satisfy the following requirements:
➣ The hostname consists of one or more "labels", concatenated
together by ".".
➣ A label may contain alphanumeric characters and "-".
➣ A label may not begin or end with "-".
➣ A label must be 1–63 characters in length.
➣ The hostname must be 1–253 characters in length.
➤ Email body text will be limited to 256 characters per line. Any lines
that exceed this limit will be broken at 256 characters and spread across
multiple lines. To avoid undesired line breaks, format body text with line
breaks in desired locations, keeping line length below the limit.
➤ Email body text must not exceed 65,535 bytes and will be truncated if it
exceeds this limit.
➤ The subject may contain ASCII characters 16#01–16#7F.

Programming Reference Date Code 20241023


EmailPlus 325
Supported Firmware Versions

➤ The email body may contain ASCII characters in the range from 1–
255. Characters with byte values of 128–255 will be evaluated using the
CP437 encoding.

Char

Char

Char

Char

Char

Char

Char

Char
Dec

Dec

Dec

Dec

Dec

Dec

Dec

Dec
128 Ç 144 É 160 á 176 ░ 192 └ 208 ╨ 224 α 240 ≡

129 ü 145 æ 161 í 177 ▒ 193 ┴ 209 ╤ 225 ß 241 ±

130 é 146 Æ 162 ó 178 ▓ 194 ┬ 210 ╥ 226 Γ 242 ≥

131 â 147 ô 163 ú 179 │ 195 ├ 211 ╙ 227 π 243 ≤

132 ä 148 ö 164 ñ 180 ┤ 196 ─ 212 ╘ 228 Σ 244 ⌠

133 à 149 ò 165 Ñ 181 ╡ 197 ┼ 213 ╒ 229 σ 245 ⌡

134 å 150 û 166 ª 182 ╢ 198 ╞ 214 ╓ 230 µ 246 ÷

135 ç 151 ù 167 º 183 ╖ 199 ╟ 215 ╫ 231 τ 247 ≈

136 ê 152 ÿ 168 ¿ 184 ╕ 200 ╚ 216 ╪ 232 Φ 248 °

137 ë 153 Ö 169 ⌐ 185 ╣ 201 ╔ 217 ┘ 233 Θ 249 ∙

138 è 154 Ü 170 ¬ 186 ║ 202 ╩ 218 ┌ 234 Ω 250 ·

139 ï 155 ¢ 171 ½ 187 ╗ 203 ╦ 219 █ 235 δ 251 √

140 î 156 £ 172 ¼ 188 ╝ 204 ╠ 220 ▄ 236 ∞ 252 ⁿ

141 ì 157 ¥ 173 ¡ 189 ╜ 205 ═ 221 ▌ 237 φ 253 ²

142 Ä 158 ₧ 174 « 190 ╛ 206 ╬ 222 ▐ 238 ε 254 ■

143 Å 159 ƒ 175 » 191 ┐ 207 ╧ 223 ▀ 239 ∩ 255

➤ Each call to append to the email body accepts content type as a parameter
for the section of the body being appended. The email body content type
determines how the email client will interpret the body text. The library
allows the user to select plain text for text to be rendered as-is, or HTML
for content formatted as HTML.
➤ The Initialize() method has a class input named UseSmtps that
specifies whether SMTPS protocol is to be used to communicate with
the server. If TRUE, the entire communication session with the server is
encrypted in an SSL/TLS wrapper. SMTPS communications typically
occur over TCP port 465. If FALSE, the initial communications with
the server occur in plain text. However, if the server reports support for
the STARTTLS function, TLS will be activated using that command
before any sensitive information is sent. This type of communications
exchange typically occurs over TCP port 587. Note that in general, the
use of SMTPS and/or TCP port 465 is deprecated; however, many email
servers still support it for compatibility reasons.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R146-V0 or later.
Versions 3.5.1.0 and 3.5.2.0 can be used on RTAC firmware version R150 and
later.

Date Code 20241023 Programming Reference


326 EmailPlus
Enumerations

Versions 3.5.3.0 and later can be used on RTAC firmware version R151 and
later.

If using Monitored Events with the COMNAME record file naming format,
firmware versions R151-V3 and later are required.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_BodyContentType
Format of email body content. Used with the AppendToBodyFromQueue/
SELString/String/Vector methods.

Enumeration Description

PLAIN_TEXT Email body content is interpreted as plain text.

HTML Email body content is interpreted as HTML.

enum_EmailerType
Configuration mode of this class_EmailClient instance. Used with the
EmailerType input in the Initialize() method.

Enumeration Description

REPORT This EmailPlus instance is configured for Triggered Reports.

ALARMS This EmailPlus instance is configured for Monitored Alarms.

EVENTS This EmailPlus instance is configured for Monitored Events.

enum_MonitoredAlarmAnalogMode
Configure the type of alarm transition with which to include the optional
Monitored Alarm analog input. Used with the AnalogMode input in the
Bootstrap_MonitoredAlarm() method.

Enumeration Description

NONE Do not include any optional analog value with the alarm email.

ON_ASSERT On assert of the monitored alarm, include the optional analog value with
the alarm email.

ON_DEASSERT On deassert of the monitored alarm, include the optional analog value
with the alarm email.

ON_EITHER On assert or deassert of the monitored alarm, include the optional analog
value with the alarm email.

Programming Reference Date Code 20241023


EmailPlus 327
Classes

enum_MonitoredAlarmAnalogTagType
Tag Type of a variable used as a Monitored Alarm optional analog input. Used
with the AnalogTagType input in the Bootstrap_MonitoredAlarm() method
to specify the tag type assigned to the pt_AnalogVariable input.

Enumeration Description

NONE No Monitored alarm analog variable.

BCR_ANALOG Monitored alarm analog is a BCR variable.

DINT_ANALOG Monitored alarm analog is a DINT variable.

INS_ANALOG Monitored alarm analog is an INS variable.

MV_ANALOG Monitored alarm analog is a MV variable.

REAL_ANALOG Monitored alarm analog is a REAL variable.

UDINT_ANALOG Monitored alarm analog is a UDINT variable.

enum_MonitoredAlarmTagType
Tag type of a variable used for a monitored alarm. Used with the TagType
input to specify the variable type assigned to the pt_Variable input in the
Bootstrap_MonitoredAlarm() method.

Enumeration Description

BOOL_ALARM Monitored alarm is a BOOL variable.

SPS_ALARM Monitored alarm is a SPS variable.

enum_RecipientType
The type of email recipient. Used with AddRecipient() method.

Enumeration Description

MAIL_TO This recipient is a direct target of the email.

MAIL_CC This recipient receives a copy of the email.

MAIL_BCC This recipient receives a blind copy of the email.

Classes
class_EmailClient (Class)
This class provides the ability to craft an email over time and allows for
multiple recipients, dynamic message body lengths with optional encoding
commands, and adding attachments. The class authenticates to the SMTP
server at the specified IP address and port and sends the email, optionally using
TLS encryption. As of library version 3.5.3.0, three configuration modes are
supported: Triggered Report mode, Monitored Alarms mode, and Monitored
Events mode.

Date Code 20241023 Programming Reference


328 EmailPlus
Classes

Triggered Report Mode


Triggered Report mode is the traditional behavior of the EmailPlus library.
In Triggered Report mode, it is the responsibility of the configured user
logic to create and trigger the send of any email messages. When the
Initialize() method is called, use the EmailerType input to specify a value
of enum_EmailerType.REPORT. In this configuration mode, after initialization
the following general workflow is used to craft and send an email message:

➤ Call the Run() method every RTAC processing interval.


➤ Use the SetSender() and SetSubject() methods to configure the
sending email address and subject line of the email message.
➤ Use the AddRecipient() method to add an email recipient. Call
multiple times for additional recipients. Note that added recipients persist
for future email messages unless the ClearRecipient() method is
called.
➤ Use the AddAttachment() method to add an email attachment.
➤ Use one of the AppendToBodyFromQueue/SELString/String/
Vector() methods to configure the body of the email message.
➤ Assert the Send class input.
➤ After the Busy output deasserts, a new email message can be crafted using
these same methods.

Monitored Alarms Mode


In Monitored Alarms mode, BOOL or SPS tag variables will be continuously
monitored for rising- or falling-edge conditions (with or without configured
pickup or dropout times), and upon detection of those conditions, an email
message will be automatically issued. If an assert or deassert message is
configured for a monitored tag, rising- or falling-edge detection is enabled.
If one of these messages is configured as an empty string, no emails will be
issued for that particular state change. Each monitored alarm can also have
an optional analog value appended to it to provide supplemental information
in the email message. For example, on a circuit breaker trip message, the
analog fault location can be appended to the email message. Upon detection of
multiple semi-simultaneous state changes, these email messages will be queued
and issued sequentially. When the Initialize() method is called, use the
EmailerType input to specify a value of enum_EmailerType.ALARMS. In this
configuration mode, after initialization the following general workflow is used
to configure alarms for monitoring and automated emails:

➤ Call the Run() method every RTAC processing interval.


➤ Use the SetSender() and SetSubject() methods to configure the
sending email address and subject line of the email message.
➤ Use the Bootstrap_GroupRecipient() method to add an email
recipient for monitored alarms. The recipient is configured with a bitmask
that allows for assignment of as many as 10 alarm groups for which this
recipient will receive emails.

Programming Reference Date Code 20241023


EmailPlus 329
Classes

➤ Use the Bootstrap_MonitoredAlarm() method to configure a BOOL


or SPS variable for state monitoring. This alarm will be associated with
a group number from 1–10 that corresponds to the groups assigned to a
particular email recipient.
➤ As the RTAC continues to run, any state changes of the monitored alarm
variables will cause an email message to be automatically crafted and
issued to appropriate recipients matching the group number assignment of
the monitored alarm.

The alarm emails will follow this general three-line format:

1. Time stamp of alarm, derived from .t.value of SPS or system time when
variable is BOOL
2. The configured assert or deassert message
3. The optional analog message appended with the analog value

The following is a sample alarm email:


Code Snippet 12.1 Alarm Email Sample
2022-05-25-18:22:14.002985
Tag Deasserted
Optional Analog Value: 35

Monitored Events Mode


In Monitored Events mode, History - New Event tags from one or more
SEL Protocol client devices are monitored to create event summary
emails that can optionally include an attachment of the associated CEV or
COMTRADE event record. The bootstrap_EventSource() method is
used to configure each individual event source, which is typically a one-for-
one match with an individual SEL Protocol client. Following assertion of
the New_Event_Detected POU pin output of the bootstrapped SEL client,
the individual time stamp components of the NEW_EVENT tags (e.g.,
SEL_421_1_SEL.NEW_EVENT_HOUR) are used to construct a target time
stamp that is used to scan the RTAC's event record database for the event. So
long as the RTAC collects the CEV or COMTRADE event record in a timely
fashion, it will be included as an attachment on the event summary email.
Event records are matched to associated New Events by way of an identical
time stamp or a matching REF_NUM that is present in the file name; for
this reason, SEL recommends configuring the SEL Protocol client to use the
COMNAME naming format for collected events so the REF_NUM (e.g., 10001)
is preserved and made part of the CEV or COMTRADE record file name. Using
the COMNAME naming format also allows the user to customize the names of
the event records and not rely on default naming (which can be generic; e.g.,
sel_event_45.cev) for those records. Note that COMNAME attachments in
EmailPlus are only supported in RTAC firmware versions R151-V3 or later.

If multiple new event detections occur across different SEL Protocol client
devices, these events will be buffered and processed in the order they are
received. If a search for an event record times out (exceeds the time specified
by Record_Search_Timeout in the bootstrap_EventSource() call), then an
event summary email is issued with the details available from the History - New
Event tags only.

Date Code 20241023 Programming Reference


330 EmailPlus
Classes

When the Initialize() method is called, use the EmailerType input to


specify a value of enum_EmailerType.EVENTS. In this configuration mode,
after initialization, the following general workflow is used to configure events
for monitoring and automated emails:

➤ Call the Run() method every RTAC processing interval.


➤ Use the SetSender() and SetSubject() methods to configure the
sending email address and subject line of the email message.
➤ Use the Bootstrap_GroupRecipient() method to add an email
recipient for monitored events. The recipient is configured with a bitmask
that allows for assignment of as many as 10 events groups for which this
recipient will receive emails.
➤ Use the Bootstrap_EventSource() method to add an event source
that is associated with a particular SEL Protocol client. Inputs to this
method constitute History - New Event tags as well as various parameters
to describe the type of event record to collect, how long to attempt
collection, and a group number from 1–10 that corresponds to the groups
assigned to a particular email recipient. Inputs that are marked as required
must be assigned a valid pointer address that resolves to the matching
New Event tag in question. Inputs that are marked as optional are not
required and, if unwanted for the resultant event summary email, can be
assigned to '0'.
➤ As the RTAC continues to run, any detected New Events will generate
event summary emails that may or may not include a record attachment.

The following is a sample event summary email:


Code Snippet 12.2 Event Email Sample
Event Email
Event Timestamp: 2023-05-03-14:06:54.868000
IED Name: My Tester 421
IED Location: Office
Event Type: TRIG
Device FID: FID=SEL-421-3-R131-V0-Z100011-D20130627
Device RID: Relay 1
Event Reference Number: 10001
Fault Location: NaN
Current: 0.00
Frequency: 60.00
Settings Group: 1
Targets:

Class Inputs and Outputs


Inputs

Name IEC 61131 Type Description

Send BOOL Asserting Send triggers the next email to be sent.


Ignored while Busy is asserted.

MaintenanceMode BOOL Asserting this input disables email sending


functionality via the Send trigger or any
bootstrapped monitored alarms.

Programming Reference Date Code 20241023


EmailPlus 331
Classes

Outputs
Name IEC 61131 Type Description

Initialized BOOL This pin asserts when the class finishes


initialization. Calls to any method other than Run()
are ignored while this is deasserted.

RuntimeErrors STR Lists any runtime errors encountered.

Status STR Lists the present status of the emailer. In Monitored


Alarm configuration, this includes indications of
a startup delay and other activity. In Monitored
Events configuration, this will indicate an active
search for an event record for a particular device.

Busy BOOL If TRUE, calls to any method other than Run() and
assertions of Send are ignored.

Processing
➤ While Initialized is deasserted, calls to the Run() method and assertions
of Send have no effect.
➤ Once Initialize() is called and the class successfully completes
initialization, resulting in the assertion of Initialized, any further calls to
Initialize() are ignored.
➤ Each email must be constructed through calls to the various class methods
before Send is asserted.
➤ When Send is asserted:
➢ Busy asserts and the class attempts to send the email. Any invalid
email fields result in a failure to send the email, and the class sets an
appropriate error in RuntimeErrors.
➢ If the parameters of the email are valid but the time-out is reached
before the class has finished sending the email, the email is not sent
and the class sets an appropriate error in RuntimeErrors.
➢ If the class instance is configured for logging, any runtime errors are
logged to the RTAC Sequence of Events (SOE) log.
➢ Email content and parameters are cleared.
➢ Busy deasserts.

AddAttachment (Method)
This method adds an attachment to the subsequent outgoing email. Any
number of attachments can be added. When the email is sent, if the total size of
attachments is greater than MaxAttachmentSize, the attachments will be broken
up across multiple emails. This method returns FALSE and has no effect when
Busy is TRUE or Initialized is FALSE. Attachments must be added before each
assertion of Send.

Inputs
Name IEC 61131 Type Description

filePath STRING(248) The path of the file to attach.

Date Code 20241023 Programming Reference


332 EmailPlus
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if attachment was successfully added.

Processing
The AddAttachment() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not add
the attachment.
➤ Returns FALSE if the attachment cannot be added and sets an appropriate
error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the attachment is added.

AddRecipient (Method)
This method adds a recipient for the subsequent outgoing emails. Any number
of recipients can be added. This method returns FALSE and has no effect when
Busy is TRUE or Initialized is FALSE. At least one recipient must be added
before the assertion of Send.

NOTE
Email addresses greater than 254 characters in length will be truncated.

Inputs
Name IEC 61131 Type Description

recipientType enum_RecipientType To, Cc, or Bcc.

emailAddress STRING(254) The email address of the recipient.

Return Value
IEC 61131 Type Description

BOOL TRUE if emailAddress is valid and the recipient is successfully


added.

Processing
The AddRecipient() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not add
the recipient.
➤ Checks that the email address contains only allowed characters.
➤ Adds the email address to the appropriate recipient field for the
subsequent email.

Programming Reference Date Code 20241023


EmailPlus 333
Classes

➤ Returns FALSE if the email address cannot be added and sets an


appropriate error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the recipient is added.

AppendToBodyFromQueue (Method)
Sets the body of the email to the content of the queue provided. This method
returns FALSE and has no effect when Busy is TRUE or Initialized is FALSE.
The body must be set before each assertion of Send. This method can be called
multiple times to append repeatedly to the body. The bodyContentType is
assigned on the first call and ignored on subsequent calls to append methods.

NOTE
See the Queue library documentation for more details on the
class_ByteDeque class.

Inputs/Outputs

Name IEC 61131 Type Description

bodyQueue class_ByteDeque The content to use as the body of the email.

Inputs

Name IEC 61131 Type Description

bodyContentType enum_BodyContentType The content type used to interpret this


section of the email body.

Return Value

IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Processing
The AppendToBodyFromQueue() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not set
the body of the email.
➤ Copies the contents of bodyQueue into internal storage, marking the
content type according to bodyContentType.
➤ Returns FALSE if the body construction failed and sets an appropriate
error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the body is successfully set.

Date Code 20241023 Programming Reference


334 EmailPlus
Classes

AppendToBodyFromSELString (Method)
Sets the body of the email to the content of the SELString provided. This
method returns FALSE and has no effect when Busy is TRUE or Initialized is
FALSE. The body must be set before each assertion of Send. This method can be
called multiple times to append to the body repeatedly. The bodyContentType is
assigned on the first call and ignored on subsequent calls to append methods.

Inputs
Name IEC 61131 Type Description

bodyString POINTER TO class_SELString Pointer to the SELString to use as the


body of the email.

bodyContentType enum_BodyContentType The content type used to interpret this


section of the email body.

Return Value
IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Processing
The AppendToBodyFromSELString() method does the following:
➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not set
the body of the email.
➤ Copies the contents of bodyString into internal storage, marking the
content type according to bodyContentType.
➤ Returns FALSE if the body construction failed and sets an appropriate
error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the body is successfully set.

AppendToBodyFromString (Method)
Sets the body of the email to the provided string. This method returns FALSE
and has no effect when Busy is TRUE or Initialized is FALSE. The body must
be set before each assertion of Send. This method can be called multiple times to
append to the body repeatedly. The bodyContentType is assigned on the first call
and ignored on subsequent calls to append methods.

Inputs
Name IEC 61131 Type Description

bodyString STRING(255) The string to use as the body of the email.

bodyContentType enum_BodyContentType The content type used to interpret this


section of the email body.

Programming Reference Date Code 20241023


EmailPlus 335
Classes

Return Value

IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Processing
The AppendToBodyFromString() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not set
the body of the email.
➤ Copies the contents of bodyString into internal storage, marking the
content type according to bodyContentType.
➤ Returns FALSE if the body construction failed and sets an appropriate
error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the body is successfully set.

AppendToBodyFromVector (Method)
Sets the body of the email to the content of the vector provided. This method
returns FALSE and has no effect when Busy is TRUE or Initialized is FALSE.
The body must be set before each assertion of Send. This method can be called
multiple times to append to the body repeatedly. The bodyContentType is
assigned on the first call and ignored on subsequent calls to append methods.

NOTE
See the DynamicVectors library documentation for more details on the
I_Vector interface.

Inputs

Name IEC 61131 Type Description

bodyVector I_Vector The content to use as the body of the


email.

bodyContentType enum_BodyContentType The content type used to interpret this


section of the email body.

Return Value

IEC 61131 Type Description

BOOL TRUE if the body content of the email was successfully populated.

Date Code 20241023 Programming Reference


336 EmailPlus
Classes

Processing
The AppendToBodyFromVector() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not set
the body of the email.
➤ Copies the contents of bodyVector into internal storage, marking the
content type according to bodyContentType.
➤ Returns FALSE if the body construction failed and sets an appropriate
error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the body is successfully set.

Bootstrap_EventSource (Method)
Add an event source with which to generate automated Event Summary emails.
Used when this EmailPlus instance is configured for Monitored Events. This
method returns FALSE and has no effect when Busy is TRUE or Initialized is
FALSE.

Inputs
Name IEC 61131 Type Description

IED_Name STRING(255) The name of the IED providing the events. Configurable description that
appears in the Event Summary email.

Device_Name STRING(32) The device name of the SEL Protocol client in the project (minus the
_SEL suffix).

GroupNumber UINT Group number (1–10) to associate with the monitored event source.

Record_Type FileIo.Enum_event_type Record type of events to monitor from this source, CEV_FILE or
COMTRADE. Specifying NO_EVENT_TYPE will indicate that no
event record attachment should be included with event summary emails.

pt_Device_OfflineStatus POINTER TO BOOL Offline POU Pin output status from the SEL Protocol client device.

pt_New_Event_Detected POINTER TO BOOL New_Event_Detected POU Pin output status from the SEL Protocol
client device.

pt_Event_Year POINTER TO DINT NEW_EVENT_YEAR tag from SEL Protocol client device (required).

pt_Event_Month POINTER TO DINT NEW_EVENT_MONTH tag from SEL Protocol client device
(required).

pt_Event_Day POINTER TO DINT NEW_EVENT_DAY tag from SEL Protocol client device (required).

pt_Event_Hour POINTER TO DINT NEW_EVENT_HOUR tag from SEL Protocol client device (required).

pt_Event_Minute POINTER TO DINT NEW_EVENT_MIN tag from SEL Protocol client device (required).

pt_Event_Second POINTER TO DINT NEW_EVENT_SEC tag from SEL Protocol client device (required).

pt_Event_Msec POINTER TO DINT NEW_EVENT_MSEC tag from SEL Protocol client device (required).

pt_Event_Type POINTER TO STRING NEW_EVENT_EVENT tag from SEL Protocol client device (required).

pt_Event_FID POINTER TO STRING NEW_EVENT_FID tag from SEL Protocol client device (optional).

pt_Event_RID POINTER TO STRING NEW_EVENT_RID tag from SEL Protocol client device (optional).

Programming Reference Date Code 20241023


EmailPlus 337
Classes

Name IEC 61131 Type Description

pt_Event_RefNum POINTER TO DINT NEW_EVENT_REFNUM tag from SEL Protocol client device
(optional, but required for COMTRADE record attachments).

pt_Event_Current POINTER TO REAL NEW_EVENT_CURR tag from SEL Protocol client device (optional).

pt_Event_Freq POINTER TO REAL NEW_EVENT_FREQ tag from SEL Protocol client device (optional).

pt_Event_Group POINTER TO DINT NEW_EVENT_GROUP tag from SEL Protocol client device (optional).

pt_Event_Location POINTER TO REAL NEW_EVENT_FAULT_LOC tag from SEL Protocol client device
(optional).

pt_Event_Shot POINTER TO DINT NEW_EVENT_SHOT tag from SEL Protocol client device (optional).

pt_Event_Shot_1P POINTER TO DINT NEW_EVENT_SHOT_1P tag from SEL Protocol client device
(optional).

pt_Event_Shot_3P POINTER TO DINT NEW_EVENT_SHOT_3P tag from SEL Protocol client device
(optional).

pt_Event_Targets POINTER TO STRING NEW_EVENT_TARGETS tag from SEL Protocol client device
(optional).

Record_Search_Timeout TIME Time to allow for the RTAC to collect the desired event record file (CEV
or COMTRADE) and become available as an attachment to the event
summary email.

Return Value

IEC 61131 Type Description

BOOL TRUE if the event source was successfully added.

Processing
The Bootstrap_EventSource() method does the following:

➤ If Busy is TRUE, Initialized is FALSE, or Initialized is TRUE


but Initialize() was not called with an EmailerType of
enum_EmailerType.EVENTS, returns FALSE and does not add the event
source.
➤ Checks that the IED_Name, IED_Location, and Device_Name values
have been specified and are not empty strings.
➤ Checks that the group number specified by GroupNumber is between 1
and 10.
➤ Checks that the pt_Device_OfflineStatus, pt_New_Event_Detected,
pt_Event_Year, pt_Event_Month, pt_Event_Day, pt_Event_Hour,
pt_Event_Minute, pt_Event_Second, pt_Event_Msec, and pt_Event_Type
inputs are all non-zero, assuming a valid pointer address is present.
➤ Checks that the Record_Type input is a valid enum_event_type value
(CEV_FILE, COMTRADE, or NO_EVENT_TYPE).
➤ Returns FALSE if the event source was not added and sets an appropriate
error in RuntimeErrors.
➤ Returns TRUE if the event source is added.

Date Code 20241023 Programming Reference


338 EmailPlus
Classes

Bootstrap_GroupRecipient (Method)
Add an email recipient associated with a set of Group Numbers to be used
when this EmailPlus instance is configured for Monitored Alarms or Monitored
Events. This method returns FALSE and has no effect when Busy is TRUE or
Initialized is FALSE.

Inputs
Name IEC 61131 Type Description

emailAddress STRING(254) The email address to associate with the recipient.

groupMask WORD A bit pattern representing Alarms Groups 1–10 (bit


0 = Group 1, bit 9 = Group 10) to associate with the
recipient. Must not exceed a numeric value of 1023.

Return Value
IEC 61131 Type Description

BOOL TRUE if the group recipient was successfully added.

Processing
The Bootstrap_GroupRecipient() method does the following:
➤ If Busy is TRUE, Initialized is FALSE, or Initialized is TRUE
but Initialize() was not called with an EmailerType of
enum_EmailerType.ALARMS, returns FALSE and does not add the
recipient.
➤ Checks that the email address contains only allowed characters.
➤ Checks that the group mask does not exceed a numeric value of 1023.
➤ Adds the email address to MAIL_TO field associated with the group
numbers specified by the bit-mask.
➤ Returns FALSE if the email address cannot be added and sets an
appropriate error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the recipient is added.

Bootstrap_MonitoredAlarm (Method)
Add a monitored alarm along with its various assert and deassert messages and
pickup/dropout timers; used when this EmailPlus instance is configured for
Monitored Alarms.

Inputs
Name IEC 61131 Type Description

TagType enum_MonitoredAlarmTagType The tag type of the monitored alarm.

pt_Variable POINTER TO BYTE Pointer to the variable representing the monitored alarm.

Programming Reference Date Code 20241023


EmailPlus 339
Classes

Name IEC 61131 Type Description

GroupNumber UINT Group number (1–10) to associate with the monitored alarm.

AssertMsg STRING(255) Assert message to include in the email body content when a
rising-edge trigger is detected on the monitored alarm.

PUDelayTime TIME Optional pickup delay time to associate with the monitored
alarm before an email is triggered.

DeassertMsg STRING(255) Deassert message to include in the email body content when a
falling-edge trigger is detected on the monitored alarm.

DODelayTime TIME Optional dropout delay time to associate with the monitored
alarm before an email is triggered.

AnalogMode enum_MonitoredAlarmAnalogMode Optionally include an analog value to associate with the


monitored alarm.

AnalogTagType enum_MonitoredAlarmAnalogTagType Tag type of the optional analog value associated with the
monitored alarm.

pt_AnalogVariable POINTER TO BYTE Pointer to the variable representing the optional analog tag.

AnalogMsg STRING(255) Optional message to associate with the analog quantity.

Return Value
IEC 61131 Type Description

BOOL TRUE if the monitored alarm was successfully added.

Processing
The Bootstrap_MonitoredAlarm() method does the following:
➤ If Busy is TRUE, Initialized is FALSE, or Initialized is TRUE
but Initialize() was not called with an EmailerType of
enum_EmailerType.ALARMS, returns FALSE and does not add the
monitored alarm.
➤ Checks that the Tag Type specified by the TagType input is a valid
enum_MonitoredAlarmTagType.
➤ Checks that the pointer address specified by pt_Variable is non-zero.
➤ Checks that the group number specified by GroupNumber is between 1
and 10.
➤ Checks that at least one non-zero-length string is assigned to AssertMsg
and DeassertMsg.
➤ Checks that the analog mode specified by the AnalogMode input is a valid
enum_MonitoredAlarmAnalogMode.
➤ If AnalogMode is not equal to
enum_MonitoredAlarmAnalogMode.NONE then checks that
the analog tag type specified by AnalogTagType is a valid
enum_MonitoredAlarmAnalogTagType and that the pointer address
specified by pt_AnalogVariable is non-zero.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Adds the grouped alarm and returns TRUE if all the checks above passed,
FALSE if otherwise.

Date Code 20241023 Programming Reference


340 EmailPlus
Classes

ClearRecipients (Method)
This method clears all recipients. This method returns FALSE and has no effect
when Busy is TRUE or Initialized is FALSE. After calling this method, at least
one recipient must be added before the next assertion of Send.

Return Value
IEC 61131 Type Description

BOOL TRUE if recipients are successfully cleared.

Processing
The ClearRecipients() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not


clear recipients.
➤ Returns FALSE if recipients cannot be cleared and sets an appropriate
error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if recipients are successfully cleared.

Initialize (Method)
This method configures the class for a configuration mode (Triggered Report
or Monitored Alarms), communication with the SMTP server, and logging.
After this method is called and Initialized asserts, these parameters cannot be
modified.

NOTE
Leave SmtpUserName and SmtpPassword blank if authentication is not
desired.

Inputs
Name IEC 61131 Type Description

EmailerType enum_EmailerType The type of emailer this EmailPlus instance


represents.

SmtpServerAddress STRING(253) Hostname or IPv4 address of the SMTP


server.

SmtpServerPort UINT(1..65534) TCP port of the SMTP server.

UseSmtps BOOL If TRUE, TLS encryption is required.

SmtpUsername STRING(255) Username for authentication to the SMTP


server. If not set, the class attempts to send
the email without authentication.

SmtpPassword STRING(255) Password for authentication to the SMTP


server. If not set, the class attempts to send
the email without authentication.

Programming Reference Date Code 20241023


EmailPlus 341
Classes

Name IEC 61131 Type Description

MaxAttachmentSize UINT(1..30) Maximum cumulative size (MB) of


attachments for an email.

LogRuntimeErrors BOOL If TRUE, logs runtime errors to the RTAC


SOE log.

Timeout UINT(1..65535) Time-out in seconds for sending an email.


This should be set appropriately according to
network latency and attachment size.

StartupDelay UDINT(1..30) Startup Delay in minutes to pause before


processing monitored alarms.

Return Value

IEC 61131 Type Description

BOOL TRUE if parameters were successfully set.

Processing
The Initialize() method does the following:

➤ If the Initialized class output is TRUE:


➢ Returns FALSE and does not affect class parameters.
➤ If the Initialized output is FALSE:
➢ Maps input variables to internal class variables.
➢ Returns FALSE if the parameters cannot be set and an appropriate
error message is set in RuntimeErrors.
➢ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➢ Returns TRUE and asserts the Initialized class output if no errors are
encountered.

Run (Method)
This method must be called every task cycle. It performs the sending of emails.

Processing
The Run() method does the following:

➤ Runs logging for the class.


➤ If MaintenanceMode is asserted, returns and does no work. While in
this mode, the Status output will contain a message indicating that
maintenance mode is active.
➤ If Busy is FALSE, Initialized is TRUE, Initialize() was called with
an EmailerType of enum_EmailerType.REPORT, and Send is asserted:
➢ Asserts Busy.
➢ Composes the email.

Date Code 20241023 Programming Reference


342 EmailPlus
Classes

➢ Attempts to send the email. If the total size of attachments is greater


than MaxAttachmentSize, the attachments will be broken up across
multiple emails.
➢ Clears the body and attachments list.
➢ If the email cannot be sent, sets any appropriate errors in
RuntimeErrors.
➢ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➢ Deasserts Busy.
➢ If the email was sent successfully, clears RuntimeErrors.
➤ If Busy is FALSE, Initialized is TRUE, and Initialize() was called
with an EmailerType of enum_EmailerType.ALARMS:
➢ If the startup delay is active, the Status output will indicate this state
along with a time remaining value. Once the startup delay expires,
regular processing commences.
➢ Each bootstrapped monitored alarm is run through its configured
pickup delay or dropout delay timer and if those expire, a rising- or
falling-edge trigger is activated.
➢ If an AssertMsg has been configured and a rising-edge trigger
was detected, an email body is constructed with a time stamp and
the assert message. If an optional analog has been configured for
OnAssert or OnEither mode, the optional analog message and tag
value are appended to the email body.
➢ If a DeassertMsg has been configured and a falling-edge trigger
was detected, an email body is constructed with a time stamp and
the deassert message. If an optional analog has been configured for
OnDeassert or OnEither mode, the optional analog message and tag
value are appended to the email body.
➢ The email body content and group number are added to an internal
queue and the next bootstrapped monitored alarm is checked for the
same criteria.
➢ After all monitored alarms have been processed, if the Busy output is
deasserted then email processing commences.
➢ The earliest queued monitored alarm email is removed from the
internal queue and the email body content is used to construct a new
email.
➢ Each bootstrapped recipients group mask is compared against the
group number associated with the alarm email. If there is a match, the
associated recipient is added to the email recipient list as a MAIL_TO
destination.
➢ The email is then queued to be sent and Busy asserts.
➢ Once Busy deasserts, the next queued alarm email is constructed and
sent.
➢ If multiple alarm emails are queued to be sent, the Status output will
indicate this with a remaining count.

Programming Reference Date Code 20241023


EmailPlus 343
Classes

➢ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➢ If the email was sent successfully, clears RuntimeErrors.
➤ If Busy is FALSE, Initialized is TRUE, and Initialize() was called
with an EmailerType of enum_EmailerType.EVENTS:
➢ Each bootstrapped event source is processed; if a rising edge is
detected on the New_Event_Detected input BOOL and the device
Device_OfflineStatus is FALSE, then additional processing is
completed.
➢ As part of the additional processing, the event time stamp is
constructed from the time-based inputs (e.g., Event_Hour) provided
on the bootstrap call. Each required input value along with any
optional input values provided are then captured and added to an
internal 'detected event' queue for later processing.
➢ Detected events are removed from the queue in the order they were
detected and added. If a record search is not already in progress, a
new one is initiated.
➢ If the configured Record_Type for this event source is CEV_FILE or
COMTRADE, the record search begins:
➣ Update the .Status output of the class with the record search
operation information, including the device name and time
remaining before a time-out is reached.
➣ Query the event database using the configured Device_Name as a
filter.
➣ Once the event list from the database is available, step through
each event. If the time stamp of an event from the database
matches that of the constructed time stamp from the time-based
inputs OR the reference number (e.g., 10001) shown in the
file name matches that of the Event_RefNum input, a match is
declared, the file name is stored, and the process moves on to
build an event summary email.
➣ If no match is found, the status is updated with the new time-out
values and another event list is queried from the database. This
process continues until the event record is located or the time
period specified by Record_Search_Timeout expires.
➢ If the configured Record_Type for this event source is
NO_EVENT_TYPE, the record search operation is skipped and the
process moves on to build an event summary email.
➢ Each bootstrapped recipient's group mask is compared against the
group number associated with the event source. If there is a match, the
associated recipient is added to the email recipient list as a MAIL_TO
destination.
➢ The mandatory portions of the event source are added to a formatted
email body (Event Time Stamp, IED Name, IED Location, Event
Type).
➢ Any available optional portions of the event source are appended
to the email body (FID, RID, RefNum, Fault Location, Current,
Frequency, Group, Targets, Shot, Shot 1P, Shot 3P).

Date Code 20241023 Programming Reference


344 EmailPlus
Classes

➢ If a record file name is available, the record is added as a file


attachment. If a record file name is not available but was desired
(Record_Type of CEV_FILE or COMTRADE), text is added to
the email body indicating the record could not be found in a timely
fashion and an error is logged to the RTAC SOE.
➢ The email is then queued to be sent and Busy asserts.
➢ Once Busy deasserts, the next queued detected event is processed per
the preceding procedure .

SetSender (Method)
This method sets the sending email address for outgoing email. This method
returns FALSE and has no effect when Busy is TRUE or Initialized is FALSE. A
sender must be set before asserting Send.

NOTE
Email addresses greater than 254 characters in length will be truncated.

Inputs

Name IEC 61131 Type Description

emailAddress STRING(254) The email address of the sender.

Return Value

IEC 61131 Type Description

BOOL TRUE if emailAddress is valid and the sender was set.

Processing
The SetSender() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not set
the sender.
➤ Checks that emailAddress contains only allowed characters.
➤ Sets emailAddress as the originating email address for outgoing emails.
➤ Returns FALSE if the sender was not set and sets an appropriate error in
RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the sender is successfully set.

SetSubject (Method)
Sets the subject of the email to the provided string. This method returns FALSE
when Busy is TRUE or Initialized is FALSE.

Programming Reference Date Code 20241023


EmailPlus 345
Troubleshooting

Inputs
Name IEC 61131 Type Description

subject STRING(255) The string to use as the subject of the email.

Return Value
IEC 61131 Type Description

BOOL TRUE if the subject line of the email was successfully populated.

Processing
The SetSubject() method does the following:

➤ If Busy is TRUE or Initialized is FALSE, returns FALSE and does not set
the subject.
➤ Copies the contents of subject into internal storage.
➤ Returns FALSE if the subject construction failed and sets an appropriate
error in RuntimeErrors.
➤ If the class instance is configured for logging, any runtime errors are
logged to the RTAC SOE log.
➤ Returns TRUE if the subject is successfully set.

Troubleshooting
The following steps can help identify issues that may prevent the library from
successfully sending emails.

➤ Confirm that the parameters set in the Initialize() method are


correct.
➤ Set LogRuntimeErrors to TRUE in the Initialize() method and
monitor the RTAC SOE log for information logged by the library during
runtime. These log items will be of Tag Type "EmailPlus".
➤ Visit the Diagnostics page of the RTAC web interface and select the Log
Files link. Download the file vcsmtpd.log and review the log information
for the most recent email attempt (at the bottom of the file).
➤ Check the log files of the SMTP server. Confirm that it is configured
to accept email from the RTAC's IP address, that the authentication
parameters are correct, and that the sender is allowed by the SMTP server.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Date Code 20241023 Programming Reference


346 EmailPlus
Examples

Configuring a Triggered Report EmailPlus Instance


Objective
The user wishes to issue an email to a fixed list of recipients containing the
RTAC's present system time and CPU burden when the lamp test button is
pressed.

Solution
The user can create a Triggered Report EmailPlus instance as shown in Code
Snippet 12.3:
Code Snippet 12.3 prg_TriggeredReport
PROGRAM prg_TriggeredReport
VAR
Client : class_EmailClient;
FirstScan : BOOL := TRUE;
BodyString : STRING(255);
SendTrig : R_TRIG;
System_Time : timestamp_t;
END_VAR

IF FirstScan THEN
Client.Initialize(EmailerType := enum_EmailerType.REPORT,
SmtpServerAddress := '192.168.1.2',
SmtpServerPort := 25,
UseSmtps := FALSE,
SmtpUsername := '',
SmtpPassword := '',
MaxAttachmentSize := 1,
LogRuntimeErrors := FALSE,
Timeout := 10,
StartupDelay := 1
);

Client.SetSubject('RTAC Report');
Client.SetSender('[email protected]');

FirstScan := FALSE;

Client.AddRecipient(enum_RecipientType.MAIL_TO,
'[email protected]');
Client.AddRecipient(enum_RecipientType.MAIL_TO,
'[email protected]');
END_IF

IF Client.Initialized THEN
SendTrig(CLK := SystemTags.Lamp_Test_Button_Status.stVal);
IF SendTrig.Q THEN
System_Time := SYS_TIME();
BodyString := CONCAT(DT_TO_STRING(System_Time.value.dateTime),
'$R$N');
BodyString := CONCAT(BodyString, 'CPU Burden Percent: ');
BodyString := CONCAT(BodyString,
DINT_TO_STRING(SystemTags.CPU_Burden_Percent.stVal));
Client.AppendToBodyFromString(BodyString,
EmailPlus.enum_BodyContentType.PLAIN_TEXT);
END_IF
Client.Send := SendTrig.Q;
END_IF

Client.Run();

Programming Reference Date Code 20241023


EmailPlus 347
Examples

Configuring a Monitored Alarms EmailPlus instance


Objective
The user wishes to automatically issue a time-stamped email any time the status
of the lamp test button changes (with a 500 ms pickup and dropout delay) and
include the RTAC's CPU Burden. A one-minute startup delay at RTAC boot time
is to be enforced.

Solution
The user can create a Monitored Alarms EmailPlus instance as shown in Code
Snippet 12.4:
Code Snippet 12.4 prg_MonitoredAlarm
PROGRAM prg_MonitoredAlarm
VAR
Client : class_EmailClient;
FirstScan : BOOL := TRUE;
END_VAR

IF FirstScan THEN
Client.Initialize(EmailerType := enum_EmailerType.ALARMS,
SmtpServerAddress := '192.168.1.2',
SmtpServerPort := 25,
UseSmtps := FALSE,
SmtpUsername := '',
SmtpPassword := '',
MaxAttachmentSize := 1,
LogRuntimeErrors := FALSE,
Timeout := 10,
StartupDelay := 1
);

Client.SetSubject('RTAC Report');
Client.SetSender('[email protected]');

FirstScan := FALSE;

Client.Bootstrap_GroupRecipient('[email protected]', 1023);
Client.Bootstrap_MonitoredAlarm(
TagType := EmailPlus.enum_MonitoredAlarmTagType.SPS_ALARM,
pt_Variable := ADR(SystemTags.Lamp_Test_Button_Status),
GroupNumber := 1,
AssertMsg := 'Lamp Test Button Asserted',
PUDelayTime := T#500MS,
DeassertMsg := 'Lamp Test Button Deasserted',
DODelayTime := T#500MS,
AnalogMode := enum_MonitoredAlarmAnalogMode.ON_EITHER,
AnalogTagType := enum_MonitoredAlarmAnalogTagType.INS_ANALOG,
pt_AnalogVariable := ADR(SystemTags.CPU_Burden_Percent),
AnalogMsg := 'CPU Burden Percent');

END_IF

Client.Run();

Configuring a Monitored Events EmailPlus Instance


Objective
The user wishes to monitor the status of SEL Protocol client devices and use the
New Event tags on these devices to construct Event Summary emails.

Date Code 20241023 Programming Reference


348 EmailPlus
Examples

Assumptions
This example assumes the following:

➤ An SEL Protocol client named SEL_421_1_SEL has been added to the


project.
➤ The SEL Protocol client has the default value of the POU pin
Enable_New_Event_Filtering set to TRUE.
➤ All tags on the SEL Protocol client History - New Event tab are
enabled.
➤ The SEL Protocol client is configured for CEV event collection.
➤ The SEL Protocol client is configured for 'COMNAME' format event
naming.

Solution
The user can create a Monitored Events EmailPlus instance as shown in Code
Snippet 12.5:
Code Snippet 12.5 prg\_MonitoredEvents
PROGRAM prg_MonitoredEvents
VAR
Client : class_EmailClient;
FirstScan : BOOL := TRUE;
END_VAR

IF FirstScan THEN
Client.Initialize(EmailerType := enum_EmailerType.EVENTS,
SmtpServerAddress := '192.168.1.2',
SmtpServerPort := 25,
UseSmtps := FALSE,
SmtpUsername := '',
SmtpPassword := '',
MaxAttachmentSize := 1,
LogRuntimeErrors := FALSE,
Timeout := 10,
StartupDelay := 1
);

Client.SetSubject('Event Summary Report');


Client.SetSender('[email protected]');

FirstScan := FALSE;

Client.Bootstrap_GroupRecipient('[email protected]', 1023);
Client.Bootstrap_EventSource(
IED_Name := 'My Test 421',
IED_Location := 'The Test Substation',
Device_Name := 'SEL_421_1',
GroupNumber := 1,
Record_Type := EmailPlus.FileIo.enum_event_type.CEV_FILE,
pt_Device_OfflineStatus := ADR(SEL_421_1_SEL_POU.Offline),
pt_New_Event_Detected := ADR(SEL_421_1_SEL_POU.New_Event_Detected),
pt_Event_Year := ADR(SEL_421_1_SEL.NEW_EVENT_YEAR.stVal),
pt_Event_Month := ADR(SEL_421_1_SEL.NEW_EVENT_MONTH.stVal),
pt_Event_Day := ADR(SEL_421_1_SEL.NEW_EVENT_DAY.stVal),
pt_Event_Hour := ADR(SEL_421_1_SEL.NEW_EVENT_HOUR.stVal),
pt_Event_Minute := ADR(SEL_421_1_SEL.NEW_EVENT_MIN.stVal),
pt_Event_Second := ADR(SEL_421_1_SEL.NEW_EVENT_SEC.stVal),
pt_Event_Msec := ADR(SEL_421_1_SEL.NEW_EVENT_MSEC.stVal),
pt_Event_Type := ADR(SEL_421_1_SEL.NEW_EVENT_EVENT.strVal),
pt_Event_FID := ADR(SEL_421_1_SEL.NEW_EVENT_FID.strVal),
pt_Event_RID := 0,

Programming Reference Date Code 20241023


EmailPlus 349
Examples

pt_Event_RefNum := ADR(SEL_421_1_SEL.NEW_EVENT_REF_NUM.stVal),
pt_Event_Current := ADR(SEL_421_1_SEL.NEW_EVENT_CURR.instMag),
pt_Event_Freq := ADR(SEL_421_1_SEL.NEW_EVENT_FREQ.instMag),
pt_Event_Group := ADR(SEL_421_1_SEL.NEW_EVENT_GROUP.stVal),
pt_Event_Location := ADR(SEL_421_1_SEL.NEW_EVENT_FAULT_LOC.instMag),
pt_Event_Shot := 0,
pt_Event_Shot_1P := 0,
pt_Event_Shot_3P := 0,
pt_Event_Targets := ADR(SEL_421_1_SEL.NEW_EVENT_TARGETS.strVal),
Record_Search_Timeout := T#5M);
END_IF

Client.Run();

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 1 3

FTPSync
Introduction
The FTPSync library allows a user to specify content to be monitored and
synced with a File Transfer Protocol (FTP) server automatically. This library
monitors specified folders and IEDs to detect when files are added or modified
and sends those files to the FTP server.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.
// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_FTPSyncObject"
myFTPSyncObject := otherFTPSyncObject;

// This is fine
someVariable := myFTPSyncObject.value;
// As is this
pt_myFTPSyncObject := ADR(myFTPSyncObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, Global Variable Lists, or VAR_STAT sections).
➤ The FTP server must have a user defined for use by the RTAC with read,
write, delete, and append permissions for files in the specified remote
folder.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R146-V0 or later.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Date Code 20241023 Programming Reference


352 FTPSync
Enumerations

struct_SyncStatus
This structure contains the sync status for a single monitored IED or directory.

Name IEC 61131 Type Description

DirectoryName STRING(255) The directory being monitored.

LastSyncSuccessful BOOL TRUE if the last sync was successful.

LastError STRING The last error encountered for the directory.

LastSyncTime DT The time of the last successful sync.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_EventType
The type of event to monitor for a given IED.

Enumeration Description

CEV SEL Compressed ASCII format event report.

COMTRADE Binary COMTRADE format event report.

MMS_COMTRADE Binary COMTRADE format event report collected via MMS


protocol.

Classes
class_FtpSync (Class)
This class monitors directories and collected CEV and COMTRADE events for
new or modified files and sends those files to an FTP server on the specified
interval.

Inputs
Name IEC 61131 Description

EnableSFTP BOOL If TRUE, the client uses SFTP.

FtpServerAddress STRING(15) IP address of the FTP server. Must be in the form XXX.XXX.XXX.XXX, where XXX
is an integer between 0 and 255.

FtpServerPort UINT The TCP port number (0-65535) of the ftp server.

UserName STRING(32) Username for the FTP server. Must be 1 to 32 characters and contain only
alphanumeric characters, "." (dot), "-" (dash), "_" (underscore), or "@" (at).

Password STRING(32) Password for the FTP Server. Must be 1 to 32 characters and may contain all
printable ASCII characters, excluding the single quote, double quote, and backtick.

Programming Reference Date Code 20241023


FTPSync 353
Classes

Name IEC 61131 Description

RemoteTargetDirectory STRING(100) The target directory where the RTAC replicates the monitored RTAC directory
structure and places files and events. Must be 1 to 100 characters and may contain
all printable ASCII characters, excluding the single quote and double quote.

SyncInterval TIME The interval at which monitored directories and IEDs are checked for updates. The
range is 1 to 60 minutes. Or set to 0 to disable periodic sync.

SyncTimeout UDINT The maximum time in seconds allowed for a file transfer operation. Defaults to 30.
Minimum is 1.

SyncTrigger BOOL Triggers a file sync in lieu of waiting for the sync interval to expire. May be a
Boolean variable or Boolean expression and is not required.

LogRuntimeErrors BOOL If TRUE, the library logs runtime errors in the RTAC Sequence of Events (SOE)
log.

SyncInfoDirectory STRING(100) Local directory for use by this class instance only. If the directory does not exist,
the RTAC creates it. Do not modify the directory or its contents. Must be 1 to 100
characters and may contain all printable ASCII characters between 16#20 (Space)
and 16#7E (~), excluding ", ', :, <, %, >, ?, \, and |. Cannot contain any file path
manipulation character sequences (//, /./, /../)

Outputs
Name IEC 61131 Description

Initialized BOOL This pin asserts when the class finishes initialization. The sync interval and SyncTrigger are
ignored while this pin is deasserted.

FileSyncInProgress BOOL This pin is TRUE while the FTP client is sending files to the FTP server.

InvalidInputPin STRING Lists an incorrectly configured input pin.

RunTimeErrors STR Lists any runtime errors the FTP client encounters.

NumSyncFolders UINT The number of directories and IEDs being monitored.

Processing
➤ Once Run() has been called, any further changes to the class inputs are
ignored.
➤ Upon the first call of Run(), the class begins the initialization process,
which includes creating the monitored directory structure on the remote
FTP server. If the server does not allow directory creation, the sync fails.
Once initialization has finished, the Initialized pin asserts.
➤ On each sync interval expiration or sync trigger assertion, the RTAC
uploads any new or updated monitored content that has not been synced
into the appropriate remote target directory. For example, events from
an IED named SEL_351S_1 on the RTAC in the directory /EVENTS/
CEV/SEL_351S_1 are placed in the directory <RemoteTargetDirectory>/
EVENTS/CEV/SEL_351S_1 on the server.
➤ If a monitored directory contains additional subdirectories, these
directories are ignored. Only files in the specified directories are
monitored.

Date Code 20241023 Programming Reference


354 FTPSync
Classes

➤ File names beginning with a period are ignored.


➤ If the FTP client cannot send a file to the FTP server, it populates the
RunTimeErrors output pin with the error message. The FTP client then
attempts to sync any other directories and IEDs to the server. The client
tracks the state of the directory or IED that could not be fully synced and
tries again on the next sync interval.

bootstrap_AddMonitorDirectory (Method)
This method adds a directory to be monitored. This method only adds directories
to be monitored if called prior to the first Run() method call.

Inputs

Name IEC 61131 Type Description

directoryName STRING(100) The directory to be monitored. Must be 1 to 100 characters and may contain all printable
ASCII characters between 16#20 (Space) and 16#7E (~), excluding ", ', :, <, %, >, ?, \, and |.
Cannot contain any file path manipulation character sequences (//, /./, /../)

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the directory is successfully listed for monitoring.

bootstrap_AddMonitorEvent (Method)
This method adds an IED to monitor for collected events to sync. This method
only adds IEDs to be monitored if called prior to the first Run() method call.

Inputs

Name IEC 61131 Type Description

iedName STRING(100) The IED to be monitored for events.

eventType enum_EventType The collected event format (CEV or COMTRADE).

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the IED is successfully listed for monitoring.

bootstrap_AddMonitorEventByPath (Method)
This method allows any events within the /EVENTS folder to be synced that
may not be available via bootstrap_AddMonitorEvent(), and requires the
full path to the events, beginning with /EVENTS. This method only adds IEDs
to be monitored if called prior to the first Run() method call.

Programming Reference Date Code 20241023


FTPSync 355
Examples

Inputs

Name IEC 61131 Type Description

iedEventPath STRING(100) The full path to be monitored for events.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the IED is successfully listed for monitoring.

GetSyncStatus (Method)
This method returns the sync status for a given directory or IED.

Inputs

Name IEC 61131 Type Description

statusIndex UINT A number between 1 and NumSyncFolders,


corresponding to a directory or IED being
monitored.

Return Value

IEC 61131 Type Description

struct_SyncStatus The current sync status for the indicated directory or IED.

Run (Method)
This method performs directory and IED monitoring. Call this method once each
processing cycle after configuration is complete.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Syncing Files and Events With class_FtpSync


Objective
You want to sync files in several directories and collected events from several
IEDs to an FTP server.

Date Code 20241023 Programming Reference


356 FTPSync
Examples

Assumptions
This example assumes the following:
➤ The RTAC project contains an SEL client collecting CEV events called
SEL_Client, a Modbus client collecting COMTRADE events from a
GE relay called GE_Client, an Axion module generating COMTRADE
events called SEL_CTPT_1, and a Recording Group instance generating
COMTRADE events called RECORDINGGROUP1.
➤ The RTAC has directory Dir1 with file File1.txt in it and directory Dir2
with file File2.txt in it.
➤ An FTP server exists with IP address 192.168.1.10, and the RTAC is
networked to communicate with it.
➤ The FTP server has an existing user with username RTACUser and the
password TAIL, with read, write, delete, and append file permissions in
the FTPFiles directory.

Solution
A program can be created to run an instance of class_FtpSync to sync the files
and events, as shown in Code Snippet 13.1.
Code Snippet 13.1 prg_FTPSync
PROGRAM prg_FTPSync
VAR
FtpSync : class_FtpSync;
FirstScan : BOOL := TRUE;
END_VAR

IF FirstScan THEN
FtpSync.EnableSFTP := FALSE;
FtpSync.FtpServerAddress := '192.168.1.10';
FtpSync.FtpServerPort := 21;
FtpSync.UserName := 'RTACUser';
FtpSync.Password := 'TAIL';
FtpSync.RemoteTargetDirectory := 'FTPFiles';
FtpSync.SyncInterval := T#5M;
FtpSync.LogRuntimeErrors := TRUE;
FtpSync.SyncInfoDirectory := 'FTPSync_1';

FtpSync.bootstrap_AddMonitorDirectory('/Dir1');
FtpSync.bootstrap_AddMonitorDirectory('/Dir2');
FtpSync.bootstrap_AddMonitorEvent('SEL_Client', enum_EventType.CEV);
FtpSync.bootstrap_AddMonitorEvent('GE_Client', enum_EventType.COMTRADE);
FtpSync.bootstrap_AddMonitorEvent('SEL_CTPT_1',
enum_EventType.COMTRADE);
// All Recording Group events share a common folder
FtpSync.bootstrap_AddMonitorEventByPath('/EVENTS/COMTRADE');

FirstScan := FALSE;
END_IF

FtpSync.Run();

Using Public Key Authentication for SFTP File Transfer


NOTE
Public key authentication is available in firmware versions R147-V0 and above.

Programming Reference Date Code 20241023


FTPSync 357
Examples

Public key authentication can be used with SFTP as an alternative to providing


a password. By placing the RTAC's public SSH key on the SFTP server,
the SFTP server can authenticate the RTAC for file transfer and encrypt the
communication.

Assumptions
This example assumes the following:

➤ Files will be sent over SFTP.


➤ An SFTP server exists with IP address 192.168.1.10, and the RTAC is
networked to communicate with it.
➤ The SFTP server allows connections on Port 22.
➤ The RTAC has a directory FilesToSync with File1.txt in it.
➤ The SFTP server has an existing user with username RTACUser
with read, write, delete, and append file permissions in the FTPFiles
directory, and the FTPFiles directory is in the FTP root. The password
for the user can be set to anything (because it will not be used) or
left blank if required as such by the SFTP server. Consult the SFTP
server's documentation pertaining to public key authentication for more
information.

Solution
First, the RTAC's public SSH key must be prepared. In the RTAC web interface,
select SSH Keys under Security. Copy the contents of the Host Key text box
between "—– BEGIN SSH2 PUBLIC KEY —–" and "—– END SSH2 PUBLIC
KEY —–".

Figure 13.1 Copying the RTAC Host SSH Key

Paste the copied text into an empty text file (e.g., in Notepad++). At the
beginning of the file, type "ssh-rsa", followed by a space. At the end of the file,
type a space, followed "RTACUser@", followed by the RTAC hostname. To find
the RTAC hostname, select Interface under Network in the web interface.

Date Code 20241023 Programming Reference


358 FTPSync
Examples

Figure 13.2 Locating the RTAC Hostname

The text should all be on a single line and look similar to this (shown with line
wrapping enabled):

Figure 13.3 Example of Prepared Host Key

At this point, the host key can be copied to the SFTP server. The steps involved
vary depending on the SFTP server. Consult the SFTP server's documentation
pertaining to public key authentication for more information.

Once the key is properly configured and placed on the SFTP server, a program
can be created to run an instance of class_FtpSync to sync the files to the SFTP
server, as shown in Code Snippet 13.2. Note the use of "HOST_SSH_KEY" as
the password. This causes FTPSync to use public key authentication.
Code Snippet 13.2 prg_PublicKeyAuth
PROGRAM prg_PublicKeyAuth
VAR
Syncer : class_FtpSync;
FirstScan : BOOL := TRUE;
END_VAR

IF FirstScan THEN
Syncer(EnableSFTP := TRUE,
FtpServerAddress := '192.168.1.10',
FtpServerPort := 22,
UserName := 'RTACUser',
// 'HOST_SSH_KEY' here forces use of public key authentication
Password := 'HOST_SSH_KEY',
RemoteTargetDirectory := '/FTPFiles',
SyncInterval := T#1M,
LogRuntimeErrors := TRUE,
SyncInfoDirectory := '/SyncInfo',
);

Syncer.bootstrap_AddMonitorDirectory('/FilesToSync');

FirstScan := FALSE;
END_IF

Syncer.Run();

Programming Reference Date Code 20241023


S E C T I O N 1 4

FallingConductorProtection
Introduction
This library is intended to provide systems to detect and preemptively mitigate
dangerous conditions in modern electric power systems caused by downed
conductors. The classes, structures, functions, and function blocks in this
library should be used as protection systems designed to operate on a wide-
area network, coordinating multiple protective devices or other IEDs capable of
taking protective action.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R147 or later.

Global Constants
The library applies the following global constants which are useful in providing
common constants and references.

FallingConductorProtection Global Constants


Name IEC 61131 Type Description

g_NO_REFERENCE_VOLTAGE CMV Constant reference for use as a phase voltage input in the
bootstrap_Switch method to indicate that the switch should instead
use the voltage associated with the zone.

g_NO_REFERENCE_TRIP_CONTROL SPS Constant reference for use in the bootstrap_Switch method to


indicate that the switch is not applicable for tripping control.

g_BREAKER_CLOSED SPS Constant reference for use in the bootstrap_Switch method to


indicate that the switch does not provide a breaker status indication
(i.e., 52A contact) and thus should always be assumed to be closed.

g_NEVER_DISABLED_SWITCH SPS Constant reference for use in the bootstrap_Switch method to


indicate that the switch will never be disabled (i.e., it will never need
to be excluded from FCP trip operations).

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Date Code 20241023 Programming Reference


360 FallingConductorProtection
Enumerations

enum_AffirmativeDetectionType
The enum_AffirmativeDetectionType enumeration is used as an input for the
FallingConductorProtection class implemented in this library to provide a means
of describing the number of detection methods required by the class to assert a
trip command.

Enumeration Description

MONITORING_ONLY No protective response (trip commands) should be applied; the class should provide
monitoring functionality only.

SINGLE_METHOD_PICKUP FallingConductorProtection schemes may intervene with at least one positive


detection method.

DOUBLE_METHOD_PICKUP FallingConductorProtection schemes may intervene with at least two positive


detection methods.

TRIPLE_METHOD_PICKUP FallingConductorProtection schemes may intervene with at least three positive


detection methods.

QUADRUPLE_METHOD_PICKUP FallingConductorProtection schemes may intervene with at least four positive


detection methods.

QUINTUPLE_METHOD_PICKUP FallingConductorProtection schemes may intervene with at least five positive


detection methods.

MATCH_ENABLED_METHOD_PICKUP The number of required detection methods to support a FallingConductorProtection


intervention (trip commands) must equal the number of enabled protection methods.

enum_SwitchType
The enum_SwitchType enumeration describes the possible variations a switch
in a FallingConductorProtection scheme may be described with to permit the
protection algorithms to make control and blocking determinations.

Enumeration Description

BREAKER_SWITCH A switch associated with an IED that can act on received trip controls and disconnect the zone from
the substation feeder.

FUSE_TAP A fused tap off of a line that is capable of breaking a circuit but not receiving trip controls. Typically
used to divide a circuit into discrete zones of FC protection. The FUSE_TAP designation should be
assigned to the first switch connected in series to the fuse in the segmented zone. In the event of a
detected blown fuse for a given zone, a switch configured as a FUSE_TAP is flagged as a possible
source of the blown fuse.

NON_OPERATIONAL A switch or sensory point on a circuit that is not capable of breaking a circuit as part of a
FallingConductorProtection scheme.

SUBSTATION_BREAKER A switch associated with an IED located at a substation whose voltage inputs are connected to Bus
PTs that are not capable of generating falling conductor events. These switches can act on received
Trip signals for a falling conductor detected in their zone but cannot make trip determinations on their
own.

FUSE_SOURCE A switch located on the boundary of a zone of FC protection on the source side of a FUSE_TAP.
This switch will not execute any FallingConductorProtection algorithms because blown fuse
conditions located in the associated child zone and detected by the associated FUSE_TAP could be
misinterpreted as FallingConductor methods.

Programming Reference Date Code 20241023


FallingConductorProtection 361
Structures

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

struct_AdvancedSettings
The struct_AdvancedSettings structure is a collection of advanced settings
for class_FallingConductorMonitor that have default values but which are
adjustable by the end user.

Name IEC 61131 Type Description

BootDelay TIME Time for which the RTAC waits before starting
FallingConductorProtection computation (defaults to 1 min)

dVdtReset TIME Time after which dV/dt pickup detection resets (defaults to
300 ms)

V0MagReset TIME Time after which zero-sequence voltage magnitude-based pickup


detection resets (defaults to 300 ms)

V0AngReset TIME Time after which zero-sequence voltage angle-based pickup


detection resets (defaults to 300 ms)

V2MagReset TIME Time after which negative-sequence voltage magnitude-based


pickup detection resets (defaults to 300 ms)

V2AngReset TIME Time after which negative-sequence voltage angle-based pickup


detection resets (defaults to 300 ms)

DetectionOverlapDelay TIME Length of time for which any detection method pickup will remain
asserted to allow concurrent detection (defaults to 300 ms)

UnconditionalDetectionResetDelay TIME Length of time between the assertion of a detection method and its
unconditional reset, forcing reevaluation of the detection criteria
(defaults to 1 s)

BlockingFaultDropOutTime TIME Time after which blocking fault detection should prohibit falling
conductor algorithm execution (defaults to 1 s)

TripSignalAssertionPeriod TIME Time after which Trip logic will deassert an output control point
used to trip a switch (defaults to 1 s)

RoundTripTimeSwitchAvailability TIME Time after which switch round-trip time monitor will indicate
switch unavailability; may be set to zero to ignore round-time as
part of switch availability (defaults to 5 s)

AvailabilityPickupTime TIME Time to wait before asserting the switch availability status (defaults
to 100 ms)

AvailabilityDropoutTime TIME Time to wait before de-asserting the switch availability status
(defaults to 100 ms)

BlownFuseQualificationTime TIME Time after which the criteria indicating a potentially blown fuse is
confirmed and statuses will be updated to reflect the blown fuse
(defaults to 100 ms)

DerivativeResetThreshold UINT Percent of nominal voltage where sequence component and


derivative calculations will be reset for switches during a voltage
excursion (defaults to 15%)

DerivativeFilterLength INT Channel Derivative Filter Length (as defined by


ChannelMonitoring.fb_ChannelDerivative.Filter-Length) (defaults
to 5)

Date Code 20241023 Programming Reference


362 FallingConductorProtection
Structures

Name IEC 61131 Type Description

V0Min REAL Minimum zero-sequence magnitude required before angle-based


zero-sequence voltage detection may activate (defaults to 500)

V2Min REAL Minimum negative-sequence magnitude required before angle-


based negative-sequence voltage detection may activate (defaults
to 1000)

VPhaseZeroDeadband REAL Value below which phase voltages will be clamped to zero for
FallingConductorProtection detection algorithms (defaults to 0.99)

BlownFuseVoltageThreshold REAL Percent of nominal voltage below which phase voltages will be
considered for blown fuse detection (defaults to 60%)

MaxSensorMagDifference REAL Maximum allowable percent difference between two switch


sensory voltage input magnitudes for faulty sensor detection
(defaults to 10%)

FaultySensorPickupTime TIME Time to wait before qualifying a faulty sensor condition (defaults
to 60 ms)

FaultySensorDropOutTime TIME Time to wait before clearing a faulty sensor condition (defaults to
500 ms)

BreakerStatusTransitedTime TIME Time to declare a switch's 52A status recently transited (defaults to
1000 ms)

BreakerStatusBadQualityBlockTime TIME Time after the 52A quality indication transitioned to invalid during
which to inhibit breaker status detection (defaults to 500 ms)

ProtPickupMessageCount UINT Synchrophasor message count required before asserting that a


falling conductor event has occurred (defaults to 3 messages)

struct_DetectedType
The struct_DetectedType structure is used to monitor the various
detection methods for each of the switches and zones composing
a circuit for the FallingConductorProtection detection algorithm
(class_FallingConductorMonitor).

Name IEC 61131 Type Description

dVdtDetect BOOL dV/dt detected

V0MagDetect BOOL V0 Mag detected

V2MagDetect BOOL V2 Mag detected

V0AngDetect BOOL V0 Angle detected

V2AngDetect BOOL V2 Angle detected

struct_ProtTypeEnable
The struct_ProtTypeEnable structure is used to identify the enabled detection
methods for an individual zone.

Name IEC 61131 Type Description

dVdtEnable BOOL dV/dt falling conductor detection method enabled

V0MagEnable BOOL V0Mag falling conductor detection method enabled

Programming Reference Date Code 20241023


FallingConductorProtection 363
Structures

Name IEC 61131 Type Description

V2MagEnable BOOL V2Mag falling conductor detection method enabled

V0AngEnable BOOL V0Ang falling conductor detection method enabled

V2AngEnable BOOL V2Ang falling conductor detection method enabled

struct_SwitchStatus
The struct_SwitchStatus structure represents all of the input and calculated
quantities that are respectively evaluated for each switch.

Name IEC 61131 Type Description

SwitchName STRING(255) Name of the associated switch

FaultDetect struct_DetectedType Structure defining the status of each of the


detection methods for the switch

VA CMV Phase A voltage

VB CMV Phase B voltage

VC CMV Phase C voltage

IA CMV Phase A current

IB CMV Phase B current

IC CMV Phase C current

V2 CMV Negative-sequence voltage

V0 CMV Zero-sequence voltage

I2 CMV Negative-sequence current

I0 CMV Zero-sequence current

dVAdt MV Rate of change for Phase A voltage

VAChangeAlert BOOL Derivative alert indicator for VA

dVBdt MV Rate of change for Phase B voltage

VBChangeAlert BOOL Derivative alert indicator for VB

dVCdt MV Rate of change for Phase C voltage

VCChangeAlert BOOL Derivative alert indicator for VC

dV0dt MV Rate of change for zero-sequence voltage

V0ChangeAlert BOOL Derivative alert indicator for zero-sequence


voltage

dI0dt MV Rate of change for zero-sequence current

I0ChangeAlert BOOL Derivative alert indicator for zero-sequence


current

CommsOK BOOL PMU/IED communications are OK

FCDetectionFlag BOOL A Falling Conductor scenario was detected on


this switch and a trip was issued

ExcludeSwitch BOOL Indicator that the switch is presently excluded


from FCP operation (i.e., Disabled)

Date Code 20241023 Programming Reference


364 FallingConductorProtection
Structures

Name IEC 61131 Type Description

Switch52AStatus BOOL The state of the switch's 52A contact status

TripControlPointOut BOOL The state of the output control point


controlled by the switch

BlockingFault BOOL A "traditional" (overcurrent) fault has been


observed and is blocking further execution

BlownFuse BOOL A blown fuse has been detected and is


blocking further execution

FaultySensor BOOL A faulty sensor has been detected and is


blocking further execution

Availability BOOL Switch availability; a combined result of


a) FCP-Enabled, b) Offline status, c) RTT
updates, d) high-accuracy time

AlgorithmsEnabled BOOL Indicator that FallingConductorProtection


detection algorithms are enabled for this
switch

LastRoundTripTime UDINT The most recent network round-trip


communication time for the specified switch
(in milliseconds)

MaxRoundTripTime UDINT The greatest network round-trip


communication time observed for the
specified switch (in milliseconds)

LastRoundTripUpdate dateTime_t The last time the round-trip time was updated

struct_ZoneStatus
The struct_ZoneStatus structure represents all of the calculated quantities that
are respectively evaluated for each zone.

Name IEC 61131 Type Description

ZoneName STRING(255) Name of the associated zone

FaultType struct_DetectedType Structure defining the status of each of the


detection methods for the zone

TripIssued BOOL Indicator that a trip signal has been issued

ZoneBlockingFault BOOL Indicator that a blocking condition has been


detected in the zone

NumSwitches UINT Monitor to identify how many switches are


members of the zone

SendTripSignal BOOL Indicator that the zone requires a trip

EnabledProtection struct_ProtTypeEnable Structure defining the enabled


FallingConductorProtection methods for the
zone

PossibleBlownFuse BOOL Indicator that the zone may contain one or


more switches with blown fuses

BlownFuse BOOL Indicator of blown fuse in the zone

Programming Reference Date Code 20241023


FallingConductorProtection 365
Classes

Classes
The FallingConductorProtection library provides classes designed to be
implemented as monitoring or protection systems related to power system
falling or downed conductors.

class_FallingConductorMonitor (Class)
The falling conductor monitor is an algorithm designed to utilize distributed,
high-accuracy, time-aligned system measurements to detect falling electric
conductors. It does this by interpreting parameters that describe the electrical
phenomena linked to events where an electrical conductor is severed and
begins to fall. When an overhead conductor breaks, there is typically a delay of
approximately 1.37 seconds before the conductor contacts the earth. This delay
provides an opportunity for the algorithm to detect the condition and react to
isolate the conductor.

Synchrophasor measurements from phasor measurement units (PMUs) located


at power distribution circuits are relayed to RTACs serving as phasor data
concentrators (PDCs) for time alignment. The time-aligned data is monitored in
order to detect falling conductor faults that may occur in the distribution circuits.
Under steady-state operating conditions, with no faults in the circuit, the voltage
sequence components along with derivatives of the phase voltages are calculated
in the PDC RTAC. These calculated quantities are monitored for abnormality in
case of falling conductor faults. Methods for detecting falling conductors include
the following:

1. Voltage change (i.e., dV/dt) method


2. Zero-sequence voltage (i.e., V0) magnitude method
3. Zero-sequence voltage (i.e., V0) angle method
4. Negative-sequence voltage (i.e., V2) magnitude method
5. Negative-sequence voltage (i.e., V2) angle method

Specific Considerations
➤ Use of this class dictates that the RTAC upon which it is running uses
a cycle-time to be set at approximately one-third of the IEEE C37.118
message period.
➤ The number of streaming data sources employed by this class will
significantly impact the overall performance and execution timing; thus,
it may dictate which processing platform should be used for satisfactory
results.
➤ To avoid any implementation challenges with achieving high performance
timing with the class, use of the SEL-3555 and/or SEL-3560 platforms is
recommended.
➤ All SOE entries generated by this class will be associated with the
logging category of "FallingConductor".

Date Code 20241023 Programming Reference


366 FallingConductorProtection
Classes

Enabled Detection Methods


Falling conductor detection methods are enabled at runtime at the class level
via five inputs (EnableVoltageChangeDetection, EnableV0MagnitudeDetection,
EnableV2MagnitudeDetection, EnableV0AngleDetection, and
EnableV2AngleDetection can be manipulated during normal operation to
dynamically disable/enable the individual methods) and at the zone level
when the zone is bootstrapped. These enables are combined at the individual
zone level when executing detection algorithms such that if either control is
deasserted, the algorithm will not process the specific detection method for the
zone. This format provides additional flexibility for detection between zones,
allowing different zones to enable subsets of the class's enabled methods to
provide tailored detection where needed while maintaining sensitivity. The
operating logic describing this behavior is described in Figure 14.1.

Figure 14.1 Detection Method Accumulation

Following qualification, a trip may be issued, which will be sent to all operable
switches in a zone if they are marked as available and one or more detection
methods are enabled, as shown in the control logic in Figure 14.2

Figure 14.2 Trip Control Point Logic

Programming Reference Date Code 20241023


FallingConductorProtection 367
Classes

Detection Blocking Criteria


To provide security in tripping operations, and to prevent misoperation, the
FallingConductorProtection algorithm employs several blocking mechanisms.
If any of these blocking criteria are met, the AlgorithmsEnabled class output
will deassert and falling conductor methods are no longer calculated. A logic
diagram for the various requirements needed to enable the algorithms is shown
in Figure 14.3. Switches that do not report a good availability status are not
evaluated for any blocking conditions; therefore, they will not contribute to
enabling or disabling FCP.

Figure 14.3 Detection Blocking Logic

Faulty Sensor Detection


The condition of a faulty sensor arises when the voltage measurements on
both sides of a closed switch do not match one another within a specified
tolerance. Faulty sensor detection only applies with switches of type
BREAKER_SWITCH, and detection of such behavior occurs only when two
switch instances bootstrapped to a class_FallingConductorMonitor (with the
bootstrap_Switch (Method) described later) share all of these common criteria:

➤ Breaker status (52A)


➤ Trip control point
➤ IED Offline status

To qualify as a faulty sensor condition, these switch instances must exhibit


voltage magnitudes differing by a value greater than a percentage of the
nominal voltage specified by the advanced setting MaxSensorMagDifference.
Once a voltage magnitude difference has been detected, a pickup delay
specified by the advanced setting FaultySensorPickUpTime is applied before
declaring the condition. If the 52A breaker status has recently transited, faulty
sensor detection is inhibited to prevent false positive detections that can
occur during this transitory state. Once a faulty sensor condition occurs, the
FaultySensorAlarm class output asserts and a descriptive message is loaded
into FaultySensorDesc to indicate which pair of switches was involved. A per-
switch FaultySensor indication is available in the struct_SwitchStatus associated

Date Code 20241023 Programming Reference


368 FallingConductorProtection
Classes

with the involved switches. Once the faulty sensor condition is resolved, both
indications remain latched until the time period specified by the advanced
setting FaultySensorDropOutPeriod expires. This faulty sensor detection is
shown in Figure 14.4.

NOTE
Although capable of monitoring for faulty sensor discrepancies to prevent
false falling conductor trip commands, this class is not explicitly designed with
the intent of monitoring for sensory failure and should not be applied for such
applications. Such applications should, instead, use logic as applied with the
class_StreamingCTPTMonitor in the ConditionMonitoring Library.

Figure 14.4 Faulty Sensor Logic

Breaker Status Transited


If the switch's circuit breaker status has recently changed state (open to closed or
closed to open), a Breaker Status Transited indication is declared and is used to
block the following detections:

➤ Faulty Sensor
➤ dI0/dt Spike
➤ Blown Fuse

These detections are blocked for the time period specified by the advanced
setting BreakerStatusTransitedTime. If the quality status associated with the
52A status tag changes to bad/invalid, then detection of a Breaker Status
Transition is inhibited for the time period specified by the advanced setting
BreakerStatusBadQualityBlockTime

Programming Reference Date Code 20241023


FallingConductorProtection 369
Classes

Figure 14.5 Breaker Status Transited Logic

Traditional Protection Blocking


This protection system is intended to be used as a distributed scheme, and
thus, it relies on localized protective devices to perform detection and tripping
for traditional protection measures such as phase and ground overcurrent.
Ultimately, this operation manifests itself as a blocking scheme wherein the
falling conductor algorithm monitors for conditions that describe traditional
faults. Each switch provides means to configure an optional set-point value for
phase and ground overcurrent that is used as a pickup and compared against the
IA/IB/IC and I0 quantities, respectively. When these conditions are detected,
the falling conductor algorithm blocks ongoing detection of falling conductor
phenomena to allow traditional protection schemes to clear existing faults. The
set points for overcurrent detection are configured with the PhaseOCPickup and
GroundOCPickup input values in the bootstrap_Switch method. Leave these
values at 0 to disable overcurrent detection.

The I0 quantity is also used in a rate-of-change calculation to determine dI0/


dt; with switches of type SUBSTATION_BREAKER, this quantity is used to
create a dI0dtSpikeAlarm condition that is also considered to be a blocking fault.
Similar to Faulty Sensor detection, if the circuit breaker associated with the
switch has recently changed state, dI0/dt spike detection is blocked.

In addition to the overcurrent pickup values (usually only configured on the


primary feeder in a circuit) each IED also provides a FAULT status available in
its incoming PMU data. This status is typically sourced from the FAULT logic
equation in the IED and is another means of remotely signaling that the field
IED has detected a traditional overcurrent scenario. Another condition that is
monitored for and used for blocking is the presence of an external disturbance;
this would manifest itself as a given falling conductor detection method picking
up a switch defined as a SUBSTATION_BREAKER. In this scenario, the
disturbance can be assumed to be upstream from the distribution network being
monitored for falling conductor conditions, and thus the falling conductor
algorithms are blocked to allow for upstream protection to act upon the fault.

Date Code 20241023 Programming Reference


370 FallingConductorProtection
Classes

After these faults have been cleared by traditional protective systems, falling
conductor detection will be unblocked to allow for falling conductor protection.
This blocking scheme is illustrated in Figure 14.6 above.

Figure 14.6 Blocking Fault Alarm Logic

Blown Fuse Detection


A final mechanism used to block falling conductor protection from operating
falsely is blown fuse detection. This determination is evaluated when all
switches in a zone report a loss of potential on an identical voltage phase for
a time period greater than the blown fuse qualification timer specified by the
advanced setting BlownFuseQualificationTime. In this scenario, the zone is
marked as having a blown fuse, and the particular switch in the zone that is
configured as a FUSE_TAP is flagged and logged as the possible source of the
blown fuse. Zones that report such behavior are blocked from tripping by way of
falling conductor detection. Switches that are considering siblings (see topology
section below) of FUSE_TAP switches in a child zone should be configured
with the FUSE_SOURCE designation to prevent errant methods being detected
in the parent zone during a blown fuse condition in the child zone. Blown
fuse detection logic is supervised by a closed state of the 52A contact status
associated with the FUSE_TAP switch; this 52A status should be assigned to
that of the upstream BREAKER_SWITCH or SUBSTATION_BREAKER 52A
status. This prevents erroneous blown fuse detection when an upstream circuit
breaker is opened. Similar to Faulty Sensor detection, if the circuit breaker
associated with the switch has recently changed state, blown fuse detection is
blocked.

The criteria to qualify a blown fuse is described in Figure 14.7 below.

NOTE
The number of switches in a zone is calculated during initialization by
evaluating the number of switches associated with a specific zone reference.
Blown fuse conditions can only be qualified for zones which contain two
or more switches. A zone's blown fuse indicator will only be asserted if the
possible blown fuse marker remains asserted long enough to surpass the
BlownFuseQualificationTime specified.

Programming Reference Date Code 20241023


FallingConductorProtection 371
Classes

Figure 14.7 Logic Evaluated to Determine a Blown Fuse Condition

Switch Availability
In addition to the blocking algorithms described above which are used to block
detection at a circuit (class) level, additional blocking is performed at the
switch level. This is done to prevent sending commands to devices that have
intentionally been excluded from the falling conductor algorithm, or those
whose communication status has come into question. This determination is
evaluated as switch availability and is logically determined on a per-switch basis
as shown in Figure 14.8 below. The Availability status of a switch is exposed
in the struct_SwitchStatus of that switch, in addition to a CommsOK flag that
is determined by a logical AND of the IED Offline Indication and a regularly
updating time stamp on the tag specified by the RTTIn bootstrap_Switch input.

Figure 14.8 Falling Conductor Protection Switch Availability Logic

At least one of the switches in a circuit must be defined as a


SUBSTATION_BREAKER switch type. This switch will have a 52A circuit
breaker status tag that is shared with the class input pt_SubstationBkr52AStatus.
If this switch becomes unavailable, then all other switches in the circuit will also
become unavailable.
There are two advanced settings parameters that allow for a configurable
pickup and dropout time associated with switch availability status. These
are AvailabilityPickUpTime and AvailabilityDropOutTime respectively.
They default to 100 ms each but can be adjusted longer to compensate for

Date Code 20241023 Programming Reference


372 FallingConductorProtection
Classes

communication links that do not have 100 percent availability and are subject
to periodic brief outages; these could cause the availability status to chatter.
If the LogRuntimeOperations class input is TRUE, a transition in a switches
availability status will be logged to the RTAC SOE.

Switches that are determined to not have full availability (as defined by the
logic diagram below) do not have the falling conductor method detection
algorithms executed on their configured phasor quantities. Also, if a
switch that is configured to provide the zone reference voltages becomes
unavailable, any other switches in that zone using those phase voltages
(e.g., they were bootstrapped with one or more voltages configured as
g_NO_REFERENCE_VOLTAGE) will not have the method detection
algorithms executed for it. The AlgorithmsEnabled status available in the
struct_SwitchStatus associated with a particular switch provides an indication
as to whether that switch has falling conductor method detection algorithms
enabled or disabled.

Zone Topology, Tripping, and Trip Transfers to Parent Zone


In the falling conductor library, an instance of the class represents a distribution
circuit that is defined as one or more logically or physically separated zones that
each contain two or more switches. Zones are typically separated physically by
controllable distribution assets such as circuit breakers or recloser controls or
more traditional protection mechanisms like fuses. In the top example shown
in Figure 14.9 below, two zones are defined ("Zone 1" and "Zone 2"), each of
which contain two switches (PMU1/PMU2 and PMU2/PMU3, respectively).

Each circuit must contain a PMU located at the substation distribution feeder;
this is defined as the substation breaker. This switch must be designated as a
SUBSTATION_BREAKER type. Other controllable switches in the circuit
should be designated as a BREAKER_SWITCH type.

In the falling conductor detection algorithm, some switches may be described


as nonoperational simply to declare that those switches cannot clear faults on
command by means such as a trip signal. In Figure 14.9 below, the bottom
diagram illustrates how PMU2 is incapable of clearing a fault on its own, but
declares Zone 1 as its parent zone and can, therefore, rely on the recloser at
PMU1 to clear any faults detected in Zone 2.

Figure 14.9 Parent Zone Reference Example

Programming Reference Date Code 20241023


FallingConductorProtection 373
Classes

Switches that provide a connection between zones (for example, PMU2 in the
examples above) will be bootstrapped twice, once in each zone. These switches
will often be bootstrapped with input signals (voltages, currents, etc.) from the
same IED. These 2 switches are referred to as siblings, and each is processed
independently in its respective zone for falling conductor criteria.

Switches can be described as fuse taps or as non-operational switches, both


of which cannot clear faults on demand (i.e., they cannot act on received trip
signals from the algorithm). As a result, these switches must be able to rely upon
other breaker switches located in their zone (or in a parent zone) to clear any
faults that they detect.

In cases where these non-operational switches are situated at the end of a line
or tap as monitors and an upstream recloser or breaker is present in the same
zone, this recloser or breaker will be responsible for clearing faults and will
inherently accept this responsibility. This is illustrated in the top illustration of
Figure 14.9. However, in situations where the non-operational monitor exists in
place of the previously described breaker (e.g., all switches in a zone are non-
operational, and thus cannot clear faults in the zone), a parent zone reference
must be described to provide a means of clearing faults. In this way, a non-
operational zone can transfer trip responsibility to its parent (upstream) zone
which is operational. This topology is illustrated in the bottom of Figure 14.9.
A fault that occurs in a given zone will not issue trips to any child zones that
reference it as a parent.

If a zone normally has tripping capabilities but all switches with a closed
52A contact status that are designated as type BREAKER_SWITCH or
SUBSTATION_BREAKER have entered an unavailable state (as defined by
the switch availability conditions above), then any tripping operations will be
deferred to a configured parent zone that still possesses tripping capabilities.

For controllable switches that provide a connection to a child zone that is


further downstream from the substation feeder, the breaker switch designation
should only be assigned to the sibling switch (associated with the same IED)
present in the child zone, as tripping this switch in the parent zone would not
disconnect the faulted zone from the source. Given the example shown in the
top illustration in Figure 14.9, this means that when PMU2 is bootstrapped as
a switch in Zone 1, it should be designated as a line monitor, and PMU1 would
be bootstrapped as the breaker switch as it would be responsible for isolating
the zone from the source. In Zone 2, when PMU2 is bootstrapped as a switch, it
should be assigned the breaker switch designation.

Voltage Change (dV/dt) Method


The rate of change of per-phase voltage with respect to time (dV/dt) is used to
detect falling conductor faults in distribution circuits. For a falling conductor
fault in a given phase that occurs between two PMU locations, the dV/dt
behavior observed at the two PMUs is such that they are in opposite polarity.
The absolute magnitude of dV/dt for the PMU farther away from the power
source rises steeply; thus, if a sharp increase in dV/dt for any particular phase
voltage is observed, a falling conductor scenario may begin the process
of qualification. When the dV/dt value rises above the threshold value, a
supervision check is performed with the help of dV0/dt threshold. Once the

Date Code 20241023 Programming Reference


374 FallingConductorProtection
Classes

dV0/dt magnitude exceeds the threshold, and the appropriate pickup delay is
applied, the supervision check confirms the observance of a falling conductor
and controls are asserted and may be communicated to the breakers associated
with these PMUs to operate as TRIP commands.

NOTE
Voltage change detection requires that multiple IEEE C37.118 messages
confirm such phenomena so as to prevent false tripping. This number of
messages is set by the advanced setting ProtPickupMessageCount and is
denoted as N_MSGS in this logic diagram.

After the voltage change detection method asserts, it may not assert again
until a time specified by the advanced setting dVdtReset passes. This is
denoted in the logic diagram as RST.

Figure 14.10 Voltage Change Method (dV/dt) Logic to Determine Falling


Conductor Criteria

Zero- and Negative-Sequence Voltage (V0 and V2) Magnitude Method


The zero-sequence and negative-sequence voltage magnitudes (V0 and V2
magnitude) are used to detect falling conductor faults in distribution circuits.
For a falling conductor fault in a given phase that occurs between two PMU
locations, the PMU farther away from the source has a steep increase in the
V0 or V2 magnitude compared to the PMU closer to the source. When the V0
or V2 magnitude rises above the threshold value and persists for a given time
duration, the observance of a falling conductor and controls are asserted and
may be communicated to the breakers associated with these PMUs to operate as
TRIP commands.

Programming Reference Date Code 20241023


FallingConductorProtection 375
Classes

NOTE
Zero-sequence and negative-sequence voltage magnitude detection require
that multiple IEEE C37.118 messages confirm such phenomena so as to prevent
false tripping. This number of messages is set by the advanced setting
ProtPickupMessageCount and is denoted as N_MSGS in this logic diagram.

After either the zero- or negative-sequence voltage magnitude detection


methods assert, they may not assert again until a time specified by the
advanced settings V0MagReset or V2MagReset passes, respectively. This is
noted in the logic diagram as |V0| RST or |V2| RST, respectively.

Figure 14.11 Zero- and Negative-Sequence Voltage Magnitude (|V0| and |V2|)
Method Logic for Determining Falling Conductor Criteria

Zero- and Negative-Sequence Voltage (V0 and V2) Angle Method


The zero- and negative-sequence voltage angles (V0 and V2 Angle,
respectively) is used to detect falling conductor faults in distribution circuits.
For a falling conductor fault in a given phase, occurring between three PMU
locations, the V0 and V2 Angles of the PMUs farther away from the source
align together while the PMUs closer to the source align together. This
observance should be met with an initial condition of substantial V0 and V2
magnitudes for each PMU location in order to trust the angles. When the V0 and
V2 angles align as previously mentioned for a given time duration (specified in
seconds by Equation 14.1), the observance of a falling conductor and controls
are asserted and may be communicated to the breakers associated with these
PMUs to operate as TRIP commands.

Equation 14.1

Date Code 20241023 Programming Reference


376 FallingConductorProtection
Classes

NOTE
Zero-sequence and negative-sequence voltage angle detection require that
multiple IEEE C37.118 messages confirm such phenomena so as to prevent
false tripping. This number of messages is set by the advanced setting
ProtPickupMessageCount and is noted as N_MSGS in this logic diagram.
After either the zero- or negative-sequence voltage angle detection methods
assert, they may not assert again until a time specified by the advanced
settings V0AngReset or V2AngReset passes, respectively. This is noted in the
logic diagram as ÐV0RST or ÐV2RST, respectively. Voltage angle detection
(either ÐV0Detect or ÐV2Detect) requires that a minimum voltage magnitude
is measured, this means that the sequence voltage magnitude must surpass
the advanced setting V0Min or V2Min, respectively. These algorithms find the
maximum angle difference between each switch and all other related switches
referenced to the same zone. This means that ÐV0 and ÐV2 shown in the
figure at left represent a discrete switch's values being compared against all
other measurements in the same zone. This algorithm is repeatedly calculated
for every switch.

Figure 14.12 Zero- and Negative-Sequence Voltage Angle (ÐV0 and ÐV2) Method Logic for Determining Falling
Conductor Criteria

Class Inputs and Outputs


The following tables describe the inputs and outputs associated with
class_FallingConductorMonitor.

Programming Reference Date Code 20241023


FallingConductorProtection 377
Classes

Inputs

Name IEC 61131 Type Description

Enable BOOL System Enable.

DataRate INT C37.118 Rate of data transmission. Normally fed


from SystemTags.Data_Rate tag.

LogRuntimeOperations BOOL If TRUE, runtime errors, falling conductor


detection, and trip operations are logged in the
RTAC SOE viewer (defaults to TRUE).

AlarmOnFaultySensor BOOL If TRUE and if LogRuntimeOperations is TRUE,


faulty sensor SOE entries will be logged as alarms
(defaults to TRUE).

AlarmOnBlownFuse BOOL If TRUE and if LogRuntimeOperations is TRUE,


blown fuse detection SOE entries will be logged
as alarms (defaults to TRUE).

SystemNominalVoltage REAL Nominal system line-to-neutral voltage in units


specified by phase measurement inputs.

AffirmativeDetectionCount enum_AffirmativeDetectionType Control to specify number of affirmative detection


methods required for tripping (defaults to
MATCH_ENABLED_METHOD_PICKUP).

EnableVoltageChangeDetection BOOL Enable/disable dV/dt-based fault detection.

dVdtPickup REAL Phase voltage magnitude rate-of- change pickup


(in units specified by phase measurement inputs;
e.g., volts per second - defaults to 5000).

EnableV0MagnitudeDetection BOOL Enable/disable zero-sequence voltage magnitude-


based fault detection.

V0MagPickup REAL Zero-sequence voltage magnitude pickup (in units


specified by phase measurement inputs - defaults
to 1000).

EnableV2MagnitudeDetection BOOL Enable/disable negative-sequence voltage


magnitude-based fault detection.

V2MagPickup REAL Negative-sequence voltage magnitude pickup (in


units specified by phase measurement inputs -
defaults to 2000).

EnableV0AngleDetection BOOL Enable/disable zero-sequence voltage angle-based


fault detection.

V0AngPickup REAL Zero-sequence voltage angle pickup (in units of


degrees - only applies if V0 magnitude is greater
than the advanced setting V0Min - defaults to 30).

EnableV2AngleDetection BOOL Enable/disable negative-sequence voltage angle-


based fault detection.

V2AngPickup REAL Negative-sequence voltage angle pickup (in units


of degrees - only applies if V2 magnitude is
greater than the advanced setting V2Min - defaults
to 50).

dI0dtBlockPickup REAL Level of zero-sequence current above which


falling conductor detection will be blocked; when
the dI0/dt value rises above this threshold, the
output dI0dt- SpikeAlarm will assert (defaults to
40).

Date Code 20241023 Programming Reference


378 FallingConductorProtection
Classes

Name IEC 61131 Type Description

AlarmOnI0Spike BOOL If TRUE and if LogRuntimeOperations is TRUE,


zero-sequence current spikes will be logged in the
RTAC SOE as alarms (defaults to FALSE).

dV0dtPickup REAL Zero-sequence voltage magnitude rate-of-change


pickup (defaults to 2000).

pt_SubstationBkr52AStatus POINTER TO SPS Pointer to an SPS tag that represents the open or
closed state of the substation circuit breaker that
feeds the distribution circuit. Typically sourced
from PMU input data from the substation relay
that feeds the entire distribution circuit.

TestModeEnabled SPS An SPS tag that represents the circuit-wide Test


Mode Enable/Disable status. Typically sourced
from PMU input data from the substation relay
that feeds the entire distribution circuit.

FCPDisabled SPS An SPS tag that represents the state of the circuit-
wide falling conductor Enable/Disable status.
Typically sourced from PMU input data from the
substation relay that feeds the entire distribution
circuit.

TargetReset BOOL A Boolean input that can be used to reset any


latched-in Falling Conductor methods that may
remain after blown fuse detection or methods that
were detected during Test Mode and/or at a time
when falling conductor protection was disabled.
Also resets per-switch round-trip time statistics.

AdvancedSettings struct_AdvancedSettings A collection of advanced settings for the class that


have default values, but which are adjustable by
the end user.

Outputs

Name IEC 61131 Type Description

Enabled BOOL System enable indicator

Licensed BOOL Indicator of successful license check for FallingConductorProtection

AlgorithmsEnabled BOOL Indicator of Enable status of FallingConductorProtection detection algorithms

Error BOOL System error indicator

ErrorDesc STRING(255) Descriptive message of applicable error

Trip BOOL Indicator that a Trip signal has been sent to one or more switches

FaultySensorAlarm SPS Faulty sensor detection alarm

FaultySensorDesc STRING(255) Faulty sensor detection description

dI0dtSpikeAlarm SPS Zero-sequence current rate-of-change spike alarm

dI0dtSpikeDesc STRING(255) Zero-sequence current rate-of-change spike description

BlownFuseDetected SPS Blown fuse detection indicator

BlownFuseDesc STRING(255) Blown fuse detection description

BlockingFaultAlarm SPS System blocking fault alarm

BlockingFaultDesc STRING(255) System blocking fault description

Programming Reference Date Code 20241023


FallingConductorProtection 379
Classes

Name IEC 61131 Type Description

dVdtFaultDetect BOOL dV/dt fault detection indicator

V0MagFaultDetect BOOL V0 magnitude fault detection indicator

V2MagFaultDetect BOOL V2 magnitude fault detection indicator

V0AngFaultDetect BOOL V0 angle fault detection indicator

V2AngFaultDetect BOOL V2 angle fault detection indicator

RoundTripTimeOutput SPS Round-trip time output for measuring round-trip network delay between RTAC and
switch devices; toggles once per second and is typically assigned to a GOOSE transmit
bit

NOTE
Note that legacy Falling Conductor applications may have used a common
GOOSE transmit bit (shared by all circuits) for Round Trip Time calculation
purposes. This should be avoided and each circuit (class) instance of
class_FallingConductorMonitor should use a unique GOOSE transmit bit that is
used only by the switches in that particular circuit. This is to provide the most
accurate RoundTripTime calculations for those switches.

bootstrap_Zone (Method)
This method should be called to create the zone references that will be used
by the protection algorithms. This method should be called once for every
zone in a circuit which will be protected against falling conductor cases. Every
call to the bootstrap_Zone method should be completed before any calls to
the bootstrap_Switch or Run methods. Any zone that may be referred to as a
ParentZoneReference by a switch should be bootstrapped before the child zone
where said switch is configured.

Inputs

Name IEC 61131 Type Description

ZoneName STRING(255) Name to be associated with zone

dVdtEnable BOOL Enable dV/dt falling conductor detection method

V0MagEnable BOOL Enable zero-sequence voltage magnitude falling


conductor detection method

V2MagEnable BOOL Enable negative-sequence voltage magnitude


falling conductor detection method

V0AngEnable BOOL Enable zero-sequence voltage angle falling


conductor detection method

V2AngEnable BOOL Enable negative-sequence voltage angle falling


conductor detection method

Date Code 20241023 Programming Reference


380 FallingConductorProtection
Classes

Inputs/Outputs
Name IEC 61131 Type Description

PhaseAVoltage CMV Phase A voltage tag referencing measured input


for IEEE C37.118 client (PMU) intended as zone
reference voltage

PhaseBVoltage CMV Phase B voltage tag referencing measured input


for IEEE C37.118 client (PMU) intended as zone
reference voltage

PhaseCVoltage CMV Phase C voltage tag referencing measured input


for IEEE C37.118 client (PMU) intended as zone
reference voltage

ZoneStatus struct_ZoneStatus Status and indication structure which will be


populated at the end of every Run method call with
the updated zone information

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if class_FallingConductorMonitor successfully


bootstraps a new zone with the described parameters

Processing
➤ The method confirms that the Run method has not yet been called.
➤ The ZoneName is verified as a valid string (i.e., not empty and not
already existing in class as previously bootstrapped zone).
➤ Pending previous verification, the zone attributes are recorded as a
reference for falling conductor protection.

bootstrap_Switch (Method)
This method should be called to create the switch references which will be
used by the protection algorithms. This method should be called once for every
reference to a zone by a switch in a circuit which will be protected against
falling conductor cases. That is to say, that if a switch is a member of two zones
(as in the case of most standard breakers), this bootstrap method should be
called twice, once for each zone (of which, there are two in this case) which
the switch holds reference to. All switch instances must define a unique name.
Every call to the bootstrap_Zone method should be completed before any calls
to this method, and similarly, all calls to the bootstrap_Switch method should be
completed before the first call to the Run method.

Inputs
Name IEC 61131 Type Description

SwitchName STRING(255) Name to be associated with switch

ZoneReference STRING(255) Name of the zone that the switch should be associated with

ParentZoneReference STRING(255) Name of the zone that supersedes the zone which this switch is associated with; i.e.,
this switch's parent zone

Programming Reference Date Code 20241023


FallingConductorProtection 381
Classes

Name IEC 61131 Type Description

SwitchType enum_SwitchType Enumerated description of the switch type as breaker, fuse tap, or non-operational
switch

PhaseOCPickup REAL Set point for which traditional relay-based phase overcurrent protection will
interrupt circuit, and which should not be managed by falling-conductor protection

GroundOCPickup REAL Set point for which traditional relay-based ground overcurrent protection will
interrupt circuit, and which should not be managed by falling-conductor protection

NOTE
Although g_NO_REFERENCE_VOLTAGE may be applied to one or even two of
the voltage inputs (i.e., PhaseAVoltage, PhaseBVoltage, and PhaseCVoltage),
at least one of these inputs must reference a valid voltage measurement and
not the "NO_REFERENCE" placeholder. If this condition is not met, the falling
conductor algorithm will result in an error describing the invalid reference.

Inputs/Outputs

Name IEC 61131 Type Description

PhaseAVoltage CMV Phase A voltage tag referencing measured input for IEEE C37.118 client (PMU)
located at switch; may be set to g_NO_REFERENCE_VOLTAGE if the zone's
reference voltage should instead be used for protection algorithms

PhaseBVoltage CMV Phase B voltage tag referencing measured input for IEEE C37.118 client (PMU)
located at switch; may be set to g_NO_REFERENCE_VOLTAGE if the zone's
reference voltage should instead be used for protection algorithms

PhaseCVoltage CMV Phase C voltage tag referencing measured input for IEEE C37.118 client (PMU)
located at switch; may be set to g_NO_REFERENCE_VOLTAGE if the zone's
reference voltage should instead be used for protection algorithms

PhaseACurrent CMV Phase A current tag referencing measured input for IEEE C37.118 client (PMU)
located at switch

PhaseBCurrent CMV Phase B current tag referencing measured input for IEEE C37.118 client (PMU)
located at switch

PhaseCCurrent CMV Phase C current tag referencing measured input for IEEE C37.118 client (PMU)
located at switch

Switch52AStatus SPS Breaker status indicator (52A contact status) reference for IEEE C37.118 client
(PMU) located at switch; may be set to g_BREAKER_CLOSED when no valid 52A
breaker status is measured at switch

OfflineIndicator BOOL IED offline status indicator to use to block what may appear as a false positive falling
conductor detection

TripControlPointOut SPS SPS tag which may provide a means to trip (open) this switch or breaker
(such as a GOOSE transmit tag configured as part of a message subscribed
to by an IED responsible for performing the trip operation(s) in the field)
under conditions determined by falling conductor algorithm; may be set to
g_NO_REFERENCE_TRIP_CONTROL for switches that do not provide a means to
execute tripping operations (i.e., fuse-taps or non-operational switches)

TestModeEnabledOut SPS SPS tag used to indicate that test mode is to be enabled for this switch; typically sent
to the switch as a tag belonging to a GOOSE transmit message. Test mode is enabled
on a class-wide basis for all switches and uses the TestModeEnabled class input with
an SPS sourced from the main substation PMU. The state of the input is inverted
before being written to the SPS tag specified here.

Date Code 20241023 Programming Reference


382 FallingConductorProtection
Classes

Name IEC 61131 Type Description

CircuitFCPDisableOut SPS SPS tag used to indicate the status of the circuit-wide FCPDisable status; typically
sent to the switch as a tag belonging to a GOOSE transmit message. The circuit-
wide FCPDisabled mode is entered on a class-wide basis for all switches and uses the
FCPDisabled class input with an SPS sourced from the main substation PMU.

ExcludeSwitch SPS Monitored point that describes whether the switch is enabled, or if it
should defer tripping operations to the upstream parent zone. May be set to
g_NEVER_DISABLED_SWITCH if the switch will never be excluded from FCP
interactions. Will typically be sourced from C37.118 client (PMU) incoming data.

FaultStatus SPS Monitored point that describes the switch's FAULT status, as determined by the IED
logic. Will typically be sourced from C37.118 client (PMU) incoming data.

IEDHealthy SPS Monitored point that describes the overall health status of the IED. Will typically be
sourced from C37.118 client (PMU) incoming data.

RTTIn SPS Round-trip time input for measuring round-trip network delay between RTAC and
switch device; typically provided as a digital status from the PMU.

SwitchStatus struct_SwitchStatus Status and indication structure which will be populated with updated switch
information at the end of every Run method call.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if class_FallingConductorMonitor successfully


bootstraps a new switch with the described parameters.

Processing
➤ The method confirms that the Run method has not yet been called.
➤ The method confirms that at least one zone has been associated with the
class instance, and thus, switches may be bootstrapped accordingly.
➤ Both the ZoneReference and ParentZoneReference are verified as zones
that have been bootstrapped to the class instance, thus validating these
references.
➤ The SwitchName is verified as a valid string (i.e., not empty and not
already existing in class as previously bootstrapped switch).
➤ Any voltages that have been set from g_NO_REFERENCE_VOLTAGE
are set to reference the associated zone's voltage data.
➤ Pending previous verification, the zone attributes are recorded as a
reference for falling conductor protection.

Run (Method)
This method must be called once every processing scan after all of the bootstrap
methods have been called to construct and model the electric circuit. General
processing of this logical flow is described in Figure 14.13.

Programming Reference Date Code 20241023


FallingConductorProtection 383
Classes

NOTE
Regardless of the presence of blocking conditions such as a traditional fault
(e.g., overcurrent), faulty sensor, or pre-existing trip condition, the falling
conductor algorithm will process trip and clear conditions for every zone
when the system is enabled to ensure trip signals are cleared after the
appropriate time delay.

Figure 14.13 Primary Decision Tree Used to Perform Logic in the Run Method

Processing
➤ Enable input is mapped to Enabled output.
➤ Boot delay timer is processed to verify that sufficient time has passed
since RTAC boot (as required by the advanced setting BootDelay) for
algorithms to perform expectantly.
➤ Protection pickup delay is calculated from the message interval and the
protection message count specified by Equation 14.1.
➤ Protection pickup timers are run for each detection method, including:
➢ change of voltage over time (dVdt)
➢ zero-sequence voltage magnitude (V0Mag)

Date Code 20241023 Programming Reference


384 FallingConductorProtection
Classes

➢ negative-sequence voltage magnitude (V2Mag)


➢ zero-sequence voltage angle (V0Ang)
➢ negative-sequence voltage angle (V2Ang)
➤ System initialization occurs on the first scan after the boot delay elapses
or the class Enable input sees a rising edge. This process resets sequence
component and derivative calculations and verifies the number of
switches in each zone.
➤ Dynamic (changeable during runtime) number of concurrent falling
conductor detection methods required to issue trip is updated.
➤ When the boot delay has passed, and on each call of the run method, the
following logic executes:
➢ All IEEE C37.118 system settings and time source information are
updated.
➢ Sequence and derivative calculations are performed for each switch.
➢ The system is evaluated for a global blocking criteria which includes:
➣ Verifying that no traditional fault types (i.e., phase-overcurrent,
ground-overcurrent, or zero-sequence current magnitude
excursion) are detected for any switch bootstrapped to the class.
➣ Verifying that no faulty sensor criteria arise by determining if
switches that share a common control point, and whose 52A
contact status indicates a closed breaker, share voltage magnitude
measurements within a tolerance specified as a percent of nominal
voltage by the advanced setting MaxSensorMagDifference.
➣ Verifying that no previous trip commands have been issued to
any zone bootstrapped to the class for a time specified by the
advanced setting TripSignalAssertionPeriod.
If no blocking criteria assert, falling conductor detection algorithms
execute as follows:
➣ Voltages of a near-zero magnitude are clamped to zero for every
zone and switch.
➣ Every switch is analyzed for falling conductor criteria according
to the enabled detection methods.
➣ Zones that report a loss of voltage potential on the same phase for
all switches are inspected for blown fuse criteria. Switches that
belong to said zone are marked with the blown fuse indicator. If
the substation circuit breaker is open, or any switch in the zone
reports unavailability, blown fuse detection is not performed.
➣ Zone-level blocking mechanisms are verified.
➣ Zones are evaluated for tripping criteria and marked for tripping
if they are not blocked or if a downstream zone requires tripping
assistance.
➢ Regardless of the globally asserted blocking criteria described
previously, the trip and clear algorithms are processed to ensure
previously asserted trip signals may be cleared after the appropriate
assertion time.
➤ If LogRuntimeOperations is TRUE, logging is performed for errors and
detection or trip operations.

Programming Reference Date Code 20241023


FallingConductorProtection 385
Examples

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Falling Conductor Protection on a Two-Zone Circuit


Objective
A simple electrical circuit with two reclosers, a fused branch, and two line
monitors should have falling conductor protection applied as shown in
Figure 14.14.

Considering this circuit, we can note a few key things:

➤ PMU1 is considered to be a circuit breaker at the electrical source of this


distribution circuit. It should be defined as a SUBSTATION_BREAKER.

Figure 14.14 Falling Conductor Protection Applied on a Two-Zone Circuit


➤ The zones overlap on the recloser PMU2, however only Zone 2 should
consider this switch a controllable asset. Additionally, this means that
these zones will each bootstrap a unique switch to represent the recloser,
but they will share the same 52A contact status and the same trip control
point. Zone 1 should bootstrap this switch as NON_OPERATIONAL and
Zone 2 should consider it of type BREAKER_SWITCH.
➤ Due to the overlap of zones at PMU2 and the downstream connection that
is observed here, the switch bootstrapped to Zone 2 representing PMU2
will "inherit" Zone 1 as the parent zone. This is not beneficial in this
particular example, but if the recloser at PMU2 were instead a simple line
monitor without any ability to clear faults on demand, this would provide
the ability for PMU1 to clear faults detected anywhere in Zone 2.

Date Code 20241023 Programming Reference


386 FallingConductorProtection
Examples

➤ Both of the line monitors (PMU3 and PMU4) are only capable of
monitoring system conditions, neither one is capable of performing trip
operations on command. However, since both of these monitors are
downstream of the recloser at PMU2, they will rely upon that recloser to
clear any faults they detect.
➤ Even though, as mentioned in the previous point, both PMU3 and PMU4
will rely upon PMU2 to clear faults they detect, they do not reference
Zone 1 as their parent zone. This is because Zone 1 does not overlap with
either of these monitors. If a fault is detected by either of these monitors,
the zone will record the fault, and thus a trip control will be sent to the
recloser at PMU2, which will inevitably clear the fault for these monitors.

Assumptions
This example assumes that there are a number of IEEE C37.118 clients and IEC
61850 GOOSE transmit tags configured in the RTAC to allow for synchrophasor
measurements as the sensory inputs and GOOSE binary controls. These assumed
devices are listed below with their respective tags.

➤ C37.118 Synchrophasor Clients


➢ PMU1
➣ VAPM (Phase A Voltage at PMU1)
➣ VBPM (Phase B Voltage at PMU1)
➣ VCPM (Phase C Voltage at PMU1)
➣ IAPM (Phase A Current at PMU1)
➣ IBPM (Phase B Current at PMU1)
➣ ICPM (Phase C Current at PMU1)
➣ FAULT (IED FAULT Status from PMU1)
➣ FCPDISABLED (FCP Disabled for circuit)
➣ FCPTEST (FCP Test Mode Enabled for circuit)
➣ IEDHEALTHY (IED Health Status from PMU1)
➣ STATUS52A (52A Contact Status at PMU1)
➣ PINGPONG (Incoming Round-Trip Time Status from PMU1)
➢ PMU2
➣ VAPM (Phase A Voltage at PMU2)
➣ VBPM (Phase B Voltage at PMU2)
➣ VCPM (Phase C Voltage at PMU2)
➣ IAPM (Phase A Current at PMU2)
➣ IBPM (Phase B Current at PMU2)
➣ ICPM (Phase C Current at PMU2)
➣ FAULT (IED FAULT Status from PMU2)
➣ IEDHEALTHY (IED Health Status from PMU2)
➣ STATUS52A (52A Contact Status at PMU2)
➣ PINGPONG (Incoming Round-Trip Time Status from PMU2)

Programming Reference Date Code 20241023


FallingConductorProtection 387
Examples

➢ PMU3
➣ VAPM (Phase A Voltage at PMU3)
➣ VBPM (Phase B Voltage at PMU3)
➣ VCPM (Phase C Voltage at PMU3)
➣ IAPM (Phase A Current at PMU3)
➣ IBPM (Phase B Current at PMU3)
➣ ICPM (Phase C Current at PMU3)
➣ FAULT (IED FAULT Status from PMU3)
➣ IEDHEALTHY (IED Health Status from PMU3)
➣ PINGPONG (Incoming Round-Trip Time Status from PMU3)
➢ PMU4
➣ VAPM (Phase A Voltage at PMU4)
➣ VBPM (Phase B Voltage at PMU4)
➣ VCPM (Phase C Voltage at PMU4)
➣ IAPM (Phase A Current at PMU4)
➣ IBPM (Phase B Current at PMU4)
➣ ICPM (Phase C Current at PMU4)
➣ FAULT (IED FAULT Status from PMU4)
➣ IEDHEALTHY (IED Health Status from PMU4)
➣ PINGPONG (Incoming Round-Trip Time Status from PMU4)
➤ IEC 61850 GOOSE Server (Transmit)
➢ GTXTags
➣ LD_VB1GGIO3_Ind001 (Trip Control for PMU1)
➣ LD_VB1GGIO3_Ind002 (Enable Test mode for PMU1)
➣ LD_VB1GGIO3_Ind003 (Circuit FCP Disable for PMU1)
➣ LD_VB1GGIO3_Ind004 (Trip Control for PMU2)
➣ LD_VB1GGIO3_Ind005 (Enable Test mode for PMU2)
➣ LD_VB1GGIO3_Ind006 (Circuit FCP Disable for PMU2)
➣ LD_VB1GGIO3_Ind007 (Trip Control for PMU3)
➣ LD_VB1GGIO3_Ind008 (Enable Test mode for PMU3)
➣ LD_VB1GGIO3_Ind009 (Circuit FCP Disable for PMU3)
➣ LD_VB1GGIO3_Ind010 (Trip Control for PMU4)
➣ LD_VB1GGIO3_Ind011 (Enable Test mode for PMU4)
➣ LD_VB1GGIO3_Ind012 (Circuit FCP Disable for PMU4)
➣ LD_VB1GGIO3_Ind020 (Round Trip Time Output for all PMUs)

Date Code 20241023 Programming Reference


388 FallingConductorProtection
Examples

Additionally, in an effort to coordinate with traditional protection and avoid


tripping for standard phase or ground overcurrent at PMU1 and PMU2, the
pickup settings for these thresholds are specified as follows for the falling
conductor detection instance.
➤ Phase Overcurrent: 360 (units as specified by the current tag; i.e.,
PMU1.IAPM)
➤ Ground Overcurrent: 180 (units as specified by the current tag; i.e.,
PMU1.IAPM)

Solution
To define and operate the logic required to operate falling conductor protection,
the user can create a program as shown in Code Snippet 14.1:
Code Snippet 14.1 prg_FallingConductorCircuit1
PROGRAM prg_FallingConductorCircuit1
VAR
RunOnce : BOOL := TRUE;
FCPInstance: FallingConductorProtection.class_FallingConductorMonitor();
ZoneStatuses : ARRAY[1..2] OF FallingConductorProtection.struct_ZoneStatus;
SwitchStatuses : ARRAY[1..5] OF FallingConductorProtection.struct_SwitchStatus;
AdvSettings : FallingConductorProtection.struct_AdvancedSettings;
END_VAR

AdvSettings.BootDelay := T#5S;

// Prepare Falling Conductor Monitor


FCPInstance.Enable := True;
FCPInstance.SystemNominalVoltage := 6900.0;
FCPInstance.DataRate := DINT_TO_INT(SystemTags.Data_Rate.stVal);
FCPInstance.TestModeEnabled := PMU1_PMU1.FCPTEST;
FCPInstance.FCPDisabled := PMU1_PMU1.FCPDISABLED;
FCPInstance.pt_SubstationBkr52AStatus := ADR(PMU1_PMU1.STATUS52A);
FCPInstance.AffirmativeDetectionCount :=
FallingConductorProtection.enum_AffirmativeDetectionType.MATCH_ENABLED_METHOD_PICKUP;
FCPInstance.AdvancedSettings := AdvSettings;

// Bootstrap all Zones


IF RunOnce THEN
FCPInstance.bootstrap_Zone( ZoneName := 'Zone 1',
dVdtEnable := True, V0MagEnable := True,
V2MagEnable := True, V0AngEnable := True,
V2AngEnable := True,
PhaseAVoltage := PMU1_PMU1.VAPM,
PhaseBVoltage := PMU1_PMU1.VBPM,
PhaseCVoltage := PMU1_PMU1.VCPM,
ZoneStatus := ZoneStatuses[1] );
FCPInstance.bootstrap_Zone( ZoneName := 'Zone 2',
dVdtEnable := True, V0MagEnable := True,
V2MagEnable := True, V0AngEnable := True,
V2AngEnable := True,
PhaseAVoltage := PMU2_PMU2.VAPM,
PhaseBVoltage := PMU2_PMU2.VBPM,
PhaseCVoltage := PMU2_PMU2.VCPM,
ZoneStatus := ZoneStatuses[2] );

// Bootstrap all Switches


FCPInstance.bootstrap_Switch( SwitchName := 'PMU1_Z1',
ZoneReference := 'Zone 1', ParentZoneReference := '',
SwitchType := FallingConductorProtection.enum_SwitchType.SUBSTATION_BREAKER,
PhaseOCPickup := 360.0, GroundOCPickup := 160.0,
PhaseAVoltage := PMU1_PMU1.VAPM, PhaseBVoltage := PMU1_PMU1.VBPM,
PhaseCVoltage := PMU1_PMU1.VCPM, PhaseACurrent := PMU1_PMU1.IAPM,
PhaseBCurrent := PMU1_PMU1.IBPM, PhaseCCurrent := PMU1_PMU1.ICPM,
Switch52AStatus := PMU1_PMU1.STATUS52A,

Programming Reference Date Code 20241023


FallingConductorProtection 389
Examples

OfflineIndicator := PMU1_C37_118_POU.Offline,
TripControlPointOut := LD_VB1GGIO3_Ind001,
TestModeEnabledOut := LD_VB1GGIO3_Ind002,
CircuitFCPDisableOut := LD_VB1GGIO3_Ind003,
ExcludeSwitch := g_NEVER_DISABLED_SWITCH,
FaultStatus := PMU1_PMU1.FAULT,
IEDHealthy := PMU1_PMU1.IEDHEALTHY,
RTTIn := PMU1_PMU1.PINGPONG,
SwitchStatus := SwitchStatuses[1] );

FCPInstance.bootstrap_Switch( SwitchName := 'PMU2_Z1',


ZoneReference := 'Zone 1', ParentZoneReference := '',
SwitchType := FallingConductorProtection.enum_SwitchType.NON_OPERATIONAL,
PhaseOCPickup := 0, GroundOCPickup := 0,
PhaseAVoltage := PMU2_PMU2.VAPM, PhaseBVoltage := PMU2_PMU2.VBPM,
PhaseCVoltage := PMU2_PMU2.VCPM, PhaseACurrent := PMU2_PMU2.IAPM,
PhaseBCurrent := PMU2_PMU2.IBPM, PhaseCCurrent := PMU2_PMU2.ICPM,
Switch52AStatus := PMU2_PMU2.STATUS52A,
OfflineIndicator := PMU2_C37_118_POU.Offline,
TripControlPointOut := LD_VB1GGIO3_Ind004,
TestModeEnabledOut := LD_VB1GGIO3_Ind005,
CircuitFCPDisableOut := LD_VB1GGIO3_Ind006,
ExcludeSwitch := g_NEVER_DISABLED_SWITCH,
FaultStatus := PMU2_PMU2.FAULT,
IEDHealthy := PMU2_PMU2.IEDHEALTHY,
RTTIn := PMU2_PMU2.PINGPONG,
SwitchStatus := SwitchStatuses[2] );

FCPInstance.bootstrap_Switch( SwitchName := 'PMU2_Z2',


ZoneReference := 'Zone 2', ParentZoneReference := 'Zone 1',
SwitchType := FallingConductorProtection.enum_SwitchType.BREAKER_SWITCH,
PhaseOCPickup := 0, GroundOCPickup := 0,
PhaseAVoltage := PMU2_PMU2.VAPM, PhaseBVoltage := PMU2_PMU2.VBPM,
PhaseCVoltage := PMU2_PMU2.VCPM, PhaseACurrent := PMU2_PMU2.IAPM,
PhaseBCurrent := PMU2_PMU2.IBPM, PhaseCCurrent := PMU2_PMU2.ICPM,
Switch52AStatus := PMU2_PMU2.STATUS52A,
OfflineIndicator := PMU2_C37_118_POU.Offline,
TripControlPointOut := LD_VB1GGIO3_Ind004,
TestModeEnabledOut := LD_VB1GGIO3_Ind005,
CircuitFCPDisableOut := LD_VB1GGIO3_Ind006,
ExcludeSwitch := g_NEVER_DISABLED_SWITCH,
FaultStatus := PMU2_PMU2.FAULT,
IEDHealthy := PMU2_PMU2.IEDHEALTHY,
RTTIn := PMU2_PMU2.PINGPONG,
SwitchStatus := SwitchStatuses[3] );

FCPInstance.bootstrap_Switch( SwitchName := 'PMU3_Z2',


ZoneReference := 'Zone 2', ParentZoneReference := 'Zone 1',
SwitchType := FallingConductorProtection.enum_SwitchType.FUSE_TAP,
PhaseOCPickup := 0, GroundOCPickup := 0,
PhaseAVoltage := PMU3_PMU3.VAPM, PhaseBVoltage := PMU3_PMU3.VBPM,
PhaseCVoltage := PMU3_PMU3.VCPM, PhaseACurrent := PMU3_PMU3.IAPM,
PhaseBCurrent := PMU3_PMU3.IBPM, PhaseCCurrent := PMU3_PMU3.ICPM,
Switch52AStatus := FallingConductorProtection.g_BREAKER_CLOSED,
OfflineIndicator := PMU3_C37_118_POU.Offline,
TripControlPointOut := FallingConductorProtection.g_NO_REFERENCE_TRIP_CONTROL,
TestModeEnabledOut := LD_VB1GGIO3_Ind008,
CircuitFCPDisableOut := LD_VB1GGIO3_Ind009,
ExcludeSwitch := g_NEVER_DISABLED_SWITCH,
FaultStatus := PMU3_PMU3.FAULT,
IEDHealthy := PMU3_PMU3.IEDHEALTHY,
RTTIn := PMU3_PMU3.PINGPONG,
SwitchStatus := SwitchStatuses[4] );

FCPInstance.bootstrap_Switch( SwitchName := 'PMU4_Z2',


ZoneReference := 'Zone 2', ParentZoneReference := 'Zone 1',
SwitchType := FallingConductorProtection.enum_SwitchType.NON_OPERATIONAL,
PhaseOCPickup := 0, GroundOCPickup := 0,
PhaseAVoltage := PMU4_PMU4.VAPM, PhaseBVoltage := PMU4_PMU4.VBPM,

Date Code 20241023 Programming Reference


390 FallingConductorProtection
Examples

PhaseCVoltage := PMU4_PMU4.VCPM, PhaseACurrent := PMU4_PMU4.IAPM,


PhaseBCurrent := PMU4_PMU4.IBPM, PhaseCCurrent := PMU4_PMU4.ICPM,
Switch52AStatus := FallingConductorProtection.g_BREAKER_CLOSED,
OfflineIndicator := PMU4_C37_118_POU.Offline,
TripControlPointOut := FallingConductorProtection.g_NO_REFERENCE_TRIP_CONTROL,
TestModeEnabledOut := LD_VB1GGIO3_Ind011,
CircuitFCPDisableOut := LD_VB1GGIO3_Ind012,
ExcludeSwitch := g_NEVER_DISABLED_SWITCH,
FaultStatus := PMU4_PMU4.FAULT,
IEDHealthy := PMU4_PMU4.IEDHEALTHY,
RTTIn := PMU4_PMU4.PINGPONG,
SwitchStatus := SwitchStatuses[5] );
END_IF

// Run the Falling Conductor Monitor


FCPInstance.Run();

LD_VB1GGIO3_Ind020 := FCPInstance.RoundTripTimeOutput;

Programming Reference Date Code 20241023


S E C T I O N 1 5

FaultLocation
Introduction
This library provides methods to determine fault conditions and distances using
COMTRADE fault recordings.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:

1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_FaultLocationObject"
myFaultLocationObject := otherFaultLocationObject;

// This is fine
someVariable := myFaultLocationObject.value;
// As is this
pt_myFaultLocationObject := ADR(myFaultLocationObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.

➤ Classes in this library have memory allocated inside them. As such,


they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).

Supported Firmware Versions


This library must be used with an RTAC device that is running firmware version
R144-V1 firmware or later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Date Code 20241023 Programming Reference


392 FaultLocation
Structures

enum_FaultType
This enumeration defines the fault type.

Enumeration Description

NoFaultFound No fault found

AG A-phase to ground fault

BG B-phase to ground fault

CG C-phase to ground fault

AB A-phase to B-phase fault

BC B-phase to C-phase fault

CA C-phase to A-phase fault

ABG A-phase and B-phase to ground fault

BCG B-phase and C-phase to ground fault

CAG C-phase and A-phase to ground fault

ABC Three-phase fault

enum_PhaseRotation
This enumeration defines the phase rotation.

Enumeration Description

ABC ABC phase rotation.

ACB ACB phase rotation.

enum_WiringConfig
This enumeration defines the potential transformer wiring configuration.

Enumeration Description

WYE Wye-connected wiring configuration.

DELTA Delta-connected wiring configuration.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Programming Reference Date Code 20241023


FaultLocation 393
Classes

struct_FaultDetails
This structure is used to represent the fault distance and type determined by a
calculation.

Name IEC 61131 Type Description

FaultDistance MV Distance-to-fault. If the fault location is undefined


or outside of the allowed range, the quality is set to
invalid or questionable, respectively.

FaultType enum_FaultType The identified faulted phases.

struct_FaultEventDetails
This structure is used by the RequestSingleEndedFaultLocation() method as an
output for calculation results.

Name IEC 61131 Type Description

FaultDetails struct_FaultDetails Information pertaining to the fault.

FaultTypeString STRING String representation of the enum_FaultType value.

AnalysisError BOOL Indicates an issue with the fault analysis.

AnalysisStatus STRING Provides additional information about the fault


analysis process.

AssetID STRING(255) Asset identifier.

TriggerTime dateTime_t Event trigger time.

Classes
class_SingleEndedFault (Class)
This class calculates the fault distance, fault time, and fault type of a single-
ended fault recording by using fault data from a COMTRADE event file. Single-
ended fault recordings include fault data that a device records on only one end
of the transmission line. This class only supports COMTRADE event recordings
from SEL-2245-42 AC Protection Modules with 24 kHz sampling rates. For
best results, use COMTRADE event recordings that have at least 30 cycles of
prefault and 30 cycles of post-fault data. This class outputs the distance-to-fault
when the inputs meet the following criteria:

➤ A valid COMTRADE event file matching DeviceID with a trigger time


equivalent to TriggerTime ±TimeVar exists in the RTAC's database prior
to the expiration of waitTime.
➤ The COMTRADE event file contains the specified input channel names.
➤ No single pole open condition has been identified prior to the fault
identification. (class_SingleEndedFault identifies a single pole open
condition when any measured phase current input is less than 5 percent of
NominalCurrentInput.)

Date Code 20241023 Programming Reference


394 FaultLocation
Classes

➤ The class_SingleEndedFault identifies a fault for a duration greater than


one cycle.
➤ The size of the COMTRADE event data file is less than or equal to 10
MB.

This class calculates the distance-to-fault in per unit of the positive-sequence


line impedance. The LineLength setting is used to determine the units that the
RTAC reports for the distance-to-fault.

If the distance-to-fault calculation result is greater than LineLength, or


an unbalanced line condition exists before the fault, the class reports the
FaultDistance quality as questionable. If the distance-to-fault cannot be
determined, the RTAC reports the fault location as –999999 and sets the quality
to invalid.

This class provides fault location details for the specified COMTRADE
events using the LocateFault() and Run() methods. The optional input
BytesToReadPerScan provides the ability to decrease the time it takes to produce
a fault location. Increasing the BytesToReadPerScan can increase task usage and
therefore this input should be used with caution.

The SEL-3555 and SEL-3350 RTAC platforms are capable of producing fault
locations for event data files as large as 500 MB. All other RTAC platforms are
limited to a maximum file size of 10 MB.

This class leverages FileIO.class_ComtradeParser for reading and parsing


COMTRADE events.

Inputs
Name IEC 61131 Type Description

BytesToReadPerScan UDINT The number of bytes that class_SingleEndedFault reads from the COMTRADE file in
a single processing interval. This input supports a range of 1,024 to 512,000 bytes per
processing interval. Optional input that defaults to 5,000.

Outputs
Name IEC 61131 Type Description

FaultAnalysisInProgress BOOL TRUE while the Run() method is collecting


an event and performing a distance-to-fault
calculation

FaultAnalysisDone BOOL Asserts TRUE for one processing interval


upon completing the fault location
calculation

FaultAnalysisInfo struct_FaultDetails Fault location details including the distance-


to-fault, fault detection time, fault location
quality, and phases involved in fault

Error BOOL TRUE if any error occurs

ErrorDescription STRING(255) A description of the last error encountered

Programming Reference Date Code 20241023


FaultLocation 395
Classes

LocateFault (Method)
Call this method to calculate fault distance using the COMTRADE file that
matches DeviceID and TriggerTime ±TimeVar. This method passes its inputs
to Run(), which calculates fault location, fault type, and fault time for the
transmission line that the input channel names and line parameters define.

For COMTRADE channels with primary scaling, update the


PrimaryScalingCTRatio and PrimaryScalingPTRatio inputs to convert
COMTRADE samples to secondary for fault location. Update these settings
when using RTAC Recording Group - Calculation Channels for fault location.

Inputs

Name IEC 61131 Type Description

DeviceID STRING(255) Name of the device that generates the COMTRADE event file

TriggerTime dateTime_t The trigger time of the event. If an exact match does not exist, this method
reads an event within TimeVar milliseconds of TriggerTime.

VaChannel STRING(255) Name of the A-phase voltage or A‑B phase-to-phase voltage channel in the
COMTRADE file that is used for calculating the fault location

VbChannel STRING(255) Name of the B-phase voltage or B‑C phase-to-phase voltage channel in the
COMTRADE file that is used for calculating the fault location

VcChannel STRING(255) Name of the C-phase voltage or C‑A phase-to-phase voltage channel in the
COMTRADE file that is used for calculating the fault location

IaChannel STRING(255) Name of the A-phase current channel in the COMTRADE file that is used for
calculating the fault location

IbChannel STRING(255) Name of the B-phase current channel in the COMTRADE file that is used for
calculating the fault location

IcChannel STRING(255) Name of the C-phase current channel in the COMTRADE file that is used for
calculating the fault location

PosSeqImpedanceMag REAL Positive-sequence line impedance magnitude (0.25–1275 ohms secondary)

PosSeqImpedanceAng REAL Positive-sequence line impedance angle (5.00–90.00 degrees)

ZeroSeqImpedanceMag REAL Zero-sequence line impedance magnitude (0.25–1275 ohms secondary)

ZeroSeqImpedanceAng REAL Zero-sequence line impedance angle (5.00–90.00 degrees)

NominalCurrentInput REAL Secondary nominal input current rating (1 or 5)

LineLength REAL Length of line

WaitTime UINT The amount of time to wait for an event to be available to parse (1–60
minutes)

TimeVar UINT The time variance in milliseconds allowed between TriggerTime and the
actual trigger time of the event (0–1000 milliseconds)

PhaseRotation enum_PhaseRotation Phase rotation

WiringConfig enum_WiringConfig Potential transformer wiring configuration type

RestraintFactor0 REAL The ratio of the magnitude of zero-sequence current to the magnitude of
positive-sequence current (0.02–0.50).

RestraintFactor2 REAL The ratio of the magnitude of negative-sequence current to the magnitude of
positive-sequence current (0.02–0.50).

Date Code 20241023 Programming Reference


396 FaultLocation
Classes

Name IEC 61131 Type Description

StepTime ULINT The maximum amount of time in microseconds the Run() method will run
each time it is called.

EventStartTimeOffset TIME (Optional) The time offset from the beginning of the event file at which to
begin the fault location analysis. Default is 0 seconds.

EventAnalysisLength TIME (Optional) The length of the event to be considered for fault location analysis.
Default is 0 seconds.

UseOpenEvent BOOL (Optional) If TRUE, the event scan/parse operation is bypassed. This is useful
if analyzing multiple assets from a single event file. Default is FALSE.

PrimaryScalingCTRatio REAL (Optional) CT ratio to apply if the current channels use primary scaling in the
COMTRADE record used for fault location (Positive REALS greater than
1.00).

PrimaryScalingPTRatio REAL (Optional) PT ratio to apply if the voltage channels use primary scaling in the
COMTRADE record used for fault location (Positive REALS greater than
1.00).

Processing
➤ LocateFault() enforces input parameter range requirements and
configures the COMTRADE event parameters to be read from the RTAC
database. For values violating the allowed range, LocateFault() sets Error
to TRUE and updates ErrorDescription for the input violation.
➤ If no errors exist, LocateFault() sets FaultAnalysisInProgress to TRUE
and passes parameters to Run(), which reads the event from database and
calculates a location to the fault for the given input parameters.

Run (Method)
Call this method on every scan. It supervises the asynchronous operation
required to read an event file and calculate a fault location from a COMTRADE
file.

Processing
➤ When LocateFault() is called, Run() performs the following:
➢ Resets ErrorDescription and FaultDistance.
➢ If LocateFault().UseOpenEvent is FALSE, begins event read
using the time window defined by EventStartTimeOffset and
EventAnalysisLength for the event containing DeviceID and
TriggerTime. If EventStartTimeOffset and EventAnalysisLength are 0,
all contents of the event record are analyzed for fault location.
➢ If LocateFault().UseOpenEvent is TRUE, bypasses event read. The
analysis window defined by the most recent call to LocateFault() with
UseOpenEvent = FALSE will be used for this analysis.
➤ If any errors occur during an event read from the database, Error is set to
TRUE, FaultAnalysisInProgress is set to FALSE, and ErrorDescription is
populated with an error message from class_ComtradeParser.

Programming Reference Date Code 20241023


FaultLocation 397
Classes

➤ After the event is successfully read, or if LocateFault().UseOpenEvent


is TRUE, Run() checks that the channel name inputs exist in the event.
Run() also validates that there are adequate event data to calculate a fault
location. If channel names are not found or there are not adequate event
data, Run() performs the following:
➢ Sets FaultAnalysisInProgress to FALSE.
➢ Sets Error to TRUE and updates ErrorDescription.
➤ When FaultAnalysisDone asserts, Run() performs the following:
➢ Populates FaultAnalysisInfo with the fault location details.
➢ Sets FaultAnalysisInProgress and FaultAnalysisDone to FALSE after
one processing interval.
➤ If any errors occur, Run() sets Error to TRUE, FaultAnalysisInProgress to
FALSE, and populates ErrorDescription appropriately.
➤ An event that is successfully read will be kept available for further
analysis until a call to LocateFault() with UseOpenEvent = FALSE is
observed.

class_FaultLocationManager (Class)
This class provides robust and versatile management of fault analysis processing
by allowing fault analysis requests to be queued as they become available. This
class also formats data for report generation through its implementation of the
ConditionMonitoring.I_Cm interface.

Inputs
Name IEC 61131 Type Description

BytesToReadPerScan UDINT (Optional) The number of bytes to be read from the COMTRADE file in a single
processing interval. This input supports a range of 1,024 to 512,000 bytes per processing
interval. Default is 5,000.

RecordInUTC BOOL Record event time stamps in UTC or local time.

Outputs
Name IEC 61131 Type Description

FaultAnalysisInProgress BOOL TRUE while the Run() method is collecting


an event and performing a distance-to-fault
calculation

FaultAnalysisDone BOOL Asserts TRUE for one processing interval


upon completing the fault location
calculation

Error BOOL TRUE if any error occurs

ErrorDescription STRING(255) A description of the last error encountered

Date Code 20241023 Programming Reference


398 FaultLocation
Classes

Implementation of the I_Cm Interface


This class supports the following I_Cm interface implementation.
➤ This class implements the SOE content portion of the interface.
➤ This class does not implement the Detail or Summary portions of this
interface.
➤ GetSoeRow().AssetID format: <LocateSingleEndedFault.AssetName>
➤ The timeStamp output of GetSoeRow() equals the return of SYS_TIME()
at the time of calling the GetSoeRow() method.
➤ SOE column labels:
➢ Fault Location (Units consistent with LineLength input of the
RequestSingleEndedFaultLocation method)
➢ Fault Type
➢ Fault Time
➤ The Fault Location and Fault Type column entries shall be populated
with the string 'No Fault' in the event that the given fault analysis finds no
fault.
➤ For any row indicating a found fault, the Fault Time column shall
be populated with the fault time stamp from the event using a time
stamp format matching that of the time stamp column defined by
ConditionMonitoring.CmReportWriter. For rows indicating 'No Fault', the
Fault Time column shall be populated with 'NA'.
➤ The NumAvailableSoeRows property increments when a fault analysis is
completed and will decrement upon a call to GetSoeRow().
➤ Sets the NewSoeFile property when NumAvailableSoeRows increments
after processing fault location from an event with a new time stamp. This
BOOL is set to indicate that the new content should be written to a new
file.

RequestSingleEndedFaultLocation (Method)
Call this method for each single-ended fault occurrence. Fault location requests
will be queued and processed by class_SingleEndedFaultLocation.LocateFault()
in queue order.

Inputs
Name IEC 61131 Type Description

AssetName STRING(255) Name of the asset associated with this event.

DeviceID STRING(255) Name of the device that generates the COMTRADE event file.

TriggerTime dateTime_t The trigger time of the event. If an exact match does not exist, this method reads an
event within TimeVar milliseconds of TriggerTime.

VaChannel STRING(255) Name of the A-phase voltage or A-B phase-to-phase voltage channel in the
COMTRADE file that is used for calculating the fault location.

VbChannel STRING(255) Name of the B-phase voltage or B-C phase-to-phase voltage channel in the
COMTRADE file that is used for calculating the fault location.

VcChannel STRING(255) Name of the C-phase voltage or C-A phase-to-phase voltage channel in the
COMTRADE file that is used for calculating the fault location.

Programming Reference Date Code 20241023


FaultLocation 399
Classes

Name IEC 61131 Type Description

IaChannel STRING(255) Name of the A-phase current channel in the COMTRADE file that is used for
calculating the fault location.

IbChannel STRING(255) Name of the B-phase current channel in the COMTRADE file that is used for
calculating the fault location.

IcChannel STRING(255) Name of the C-phase current channel in the COMTRADE file that is used for
calculating the fault location.

PosSeqImpedanceMag REAL Positive-sequence line impedance magnitude (0.25–1275 ohms secondary).

PosSeqImpedanceAng REAL Positive-sequence line impedance angle (5.00–90.00 degrees).

ZeroSeqImpedanceMag REAL Zero-sequence line impedance magnitude (0.25–1275 ohms secondary).

ZeroSeqImpedanceAng REAL Zero-sequence line impedance angle (5.00–90.00 degrees).

NominalCurrentInput REAL Secondary nominal input current rating (1 or 5).

LineLength REAL Length of line.

WaitTime UINT The amount of time to wait for an event to be available to parse (1–60 minutes).

TimeVar UINT The time variance in milliseconds allowed between TriggerTime and the actual
trigger time of the event (0–1000 milliseconds).

PhaseRotation enum_PhaseRotation Phase rotation.

WiringConfig enum_WiringConfig Potential transformer wiring configuration type.

RestraintFactor0 REAL The ratio of the magnitude of zero-sequence current to the magnitude of positive-
sequence current (0.02–0.50).

RestraintFactor2 REAL The ratio of the magnitude of negative-sequence current to the magnitude of
positive-sequence current (0.02–0.50).

StepTime ULINT The maximum amount of time in microseconds the Run() method will run each
time it is called.

EventStartTimeOffset TIME (Optional) The time offset from the beginning of the event file at which to begin the
fault location analysis. Default is 0 seconds.

EventAnalysisLength TIME (Optional) The length of the event to be considered for fault location analysis.
Default is 0 seconds.

PrimaryScalingCTRatio REAL (Optional) CT ratio to apply if the current channels use primary scaling in the
COMTRADE record used for fault location (Positive REALS greater than 1.00).

PrimaryScalingPTRatio REAL (Optional) PT ratio to apply if the voltage channels use primary scaling in the
COMTRADE record used for fault location (Positive REALS greater than 1.00).

Inputs/Outputs

Name IEC 61131 Type Description

OutputDetails struct_FaultEventDetails The structure to be populated with the results of


this analysis.

Processing
➤ The inputs will be cached in a structure and stored in a work request
queue.

Date Code 20241023 Programming Reference


400 FaultLocation
Examples

Run (Method)
Call this method on every scan. It supervises the asynchronous operation of the
underlying fault location class(es).

Processing
➤ If a fault analysis is not currently being processed, the associated work
request queue will be assessed for content. Work requests will be
removed from the queue and serviced in first-in-first-out order.
➤ While the internal class instance is processing a fault analysis, the class
output FaultAnalysisInProgress is asserted.
➤ Once the analysis on a given work request is complete, the class output
FaultAnalysisComplete is pulsed for one cycle.
➤ Once the analysis on a given work request is complete, the fault analysis
results will be used to update the OutputDetails structure instance passed
into the LocateSingleEndedFault method.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

SEL-2245-42 Event Analysis


Objective
A user has programmed the RTAC to trigger an event collection on an
SEL-2245-42 module when any fault condition occurs. Following each event
trigger, the user wants to identify the distance-to-fault and the fault type and
store information for the last five events in arrays for further analysis.

Assumptions
This example assumes the following:

➤ An SEL-2245-42 module is contained in the EtherCAT I/O Network and


is named "SEL_PRCTPT".
➤ For best results, the SEL_PRCTPT recordings contain 30 cycles of
prefault and 30 cycles of post-fault data.
➤ A transmission line study has been conducted for a 100-mile line.
The secondary positive-sequence line impedance is 7.80Ð84 and the
secondary zero-sequence line impedance is 24.80Ð81.50.
➤ The SEL_PRCTPT event trigger tag is triggered through external fault
detection logic that is not provided by this program.

Programming Reference Date Code 20241023


FaultLocation 401
Examples

Solution
Perform a call to class_SingleEndedFault each time an event trigger is detected.
After the class completes the fault analysis, write the fault type and distance-to-
fault tags into logic engine arrays.
Code Snippet 15.1 prg_FaultLocator
PROGRAM prg_FaultLocator
VAR
FaultLocator2245 : class_SingleEndedFault;
EventDateTime : dateTime_t;
RTrigEvent : R_TRIG;
Distance_To_Fault_Array : ARRAY [1..5] OF MV;
Fault_Type_Array : ARRAY [1..5] OF INT;
ArrayIterator : INT := 1;
END_VAR

// Monitor SEL_PRCTPT for RisingEdge of EventTrigger


RTrigEvent(CLK := SEL_PRCTPT_ECAT.EVENT_TRIGGER);
// Analyze event file for Distance-To-Fault and Fault-Type
IF RTrigEvent.Q THEN
EventDateTime := System_Time_Control_POU.System_Time.value;
FaultLocator2245.LocateFault(DeviceID := 'SEL_PRCTPT',
TriggerTime := EventDateTime,
VaChannel := 'VA',
VbChannel := 'VB',
VcChannel := 'VC',
IaChannel := 'IA',
IbChannel := 'IB',
IcChannel := 'IC',
PosSeqImpedanceMag := 7.80,
PosSeqImpedanceAng := 84,
ZeroSeqImpedanceMag := 24.80,
ZeroSeqImpedanceAng := 81.50,
NominalCurrentInput := 5,
LineLength := 100,
WaitTime := 5,
TimeVar := 1000,
PhaseRotation := enum_PhaseRotation.ABC,
WiringConfig := enum_WiringConfig.WYE,
RestraintFactor0 := 0.10,
RestraintFactor2 := 0.10,
StepTime := 50000);
END_IF
// Wait for fault analysis completion and write the fault data into arrays
IF FaultLocator2245.FaultAnalysisDone THEN
Distance_To_Fault_Array[ArrayIterator] :=
FaultLocator2245.FaultAnalysisInfo.FaultDistance;
Fault_Type_Array[ArrayIterator] :=
FaultLocator2245.FaultAnalysisInfo.FaultType;
IF ArrayIterator < 5 THEN
ArrayIterator := ArrayIterator + 1;
ELSIF ArrayIterator = 5 THEN
ArrayIterator := 1;
END_IF
END_IF
FaultLocator2245.Run(); // Call Run on every scan

Date Code 20241023 Programming Reference


402 FaultLocation
Examples

Recording Group Cross Module Fault Analysis


Objective
A user wants to use three SEL-2245-42 Axion modules to analyze fault
conditions on two parallel transmission lines (Line 1 and Line 2). The three
Axion modules are configured to measure as follows:

➤ Module 1 measures the bus voltage for transmission Lines 1 and 2.


➤ Module 2 measures Line 1 currents.
➤ Module 3 measures Line 2 currents.

Figure 15.1 Recording Group Multimodule Fault Analysis

A user has programmed an Axion to trigger an event collection on a


Recording Group when a fault condition on Line 1 or Line 2 is detected.
Following the event trigger, the user wants to identify the distance-to-
fault and the fault type using the current and line parameters from the
faulted transmission line.

Assumptions
This example assumes the following:

➤ A Recording Group named DFR is added to the program.


➤ DFR contains three SEL-2245-42 modules with the bus voltage being
recorded on Module 1, Line 1 current signals on Module 2, and Line 2
current signals on Module 3.
➤ DFR contains analog channel names of VA1, VB1, VC1, IA2, IB2, IC2,
IA3, IB3, IC3.
➤ DFR's event trigger is triggered through external fault detection logic that
is not provided by this program.
➤ Global variable Boolean tags are programmed to indicate the faulted
transmission line. A Line 1 fault is indicated by g_Line1Fault, and a Line
2 fault is indicated by g_Line2Fault.
➤ A transmission line study is conducted for a 100-mile line with the
following parameters:
➢ The Line 1 secondary positive-sequence line impedance is 7.40Ð86.7
and the secondary zero-sequence line impedance is 25.00Ð82.50.
➢ The Line 2 secondary positive-sequence line impedance is 8.2Ð84.7
and the secondary zero-sequence line impedance is 24.00Ð83.00.

Programming Reference Date Code 20241023


FaultLocation 403
Examples

Solution
Perform a call to class_SingleEndedFault each time the DFR event trigger is
detected. After the class completes its analysis, write the fault type and distance-
to-fault tags to the associated faulted line tags.
Code Snippet 15.2 prg_ParallelTransmissionLineFaultLocator
PROGRAM prg_ParallelTransmissionLineFaultLocator
VAR
DFRFaultLoc : class_SingleEndedFault;
EventDateTime : dateTime_t;
RTrigEvent : R_TRIG;
Line1FaultAnalysis : BOOL;
Line2FaultAnalysis : BOOL;
DistanceToFaultLine1 : MV;
DistanceToFaultLine2 : MV;
FaultTypeLine1 : INT;
FaultTypeLine2 : INT;
NewEventReady : BOOL;
END_VAR

// Monitor Recording Group DFR for rising edge of event trigger


RTrigEvent(CLK := DFR_POU.EVENT_TRIGGER);
// Analyze event file for Distance-To-Fault and Fault-Type
IF RTrigEvent.Q THEN
EventDateTime := System_Time_Control_POU.System_Time.value;
NewEventReady := TRUE;
END_IF
// Line 1 fault indicated by BOOL trigger - use Line 1 parameters
IF NewEventReady AND g_Line1Fault THEN
NewEventReady := FALSE;
Line1FaultAnalysis := TRUE;
DFRFaultLoc.LocateFault(DeviceID := 'DFR',
TriggerTime := EventDateTime,
VaChannel := 'VA1', VbChannel := 'VB1',
VcChannel := 'VC1', IaChannel := 'IA2',
IbChannel := 'IB2', IcChannel := 'IC2',
PosSeqImpedanceMag := 7.40, PosSeqImpedanceAng := 86.7,
ZeroSeqImpedanceMag := 25.00, ZeroSeqImpedanceAng := 82.50,
NominalCurrentInput := 5, LineLength := 100,
WaitTime := 5, TimeVar := 1000,
PhaseRotation := enum_PhaseRotation.ABC,
WiringConfig := enum_WiringConfig.WYE,
RestraintFactor0 := 0.10, RestraintFactor2 := 0.10,
StepTime := 50000);
// Line 2 fault indicated by BOOL Trigger - use Line 2 parameters
ELSIF NewEventReady AND g_Line2Fault THEN
NewEventReady := FALSE;
Line2FaultAnalysis := TRUE;
DFRFaultLoc.LocateFault(DeviceID := 'DFR',
TriggerTime := EventDateTime,
VaChannel := 'VA1', VbChannel := 'VB1',
VcChannel := 'VC1', IaChannel := 'IA3',
IbChannel := 'IB3', IcChannel := 'IC3',
PosSeqImpedanceMag := 8.20, PosSeqImpedanceAng := 84.70,
ZeroSeqImpedanceMag := 24.00, ZeroSeqImpedanceAng := 83.00,
NominalCurrentInput := 5, LineLength := 100,
WaitTime := 5, TimeVar := 1000,
PhaseRotation := enum_PhaseRotation.ABC,
WiringConfig := enum_WiringConfig.WYE,
RestraintFactor0 := 0.10, RestraintFactor2 := 0.10,
StepTime := 50000);
END_IF
// After Fault Analysis is complete, write Line 1 or Line 2 fault location
IF DFRFaultLoc.FaultAnalysisDone AND Line1FaultAnalysis THEN
DistanceToFaultLine1 := DFRFaultLoc.FaultAnalysisInfo.FaultDistance;
FaultTypeLine1 := DFRFaultLoc.FaultAnalysisInfo.FaultType;
Line1FaultAnalysis := FALSE;

Date Code 20241023 Programming Reference


404 FaultLocation
Examples

ELSIF DFRFaultLoc.FaultAnalysisDone AND Line2FaultAnalysis THEN


DistanceToFaultLine2 := DFRFaultLoc.FaultAnalysisInfo.FaultDistance;
FaultTypeLine2 := DFRFaultLoc.FaultAnalysisInfo.FaultType;
Line2FaultAnalysis := FALSE;
END_IF
DFRFaultLoc.Run(); // Call Run on every scan

Programming Reference Date Code 20241023


S E C T I O N 1 6

FileIO
Introduction
The FileIO library includes the internal RTAC sel_file and sel_ftp_client
libraries. This library provides function blocks that simplify asynchronous file
management for basic file read and write operations. It also provides access to
the underlying firmware interface libraries.

Because the classes this library provides manage asynchronous file operations,
the user must call the Run() method of instantiated classes on every scan to
ensure that all queued work is correctly performed and monitored. Each class
provides various methods to initiate new read or write operations, collect data,
or cause other changes in state.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_FileIOObject"
myFileIOObject := otherFileIOObject;

// This is fine
someVariable := myFileIOObject.value;
// As is this
pt_myFileIOObject := ADR(myFileIOObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).
➤ All file read operations are done completely into RAM. This means that
the reading of large files that exceed the available RAM will not work as
expected.

Supported Firmware Versions


Versions 3.5.7.3 and later of this library must be used with an RTAC device that
is running firmware version R151 firmware or later.

Versions 3.5.4.0 and later of this library must be used with an RTAC device that
is running firmware version R144-V1 firmware or later.

Date Code 20241023 Programming Reference


406 FileIO
Global Parameters

Versions 3.5.3.0 and later of this library must be used with an RTAC device that
is running firmware version R143-V0 firmware or later.
Versions 3.5.2.0 and later of this library must be used on an RTAC device that is
running firmware version R136-V2 or later.
Version 3.5.1.0 of this library must be used on an RTAC device that is running
firmware version R135.
Previous versions of this library can be used on firmware versions R132–R135.
To enable FileIO library support, the device number of your RTAC must include
the correct feature in its model option table (MOT). You cannot download
projects that include this library to RTACs that do not support the library. Use
the SEL website MOT configuration (https://selinc.com/products/) to ensure that
a particular part number has FileIO support enabled.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_p_FileIo_MaxBufferSize UDINT 1048576 The maximum internal buffer size allowed for class_FileReader2
or class_FileWriter. This value is the maximum file size you can
read in, and the maximum amount you can append to a file at one
time. The default value is 10242 • 10. If desired, the maximum
buffer size can be overridden for classes that support an associated
MaxBufferSizeOverride input.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_FtpSendSchedule
Enumeration Description

ON_CLOSE When the previous log file is closed, as part of starting a new log file
with the StartNewLog() method, synchronize the closed log to the
FTP server.

ON_UPDATE Send active log file each time an additional log is added.

sel_file.Enum_protocol_id
This enumeration is defined in the underlying sel_file library. It lists the
protocols that can create an event.

Enumeration Value

NO_PROTOCOL_SPECIFIED 0

SEL_CLIENT 1

Programming Reference Date Code 20241023


FileIO 407
Enumerations

Enumeration Value

SEL_SERVER 2

MODBUS_CLIENT 3

MODBUS_SERVER 4

DNP_CLIENT 5

DNP_SERVER 6

SEL_MIRRORED_BITS 7

C37118_CLIENT 8

GOOSE_RX 9

ACCESS_POINT_CLIENT 10

ACCESS_POINT_SERVER 11

GOOSE_TX 12

ETHERCAT 13

DNP_SERVER_FAILOVER 14

IEC61850_CLIENT 15

IEC61850_SERVER 16

NGVL 17

LG8979_CLIENT 18

LG8979_SERVER 19

IEC60870_CLIENT 20

IEC60870_SERVER 21

C37118_SERVER 22

SES92_SERVER 23

PGE2179_CLIENT 24

FLEX_PARSE_CLIENT 25

sel_file.Enum_event_type
This enumeration is defined in the underlying sel_file library. This enumeration
defines the types of events the database can store. It is part of the event handle
and should be used to help decide which sel_file.Enum_event_data to use when
opening an event.

Enumeration Description

NO_EVENT_TYPE There is no event type associated with this file.

CEV_FILE A plaintext file containing event data.

COMTRADE A zipped folder containing the event data as COMTRADE files.

Date Code 20241023 Programming Reference


408 FileIO
Enumerations

sel_file.Enum_event_data
This enumeration is defined in the underlying sel_file library. It defines how that
library attempts to open events.

Enumeration Description

RAW_DATA Return the data exactly as it is stored in the database.

CFG_FILE Treat the data as an archive and extract the first file with a .cfg
extension.

DAT_FILE Treat the data as an archive and extract the first file with a .dat
extension.

HDR_FILE Treat the data as an archive and extract the first file with a .hdr
extension.

INF_FILE Treat the data as an archive and extract the first file with a .inf
extension.

sel_file.Enum_sel_file_errors
This enumeration is defined in the underlying sel_file library. It defines the
status of file and SOE requests. After a call to a function, variables of this type
will display IN_PROGRESS for a time, after which they will change to some
other value. NO_ERROR implies that the task completed successfully, and
SYSTEM_BUSY means that the driver already has too many jobs queued that
it must complete before accepting any more jobs. In this case, a subsequent
request might succeed if one of the queued jobs has been completed. Any other
result should be descriptive of the error encountered.

Enumeration Description

NO_ERROR The request completed successfully.

FILE_NOT_FOUND The requested file was not found in the file system.

INVALID_FILE_NAME The file name provided was invalid.

INVALID_FH The file handle provided was not for an open file.

INVALID_FILTER The filter provided was invalid.

INVALID_TIMESTAMP The time stamp provided was invalid.

FS_OUT_OF_SPACE The file system did not have enough space to perform the action.

DIR_LIST_NOT_INIT The directory iterator has not been initialized.

SYSTEM_BUSY The system is too busy to process the request.

TOO_MANY_TASKS The system has received requests from more than two tasks.

OPERATION_FAILED There was a system call failure while processing the request.

IN_PROGRESS The system is processing the request.

Programming Reference Date Code 20241023


FileIO 409
Structures

sel_ftp_client.Enum_sel_ftp_client_errors
This enumeration is defined in the underlying sel_ftp_client library. It defines
the status of FTP requests. After a call to a function, variables of this type
will display IN_PROGRESS for a time, after which they will change to some
other value. NO_ERROR implies that the task completed successfully, and
SYSTEM_BUSY means that the driver already has too many jobs queued that
it must complete before accepting any more jobs. In this case, a subsequent
request might succeed if one of the queued jobs has been completed. Any other
result should be descriptive of the error encountered.

Enumeration Description

NO_ERROR The request successfully triggered an FTP attempt.

INIT_FAILED The FTP process is not responding.

INVALID_OPERATION There was a system call failure while processing the request.

INVALID_IP The IP address provided was not in the form XXX.XXX.XXX.XXX, where XXX is an integer that is ≤
255.

INVALID_USR_NAME The username provided contained invalid characters.

INVALID_PASSWORD The password provided contained invalid characters.

INVALID_FILE_NAME The file name provided contained invalid characters.

INVALID_MAX_TIME The time provided was less than or equal to 0.

FS_OUT_OF_SPACE The file system did not have enough space to perform the action.

SYSTEM_BUSY The system is too busy to process the request.

OPERATION_TIMEOUT The FTP attempt took longer than the provided time-out.

IN_PROGRESS The system is processing the request.

enum_FileType
Enumeration Description

ASCII COMTRADE data file is represented by ASCII data.

BINARY COMTRADE data file is represented by 16 bit binary data.

BINARY32 COMTRADE data file is represented by 32 bit binary data.

FLOAT32 COMTRADE data file is represented by 32 bit floating point data.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Date Code 20241023 Programming Reference


410 FileIO
Structures

struct_EventDetails
Name IEC 61131 Type Description

Handle Struct_event_handle The details required to access this event via the
database.

Device STRING(32) The name of the device the event was collected
from.

TimeStamp DT The time stamp of the event as seconds since


epoch.

TimeMilliseconds UINT The millisecond at which the event occurred.

FileSize DINT The size of the event in the database in bytes.

struct_EventDetails2
Name IEC 61131 Type Description

Handle Struct_event_handle The details required to access this event via the
database.

Device STRING(32) The name of the device the event was collected
from.

TimeStamp DT The time stamp of the event as seconds since


epoch.

TimeMilliseconds UINT The millisecond at which the event occurred.

FileSize DINT The size of the event in the database in bytes.

FileName STRING(255) The file name and path of the event.

sel_file.Struct_event_handle
This struct is defined in the underlying sel_file library. This struct contains all
information required to uniquely identify an event in the database.

Name IEC 61131 Type Description

EventID LINT An identifier of the event.

ProtocolID Enum_protocol_id An identifier of the protocol that gathered the


event.

EventType Enum_event_type The type of the event file.

Programming Reference Date Code 20241023


FileIO 411
Structures

sel_file.Struct_soe_content
This struct is defined in the underlying sel_file library. This struct contains all
value fields returned by an SOE query.

Name IEC 61131 Type Description

DeviceName STRING(255) The name of the device that logged this event
on the RTAC.

TagName STRING(255) The tag that changed prompting this SOE to be


logged.

Message STRING(255) The message of this SOE.

Category STRING(255) The category string provided for this SOE.

Priority STRING(255) The priority string provided for this SOE.

TimeStamp DT The time stamp of the event as seconds since


epoch.

Millisecond UINT The time at which the event occurred with


resolution to the ms.

DSTOffset INT The daylight-saving time offset that should be


applied to the time stamp.

UTCOffset INT The timezone offset that should be applied to


the time stamp.

AlarmEnabled BOOL This SOE can trigger an alarm.

sel_file.Struct_soe_content_id
This struct is defined in the underlying sel_file library. This struct contains all
value fields returned by an SOE query.

Name IEC 61131 Type Description

DeviceName STRING(255) The name of the device that logged this event
on the RTAC.

TagName STRING(255) The tag that changed prompting this SOE to be


logged.

Message STRING(255) The message of this SOE.

Category STRING(255) The category string provided for this SOE.

Priority STRING(255) The priority string provided for this SOE.

TimeStamp DT The time stamp of the event as seconds since


epoch.

Millisecond UINT The time at which the event occurred with


resolution to the ms.

DSTOffset INT The daylight-saving time offset that should be


applied to the time stamp.

UTCOffset INT The timezone offset that should be applied to


the time stamp.

AlarmEnabled BOOL This SOE can trigger an alarm.

Date Code 20241023 Programming Reference


412 FileIO
Structures

Name IEC 61131 Type Description

RemoteSoe BOOL The SOE was generated by a device other than


the local RTAC.

ID STRING(80) A unique identifier for this SOE.

sel_file.Struct_soe_filter
This struct is defined in the underlying sel_file library. This struct contains all
filters possible to apply to an SOE query. If left empty, no filter will be applied
on that field.
The filter string must contain only letters (case-sensitive); numbers; the symbols
_, -, and " " (space); and the wildcard characters * and ?. The character * acts as
a multicharacter wildcard and the character ? acts as a single character wildcard
when inside any string.

Name IEC 61131 Type Description

DeviceNameFilter STRING(255) The filter to place on the device name.

TagNameFilter STRING(255) The filter to use on the tag name.

MessageFilter STRING(255) The filter to use on the SOE message.

CategoryFilter STRING(255) The filter to use on the SOE category.

PriorityFilter STRING(255) The filter to use on the SOE priority.

ReturnAlarmSoeOnly BOOL Only return SOEs that can trigger an alarm.

struct_ComtradeInfo
Name IEC 61131 Type Description

StationName STRING(64) Substation name or location

RecordingDeviceId STRING(64) Recording device name or identification

RevisionYear STRING(4) Standard revision year

TotalChannelCount UDINT Total number of channels

AnalogChannelCount UDINT Number of analog channels

DigitalChannelCount UDINT Number of digital channels

NominalLineFreq REAL Nominal line frequency Hz

NumOfSampleRates UINT Number of sample rates

NumSamples UDINT Number of samples in the event

StartTime datetime_t Event record start time

TriggerTime datetime_t Event record trigger time

FileType STRING(8) Data file type

TimeMultFactor REAL Multiplication factor for time differential field


in data file

TimeCode STRING(6) Time code units defined in IEEE Std


C37.232-2007

Programming Reference Date Code 20241023


FileIO 413
Structures

Name IEC 61131 Type Description

LocalCode STRING(6) Time difference between local time and UTC


with time code units defined in IEEE Std
C37.232-2007

TimeQualityCode STRING(1) IEEE Std C37.118 time quality indicator code

LeapSecondCode UINT Leap second indicator code

struct_AnalogChannelInfo
Name IEC 61131 Type Description

AnalogChannelIndex UDINT Analog channel index number

ChannelId STRING(128) Alphanumeric channel name

PhaseId STRING(2) Channel phase identification

CircuitComponent STRING(64) Circuit component

ChannelUnits STRING(32) Alphanumeric channel units

ChannelMultipler REAL Channel multiplier

ChannelOffset REAL Channel offset

Skew REAL Time skew between channels

MinimumValue REAL Data range minimum value

MaximumValue REAL Data range maximum value

PrimaryRatio REAL PT/CT primary ratio

SecondaryRatio REAL PT/CT secondary ratio

ChannelScaling STRING(1) Primary or secondary scaling identifier

struct_DigitalChannnelInfo
Name IEC 61131 Type Description

DigitalChannelIndex UDINT Digital channel index number

ChannelId STRING(128) Alphanumeric channel name

PhaseId STRING(2) Channel phase identification

CircuitComponent STRING(64) Circuit component

NormalChannelState BOOL Normal state of the channel

struct_SamplingInfo
Name IEC 61131 Type Description

SampleRate REAL The sample rate in Hz

EndSample UDINT The last sample number at the sample rate

Date Code 20241023 Programming Reference


414 FileIO
Functions

Functions
This library provides the following functions, which allow single-operation
asynchronous actions. Each call has a status argument that must persist across
multiple scans. Calling any function does not complete the requested work, but
rather queues the work to be performed over multiple scans. This means you
should only call a given function once per desired operation. The system updates
the status variable automatically when the operation completes in either success
or failure. Avoid reusing pointers or variables passed as VAR_IN_OUT until the
status variable used has changed from the value of IN_PROGRESS.

fun_FtpDownload
Use this function to download files to the local, sequestered file system from an
FTP server.

Inputs
Name IEC 61131 Type Description

ftpServer STRING(15) The IP address of the FTP server being contacted.

localPath STRING(255) The local path and file name to which you are writing. It must begin with "/" and contain
the full file path. It may contain all printable ASCII characters between 16#20(Space) and
16#7E(~) except for ", ', :, <, %, >, ?, \, and |. It cannot contain any file path manipulation
variables (//, /./, /../).

remotePath STRING(255) The complete path and file name of the file to download from the FTP server. It must contain
only printable characters (ASCII values 0x32 to 0x7E inclusive), excluding single and double
quotation characters.

username STRING(32) The username to be used. This must only contain alphanumeric characters and "_".

password STRING(32) The password for use on the FTP server. This may contain any printable ASCII characters
excluding the quote characters.

timeout UDINT The number of seconds for the FTP attempt to run before it is canceled. This value must be
greater than 0.

Inputs/Outputs
Name IEC 61131 Type Description

status Enum_sel_ftp_client_errors The active status of this FTP event.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the FTP download request for processing.
➤ Validates that the time-out exceeds zero seconds.
➤ Validates that all string characters meet the prescribed requirements.
➤ Validates that at least 250 MB of space are available in the file system for
the download contents.

Programming Reference Date Code 20241023


FileIO 415
Functions

➤ Attempts to FTP the file onto the RTAC as an asynchronous event.


➤ A status of NO_ERROR implies that the FTP command was successfully
issued, the FTP service completed, and the service returned no error code.

fun_FtpEventUpload
Use this function to upload event files from the database to an FTP server.

Inputs
Name IEC 61131 Type Description

ftpServer STRING(15) The IP address of the FTP server being contacted.

localEvent Struct_event_handle The event file to upload.

remotePath STRING(255) The complete path and file name of the file to save on the FTP server. It must contain
only printable characters (ASCII values 0x32 to 0x7E inclusive), excluding single and
double quotation characters.

username STRING(32) The username to be used. This must only contain alphanumeric characters and "_".

password STRING(32) The password for use on the FTP server. This may contain any printable ASCII
characters excluding the quote characters.

timeout UDINT The number of seconds for the FTP attempt to run before it is canceled. This value must
be greater than 0.

Inputs/Outputs
Name IEC 61131 Type Description

status Enum_sel_ftp_client_errors The active status of this FTP event.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the FTP upload request for processing.
➤ Attempts to FTP the file from the RTAC as an asynchronous event.
➤ A status of NO_ERROR implies that the FTP command was successfully
issued, the FTP service completed, and the service returned no error code.

fun_FtpUpload
Use this function to upload individual files from the local, sequestered file
system to an FTP server.

Date Code 20241023 Programming Reference


416 FileIO
Functions

Inputs
Name IEC 61131 Type Description

ftpServer STRING(15) The IP address of the FTP server being contacted.

localPath STRING(255) The complete local path and file name to upload. It must begin with "/" and contain the full
file path. It may contain all printable ASCII characters between 16#20(Space) and 16#7E(~)
except for ", ', :, <, %, >, ?, \, and |. It cannot contain any file path manipulation variables
(//, /./, /../).

remotePath STRING(255) The complete path and file name of the file to write on the FTP server. It must contain only
printable characters (ASCII values 0x32 to 0x7E inclusive), excluding single and double
quotation characters.

username STRING(32) The username to be used. This must only contain alphanumeric characters and "_".

password STRING(32) The password for use on the FTP server. This may contain any printable ASCII characters
excluding the quote characters.

timeout UDINT The number of seconds for the FTP attempt to run before it is canceled. This value must be
greater than 0.

Inputs/Outputs
Name IEC 61131 Type Description

status Enum_sel_ftp_client_errors The active status of this FTP event.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the FTP upload request for processing.
➤ Attempts to FTP the file from the RTAC as an asynchronous event.
➤ A status of NO_ERROR implies that the FTP command was successfully
issued, the FTP service completed, and the service returned no error code.

fun_DeleteFile
Use this function to delete any file or empty folder from the sequestered file
system.

Inputs
Name IEC 61131 Type Description

filename STRING(255) The full path and file name of the file to delete. It may contain all printable ASCII characters
between 16#20(Space) and 16#7E(~) except for ", ', :, <, %, >, ?, \, and |. It cannot contain any
file path manipulation variables (//, /./, /../).

Inputs/Outputs
Name IEC 61131 Type Description

status Enum_sel_file_errors The variable where the state of the asynchronous


task that is deleting the file will be reported.

Programming Reference Date Code 20241023


FileIO 417
Functions

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the file deletion request for processing.
➤ If status later changes to NO_ERROR, the system successfully found and
deleted the file.
➤ If status later changes to OPERATION_FAILED, the system failed to
either find or delete the file.
➤ If status later changes to anything else, the system stopped the request
before the deletion command was issued.

fun_FileSize
Use this function to request the size of any file in the sequestered file system.
If the size of the file provided exceeds UDINT max (4,294,967,295) bytes,
then the value that is returned will roll over and equal the file size modulo
4,294,967,296.

Inputs
Name IEC 61131 Type Description

filename STRING(255) The full path and file name for the size calculations. It may contain all printable ASCII
characters between 16#20(Space) and 16#7E(~) except for ", ', :, <, %, >, ?, \, and |. It cannot
contain any file path manipulation variables (//, /./, /../).

Inputs/Outputs
Name IEC 61131 Type Description

status Enum_sel_file_errors The variable where the state of the asynchronous


task that is obtaining the file size will be reported.

sizeInBytes UDINT After completion, this variable contains the size


of the file in bytes.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the file size request for processing.
➤ If status later changes to NO_ERROR, sizeInBytes contains the file size.
➤ If status later changes to OPERATION_FAILED, then the system failed
to find the file.
➤ If status later changes to anything else, sizeInBytes is undefined.

fun_FilesystemFreeSpace
Use this function to validate how much usable space remains in the file system.
FileIO will not use all the space on the file system, and the value returned by
this function reflects that. When the value this function returns reaches zero,
additional writes to the file system through FileIO will fail.

Date Code 20241023 Programming Reference


418 FileIO
Functions

Inputs/Outputs
Name IEC 61131 Type Description

status Enum_sel_file_errors The variable where the state of the


asynchronous task that is obtaining the
file system free space will be reported.

spaceAvailable ULINT After completion, this variable contains


the space left in the file system that the
FileIO library can use, in bytes.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the file system size request for processing.
➤ If status later changes to NO_ERROR, spaceAvailable contains the file
system free space.
➤ If status later changes to anything else, spaceAvailable is undefined.

fun_SoeAscending
Use this function to request a limited number of SOEs from the database,
beginning with a specified time and moving toward the future.

Inputs
Name IEC 61131 Type Description

pt_soeBuffer POINTER TO Struct_soe_content Pointer to the array to populate with the SOE data. The array provided must
have at least maxSoeCount members, or memory corruption will occur.

startTime DT The earliest time to include in the results. This value must be between the
years 2000 and 2037, or the call will result in an error.

maxSoeCount UINT The maximum number of SOEs to place in pt_soeBuffer. This number must
exceed zero to obtain a non-error result and it must not exceed the number
of Struct_soe_content objects that can fit in the memory space pt_soeBuffer
points to, or memory corruption will occur.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE
list.

soeCount UINT The location to report the number of SOEs


placed in pt_soeBuffer.

Programming Reference Date Code 20241023


FileIO 419
Functions

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ If status later changes to NO_ERROR, soeCount SOEs were placed at
location pt_soeBuffer.
➤ If status later changes to anything else, values at pt_soeBuffer remain
unchanged.

fun_SoeDescending
Use this function to request a limited number of SOEs from the database,
beginning with a specified time and moving toward the past.

Inputs
Name IEC 61131 Type Description

pt_soeBuffer POINTER TO Struct_soe_content Pointer to the array to populate with the SOE data. The array provided must
have at least maxSoeCount members, or memory corruption will occur.

startTime DT The latest time to include in the results. This value must be between the years
2000 and 2037, or the call will result in an error.

maxSoeCount UINT The maximum number of SOEs to place in pt_soeBuffer. This number must
exceed zero to obtain a non-error result and it must not exceed the number
of Struct_soe_content objects that can fit in the memory space pt_soeBuffer
points to, or memory corruption will occur.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE
list.

soeCount UINT The location to report the number of SOEs


placed in pt_soeBuffer.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ If status later changes to NO_ERROR, soeCount SOEs were placed at
location pt_soeBuffer.
➤ If status later changes to anything else, values at pt_soeBuffer remain
unchanged.

Date Code 20241023 Programming Reference


420 FileIO
Functions

fun_SoeWindow
Use this function to request a limited number of SOEs from the database,
beginning with a specified time and moving toward the specified, future end
time.

Inputs
Name IEC 61131 Type Description

pt_soeBuffer POINTER TO Struct_soe_content Pointer to the array to populate with the SOE data. The array provided must
have at least maxSoeCount members, or memory corruption will occur.

startTime DT The earliest time to include in the results. This value must be between the
years 2000 and 2037, or the call will result in an error.

endTime DT The latest time to include in the results. This value must be between the years
2000 and 2037, or the call will result in an error.

maxSoeCount UINT The maximum number of SOEs to place in pt_soeBuffer. This number must
exceed zero to obtain a non-error result and it must not exceed the number
of Struct_soe_content objects that can fit in the memory space pt_soeBuffer
points to, or memory corruption will occur.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE
list.

soeCount UINT The location to report the number of SOEs


placed in pt_soeBuffer.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ If status later changes to NO_ERROR, soeCount SOEs were placed at
location pt_soeBuffer.
➤ If status later changes to anything else, values at pt_soeBuffer remain
unchanged.

fun_LocalSoeGetID
Use this function to request the data of a single SOE after a provided time
stamp. If the system finds no SOE after the time stamp, it provides the nearest
SOE before the time stamp. If the system finds no SOEs, then status reports an
error. Any data returned are for an SOE the local RTAC generated.

Programming Reference Date Code 20241023


FileIO 421
Functions

Inputs
Name IEC 61131 Type Description

soeTime DT The time near which to search for an SOE.


This value must be between the years 2000 and
2037, or the call will result in an error.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE id
will be reported.

soeData Struct_soe_content_id The location that will be populated with the


information describing the returned SOE.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ If status later changes to NO_ERROR, soeData contains the pertinent
information for one local SOE.
➤ If status later changes to anything else, the contents of soeData are
undefined.

fun_LocalSoeAscending
Use this function to request a limited number of SOEs from the database
beginning with a specified SOE and moving toward the future. The order of
the returned SOEs is the time of their creation on the RTAC, not the time of the
actual event. The local RTAC generated all returned SOEs.

Inputs
Name IEC 61131 Type Description

pt_soeBuffer POINTER TO Struct_soe_content_id Pointer to the array to populate with the SOE data. The array
provided must have at least maxSoeCount members, or memory
corruption will occur.

startID STRING(80) The unique identifier of a local SOE.

maxSoeCount UINT The maximum number of SOEs to place in pt_soeBuffer. This


number must exceed zero to obtain a non-error result and it must not
exceed the number of Struct_soe_content_id objects that can fit in
the memory space pt_soeBuffer points to, or memory corruption will
occur.

Date Code 20241023 Programming Reference


422 FileIO
Functions

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE list.

soeCount UINT The location to report the number of SOEs


placed in pt_soeBuffer.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ The selection of SOEs begins at the SOE after startID. If startID
represent an invalid SOE, the system returns no SOEs.
➤ If status later changes to NO_ERROR, soeCount SOEs were placed at
location pt_soeBuffer.
➤ If status later changes to anything else, values at pt_soeBuffer remain
unchanged.

fun_LocalSoeDescending
Use this function to request a limited number of SOEs from the database
beginning with a specified SOE and moving toward the past. The order of the
returned SOEs is the time of their creation on the RTAC, not the time of the
actual event. The local RTAC generated all returned SOEs.

Inputs
Name IEC 61131 Type Description

pt_soeBuffer POINTER TO Struct_soe_content_id Pointer to the array to populate with the SOE data. The array
provided must have at least maxSoeCount members, or memory
corruption will occur.

startID STRING(80) The unique identifier of a local SOE.

maxSoeCount UINT The maximum number of SOEs to place in pt_soeBuffer. This


number must exceed zero to obtain a non-error result and it must not
exceed the number of Struct_soe_content_id objects that can fit in
the memory space pt_soeBuffer points to, or memory corruption will
occur.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE list.

soeCount UINT The location to report the number of SOEs


placed in pt_soeBuffer.

Programming Reference Date Code 20241023


FileIO 423
Functions

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ The selection of SOEs begins at the SOE before startID. If startID
represent an invalid SOE, the system returns no SOEs.
➤ If status later changes to NO_ERROR, soeCount SOEs were placed at
location pt_soeBuffer.
➤ If status later changes to anything else, values at pt_soeBuffer remain
unchanged.

fun_RemoteSoeGetID
Use this function to request the data of a single SOE after a provided time
stamp. If the system finds no SOE after the time stamp, it provides the nearest
SOE before the time stamp. If the system finds no SOEs, then status reports
an error. Any data returned are an SOE a device other than the local RTAC
generated.

Inputs
Name IEC 61131 Type Description

soeTime DT The time near which to search for an SOE.


This value must be between the years 2000 and
2037, or the call will result in an error.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable where the state of the


asynchronous task that is obtaining the SOE id
will be reported.

soeData Struct_soe_content_id The location that will be populated with the


information describing the returned SOE.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ If status later changes to NO_ERROR, soeData contains the pertinent
information for one remote SOE.
➤ If status later changes to anything else, the contents of soeData are
undefined.

Date Code 20241023 Programming Reference


424 FileIO
Functions

fun_RemoteSoeAscending
Use this function to request a limited number of SOEs from the database
beginning with a specified SOE and moving toward the future. The order of
the returned SOEs is the time of their creation on the RTAC, not the time of the
actual event. A device other than the local RTAC generated all SOEs returned.

Inputs
Name IEC 61131 Type Description

pt_soeBuffer POINTER TO Struct_soe_content_id Pointer to the array to populate with the SOE data. The array
provided must have at least maxSoeCount members, or memory
corruption will occur.

startID STRING(80) The unique identifier of a remote SOE.

maxSoeCount UINT The maximum number of SOEs to place in pt_soeBuffer. This


number must exceed zero to obtain a non-error result and it must not
exceed the number of Struct_soe_content_id objects that can fit in
the memory space pt_soeBuffer points to, or memory corruption will
occur.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE
list.

soeCount UINT The location to report the number of SOEs


placed in pt_soeBuffer.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ The selection of SOEs begins at the SOE after startID. If startID
represent an invalid SOE, the system returns no SOEs.
➤ If status later changes to NO_ERROR, soeCount SOEs were placed at
location pt_soeBuffer.
➤ If status later changes to anything else, values at pt_soeBuffer remain
unchanged.

fun_RemoteSoeDescending
Use this function to request a limited number of SOEs from the database
beginning with a specified SOE and moving toward the past. The order of the
returned SOEs is the time of their creation on the RTAC, not the time of the
actual event. A device other than the local RTAC generated all SOEs returned.

Programming Reference Date Code 20241023


FileIO 425
Classes

Inputs
Name IEC 61131 Type Description

pt_soeBuffer POINTER TO Struct_soe_content_id Pointer to the array to populate with the SOE data. The array
provided must have at least maxSoeCount members, or memory
corruption will occur.

startID STRING(80) The unique identifier of a remote SOE.

maxSoeCount UINT The maximum number of SOEs to place in pt_soeBuffer. This


number must exceed zero to obtain a non-error result and it must not
exceed the number of Struct_soe_content_id objects that can fit in
the memory space pt_soeBuffer points to, or memory corruption will
occur.

Inputs/Outputs
Name IEC 61131 Type Description

filters Struct_soe_filter The values defining the filter criteria.

status Enum_sel_file_errors The variable that reports the state of the


asynchronous task that is obtaining the SOE list.

soeCount UINT The location to report the number of SOEs


placed in pt_soeBuffer.

Processing
➤ Sets status to IN_PROGRESS.
➤ Queues the SOE request for processing.
➤ The selection of SOEs begins at the SOE after startID. If startID
represent an invalid SOE, the system returns no SOEs.
➤ If status later changes to NO_ERROR, soeCount SOEs were placed at
location pt_soeBuffer.
➤ If status later changes to anything else, values at pt_soeBuffer remain
unchanged.

Classes
This library provides the following classes as extensions of the IEC 61131
function block.

class_DirectoryListing (Class)
This class calls the sel_file.sel_open_dir() function after a new listing
is requested by the call to CreateNewList(). On the task where this class
is instantiated, Run() must be called once on every scan to handle all of the
asynchronous file system interactions. While there are still items to list, Run()
will call sel_file.sel_read_dir() once each scan until the complete
directory listing is built.

Date Code 20241023 Programming Reference


426 FileIO
Classes

Outputs
Name IEC 61131 Type Description

InProgress BOOL Stays TRUE while the Run() method constructs


the listing. The class ignores any calls to
CreateNewList() while this output is TRUE.

Error BOOL TRUE if the directory listing could not be created.

ErrorDesc STRING(255) The last error encountered is described here.

NewListReady BOOL Once a list has been built, this output is set to
TRUE.

CreateNewList (Method)
This is one of the methods that can be called each time a new directory listing is
required. If no filter is given, it will provide a complete listing of the directory.

Inputs

Name IEC 61131 Type Description

directoryName STRING(255) The directory path to get file list from. Path
separators should be the "/" character.

filter STRING(255) If not blank, only those files that contain this
substring will be appended to the list.

Processing
➤ Clears Error.
➤ Sets the NewListReady value to FALSE and destroys any internal lists.
➤ Initiates the enumeration of the directory, carried out by the Run()
method.

CreateNewerThanList (Method)
This is one of the methods that can be called each time a new directory listing is
required. This method causes a list to be generated that contains all files with a
date code equal to or newer than the value passed in.

Inputs

Name IEC 61131 Type Description

directoryName STRING(255) The directory path to get file list from. Path
separators should be the "/" character.

filter STRING(255) If not blank, only those files that contain this
substring will be appended to the list.

mtimeSec DT Last UTC modification time (DT#yyyy-mm-


dd-00:00:00)

Programming Reference Date Code 20241023


FileIO 427
Classes

Processing
➤ Clears Error.
➤ Sets the NewListReady value to FALSE and deletes any internal lists.
➤ Initiates the enumeration of the directory, carried out by the Run()
method.

GetList (Method)
The call to this method must occur after the NewListReady output is TRUE to
obtain the populated class_SELStringList. There can only be one call to this
method per created list.

Inputs/Outputs

Name IEC 61131 Type Description

list SELString.class_SELStringList The class_SelStringList to write the directory listing to. See the SELString library for
more information about the type class_SELStringList.

Outputs

Name IEC 61131 Type Description

NewestFileTime timeStamp_t The most recent update time, in UTC, among the listed files.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the class_SELStringList provided was populated


successfully.

Processing
➤ Returns FALSE if NewListReady is not TRUE.
➤ Populates list with the prepared list.
➤ Sets the NewListReady class output to FALSE.
➤ Destroys the internal list.

Run (Method)
Call this method on every scan. It supervises the asynchronous directory listing.

Date Code 20241023 Programming Reference


428 FileIO
Classes

Processing
➤ If a directory listing has been initiated:
➢ Ensure that the directory is opened, using the
sel_file.sel_open_dir() function.
➢ Repeatedly call the sel_file.sel_read_dir() and append
a class_SELString to list for each file name containing the filter
substring, until no more file names are returned.
➤ Once the directory listing is complete, it closes the operation by setting
NewListReady to TRUE and calling sel_file.sel_close_dir().
➤ If any error occurs, Error is set to TRUE and ErrorDesc is populated
appropriately.

class_EventReportListing (Class)
This class has been completely removed from the library. If it was included in
projects, these projects will now provide compile-time errors. If you want event
access, the class_EventListing provides access to those files along with non-
obfuscated file names, the ability to filter queries based on several criteria, and
the ability to properly open COMTRADE file collections to view individual
files.
Please note that the class_EventListing class does have one limitation that this
class did not. All class_EventListing objects on a single RTAC task (e.g., Main
or Automation) share an internal iterator. It is best practice to only have one
class_EventListing per task.

class_EventListing (Class)
This class calls sel_file.sel_begin_event_iterator_filtered()
after a new listing request activated by a call to CreateNewList() or
CreateNewFilteredList(). On the task in which this class is instantiated,
Run() must be called once on every scan to handle all of the asynchronous
file system interactions. While there are still items to list, Run() calls
sel_file.sel_next_event() once each scan until the complete directory
listing is built.
All class_EventListing objects on a single RTAC task (e.g., Main or
Automation) share an internal iterator. It is best practice to only have one
class_EventListing per task.

Outputs
Name IEC 61131 Type Description

InProgress BOOL Stays TRUE while the Run() method constructs


the listing. The class ignores any calls to
CreateNewList() while this output is TRUE.

Error BOOL TRUE if the directory listing could not be created.

ErrorDesc STRING(255) The last error encountered is described here.

NewListReady BOOL Once a list has been built, this output is set to
TRUE.

Programming Reference Date Code 20241023


FileIO 429
Classes

CreateNewList (Method)
This method may be called each time a new listing of event reports is required.
It filters by device name only.

Inputs/Outputs
Name IEC 61131 Type Description

deviceName STRING(32) If not blank, only events from this device will be
listed.

Processing
➤ Clears Error.
➤ Sets the NewListReady value to FALSE and destroys any internal lists.
➤ Initiates the enumeration of the directory, carried out by the Run()
method.

CreateNewFilteredList (Method)
This method may be called each time a new listing of event reports is required.
It filters by device name, time of creation, the reporting protocol, and the event
type.

Inputs/Outputs
Name IEC 61131 Type Description

deviceName STRING(32) If not blank, only events from this device will
be listed.

Inputs
Name IEC 61131 Type Description

startTime DT The earliest time stamp of a returned event as


seconds since epoch.

endTime DT The latest time stamp of a returned event as


seconds since epoch.

protocol Enum_protocol_id The protocol that collected the events.

eventType Enum_event_type The type of the events to be presented.

Processing
➤ Clears Error.
➤ Sets the NewListReady value to FALSE and destroys any internal lists.
➤ Initiates the enumeration of the events, carried out by the Run() method.
➤ Values of NO_PROTOCOL_SPECIFIED, NO_EVENT_TYPE, or zero
for startTime and endTime result in the associated filter not being used.

Date Code 20241023 Programming Reference


430 FileIO
Classes

GetList (Method)
The call to this method must occur after the NewListReady output is TRUE to
obtain the vector of event handles. There can only be one call to this method per
created list.

Inputs/Outputs

Name IEC 61131 Type Description

list DynamicVectors.class_BaseVector The vector to write the directory listing to. This vector must have been initialized with
an element size SIZEOF(struct_EventDetails).

See the DynamicVectors library for more information about the type
class_BaseVector.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the class_BaseVector provided was populated


successfully.

Processing
➤ Returns FALSE if NewListReady is not TRUE.
➤ Populates list with the prepared list.
➤ Sets the NewListReady class output to FALSE.
➤ Destroys the internal list.

Run (Method)
Call this method on every scan. It supervises the asynchronous event report
listing.

Processing
➤ If an event listing has been initiated:
➢ Ensure that the listing is opened by using
sel_file.sel_begin_event_iterator().
➢ Repeatedly call sel_file.sel_next_event() and append a
struct_EventDetails to list for each of the returned files that were
issued by deviceName until the system returns no more files.
➤ Once the directory listing is complete, it closes the operation by setting
NewListReady to TRUE.
➤ If any error occurs, Error is set to TRUE and ErrorDesc is populated
appropriately.

Programming Reference Date Code 20241023


FileIO 431
Classes

class_EventListing2 (Class)
This class provides identical event listing functionality to that offered in
class_EventListing(), but it operates on struct_EventDetails2 elements
when using the GetList method. It also calls sel_file.sel_next_event2()
internally while iterating through all the event records located in the RTAC's
event list. This class is only compatible with RTAC firmware R151 or later.

class_FileWriter (Class)
This class provides the ability to write files to the sequestered RTAC file system.
This class is instantiated with a specific file name. The return value of each
method is based on the success or failure of queuing the requested action.
The final success or failure of each action is not determined until processing
completes after multiple calls to the Run() method, which you must call every
scan to perform whatever file-handling actions are buffered in its internal queue.
The maximum amount of data that can be buffered at one time before writing
to the specified file is dictated by the g_p_FileIo_MaxBufferSize parameter,
detailed in Global Parameters on page 406.

Initialization Inputs
Name IEC 61131 Type Description

filename STRING(255) The full path of the file opened in append mode. The character "/" delimits the folder path.
This path must end with the full file name, including extension. It may contain all printable
ASCII characters between 16#20(Space) and 16#7E(~) except for ", ', :, <, %, >, ?, \, and |. It
cannot contain any file path manipulation variables (//, /./, /../). If the file does not exist, it will
be created.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

BytesLeft UDINT R Number of unwritten bytes in the internal buffer.

Filename STRING(255) R/W Write to this property to set the next file to which data are written. It may contain all
printable ASCII characters between 16#20(Space) and 16#7E(~) except for ", ', :, <,
%, >, ?, \, and |. It cannot contain any file path manipulation variables (//, /./, /../).

Writing to this property sets the FileRename output true. If data are appended to this
class while FileRename is TRUE, subsequent attempts to set Filename are ignored
until FileRename returns to FALSE.

After modifying Filename, any append method call queues data for the new file.

Inputs
Name IEC 61131 Type Description

MaxBufferSizeOverride UDINT Optional. The Maximum buffer size for file writes. Default value equals
param_FileIo.g_p_FileIo_MaxBufferSize.

Date Code 20241023 Programming Reference


432 FileIO
Classes

Outputs
Name IEC 61131 Type Description

Error BOOL TRUE if the function block cannot write the


contents of its buffer to file.

ErrorDesc STRING(255) The last error encountered will be described here.

FileRename BOOL After the Filename property is set, this pin will
remain TRUE until all pending writes to the
previous file name have been completed.

AppendBytes (Method)
Call this method whenever bytes are to be appended to the write buffer. Every
subsequent call of the Run() method will write as many bytes as possible until
nothing remains in the write buffer.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the item to write to file, as


returned by the ADR() function.

numBytes UDINT The number of bytes to write, starting with


pt_data.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE for successful addition of the data to the output buffer.

Processing
➤ Check that numBytes exceeds 0.
➤ Check that the memory region specified has read access.
➤ If both previous statements are true, copy the contents of the specified
region into the output buffer.
➤ If the copy succeeded, return TRUE.
➤ If any error occurs, the method sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

AppendSELString (Method)
Call this method to append the content of a class_SELString to the write buffer.

Inputs/Outputs
Name IEC 61131 Type Description

strSel class_SELString The class_SELString to append.

Programming Reference Date Code 20241023


FileIO 433
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of strSel was successfully added to the
output buffer.

Processing
➤ Copy the content of the supplied string to the output buffer.
➤ If the copy succeeded, return TRUE.
➤ If any error occurs, the method sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

AppendString (Method)
Call this method to append the content of a string to the write buffer.

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(255) The string to append.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of str was successfully added to the
output buffer.

Processing
➤ Copy the content of the supplied string to the output buffer.
➤ If the copy succeeded, return TRUE.
➤ If any error occurs, the method sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

AppendVector (Method)
Call this method to append the content of a vector to the write buffer.

Inputs

Name IEC 61131 Type Description

vector I_Vector The vector to append to the file. See the


DynamicVectors library documentation for
information about the I_Vector interface.

Date Code 20241023 Programming Reference


434 FileIO
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the vector was successfully added to the output
buffer.

Processing
➤ Check that vector passed in is valid and has contents to copy.
➤ Copy the content of the dynamic vector into the output buffer.
➤ If the copy succeeded, return TRUE.
➤ If any error occurs, the method sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

Run (Method)
Call this method on every scan to supervise the asynchronous writing of the
internal buffer to the specified file.

Processing
➤ If the file is not open, this method opens it in append mode and stores the
file handle internally.
➤ If the file is open and there are data in the internal buffer, this method
writes to the opened file.
➤ Monitors the asynchronous write process, clears the buffer of written
data, and subtracts number of bytes written from BytesLeft.
➤ If any error occurs, this method sets Error to TRUE and fills ErrorDesc
appropriately.

class_FileReader2 (Class)
The maximum file size that can be read using this class is dictated by the
g_p_FileIo_MaxBufferSize parameter, detailed in Global Parameters on
page 406, unless overridden by the MaxBufferSizeOverride class input.

The BytesToReadPerScan input provides the ability to define the number


of bytes that the RTAC reads from a file during a single RTAC task cycle.
This input allows more control over the time it takes to read contents from
the file into the logic engine. Changing this input from the default value can
lead to increased task usage on the RTAC task that is responsible for the file
read. To update the bytes to read per scan, assign a value to the class input
BytesToReadPerScan prior to the first call to the Run method.

When using the MaxBufferSizeOverride class input to read files larger than
10MB, a spike in task cycle usage that scales with the file size is expected for
the first file read only.

Programming Reference Date Code 20241023


FileIO 435
Classes

Inputs
Name IEC 61131 Type Description

BytesToReadPerScan UDINT (Optional) The number of bytes that this instance of class_FileReader2
reads in a single processing interval. This input supports a range of 1,024 to
512,000 bytes per processing interval. Default is 5,000.

MaxBufferSizeOverride UDINT (Optional). The Maximum buffer size for file reads. This input
supports a range of 1,048,576 to 524,288,000 bytes. Default is
param_FileIo.g_p_FileIo_MaxBufferSize.

Outputs
Name IEC 61131 Type Description

InProgress BOOL Stays TRUE while the Run() method reads a file.
The class ignores any calls to a read method while
this output is TRUE.

Error BOOL TRUE if the function block cannot read contents of


the file into buffer.

ErrorDesc STRING(255) The last error encountered is described here.

BytesInBuffer UDINT The number of bytes that were read from file. Set
to 0 when a read method is called, and populated
when read is complete.

ReadFile (Method)
Call this method to read the content of a file into the internal buffer.

Inputs

Name IEC 61131 Type Description

filename STRING(255) The full path to the file of interest within the sequestered file system. The character "/" delimits
the folder path. This path must end with the full file name, including extension. It may contain
all printable ASCII characters between 16#20(Space) and 16#7E(~) except for ", ', :, <, %, >, ?, \,
and |. It cannot contain any file path manipulation variables (//, /./, /../).

Processing
➤ Checks that a read operation is not in progress.
➤ Ensures that the first character of filename is "/". This method prepends
the character if it is missing from the filename provided.
➤ Initiates a read operation, which Run() performs.

ReadEventFromDB (Method)
Call this method to read the content of an event from the database into the
internal buffer. Populate inputs startByte and totalBytes to read a window of
bytes from COMTRADE data (.dat) file types into the internal buffer.

Date Code 20241023 Programming Reference


436 FileIO
Classes

Inputs

Name IEC 61131 Type Description

handle Struct_event_handle The details required to request this event from the database.

fileType Enum_event_data The file extension to attempt to extract from this event.

startByte UDINT The starting byte position of the event to read from the database. Optional input that
defaults to 0.

totalBytes UDINT The total number of bytes to read from the database event. Set this value to 0 to read all
bytes from startByte to the end of the file. Optional input that defaults to 0.

Processing
➤ Checks that a read operation is not in progress.
➤ Initiates a read operation, which Run() performs.

CopyTo (Method)
Copies the contents of the buffer to a user-accessible location.

Inputs

Name IEC 61131 Type Description

startByte UDINT Indicates the first byte to copy as an offset


from the beginning of the internal buffer.

pt_byte POINTER TO BYTE The destination address to where the bytes


should be copied.

numBytes UDINT The maximum number of bytes to write out,


starting with startByte.

Return Value

IEC 61131 Type Description

UDINT Returns the number of bytes copied to the destination address.

Processing
➤ Checks that startByte is less than BytesInBuffer and that pt_byte is a valid
pointer with write access. If the initial checks fail, return 0.
➤ Copies contents of internal buffer to destination until all remaining bytes
in buffer have been copied or numBytes specified have been copied.
➤ Returns the number of bytes copied.

AppendToSELString (Method)
Copies the contents of the internal buffer to a class_SELString.

Programming Reference Date Code 20241023


FileIO 437
Classes

Inputs
Name IEC 61131 Type Description

startByte UDINT Indicates the first byte to copy as an offset from the
beginning of the internal buffer.

Inputs/Outputs
Name IEC 61131 Type Description

strSel class_SELString The class_SELString to which the contents of the internal buffer will be appended. See the
SELString library documentation for information about the class_SELString type.

Return Value
IEC 61131 Type Description

UDINT Returns the number of characters added to the SELString.

Processing
➤ Checks that startByte is less than BytesInBuffer. If the initial check fails,
returns 0.
➤ Beginning with startByte, appends the bytes from the internal buffer to
the strSel supplied, until one of the following occurs:
1. The class_SELString throws an internal error.
2. No bytes remain in the buffer.
➤ Returns the number of characters added to strSel.

CopyToString (Method)
Copies the content of the internal buffer to a string.

NOTE
This method assumes that the string str is of type STRING(255). Smaller
strings will cause undesired behavior.

Inputs
Name IEC 61131 Type Description

startByte UDINT Indicates the first byte to copy as an offset from the
beginning of the internal buffer.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(255) The string to which the content of the internal


buffer will be written.

Date Code 20241023 Programming Reference


438 FileIO
Classes

Return Value

IEC 61131 Type Description

UDINT Returns the number of characters added to the string.

Processing
➤ Checks that startByte is less than BytesInBuffer. If the initial check fails,
returns 0.
➤ Copies the bytes from the internal buffer to str until either of the
following occurs:
1. Two hundred and fifty-five (255) characters have been copied.
2. No bytes remain in the buffer.
➤ Appends a null terminator onto the str.

AppendToVector (Method)
Allows the content of the buffer to be copied to the end of a user-accessible
vector.

Inputs

Name IEC 61131 Type Description

startByte UDINT Indicates the first byte to copy as an offset from the beginning of the internal buffer.

vector I_Vector The vector to which the internal buffer content is appended. See the DynamicVectors library
documentation for information about the I_Vector interface.

Return Value

IEC 61131 Type Description

UDINT Returns the number of elements added to the vector.

Processing
➤ Checks that startByte is less than BytesInBuffer. If the initial check fails,
return 0.
➤ Pushes the contents of the buffer into the supplied vector.
➤ If the number of bytes specified for the copied output (BytesInBuffer
minus startByte) is not evenly divisible by the vector ElementSize, then
pads the last element appended to vector with trailing zeros.

Run (Method)
Call this method on every scan to supervise the asynchronous reading of the
specified file into the internal buffer.

Programming Reference Date Code 20241023


FileIO 439
Classes

Processing
➤ On the first call of Run, the MaxBufferSizeOverride class input will be
fixed and cannot be modified again during runtime. If the input value is
outside of the specified bounds, it will be set to the nearest acceptable
value.
➤ Waits until the initiation of a file read operation by the ReadFile() or
ReadEventFromDB methods.
➤ If the file is not open, opens the file in read mode and stores the file
handle internally.
➤ If the file is open and a read has been signaled by the ReadFile() or
ReadEventFromDB methods, monitors the asynchronous task until
complete.
➤ Populates BytesInBuffer upon completion of the read.
➤ If any error occurs, this method sets Error TRUE and fills ErrorDesc
appropriately.

class_FileReader (Class)
This is a deprecated class that is now an exact copy of class_FileReader2.
The ability to view event files by name only has been removed from the file
system. Projects that contain the ReadEventReport method will now generate
compile-time errors. Reading files should be accomplished using full paths or
Struct_event_handle objects.
The g_p_FileIo_MaxBufferSize parameter, detailed in Global Parameters on
page 406, dictates the maximum file size that can be read using this class.
If you use this class, consider refactoring to use class_FileReader2.

class_BasicDirectoryManager (Class)
This class manages files within a given directory by removing files based on
the size of the directory, the number of files in the directory, or the maximum
number of days to hold a file since modified.
This class does not do the following:
➤ Directly write any files.
➤ Modify any files.
➤ Monitor files within a subdirectory.
Before you can use class_BasicDirectoryManager to manage a directory, it must
be provided the folder path to monitor, a maximum size for that directory, and
either a maximum number of files to hold or a maximum number of days for
which to hold files.

File Blacklisting
File blacklisting allows for files to be ignored by the
class_BasicDirectoryManager. A blacklisted file cannot be deleted, and it is not
counted in the total directory size or number of files.
A file is blacklisted by having a period (.) as the first character in the file name.

Date Code 20241023 Programming Reference


440 FileIO
Classes

For example, a file named ".somefile.txt" is ignored by


class_BasicDirectoryManager, while a file named "MySpecialFileData.txt" is
managed by class_BasicDirectoryManager.

File Rotation
Periodically, the class compares the new directory size against the maximum
permitted directory size set in the object declaration. If the directory exceeds the
maximum folder size, the oldest file is deleted. If only one file exists, no files
are deleted. This allows the single file to overfill the allotted maximum until the
creation of a new file. This means that if the maximum number of files is set to
one, the manager never deletes files based on the directory size or age of the file.

Outputs
Name IEC 61131 Type Description

Directory STRING(128) The directory being managed.

Error BOOL TRUE if the class encounters any error.

ErrorDesc STRING(255) The last error encountered by this class.

SpaceUsed ULINT The size, in bytes, of all managed files in this


directory.

MaxFolderSize ULINT The size, in bytes, at which the directory begins


deleting files, starting at the oldest.

MaxFileCount UDINT The maximum number of files this directory stores.


A value of zero indicates that MaxFileCount is
ignored.

MaxDaysHeld UDINT The maximum number of days this directory stores


files based on the time stamp. A value of zero
indicates that MaxDaysHeld is ignored.

bootstrap_SetDirectory (Method)
This method is called once, before any other method, to configure the
class_BasicDirectoryManager. It provides the values the class uses to determine
what directory to watch and when to delete files.

Inputs
Name IEC 61131 Type Description

folderName STRING(127) The folder to use and manage. The character "/" delimits the folder path. It may contain
all printable ASCII characters between 16#20(Space) and 16#7E(~) except for ", ', :, <,
%, >, ?, \, and |. It cannot contain any file path manipulation variables (//, /./, /../). If the
folder does not exist, the class will show an error until the directory is created by some
other mechanism.

maximumFolderSize ULINT The size, in bytes, at which the directory begins deleting files, starting at the oldest.

maximumNumFiles UDINT The maximum number of files this directory stores. A value of zero indicates that
maximumNumFiles is ignored.

maximumNumDays UDINT The maximum number of days this directory stores files based on the time stamp. A
value of zero indicates that maximumNumDays is ignored.

Programming Reference Date Code 20241023


FileIO 441
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors occurred during bootstrapping.

Run (Method)
Call this method on every scan. It supervises the asynchronous deletion of old
files. Deletions occur only if the number of files in the directory, the size of the
directory, or the number of days to hold a file exceeds user-set limits.

Processing
This class maintains an internal state machine with a round-robin job scheduler,
ensuring that the amount of processing overhead per scan remains relatively
constant.

Subsequent calls to the Run() method perform the following sequence of


operations:

1. If the directory listing is exhausted:


a. Determine the cutoff file for deletions on the next scan by performing
the following steps:
i. Collect a running total of space moving backward in time.
ii. Find the file that causes the space to be exceeded and store its
time stamp.
iii. Find the file that exceeds the file count and store its time stamp.
iv. Set the cutoff time to the newest of the two saved time stamps.
b. Restart the directory iterator.
2. If the directory listing is not exhausted, perform one of the following
checks on the next file:
a. If the file is blacklisted, ignore it.
b. If the file is managed and newer than the cutoff time from the
previous directory scan, leave it alone.
c. If the file is managed and older than the cutoff time from the previous
directory scan, delete it.

class_DirectoryManager (Class)
This class allows for the creation of managed files, over time, in a controlled
directory. It provides protection for the size of the directory, the number of files
in the directory, and the size of those files.

Before you can use this class to manage a directory, you must provide it the
folder path designating to where log files are written, a maximum size for that
directory, a maximum number of files to allow in that directory, and a postfix to
add to log files.

Date Code 20241023 Programming Reference


442 FileIO
Classes

This class uses class_FileWriter objects to perform the writing of log files
and event logs. See class_FileWriter (Class) on page 431 for more detailed
information about the limitations on the maximum size of log files or maximum
number of buffered log entries.

File Entries
File entries take exactly the data provided and append this information to the
active file. No additional formatting is performed.

Event Logs
In addition to log files, you may want to create a separate file that records
information corresponding to some event, with custom formatting. These
are referred to as "Event Logs," and should not be confused with the "Event
Records" relays generate, containing high-resolution waveforms. An event file
is simply a custom log file written out to the managed directory, rotated with the
files (as described in File Rotation on page 442), and sent to the same FTP
server (if set) for this manager object.

Event Logs are stored with the time stamp of when they were created.
The format for these files is YYYY-MM-DD-HH-MM_eventPostfix, where
eventPostfix is defined in the method call to write the file.

It is important to recognize that, because the file name does not include
seconds, two events recorded within the same minute and defined with the
same eventPostfix argument will cause the contents of the second event to be
appended to the end of the first file.

File Rotation
Periodically, the class compares the new directory size against the maximum
permitted directory size set in the object declaration. If the directory exceeds the
maximum folder size, the oldest file is deleted. If no other files exist except the
active file, no files are deleted. This allows the single active file to overfill the
allotted maximum until the creation of a new file.

Inputs
Name IEC 61131 Type Description

MaxBufferSizeOverride UDINT Optional. The Maximum buffer size for file writes. Default value equals
param_FileIo.g_p_FileIo_MaxBufferSize.

Outputs
Name IEC 61131 Type Description

Directory STRING(127) The directory being managed.

ActiveFile STRING(128) The rotating file presently waiting for write


requests.

Error BOOL TRUE if the class cannot write the contents of its
buffer to file.

Programming Reference Date Code 20241023


FileIO 443
Classes

Name IEC 61131 Type Description

ErrorDesc STRING(255) The last error encountered by this class.

SpaceUsed ULINT The size, in bytes, of all managed files in this


directory.

MaxFolderSize ULINT The size, in bytes, at which the directory begins


deleting files, starting at the oldest.

MaxFileSize UDINT The size, in bytes, at which this class rotates its
automatically generated files.

MaxFileCount UDINT The maximum number of files this directory stores.


A value of zero indicates that MaxFileCount is
ignored.

bootstrap_SetDirectory (Method)
This method is called once, before any other method, to configure the
class_DirectoryManager. It provides the values the class uses to determine
where to store files, what to call them, and when to create and delete them.

Inputs

Name IEC 61131 Type Description

folderName STRING(127) The folder to use and manage. The character "/" delimits the folder path. It may contain
all printable ASCII characters between 16#20(Space) and 16#7E(~) except for ", ', :, <,
%, >, ?, \, and |. It cannot contain any file path manipulation variables (//, /./, /../). If the
folder does not exist, it will be created the first time that a file is written. Any files in this
directory that are not managed files will be deleted.

filenamePostfix STRING(16) A string that is added to the end of the time-stamped file name on every file.

maximumFolderSize UDINT The size, in bytes, at which the directory manager begins deleting files, starting at the
oldest.

maximumFileSize UDINT The size, in bytes, at which this class rotates its automatically generated files.

maximumNumFiles UDINT The maximum number of files this directory stores. A value of zero indicates that
maximumNumFiles is ignored.

rollFileAtDay BOOL Close the working file each day at midnight and start a new file.

SetFtpServerForArchiving (Method)
Call this method once to specify a remote FTP server to which generated files
are sent and how often the files should be sent.

Every FTP attempt generates a log file to assist with debugging (overwriting
the previous log file if it exists). The file includes success notifications as well
as errors the ftp client encounters (such as a bad username or password). View
the following file, found at the root of the sequestered file system, via a web
browser after attempting an FTP file transfer:

ftplog.txt

Date Code 20241023 Programming Reference


444 FileIO
Classes

Inputs
Name IEC 61131 Type Description

ftpServer STRING(15) The IP address of the FTP server being contacted.

remotePath STRING(127) The folder on the FTP server to where the local files are sent.

username STRING(32) The FTP username used to log into the server. This must contain only
alphanumeric or underscore characters.

password STRING(32) The password associated with the FTP username used to log into the server. This
may contain any printable ASCII characters, excluding the quote characters.

timeout UDINT The number of seconds for the FTP attempt to be run before it is canceled. Must
be greater than 0.

schedule enum_FtpSendSchedule Specify when local files should be sent to the remote FTP server.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the arguments provided are within range.

Processing
➤ Validates the input strings and confirms that a valid IP address is
provided.
➤ If the inputs provided are valid, sets internal variables so that the Run()
method attempts to send files, and returns TRUE.
➤ If the inputs provided are invalid, returns FALSE.

SetFileHeaderBytes (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A numBytes of zero clears any existing header; new files will be
started with the first data entry instead.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to use as the header
block, as returned by the ADR() function.

numBytes UDINT The number of bytes to store, beginning with


pt_data.

SetFileHeaderSELString (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A strSel of Size zero clears any existing header; new files will
be started with the first data entry instead.

Programming Reference Date Code 20241023


FileIO 445
Classes

Inputs/Outputs

Name IEC 61131 Type Description

strSel class_SELString The class_SELString to use as the header block.

SetFileHeaderString (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A str of LEN zero clears any existing header; new files will be
started with the first data entry instead.

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(255) The string to use as the header block.

SetFileHeaderVector (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A vector of Size zero clears any existing header; new files will
be started with the first data entry instead.

Inputs

Name IEC 61131 Type Description

vector I_Vector The vector to use as the header block. See the
DynamicVectors library documentation for
information about the I_Vector interface.

SetFileFooterBytes (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A numBytes of zero clears any existing footer.

Inputs

Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to use as the footer
block, as returned by the ADR() function.

numBytes UDINT The number of bytes to store, beginning with


pt_data.

Date Code 20241023 Programming Reference


446 FileIO
Classes

SetFileFooterSELString (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A strSel of Size zero clears any existing footer.

Inputs/Outputs
Name IEC 61131 Type Description

strSel class_SELString The class_SELString to use as the footer block.

SetFileFooterString (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A str of LEN zero clears any existing footer.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(255) The string to use as the footer block.

SetFileFooterVector (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A vector of Size clears any existing footer.

Inputs
Name IEC 61131 Type Description

vector I_Vector The vector to use as the new footer block. See
the DynamicVectors library documentation for
information about the I_Vector interface.

StartNewFile (Method)
Use this method to close the active file and begin a new one. Unless
you call this method, a new file starts only if the conditions provided in
bootstrap_SetDirectory() are met, (i.e., rollFileAtDay is TRUE and a
new day has begun or the active file size exceeded maximumFileSize).

Processing
➤ For an active log file and a non-empty footer string, this method places
that string at the end of the active file.
➤ Closes the active file.
➤ Creates a new file with the present time stamp.
➤ For a non-empty header string, places that string at the top of the new file.

Programming Reference Date Code 20241023


FileIO 447
Classes

WriteToFileBytes (Method)
Call this method to append a raw byte array to the active file.

Inputs/Outputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to write to file, as


returned by the ADR() function.

numBytes UDINT The number of bytes to write, beginning with


pt_data.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the content of pt_data was successfully added to the
output buffer.

Processing
➤ Appends numBytes characters, starting at address pt_data to the output
buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteToFileSELString (Method)
Call this method to append an SELString to the active file.

Inputs/Outputs
Name IEC 61131 Type Description

strSel class_SELString The class_SELString to append.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the content of strSel was successfully added to the
output buffer.

Processing
➤ Appends the content of selStr to the output buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

Date Code 20241023 Programming Reference


448 FileIO
Classes

WriteToFileString (Method)
Call this method to append a string to the active file.

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(255) The string to append to the file.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of str was successfully added to the
output buffer.

Processing
➤ Appends the value of str to the output buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteToFileVector (Method)
Call this method to append a vector of data to the active file.

Inputs/Outputs

Name IEC 61131 Type Description

vector I_Vector The vector to append to the file. See the


DynamicVectors library documentation for
information about the I_Vector interface.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of vector was successfully added to the
output buffer.

Processing
➤ Appends the content of vector to the output buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

Programming Reference Date Code 20241023


FileIO 449
Classes

EventLogFromBytes (Method)
Call this method to write a log file with contents defined in a contiguous set of
memory.

Inputs

Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to write to file, as


returned by the ADR() function.

numBytes UDINT The number of bytes to write, beginning with


pt_data.

Inputs/Outputs

Name IEC 61131 Type Description

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromSELString (Method)
Call this method to write a log file with contents defined in a class_SELString.

Inputs/Outputs

Name IEC 61131 Type Description

strSel class_SELString The content of the event file.

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Date Code 20241023 Programming Reference


450 FileIO
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromString (Method)
Call this method to write a log file with contents defined in a string.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(255) The content of the event file.

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromVector (Method)
Call this method to write a log file with contents defined in an I_Vector.

Programming Reference Date Code 20241023


FileIO 451
Classes

Inputs

Name IEC 61131 Type Description

vector I_Vector The content of the event file. See the


DynamicVectors library documentation for
information about the I_Vector interface.

Inputs/Outputs

Name IEC 61131 Type Description

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

Run (Method)
Call this method on every scan. It supervises the asynchronous writing of
queued data to active files and the asynchronous deletion of old files. Deletions
occur only if the number of files in the directory or size of the directory exceed
user-set limits.

This method is also responsible for sending local files to a remote


FTP server if the user has configured FTP through a successful call to
SetFtpServerForArchiving().

Processing
This class maintains an internal state machine with a round-robin job scheduler,
ensuring that the amount of processing overhead per scan remains relatively
constant.

Date Code 20241023 Programming Reference


452 FileIO
Classes

Subsequent calls to the Run() method perform the following sequence of


operations:
1. If the system day of year has changed since the last time Run() was
called and the class is set to start a new file each day, the method starts a
new log by calling the StartNewFile() method.
2. Is this object already in one of the states described in Processing States on
page 452?
➤ Yes: Continues execution of that state.
➤ No: Evaluates the job priority list described in Processing Jobs on
page 452 and executes the next job.
3. Calls Run() on the internal class_FileWriter object that handles the
writing of entries.
4. Calls Run() on the internal class_FileWriter object that handles the
writing of event logs.

Processing Jobs
Only one job is performed per call to this method. The jobs are listed below in
priority order:
1. Enters the Send File state if a write operation has been completed since
the last Send File state completed (determined by looking for the falling
edge of class_FileWriter.BytesLeft <> 0).
2. Enters the Directory Housekeeping state if there is no directory listing or
the last listing was exhausted.
3. Enters the Resend File state if there are unsent files that have not been
synchronized to the remote server.

Processing States
Some of the jobs in Processing Jobs on page 452 cause this object to enter a
state. The following describes these states and their exit criteria:
➤ Send File: This state exits immediately if a valid FTP server was not
provided using the method SetFtpServerForArchiving().
If the FTP server was set appropriately, the behavior of this state varies
depending on the value of the schedule argument passed in using the
SetFtpServerForArchiving() method call. Enumerations on
page 1232 defines the enumeration for this argument.
➢ schedule = ON_CLOSE: If this write was initiated by the
StartNewFile() method, the closed file is sent to the FTP server
using the sel_ftp_client.ftp_upload() function call.
The state is maintained until the file is sent and then successfully read
back using the sel_ftp.ftp_download() function call.
If any error occurs, this method sets Error to TRUE and fills
ErrorDesc appropriately.
➢ schedule = ON_UPDATE: The active file is sent to the server using
the method call sel_ftp.ftp_upload().
➤ Directory Housekeeping: The following sub-states exist in this state.
➢ Obtain the size of the active file.
➢ If the active file size is greater than maximumFileSize, start a new file.

Programming Reference Date Code 20241023


FileIO 453
Classes

➢ If the file list is exhausted:


1. Determine the cutoff file for deletions on the next scan by
performing the following steps:
a. Collect a running total of space moving backward in time.
b. Find the file that causes space to be exceeded and store the
time stamp of that file.
c. Find the file that exceeds the file count moving backward in
time and store its time stamp.
d. Set the cutoff time to the newest of the two saved time stamps.
2. Restart the directory iterator.
➢ If the directory listing is not exhausted, perform one of the following
checks on the next file:
➣ If unmanaged, delete it.
➣ If the file is managed and newer than the cutoff time from the
previous directory scan, leave it alone.
➣ If the file is managed and older than the cutoff time from the
previous directory scan, delete it.

class_TimeBasedDirectoryManager (Class)
This class allows for the creation of managed files, over time, in a controlled
directory. It provides protection for the size of the directory, the number of files
in the directory, and the size of those files.
Before you can use this class to manage a directory, you must provide it the
folder path designating to where log files are written, a maximum size for that
directory, a maximum number of days for which to hold files, and a postfix to
add to log files.
This class uses class_FileWriter objects to perform the writing of log files
and event logs. See class_FileWriter (Class) on page 431 for more detailed
information about the limitations on the maximum size of log files or maximum
number of buffered log entries.

File Entries
File entries take exactly the data provided and append this information to the
active file. No additional formatting is performed.

Event Logs
In addition to log files, you may want to create a separate file that records
information corresponding to some event, with custom formatting. These
are referred to as "Event Logs," and should not be confused with the "Event
Records" relays generate, containing high-resolution waveforms. An event file
is simply a custom log file written out to the managed directory, rotated with the
files (as described in File Rotation on page 454), and sent to the same FTP
server (if set) for this manager object.
Event Logs are stored with the time stamp of when they were created.
The format for these files is YYYY-MM-DD-HH-MM_eventPostfix, where
eventPostfix is defined in the method call to write the file.

Date Code 20241023 Programming Reference


454 FileIO
Classes

It is important to recognize that, because the file name does not include
seconds, two events recorded within the same minute and defined with the
same eventPostfix argument will cause the contents of the second event to be
appended to the end of the first file.

File Rotation
Periodically, the class compares the new directory size against the maximum
permitted directory size set in the object declaration. If the directory exceeds the
maximum folder size, the oldest file is deleted. If no other files exist except the
active file, no files are deleted. This allows the single active file to overfill the
allotted maximum until the creation of a new file.

Outputs
Name IEC 61131 Type Description

Directory STRING(127) The directory being managed.

ActiveFile STRING(128) The rotating file presently waiting for write


requests.

Error BOOL TRUE if the class cannot write the contents of its
buffer to file.

ErrorDesc STRING(255) The last error encountered by this class.

SpaceUsed ULINT The size, in bytes, of all managed files in this


directory.

MaxFolderSize ULINT The size, in bytes, at which the directory begins


deleting files, starting at the oldest.

MaxFileSize UDINT The size, in bytes, at which this class rotates its
automatically generated files.

MaxDaysHeld UDINT The maximum number of days this directory stores


files based on the time stamp.

bootstrap_SetDirectory (Method)
This method is called once, before any other method, to configure the class. It
provides the values the class uses to determine where to store files, what to call
them, and when to create and delete them.

Inputs
Name IEC 61131 Type Description

folderName STRING(127) The folder to use and manage. The character "/" delimits the folder path. It may contain
all printable ASCII characters between 16#20(Space) and 16#7E(~) except for ", ', :, <,
%, >, ?, \, and |. It cannot contain any file path manipulation variables (//, /./, /../). If the
folder does not exist, it will be created the first time that a file is written. Any files in this
directory that are not managed files will be deleted.

filenamePostfix STRING(16) A string that is added to the end of the time-stamped file name on every file.

maximumFolderSize UDINT The size, in bytes, at which the directory begins deleting files, starting at the oldest.

maximumFileSize UDINT The size, in bytes, at which this class rotates its automatically generated files.

Programming Reference Date Code 20241023


FileIO 455
Classes

Name IEC 61131 Type Description

maximumNumDays UDINT The maximum number of days from today this directory stores files based on the time
stamp.

rollFileAtDay BOOL Close the working file each day at midnight and start a new file.

SetFileHeaderBytes (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A numBytes of zero clears any existing header; new files will be
started with the first data entry instead.

Inputs

Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to use as the header
block, as returned by the ADR() function.

numBytes UDINT The number of bytes to store, beginning with


pt_data.

SetFileHeaderSELString (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A strSel of Size zero clears any existing header; new files will
be started with the first data entry instead.

Inputs/Outputs

Name IEC 61131 Type Description

strSel class_SELString The class_SELString to use as the header block.

SetFileHeaderString (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A str of LEN zero clears any existing header; new files will be
started with the first data entry instead.

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(255) The string to use as the header block.

Date Code 20241023 Programming Reference


456 FileIO
Classes

SetFileHeaderVector (Method)
This method sets a block of text the class will place at the beginning of every
non-event file it creates. If you desire a newline, you must include it in the
provided data. A vector of Size zero clears any existing header; new files will
be started with the first data entry instead.

Inputs
Name IEC 61131 Type Description

vector I_Vector The vector to use as the header block. See the
DynamicVectors library documentation for
information about the I_Vector interface.

SetFileFooterBytes (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A numBytes of zero clears any existing footer.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to use as the footer
block, as returned by the ADR() function.

numBytes UDINT The number of bytes to store, beginning with


pt_data.

SetFileFooterSELString (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A strSel of Size zero clears any existing footer.

Inputs/Outputs
Name IEC 61131 Type Description

strSel class_SELString The class_SELString to use as the footer block.

SetFileFooterString (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A str of LEN zero clears any existing footer.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(255) The string to use as the footer block.

Programming Reference Date Code 20241023


FileIO 457
Classes

SetFileFooterVector (Method)
This method sets a block of text the class will place at the end of every non-
event file it creates. If you desire a newline, you must include it in the provided
data. A vector of Size clears any existing footer.

Inputs

Name IEC 61131 Type Description

vector I_Vector The vector to use as the new footer block. See
the DynamicVectors library documentation for
information about the I_Vector interface.

StartNewFile (Method)
Use this method to close the active file and begin a new one. Unless
you call this method, a new file starts only if the conditions provided in
bootstrap_SetDirectory() are met, (i.e., rollFileAtDay is TRUE and a
new day has begun or the active file size exceeded maximumFileSize).

Processing
➤ For an active log file and a non-empty footer string, this method places
that string at the end of the active file.
➤ Closes the active file.
➤ Creates a new file with the present time stamp.
➤ For a non-empty header string, places that string at the top of the new file.

WriteToFileBytes (Method)
Call this method to append a raw byte array to the active file.

Inputs/Outputs

Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to write to file, as


returned by the ADR() function.

numBytes UDINT The number of bytes to write, beginning with


pt_data.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of pt_data was successfully added to the
output buffer.

Date Code 20241023 Programming Reference


458 FileIO
Classes

Processing
➤ Appends numBytes characters, starting at address pt_data to the output
buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteToFileSELString (Method)
Call this method to append an SELString to the active file.

Inputs/Outputs

Name IEC 61131 Type Description

strSel class_SELString The class_SELString to append.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of strSel was successfully added to the
output buffer.

Processing
➤ Appends the content of selStr to the output buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteToFileString (Method)
Call this method to append a string to the active file.

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(255) The string to append to the file.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of str was successfully added to the
output buffer.

Programming Reference Date Code 20241023


FileIO 459
Classes

Processing
➤ Appends the value of str to the output buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteToFileVector (Method)
Call this method to append a vector of data to the active file.

Inputs/Outputs
Name IEC 61131 Type Description

vector I_Vector The vector to append to the file. See the


DynamicVectors library documentation for
information about the I_Vector interface.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the content of vector was successfully added to the
output buffer.

Processing
➤ Appends the content of vector to the output buffer.
➤ Does not append a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

EventLogFromBytes (Method)
Call this method to write a log file with contents defined in a contiguous set of
memory.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to write to file, as


returned by the ADR() function.

numBytes UDINT The number of bytes to write, starting with


pt_data.

Inputs/Outputs
Name IEC 61131 Type Description

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Date Code 20241023 Programming Reference


460 FileIO
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromSELString (Method)
Call this method to write a log file with contents defined in a class_SELString.

Inputs/Outputs
Name IEC 61131 Type Description

strSel class_SELString The content of the event file.

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromString (Method)
Call this method to write a log file with contents defined in a string.

Programming Reference Date Code 20241023


FileIO 461
Classes

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(255) The content of the event file.

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromVector (Method)
Call this method to write a log file with contents defined in an I_Vector.

Inputs

Name IEC 61131 Type Description

vector I_Vector The content of the event file. See the


DynamicVectors library documentation for
information about the I_Vector interface.

Inputs/Outputs

Name IEC 61131 Type Description

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Date Code 20241023 Programming Reference


462 FileIO
Classes

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

Run (Method)
Call this method on every scan. It supervises the asynchronous writing of
queued data to active files and the asynchronous deletion of old files. Deletions
occur only if the number of files in the directory or size of the directory exceed
user-set limits.

This method is also responsible for sending local files to a remote


FTP server if the user has configured FTP through a successful call to
SetFtpServerForArchiving().

Processing
This class maintains an internal state machine with a round-robin job scheduler,
ensuring that the amount of processing overhead per scan remains relatively
constant.

Subsequent calls to the Run() method perform the following sequence of


operations:

1. If the system day of year has changed since the last time Run() was
called and the class is set to start a new file each day, the method starts a
new log by calling the StartNewFile() method.
2. Is this object already in one of the states described in Processing States on
page 452?
➤ Yes: Continues execution of that state.
➤ No: Evaluates the job priority list described in Processing Jobs on
page 452 and executes the next job.
3. Calls Run() on the internal class_FileWriter object that handles the
writing of entries.
4. Calls Run() on the internal class_FileWriter object that handles the
writing of event logs.

Programming Reference Date Code 20241023


FileIO 463
Classes

Processing Jobs
Only one job is performed per call to this method. The jobs are listed below in
priority order:

1. Enters the Send File state if a write operation has been completed since
the last Send File state completed (determined by looking for the falling
edge of class_FileWriter.BytesLeft <> 0).
2. Enters the Directory Housekeeping state if there is no directory listing or
the last listing was exhausted.
3. Enters the Resend File state if there are unsent files that have not been
synchronized to the remote server .

Processing States
Some of the jobs in Processing Jobs on page 463 cause this object to enter a
state. The following describes these states and their exit criteria:

➤ Send File: This state exits immediately if a valid FTP server was not
provided using the method SetFtpServerForArchiving().
If the FTP server was set appropriately, the behavior of this state varies
depending on the value of the schedule argument passed in using the
SetFtpServerForArchiving() method call. Enumerations on
page 1232 defines the enumeration for this argument.
➢ schedule = ON_CLOSE: If this write was initiated by the
StartNewFile() method, the closed file is sent to the FTP server
using the sel_ftp_client.ftp_upload() function call.
The state is maintained until the file is sent and then successfully read
back using the sel_ftp.ftp_download() function call.
If any error occurs, this method sets Error to TRUE and fills
ErrorDesc appropriately.
➢ schedule = ON_UPDATE: The active file is sent to the server using
the method call sel_ftp.ftp_upload().
➤ Directory Housekeeping: The following sub-states exist in this state.
➢ Obtain the size of the active file.
➢ If the active file size is greater than maximumFileSize, start a new file.
➢ If the file list is exhausted:
1. Determine the cutoff file for deletions on the next scan by
performing the following steps:
a. Collect a running total of space moving backward in time.
b. Find the file that causes space to be exceeded and store the
time stamp of that file.

Date Code 20241023 Programming Reference


464 FileIO
Classes

c. Calculate and save the time stamp that exceeds the


maxNumDays value.
d. Set the cutoff time to the newest of the two saved time stamps.
2. Restart the directory iterator.
➢ If the directory listing is not exhausted, perform one of the following
checks on the next file:
➣ If unmanaged, delete it.
➣ If the file is managed and newer than the cutoff time from the
previous directory scan, leave it alone.
➣ If the file is managed and older than the cutoff time from the
previous directory scan, delete it.

class_LogDirectoryManager (Class)
This class allows for the creation of managed files, over time, in a controlled
directory. It provides protection for the size of the directory, the number of files
in the directory, and the size of those files.

Before you can use this class to manage a directory, you must provide it the
folder path designating to where log files are written, a maximum size for that
directory, a maximum number of files to allow in that directory, and a postfix to
add to log files.

This class uses class_FileWriter objects to perform the writing of log files
and event logs. See class_FileWriter (Class) on page 431 for more detailed
information about the limitations on the maximum size of log files or maximum
number of buffered log entries.

Log Entries
Log entries are prefixed with a time stamp and added as a single-row entry to the
active log file.

The log file names are stored with the time stamp of when they were created.
The format for these files is YYYY-MM-DD-HH-MM_logPostfix, where
logPostfix is set in the declaration of the class.

Event Logs
In addition to log files, you may want to create a separate file that records
information corresponding to some event, with custom formatting. These
are referred to as "Event Logs," and should not be confused with the "Event
Records" relays generate, containing high-resolution waveforms. An event file
is simply a custom log file written out to the managed directory, rotated with
the log files (as described in File Rotation on page 465), and sent to the same
FTP server (if set) for this manager object.

Event Logs are stored with the time stamp of when they were created.
The format for these files is YYYY-MM-DD-HH-MM_eventPostfix, where
eventPostfix is defined in the method call to write the file.

Programming Reference Date Code 20241023


FileIO 465
Classes

It is important to recognize that, because the file name does not include
seconds, two events recorded within the same minute and defined with the
same eventPostfix argument will cause the contents of the second event to be
appended to the end of the first file.

File Rotation
Periodically, the class compares the new directory size against the maximum
permitted directory size set in the object declaration. If the directory exceeds
the maximum folder size, the oldest file is deleted. If no other files exist except
the active log file, no files are deleted. This allows the single active log file to
overfill the allotted maximum until the creation of a new log file.

Initialization Inputs

Name IEC 61131 Type Description

folderName STRING(127) The folder to write logs to and manage. The character "/" delimits the folder path. It may
contain all printable ASCII characters between 16#20(Space) and 16#7E(~) except for ",
', :, <, %, >, ?, \, and |. It cannot contain any file path manipulation variables (//, /./, /../).
If the folder does not exist, it will be created the first time that a log is written. Any files
in this directory that are not log files will be deleted.

logPostfix STRING(16) A string that is added to the end of the time-stamped file name on every log file.

maxFolderSize UDINT The size, in bytes, at which the directory begins deleting files, starting at the oldest.

maxNumFiles UDINT The maximum number of files this directory stores. A value of zero indicates that
maxNumFiles is ignored.

autoStartNewLogDaily BOOL If this is TRUE, a new log file is automatically created on the first PLC scan of every
day, regardless of whether an entry is written that day. If FALSE, a new log file will only
be created at the first log entry method call.

Outputs

Name IEC 61131 Type Description

Directory STRING(127) The directory being managed.

ActiveFile STRING(128) The rotating file presently waiting for write


requests.

Error BOOL TRUE if the class cannot write the contents of its
buffer to file.

ErrorDesc STRING(255) The last error encountered by this class.

SpaceUsed ULINT The size, in bytes, of all managed files in this


directory.

MaxFolderSize ULINT The size, in bytes, at which the directory begins


deleting files, starting at the oldest.

MaxFileSize UDINT The size, in bytes, at which this class rotates its
automatically generated files.

MaxFileCount UDINT The maximum number of files this directory stores.


A value of zero indicates that MaxFileCount is
ignored.

Date Code 20241023 Programming Reference


466 FileIO
Classes

SetFtpServerForArchiving (Method)
Call this method once to specify a remote FTP server to which generated files
are sent and how often the files should be sent.

Every FTP attempt generates a log file to assist with debugging (overwriting
the previous log file if it exists). The file includes success notifications as well
as errors the ftp client encounters (such as a bad username or password). View
the following file, found at the root of the sequestered file system, via a web
browser after attempting an FTP file transfer:

ftplog.txt

Inputs

Name IEC 61131 Type Description

ftpServer STRING(15) The IP address of the FTP server being contacted.

remotePath STRING(127) The folder on the FTP server to where the local files are sent.

username STRING(32) The FTP username used to log into the server. This must contain only alphanumeric or
underscore characters.

password STRING(32) The password associated with the FTP username used to log into the server. This may
contain any printable ASCII characters, excluding the quote characters.

timeout UDINT The number of seconds for the FTP attempt to be run before it is canceled. Must be
greater than 0.

schedule enum_FtpSendSchedule Specify when local files should be sent to the remote FTP server.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the arguments provided are within range.

Processing
➤ Validates the input strings and confirms that a valid IP address is
provided.
➤ If the inputs provided are valid, sets internal variables so that the Run()
method attempts to send files, and returns TRUE.
➤ If the inputs provided are invalid, returns FALSE.

StartNewLog (Method)
Call this method to create a new log file. All new log entries are added to this
file until this method is called again or the system day of year changes. Do not
call this method if you desire exactly one log file per day.

Programming Reference Date Code 20241023


FileIO 467
Classes

Processing
➤ If there was an active log file, adds a log entry with the text: --End log
file--
➤ Updates internal retained variable storing the active log time via the
SYS_TIME() function call.
➤ Adds a log to this new file with the text: --Begin log file--

WriteLogEntryBytes (Method)
Call this method to append a raw byte array to the active log file.

Inputs/Outputs

Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to write to file, as


returned by the ADR() function.

numBytes UDINT The number of bytes to write, beginning with


pt_data.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of pt_data was successfully added to the
output buffer.

Processing
➤ Gets the current date from SYS_TIME().
➤ Writes the time stamp of the log entry to the output buffer in the form
YYYY-MM-DD-HH-MM-SS.MiS, where MiS is milliseconds.
➤ Appends numBytes characters starting at address pt_data to the output
buffer.
➤ Appends a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteLogEntrySELString (Method)
Call this method to append an SELString to the active log file.

Inputs/Outputs

Name IEC 61131 Type Description

strSel class_SELString The class_SELString to append.

Date Code 20241023 Programming Reference


468 FileIO
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of strSel was successfully added to the
output buffer.

Processing
➤ Gets the current date from SYS_TIME().
➤ Writes the time stamp of the log entry to the output buffer in the form
YYYY-MM-DD-HH-MM-SS.MiS, where MiS is milliseconds.
➤ Appends the content of selStr to the output buffer.
➤ Appends a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteLogEntryString (Method)
Call this method to append a string to the active log file.

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(255) The string to add to the log.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the content of str was successfully added to the
output buffer.

Processing
➤ Gets the current date from SYS_TIME().
➤ Writes the time stamp of the log entry to the output buffer in the form
YYYY-MM-DD-HH-MM-SS.MiS, where MiS is milliseconds.
➤ Appends the value of str to the output buffer.
➤ Appends a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

WriteLogEntryVector (Method)
Call this method to append a vector of data to the active log file.

Programming Reference Date Code 20241023


FileIO 469
Classes

Inputs/Outputs
Name IEC 61131 Type Description

vector I_Vector The vector to append to the file. See the


DynamicVectors library documentation for
information about the I_Vector interface.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the content of vector was successfully added to the
output buffer.

Processing
➤ Gets the current date from SYS_TIME().
➤ Writes the time stamp of the log entry to the output buffer in the form
YYYY-MM-DD-HH-MM-SS.MiS, where MiS is milliseconds.
➤ Appends the content of vector to the output buffer.
➤ Appends a newline to the output buffer.
➤ If any error occurs, sets Error TRUE and populates ErrorDesc
appropriately.

EventLogFromBytes (Method)
Call this method to write a log file with contents defined in a contiguous set of
memory.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The address of the bytes to write to file, as


returned by the ADR() function.

numBytes UDINT The number of bytes to write, starting with


pt_data.

Inputs/Outputs
Name IEC 61131 Type Description

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Date Code 20241023 Programming Reference


470 FileIO
Classes

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromSELString (Method)
Call this method to write a log file with contents defined in a class_SELString.

Inputs/Outputs
Name IEC 61131 Type Description

strSel class_SELString The content of the event file.

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromString (Method)
Call this method to write a log file with contents defined in a string.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(255) The content of the event file.

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Programming Reference Date Code 20241023


FileIO 471
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

EventLogFromVector (Method)
Call this method to write a log file with contents defined in an I_Vector.

Inputs
Name IEC 61131 Type Description

vector I_Vector The content of the event file. See the


DynamicVectors library documentation for
information about the I_Vector interface.

Inputs/Outputs
Name IEC 61131 Type Description

eventPostfix STRING(16) A string that is added to the end of the time-


stamped file name of an event log file.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the data are successfully added to the output buffer.

Processing
➤ Obtains the system time through the SYS_TIME() function call.
➤ Constructs the new file name from the time and eventPostfix.
➤ Sets the internal class_FileWriter object that handles event logs to use the
new file name.
➤ Passes the provided data to the internal class_FileWriter that handles
event logs.
➤ If any error occurs, sets Error to TRUE, populates ErrorDesc
appropriately, and returns FALSE.

Date Code 20241023 Programming Reference


472 FileIO
Classes

Run (Method)
Call this method on every scan. It supervises the asynchronous writing of
queued data to active files and the asynchronous deletion of old files. Deletions
occur only if the number of files in the directory or size of the directory exceed
user-set limits.

This method is also responsible for sending local files to a remote


FTP server if the user has configured FTP through a successful call to
SetFtpServerForArchiving().

Processing
This class maintains an internal state machine with a round-robin job scheduler,
ensuring that the amount of processing overhead per scan remains relatively
constant.

Subsequent calls to the Run() method perform the following sequence of


operations:

1. If the system day of year has changed since the last time Run() was
called, the method starts a new log by calling the StartNewLog()
method.
2. Is this object already in one of the states described in Processing States on
page 473?
➤ Yes: Continues execution of that state.
➤ No: Evaluates the job priority list described in Processing Jobs on
page 472 and executes the next job.
3. Calls Run() on the internal class_FileWriter object that handles the
writing of entries.
4. Calls Run() on the internal class_FileWriter object that handles the
writing of event logs.

Processing Jobs
Only one job is performed per call to this method. The jobs are listed below in
priority order:

1. Enters the Send File state if a write operation has been completed since
the last Send File state completed (determined by looking for the falling
edge of class_FileWriter.BytesLeft <> 0).
2. Enters the Directory Housekeeping state if there is no directory listing or
the last listing was exhausted.
3. Enters the Resend File state if there are unsent files that have not been
synchronized to the remote server.

Programming Reference Date Code 20241023


FileIO 473
Classes

Processing States
Some of the jobs in Processing Jobs on page 472 cause this object to enter a
state. The following describes these states and their exit criteria:
➤ Send File: This state exits immediately if a valid FTP server was not
provided using the method SetFtpServerForArchiving().
If the FTP server was set appropriately, the behavior of this state varies
depending on the value of the schedule argument passed in using the
SetFtpServerForArchiving() method call. Enumerations on
page 1232 defines the enumeration for this argument.
➢ schedule = ON_CLOSE: If this write was initiated by the
StartNewLog() method, the closed file is sent to the FTP server
using the sel_ftp_client.ftp_upload() function call.
The state is maintained until the file is sent and then successfully read
back using the sel_ftp.ftp_download() function call.
If any error occurs, this method sets Error to TRUE and fills
ErrorDesc appropriately.
➢ schedule = ON_UPDATE: The active file is sent to the server using
the method call sel_ftp.ftp_upload().
➤ Directory Housekeeping: The following sub-states exist in this state.
➢ Obtain the size of the active file.
➢ If the active file size is greater than 1/3 of the maxFolderSize, start a
new file.
➢ If the file list is exhausted:
1. Determine the cutoff file for deletions on the next scan by
performing the following steps:
a. Collect a running total of space moving backward in time.
b. Find the file that causes space to be exceeded and store the
time stamp of that file.
c. Find the file that exceeds the file count moving backward in
time and store its time stamp.
d. Set the cutoff time to the newest of the two saved time stamps.
2. Restart the directory iterator.
➢ If the directory listing is not exhausted, perform one of the following
checks on the next file:
➣ If unmanaged, delete it.
➣ If the file is managed and newer than the cutoff time from the
previous directory scan, leave it alone.
➣ If the file is managed and older than the cutoff time from the
previous directory scan, delete it.

class_ComtradeParser (Class)
This class provides the necessary functionality to read COMTRADE .dat
and .cfg event files from the RTAC's database into the logic engine. The class
automatically parses the COMTRADE file using information from the .cfg file.
The initial release of this class only supports SEL Axion COMTRADE event
files.

Date Code 20241023 Programming Reference


474 FileIO
Classes

This class leverages FileIO.class_FileReader2 for reading COMTRADE events.

Because this class manages asynchronous file operations, call the Run() method
of the instantiated class on every scan to ensure that all queued work is correctly
performed and monitored after calling the ReadEventFromDB() method.

This class is compatible with the following COMTRADE standards:

➤ IEEE C37.111-1999
➤ IEEE C37.111-2013

This class is compatible with the following file types:

➤ BINARY
➤ FLOAT32

The BytesToReadPerScan input provides the ability to define the number of


bytes that the RTAC reads from the COMTRADE data file during a single
processing interval. Changing this input from the default value can lead to
increased task usage on the RTAC task that is responsible for the file read. To
update the bytes to read per scan, assign a value to the BytesToReadPerScan
input prior to the first call this class Run method.

Inputs
Name IEC 61131 Type Description

BytesToReadPerScan UDINT (Optional) The number of bytes that class_ComtradeParser reads from the data file in
a single processing interval. This input supports a range of 1,024 to 512,000 bytes per
processing interval. Default is 5,000.

MaxEventSize UDINT (Optional) The Maximum buffer size for file reads. This input
supports a range of 1,048,576 to 524,288,000 bytes. Default is
param_FileIo.g_p_FileIo_param_FileIo.g_p_FileIo_MaxBufferSize.

Outputs
Name IEC 61131 Type Description

InProgress BOOL Remains TRUE while the Run() method reads an


event. The class ignores any calls to read methods
while this output is TRUE.

Error BOOL TRUE if the function block is unable to read or


parse a COMTRADE event file.

ErrorDesc STRING(255) The last error encountered is described here.

CfgBytes UDINT The number of bytes read from the .cfg file.

DatBytes UDINT The number of bytes read from the .dat file.

NewEventReady BOOL Asserts TRUE for one processing interval after


event is successfully retrieved from database.

Programming Reference Date Code 20241023


FileIO 475
Classes

ReadEventFromDB (Method)
Call this method to initiate reading an event from the RTAC's database. After
calling this method, Run() reads the event that matches the device identification
and has a trigger time that is within TimeVar. If the file cannot be found, Run()
continues looking for the event for the duration of WaitTime. When Run() finds
an event that matches the input criteria, it reads the contents of the event into
internal data buffers for later use.

The optional StartSample and TotalSamples inputs provide the ability to read a
window of samples from the COMTRADE data (.dat) file only. Setting a value
of 0 to StartSample and TotalSamples results in reading all contents contained in
the COMTRADE data file.

Calling this method more than once every logic processing interval results in the
last call overwriting previous calls. If more than one call per processing interval
is expected, instantiate multiple instances of class_ComtradeParser for each call.

Inputs
Name IEC 61131 Type Description

DeviceId STRING(255) The name of the device that generates the COMTRADE event. Must be equivalent to the .cfg
DeviceID field.

TriggerTime dateTime_t The event's trigger time. If exact match does not exist, this method reads an event within
TimeVar milliseconds of TriggerTime.

TimeVar UINT The time variance in milliseconds allowed between TriggerTime and the event's actual trigger
time (0–1000 milliseconds).

WaitTime UINT The amount of time that ReadEventFromDB() waits until the event is available in the database
(1–60 minutes). This method keeps looking for the event until WaitTime transpires.

StartSample UDINT The starting sample to read from the COMTRADE file. Optional input that defaults to 0.

TotalSamples UDINT The total number of samples, beginning from StartSample, in the COMTRADE data file
to read into the RTAC's internal buffers. A value of 0 results in reading all samples from
StartSample to the end of the of the file. Optional input that defaults to 0.

Processing
➤ ReadEventFromDB() call sets InProgess to TRUE and Error to FALSE.
➤ ReadEventFromDB() configures parameters for the event to be read.
➤ ReadEventFromDB() method enforces the maximum and minimum
limits on TimeVar and WaitTime. For values greater than or less than the
maximum and minimum, ReadEventFromDB() sets the values to the
maximum or minimum, respectively.
➤ It then passes these parameters to Run() which initiates a database search
and read operation for event containing DeviceID and a TriggerTime
within allowed TimeVar.

ReadEventFromDBDirect (Method)
Call this method to retrieve a COMTRADE event from the database using the
event handle. After calling this method, Run() reads the event into internal data
buffers for later use.

Date Code 20241023 Programming Reference


476 FileIO
Classes

The event handle is an attribute of the struct_EventDetails structure. See


class_EventListing for details on populating an instance of struct_EventDetails.

Inputs

Name IEC 61131 Type Description

EventHandle sel_file.Struct_event_handle The details required to request an event from


the database.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the read request was successfully processed.

Processing
➤ If EventID is null, or InProgress is TRUE, does no work and returns
FALSE. Else, does the following.
➤ Sets InProgess to TRUE and Error to FALSE and ErrorDesc to a null
string.
➤ Passes the EventID to Run() which initiates a database read operation for
the event.

ReadEventFromFS (Method)
Call this method to initiate a search of the RTAC's file system for a set of files
that define a COMTRADE event (.cfg , .dat). After calling this method, Run()
reads the event into internal data buffers for later use.

Inputs

Name IEC 61131 Type Description

CfgFileName STRING(255) The full path to the .cfg file. The character /
delimits the folder path.

DatFileName STRING(255) The full path to the .dat file. The character /
delimits the folder path.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the read request was successfully processed.

Programming Reference Date Code 20241023


FileIO 477
Classes

Processing
➤ If InProgress is TRUE, or either file name does not conform to the
requirements of the fileIO.class_FileReader2.ReadFile method, does no
work and returns FALSE. Else, does the following.
➤ Sets InProgess to TRUE and Error to FALSE and ErrorDesc to a null
string.
➤ Passes the file names to Run() which initiates a file system read
operation for the event.

GetComtradeInfo (Method)
Call this method to read the COMTRADE event information from the .cfg file
and output the data to a struct_ComtradeInfo variable.

Outputs
Name IEC 61131 Type Description

ComtradeInfo struct_ComtradeInfo The COMTRADE event information.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the event information is found.

Processing
If Error and InProgress are FALSE:
➤ GetComtradeInfo() method scans event information and outputs the
COMTRADE event details to ComtradeInfo.
➤ GetComtradeInfo() returns TRUE after event information is collected.
GetComtradeInfo() call is ignored if Error or InProgress is TRUE.

GetAnalogChannelInfo (Method)
Call this method to read an analog channel's information from the .cfg file and
output the data to a struct_AnalogChannelInfo variable.

Inputs
Name IEC 61131 Type Description

ChannelNumber UDINT The analog channel number for which the method
collects information.

Outputs
Name IEC 61131 Type Description

ChannelInfo struct_AnalogChannelInfo The analog channel information.

Date Code 20241023 Programming Reference


478 FileIO
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if channel information is found.

Processing
If Error and InProgress are FALSE:

➤ GetAnalogChannelInfo() checks that channelNumber exists in the .cfg


file and outputs the analog channel's information.
➤ GetAnalogChannelInfo() returns TRUE after channel information is
collected.

GetAnalogChannelInfo() call is ignored if Error or InProgress is TRUE.

GetDigitalChannelInfo (Method)
Call this method to read a digital channel's information from the .cfg file and
output the data to a struct_digitalChannelInfo variable.

Inputs

Name IEC 61131 Type Description

ChannelNumber UDINT The digital channel number for which the method
collects information.

Outputs

Name IEC 61131 Type Description

ChannelInfo struct_DigitalChannelInfo The digital channel information.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if channel information is found.

Processing
If Error and InProgress are FALSE:

➤ GetDigitalChannelInfo() checks that channelNumber exists in the .cfg file


and outputs the digital channel's information.
➤ GetDigitalChannelInfo() returns TRUE after channel information is
collected.

GetDigitalChannelInfo() call is ignored if Error or InProgress is TRUE.

Programming Reference Date Code 20241023


FileIO 479
Classes

GetAnalogChannelNumber (Method)
Call this method to retrieve the channel number of the analog channel specified
by the input channel name. This method is useful in conjunction with the
GetAnalogChannelInfo() method when only the channel name is known.

Inputs

Name IEC 61131 Type Description

ChannelName STRING(128) The channel name string of the analog channel.

Return Value

IEC 61131 Type Description

UDINT Returns the analog channel number of the first found channel whose
channel ID matches the input ChannelName (case insensitive).
Returns zero if no match is found.

GetDigitalChannelNumber (Method)
Call this method to retrieve the channel number of the digital channel specified
by the input channel name. This method is useful in conjunction with the
GetDigitalChannelInfo() method when only the channel name is known.

Inputs

Name IEC 61131 Type Description

ChannelName STRING(128) The channel name string of the digital channel.

Return Value

IEC 61131 Type Description

UDINT Returns the digital channel number of the first found channel whose
channel ID matches the input ChannelName (case insensitive).
Returns zero if no match is found.

ConvertComtradeTStoUTC (Method)
Call this method to convert a class_ComtradeParser-calculated time stamp to a
UTC time stamp, based on the Local Code offset denoted in the .cfg file.

Inputs

Name IEC 61131 Type Description

TimeStamp dateTime_t Time stamp returned from GetDigitalSample(),


GetAnalogSample(), or struct_ComtradeInfo.

Date Code 20241023 Programming Reference


480 FileIO
Classes

Return Value
IEC 61131 Type Description

dateTime_t Returns the UTC representation of the TimeStamp input.

GetRealVector (Method)
Call this method to parse samples contained in the range of FirstSample to
LastSample of an analog channel and write it to a REAL vector. This method
scales the data using the channel's information from the .cfg file.

Inputs
Name IEC 61131 Type Description

ChannelInfo struct_AnalogChannelInfo The analog channel information to parse.

FirstSample UDINT The first sample to read.

LastSample UDINT The last sample to read.

Inputs/Outputs
Name IEC 61131 Type Description

SampleVector DynamicVectors.class_RealVector The REAL vector to which the


method writes the analog samples.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if channel information is found.

Processing
If Error and InProgress are FALSE:

➤ GetRealVector() checks that ChannelInfo and analog samples within the


provided sample range from FirstSample to LastSample exist.
➤ Parses the .dat file for ChannelName and write the samples to
SampleVector.
➤ GetRealVector() returns TRUE after real vector is written.
GetRealVector() call is ignored if Error or InProgress is TRUE.

GetAnalogSample (Method)
Call this method to get a single sample of an analog channel and output the
sample as a REAL value. This method scales the sample using the channel's
information from the .cfg file. The method also outputs the sample's absolute
time stamp with respect to the event trigger time.

Programming Reference Date Code 20241023


FileIO 481
Classes

Inputs
Name IEC 61131 Type Description

ChannelInfo struct_AnalogChannelInfo The analog channel information to parse.

SampleNumber UDINT The sample to read.

Outputs
Name IEC 61131 Type Description

Sample REAL The analog sample's value.

SampleTime dateTime_t The sample's date and time stamp.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if sample is found.

Processing
If Error and InProgress are FALSE:

➤ GetAnalogSample() checks that channelName and the sampleNumber


exist.
➤ Parses the .dat file for ChannelName and outputs the analog sample
information for SampleNumber.
➤ GetAnalogSample() returns TRUE after sample information is written.
GetAnalogSample() call is ignored if Error or InProgress is TRUE.

GetBoolVector (Method)
Call this method to parse samples contained in the range of FirstSample to
LastSample of a digital channel and write it to a vector.

Inputs
Name IEC 61131 Type Description

ChannelInfo struct_DigitalChannelInfo The digital channel information to parse.

FirstSample UDINT The first sample to read.

LastSample UDINT The last sample to read.

Inputs/Outputs
Name IEC 61131 Type Description

SampleVector DynamicVectors.class_BaseVector The vector to which the method writes the Boolean samples. Vector
must be declared with elementSize := SIZEOF(BOOL).

Date Code 20241023 Programming Reference


482 FileIO
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if channel information is found.

Processing
If Error and InProgress are FALSE:

➤ Checks that ChannelInfo and digital samples within the provided sample
range from FirstSample to LastSample exist.
➤ Calls .clear() on SampleVector if not already cleared.
➤ Parses the .dat file for struct_DigitalChannelInfo.ChannelId and write the
samples to SampleVector.
➤ Returns TRUE if all samples in the specified range were successfully
written to SampleVector. Otherwise, returns FALSE.

GetBoolVector() call is ignored if Error or InProgress is TRUE.

GetDigitalSample (Method)
Call this method to get a single sample of a digital channel and output the
sample as a BOOL value.

Inputs

Name IEC 61131 Type Description

ChannelInfo struct_DigitalChannelInfo The digital channel information to parse.

SampleNumber UDINT The sample to read.

Outputs

Name IEC 61131 Type Description

Sample BOOL The digital sample's state.

SampleTime dateTime_t The digital sample's date and time stamp.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if sample is found.

Programming Reference Date Code 20241023


FileIO 483
Classes

Processing
If Error and InProgress are FALSE:

➤ GetDigitalSample() checks that ChannelName and the SampleNumber


exist.
➤ Parse the .dat file for ChannelName and output the digital sample
information for SampleNumber.
➤ GetDigitalSample() returns TRUE after sample information is written.

GetDigitalSample() call is ignored if Error or InProgress is TRUE.

GetSamplingInfo (Method)
Call this method to get a sample rate and corresponding last sample number
from the .cfg file. When the number of samples read from the database is less
than the number of samples indicated in the .cfg file, the last sample number
displays the quantity of samples stored in the internal buffer.

Inputs
Name IEC 61131 Type Description

SampleRateNumber UDINT The .cfg file sample rate to collect sampling


information from.

Outputs
Name IEC 61131 Type Description

SamplingInfo Struct_SamplingInfo The sample rate and corresponding last


sample number.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if sample rate and last sample number are found.

Processing
If Error and InProgress are FALSE:

➤ GetSamplingInfo() checks that SampleRateNumber exists in the .cfg file


and outputs information to SamplingInfo.
➤ GetSamplingInfo() returns TRUE after sampling information is collected.

GetSamplingInfo() call is ignored if Error or InProgress is TRUE.

Run (Method)
Call this method on every scan. It supervises all asynchronous operations.

Date Code 20241023 Programming Reference


484 FileIO
Classes

Processing
➤ On the first call of Run, the MaxEventSize class input will be fixed and
cannot be modified again during runtime. If the input is outside of the
specified bounds, it will be set equal to the nearest acceptable value.
➤ If a ReadEventFromDB() or ReadEventFromDBDirect() method has
been initiated:
➢ Set InProgress to TRUE.
➢ Set Error to FALSE.
➢ Clear ErrorDesc.
➤ ReadEventFromDB() invokes the following behavior:
➢ Begin searching for a COMTRADE event that matches DeviceID and
has as trigger time that is within ±TimeVar of TriggerTime.
➢ Continue searching for event until one is found or WaitTime expires.
➢ If a COMTRADE event is found, read the .cfg file into internal
buffers.
➣ If StartSample and TotalSamples are 0, all contents from the .dat
file are asynchronously read into internal buffers.
➣ If StartSample is non-zero and less than the number of samples
contained in the .dat file, the run method reads TotalSamples
samples from the .dat file with an offset starting sample of
StartSample into internal buffers. If TotalSamples is zero, the run
method reads all contents from the .dat file with an offset starting
sample of StartSample into internal buffers.
➣ When the .dat file read is complete, the run method sets
InProgress to FALSE and NewEventReady to TRUE for one
processing cycle.
➢ If a COMTRADE event is not found before WaitTime expires,
perform the following actions:
➣ Set InProgess to FALSE.
➣ Populate ErrorDesc with "Event Not Found".
➤ ReadEventFromDBDirect() invokes the following behavior:
➢ Read the .cfg and then the .dat file into internal buffers for later use.
➢ When the .dat file read is complete, set InProgress to FALSE, and set
NewEventReady to TRUE for one processing cycle.
➤ If any error occurs, set Error to TRUE and populate ErrorDesc
appropriately.

class_PersistentData (Class)
This class provides the necessary functionality to monitor the present values
of a configurable collection of variables of any data type or custom structure;
periodically write the values of those variables to a managed JSON data file;
and, upon the next restart of the RTAC, automatically apply the variable values
found in the managed file to the original logic engine variables.

Programming Reference Date Code 20241023


FileIO 485
Classes

The functionality offered by this class is similar to that offered by retained


global variable lists (GVLs) in the user logic engine with the following major
differences:

➤ Retained GVLs are limited to approximately 28 kB of dedicated


nonvolatile memory, whereas the JSON data files created by this class are
limited by the free space in the RTAC's file system.
➤ The first time a project file containing a retained GVL is sent to an RTAC,
the 'Reinitialize Retain Variables' option in the project send dialog must
be selected to apply default values to these variables. A subsequent
change in the structure of the variable layout (additions, removals,
relocations, etc.) contained within the retained GVL necessitates that
the re-initialization option be selected again to ensure that predictable
defaults are loaded to the variables. Similar changes to the list of
variables monitored by class_PersistentData require no manual re-
initialization steps during subsequent project send operations and
variables not found in the managed JSON file at startup are automatically
initialized to their bootstrapped default values.
➤ Values contained within retained GVLs can be a challenge to apply
back to tag values owned by other devices or tag lists (e.g., applying
a raw retained BOOL value back to the .stVal component of an SPS
tag contained in a DNP tag list), requiring custom user logic. Variables
monitored by class_PersistentData are automatically re-assigned to their
intended location on startup and then monitored and stored periodically
during runtime.

This class is compatible with all IEC 61131 data types, including custom
structures. When the managed JSON data file is created, the raw data
representing the value of a variable are encoded into an ASCII string and stored
as a value associated with a specified key in the JSON structure.

The persistent JSON data file written to the RTAC's file system will contain
content similar to the following:
Code Snippet 16.1 datastore.json Example
{"aBool":"00",
"aReal":""B6F39D3F"",
"aSPSTag":"0100000001000000000000000000000000000000000000003D32 /
95611C9B0900000001001F00000001003C00000000000400000000000000",
"aString":"77686F612E2E2E206973207468697320776F726B696E673F0000 /

0000000000000000000000000000000000000000000000000000 /
0000000000000000000000000000000000000000000000000000000000"}

The most accurate way to store the values of variables of any type in the JSON
file is an ASCII-encoded equivalent of the raw hex data bytes that represent the
entire variable contents. This ASCII-encoded data is not human-readable, but it
can be easily converted back to a raw byte format and used to restore the value
of a variable upon restart.

During runtime, if the values of any monitored variables change and the RTAC
is restarted, the last known values of those variables written to the JSON data
file are automatically restored to the appropriate variables at startup.

Date Code 20241023 Programming Reference


486 FileIO
Classes

Initialization Inputs
Name IEC 61131 Type Description

PersistentPath STRING(255) The fully qualified directory path to the managed JSON data file on the RTAC's
file system. This path must comply with the allowable characters specified by
enum_FilenameScheme.SEL_FILEIO_LOCAL contained in the SELUtils library.

WriteInterval TIME The interval in which the class will periodically generate the managed JSON data file
containing the present values of all monitored variables.

LogRuntimeErrors BOOL Set to TRUE to log runtime errors to the SOE log.

Outputs
Name IEC 61131 Type Description

Error BOOL TRUE when class_PersistentData encounters an error.

ErrorDesc STRING(255) Errors encountered will be described here and will only be displayed when Error is TRUE.

Initialized BOOL Asserts once the class has completed its first executions of the Run() method on startup and
restored any variable values stored in the persistent JSON file.

bootstrap_Variable (Method)
Call this method to monitor a specified variable as part of the persistent JSON
data file. Only call this method once per monitored variable and before the first
call to the Run() method. Calls to this method after the first call to Run() are
ignored.

NOTE
Other applications within the RTAC project that are referring to variables
bootstrapped by this class should wait until Initialized is asserted before
operating on those variables.

Inputs
Name IEC 61131 Type Description

pt_Variable POINTER TO BYTE Pointer to the variable to be persistently maintained as evaluated by the ADR()
function.

NumBytes UDINT Number of bytes required to store the variable as evaluated by the SIZEOF() function.

DataName STRING(255) The unique name with which to identify this variable value in the managed JSON data
file. This name becomes the 'key' in a collection of key-value pairs.

pt_Default POINTER TO BYTE Pointer to a variable containing the default state which the data at pt_Variable are
initialized to in the event that DataName is not found in the persistent file at startup.
Must be the same variable type/size as that specified by pt_Variable and NumBytes.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the variable was successfully added to persistent


data tracking.

Programming Reference Date Code 20241023


FileIO 487
Classes

Processing
If Error and Initialized are FALSE:

➤ Checks that the pointer address specified by pt_Variable is a valid unique


memory address amongst all prior calls to bootstrap_Variable(). Returns
FALSE if otherwise.
➤ Checks that NumBytes is non-zero.
➤ Checks that the string value specified by DataName is not empty and is
unique amongst all prior calls to all bootstrap methods. Returns FALSE if
otherwise.
➤ Checks that the pointer address specified by pt_Default is a valid memory
address. Returns FALSE if otherwise.
➤ Stores the criteria specified by the four inputs into an internal dictionary
structure that is used to later parse and create the managed JSON data file.
➤ bootstrap_Variable() returns TRUE after successfully adding the variable
to its monitored data points.

bootstrap_Variable() call returns FALSE if Error or Initialized is TRUE.

Run (Method)
Call the Run() method of the instantiated class on every scan to ensure that
all variables are correctly monitored and periodically written to the managed
JSON data file. This method should only be called after initially calling the
bootstrap_Variable() method on startup to define the monitored variables.

Processing
➤ On calls to Run() until the Initialized output is asserted:
➢ Initiates a file read operation of the persistent JSON data file on the
RTAC's file system.
➢ Passes through any Errors encountered by the file read operation to
the Error and ErrorDesc outputs.
➢ Waits for the file read operation to successfully complete and attempts
to perform a JSON parse operation on the file content.
➢ Passes through any Errors encountered by the JSON parse operation
to the Error and ErrorDesc outputs.

Date Code 20241023 Programming Reference


488 FileIO
Benchmarks

➢ Iterates through the internal dictionary populated by the calls to the


bootstrap_Variable() method and attempts to locate the keys found in
this dictionary in the parsed JSON content:
➣ If a matching key is found, the data located at the memory
address specified by pt_Variable in the original bootstrap call is
overwritten with the value located in the parsed JSON data. The
number of bytes that are overwritten at pt_Variable are determined
by the NumBytes value in the original bootstrap call.
➣ If a matching key is not found, the data located at the memory
address specified by pt_Variable in the original bootstrap call
are overwritten with the data located at the address specified by
pt_Default in the original bootstrap call. The number of bytes that
are overwritten at pt_Variable are determined by the NumBytes
value in the original bootstrap call.
➢ If no errors have been encountered, sets Initialized to TRUE.
➤ On subsequent calls to Run():
➢ At a cyclic interval specified by WriteInterval:
➣ Iterates through the internal dictionary populated by the calls
to the bootstrap_Variable() method and uses the DataName and
raw byte data from the content located at pt_Variable to create an
internal JSON structure represented by keys and ASCII-encoded
values, respectively.
➣ Once the internal JSON structure is successfully created,
initializes a sequence to:
⦁ Open the managed file contained on the RTAC's file system.
⦁ Serialize the internal JSON structure.
⦁ Using Over-Write mode, write the serialized JSON content to
the data file.
⦁ Close the managed data file.
➣ Passes through any errors encountered by the JSON creation
or file open/write/close operations to the Error and ErrorDesc
outputs.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3505
➢ R136-V0 firmware
➤ SEL-3530
➢ R136-V0 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R136-V0 firmware

Programming Reference Date Code 20241023


FileIO 489
Benchmarks

Benchmark Test Descriptions


It is important to note that all computation in the sel_file and sel_ftp_client
libraries is performed at a lower priority than any logic processing functionality.
The time required to perform a given action is proportional to the RTAC
processing burden. The only values this document records are the times for
queuing that lower-priority work. The system performs the lower-priority work
asynchronously, so the Run() method of each class must be called or the status
variable passed to the functions must be monitored on every scan to supervise
the asynchronous operations.

Calculation of each time is the average of 100 iterations of the described


computation.

class_DirectoryListing
CreateNewList
The time necessary to request a new list when provided a 255-character path.

GetList
The time necessary to copy a list containing 10 file names.

Run
The time necessary to call Run() on each scan when there is directory work
pending.

Idle
The time necessary to call Run() on each scan when there is no directory work
pending.

class_EventListing
CreateNewList
The time necessary to request a new list when provided a 255-character path.

GetList
The time necessary to copy a list containing 10 file names.

Run
The time necessary to call Run() on each scan when there is directory work
pending.

Run (Idle)
The time necessary to call Run() on each scan when there is no directory work
pending.

Date Code 20241023 Programming Reference


490 FileIO
Benchmarks

class_FileWriter
AppendBytes
The time necessary to request 255 bytes be written via AppendBytes().

AppendVector
The time necessary to request 255 bytes be written via AppendVector().

AppendString
The time necessary to request 255 bytes be written via AppendString().

AppendSELString
The time necessary to request 255 bytes be written via AppendSELString().

Run
The time necessary to call Run() on the scan it switches from idle to work
pending. This tests how long it takes to request a copy of 255 characters when
switching from idle state.

Run (Idle)
The time necessary to call Run() on each scan when there is no work pending.

class_FileReader2
ReadFile
The time necessary to request that a file with a 255-byte-long file name be
opened via ReadFile().

CopyTo
The time necessary to copy 255 bytes from the internal buffer via CopyTo().

AppendToVector
The time necessary to append 255 bytes from the internal buffer by using
AppendToVector().

CopyToString
The time necessary to copy 255 bytes from the internal buffer via
CopyToString().

AppendToSELString
The time necessary to append 255 bytes from the internal buffer by using
AppendToSELString().

Programming Reference Date Code 20241023


FileIO 491
Benchmarks

Run
The time necessary to call Run() on a class_FileReader2 on the scan it switches
from work pending to idle. This tests how long it takes to request a copy of 255
characters into the internal buffer when switching to idle state.

Run (Idle)
The time necessary to call Run() on a class_FileReader each scan when there is
no work pending.

class_LogDirectoryManager
StartNewLog
The time necessary to call StartNewLog().

WriteLogEntryBytes
The time necessary to call WriteLogEntryBytes() with 255 bytes of input.

WriteLogEntryVector
The time necessary to call WriteLogEntryVector() with 255 bytes of
content.

WriteLogEntryString
The time necessary to call WriteLogEntryString() with 255 characters of
content.

WriteLogEntrySELString
The time necessary to call WriteLogEntrySELString() with 255 characters
of content.

EventLogFromBytes
The time necessary to call EventLogFromBytes() with 255 bytes of input.

EventLogFromVector
The time necessary to call EventLogFromVector() with 255 bytes of input.

EventLogFromString
The time necessary to call EventLogFromString() with 255 bytes of input.

EventLogFromSELString
The time necessary to call EventLogFromSELString() with 255 bytes of
input.

Date Code 20241023 Programming Reference


492 FileIO
Benchmarks

Run
The time necessary to call Run() with FTP configured.

class_DirectoryManager
StartNewFile
The time necessary to call StartNewLog().

WriteLogEntryBytes
The time necessary to call WriteLogEntryBytes() with 255 bytes of input.

WriteLogEntryVector
The time necessary to call WriteLogEntryVector() with 255 bytes of
content.

WriteLogEntryString
The time necessary to call WriteLogEntryString() with 255 characters of
content.

WriteLogEntrySELString
The time necessary to call WriteLogEntrySELString() with 255 characters
of content.

EventLogFromBytes
The time necessary to call EventLogFromBytes() with 255 bytes of input.

EventLogFromVector
The time necessary to call EventLogFromVector() with 255 bytes of input.

EventLogFromString
The time necessary to call EventLogFromString() with 255 bytes of input.

EventLogFromSELString
The time necessary to call EventLogFromSELString() with 255 bytes of
input.

Run
The time necessary to call Run() with FTP configured.

Programming Reference Date Code 20241023


FileIO 493
Benchmarks

class_TimeBasedDirectoryManager
StartNewFile
The time necessary to call StartNewLog().

WriteLogEntryBytes
The time necessary to call WriteLogEntryBytes() with 255 bytes of input.

WriteLogEntryVector
The time necessary to call WriteLogEntryVector() with 255 bytes of
content.

WriteLogEntryString
The time necessary to call WriteLogEntryString() with 255 characters of
content.

WriteLogEntrySELString
The time necessary to call WriteLogEntrySELString() with 255 characters
of content.

EventLogFromBytes
The time necessary to call EventLogFromBytes() with 255 bytes of input.

EventLogFromVector
The time necessary to call EventLogFromVector() with 255 bytes of input.

EventLogFromString
The time necessary to call EventLogFromString() with 255 bytes of input.

EventLogFromSELString
The time necessary to call EventLogFromSELString() with 255 bytes of
input.

Run
The time necessary to call Run() with FTP configured.

fun_FtpDownload
The time necessary to request a file download when provided a 255-character
path.

Date Code 20241023 Programming Reference


494 FileIO
Benchmarks

fun_FtpEventUpload
The time necessary to request an event upload when provided a 255-character
path.

fun_FtpUpload
The time necessary to request a file upload when provided a 255-character path.

fun_DeleteFile
The time necessary to request a file delete when provided a 255-character path.

fun_FileSize
The time necessary to request a file size when provided a 255-character path.

fun_FilesystemFreeSpace
The time necessary to request the available free space on the system.

fun_SoeAscending
The time necessary to request a list of 10 SOE reports without a filter.

fun_SoeDescending
The time necessary to request a list of 10 SOE reports without a filter.

fun_SoeWindow
The time necessary to request a list of 10 SOE reports without a filter.

fun_LocalSoeGetID
The time necessary to request a list of 10 SOE reports without a filter.

fun_LocalSoeAscending
The time necessary to request a list of 10 SOE reports without a filter.

fun_LocalSoeDescending
The time necessary to request a list of 10 SOE reports without a filter.

fun_RemoteSoeGetID
The time necessary to request a list of 10 SOE reports without a filter.

Programming Reference Date Code 20241023


FileIO 495
Benchmarks

fun_RemoteSoeAscending
The time necessary to request a list of 10 SOE reports without a filter.

fun_RemoteSoeDescending
The time necessary to request a list of 10 SOE reports without a filter.

Benchmark Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

class_DirectoryListing.CreateNewList 327 202 11

class_DirectoryListing.GetList 72 45 4

class_DirectoryListing.Run 137 42 3

class_DirectoryListing.Run (Idle) 5 4 1

class_EventListing.CreateNewList 6 4 1

class_EventListing.GetNewList 353 218 73

class_EventListing.Run 18 12 2

class_EventListing.Run (Idle) 2 1 1

class_FileWriter.AppendBytes 27 20 2

class_FileWriter.AppendVector 37 17 1

class_FileWriter.AppendString 43 26 2

class_FileWriter.SELString 1170 678 53

class_FileWriter.Run 62 50 5

class_FileWriter.Run (Idle) 5 4 1

class_FileReader2.ReadFile 25 14 1

class_FileReader2.CopyTo 38 19 1

class_FileReader2.AppendToVector 824 459 19

class_FileReader2.AppendToString 13 6 1

class_FileReader2.AppendToSELString 460 287 17

class_FileReader2.Run 4 2 1

class_FileReader2.Run (Idle) 3 1 1

class_LogDirectoryManager.StartNewLog 552 285 13

class_LogDirectoryManager.WriteLogEntryBytes 113 127 4

class_LogDirectoryManager.WriteLogEntryVector 159 100 4

class_LogDirectoryManager.WriteLogEntryString 143 71 5

class_LogDirectoryManager.WriteLogEntrySELString 1934 1030 45

class_LogDirectoryManager.EventLogFromBytes 145 91 4

Date Code 20241023 Programming Reference


496 FileIO
Benchmarks

Platform (time in μs)


Operation Tested
SEL-3505 SEL-3530 SEL-3555

class_LogDirectoryManager.EventLogFromVector 149 68 3

class_LogDirectoryManager.EventLogFromString 172 116 4

class_LogDirectoryManager.EventLogFromSELString 1927 1024 44

class_LogDirectoryManager.Run 624 368 14

class_DirectoryManager.StartNewFile 237 104 5

class_DirectoryManager.WriteLogEntryBytes 92 27 1

class_DirectoryManager.WriteLogEntryVector 41 15 1

class_DirectoryManager.WriteLogEntryString 46 30 2

class_DirectoryManager.WriteLogEntrySELString 1770 952 44

class_DirectoryManager.EventLogFromBytes 286 135 4

class_DirectoryManager.EventLogFromVector 220 85 4

class_DirectoryManager.EventLogFromString 158 80 4

class_DirectoryManager.EventLogFromSELString 1966 1020 43

class_DirectoryManager.Run 574 309 14

class_TimeBasedDirectoryManager.StartNewFile 256 95 5

class_TimeBasedDirectoryManager.WriteLogEntryBytes 79 27 1

class_TimeBasedDirectoryManager.WriteLogEntryVector 46 17 1

class_TimeBasedDirectoryManager.WriteLogEntryString 47 21 2

class_TimeBasedDirectoryManager.WriteLogEntrySELString 1769 969 45

class_TimeBasedDirectoryManager.EventLogFromBytes 282 116 4

class_TimeBasedDirectoryManager.EventLogFromVector 236 84 3

class_TimeBasedDirectoryManager.EventLogFromString 165 82 4

class_TimeBasedDirectoryManager.EventLogFromSELString 198 1016 45

class_TimeBasedDirectoryManager.Run 592 348 16

fun_FtpDownload 112 76 4

fun_FtpEventUpload 75 45 5

fun_FtpUpload 88 88 5

fun_DeleteFile 73 50 4

fun_FileSize 93 53 5

fun_FilesystemFreeSpace 75 41 4

fun_SoeAscending 106 64 5

fun_SoeDescending 106 63 4

fun_SoeWindow 118 62 4

fun_LocalSoeGetID 122 60 5

fun_LocalSoeAscending 108 64 4

Programming Reference Date Code 20241023


FileIO 497
Examples

Platform (time in μs)


Operation Tested
SEL-3505 SEL-3530 SEL-3555

fun_LocalSoeDescending 118 65 4

fun_RemoteSoeGetID 113 61 4

fun_RemoteSoeAscending 116 65 5

fun_RemoteSoeDescending 106 63 4

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Writing From Changing String


Objective
You want to append the contents of a string to a file every time the value of that
string changes.

Assumptions
This example assumes that a user-specified IEC 61131 function called
fun_StringsDifferent provides functionality similar to that in Code Snippet 16.2.
Code Snippet 16.2 fun_StringsDifferent
(* Compares str1 to str2. If they are identical until the null terminator
is encountered in both strings, then return FALSE. *)
FUNCTION fun_StringsDifferent : BOOL
VAR CONSTANT
c_maxStringSize : UDINT := 255;
END_VAR
VAR_IN_OUT
str1 : STRING(c_maxStringSize); // The first string to compare
str2 : STRING(c_maxStringSize); // The second string to compare
END_VAR
VAR
i : UDINT;
differenceFound : BOOL := FALSE;
END_VAR

FOR i := 0 TO c_maxStringSize - 1 DO
IF (0 = str1[i]) AND (0 = str2[i]) THEN
// Found null terminator on both strings at the same time.
EXIT;
ELSIF str1[i] <> str2[i] THEN
differenceFound := TRUE;
EXIT;
END_IF
END_FOR
(* Return True if difference found *)
fun_StringsDifferent := differenceFound;

Date Code 20241023 Programming Reference


498 FileIO
Examples

Solution
Because we assume that a simple string comparison function exists, we can
write out the contents of a string to a file every time it changes by using just a
few lines of code, as in Code Snippet 16.3.
Code Snippet 16.3 prg_WriteStringOnChange
PROGRAM prg_WriteStringOnChange
VAR
TheStringToWrite : STRING(255) := '';
TheStringLastWritten : STRING(255) := '';
FileWriter : class_FileWriter('/OutputFolder/OutputFile.txt');
END_VAR

IF fun_StringsDifferent(TheStringToWrite, TheStringLastWritten) THEN


FileWriter.AppendString(TheStringToWrite);
TheStringLastWritten := TheStringToWrite;
END_IF
FileWriter.Run(); // Run this every scan regardless.

Reading File Contents Into Byte Array


Objective
You want to read the contents of a file into a byte array.

Assumptions
The file "/FileToRead.txt" exists in the root of the RTAC public file system.

Solution
The file is read into an internal buffer and then copied into an empty user-
supplied byte array using the program in Code Snippet 16.4.
Code Snippet 16.4 prg_ReadToByteArray
PROGRAM prg_ReadToByteArray
VAR CONSTANT
c_ByteArraySize : UDINT := 10_000;
END_VAR
VAR
TheByteArray : ARRAY[1..c_ByteArraySize] OF BYTE;
Filename : STRING(255) := '/FileToRead.txt';
FileReader : class_FileReader2;
FirstScan : BOOL := TRUE;
Copied : BOOL := FALSE;
END_VAR

IF FirstScan THEN
//Initiate the File Read.
FileReader.ReadFile(Filename);
FirstScan := FALSE;
ELSIF 0 < FileReader.BytesInBuffer AND NOT Copied THEN
FileReader.CopyTo(startByte := 0,
pt_byte := ADR(TheByteArray),
numBytes := c_ByteArraySize);
Copied := TRUE;
END_IF
FileReader.Run(); // Run this every scan regardless.

Programming Reference Date Code 20241023


FileIO 499
Examples

Reading File Contents Into Dynamic Byte Vector


Objective
You want to read the contents of a file into a Dynamic Byte Vector.

Assumptions
1. You have included the DynamicVectors library in your project.
2. The file "/FileToRead.txt" exists in the root of the RTAC public file
system.

Solution
The file will first be read into an internal buffer and then copied into an empty
user-supplied class_ByteVector using the program in Code Snippet 16.5.
Code Snippet 16.5 prg_ReadToByteVector
PROGRAM prg_ReadToByteVector
VAR
TheByteVector : DynamicVectors.class_ByteVector;
Filename : STRING(255) := '/FileToRead.txt';
FileReader : class_FileReader2;
FirstScan : BOOL := TRUE;
Copied : BOOL := FALSE;
END_VAR

IF FirstScan THEN
//Initiate the File Read.
FileReader.ReadFile(Filename);
FirstScan := FALSE;
ELSIF 0 < FileReader.BytesInBuffer AND NOT Copied THEN
FileReader.AppendToVector(startByte := 0, vector := TheByteVector);
Copied := TRUE;
END_IF
FileReader.Run(); // Run this every scan regardless.

Reading File Contents Into Array of Strings


Objective
You want to read the contents of a file into an array of strings.

Assumptions
The file "/FileToRead.txt" exists in the root of the RTAC File Manager.

Date Code 20241023 Programming Reference


500 FileIO
Examples

Solution
The file will first be read into an internal buffer and then it will be copied into an
empty user-supplied strings using the program in Code Snippet 16.6.
Code Snippet 16.6 prg_ReadToArrayOfStrings
PROGRAM prg_ReadToArrayOfStrings
VAR CONSTANT
c_NumStringsInArray : UDINT := 1_000;
c_StringSize : UDINT := 255;
END_VAR
VAR
TheStringArray : ARRAY[1..c_NumStringsInArray] OF STRING(c_StringSize);
Filename : STRING(255) := '/FileToRead.txt';
FileReader : class_FileReader2;
FirstScan : BOOL := TRUE;
Copied : BOOL := FALSE;
stringIter : UDINT;
bufferTracker : UDINT := 0;
END_VAR

IF FirstScan THEN
//Initiate the File Read.
FileReader.ReadFile(Filename);
FirstScan := FALSE;
ELSIF 0 < FileReader.BytesInBuffer AND NOT Copied THEN
FOR stringIter := 1 TO c_NumStringsInArray DO
IF bufferTracker <= FileReader.BytesInBuffer THEN
FileReader.CopyToString(startByte := bufferTracker,
str := TheStringArray[stringIter]);
ELSE
// All of the file contents has been copied into strings.
EXIT;
END_IF
bufferTracker := bufferTracker + c_StringSize;
END_FOR
Copied := TRUE;
END_IF
FileReader.Run(); // Run this every scan regardless.

Reading Event Reports Retrieved From Relays


Objective
You have set up the RTAC to automatically collect and buffer event records and
want to read the contents of these records.

Assumptions
1. You have included the SELString and DynamicVectors libraries in your
project.
2. The RTAC database contains events collected from the desired relays.

NOTE
See the SELString library documentation for more information about
class_SELStrings and class_SELStringLists.

Programming Reference Date Code 20241023


FileIO 501
Examples

Solution
You can locate qualifying files using a class_EventListing. Then you can select
one as in Code Snippet 16.7.
Code Snippet 16.7 prg_ReadEventReportFromRelay
PROGRAM prg_ReadEventReportFromRelay
VAR
EventReportListing : class_EventListing;
EventReportList : class_BaseVector(SIZEOF(struct_EventDetails), 32);
FileReader : class_FileReader2;
FileContents : class_ByteVector;
//A record of the first 255 characters of the read in file.
FirstFileChars : STRING(255);
EventReportFileDetails : struct_EventDetails;
StepNumber : UDINT := 1; // Start off by running.
EventIndexToRead : UDINT := 0; // The index of the file to read in
EventIndexRead : UDINT := 0;
Initiate : BOOL; // Force this value to TRUE in order to start reading files.
END_VAR

IF Initiate THEN
// Start the state machine to read the event.
StepNumber := 1;
Initiate := FALSE;
END_IF
CASE StepNumber OF
1:
// Request a list of all events on the system.
EventReportListing.CreateNewList(deviceName := '');
StepNumber := StepNumber + 1;
2:
// Wait for the list to be ready.
IF EventReportListing.NewListReady THEN
IF EventReportListing.GetList(list := EventReportList) THEN
StepNumber := StepNumber + 1;
END_IF
END_IF
3:
// Select a specific event if that many events exist on the system.
IF EventIndexToRead < EventReportList.Size THEN
EventReportList.GetCopyOfElement(EventIndexToRead,
ADR(EventReportFileDetails));
EventIndexRead := EventIndexToRead;
FileReader.ReadEventFromDB(EventReportFileDetails.Handle,
FileIo.sel_file.RAW_DATA);
StepNumber := StepNumber + 1;
END_IF
4:
// The file reader has read the data in. Do any required work.
IF 0 < FileReader.BytesInBuffer THEN
FileReader.AppendToVector(0, FileContents);
(*Update the output string by copying to it the first 255 bytes or
the complete file, whichever is less.*)
SysMemCpy(pDest := ADR(FirstFileChars),
pSrc := FileContents.pt_Data,
udiCount := MIN(FileContents.Size, 255));
StepNumber := StepNumber + 1;
END_IF
5:
// Wait for until Initiate = TRUE for next file read request.
StepNumber := 0;
END_CASE
EventReportListing.Run(); // Run this every scan regardless.
FileReader.Run(); // Run this every scan regardless.

Date Code 20241023 Programming Reference


502 FileIO
Examples

Reading COMTRADE Events Retrieved From Relays


Objective
You have set up the RTAC to automatically collect COMTRADE events and
want to read the contents of these records.

Assumptions
1. You have included the SELString and DynamicVectors libraries in your
project.
2. Collected events from the desired relays exist in the RTAC database.

NOTE
See the SELString library documentation for more information about
class_SELStrings and class_SELStringLists.

Solution
You can locate qualifying files using a class_EventListing. Then you can select
one as in Code Snippet 16.8.
Code Snippet 16.8 prg_ReadComtradeEventFromRelay
PROGRAM prg_ReadComtradeEventFromRelay
VAR
EventReportListing : class_EventListing;
EventReportList : class_BaseVector(SIZEOF(struct_EventDetails), 32);
cfgReader : class_FileReader2;
datReader : class_FileReader2;
//A record of the first 255 characters of the read in file.
EventReportFileDetails : struct_EventDetails;
StepNumber : UDINT := 1; // Start off by running.
EventIndexToRead : UDINT := 0;
Initiate : BOOL; // Force this value to TRUE in order to start reading files.
END_VAR

IF Initiate THEN
StepNumber := 1; // Start executing the state machine
Initiate := FALSE;
END_IF
CASE StepNumber OF
1:
EventReportListing.CreateNewList(deviceName := '');
StepNumber := StepNumber + 1;
2:
IF EventReportListing.NewListReady THEN
IF EventReportListing.GetList(list := EventReportList) THEN
StepNumber := StepNumber + 1;
END_IF
END_IF
EventIndexToRead := 0;
3:
WHILE EventIndexToRead < EventReportList.Size DO // An event was found
EventReportList.GetCopyOfElement(EventIndexToRead,
ADR(EventReportFileDetails));
EventIndexToRead := EventIndexToRead + 1;
IF EventReportFileDetails.Handle.EventType = FileIo.sel_file.COMTRADE THEN
cfgReader.ReadEventFromDB(EventReportFileDetails.Handle,
FileIo.sel_file.CFG_FILE);
datReader.ReadEventFromDB(EventReportFileDetails.Handle,
FileIo.sel_file.DAT_FILE);

Programming Reference Date Code 20241023


FileIO 503
Examples

EXIT;
END_IF
END_WHILE
StepNumber := StepNumber + 1;
4:
IF NOT cfgReader.InProgress AND NOT datReader.InProgress THEN
//Extract data and perform desired actions on the data here.
//cfgReader and datReader contain the contents desired.
StepNumber := StepNumber + 1;
END_IF
5:
IF EventIndexToRead >= EventReportList.Size THEN
//This branch represents having accessed all COMTRADE files found.
StepNumber := 0;
ELSE
//This branch represents having more files to check.
StepNumber := 3;
END_IF
END_CASE
EventReportListing.Run(); // Run this every scan regardless.
cfgReader.Run(); // Run this every scan regardless.
datReader.Run();

Downloading File to Local File System From Remote FTP Server


Objective
You want to read a file onto the local file system from a remote FTP server and
call the local file "FileFromFtpServer.csv".

Assumptions
1. An FTP server is set up, configured, and accessible by the RTAC over the
network.
2. The FTP server configuration is as follows:
➤ IP address: 192.168.0.2
➤ Username: FTPUSER
➤ Password: TAIL
3. The file "FileToFtp.csv" exists in the root of the FTP server file system.

Solution
First, you must get the file from the remote server by performing an FTP
download using code similar to that shown in Code Snippet 16.9.

Then you can manipulate the file at will. For example, you could read
the file into an internal buffer, then copy it into an empty user-supplied
class_ByteVector by using the program shown previously in Code Snippet 16.5.
Code Snippet 16.9 prg_FtpDownload
PROGRAM prg_FtpDownload
VAR
FtpServerIP : STRING(15) := '192.168.0.2';
FtpServerUsername : STRING(32) := 'FTPUSER';
FtpServerPassword : STRING(32) := 'TAIL';
FtpServerFileToGet : STRING(255) := 'FileToFtp.csv';
RenameAsLocalFile : STRING(255) := '/FileFromFtpServer.csv';

Date Code 20241023 Programming Reference


504 FileIO
Examples

FirstScan : BOOL := TRUE;


Timeout : UDINT := 10; // Time in seconds
DownloadStatus : FileIo.sel_ftp_client.Enum_sel_ftp_client_errors := 0;
CurrentStatus : FileIo.sel_ftp_client.Enum_sel_ftp_client_errors;
DownloadAttemptCompleted : BOOL := FALSE;
DownloadAttemptFailed : BOOL := FALSE;
END_VAR

CurrentStatus := DownloadStatus;
IF FirstScan THEN
//Initiate the FTP Read.
FileIo.sel_ftp_client.ftp_download(
ftp_server := FtpServerIP,
local_path := RenameAsLocalFile,
remote_path := FtpServerFileToGet,
username := FtpServerUsername,
password := FtpServerPassword,
timeout := Timeout,
status := DownloadStatus); // This is passed in as a VAR_IN_OUT
(* Note, making this call will cause the download status to be initialized to
'IN_PROGRESS'*)
FirstScan := FALSE;

(* Because DownloadStatus was passed in as a VAR_IN_OUT, it can be written to by the


external FTP task. Check it regularly to see if the download status changed to 0 *)
ELSIF FileIo.sel_ftp_client.NO_ERROR = CurrentStatus THEN
DownloadAttemptCompleted := TRUE;
ELSIF CurrentStatus < FileIo.sel_ftp_client.IN_PROGRESS THEN
// The operation has hit an error because NO_ERROR was already checked.
DownloadAttemptFailed := TRUE;
END_IF

Uploading File From Local File System to Remote FTP Server


Objective
You want to write a file from the local file system to a remote FTP server and
call the local file "FileFromRTAC.csv".

Assumptions
1. An FTP server is set up, configured, and accessible by the RTAC over the
network.
2. The FTP server configuration is as follows:
➤ IP address: 192.168.0.2
➤ Username: FTPUSER
➤ Password: TAIL
3. The file "FileToSend.csv" exists in the root of the RTAC File Manager.

Solution
Get the file onto the remote server by performing an FTP upload.
Code Snippet 16.10 prg_FtpUpload
PROGRAM prg_FtpUpload
VAR
FtpServerIP : STRING(15) := '192.168.0.2';
FtpServerUsername : STRING(32) := 'FTPUSER';
FtpServerPassword : STRING(32) := 'TAIL';

Programming Reference Date Code 20241023


FileIO 505
Examples

FileNameForFtpServer : STRING(255) := 'FileFromRTAC.csv';


LocalFileToSend : STRING(255) := '/FileToSend.csv';
FirstScan : BOOL := TRUE;
Timeout : UDINT := 10; // Time in seconds
UploadStatus : FileIo.sel_ftp_client.Enum_sel_ftp_client_errors := 0;
CurrentStatus : FileIo.sel_ftp_client.Enum_sel_ftp_client_errors;
UploadAttemptCompleted : BOOL := FALSE;
UploadAttemptFailed : BOOL := FALSE;
END_VAR

CurrentStatus := UploadStatus;
IF FirstScan THEN
//Initiate the FTP write.
FileIo.sel_ftp_client.ftp_upload(
ftp_server := FtpServerIP,
local_path := LocalFileToSend,
remote_path := FileNameForFtpServer,
username := FtpServerUsername,
password := FtpServerPassword,
timeout := Timeout,
status := UploadStatus); // This is passed in as a VAR_IN_OUT
(* Note, making this call will cause the upload status to be initialized to
'IN_PROGRESS'*)
FirstScan := FALSE;

(* Because UploadStatus was passed in as a VAR_IN_OUT, it can be written to by the


external FTP task. Check it regularly to see if the upload status changed to 0 *)
ELSIF FileIo.sel_ftp_client.NO_ERROR = CurrentStatus THEN
UploadAttemptCompleted := TRUE;
ELSIF CurrentStatus < FileIo.sel_ftp_client.IN_PROGRESS THEN
// The operation has hit an error because NO_ERROR was already checked.
UploadAttemptFailed := TRUE;
END_IF

Basic Directory Management With Persistent Log Files


Objective
Use the basic directory manager to implement a six-file circular buffer in a target
directory that is being populated by an independent FileIO class_FileWriter
instance. Write application errors to a persistent log file in the target directory so
the log file is not subject to the circular buffer.

Assumptions
1. A user-programmed application is writing files to a designated folder,
Dir1, on the RTAC file system by using FileIO class_FileWriter.
2. A Global Variable List, GVL1, has been defined to contain variables
pertinent to error tracking activities for the application. This example
GVL is shown in Code Snippet 16.11.
3. The user-programmed application populates the variables in GVL1.
Code Snippet 16.11 Error Tracking: GVL1
VAR_GLOBAL
//Flag indicating error condition on the given application
g_ApplicationError : BOOL;
//User-defined numeric error category
g_ApplicationErrorCode : DINT;
//Specific error message
g_ApplicationErrorDescription : STRING(255);
END_VAR

Date Code 20241023 Programming Reference


506 FileIO
Examples

Solution
Instantiate a class_BasicDirectoryManager to fulfill the stated directory
management objectives. Also use class_FileWriter to generate a persistent error
log file. Recall that class_BasicDirectoryManager ignores files with file names
beginning with a period (.).
Code Snippet 16.12 prg_ManageComplexDirectory
PROGRAM prg_ManageComplexDirectory
VAR
FirstScan : BOOL := TRUE;
FolderName : STRING := 'Dir1';
ErrorFileWriter : FileIO.class_FileWriter(filename := 'Dir1/.ErrorLog.txt');
Manager : FileIO.class_BasicDirectoryManager;
ApplicationErrorTrigger : R_TRIG;
TempLogString : STRING(255);
END_VAR

IF FirstScan THEN
(* Initialize the basic directory manager by calling the bootstrap_SetDirectory() method.
Limit target directory to 1MB, 6 files, and no limit on the age of the files. *)
Manager.bootstrap_SetDirectory(folderName := FolderName, maximumFolderSize := 1024*1024,
maximumNumFiles := 6, maximumNumDays := 0);
FirstScan := FALSE;
END_IF

//Look for the rising edge of the error flag.


ApplicationErrorTrigger(CLK := GVL1.g_ApplicationError);

(* IF error detected, write current state of GVL1 variables to the persistent log file,
preceded by the current system time. *)
IF ApplicationErrorTrigger.Q THEN
TempLogString :=
CONCAT(DT_TO_STRING(System_Time_Control_POU.System_Time_DateAndTime),
' Application error code:');
TempLogString := CONCAT(TempLogString, DINT_TO_STRING(GVL1.g_ApplicationErrorCode));
TempLogString := CONCAT(TempLogString, '$nError message: ');
TempLogString := CONCAT(TempLogString, GVL1.g_ApplicationErrorDescription);
TempLogString := CONCAT(TempLogString, '$n$r');
ErrorFileWriter.AppendString(TempLogString);
END_IF

//Run the persistent file writer


ErrorFileWriter.Run();
//Manage the target directory
Manager.Run();

Logging a History of Inputs and Outputs


Objective
You want to keep a week's worth of input value history, as well as outputs from
a protection algorithm that has been implemented.

Programming Reference Date Code 20241023


FileIO 507
Examples

Assumptions
There exist some set of inputs and outputs to the work being done. Here these
are delineated by adding the prefix g_, indicating that they exist in a GVL as
shown in Code Snippet 16.13.
Code Snippet 16.13 Global Variable List
VAR_GLOBAL
g_TriggerOne : BOOL;
g_TriggerTwo : BOOL;
g_WorkingVoltage : REAL;
g_WorkingCurrent : REAL;

g_OutputOne : BOOL;
g_OutputTwo : BOOL;
END_VAR

Solution
You can instantiate a class_LogDirectoryManager to manage rotation of the logs
you want.
Code Snippet 16.14 prg_LogApplicationActions
PROGRAM prg_LogApplicationActions
VAR
LogManager : class_LogDirectoryManager( folderName := '/WeekOfLogs/',
logPostfix := 'InVsOuts.log',
maxFolderSize := 512000,
maxNumFiles := 7,
autoStartNewLogDaily := TRUE);
WorkspaceString : STRING(255);
END_VAR

IF g_TriggerOne THEN
WorkspaceString := CONCAT( 'Trigger One received with an input voltage of ',
REAL_TO_STRING(g_workingVoltage));
LogManager.WriteLogEntryString(WorkspaceString);
END_IF
IF g_TriggerTwo THEN
WorkspaceString := CONCAT( 'Trigger Two received with an input current of ',
REAL_TO_STRING(g_workingCurrent));
LogManager.WriteLogEntryString(WorkspaceString);
END_IF

(*At this point the user calls the application doing work so the outputs update.*)

IF g_OutputOne THEN
LogManager.WriteLogEntryString('Action One requested');
END_IF
IF g_OutputTwo THEN
LogManager.WriteLogEntryString('Action Two requested');
END_IF

LogManager.Run();

Rotating Logs More Frequently


Objective
You want to keep a week's worth of logs with creation of a new log file every
eight hours.

Date Code 20241023 Programming Reference


508 FileIO
Examples

Solution
You can instantiate a class_LogDirectoryManager to manage rotation of the logs
you want. To do this, you must track the time and issue StartNewLog() on the
eight-hour shift boundaries.
Code Snippet 16.15 prg_RotatingLogs
PROGRAM prg_RotatingLogs
VAR CONSTANT
c_ShiftChange1 : UDINT := 1;
c_ShiftChange2 : UDINT := 9;
c_ShiftChange3 : UDINT := 17;
END_VAR
VAR
//Note that maxNumFiles allows for three files and the automated nightly rollover.
LogManager : class_LogDirectoryManager( folderName := '/WeekOfShiftLogs/',
logPostfix := 'Shift.log',
maxFolderSize := 512000,
maxNumFiles := 28,
autoStartNewLogDaily := TRUE);

FirstScan : BOOL := TRUE;

PresentTime : timestamp_t;
TimeOfDay : TIME_OF_DAY;

PreviousHours : UDINT;
PresentHours : UDINT;
END_VAR

PresentTime := SYS_TIME();
TimeOfDay := DT_TO_TOD(PresentTime.value.dateTime);

PreviousHours := PresentHours;
//Divide by 1000 to remove milliseconds and 3600 to remove seconds and minutes.
PresentHours := TOD_TO_UDINT(TimeOfDay)/3600000;

IF FirstScan THEN
PreviousHours := PresentHours;
FirstScan := FALSE;
END_IF

IF PreviousHours < c_ShiftChange1 AND PresentHours >= c_ShiftChange1 THEN


LogManager.StartNewLog();
ELSIF PreviousHours < c_ShiftChange2 AND PresentHours >= c_ShiftChange2 THEN
LogManager.StartNewLog();
ELSIF PreviousHours < c_ShiftChange3 AND PresentHours >= c_ShiftChange3 THEN
LogManager.StartNewLog();
END_IF

//Do any work and logging desired.

LogManager.Run();

Logging Events Via FTP


Objective
You want to record event logs on a remote server.

Programming Reference Date Code 20241023


FileIO 509
Examples

Assumptions
1. An FTP server is set up, configured, and accessible by the RTAC over the
network.
2. The FTP server configuration is as follows:
➤ IP address: 192.168.0.2
➤ Username: FTPUSER
➤ Password: TAIL
3. There are external variables g_EventOccurred and g_EventDescription,
driven by other code, that cause an event to be populated and sent.
4. There exists some set of inputs and outputs for the work being done. Here
these are delineated by adding the prefix g_, indicating that they exist in a
GVL as shown in Code Snippet 16.16.
Code Snippet 16.16 Global Variable List
VAR_GLOBAL
g_EventOccurred : BOOL;
g_EventDescription : STRING(255);
END_VAR

Solution
You can instantiate a class_LogDirectoryManager to accept the data for
transmission and to manage the storage required to facilitate the transaction.
Code Snippet 16.17 prg_RemoteEventLogs
PROGRAM prg_RemoteEventLogs
VAR
LogManager : class_LogDirectoryManager( folderName := '/RemoteLogs/',
logPostfix := '',
maxFolderSize := 10240,
maxNumFiles := 10,
autoStartNewLogDaily := FALSE);

EventPostfix : String(16) := 'RTAC1.event';


ServerIP : STRING(15) := '192.168.0.2';
RemotePath : STRING := '/RTAC1_Event_Files/';
FtpUser : STRING := 'FTPUSER';
FtpPassword : STRING := 'TAIL';

FirstScan : BOOL := TRUE;


Workbench : STRING(255);
END_VAR

IF FirstScan THEN
LogManager.SetFtpServerForArchiving( ftpServer := ServerIP,
remotePath := RemotePath,
username := FtpUser,
password := FtpPassword,
timeout := 5,
schedule := ON_UPDATE);
FirstScan := FALSE;
END_IF

//Do any work and logging desired.


IF g_EventOccurred THEN
LogManager.EventLogFromString( str := g_EventDescription, eventPostfix := EventPostfix);
g_EventOccurred := FALSE;
END_IF
LogManager.Run();

Date Code 20241023 Programming Reference


510 FileIO
Examples

Iterating Over All SOEs


Objective
You need to programmatically iterate over all SOEs from the RTAC and be sure
that every SOE after a certain time is addressed.

Assumptions
Your workload requires assurances that every SOE is seen and that duplication
of responses to SOEs is unacceptable. In this use case, the order of the events
matters less than ensuring that each event is seen and addressed. For this method
to work, the SOEs must either be all from the local RTAC or from external
devices being logged on the RTAC. If both types of SOEs exist, they would need
to be handled independently.

Solution
You periodically query the system for the next c_MaxSoeCount SOEs that have
not yet been addressed.
Code Snippet 16.18 prg_SoeIterator
PROGRAM prg_SoeIterator
VAR CONSTANT
c_MaxSoeCount : UINT := 10;
END_VAR
VAR
// Variables to control the program flow
GetFirstSOE : BOOL := TRUE;
SoeQueried : BOOL := FALSE;
DoWork : BOOL := FALSE;
i : UINT;

// Input Filters
StartTime : DT := DT#2000-1-1-0:0:0;
Filters : FileIo.sel_file.Struct_soe_filter;

// Variables to store function output


Status : FileIo.sel_file.Enum_sel_file_errors;
Content : ARRAY [1..c_MaxSoeCount] OF
FileIo.sel_file.Struct_soe_content_id;
LastOutput : FileIo.sel_file.Struct_soe_content_id;
Count : UINT;
END_VAR

IF GetFirstSOE THEN
// We need to get a starting SOE.
IF NOT SoeQueried THEN
FileIo.fun_LocalSoeGetID(StartTime, Filters, Status, Content[1]);
SoeQueried := TRUE;
ELSE
IF Status = FileIo.sel_file.SYSTEM_BUSY THEN
// The system was too busy try again.
SoeQueried := FALSE;
ELSIF Status = FileIo.sel_file.NO_ERROR THEN
// We got a result, switch to group queries
GetFirstSoe := FALSE;
SoeQueried := FALSE;
LastOutput := Content[1];
StartTime := Content[1].TimeStamp;
// This function only ever returns one result.
Count := 1;
// Trigger processing for the SOE data returned

Programming Reference Date Code 20241023


FileIO 511
Examples

DoWork := TRUE;
ELSIF Status = FileIo.sel_file.OPERATION_FAILED THEN
;(* The database was unable to find any SOEs matching the filters provided. *)
ELSIF Status <> FileIo.sel_file.IN_PROGRESS THEN
;(* If we arrive here configuration is bad and needs to be manually adjusted
to continue. *)
END_IF
END_IF
ELSE
IF NOT SoeQueried THEN
// Beginning from the last SOE received, query for the next set of SOEs.
FileIo.fun_LocalSoeAscending( ADR(content[1]), LastOutput.ID,
c_MaxSoeCount,
Filters, Status, Count);
SoeQueried := TRUE;
ELSE
IF Status = FileIo.sel_file.SYSTEM_BUSY THEN
// The system was too busy try again.
SoeQueried := FALSE;
ELSIF Status = FileIo.sel_file.NO_ERROR THEN
DoWork := Count > 0;
SoeQueried := FALSE;
IF DoWork THEN
// Store next lookup information if there is any.
LastOutput := Content[Count];
StartTime := Content[Count].TimeStamp;
END_IF
ELSIF Status <> FileIo.sel_file.IN_PROGRESS THEN
(* If we arrive here configuration is probably OK, as we got results above.
Something probably affected the ID we were using. Start over. *)
SoeQueried := FALSE;
GetFirstSOE := TRUE;
END_IF
END_IF
END_IF

IF DoWork THEN
// Process any new data.
FOR i := 1 TO Count DO
;(* Insert your code here to do work on the SOEs encountered. *)
END_FOR
DoWork := FALSE;
END_IF

Querying a Subset of SOEs


Objective
You want to display the 10 most recent SOEs each minute.

Assumptions
You have some code for presenting or communicating the SOE content at some
other location. In this use case, the order of events is more important than hard
guarantees of seeing each event occur.

Date Code 20241023 Programming Reference


512 FileIO
Examples

Solution
You periodically query the system for the most recent SOE data.
Code Snippet 16.19 prg_SoeUpdater
PROGRAM prg_SoeUpdater
VAR CONSTANT
c_MaxSoeCount : UINT := 10;
END_VAR
VAR
// This query has no filters, so leave all values as default empty strings.
Filters : FileIo.sel_file.Struct_soe_filter;
Status : FileIo.sel_file.Enum_sel_file_errors;

SoeData : ARRAY [1..c_MaxSoeCount] OF


FileIo.sel_file.Struct_soe_content;
SoesFound : UINT;

Timestamp : timestamp_t;
Now : DT;
Last : DT;

// These are the arrays populated with display data


Devices : ARRAY [1..c_MaxSoeCount] OF STRING(255);
Messages : ARRAY [1..c_MaxSoeCount] OF STRING(255);
Times : ARRAY [1..c_MaxSoeCount] OF DT;

// Flag indicating that SOE data has been requested and not copied.
Running : BOOL := FALSE;

i : UDINT;
END_VAR

(*Check for the first run after the SOE query completes.*)
IF Running AND Status <> FileIo.sel_file.IN_PROGRESS THEN
(* Loop across all found SOEs. This is guaranteed to be less than our array
* sizes c_MaxSoeCount because of the arguments passed to the function below *)
FOR i := 1 TO SoesFound DO
Devices[i] := SoeData[i].DeviceName;
Messages[i] := SoeData[i].Message;
Times[i] := SoeData[i].TimeStamp;
END_FOR
Running := FALSE;
END_IF

Timestamp := Sys_Time();
Now := Timestamp.value.dateTime;

(* Only query for SOEs on even minute intervals *)


IF ((DT_TO_UDINT(Now) MOD 60) = 0) AND
(* Only query for SOEs if any previous request has completed. *)
Status <> FileIo.sel_file.IN_PROGRESS AND
(* Only allow one query per second even if the last one completed. *)
Now > Last THEN
fun_SoeDescending(ADR(SoeData), Now, c_MaxSoeCount, Filters, Status, SoesFound);
Running := TRUE;
Last := Now;
END_IF

Listing the Content of a Directory


Objective
You want to list the files contained in the /TestDirectory.

Programming Reference Date Code 20241023


FileIO 513
Examples

You want the listing to automatically occur when the project is uploaded. In
addition, you want the ability to refresh the directory listing after the project is
downloaded by forcing a value in the online editor.

Assumptions
The directory content to be listed is uploaded.

Solution
Create the file list using the FileIo.class_DirectoryListing, and write that content
into an array to make it easier to see.
Code Snippet 16.20 prg_ListDirectory
PROGRAM prg_ListDirectory
VAR CONSTANT
c_MaxFilesToList : UDINT := 10;
c_MaxFilenameLength : UDINT := 255;
END_VAR
VAR
Lister : FileIo.class_DirectoryListing;
DirList : FileIo.class_SELStringList;
ArrayList : ARRAY[1..c_MaxFilesToList] OF
STRING(c_MaxFilenameLength);
Stage : UDINT := 1; // Force to 1 with <Ctrl> <F6> to run again
END_VAR
VAR_TEMP
i : UDINT;
pt_SelStr : POINTER TO FileIo.class_SELString;
END_VAR

CASE Stage OF
1: // Clear from last run, and request a new list
DirList.Clear();
FOR i := 1 TO c_MaxFilesToList DO
ArrayList[i] := ''; // Empty the array
END_FOR
Lister.CreateNewList(directoryName := '/TestDirectory', filter := '');
Stage := Stage + 1;
2: // Wait until done
IF Lister.NewListReady THEN
Lister.GetList(DirList);
// Read the list into the array
DirList.Begin(); // Start at the beginning of the list
FOR i := 1 TO DirList.Size DO
IF (i > c_MaxFilesToList) THEN
EXIT; // No more room in the array
END_IF
pt_SelStr := DirList.Next();
IF 0 <> pt_SelStr THEN // Always check pointers aren't 0
ArrayList[i] := pt_SelStr^.ToString();
END_IF
END_FOR
Stage := 0; // Reset to start
END_IF
ELSE
; // Do nothing
END_CASE
Lister.Run(); // Always run the worker method

Date Code 20241023 Programming Reference


514 FileIO
Examples

Pass Data From COMTRADE Record in Logic Engine


Objective
Pass Real data from a COMTRADE record stored in the RTAC's event
collection into the RTAC's logic engine.

Assumptions
An SEL-2245-42 with device name of CTPTModule is included in the Axion
backplane.

Solution
Read event data into the RTAC's logic engine using the
FileIo.class_ComtradeReader, and write one channel's content into an array.
Code Snippet 16.21 prg_EventDataToArray
PROGRAM prg_EventDataToArray
VAR CONSTANT
c_TriggerTimeVariance1 : UINT := 1000; // Milliseconds
c_EventRetrivalWaitTime1: UINT := 1; // Minutes
c_BeginingSample1 : UDINT := 1;
c_LastSample1 : UDINT := 1000;
c_AnaChannelNumber1 : UINT := 4;
c_DBReadWaitTime : TIME := T#30S;
END_VAR
VAR
Event1 : class_ComtradeParser;
AnalogInfo1 : struct_AnalogChannelInfo;
Device1 : STRING;
EventTrigTime1 : timestamp_t;
EventTrigDetc1 : R_TRIG;
GetEventTrig1 : R_TRIG;
GetSamplesTrig1 : R_TRIG;
SampVec1 : DynamicVectors.class_RealVector;
VAArray1 : ARRAY[0..999] OF REAL;
kindex1 : UDINT;
DBReadTimerEnable : BOOL;
DBReadTimer : TON;

Error : BOOL;
ErrorMessage : STRING := '';
END_VAR

// Collect event trigger timestamp


EventTrigDetc1(CLK := CTPTModule_ECAT.EVENT_TRIGGER);
IF EventTrigDetc1.Q THEN
EventTrigTime1 := SYS_TIME();
Device1 := 'CTPTModule';
DBReadTimerEnable := TRUE;
END_IF

// If event triggered, wait for event to load into database


DBReadTimer(IN := DBReadTimerEnable, PT := c_DBReadWaitTime);

// Read event from RTAC database


GetEventTrig1(CLK := DBReadTimer.Q);
IF GetEventTrig1.Q THEN
Event1.ReadEventFromDB(DeviceId := Device1,
TriggerTime := EventTrigTime1.value,
TimeVar := c_TriggerTimeVariance1,
WaitTime := c_EventRetrivalWaitTime1);
END_IF

Programming Reference Date Code 20241023


FileIO 515
Examples

IF Event1.NewEventReady THEN
IF Event1.GetAnalogChannelInfo(ChannelNumber := c_AnaChannelNumber1,
ChannelInfo => AnalogInfo1)
THEN
IF EVENT1.GetRealVector(ChannelInfo := AnalogInfo1,
FirstSample := c_BeginingSample1,
LastSample := c_LastSample1,
SampleVector := SampVec1) THEN
FOR kindex1 := c_BeginingSample1 - 1 TO c_LastSample1 - 1 DO
SampVec1.GetAt(index := KIndex1, element => VAArray1[KIndex1]);
END_FOR
ELSE
Error := TRUE;
ErrorMessage := 'Unable to retrieve REAL vector';
RETURN;
END_IF
ELSE
Error := TRUE;
ErrorMessage := 'Unable to retrieve analog channel info';
RETURN;
END_IF

END_IF
EVENT1.Run();

Monitor Values of Logic Engine Variables and Restore Them on Startup


Objective
Implement functionality to monitor and store the states of various logic engine
variables and automatically restore their previous value upon RTAC restart.

Solution
Use FileIo.class_PersistentData, to monitor and restore a collection of user logic
variables.
Code Snippet 16.22 prg_PersistentData
PROGRAM prg_PersistentData
VAR
FirstRun : BOOL := TRUE;
MyStoredData : FileIo.class_PersistentData(PersistentPath := '/datastore.json',
WriteInterval := T#5S, LogRunTimeErrors := TRUE);
aBoolVariable : BOOL;
defaultBool : BOOL := FALSE;
aRealVariable : REAL;
defaultReal : REAL := 1.234;
aStringVariable : STRING(255);
defaultString : STRING(255) := 'default string content';
aSPSVariable : SPS;
defaultSPSVariable : SPS;
END_VAR

IF FirstRun Then
MyStoredData.bootstrap_Variable(ADR(aBoolVariable), SIZEOF(BOOL),
'aBool', ADR(defaultBool));
MyStoredData.bootstrap_Variable(ADR(aRealVariable), SIZEOF(REAL),
'aReal', ADR(defaultReal));
MyStoredData.bootstrap_Variable(ADR(aStringVariable),
SIZEOF(STRING(255)), 'aString', ADR(defaultString));
MyStoredData.bootstrap_Variable(ADR(aSPSVariable), SIZEOF(SPS),
'aSPSTag', ADR(defaultSPSVariable));
FirstRun := FALSE;
END_IF

Date Code 20241023 Programming Reference


516 FileIO
Examples

MyStoredData.Run();

Upon initial loading of this program onto an RTAC, the values of the 3 simple
variable types specified as aBoolVariable, aRealVariable and aStringVariable are
"FALSE", "1.234" and "default string contents" respectively. The aSPSVariable
contains a default SPS structure with a time stamp initialized to the RTAC
startup time. If the values in those variables later update and the RTAC is
subsequently restarted, the updated values stored in the managed JSON file will
be restored.

Programming Reference Date Code 20241023


S E C T I O N 1 7

GridConnect
Introduction
The GridConnect library is designed for use with the SEL Real-Time
Automation Controller (RTAC) family of products. It contains ready-to-use
function blocks for controlling the point of common coupling (PCC) between
the utility grid and a solar power generation resource. The GridConnect library
uses proportional integral (PI) controllers when in a closed-loop mode to
regulate output set points.

Feature Summary
This library contains the following features for PCC of a solar facility to the
utility grid.

Reactive Control at PCC


➤ Closed-loop control of power factor
➤ Closed-loop control of reactive power (constant VAR)
➤ Closed-loop control of voltage
➤ Closed-loop power factor compensation
➤ Closed-loop voltage compensation
➤ Open-loop control of power factor (PCC set-point pass-through)

Power Limit Control at PCC


➤ Closed-loop control of power output (i.e., advanced power limit control)
➤ Open-loop control of power output (i.e., simple power limit control)

Frequency Regulation at PCC


➤ Automatic adjustment of plant power output in response to system
frequency changes
➤ Automatic adjustment of storage device output in response to system
frequency changes

Additional Features
➤ PCC voltage limit override when in power factor or reactive power
control or compensation modes
➤ PCC power factor limit override when in voltage control or compensation
modes

Date Code 20241023 Programming Reference


518 GridConnect
Supported Firmware Versions

➤ Integrated control of PV inverters, storage inverters, and capacitors to


provide precise control at the PCC
➤ Solar Smoothing integrates storage assets with PV assets to maintain
ramp rates for increasing or decreasing PV power output
➤ Automated charging of storage assets

Licensing
GridConnect versions 3.5.3.X and later support two license tiers. The two
licenses will show up on the RTACs web interface with the following strings.

➤ GridConnect_5MW: This license supports managing systems up to 5MW.


This is determined by adding up the PRating input of each manager asset.
This includes all inverter and storage function blocks. If the total capacity
of power system assets starts below 5MW, then increases above 5MW
GridConnect will disable and will not re-enable until the RTAC has been
power cycled. All features are supported with this license.
➤ GridConnect: This license has no restrictions on features or power
managed.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_GridConnectObjectObject"
myGridConnectObjectObject := otherGridConnectObjectObject;

// This is fine
someVariable := myGridConnectObjectObject.value;
// As is this
pt_myGridConnectObjectObject := ADR(myGridConnectObjectObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Programming Reference Date Code 20241023


GridConnect 519
Operational Modes

Operational Modes
Overview
The master plant controller (hereafter referred to as the Controller) is operated
in several different control modes, each having the objective of controlling
or compensating power factor, reactive power, or voltage. The desired mode
is provided as an input on the fb_MasterPlantController function block. The
controller is enabled by asserting the Enable input and is disabled by deasserting
the Enable input. Top-level mode and enable/disable control inputs are described
in Table 17.1.

Table 17.1 Master Plant Controller Control Mode Parameters

Parameter Description

ControlMode PCC control mode:


➤ 0 = Power Factor Control
➤ 1 = VAR Control
➤ 2 = Power Factor Compensation
➤ 3 = Voltage Compensation
➤ 4 = Voltage Control
➤ 5 = Open-Loop Power Factor Control
➤ 6 = No Reactive Control

Enable PCC control enable

StorageOperationMode Storage Operation mode:


➤ 0 = Manual Storage Operation
➤ 1 = Downramp
➤ 2 = Storage Generation
➤ 3 = Coordination Mode
➤ 4 = Managed By Grid Connect

PLimitMode Power limit mode:


➤ 0 = NoLimit
➤ 1 = Simple
➤ 2 = Advanced
➤ 3 = PCC Metering
➤ 4 = Constant PCC Power

When the controller is in open-loop power factor control mode it passes the
power factor set point to the power factor reference for all inverters in the
facility. This mode is used as a fall-back mode (when PCC measurements are not
reliable).

In closed-loop mode, the controller automatically adjusts either the power,


power factor, or VAR reference signal of the inverter to perform control or
compensation at the PCC.

The controller automatically adjusts the power limit reference signal of the
inverters to limit the cumulative power output of the plant.

Configuring Grid Connect Regardless of Operation Modes


The following settings are used as guard rails in generating real and reactive
power set points to make sure GridConnect does not calculate a value that
is outside of the operating ranges of the system as a whole as defined by the
configuration. Regardless of operation mode, it is important that each of these

Date Code 20241023 Programming Reference


520 GridConnect
Operational Modes

is configured with operating ranges of the actual system and that the metering
values are within the defined ranges. If PlantP, PlantQ, PlantPF, or PlantV inputs
are outside the ranges defined by these settings, it will affect the set points for
each inverter.
➤ QLimitHigh
➤ QLimitLow
➤ PFLagLimit
➤ PFLeadLimit
➤ VLimitHigh
➤ VLimitLow
➤ dV_dQ
➤ PlantPRating
➤ PlantQRating
➤ PlantLowPowerCutoff
The following settings tell GridConnect the mode in which it will operate for
four primary categories: real power management, reactive power management,
coordination with any configured storage assets, and frequency regulation.
GridConnect can operate in one real power mode and one reactive power
mode at a time. Please note that some real power management modes are
not compatible with all StorageOperationMode inputs and will override
StorageOperationMode. Frequency regulation is supported for the following real
power modes:
➤ PLimitMode
➤ ControlMode
➤ StorageOperationMode
➤ FrequencyRegulationMode
The following inputs are used to manage the operation of GridConnect to drive
the set points configured by the user in the active control modes. All of these
settings must be set to appropriate values during the operation of the system.
➤ Enable
➤ PlantP
➤ PlantQ
➤ PlantPF
➤ PlantV
➤ PlantF
➤ PlantMeasurementsGood
➤ EvaluationPeriod
➤ ControlRetryPeriod
➤ InverterModeChangeControlDelay

Data Recording
Starting in version 3.5.7.0, GridConnect will automatically create several
log files that record operational data and system settings information.
Operational status logging will record changes in system setpoints calculated
by GridConnect over time and PCC data. System settings logging will record
changes in system settings like set point, deadbands, and operational modes.

Programming Reference Date Code 20241023


GridConnect 521
Operational Modes

Data recording in GridConnect is offered by default to provide records of


common operational data that are useful for troubleshooting and understanding
system calculations. Additional or customized data logging can be done
using the RTAC Dynamic Disturbance Recorder (DDR) license included
with the GridConnect license. This allows users to configure additional data
logging as necessary to meet the needs of an installation. It is possible to run
DDR in conjunction with, or separately from, GridConnect's built-in logging
functionality. If you have interest in logging data other than the default data
described here, review instructions and reference material relative to the
Dynamic Disturbance Recorder in Section 10 of the ACSELERATOR RTAC
SEL-5033 Instruction Manual.

Logging Rate
When operating in grid connected mode, the master plant controller will record
data on each evaluation period. When operating in islanded mode, the master
plant controller will record data every RTAC task-cycle in an effort to provide
additional visibility.

Settings SOE
GridConnect provides a log file intended to keep track of asset operation status
and operation setpoints. The log file will be generated in a directory called
"GridConnectLogs_" appended with the fb_MasterPlantController instance
name. New log files will be generated every 14 days or once the log file reaches
a size of 250 KB, whichever occurs first. Once the folder reaches a size of 1
MB, the oldest log file will be deleted. If the log files or directory are deleted,
GridConnect will automatically regenerate the directory and start a new log file.
Files in the directory will be named with the time that the log file started and
appended with GridConnect_log. Recorded data include:

➤ Real Power Setpoint Changes


➤ Reactive Power Setpoint Changes
➤ Power Factor Setpoint Changes
➤ PLimitMode Changes
➤ ControlMode Changes
➤ FrequencyRegulationMode Changes
➤ StorageOperationMode Changes
➤ Quickstop Changes
➤ Asset availability
➤ Asset inclusion or exclusion from GridConnect control
➤ Asset Group Changes
➤ Asset real or reactive power clamps
➤ System Capacity Changes

Date Code 20241023 Programming Reference


522 GridConnect
Operational Modes

Site Operational Data


GridConnect will automatically manage the rotation of files that it generates
based on the configuration provided. Two standard options exist to configure
this file-rotation system, which can be set using the enum_fileConfig
enumeration (see enum_fileConfig on page 555). An approximation of
the total size of a log file may be determined with the following equations.
Equation 17.1 is relevant for grid connected operations, and Equation 17.2 can
be referred to for islanded operations.

NOTE
Site Operational Data records data respective to the active generation assets
that are included for control in the fb_MasterPlantController following the
boot-up delay and license checks. This means that any assets included after
the fb_MasterPlantController enables will not be logged and any assets
excluded following this initialization will continue to be logged.

Equation 17.1

Equation 17.2

GridConnect will retain data in each respective folder and will automatically
rotate data in a first-in, first-out (FIFO) manner. Oldest data files will be
removed as the directory reaches the limit configured by MaxFolderSize on
the fb_MasterPlantController. To evaluate the approximate number of days for
which logs will be retained during grid connected operations, use Equation 17.3.
When operating in islanded mode, use Equation 17.4.

Equation 17.3

Equation 17.4

The log file will be generated in a directory called "GridConnectLogs_"


appended with the fb_MasterPlantController instance name. These data will be
recorded in one of two different CSV files depending on the grid connected or
islanded operation mode. These modes can be correlated to the file paths that are
used as follows:

Grid Connected: /FILES/GridConnectLogs_<controller-name>/Grid-Connected/

Islanded: /FILES/GridConnectLogs_<controller-name>/Islanded/

The following tables denote the complete list of data points that are logged in
grid connected or islanded states, respectively.

Programming Reference Date Code 20241023


GridConnect 523
Operational Modes

Evaluation Period
The EvaluationPeriod setting manages how often GridConnect generates new
set points for inverters to implement. SEL recommends that this be set to a
minimum value of 105 percent of the update rate from the PCC. If inverters do
not respond quickly to set points, a larger evaluation period may be necessary.
Many of the modes in GridConnect use a PI controller to calculate set points.
Just like any PI controller, if it runs more frequently than the data update or
faster than the system can respond, the controller will accumulate errors, which
is likely to generate undesirable set points.

Managing Closed-Loop Controls


GridConnect employs the use of proportional-integral controllers in calculating
set points for a variety of operation modes. All PI controllers follow the ideal
PI controller model. The pseudo code for all GridConnect PI controllers is as
follows:

IF CurrentValue <> Setpoint +/– Deadband THEN


Error = Setpoint – CurrentValue
IntegralTerm = IntegralTerm + (Error * EvaluationPeriod)
PICorrection = Kp * Error + Ki * IntegralTerm
Output = OldOutput + PICorrection
ELSE
Integral = 0
Correction = 0
END_IF

For an EvaluationPeriod of one second, this would translate to multiplying the


error by one in calculating the IntegralTerm. Tuning of the PI controller is the
responsibility of the end user. Starting in GridConnect version 3.5.4.3, there
are POU output pins on the fb_MasterPlantController that show the error and
integral terms for each PI controller that is active in GridConnect.

The feedback signal, which is used in all PI controllers, comes from the PCC
measurements (i.e., PlantP, PlantQ, PlantV, PlantPF, or PlantF).

Generation Groups
Starting in GridConnect version 3.5.7.0, all asset types except capacitors will
have the ability to be assigned a generation group number. GridConnect will
attempt to meet set-point objectives with assets assigned to group number one. If
group one is unable to meet system objectives on its own, then group two assets
will be utilized. This cycle will be repeated for subsequent groups. There are ten
possible groups. Generation groups only apply to grid connected modes. The
following requirements must be met when adding assets to a generation group:

➤ A group cannot contain multiple asset types. For example, a PV inverter


and Storage inverter cannot be members of the same group.
➤ The generation group input must be between 1 and 10. Any other input
will result in the asset being excluded from all groups.

Date Code 20241023 Programming Reference


524 GridConnect
Operational Modes

➤ If ExcludeCommand is asserted on an asset, the asset will be removed


from its active generation group. When an asset is excluded from
GridConnect control, the IncludedInMasterControl output pin is
deasserted and all setpoints remain unmodified.
➤ Assets can change group numbers during run time. When an asset
changes group, its output will change to the new generation group's
output on the subsequent evaluation interval.
➤ When an asset is not a part of any generation group, the active generation
group output will be set to 65,535.
➤ In order for an asset to be added to a generation group, the reserve input
pin must match the reserve status of other assets in that group. If the asset
does not match the reserve status of the other assets in the group, the asset
is not added to the group until the reserve status matches. If reserve status
for an asset changes after it is added to the group, it does not take effect
until the asset is removed from the group and moved to a new group that
has assets with a matching reserve status.

Assets that are marked as reserved within a group will only be used to meet
reserve objectives. Different assets marked as reserved may only participate in
certain reserve objectives. See each asset type for the reserve objectives it will
participate in.

Managing Anti-Windup in Closed-Loop Controls


Real power anti-windup protections are supported starting in version 3.5.0.0.
Real power anti-windup only operates in Advanced PLimitMode.

Reactive power anti-windup protections are supported starting in version 3.5.6.0.


Reactive power anti-windup operates in the Var Control, Voltage Control, and
Voltage Compensation modes.

Reactive power anti-windup protections for storage assets are supported starting
in version 3.5.7.4.

If an inverter does not respond to the power set point, the inverter will decrease
the power set point to the inverter to a value slightly above its current power
output. This power clamp limit prevents inverter windup if the condition
preventing the inverter from outputting its target value is suddenly removed.
The power clamp limit occurs when the inverter power has not come within
the PowerClampMarginPercent of the current set point on the inverter. If an
inverter is currently in power clamp mode, this is reflected by the output pin on
the inverter block, PowerClampActive or ReactiveClampActive. These pins are
driven by the following logic; this example uses real power, but the same logic
and inputs apply for reactive power:

Conditions for entering and leaving power clamp mode prior to version 3.5.7.0:

PowerClampPickupTimer(IN = InverterP < (PLimitSetMag –


(PowerClampMarginPercent * PRating)), PT = PLimitDelay);
PowerClampActive = PowerClampPickupTimer.Q;

When an inverter's PowerClampActive output pin is TRUE, the PLimitSetMag


will be determined by the following equation:

PLimitSetMag = InverterP + PRating* PowerClampMarginPercent

Programming Reference Date Code 20241023


GridConnect 525
Operational Modes

Power clamp mode is deactivated when InverterP has come within 5 percent of
PLimitSetMag.

Conditions for entering and leaving power clamp mode prior to version 3.5.7.0:

PowerClampPickupTimer(IN = AssetP < (PLimitSetMag –


(PowerClampMarginPercent * PRating)) OR ((PLimitSetMag <
(PowerClampMarginPercent * PRating)) AND AssetP < (PLimitSetMag
– (AssetPError * PRating))), PT = PLimitDelay); PowerClampActive =
PowerClampPickupTimer.Q;

When an asset's ClampActive output pin is TRUE, the PLimitSetMag will be


determined by the following equation:

PLimitSetMag = AssetP + PRating * PowerClampMarginPercent

Power clamp mode is deactivated when the asset's response is greater than the
proportional setpoint for the group. Until this condition occurs, the setpoint will
be PowerClampMarginPercent above the current asset response.

When considering the value of PowerClampMarginPercent to assist with anti-


wind up and overshoot, it is important to consider the scenario where one or
more inverters are in power clamp mode and PlantP is within the deadband of
the PSetpoint. To ensure a smooth transition after an asset leaves power clamp
mode, the PLimitSetMag of the power clamped asset above AssetP must be
less than the deadband around Psetpoint. This is because GridConnect has a
smoothing function to return all inverters to proportional setpoints after a power
clamp is removed, provided that PlantP is within the deadband of Psetpoint.

The value of AssetPError should be slightly above the error of the asset's
response. For example, if the setpoint for a given asset is 100, and the device
typically settles in at a value of 97, that asset has a 3 percent error in its
response. Therefore, the recommended AssetPError setting would be 3.5 or 4.
This helps detect when an asset needs to enter power clamp mode if the setpoint
is below PowerClampMarginPercent. Additionally, when an asset is power-
clamped, if the plant response is above the deadband of the setpoint, the setpoint
for the clamped asset will be the response plus the AssetPError (instead of
PowerClampMarginPercent). This helps prevent the system from increasing
site output when plant response is over the current target setpoint. Once the site
response is within the deadband of the setpoint or below the deadband of the site
setpoint, the clamped asset will return its setpoint to PowerClampMarginPercent
plus asset response.

If PlantP is outside the deadband of Psetpoint, then all inverters are driven
proportionally as quickly as possible to the deadband of Psetpoint. This
may cause some over- or undershoot during this transition. Ensuring that
PowerClampMarginPercent is configured such that the difference between
PLimitSetMag and AssetP is less than the deadband around PSetpoint will
ensure a smooth transition after an asset leaves power clamp mode. For
example, if PowerClampMarginPercent is 3 percent, an asset has a PRating
of 1000, current AssetP is 100, and Pdeadband is 50. These settings would
mean the single asset would have a PLimitSetmag of 130 when InverterP is 100
during power clamp. This is less than the Pdeadband of 50, making it likely that
as the asset initially leaves power clamp mode, it will keep the system within
the deadband of PlantP. Ultimately, this will allow GridConnect's smoothing
function to return all inverters to a proportional set point. If there are multiple
inverters that may be in power clamp mode in this example scenario, it is
important to consider the probability of all power clamped inverters returning

Date Code 20241023 Programming Reference


526 GridConnect
Operational Modes

to normal operation simultaneously. The asset makes small adjustments in order


to return to a proportional deadband. The adjustment amount can be configured
per inverter by the ContinuityAdjustment setting. This setting adjusts the
PlimitSetmag of the inverter by a percentage of the asset PRating. By default,
this is set to 0.25 percent. For most systems this will be a slow rate of change but
will help ensure a smooth transition. This value can be configured to increase
the rate at which the inverter returns to a proportional PLimitSetMag but should
not be increased such that it causes PlantP to exceed Pdeadband of Psetpoint.

Control Modes
The GridConnect library supports a variety of reactive power control modes.
This section provides details about the following modes: no reactive control,
power factor, voltage, VAR, and open-loop power factor. The remaining two
modes are compensation modes and are detailed in Compensation Modes on
page 530.
Reactive power objectives are only met with generation groups that are used
to meet real power objectives as defined by PSetpoint. The following pseudo-
code describes how reactive power objectives are distributed between generation
groups. If reactive power requirements cannot be met with active generation
groups for PSetpoint objectives, additional generation groups will not be
utilized. For this scenario, SEL recommends that generation assets are re-
organized such that real and reactive power objectives can both be met with the
generation groups that meet PSetpoint objectives.

FOR i = 1 TO numGenerationGroups BY 1 DO
IF GenerationGroup[i].PSetpointActive THEN
IF GenerationGroupInfo[i].capability > remainingSetpoint THEN
GenerationGroupInfo[i].setpoint = remainingSetpoint
remainingSetpoint = 0
EXIT
ELSE
GenerationGroupInfo[i].setpoint = GenerationGroupInfo[i].capability
remainingSetpoint = remainingSetpoint - GenerationGroupInfo[i].setpoint
END_IF
END_IF
END_FOR

No Reactive Control
When the controller is in no reactive control mode, it will not send any VAR
or power factor set points to the inverter. In addition, it will not change the
operating mode of the inverter. Any current set points on the inverter function
block outputs will be left as is. The trigger bits for VAR or power factor set
points will not assert while this mode is active.

Power Factor Control


When the controller is in power factor control mode, it adjusts the power factor
reference of the inverter to provide precise adjustment of the power factor at
the PCC. The controller uses a proportional integral (PI) controller for these
adjustments. For this mode to function properly, the inverter must be in power
factor control mode (as opposed to VAR control mode). If the inverter is not
in power factor control mode, the controller will periodically attempt to send
a mode change control. The inverter is considered unavailable to the master
controller if it is unable to change modes.

Programming Reference Date Code 20241023


GridConnect 527
Operational Modes

Closed-loop behavior of power factor control is managed using the following


inputs on the fb_MasterPlantController:

➤ PFSetpoint
➤ PFDeadband
➤ PFKp
➤ PFKi
➤ PFRampSetpoint

Once PlantPF is within the range of PFSetpoint ± PFDeadband, the error and
integral of the closed control loop managing power factor will be set to zero.
Inverter set points for power factor will remain steady until PlantPF is outside
the deadband around PFSetpoint. See the following model diagram for operation
of power factor control in the time and frequency domains.

Figure 17.1 Power Factor Control Mode Models

VAR Control
When the controller is in VAR control mode, it adjusts the VAR reference
of the inverter to provide precise adjustment of VAR flow at the PCC. The
controller uses a PI controller for these adjustments. For this mode to function
properly, the inverter must be in VAR control mode (as opposed to power factor
control mode). If the inverter is not in VAR control mode, the controller will
periodically attempt to send a mode change control. The inverter is considered
unavailable to the master controller if it is unable to change modes.

See the following model diagram for operation of VAR control in the time and
frequency domains.

Date Code 20241023 Programming Reference


528 GridConnect
Operational Modes

Figure 17.2 VAR Control Mode Models

Closed-loop behavior of VAR control is adjusted using the following inputs:

➤ QSetpoint
➤ QDeadband
➤ QRampSetpoint
➤ QKp
➤ QKi

Voltage Control
When the controller is in voltage control mode, it adjusts the VAR reference
of the inverter to provide precise adjustment of the voltage magnitude at the
PCC. The controller uses a PI controller for these adjustments, and separate
tuning parameters (VKp and VKi) are provided for this mode. For this mode
to function properly, the inverter must be in VAR control mode (as opposed
to power factor control mode). If the inverter is not in VAR control mode, the
controller will periodically attempt to send a mode change control. The inverter
will be considered unavailable to the master controller if it is unable to change
modes.

It is important that PlantV is within the range of VLimitHigh and VLimitLow.


If it is not, the max and min Q values at the voltage limits will be significantly
distorted, causing nonfunctional set points. The min and max Q values at
the voltage limits are identified on output pins CalculatedQAtVHighLimit
and CalculatedQAtVLowLimit. These Q limits are defined by the following
equations.

CalculatedQAtVHighLimit = PlantQ + ((VLimitHigh – PlantV) /


ConditionedDVDQ);

Programming Reference Date Code 20241023


GridConnect 529
Operational Modes

CalculatedQAtVLowLimit = PlantQ – ((PlantV – VLimitLow) /


ConditionedDVDQ);
GridConnect also checks that QSetpoint calculated for voltage control does
not exceed the ranges of Q at the PCC at the defined lead and lag limits for
power factor. This is reflected in the output pins CalculatedQAtPFLeadLimit
and CalculatedQAtPFLagLimit.
The input setting dV_dQ is the relationship between voltage and reactive power.
It is the ratio of one voltage change over the number of VARs needed to cause
that voltage change.
Voltage set points at the PCC given to GridConnect are translated to VAR set
points distributed to inverters. Because the control loop is driving VARs to a
target value to achieve a voltage set point, the voltage deadband is converted
to a VAR deadband. The QDeadband in Voltage control mode is VDeadband/
dV_dQ.
The QSetpoint achieved at the PCC is determined by the following equation:
Voltage QSetpoint = PlantQ + (VSetpoint – PlantV) / dV_dQ;
The input dV_dQ heavily influences the voltage control management. Having
this input match system performance allows the voltage set point to be reached
faster with a smoother response. If this input does not match the voltage-to-
reactive-power-change ratio, the PI controller, in most cases, correctly drives the
system to the voltage set point. If the configured dV_dQ is significantly different
than the actual volt/VAR relationship in this system, the resulting plant voltage
may be outside of the configured voltage deadband. This is because the voltage
deadband is translated to a QDeadband in which dV_dQ is an important factor.
The following logic diagram shows the process for generating a QSetpoint from
a VSetpoint input modeled in both the time and frequency domains.

Figure 17.3 Voltage Control Mode Models

Date Code 20241023 Programming Reference


530 GridConnect
Operational Modes

Settings on the fb_MasterPlantController that affect voltage control are the


following:

➤ VSetpoint
➤ VDeadband
➤ VKp
➤ VKi
➤ dV_dQ
➤ QRampSetpoint

Open-Loop Power Factor Control


When the controller is in open-loop power factor control mode, it passes the
power factor set point to the power factor reference for all configured inverters.
For this mode to function properly, the inverter must be in power factor control
mode (as opposed to VAR control mode). If the inverter is not in power factor
control mode, the controller will periodically attempt to send a mode change
control. The inverter will be considered unavailable to the master controller if it
is unable to change modes.

Power factor ramp rate changes are also passed to the inverters. Settings on the
fb_MasterPlantController that affect open-loop power factor are the following:

➤ PFSetpoint
➤ PFRampSetpoint

Compensation Modes
The GridConnect library supports both power factor and voltage compensation.
These modes regulate the controlled value (power factor or voltage) in a
response proportional to the percentage of plant output power or voltage.

Power Factor Compensation


When the controller is in power factor compensation mode, it regulates the
power factor at the PCC based on how much power the plant is generating. This
mode uses the same PI controller tuning parameters as the Power Factor control
mode. The relationship between power factor and plant power output is a slope
defined by a power factor compensation gradient setting (its units are PF/%kW).
Control of the PCC power factor is limited by a compensation limit setting, as
well as a low power cutoff setting.

This mode requires that the inverters be in power factor control mode. Any
inverter not in power factor control mode is flagged as unavailable to the master
controller and is periodically sent a mode change control signal.

Settings on the fb_MasterPlantController that affect power factor compensation


are the following:

➤ PFCompensationSetpoint
➤ PFCompensationCutoff
➤ PFCompensationGradient

Programming Reference Date Code 20241023


GridConnect 531
Operational Modes

➤ PFCompensationLimit
➤ PFKp
➤ PFKi

Voltage Compensation
When the controller is in voltage compensation mode, it regulates VAR
flow at the PCC based on voltage at the PCC. This mode uses the same PI
controller tuning parameters as the Voltage Control mode, this mode the plant
can provide VAR support for grid voltage, even at night or when real power
output is otherwise very low. The relationship between VAR output and voltage
magnitude follows a curve defined by voltage and VAR set points (as illustrated
in Figure 17.4). These inputs can be adjusted at any time, which will change
the curve being used by the controller for voltage compensation. If these inputs
are made variable, it is important to ensure that they have correct and intended
values at all times, including at controller startup.

Figure 17.4 Voltage Compensation Curve

This mode requires that the inverters be in VAR control mode. Any inverter not
in VAR control mode is flagged as unavailable to the master controller and is
periodically sent a mode change control signal.
The following settings are used to manage Voltage Compensation Mode:
➤ VCompensationV1
➤ VCompensationV2
➤ VCompensationV3
➤ VCompensationV4
➤ VCompensationQ1
➤ VCompensationQ2
➤ VCompensationQ3
➤ VCompensationQ4

Date Code 20241023 Programming Reference


532 GridConnect
Operational Modes

➤ VKp
➤ VKi
➤ QRampSetpoint
➤ QDeadband
The following logic diagram shows the process for generating a QSetpoint
from the voltage compensation mode modeled in both the time and frequency
domains.

Figure 17.5 Voltage Compensation Mode Models

Capacitor Control
The master controller calculates the reactive power required to achieve the
active control objective (i.e., VAR, voltage, or power factor at the PCC).
Additionally, the master controller calculates the reactive power available to be
added or removed using inverters and capacitors. Generally, the capacitors will
operate to improve the power factor of the inverters that GridConnect manages.
If inverters collectively output more than the setting, CapacitorOperatePercent
(default is 75), which is a percentage of the next capacitor rating selected to
operate for a time duration that exceeds the setting CapacitorPickUpTime, the
capacitor will close (as long as the CapacitorOperationPeriod interval is not
violated). In this manner, the master controller will attempt to use capacitors
to make coarse control adjustments at the PCC and use the inverters to reach
and maintain fine control at the PCC. This functionality is demonstrated by the
following equation.
Total Inverter Q >= Next Capacitor Q Rating * CapacitorOperationPeriod
Capacitor banks will open when collective inverter Q output is less than Q's to
be removed by the next capacitor block. This functionality is demonstrated by
the following equation.

Programming Reference Date Code 20241023


GridConnect 533
Operational Modes

Total Inverter Q <= Next Capacitor Q Rating * CapacitorOperationPeriod


Capacitors will close on the sequence defined by the input pin SequenceNumber
of each capacitor. The last capacitor to close in will be the first capacitor to
open.
The following settings are used to manage capacitor operation on the
fb_MasterplantController:
➤ CapacitorOperationPeriod
➤ CapacitorOperatePercent
➤ CapacitorPickUpTime
➤ CapacitorDropOutTime

Storage Inverter Control


The storage inverter function block functionality added in GridConnect version
3.5.2.X may be incompatible with previous versions of the storage inverter
function block. Previous configurations that included the storage inverter
function block may require some configuration changes. All storage inverter
control functionality prior to 3.5.2.X is retained.
The GridConnect library provides a storage inverter function block. The
storage inverter provides the same functionality as PV inverters in terms of real
power and reactive control modes. Storage inverters have a MinStateOfCharge
input pin, defined as a state of charge (SOC) percentage, that limits how far
GridConnect will discharge the storage. Once this SOC percentage has been
reached, GridConnect will apply the defined downramp rate and decrease
power output from the storage inverter until the real power output from that
inverter is 0. If a single storage inverter reaches this condition, GridConnect
will attempt to meet the plant power set point by increasing output from other
storage inverters if their SOC is still greater than the MinStateOfCharge.
MinStateOfCharge can dynamically change during run time. Setting this value
to 0 will cause power to be requested from the storage inverter until it is unable
to provide any additional power. Configuring a storage inverter as such, or
with a very low MinStateOfCharge value, may cause damage to the storage
asset. Users should consult the storage asset documentation and vendor to
understand the risks of discharging their storage assets beyond certain levels. If
storage inverter power reaches 0 due to SOC meeting MinStateOfCharge, and
MinStateOfCharge is subsequently set to a new lower value, ramp rates will
apply to power discharged from the battery because SOC is again greater than
MinStateOfCharge.
There are three methods to charge storage assets:
➤ StoragePSetPoint on each inverter allows users to set individual charge
set points for storage assets. This manual control of storage assets is
only available when StorageOperationMode is in ManualStorage or
DownRamp. As long as the input is non-zero, the storage asset will be
unavailable for discharge or participation in GridConnect operation. Once
the SOC reaches the maximum defined SOC, the inverter will receive an
updated set point to stop charging.
➤ StorageChargeSetpoint on the master plant controller. This set point
will be divided proportionally among the configured storage inverters.
Each storage inverter takes an input, MaxChargingPower, which
is typically a feedback point from the storage asset that defines the

Date Code 20241023 Programming Reference


534 GridConnect
Operational Modes

maximum amount of current the storage asset can presently consume. If


the proportionally defined charge amount for a storage inverter exceeds
this input, that storage inverter's charge set point will be restricted to
the MaxChargingPower value. If the MaxChargingPower input is set
to 0, GridConnect will not restrict the set point for charging the storage
inverter. If the calculated charge value exceeds the charging capabilities
of the storage inverter and the charge output signal is restricted based
upon that input, the extra capacity that the inverter could have consumed
will not be redirected to other storage inverters. The charging algorithm
will use open-loop control. If the storage inverter does not charge
at the set point calculated by GridConnect, no adjustments will be
made. Each storage inverter will charge until it has reached its defined
MaxStateOfCharge on each storage inverter function block. Once a
storage inverter has reached this value, the charging power for that
storage inverter will be allocated to other storage inverters that have not
reached their MaxStateOfCharge. While this value is non-zero value,
all storage assets will be unavailable for participation in GridConnect
operations.
➤ AutomaticStorageCharging on the master plant controller is a Boolean
input that will tell GridConnect to manage charging storage assets.
When this Boolean is true, GridConnect will charge storage assets up
to the ReferenceSOC with the defined PVOutputChargeMargin, which
takes a percentage of current PV power output and charge storage
assets. Once the storage asset SOC reaches the ReferenceSOC, the
storage asset will be returned to GridConnect for control again. Storage
inverter charging will not occur until storage asset SOC is a certain
percentage below ReferenceSOC. This percentage is defined by the
setting ReferenceSOCRange. Once this condition occurs, GridConnect
will charge the storage asset to ReferenceSOC. If GridConnect encounters
a situation that requires downramp control, all storage inverters will stop
charging and then participate in downramp control. If GridConnect was
charging storage assets and then needs to suspend charging due to another
system condition, then charging storage assets will resume after SOC falls
below ReferenceSOCRange of ReferenceSOC again.

The master plant controller function block has an input pin called
StorageOperationMode. This input pin has several modes that define how
storage inverters will participate in power plant control. The following modes
are supported:

➤ Manual Storage Operation: Storage assets will not participate in


aggregate control via PCC power set points. Storage assets will receive
one power set point per storage inverter function block. The storage
asset will receive the set point configured on the input pin provided it
is within the bounds of SOC management and the storage asset has the
SOC level to provide the amount of power dictated by the set point. In
NoLimitPower and SimplePowerMode real power modes, the power the
storage asset produces will be in addition to the power set point on the
master plant controller. The total real power output of GridConnect at
the PCC will be master plant controller power set point plus each storage

Programming Reference Date Code 20241023


GridConnect 535
Operational Modes

inverter PstorageSetpoint. In advanced power mode, the PI controller


will adjust the PV inverter output so that the combination of the PV and
storage inverter outputs matches the master plant controller power set
point.
➤ Downramp Control: Storage assets will only be used to discharge
energy to the PCC in order to maintain the PCC real power ramp rate as
photovoltaic (PV) power output decreases.
➤ Storage Generation: Storage assets will be included to meet the PCC set
point. Each storage inverter will receive a proportional set point to meet
the PCC set point. SEL recommends using this mode when the system
only contains storage assets.

Grid Connected Operation Modes


When the controller is enabled, it sets the power limit reference signals to the
inverters based on the power limit mode.

GridConnect will identify the minimum number of generation groups required


to meet the set point. GridConnect then distributes the setpoints among those
groups via the following pseudo-logic. GridConnect will set each group to its
minimum set point defined as a percentage of the group's capability. Then,
starting with the lowest group number, GridConnect will use the maximum
capacity of each group until all set point requirements are met. Generation
groups that have assets marked as reserved are not used to meet PSetpoint
objectives.

FOR i = 1 to numberOfActiveGenerationGroups BY 1 DO
IF GroupSetpoint[i] < MinimumGroupSetpoint*GroupCapability[i] THEN
GroupSetpoint[i] = GroupSetpoint[i] + MinimumGroupSetpoint*GroupCapability[i]
remainingSetpoint = remainingSetpoint - (MinimumGroupSetpoint*GroupCapability[i])
END_IF
END_FOR

FOR i = 1 to numberOfActiveGenerationGroups BY 1 DO
setpointRoom = GroupCapability[i] - GroupSetpoint[i]
IF setpointRoom > remainingSetpoint THEN
GroupSetpoint[i] = GroupSetpoint[i] + remainingSetpoint
EXIT
ELSE
GroupSetpoint[i] = GroupCapability[i]
remainingSetpoint = remainingSetpoint - setpointRoom
END_IF
END_FOR

For any subsequent reserve power objectives, any qualifying generation group
based on asset type starting with the lowest group number will be used to meet
the reserve objectives. The following pseudo-logic demonstrates how additional
reserve power requirements are met.

FOR i = 1 to numberOfActiveGenerationGroups BY 1 DO
IF GroupAssetType == ReserveSetpointAssetType THEN
setpointRoom = GroupCapability[i] - GroupSetpoint[i]
IF setpointRoom > remainingSetpoint THEN
GroupSetpoint[i] = GroupSetpoint[i] + remainingSetpoint
EXIT
ELSE
GroupSetpoint[i] = GroupCapability[i]
remainingSetpoint = remainingSetpoint - setpointRoom
END_IF
END_IF

Date Code 20241023 Programming Reference


536 GridConnect
Operational Modes

END_FOR

Each generation asset type defines which reserve objectives they participate in.
Reserve power objectives include the following:

➤ Peak Shaving
➤ Time Shifted Generation
➤ Solar Smoothing
➤ Constant Power

NoLimit Power Limit Mode


The controller sets the power limit reference signal to 100 percent for all
inverters.

Simple Power Limit Mode


The power limit set point is calculated based on a percentage of the total power
rating of the inverters that are online and available to be controlled. While the
real power set point is in kW, the real power set point of each inverter will be
the same in terms of the rating of each inverter. For example, if there are 40
inverters at 500 kW rating each, the total power rating is 20 MW. If the power
limit set point is 15 MW, each inverter will be limited to 75 percent of 500 kW
or 375 MW. If some of the 40 inverters are not online, the total power rating will
be less. For example, if two inverters are offline, each of the remaining online
inverters should be limited to 79 percent of 500 kW or 395 kW.

In some cases, there may be inverters that are online and producing power but
are not available to be controlled. For example, the controller does not attempt to
control inverters that are in one of the following states:

➤ The inverter is in local mode and is excluded from operation.


➤ The inverter indicates that a fault is present.
➤ The inverter controller detects a communications failure alarm.
When one of these conditions is true, the controller assumes that the power
output of these inverters will remain constant and adjusts the power limit of
the remaining inverters to compensate. In the example below, if the two offline
inverters were actually online generating 250 kW each but not available to
be controlled, then the controller will calculate the power limit as shown in
Equation 17.5. Each inverter will then output this percentage multiplied by its
individual real power rating.

Equation 17.5

The simple power limit mode does not address any non-uniform cloud cover
issues or the presence of local load.

The following settings are used to manage Simple Power Mode:

➤ PSetpoint
➤ PLimitRampSetpoint

Programming Reference Date Code 20241023


GridConnect 537
Operational Modes

Advanced Power Limit Mode


The power output of an inverter is very sensitive to fluctuations in solar
radiation. A disturbance, such as a cloud, quickly reduces the power output of
some inverters while other inverters in the facility may have unused capacity.
Additionally, a storage inverter may be used to provide energy at the PCC in
these cases. The advanced power limit acts to aggregate the fast-changing power
output available at individual inverters to produce a steady power output at the
PCC. Additionally, the changes to the power limit reference are limited by the
specified power limit ramp rate of the inverter.

In advanced power limit mode, a PI controller manages the set points to the
inverters. If PlantP comes within ± PDeadband of PSetpoint, the PI controller
will stop generating new set points until PlantP is outside the Pdeadband of
PSetpoint.

This mode is modeled by the following time and frequency diagrams.

Figure 17.6 Advanced Power Mode Logic

The following settings are used to manage Advanced Power mode:

➤ PSetpoint
➤ PDeadband
➤ PKp
➤ PKi
➤ PLimitRampSetpoint
➤ PLimitDelay
➤ PowerClampMarginPercent

Date Code 20241023 Programming Reference


538 GridConnect
Operational Modes

Constant PCC Power Limit Mode


In this mode, GridConnect takes a PCC set point and will attempt to meet that
set point with PV inverter resources. If PV inverters are unable to meet the
configured set point, any available storage resources will be used to maintain
the configured set point. This mode will use closed-loop control to calculate
inverter set points. All functionality described in Advanced Power Limit Mode
will be used to calculate inverter set points. There are no differences in the PI
control algorithm between Constant PCC Power Limit Mode and Advanced
Power Limit mode. If there are other power system assets behind the PCC that
affect power that GridConnect does not control, PCC will still work to achieve
PSetpoint at the PCC with the assets it does manage.
GridConnect will start to supplement storage power when logic detects
that PlantP lags behind (PSetpoint – PDeadband) by input setting
ConstantPowerPickupTime. Storage assets will start discharging energy to
meet the set point at the PCC. Once storage power is used to supplement PV
power to hit the PSetpoint at the PCC metering point, it will continue to do
so until the PCC is able to achieve the PCC PSetpoint without storage asset
assistance for the time period defined by ConstantPowerDropOutTime or until
there is insufficient charge in the storage assets to maintain PSetpoint. If storage
asset assistance is no longer needed but not maintained for the duration of
ConstantPowerDropOutTime, storage asset assistance will begin without waiting
for the duration of ConstantPowerPickupTime. Once storage asset assistance
is no longer needed and the duration of ConstantPowerDropOutTime occurs,
the input condition to start storage asset assistance will need to wait for the time
defined by ConstantPowerPickupTime.
When GridConnect is in Constant PCC Power Limit mode, the
StorageOperationMode input will be ignored. The output pin
ConditionedStorageOperationMode will be set to ManagedByGridConnect,
indicating that PStorageSetPoint on the storage inverter will not be processed.
Additional power can be drawn from all storage assets proportionally using
the AdditionalStorageDischargeSetPoint pin on the master plant controller.
If StorageChargeSetpoint is used on the master plant controller to charge
storage assets, storage assets will not be available to discharge while charging is
occurring.
If the real power mode (PLimitMode) is changed to another value, any active
storage discharge for constant power mode will be set to zero. When real power
mode is changed back to Constant PCC Power limit mode, the duration of
ConstantPowerPickupTime will need to occur before power is discharged from
storage assets again.
The following logic diagram shows the constant power limit mode.

Figure 17.7 Constant PCC Power Logic

Programming Reference Date Code 20241023


GridConnect 539
Operational Modes

The following settings are used to manage the Constant PCC Power mode:
➤ PSetpoint
➤ PDeadband
➤ PKp
➤ PKi
➤ PLimitRampSetpoint
➤ PLimitDelay
➤ PowerClampMarginPercent
➤ AdditionalStorageDischargeSetPoint
➤ ConstantPowerPickupTime
➤ ConstantPowerDropOutTime

PCC Metering Power Limit Mode


In this mode, it is expected that there is load behind the same meter as the power
system assets that GridConnect manages. GridConnect will take two input
settings: MaxPExportSetpoint and MaxPImportSetpoint. These settings will
represent the maximum amount of energy GridConnect should allow to export
or import at the PCC. GridConnect will allow power at the PCC to fluctuate
between these two values. When power export reaches MaxPExportSetpoint,
GridConnect will reduce inverter set points so that PCC power is reduced to stay
under MaxPExportSetpoint. When power is imported at the PCC, GridConnect
will tell all PV inverters to produce as much power as possible. When imported
power is equal to MaxPImportSetpoint, GridConnect will discharge energy
from available storage inverters to keep imported energy less than the defined
MaxPImportSetpoint. If storage assets are depleted, then PCC power import
may exceed MaxPImportSetpoint.
In this mode, power changes will be limited to the configured ramp rate. If
PLimitRampSetpoint is set to 0, then there will be no limitations on power
output rate increase. If the ramp rate is non-zero, GridConnect will allow PV
inverters to generate power up to MaxPExportSetpoint while creating smooth
transitions between power set points. GridConnect will limit output changes by
the configured ramp rate. From 0 power output, GridConnect will set inverters
to a percentage of rated capacity, defined by the input InitialSmoothingSetpoint.
Once collective inverter power output reaches this level, GridConnect will
increase the inverter set point by the defined ramp rate. Each time the PV
output reaches the target set point within the defined deadband, GridConnect
will again increase the power output by the defined ramp rate. This creates a
smooth linear increase in power output. When power output decreases by an
amount larger than SolarSmoothingRampRate, GridConnect will use storage
assets to decrease PlantP by SolarSmoothingRampRate at the rate defined
by SolarSmoothingRampTime. For example, if at t0, PV output is 500 kW,
SolarSmoothingRampRate is 25 and SolarSmoothingRampTime is one minute.
At t1, PV output drops to 400 kW, then PlantP will decrease at a linear rate from
500 kW to 400 kW over a period of four minutes. Note in this mode only PV
power output is smoothed. PCC power readings may not always fall within
configured ramp rates if there is load or other factors that impact the readings.
When PV power is increasing, an additional charging mode for storage assets
is available. If SmoothingStrategy is set to UpRampCharging, when the rate of
PV increases faster than the rate defined by settings SolarChargingRampRate
and SolarChargingRampTime, GridConnect will start a ramp defined by these

Date Code 20241023 Programming Reference


540 GridConnect
Operational Modes

settings. The difference between the ramp value and actual PV production
will be dedicated to charging the storage asset. Once the ramp value reaches
current PV production, charging the storage asset will stop and other charging
algorithms can continue to charge the storage assets. For example, if PV output
at t0 is 300 kW, SolarChargingRampRate is 25 and SolarChargingRampTime is
two minutes. If the PV output at t1 goes to 400 kW, PlantP will see a ramp occur
from 300 kW to 400 kW, which takes eight minutes at 25 kW increments every
two minutes. During these eight minutes, the differential between the PlantP
ramp and current PV production will be dedicated to storage charging. At t2,
when PlantP is at 325 kW, 75 kW are dedicated to charging storage assets. At
t3, when PlantP is at 350 kW, 50 kW are dedicated to charging storage assets. If
there is load, other factors impacting the PCC power readings may not always
fall within configured ramp rates.

When GridConnect is in PCC Metering Power Limit mode,


StorageOperationMode input will be ignored. To discharge additional energy
from storage assets, use AdditionalStorageDischargeSetPoint on the master
plant controller. This will output energy from the storage asset in addition
to any current storage set point calculated by GridConnect. The output
pin ConditionedStorageOperationMode will be set to CoordinationMode,
indicating that PStorageSetPoint on the storage inverter will not be processed.
Additional power can be drawn from all storage assets proportionally using
the AdditionalStorageDischargeSetPoint pin on the master plant controller.
If StorageChargeSetpoint is used on the master plant controller to charge
storage assets, storage assets will not be available to discharge while charging is
occurring.

The following settings are used to manage PCC Metering Power mode:

➤ PLimitRampSetpoint
➤ StorageChargeSetpoint
➤ AdditionalStorageDischargeSetPoint
➤ InitialSmoothingSetpoint
➤ MaxPImportSetpoint
➤ MaxPExportSetpoint
➤ PDeadband
➤ SmoothingStrategy
➤ SolarSmoothingRampRate
➤ SolarSmoothingRampTime
➤ SolarChargingRampRate
➤ SolarChargingRampTime

Islanded Operation Mode


It is important to note that GridConnect is not a protection system. GridConnect
is designed to match generation to load requirements and distribute set points
among the managed assets depending upon user configuration. During islanded
operations, it is expected that system designers will use protective relays or
generation internal equipment to protect the system from faults, frequency
concerns, and voltage concerns. GridConnect does have a variety of conditions
that it monitors where it will shut down all generation, but these should be

Programming Reference Date Code 20241023


GridConnect 541
Operational Modes

treated as a last resort and not as primary protection for the system when
operating as an island. The itemized list that follows is common components
that GridConnect provides for an islanded system. SEL offers additional energy
management systems and microgrid controllers that are able to provide all
functionality discussed in the following list. For additional information, review
these systems offered through SEL Engineering Services at https://selinc.com/
engineering-services/microgrids/.

➤ Visualization
➢ HMI: Can be provided with web-based HMI on the same RTAC
running GridConnect. RTAC HMI requires a separate license from
GridConnect.
➢ SCADA: Standard functionality included on an RTAC running
GridConnect.
➢ SOE: Standard functionality included on an RTAC running
GridConnect.
➢ DataLogging: Recording of historical data can be done with
the Dynamic Disturbance Recorder feature, included with the
GridConnect license.
➢ Reporting: Can be provided with the same RTAC running
GridConnect. Email, Report formatting, and FTP synchronization
may require additional licenses.
➤ Protection: GridConnect does not provide this.
➤ Load Management
➢ Load Restoration: GridConnect does not provide this.
➢ Load Shedding: GridConnect does not provide this.
➤ Generation Management
➢ Voltage and Frequency Reference: GridConnect does not manage
voltage or frequency. This is the responsibility of the grid forming
asset.
➢ Managing operational modes of generation assets in accordance with
grid connected or islanded operation requirements: GridConnect
provides this.
➢ Managing generation balance: GridConnect provides this.
➢ Economic Dispatch: GridConnect does not provide this.
➤ Point of Common Coupling Management
➢ IEEE 1547 Compliance: Typically, a protective relay and inverters
will provide most compliance requirements. GridConnect can provide
some functionality of IEEE 1547 requirements in regard to:
➣ Islanding
➣ Interoperability, information models, and protocols
➢ Power Factor Management: GridConnect does not provide this.
➢ Seamless Disconnect: GridConnect does not provide this.
➢ Re-synchronization: GridConnect provides an initial command
to start this process, but typically a protective relay provides this
functionality.
➢ Anti-Islanding: GridConnect does not provide this.

Date Code 20241023 Programming Reference


542 GridConnect
Operational Modes

When it is time for an island to form, GridConnect will search through all assets
that have their input pin GridFormingAsset set to true and find the asset with
the highest PRating and fuel or charge level above the fb_MasterPlantController
input pin GridFormingMinFuel. If multiple assets have the same PRating, the
asset with the largest fuel or charge level will be selected. If multiple assets have
the same fuel or charge level, the first grid forming asset found will be selected.
PV assets will be placed into grid following mode and will be expected to take
real and reactive setpoints. It is not expected that any asset will operate in power
factor mode. All PV assets will be placed in a single generation group outside
the available user configured groups.

It is important to note that information update rates from generation assets for
real power, reactive power, voltage, and frequency need to be equivalent or
faster than the evaluation period. This ensures new relevant data each calculation
cycle for accurate re-distribution setpoints.

GridConnect expects the grid forming asset to provide the voltage and
frequency reference for the system. The grid forming asset should be running in
isochronous mode where it regulates P and Q to maintain a constant frequency
or voltage. Any disruptions or changes in load will be handled by the grid
forming asset assisted by any additional assets placed in droop mode. Droop
mode is where the asset is grid following and given a nominal operating point
but the asset automatically increases/decreases P or Q based upon frequency
or voltage deviations specified by the droop curve on the asset. GridConnect
does not manage the droop curve for the asset. It is the responsibility of the
system designer to implement the appropriate curve on droop assets to support
the grid forming asset during islanded operations. During the evaluation period,
GridConnect will review the utilization of the grid forming asset, any assets in
droop mode, any available PV, and then re-balance the utilization of all managed
generation to meet the configuration requirements. This re-distribution period
is likely to occur on a one- to five-second basis. The grid forming asset and
any assets in droop mode will absorb real-time changes in load requirements.
GridConnect will not provide power system cycle (sub-20 ms) control of
frequency or voltage. SEL offers the energy management system PowerMax
for these types of applications. GridConnect will sum each generator's output
to determine the power that should be redistributed via all generation assets. If
load metering is available, this will help provide more accurate load acceptance
criteria and can be integrated into historical logging.

When GridConnect detects the system needs to island, the following steps will
occur:

1. IslandOperationState: Disabled
When EnableIsland is TRUE and GridAvailable is FALSE and
these conditions exist for the time period, GridAvailableDelay
IslandOperationState will progress. Alternatively, if
AutomaticTransferSwitch is TRUE, then GridConnect will assume that
the PCC connection will be managed by the transfer switch and it will not
issue open commands.
2. IslandOperationState: SelectGridFormingAsset
A generation asset will be identified as the grid forming asset using the
following criteria:
➤ Generation asset POU pin GridForming is TRUE.
➤ Largest PRating of all assets with GridForming set to TRUE.

Programming Reference Date Code 20241023


GridConnect 543
Operational Modes

➤ If multiple assets are tied for largest PRating, the asset with the
greatest charge/fuel level is selected.
➤ Grid forming asset fuel/charge level is greater than
GridFormingMinFuel.
3. IslandOperationState: ReviewStartUpRequirements
GridConnect will review and sum the requirements from all loads that
have ConnectionStatus = TRUE. Generation capabilities to support an
island will also be reviewed before starting the island. These are the
requirements:
➤ A grid forming asset is configured and has sufficient charge or fuel.
➤ All configured loads have nominal power consumption greater than 0.
➤ Sufficient spinning reserves.
➤ Sufficient incremental reserve margin exists to support load PickUp.
If PickUp on the load function block is 0, the nominal value will be
used for PickUp requirements.
➤ At least one load function block is included. If multiple loads exist,
they can be represented as a single load block or independently
regardless of metering capability. If no load block exists, GridConnect
will not enable islanded operation.
If these requirements cannot be met, no changes to PCC connection or
assets will be made to support islanding operation. The system will be left
as is.
4. IslandOperationState: WaitForATS or StartIslandTransition
If all island checks pass, GridConnect will issue an open command to the
PCC connection if the PCC connection is still closed.
GridConnect will then wait until the following system conditions are
correct for islanded operation. If any conditions are not met, GridConnect
will not start generation assets.
AutomaticTransferSwitch is FALSE:
➤ PccConnectionClosed is FALSE
➤ PlantV is 0.
➤ EnableIsland is TRUE.
➤ GridAvailable is FALSE.
➤ InternalFault is FALSE.
AutomaticTransferSwitch is TRUE:
➤ PccConnectionClosed is FALSE.
➤ EnableIsland is TRUE.
➤ GridAvailable is FALSE.
➤ InternalFault is FALSE.
➤ Grid forming asset power output is greater than 0.
GridConnect brings online the grid forming asset.

Date Code 20241023 Programming Reference


544 GridConnect
Operational Modes

5. IslandOperationState: BringInitialGenerationOnline
If AutomaticTransferSwitch is TRUE, this stage is skipped; if FALSE,
the cold-load pickup capability on the grid forming asset will be used to
determine load acceptance for the specified pickup requirements on all
load with ConnectionStatus = TRUE. If the grid forming cold-load pickup
of the grid forming asset is capable of supporting all identified load, the
grid forming asset will be turned on to energize the system.
6. IslandOperationState: RedistributeSetpoints
GridConnect will continuously redistribute setpoints to assets based upon
the evaluation period and monitor the following criteria:
➤ Grid forming asset utilization and set-point distribution to all
generation assets based upon configuration. See Island Generation
Group Distribution on page 545 for additional details.
➤ GridConnect will monitor IslandVoltage between IslandVoltageHigh
and IslandVoltageLow. If either limit is exceeded, emergency island
shut down will occur.
➤ GridConnect will monitor IslandFrequency between
IslandFrequencyHigh and IslandFrequencyLow. If either limit is
exceeded, emergency island shut down will occur.
➤ GridConnect will monitor InternalFault. If at any time InternalFault
transitions to TRUE, emergency island shut down will occur.
➤ GridConnect will monitor EnableIsland. If at any time EnableIsland
transitions to FALSE, standard island shut down will occur.
➤ GridConnect will monitor GridAvailable for a rising edge. If a rising
edge is detected, standard island shut down will occur.
➤ GridConnect will monitor QuickStop for a rising edge. If a rising edge
is detected, emergency island shut down will occur.
The target PV value will be achieved by increasing or decreasing PV
setpoints by the PvIslandSlewRate. This is done by proportionally
dividing the PvIslandSlewRate among PV assets based upon their
PRating. PV assets will either then increase or decrease their individual
set point by the proportional split of PvIslandSlewRate until the target PV
value is achieved by combined output of all active PV inverters.
Standard Island Shut Down: During standard island shutdown,
GridConnect ensures all generation assets that have current output
greater than 0 are communicating. If any generation assets are not
communicating with GridConnect, the island will continue until
either operator intervention or all assets resume communications.
Communication status of loads is not considered. GridConnect will then
attempt to open any loads that are controllable and can load break. Then
all generation assets will be turned off by setting their real and reactive
power setpoints to 0. All generation assets will assert the output pin
IslandShutDown. All generation assets must report a feedback of 0 for
real and reactive power.
Emergency Island Shut Down: During emergency island shutdown,
which occurs when a problem is present, GridConnect immediately
opens all loads and sets all generation to 0 and will not consider the
communication status of any loads or generation. Once this state is
entered, the IslandReset input on the fb_MasterPlantController will need
to see a rising edge before any additional processing can occur.

Programming Reference Date Code 20241023


GridConnect 545
Operational Modes

7. IslandOperationState: IslandShutDownDeEnergized
Once the system is de-energized, all loads that have IsControllable =
TRUE will attempt to be closed back in. Once all loads report closed in or
unavailable, GridConnect will move to the next state.
Reciprocating generators will be turned off and disconnected from the
power system. Storage assets will transition back to grid following mode.
8. IslandOperationState: IslandShutDownClosePccConnection
The PCC connection will be told to close.
Once the following conditions are met, GridConnect will set all
generation assets back to grid following mode:
➤ PccConnectionClosed is TRUE.
➤ PlantV is greater than VLimitLow.
➤ PlantV is less than VLimitHigh.
9. IslandOperationState: ReturnToGridFollowing
Once assets set back to grid following mode, assets will be enabled and
follow the configured grid following operation modes. IslandState will be
set to disabled.
The IslandShutDown output pin on all generation assets will be set back
to FALSE.

Island Generation Group Distribution


During islanded operations, GridConnect will sum the output from all active
generation and then redistribute that amount of energy among active generation
assets according to the configuration. If generation assets are under- or
overutilized, changes to active generation assets will be made. Metering of
individual loads is not necessary for islanded operations.

The GridForming asset will attempt to operate as close to the setting percentage
MinIslandOperation defined on the function block for the grid forming asset as
possible provided PV assets are available. The following pseudo-code shows
how generation assets will be managed during islanded conditions.

MinGridFormingAssetContribution = (MinIslandOperation/100) * GridFormingAssetPRating

IF TotalPower < MinGridFormingAssetContribution THEN


remainingPower = 0
GridFormingAssetContribution = TotalPower
ELSE
remainingPower = TotalPower - MinGridFormingAssetContribution
END_IF

(* Identify the PV contribution *)


PVSetpoint = Determined by max PV penetration configuration
remainingPower = remainingPower - PVSetpoint

IF remainingPower > 0 THEN


GridFormingAssetContribution = GridFormingAssetContribution + remainingPower
END_IF

Date Code 20241023 Programming Reference


546 GridConnect
Operational Modes

Charging During Islanded Conditions


GridConnect will only charge the GridForming asset (provided the grid forming
asset is a storage asset) during islanded operations. Only PV will be used
to charge the grid forming storage asset. The automatic charging algorithm
will begin to attempt charging the storage asset once its SOC falls below
TargetIslandSOC.
To charge the GridForming asset, GridConnect will increase the PV set point
by the current utilization of the GridForming asset plus the MaxChargingPower
input pin on the fb_storageInverter function block. If the PV is unable to reach
this target amount, GridConnect will utilize the PV to its maximum capacity
in an attempt to charge the storage asset. GridConnect will not close in any
additional load while charging the grid forming asset. Charging completes when
TargetIslandSOC is achieved or StartIslandCharging is set to –1. It is important
to note that when charging completes, the PV will decrease its set point by the
PvIslandSlewRate.
If the PV is unable to generate enough power to charge the storage asset, it will
continue to produce power in excess of the maximum PV set point determined
by the PvPenetrationMode input until sufficient power is available to charge the
grid forming asset or until charging is turned off.
If communication to the grid forming device is lost while charging, charging
will be turned off and the PV will be returned to maximum value defined by
PvPenetrationMode.
Charging Algorithm Settings:
➤ TargetIslandSOC
➤ StartIslandCharging
➤ IslandChargingSettleTime
➤ PvIslandSlewRate
➤ MaxChargingPower

Considerations of PV Penetration in Islanded Mode


PV utilization during islanded operations offers both advantages and
disadvantages. Because PV power is provided by irradiance, it does not reduce
the fuel or charge of storage or generator assets. This aspect increases the
amount of time that other assets are able to stay online by decreasing their
utilization and reducing consumption of fuel or charge. However, the amount of
PV irradiance is not controllable. Placing too large of a percentage of islanded
operation on PV irradiance creates the risk that if the irradiance decreases
due to cloud cover or sunset, the other power system assets would not be able
to maintain the islanded power system. Because of these reasons, it may be
desirable to restrict the amount of PV that contributes to the generation mix
during islanded operations. Some grid forming or droop assets may not be able
to respond quickly enough to stabilize voltage or frequency if a sizeable amount
of PV suddenly decreases, or additional generation assets may not be able to
come online quickly enough to replace the energy provided by the PV to prevent
blackout. If PV drops such that other power system assets are unable to stabilize
the power system, GridConnect will attempt to bring additional assets online
but will not take any additional load management actions to prevent blackout.
If you are interested in load-shedding energy management systems, review
the information at SEL Engineering Services available via https://selinc.com/

Programming Reference Date Code 20241023


GridConnect 547
Operational Modes

engineering-services/microgrids/, which offers load- and generation-shedding


functionality for power grid stabilization. To ensure the best conditions during
islanded operations, consider the following when configuring PV penetration
settings:
➤ The type of grid forming and droop assets. Storage assets may react
to large swings of power faster than a generator depending upon asset
capabilities.
➤ The acceptable level of risk of PV exceeding incremental or spinning
reserve margins.
➤ Additional mitigation/protection systems in place outside of GridConnect
control.
To account for a wide range of system conditions and implementations, the
islanding algorithm provides multiple methods for determining the maximum
amount of PV contributed to the islanded system. The following are a few
recommendations on when each mode may be used:
➤ LimitByIRM is the most resiliency focused strategy, but depending
upon the generation mix capability, it is likely to only allow a smaller
percentage of PV capability.
➤ LimitByKW offers the most flexibility to the user to manage PV
contribution through changing system conditions. It also comes with
significant user responsibility to ensure system stability.

LimitByIRM
LimitByIRM limits PV by the incremental reserve margin capability of the grid
forming asset. In this mode, the PV will be limited to what the active non-PV
generating assets can instantaneously pick up. This will be determined by the
incremental reserve margin minus the minimum operating point if PRating –
minimum operating point < incremental reserve margin. Otherwise, if Prating
– minimum operating point > incremental reserve margin, the maximum PV
set point will be the incremental reserve margin. For example, if a system only
contains a grid forming reciprocating generator with an IRM of 250 kW, a
PRating of 250 kW, and a minimum operating point of 100 kW, then regardless
of the PV capacity, the maximum amount of PV that could be contributed to
the system would be 150 kW. In this mode, PV does not increase the total
generation capacity of the island. The PV contributes to the reduction of
utilization of generating assets that use fuel or charge to provide power.

LimitByKW
LimitByKW limits PV by a user-defined input, MaxIslandPV, on the
fb_MasterPlantController. This can be adjusted during run time. If dynamically
adjusted during run time, the user is responsible for power system stability
while changing this value. The LimitByKW cannot exceed PRating of the grid
forming asset.

Considerations for GridAvailable Input


GridConnect will make operational decisions to transition in or out of islanded
operations based upon GridAvailable on the fb_MasterPlantController (with
additional criteria). This input pin is driven by user input, and the conditions
that drive this value are designed by the system implementer and may fluctuate

Date Code 20241023 Programming Reference


548 GridConnect
Operational Modes

from system to system depending upon information available to the controller


and desired system operation. For example, the decision to transition in and out
of islanded operation may be driven by an operator interface. This input pin
may be tied to a SCADA control or HMI control tag that an operator turns on
or off when the system should operate as an island. Alternatively, this may be
driven by a voltage potential signal from the grid side of the PCC connection
indicating if the external grid is or is not available. It is the responsibility of
the configuration to define the criteria for when the system should transition in
or out of an island and the GridAvailable input to GridConnect is how that is
conveyed.

Considerations for System Design


When designing a system for islanded operation, there are many factors to take
into consideration. GridConnect operates on the philosophy that a single device
provides a single frequency and voltage reference for system stability and PV
reduces the fuel or charge consumption of the grid forming asset.

When an asset is selected for grid forming during an island, the asset is
configured to attempt to maintain a utilization percentage of its nameplate rating.
The designer of the system needs to take this value into consideration for system
stability. Because the grid forming asset maintains the frequency and voltage
reference for the island, configuring a utilization percentage that is too low could
cause overfrequency issues if load suddenly decreases where the grid forming
asset is not able to drop output sufficiently to account for the sudden loss of
load. This is more of a concern for a reciprocating engine rather than a storage
asset because the storage asset can transition from producing power to charging
and consume additional power during those islanded conditions. Additionally,
if the utilization percentage is too high, the grid forming asset may not have
enough incremental reserve margin to handle increases in load consumption.
The correct target utilization value will depend upon the characteristics of the
grid forming asset, the load composition, and the amount of PV in the system. It
is the implementer's responsibility to appropriately account for these factors.

If a load in the system is close to the total or available incremental reserve


margin of the grid forming asset, this can potentially represent stability issues.
It is not advisable to operate a system where the load swings or drop out is
approximate to the available incremental reserve margin. For example, consider
the following scenario:

➤ Reciprocating generator asset in isochronous mode with a nameplate of


500 kW operating at 200 kW.
➤ 3 PV inverters with a total nameplate rating of 250 kW operating at
combined output of 200 kW.
➤ 4 loads in the system with a total consumption of 400 kW:
➢ Load 1 consumption: 200 kW
➢ Load 2 consumption: 50 kW
➢ Load 3 consumption: 90 kW
➢ Load 4 consumption: 60 kW

A single load of 200 kW would pose significant risk to the system stability.
If the entire 200 kW load were to trip offline, there is risk of reverse power to
the generator, which would cause the generator to trip offline and the system
to black out. The system design should account for sufficient overhead on

Programming Reference Date Code 20241023


GridConnect 549
Operational Modes

the grid forming asset to absorb additional increases or decreases in load


demand. GridConnect will re-balance the load between generation assets on the
evaluation period transferring power between PV and the grid forming asset at
the PvIslandSlewRate. But the grid forming asset needs to be able to manage the
power system fluctuations between evaluation periods.
When using a storage asset as the grid forming asset and configuring charging
settings for the asset, keep in mind the asset's ability to increase or decrease
its power output to handle changes in load to address frequency concerns. If
a battery is charging at its maximum amount, it will not have any overhead to
consume additional power to lower the frequency if load suddenly decreases.
The charging algorithm only executes on the evaluation interval. It is expected
that the grid forming asset will handle fluctuations in between evaluation
periods. Depending upon system criteria, it may be advisable to delay
charging for a time period after the island starts. This can be done by setting
StartIslandCharging to –1 until the system is ready to consider charging.
If there are any concerns with system design or planning for islanded operation,
see the use of SEL Engineering Services https://selinc.com/engineering-services/
microgrids/ to help with these factors.

Settings for Island Operations


The following settings are all associated with island operating. Each will need
configuration or consideration.
➤ fb_MasterPlantController:
➢ GridAvailable
➢ EnableIsland
➢ PccConnectionClosed
➢ IslandSettleTime
➢ GridAvailableDelay
➢ AutomaticTransferSwitch
➢ GridFormingVarPercentage
➢ GridFormingMinFuel
➢ IslandBlackout
➢ IslandReset
➢ IslandPvDeadband
➢ MaxIslandPV
➢ PvPenetrationMode
➢ IslandFrequencyLow
➢ IslandFrequencyHigh
➢ IslandFrequency
➢ IslandVoltageDeviationTimeout
➢ IslandFrequencyDeviationTimeout
➢ GenTurnOnTimeout
➢ IslandVoltageLow
➢ IslandVoltageHigh
➢ IslandVoltage

Date Code 20241023 Programming Reference


550 GridConnect
Operational Modes

➢ InternalFault
➢ PvIslandSlewRate
➢ StartIslandCharging
➢ TargetIslandSOC
➢ MinimumGroupSetpoint
➤ fb_StorageInverter:
➢ OperationModeStatus
➢ GridFormingAsset
➢ MinIslandOperation
➤ fb_ReciprocatingGenerator:
➢ OperationModeStatus
➢ MinIslandOperation
➤ fb_Load:
➢ ConnectionStatus
➢ Disconnect
➢ IsControllable
➢ CanLoadBreak
➢ IsMetered
➢ UseMeteredData
➢ NominalPower
➢ ExpectedPickup
➢ Order

Frequency Regulation
The following settings determine how the controller performs frequency
regulation. It is able to do so using either the non-storage generation assets
(general PV plant output) or by using storage devices. Frequency regulation is
performed according to a curve defined by inputs on the Master Plant Controller.
These inputs can be adjusted at any time, which will change the curve being
used by the controller for frequency regulation. If these inputs are made
variable, it is important to ensure that they have correct and intended values at
all times, including at controller startup. These inputs are described in Table 17.2
and Figure 17.8.
Table 17.2 Frequency Regulation Parameters

Parameter Description

FRegulationF1 Frequency regulation frequency set point 1. Units are Hz. Default is 0.

FRegulationF2 Frequency regulation frequency set point 2. Units are Hz. Default is 0.

FRegulationF3 Frequency regulation frequency set point 3. Units are Hz. Default is 0.

FRegulationF4 Frequency regulation frequency set point 4. Units are Hz. Default is 0.

FRegulationP1 Frequency regulation real power set point 1. Units are % of


PlantPRating above or below PSetpoint. Default is 0.

FRegulationP2 Frequency regulation real power set point 2. Units are % of


PlantPRating above or below PSetpoint. Default is 0.

Programming Reference Date Code 20241023


GridConnect 551
Operational Modes

Parameter Description

FRegulationP3 Frequency regulation real power set point 3. Units are % of


PlantPRating above or below PSetpoint. Default is 0.

FRegulationP4 Frequency regulation real power set point 4. Units are % of


PlantPRating above or below PSetpoint. Default is 0.

Figure 17.8 Frequency Regulation Curve

Disabled
When Frequency Regulation is disabled, the controller does not perform any
adjustment of real power set points in response to frequency input.

Plant
In GridConnect versions prior to 3.5.7.4, when Frequency Regulation is in
Plant mode, the controller uses any available capacity in configured non-
storage generation devices to perform frequency regulation. The output
adjustment of these non-storage devices is changed at a rate according
to the EvaluationInterval setting on the controller in accordance with the
PLimitRampSetpoint setting. This mode uses the plant's non-storage generation
devices. If an increase in power output is desired in response to a frequency
event, some margin must be left (the plant needs to be run at less than maximum
capacity) proportional to the slope of the frequency regulation curve and the
expected severity of frequency events.
In GridConnect versions 3.5.7.4 and later, when Frequency Regulation is in
Plant mode, the controller uses any available capacity in non-reserve assets
to perform frequency regulation. The order of assets used follows the order
of generation groups and setpoint changes follow the PLimitRampSetpoint.
New setpoints for frequency regulation occur on the EvaluationPeriod setting
interval. When a frequency regulation event occurs (which is defined as any
time the plant output setpoint is modified according to the regulation curve), the
new target setpoint will be modified either from the current plant output when
the frequency regulation event occured (if setting FRegulationBaseSetpoint =

Date Code 20241023 Programming Reference


552 GridConnect
Enumerations

PlantP), or the current power setpoint (if setting FRegulationBaseSetpoint =


PSetpoint). For example, if the current plant output is 50 units, the site setpoint
is 70 units, and the expected frequency response is to decrease by 10 units, when
FRegulationBaseSetpoint = PlantP, the site's target setpoint would be 40 units.
When FRegulationBaseSetpoint = PSetpoint, the site's target setpoint would be
60 units. SEL recommends using FRegulationBaseSetpoint = PlantP.
On the frequency regulation curve, the amount by which to modify the plant's
response is defined in percentage units. This will be a percentage of the
FRegulationBaseModifier setting. By default, this setting is set to 0, and
when set to 0 internally will use the value of the input setting PlantPRating. If
FRegulationBaseModifier is a non-zero value, the change in plant response will
be a percentage of the user-defined FRegulationBaseModifier. For example, if
the frequency response is to decrease power by 20 percent and PlantPRating is
100 units, when FRegulationBaseModifier is 0, the site will decrease power by
20 units. When FRegulationBaseModifier is 50, the site will decrease power by
10 units. The curve and the settings to manage the frequency response can all be
configured to dynamically change during runtime.

HighSpeedStorage
When Frequency Regulation is in HighSpeedStorage mode, the controller uses
any available capacity in configured storage devices to perform frequency
regulation. The output of these storage devices is adjusted every RTAC task
cycle, which allows this feature to quickly react to changes in frequency using
stored energy. This mode does not apply any ramp rate control to the set point
delivered to storage devices.

Enumerations
Enumerations make code more readable by allowing a specific number to have
a text equivalent. Either the raw integer value can be assigned to a value that
requires an enumeration or the text of the enumeration itself can be assigned.
When viewing the values online, the enumeration text is displayed instead of the
integer value.

enum_ReactiveControlMode
This enumeration is used to set and indicate the desired reactive power control
mode of the Master Plant Controller.

Enumeration Value Description

PFControl 0 Power factor control mode

VARControl 1 VAR control mode

PFCompensation 2 Power factor compensation mode

VoltageCompensation 3 Voltage compensation mode

VoltageControl 4 Voltage control mode

OpenLoopPFControl 5 Open-loop power factor control mode

NoReactiveControl 6 No active control mode for the power plant


controller

Programming Reference Date Code 20241023


GridConnect 553
Enumerations

enum_ChargingSource
This enumeration is used to manage the source of power for charging storage
assets.

Enumeration Value Description

pvOnly 1 Only use PV to charge storage assets.

anySource 2 Use any asset available to charge storage assets, including


importing energy from PCC.

endOfEnum 3 End of Enumeration.

enum_PLimitMode
This enumeration is used to set and indicate the real power control mode of the
Master Plant Controller.

Enumeration Value Description

NoLimit 0 Maximum power limit set to 100 percent of inverter capacity.

Simple 1 Equally divide intertie power limit amongst all available


inverters (see Simple Power Limit Mode on page 536).

Advanced 2 Allows an individual inverter maximum power output to


adapt based on present power output. Allows use of storage
inverter to maintain ramp rate during cloud cover (see
Advanced Power Limit Mode on page 537).

PCCMetering 3 Allows for a range of energy to be imported or exported at


the PCC. Enable solar smoothing with this mode (see PCC
Metering Power Limit Mode on page 539).

ConstantPower 4 Uses both PV and storage inverters to meet configured set


point at the PCC. Uses closed-loop control to calculate
inverter set points (see Constant PCC Power Limit Mode on
page 538).

EndOfEnum 5 End of Enumeration.

enum_FrequencyRegulationMode
This enumeration is used to set and indicate the frequency regulation mode of
the Master Plant Controller.

Enumeration Value Description

Disabled 0 Frequency regulation is disabled.

Plant 1 Frequency regulation is performed by automatically


adjusting PSetpoint, which controls the output of
non-storage generation assets.

HighSpeedStorage 2 Frequency regulation is performed by automatically


adjusting StoragePSetpoint, which controls
configured storage assets.

Date Code 20241023 Programming Reference


554 GridConnect
Enumerations

enum_SolarSmoothingStrategy
This enumeration is used to manage solar smoothing strategies.

Enumeration Value Description

Disabled 0 Solar smoothing on increasing PV power is disabled.

UpRampCharging 1 The difference between PV production and the PCC


ramp rate for increasing PV setpoints will be used to
charge batteries.

EndOfEnum 2 End of Enumeration.

enum_StorageOperation
This enumeration manages and describes how storage assets are being utilized
by GridConnect.

Enumeration Value Description

ManualStorage 0 Storage assets will not be used in algorithmic control


decisions by GridConnect.

DownRamp 1 Storage assets will only be used to supplement PCC


ramp rate when PV output drops faster than the
configured PCC ramp rate.

StorageGeneration 2 Storage assets will be used to meet PSetpoint


objectives.

CoordinationMode 3 Storage assets operate in accordance with PCC


Metering mode functionality.

ManagedByGridConnect 4 Storage assets receive set points from GridConnect


power management algorithms.

EndOfEnum 5 End of Enumeration.

enum_AssetOperationMode
Generally speaking, generation assets can operate in three different modes. The
following descriptions explain the enumerated names that GridConnect uses.
Assets that GridConnect manages will support one or more of these operation
modes. The assets may use different name descriptions.

Enumeration Value Description

GridFollowing 0 The asset follows grid frequency and voltage and takes direct
real and reactive power setpoints.

GridForming 1 The asset provides the frequency and voltage reference. Runs
in an isochronous mode to maintain a constant frequency and
voltage.

Droop 2 The asset operates on a curve/slope for frequency/watt and


voltage/var. Takes a nominal operation point on the curve/
slope with P and Q setpoints. Asset should be grid following.

EndOfEnum 3 End of Enumeration.

Programming Reference Date Code 20241023


GridConnect 555
Function Blocks

enum_IslandOperationState
Enumeration Value Description

Disabled 0 Island operations are not active.

SelectGridFormingAsset 1 In process of selecting a grid forming asset for islanded operations.

ReviewStartUpRequirements 2 Ensuring included load is capable of being supported by grid forming asset.

WaitForATS 3 Transition period while waiting for automatic transition switch to disconnect
from the grid and connect the grid forming asset.

StartIslandTransition 4 Open the PCC connection. Prepare island to start.

BringInitialGenerationOnline 5 Turn on grid forming asset if not already on.

RedistibuteSetpoints 6 PV setpoints are set to meet grid forming utilization settings.

IslandShutDownGeneration 7 Island shutdown initiated. Shuts down all generation asset and opens all loads if
possible.

IslandShutDownDeEnergized 8 When system is de-energized, load will be closed back in.

IslandShutDownClosePccConnection 9 Transition stage back to grid connected mode.

ReturnToGridFollowing 10 Set all assets back to grid following mode.

IslandEmergencyShutDown 50 Island shutdown procedure regardless of communication status of assets.

IslandErrorState 100 Island encountered an issue.

enum_PvPenetrationMode
The mode in which PV output will be restricted in islanded operations.

Enumeration Value Description

LimitByIRM 0 Limits PV by the incremental margin reserve of active


generators.

LimitByKW 1 Limits PV by the value on the input pin MaxIslandPV.

EndOfEnum 3 End of Enumeration.

enum_fileConfig
The mode in generated log files will be rotated automatically.

Enumeration Value Description

RotateFileAtMidnight 0 Rotate generated files each day at midnight.

RotateFileAtFilesize 1 Rotate generated files when file size exceeds a limit


specified as an input to fb_MasterPlantController.

Function Blocks
The library contains the function blocks required to build a GridConnect control
system.

Date Code 20241023 Programming Reference


556 GridConnect
Function Blocks

fb_MasterPlantController (Function Block)


The Master Plant Controller function block provides the control algorithms and
I/O interface for controlling the PCC between the utility and a managed power
system.

Inputs
Name IEC 61131 Type Description

ControlMode enum_ReactiveControlMode PCC control mode. Default is OpenLoopPFControl.


For more information, see Enumerations on
page 552.

StorageOperationMode enum_StorageOperation Operation mode storage inverters will operate in.


Default is ManualStorage. For more information see
Enumerations on page 552.

FrequencyRegulationMode enum_FrequencyRegulationMode Frequency Regulation mode. Default is Disabled. For


more information see Enumerations on page 552.

Enable BOOL PCC control enable. Default is FALSE.

QuickStop BOOL Stop signal. Sets power and Q output set points to
zero, disregarding ramp rates on all inverters. Disables
master controller. This signal will go through to
connected inverters even if the master controller is
already disabled.

PlantP REAL PCC real power measurement. Units are kW. Default
is 0. (Positive values = flow from plant to grid)

PlantQ REAL PCC reactive power measurement. Units are kVAR.


Default is 0. (Positive values = flow from plant to
grid)

PlantPF REAL PCC power factor measurement. Default is 1. Units


are PF. (Positive values = lagging, negative values =
leading)

PlantV REAL PCC voltage measurement. Units are kV. Default is 1.

PlantF REAL PCC frequency. Units are Hz. Default is 60.

PccConnectionClosed BOOL The point of common coupling connection status.


If TRUE, connection is closed and connected to
external power systems. If FALSE, connection is open.
Defaults to TRUE.

PlantMeasurementsGood BOOL PCC measurement quality indication. Default is


FALSE.

QSetpoint REAL PCC reactive power control set point. Units are kVAR.
Default is 0.

QDeadband REAL PCC reactive power control deadband. Units are


kVAR. Default is 250.

QKp REAL Proportional tuning parameter for VAR control.


Default is 1.

QKi REAL Integral tuning parameter for VAR control. Default is


0.

QLimitHigh REAL Reactive power high limit.

QLimitLow REAL Reactive power low limit.

Programming Reference Date Code 20241023


GridConnect 557
Function Blocks

Name IEC 61131 Type Description

EnableVarForAllGroups BOOL If TRUE, assets will be used to meet reactive power


objectives regardless of the state of real power. If
FALSE, assets will be used to meet reactive power
objectives only when real power is being discharged
from the asset. Defaults to FALSE.

PFSetpoint REAL PCC power factor control set point. Units are PF.
Default is 1. (Positive values = lagging, negative
values = leading)

PFDeadband REAL PCC power factor control deadband. Units are PF.
Default is 0.0002.

PFKp REAL Proportional tuning parameter for power factor


control. Default is 1.

PFKi REAL Integral tuning parameter for power factor control.


Default is 0.

EnforcePccPFLimitsForAllModes BOOL If TRUE, PF Lead and Lag limits will be enforced


at the PCC for all reactive power modes based upon
PlantP. If FALSE, lead and lag limits will be enforced
for power factor control mode only. Defaults to TRUE.

PFLagLimit REAL PCC lagging power factor limit (positive). Units are
PF. Default is 0.95.

PFLeadLimit REAL PCC leading power factor limit (negative). Units are
PF. Default is –0.95.

PFCompensationSetpoint REAL Power factor compensation nominal set point. Units


are PF. Default is 0.

PFCompensationLowPowerCutoff REAL Power factor compensation low-power cutoff. Units


are in % (value should be between 0 and 100). Default
is 0.

PFCompensationGradient REAL Power factor compensation gradient. Units are in PF/


kW. Default is 0.

PFCompensationLowPFLimit REAL Power factor compensation low power factor limit.


Units are PF. Default is 0.

VCompensationV1 REAL Voltage compensation voltage set point 1. Units are


kV. Default is 0.

VCompensationV2 REAL Voltage compensation voltage set point 2. Units are


kV. Default is 0.

VCompensationV3 REAL Voltage compensation voltage set point 3. Units are


kV. Default is 0.

VCompensationV4 REAL Voltage compensation voltage set point 4. Units are


kV. Default is 0.

VCompensationQ1 REAL Voltage compensation reactive power set point 1.


Units are kVAR. Default is 0.

VCompensationQ2 REAL Voltage compensation reactive power set point 2.


Units are kVAR. Default is 0.

VCompensationQ3 REAL Voltage compensation reactive power set point 3.


Units are kVAR. Default is 0.

VCompensationQ4 REAL Voltage compensation reactive power set point 4.


Units are kVAR. Default is 0.

Date Code 20241023 Programming Reference


558 GridConnect
Function Blocks

Name IEC 61131 Type Description

VSetpoint REAL PCC voltage control set point. Units are kV. Default is
1.

VDeadband REAL PCC voltage control deadband. Units are kV. Default
is 0.02.

OptionalLowerVDeadband REAL An optional lower deadband for voltage control.


If greater than 0, this will be applied as the lower
deadband for voltage control. Default is 0.

VKp REAL Proportional tuning parameter for voltage control.


Default is 1.

VKi REAL Integral tuning parameter for voltage control. Default


is 0.

VLimitHigh REAL PCC high voltage limit. Units are kV. Default is 1.05.

VLimitLow REAL PCC low voltage limit. Units are kV. Default is 0.95.

dV_dQ REAL PCC ratio of the expected change in voltage to a


change in reactive power. Units are Volts/VAR.
Default is 0.01.

FRegulationF1 REAL Frequency regulation frequency set point 1. Units are


Hz. Default is 0.

FRegulationF2 REAL Frequency regulation frequency set point 2. Units are


Hz. Default is 0.

FRegulationF3 REAL Frequency regulation frequency set point 3. Units are


Hz. Default is 0.

FRegulationF4 REAL Frequency regulation frequency set point 4. Units are


Hz. Default is 0.

FRegulationP1 REAL Frequency regulation real power set point 1. Units are
% of PlantPRating above or below PSetpoint (from 0
to 100). Default is 0.

FRegulationP2 REAL Frequency regulation real power set point 2. Units are
% of PlantPRating above or below PSetpoint (from 0
to 100). Default is 0.

FRegulationP3 REAL Frequency regulation real power set point 3. Units are
% of PlantPRating above or below PSetpoint (from 0
to 100). Default is 0.

FRegulationP4 REAL Frequency regulation real power set point 4. Units are
% of PlantPRating above or below PSetpoint (from 0
to 100). Default is 0.

PLimitMode enum_PLimitMode Power limit mode. Default is NoLimit. For more


information, see Enumerations on page 552.

PSetpoint REAL PCC power limit set point. Units are kW. Default is
50000.

PDeadband REAL PCC power limit deadband. Units are kW. Default is
500.

PKp REAL Proportional tuning parameter for power control.


Default is 1.

PKi REAL Integral tuning parameter for power control. Default is


0.

Programming Reference Date Code 20241023


GridConnect 559
Function Blocks

Name IEC 61131 Type Description

PFRampSetpoint REAL Plant power factor ramp rate (power factor change/
second). Units are PF/second. Default is 0.02. Setting
to 0 will result in no ramp supervision.

QRampSetpoint REAL Plant reactive power ramp rate (reactive power


change/second). Units are kVAR/second. Default is 10.
Setting to 0 will result in no ramp supervision.

PLimitRampSetpoint REAL Plant power limit ramp rate (real power change/
second). Units are kW/second. Default is 10. Setting to
0 will result in no ramp supervision.

PLimitDelay TIME Time between the last valid inverter response and
application of the adaptive power limit. Units are
seconds. Default is 120.

StorageChargeSetpoint REAL The amount of power used to charge storage assets.


Each storage asset will receive a proportional charge
set point based upon the power rating of the storage
asset. Units are kW. Default is 0.

AdditionalStorageDischargeSetPoint REAL Set point for storage inverters to output in addition


to current PV output. If PLimitMode is simple or
advanced, this set point will not contribute to meeting
PSetpoint. Plant output should match PSetpoint +
AdditionalStorageDischageSetPoint. Units are kW.
Default is 0.

AutomaticStorageCharging BOOL Enables automatic charging of storage assets without


specified user inputs. See storage inverter charging for
additional details. Default is false.

AutomaticChargingSource enum_chargingSource Select a source to use for automatic charging. Defaults


to PV only.

ReferenceChargeSOC REAL This is a target value to keep storage assets SOC at by


the automatic storage charging algorithm. Units are in
percent between 1 and 100. Default is 90.

ReferenceSOCRange REAL This is a percentage of the setting ReferenceCharge-


SOC that will determine once SOC drops by this
amount below ReferenceChargeSOC that Automatic-
StorageCharging will begin charging storage assets.
Units are a percentage between 1 and 100. Default is
10.

PVOutputChargeMargin REAL The percentage of current PV output that


will be utilized to charge storage assets when
AutomaticStorageCharging is true. Units are a
percentage between 1 and 100. Default is 5.

AutomaticChargeDelayTime TIME The amount of time to pass before the automatic


charging algorithm to start after storage assets stop
discharging. Default is set to T#5m.

InitialSmoothingSetpoint REAL The percentage of PV capacity that will be the set


point for PV output in smoothing modes when
collective PV output is less than this set point. Units
are a percentage between 1 and 100. Default is 10.

MaxPImportSetpoint REAL The maximum amount of real power that GridConnect


will import at the PCC before using storage assets to
reduce importing real power at the PCC. Units are kW.
Default is 1000.

Date Code 20241023 Programming Reference


560 GridConnect
Function Blocks

Name IEC 61131 Type Description

MaxPExportSetpoint REAL The maximum amount of real power that GridConnect


will export at the PCC before reducing inverter set
points to reduce exported power at the PCC. Units are
kW. Default is 1000.

PlantPRating REAL PCC power output rating. Units are kW. Default is
50000.

PlantQRating REAL PCC reactive power rating. Units are kVAR. Default is
50000.

PlantLowPowerCutoff REAL Power output below which no power factor control


will occur. Units are kW. Default is 25.

EvaluationPeriod TIME Time between closed-loop control algorithm


execution. Default is T#5S.

ControlRetryPeriod TIME Time between control retries to field devices. Default


is T#20S.

CapacitorOperationPeriod TIME Minimum time between capacitor operations. Default


is T#5M.

CapacitorOperatePercent REAL A capacitor will close/open when total inverter


Q is greater/less than capacitor Q rating *
CapacitorOperatePercent. Default is 75.

CapacitorPickUpTime TIME The amount of time to wait before closing a capacitor


in when the requirement for VARs is met. Default is
T#60s.

CapacitorDropOutTime TIME The amount of time to wait before opening a capacitor


when the requirement for VARs is met. Default is
T#60s.

ResetPIControllersForSetpointChanges BOOL If TRUE, when a set-point change occurs, the PI


controller resets to current plant output. If FALSE,
when a set point changes, the PI controller will remain
at its current output and the system will drive to a
new set point. When FALSE, the PI controller may
need to work through any accumulated errors from the
previous set-point objective.

ResetPIControllers BOOL A rising edge will reset all closed-loop controllers.


Outputs of the controllers will be set to the
proportional value of all summed power from
managed assets.

ConstantPowerPickupTime TIME The time to wait for storage assets to assist in


achieving the PSetpoint at the PCC. Default is T#1m.

ConstantPowerDropOutTime TIME The time to wait to stop using storage assets to assist
with achieving the PSetpoint at the PCC. Default is
T#5m.

SolarSmoothingRampRate REAL The rate at which storage assets will ramp down from
previous PV output. Units are in kW. Default is 25.

SolarSmoothingRampTime REAL Time rate at which storage assets will discharge each
ramp rate interval. Units are in seconds. Default is 1.

SolarChargingRampRate REAL The rate at which the PCC will increase ramp and
dedicate excess PV energy to charging. Units are in
kW. Default is 25.

SolarChargingRampTime REAL Time rate at which SolarChargingRampRate will


operate. Units are in seconds. Default is 1.

Programming Reference Date Code 20241023


GridConnect 561
Function Blocks

Name IEC 61131 Type Description

SmoothingStrategy enum_solarSmoothingStrategy Select a solar smoothing strategy to manage ramp rates


and charging. Defaults to disabled.

PowerClampMarginPercent REAL The percentage of the inverter set point to initiate


power clamping in advanced mode when an inverter's
response does not meet the set point. Default is 15.

InverterModeChangeControlDelay TIME Time to delay sending set points after an inverter mode
change. Default is T#10S.

GenTurnOnTimeout TIME The time to wait for a generator to have Synchronized


asserted after GenOn asserts before marking the
generator as unavailable. Minimum value is T#1S.
Default is T#1M.

TargetIslandSOC DINT The target SOC level to charge the grid forming
storage asset to when in islanded operations. Units are
in percentage. Range is 1 to 100. Default is 90.

StartIslandCharging DINT The SOC level to begin charging when the


grid forming storage asset's SOC is below
StartIslandCharging when in islanded operations with
PV assets. If –1, GridConnect will not charge the grid
forming storage asset while in islanded mode. Units
are in percentage. Range is –1 to 100. Default is 60.

MinimumGroupSetpoint REAL The minimum group set point as a percentage of


each active generation group's capability. Units are in
percentage. Range is 1 to 100. Default is 10.

PVIslandSlewRate REAL The overall ramp rate to use when increasing or


decreasing PV set points in islanded operations. This
ramp rate is split proportionally between all active PV
inverters based upon each inverter's PRating. Units are
kW per second. Default is 25.

EnableIsland BOOL If TRUE, when islanding conditions exist,


GridConnect will attempt to form and operate an
island. If FALSE during islanded operation, all
generation assets will be turned off. Otherwise, will
prevent an island being formed when FALSE.

GridAvailable BOOL The indication that external grid power is available


and the site can be connected to the external grid. If
in islanded mode and this input transitions to TRUE,
GridConnect will return to grid connected operation
mode. Default is TRUE.

InternalFault BOOL An indication that a fault has occurred in the island


which cannot be isolated. If TRUE, all generation will
be shut down. An island cannot start when TRUE.
Default is FALSE.

IslandVoltage REAL The voltage that will be monitored during islanded


operations. PlantV will be ignored during islanded
operations. Units are in kV. Default is 0.

IslandVoltageHigh REAL The high limit of acceptable voltage during islanded


operations. If GridConnect detects IslandVoltage >
IslandVoltageHigh, all generation will be shut down.
When IslandVoltageHigh is 0, no monitoring for high
voltage will be performed. Units are kV. Default is 0.

Date Code 20241023 Programming Reference


562 GridConnect
Function Blocks

Name IEC 61131 Type Description

IslandVoltageLow REAL The low limit of acceptable voltage during islanded


operations. If GridConnect detects IslandVoltage <
IslandVoltagelow, all generation will be shut down.
When IslandVoltagelow is 0, no monitoring for low
voltage will be performed. Units are kV. Default is 0.

IslandFrequencyHigh REAL The high limit of acceptable frequency during islanded


operations. If GridConnect detects IslandFrequency
> IslandFrequencyHigh, all generation will be shut
down. When IslandFrequencyHigh is 0, no monitoring
for high frequency will be performed. Units are Hz.
Default is 0.

IslandFrequencyLow REAL The low limit of acceptable frequency during islanded


operations. If GridConnect detects IslandFrequency <
IslandFrequencylow, all generation will be shut down.
When IslandFrequencylow is 0, no monitoring for low
frequency will be performed. Units are Hz. Default is
0.

IslandFrequencyDeviationTimeout TIME The time to wait after a frequency excursion has


occurred during islanded operation before turning off
all generation. Default is T#0S.

IslandVoltageDeviationTimeout TIME The time to wait after a voltage excursion has occurred
during islanded operation before turning off all
generation. Default is T#0S.

IslandFrequency REAL The frequency that will be monitored during islanded


operations. PlantF will be ignored during islanded
operations.

GridAvailableDelay TIME The time to wait after GridAvailable transitions to


TRUE to shut down the island and start the transition
back to grid connected operation. Default is T#10S.

PvPenetrationMode enum_pvPenetrationMode The mode in which to restrict PV output during


islanded operations. Default is LimitByIRM.

MaxIslandPV REAL The maximum amount of PV can contribute during


islanded operations. Default is 0.

GridFormingVarPercentage REAL The percentage of VARs that are generated during


islanded operation that should remain on the grid
forming asset. Units are in percentage. Range is 1 to
100. Default is 80.

GridFormingMinFuel REAL The percentage of fuel or charge the grid forming


asset must have before the asset is selected as a grid
forming asset. Units are in percentage. Range is 1 to
100. Default is 10.

IslandBlackOut BOOL Power System protection detected an issue that


prevented the island from operating due to imbalance
between load and generation or other issues. If TRUE,
GridConnect will set all generation output to 0 and
wait for user to reset. An island will not start if
asserted.

IslandReset BOOL If island operations are in IslandErrorState, a rising


edge on IslandReset must occur before GridConnect
will attempt to start the island again.

Programming Reference Date Code 20241023


GridConnect 563
Function Blocks

Name IEC 61131 Type Description

AutomaticTransferSwitch BOOL If TRUE, when an island is formed, the transfer switch


will automatically disconnect from the grid and turn
on the grid forming asset. Island management will start
when the grid forming asset is producing power. No
island validation of load and generation capabilities
will occur before re-distributing set points. If FALSE,
island validation procedures will occur before starting
the island.

IslandSettleTime TIME The time to wait after IslandOperationMode =


RedistibuteSetpoints before starting to adjust PV set
points. Default is T#5M.

EnableDdrRecording BOOL If TRUE, set points and status indicators will be


logged to unique files dependent on grid connected or
islanded operation on each evaluation period.

NewFileTrigger enum_fileConfig The criteria for which log files will be rotated. Specify
whether files should be automatically rotated each day
at midnight or whether they should be rotated after
reaching a specific file size.

MaxFileSize UDINT(1,024..1,048,576) Maximum size (in bytes) allowed for a log file before
rolling to a new file. May not be lower than 1 KB
(1,024 bytes) or larger than 10 MB (10,485,760 bytes).

MaxFolderSize UDINT(100..102,400) Maximum size (in MB) allowed for within a log folder
before removing the oldest log files. May not be lower
than 100 MB or larger than 100 GB (102,400 MB).

Outputs
Name IEC 61131 Type Description

ConnectToPlantDevices POINTER Connect to all plant devices.

Enabled BOOL Master controller is enabled.

QuickStopAsserted BOOL QuickStop input pin is asserted.

PFControlMode BOOL Master controller is in power factor control mode.

QControlMode BOOL Master controller is in reactive power control


mode.

PFCompensationMode BOOL Master controller is in power factor compensation


mode.

VCompensationMode BOOL Master controller is in voltage compensation


mode.

VControlMode BOOL Master controller is in voltage control mode.

OpenLoopPFControlMode BOOL Master controller is in open-loop power factor


control mode.

NoLimitPControl BOOL Master controller is in NoLimit power control


mode.

SimplePControl BOOL Master controller is in Simple power control


mode.

AdvancedPControl BOOL Master controller is in Advanced power control


mode.

Date Code 20241023 Programming Reference


564 GridConnect
Function Blocks

Name IEC 61131 Type Description

PlantFRegulationEnabled BOOL Plant frequency regulation mode is enabled.

StorageFRegulationEnabled BOOL High-speed storage frequency regulation mode is


enabled.

PFOutOfBand BOOL Power factor at the PCC is outside the deadband.

QOutOfBand BOOL VAR flow at the PCC is outside the deadband.

VOutOfBand BOOL Voltage at the PCC is outside the deadband.

PFLagAlarm BOOL Power factor lagging beyond the limit at the PCC
(generating more kVAR).

PFLeadAlarm BOOL Power factor leading beyond the limit at the PCC
(consuming more kVAR).

VHighAlarm BOOL Voltage above the high limit at the PCC.

VLowAlarm BOOL Voltage below the low limit at the PCC.

ConditionedDVDQ REAL Conditioned DVDQ input. Conditioning checks to


make sure the input is greater than zero.

ConditionedPFCompensationLowPowerCutoff REAL Conditioned PF compensation cutoff.


Conditioning checks to make sure the input is
between 0 and 100.

ConditionedPFCompensationSetpoint REAL Conditioned PF compensation set point.


Conditioning checks to make sure input is within
PF lag and lead limits.

ConditionedPFSetpoint REAL Conditioned PF set point. Conditioning checks to


make sure input is within PF lag and lead limits.

ConditionedPLimitSetpoint REAL Conditioned power limit set point. Conditioning


checks to make sure input is between 0 and
PRating.

ConditionedQSetpoint REAL Conditioned reactive power limit set point.


Conditioning checks to make sure input is between
leading and lagging QRating.

ConditionedPFRampSetpoint REAL Conditioned power factor ramp rate set point.


Conditioning checks to make sure input is between
0 and 1.

ConditionedQRampSetpoint REAL Conditioned reactive power ramp rate set point.


Conditioning checks to make sure input is between
0 and ConditionedQRating.

ConditionedPLimitRampSetpoint REAL Conditioned real power ramp rate set point.


Conditioning checks to make sure input is between
0 and ConditionedPRating.

ConditionedVSetpoint REAL Conditioned voltage set point. Conditioning


checks to make sure input is between the
VLimitHigh and VLimitLow inputs.

ConditionedPRating REAL Conditioned real power rating. Conditioning


checks to make sure input is greater than 0.

ConditionedQRating REAL Conditioned reactive power rating. Conditioning


checks to make sure input is between lagging and
leading reactive power limits.

ConditionedStorageOperationMode enum_StorageOperation Mode in which storage assets are currently


operating.

Programming Reference Date Code 20241023


GridConnect 565
Function Blocks

Name IEC 61131 Type Description

ConditionedSmoothingStrategy enum_solarSmoothingStrategy Mode in which smoothing strategy is currently


operating.

ConditionedAutomaticChargingSource enum_chargingSource Mode in which automatic charging source is


active.

DownrampEventActive BOOL This output asserts when a downramp event


is active. This input will only assert if the
EnableStorageDownrampControl input is asserted.

FrequencyRegulationEventActive BOOL This output asserts if a real power set point is


being adjusted due to an ongoing frequency
regulation event.

StorageDownrampControlEnabled BOOL Storage downramp control is enabled.

ConstantPowerEventActive BOOL Power from storage assets will immediately


be discharged to meet power set point without
waiting for pickup time.

PControlLoopError REAL The error calculation from the last evaluation


period for the closed-loop control logic.

PControlLoopIntegral REAL The integral factor of error built up over time from
a set-point change.

QControlLoopError REAL The error calculation from the last evaluation


period for the closed-loop control logic.

QControlLoopIntegral REAL The integral factor of error built up over time from
a set-point change.

PFControlLoopError REAL The error calculation from the last evaluation


period for the closed-loop control logic.

PFControlLoopIntegral REAL The integral factor of error built up over time from
a set-point change.

CalculatedQAtPFLeadLimit REAL The maximum Q value that can be consumed or


generated at PF Lead Limit.

CalculatedQAtPFLagLimit REAL The maximum Q value that can be consumed or


generated at PF Lag Limit.

CalculatedQAtVHighLimit REAL The maximum Q value that can be consumed or


generated at Voltage High Limit.

CalculatedQAtVLowLimit REAL The maximum Q value that can be consumed or


generated at Voltage Low Limit.

PoiGenerativeQLimit REAL The maximum Q value that can be generated at


PCC based upon current system conditions.

PoiConsumptiveQLimit REAL The maximum Q value that can be absorbed at


PCC based upon current system conditions.

ExpectPccConnectionClosed BOOL The expected status of the PCC connection. If


TRUE, the PCC connection should be closed
and connected to external power systems. If
FALSE, the PCC connection should be open and
potentially operate GridConnect managed assets as
an island.

GenerationGroupSizes ARRAY[1..10] OF UDINT Displays the number of assets in each generation


group.

Date Code 20241023 Programming Reference


566 GridConnect
Function Blocks

Name IEC 61131 Type Description

PccConnectionOpen BOOL Command to open the PCC connection. Will assert


for one processing cycle on ControlRetryPeriod
until PccConnectionClosed = FALSE.

PccConnectionClose BOOL Command to close the PCC connection.


Will assert for one processing cycle on
ControlRetryPeriod until PccConnectionClosed =
TRUE.

OperationStatus enum_PlantOperationStatus Status of GridConnect management mode.


Defaults to GridConnectManagementOff.

IslandStatus STRING(255) Information about the current operational state of


the island.

IslandOperationState enum_IslandOperationState Current state of the island state machine.

ActiveFileName STRING(255) Name of the file that logs are being written to.

NumberLoadsIncluded UDINT The number of load function blocks included in


master plant control.

Inverter Processing Behavior


The PV and Storage inverter blocks have several expected operating conditions
before set points are calculated or updated on the input pins. This state is
reflected by the DeviceAvailableForControl output pin on each individual
inverter block. If this pin is FALSE, no real, reactive, or power factor set points
will be updated or calculated for that individual inverter block. The following
are expected conditions for DeviceAvailableForControl to be TRUE:

➤ InputAlarm output pin is FALSE.


➤ Offline input pin is FALSE.
➤ OnStatus input pin is TRUE.
➤ RemoteEnabled input pin is TRUE.
➤ Fault input pin is FALSE.
➤ Inverter must be in the same reactive power control mode as the plant
controller.
➤ IncludeCommand input pin is TRUE.
➤ ExcludeCommand input pin is FALSE.
➤ IncludedInMasterControl output pin is TRUE.
The InputAlarm indicates that one or more inverter inputs are in an invalid state.
Providing invalid inputs results in the inverter being excluded from control
commands. The InputAlarm output will assert if any of the following are true:

➤ PFModeEnabled and QModeEnabled are both TRUE.


➤ Inverter is not in correct reactive power mode after three times the master
controller's ControlRetryPeriod setting.
➤ OnCommandInput and OffCommandInput are both TRUE.
➤ IncludeCommand and ExcludeCommand are both TRUE.
➤ PFModeEnabled and QModeEnabled are both TRUE.
➤ InverterPF, PFSetpointFeedback, InverterPFLagLimit, or
InverterPFLeadLimit are less than –1 or greater than 1.

Programming Reference Date Code 20241023


GridConnect 567
Function Blocks

➤ PRating is less than 0.


➤ QRating is less than 0.

fb_PvInverter (Function Block)


The PV Inverter function block provides the control algorithms and I/O interface
for one photovoltaic inverter in a solar generating facility.

If GenerationGroupNumber is left to the default value of 65,278, then upon


startup, PvInverter function blocks will be set generation group 1. This will
make the behavior consistent with previous releases. The PvInverter asset class
does not participate in any reserve objectives.

Inputs
Name IEC 61131 Type Description

ConnectToMasterController POINTER Connect this input to a master controller instance.

Offline BOOL If TRUE, no communications are active to the device. If FALSE, communications
are working correctly. Default is FALSE.

RemoteEnabled BOOL If TRUE, asset will take remote operational commands. If FALSE, asset may be on
but does not accept remote operational commands. May be in maintenance or local
control mode. Default is FALSE.

Fault BOOL Asset control device is reporting a fault. Default is FALSE.

OnStatus BOOL On/off status of the asset. Default is FALSE.

OnCommandInput BOOL Command to turn on the asset control device. Default is FALSE.

OffCommandInput BOOL Command to turn off the asset control device. Default is FALSE.

Include BOOL Latch to include asset in the master control. Default is FALSE.

Exclude BOOL Latch to remove asset from the control. Default is FALSE.

PFModeEnabled BOOL Asset is in power factor control mode.

QModeEnabled BOOL Asset is in reactive power control mode.

AssetP REAL Real power output from asset. Units are kW.

AssetQ REAL Reactive power output from asset. Units are kVAR.

AssetPF REAL Power factor at asset (generative +, consumptive –). Units are PF.

AssetPFLagLimit REAL Asset lagging power factor limit (positive). Units are PF. Default is 0.8.

AssetPFLeadLimit REAL Asset leading power factor limit (negative). Units are PF. Default is –0.8.

PFSetpointFeedback REAL Power factor set-point feedback. Units are PF.

QSetpointFeedback REAL Reactive power set-point feedback. Units are kVAR.

PLimitSetpointFeedback REAL Power limit set-point feedback. Units are kW.

PFRampFeedback REAL Power factor ramp feedback. Units are PF/sec.

QRampFeedback REAL Reactive power ramp feedback. Units are kVAR/sec.

PLimitRampFeedback REAL Power limit ramp feedback. Units are kW/sec.

Date Code 20241023 Programming Reference


568 GridConnect
Function Blocks

Name IEC 61131 Type Description

ContinuityAdjustment REAL The percentage amount to adjust PV set points by, when returning to a proportional
set point after system conditions have caused set points to be non-proportional.
Units are in percentage. Range is 0–3. Default is 0.25.

PRating REAL Power rating for the asset. Units are kW. Default is 0.

QRating REAL Reactive power rating for the asset. Units are kVAR. Default is 0.

GridGroup UINT The generation group to include this asset in during grid connected operation
modes. Range is 1–10.

Reserve BOOL If TRUE, this asset will be treated as a part of the reserve group that will be used to
supplement PCC objectives when primary assets are unable to do so on their own.

AssetPError REAL The error percentage that exists in the asset's response to a real power set point.
This error value is used in power clamp logic when clamp is applied. This value
should be slightly more than the actual error from the asset. Units are percent.
Range is 0–100. Defaults to 3.

AssetQError REAL The error percentage that exists in the asset's response to a reactive power set point.
This error value is used in power clamp logic when clamp is applied. This value
should be slightly more than the actual error from the asset. Units are percent.
Range is 0–100. Defaults to 3.

MinimumPVSetpoint REAL When AssetP is less than the percentage of MinimumPVSetpoint of PRating the
PLimitSetmag will be set to the percentage of PRating. This accounts for conditions
with lower power production or when the inverter produces no power at all. Units
are percent. Range is 0–100. Default is 1.

Outputs
Name IEC 61131 Type Description

IncludedInMasterControl BOOL Asset is included in master control. Will assert when asset is on,
included, and not excluded.

OnCommand BOOL Pulse to turn on asset.

OffCommand BOOL Pulse to turn off asset.

QuickStop BOOL Asserts to send stop signal to asset. This output can assert when
required even if the master controller is not enabled.

PFModeCommand BOOL Command to put asset in power factor mode.

QModeCommand BOOL Command to put asset in reactive power mode.

PFSetMag REAL Power factor output. Units are PF.

PFTrigger BOOL Power factor trigger (1 = Write).

QSetMag REAL Reactive power output. Units are kVAR.

QTrigger BOOL Reactive power trigger (1 = Write).

PLimitSetMag REAL Power limit output. Units are kW.

PLimitTrigger BOOL Power limit trigger (1 = Write).

PFRampSetMag REAL Power factor ramp output. Units are PF/sec.

PFRampTrigger BOOL Power factor ramp trigger (1 = Write).

QRampSetMag REAL Reactive power ramp output. Units are kVAR/sec.

QRampTrigger REAL Reactive power trigger (1 = Write).

Programming Reference Date Code 20241023


GridConnect 569
Function Blocks

Name IEC 61131 Type Description

PLimitRampSetMag REAL Power limit ramp output. Units are kW/sec.

PLimitRampTrigger BOOL Power limit ramp trigger (1 = Write).

InputAlarm BOOL One or more asset inputs are in an invalid state.

OperationStatus enum_assetOperationStatus The current operational state of this asset.

ActiveGridGroup UDINT The active group number this asset is a part of for grid connected
operations. Default is 65,535.

CorrectReactiveControlMode BOOL If TRUE, this asset is in the correct reactive power control mode. PF
or VAR set points will update. If FALSE, PF or VAR set points will
not update.

PowerClampActive BOOL Power clamp logic is active for this asset.

ReactiveClampActive BOOL Reactive power clamp is active for this inverter

IslandShutDown BOOL If TRUE, the island shut down process is active. All set-point
outputs are set to 0 while this output is asserted.

ReserveGroup BOOL If TRUE, this asset was successfully added to an active generation
group that only contains reserve assets.

DeviceAvailableForControl BOOL If TRUE, device is included in GridConnect Control Algorithms and


is executing set points.

MinimumPVSetpointActive BOOL Boolean indication that PLimitSetMag is set to the


MinimumPVSetpoint of PRating due to low power production.

fb_StorageInverter (Function Block)


The Storage Inverter function block provides the control algorithms and I/O
interface for one storage inverter in a solar generating facility.
If GenerationGroupNumber is left to the default value of 65,278, then upon
startup, StorageInverter function blocks will be set generation group 2 and
Reserve set to True. This will make the behavior consistent with previous
releases. The StorageInverter asset participates in the following reserve
objectives:
➤ Solar Smoothing
➤ Constant Power
➤ Peak Shaving

Inputs
Name IEC 61131 Type Description

ConnectToMasterController POINTER Connect this input to a master controller instance.

Offline BOOL If TRUE, no communications are active to the device. If FALSE,


communications are working correctly. Default is FALSE.

RemoteEnabled BOOL If TRUE, asset will take remote operational commands. If FALSE, asset
may be on but does not accept remote operational commands. May be in
maintenance or local control mode. Default is FALSE.

Fault BOOL Asset control device is reporting a fault. Default is FALSE.

OnStatus BOOL On/off status of the asset. Default is FALSE.

Date Code 20241023 Programming Reference


570 GridConnect
Function Blocks

Name IEC 61131 Type Description

OnCommandInput BOOL Command to turn on the asset control device. Default is FALSE.

OffCommandInput BOOL Command to turn off the asset control device. Default is FALSE.

IncludeCommand BOOL Command to include asset in the master control. Default is FALSE.

ExcludeCommand BOOL Command to remove asset from the control. Default is FALSE.

PFModeEnabled BOOL Asset is in power factor control mode.

QModeEnabled BOOL Asset is in reactive power control mode.

AssetP REAL Real power output from asset. Units are kW.

AssetQ REAL Reactive power output from asset. Units are kVAR.

AssetPF REAL Power factor at asset (generative +, consumptive –). Units are PF.

AssetPFLagLimit REAL Asset lagging power factor limit (positive). Units are PF. Default is 0.8.

AssetPFLeadLimit REAL Asset leading power factor limit (negative). Units are PF. Default is –0.8.

PFSetpointFeedback REAL Power factor set-point feedback. Units are PF.

QSetpointFeedback REAL Reactive power set-point feedback. Units are kVAR.

PSetpointFeedback REAL Real power set-point feedback. 0 to +PRating indicate battery charging
(consume kW) and 0 to –PRating indicate battery discharge (output kW).
Units are kW.

PFRampFeedback REAL Power factor ramp feedback. Units are PF/sec.

PRampFeedback REAL Real power ramp feedback. Units are kW/sec.

QRampFeedback REAL Reactive power ramp feedback. Units are kVAR/sec.

PRating REAL Power rating for the asset. Units are kW. Default is 0.

QRating REAL Reactive power rating for the asset. Units are kVAR. Default is 0.

Reserve BOOL If TRUE, this asset will be treated as a part of the reserve group that will be
used to supplement PCC objectives when primary assets are unable to do so
on their own.

StoragePSetpoint REAL Storage real power set point. The storage asset will only take this set point
when StorageOperationMode is either ManualStorage or DownRamp. Units
are kW. Default is 0.

MinStateOfCharge REAL A percentage value that the storage asset should not discharge the storage
asset below. A value of 0 will not restrict discharging from the storage asset in
any manner. Default is 40.

MaxChargingPower REAL The maximum amount of power that the storage asset is able to accept for
charging. Units are in kW. Default is 250.

RampChargingValues BOOL When TRUE, uses a ramp when reaching the target charging value; when
FALSE, no ramp is used for charging set points. Default is FALSE.

StateOfCharge REAL A percentage value representing the present state of charge of the storage
asset. Default is 0.

MaxStateOfCharge REAL A percentage value representing the maximum state of charge the storage
asset should be charged to. Default is 95.

GridFormingAsset BOOL If TRUE, this asset will be considered to be the single grid forming asset
during islanded operation.

Programming Reference Date Code 20241023


GridConnect 571
Function Blocks

Name IEC 61131 Type Description

MinIslandOperation REAL A percentage value of PRating that is the minimum utilization this asset
should have as the grid forming asset during islanded operations. Units are in
percent. Range is 1–100. Default is 20.

IslandMinStateOfCharge REAL A percentage value that the storage asset should not discharge the storage
asset below when operating in islanded conditions. A value of 0 will not
restrict discharging from the storage asset in any manner. Default is 5.

IncrementalReserveMargin REAL The percentage of PRating the asset is able to pick up without a significant
deviation in output frequency. Used for load acceptance criteria during
islanded conditions. Units are in percent. Range is 1–100. Default is 100.

ColdLoadPickUp REAL The percentage of PRating the asset is able to pick up without a significant
deviation in output frequency when current asset output is 0. Used for load
acceptance criteria during islanded conditions. Units are in percent. Range is
1–100. Default is 100.

OperationModeFeedback enum_operationMode The feedback operation mode of the asset. Default is GridFollowing.

AssetPError REAL The error percentage that exists in the asset's response to a real power set
point. This error value is used in power clamp logic when clamp is applied.
This value should be slightly more than the actual error from the asset. Units
are percent. Range is 0–100. Defaults to 3.

AssetQError REAL The error percentage that exists in the asset's response to a reactive power set
point. This error value is used in power clamp logic when clamp is applied.
This value should be slightly more than the actual error from the asset. Units
are percent. Range is 0–100. Defaults to 3.

Outputs
Name IEC 61131 Type Description

IncludedInMasterControl BOOL Asset is included in master control. Will assert when asset is on, included,
and not excluded.

OnCommand BOOL Pulse to turn on asset.

OffCommand BOOL Pulse to turn off asset.

QuickStop BOOL Asserts to send stop signal to asset. This output can assert when required
even if the master controller is not enabled.

PFModeCommand BOOL Command to put asset in power factor mode.

QModeCommand BOOL Command to put asset in reactive power mode.

PFSetMag REAL Power factor output. Units are PF.

PFTrigger BOOL Power factor trigger (1 = Write).

QSetMag REAL Reactive power output. Units are kVAR.

QTrigger BOOL Reactive power trigger (1 = Write).

PLimitSetMag REAL Power limit output. Units are kW.

PLimitTrigger BOOL Power limit trigger (1 = Write).

PFRampSetMag REAL Power factor ramp output. Units are PF/sec.

PFRampTrigger BOOL Power factor ramp trigger (1 = Write).

QRampSetMag REAL Reactive power ramp output. Units are kVAR/sec.

QRampTrigger REAL Reactive power trigger (1 = Write).

Date Code 20241023 Programming Reference


572 GridConnect
Function Blocks

Name IEC 61131 Type Description

PLimitRampSetMag REAL Power limit ramp output. Units are kW/sec.

PLimitRampTrigger BOOL Power limit ramp trigger (1 = Write).

InputAlarm BOOL One or more asset inputs are in an invalid state.

ChargeComplete BOOL This storage asset has an SOC that is equal to or greater than input
MaxStateOfCharge. Once this condition is true, the storage asset will stop
charging.

StorageCurrentlyCharging BOOL This storage asset is in the process of charging.

InsufficientCharge BOOL This storage asset has insufficient SOC to discharge power. This is set
when SOC is less than or equal to MinStateOfCharge.

PowerClampActive BOOL Power clamp logic is active for this asset.

ReactiveClampActive BOOL Reactive power clamp is active for this inverter.

DeviceAvailableForControl BOOL If TRUE, device is included in GridConnect Control Algorithms and is


executing set points.

OperationModeSetpoint enum_operationMode The expected operation mode of how the asset takes setpoints. Default is
GridFollowing.

ActiveGridGroup UDINT The active group number this asset is a part of for grid connected
operations. Default is 65,535.

ReserveGroup BOOL If TRUE, this asset was successfully added to an active generation group
that only contains reserve assets.

ReactiveControlSetpointsActive BOOL If TRUE, this asset is in the correct reactive power control mode. PF
or VAR setpoints will update. If FALSE, PF or VAR setpoints will not
update.

StatusMessage STRING(255) Displays information about this power system assets input validation.

fb_ReciprocatingGenerator (Function Block)


The generator function block provides the control algorithms and I/O interface
for one generator in the system. This block only manages reciprocating
generation assets. The primary distinction between this block and other
generator types is that only speed modes are managed. It is expected that
GridConnect will interface with a separate controller that manages the
implementation of the setpoints to the generator, similar to a manufacturer-
provided genset or a PLC that directly interfaces with the generator.

GridConnect will only utilize a generator as a grid forming or isochronous


source during islanded operations. A generator will not be utilized during grid
connected operations. The generator cannot be included in any grid groups. It
can only be a grid forming asset during islanded operations. If the system has
multiple generators that are paralleled, only configure a single generator block in
GridConnect.

The PRating of the generator is assumed to be 100 percent duty cycle. This
assumption means the asset will not experience any mechanical failures as
a result of operating at PRating for extended time periods. Most generator
manufacturers will have documentation with information regarding power
ratings corresponding with various duty cycles percentages. It is important to
configure GridConnect with a PRating that corresponds with a 100 percent duty
cycle.

Programming Reference Date Code 20241023


GridConnect 573
Function Blocks

An important consideration that needs to be taken into account when configuring


reciprocating generators is the cool-down period after a generator has been
turned off. GridConnect does not manage a cool-down period for the generator.
The generator's manufacturer may specify a cool-down period or the local
controller may implement a cool-down period. SEL recommends using the cool-
down functionality of the manufacturer of the asset and, during this time period,
setting the OnStatus of the generator block to FALSE.

Inputs
Name IEC 61131 Type Description

ConnectToMasterController POINTER Connect this input to a master controller instance.

Offline BOOL If TRUE, no communications are active to the device. If FALSE,


communications are working correctly.

Fault BOOL Generator control device is reporting a fault. Default is FALSE.

OnStatus BOOL On/off status of the asset. Default is FALSE.

Synchronized BOOL Generator is on and connected to the power system and ready to respond to
setpoints.

IncludeCommand BOOL Command to include asset in the master control. Default is FALSE.

ExcludeCommand BOOL Command to remove asset from the control. Default is FALSE.

PFModeEnabled BOOL Generator is in power factor control mode.

QModeEnabled BOOL Generator is in reactive power control mode.

AssetP REAL Real power output from generator. Units are kW.

AssetQ REAL Real & reactive power output from generator. Units are kVAR.

AssetPF REAL Power factor at generator (generative +, consumptive –. Units are PF).

PRating REAL Power rating for the generator. Units are kW. Default is 0.

QRating REAL Reactive power rating for the generator. Units are kVAR. Default is 0.

MinFuelLevel REAL A percentage value that the generator should not discharge below. A value of
0 will not restrict discharging from the generator asset in any manner. Default
is 5.

FuelLevel REAL A percentage value representing the present fuel capacity of the generator.
Default is 100.

IncrementalReserveMargin REAL The percentage of PRating the asset is able to pick up without a significant
deviation in output frequency. Used for load acceptance criteria during
islanded conditions. Units are in percentage. Range is 1 to 100. Default is 100.

ColdLoadPickUp REAL The percentage of PRating the asset is able to pick up without a significant
deviation in output frequency when current asset output is 0. Used for load
acceptance criteria during islanded conditions. Units are in percentage. Range
is 1 to 100. Default is 100.

OperationModeFeedback enum_operationMode The feedback operation mode of the asset. Default is GridFollowing.

MinIslandOperation REAL A percentage value of PRating that is the minimum utilization this asset
should have as the grid forming asset during islanded operations.

Date Code 20241023 Programming Reference


574 GridConnect
Function Blocks

Outputs
Name IEC 61131 Type Description

IncludedInMasterControl BOOL Asset is included in master control. Will assert when asset is on,
included, and not excluded.

QuickStop BOOL Asserts to send stop signal to asset. This output can assert when required
even if the master controller is not enabled.

InsufficientFuelLevel BOOL This generator has insufficient fuel to discharge power.

GenOn BOOL This generator is expected to be on and participating in power system


objectives.

OperationModeSetpoint enum_gridOperationMode The expected operation mode of how the asset takes setpoints. Default is
GridForming.

OperationStatus enum_assetOperationStatus The current operational state of this asset.

fb_Load (Function Block)


The load function block provides the I/O interface for one or more loads in the
system. The load block is used to provide information and acceptance criteria for
islanded operations. If the system contains multiple loads that can be separated
from the system via some mechanism, SEL recommends that each load be
represented as a load function block instance. For loads that are not controllable,
it is simplest to model all of these as a single load function block aggregating
any power consumption from these loads. For metering purposes, however, it
may be more useful to model non-controllable load as multiple function blocks.
GridConnect will manage including load during an islanded condition, but it
does not manage removing load during islanded operation. No load shedding is
supported. All load must be represented via either one or multiple load blocks,
but accurate metering information is not required for loads. If metering data
are available, they can be given to GridConnect via the load function blocks.
Alternatively, the user can input estimated nominal load values for GridConnect
to use when determining load acceptance criteria during islanded conditions.

By default, GridConnect assumes that the power requirements after a load


is connected to the system during blackout are within the capabilities of the
generation assets. If there are additional power generation requirements to
support the initial pickup for a load (perhaps for an inductive based load),
GridConnect can consider this factor for load acceptance via the input pin
ExpectedPickup.

When configuring the order in which load will be brought online, GridConnect
will check that the load is controllable via the IsControllable input pin. If
IsControllable is FALSE, the output pin LoadOrder will be set to zero, which
assumes the load is always connected and does not take into consideration the
ConnectionStatus input. Additionally, two loads cannot share the same order
number. If two load blocks share the same Order input value, one block will
have the output LoadOrder pin set to 65,535, indicating the load will not be
included during islanded operations.

Programming Reference Date Code 20241023


GridConnect 575
Function Blocks

Inputs
Name IEC 61131 Type Description

ConnectToMasterController POINTER Connect this input to a master controller instance.

Offline BOOL If TRUE, no communications are active to the device. If FALSE, communications
are working correctly.

IncludeCommand BOOL Command to include load in master plant control. Default is FALSE.

ExcludeCommand BOOL Command to remove load from master plant control. Default is FALSE.

ConnectionStatus BOOL Status of the connection to separate the load from the grid. If TRUE, the load is
connected to grid and will draw power. If FALSE, the load is disconnected from
grid. If IsControllable is FALSE, this input setting will be disregarded. Default is
FALSE.

Disconnect BOOL A command to open the connection, provided system conditions allow for that.
If TRUE GridConnect will issue an open command and will prevent attempts to
include the load in grid operations until the Disconnect input is FALSE. Will issue
open command when energized when CanLoadBreak is TRUE.

Connect BOOL A command to close the connection. If TRUE, GridConnect will issue a close
command. GridConnect Will not attempt to close if Disconnect is TRUE.

IsControllable BOOL If TRUE, asset can be dynamically included or excluded from the power system. If
FALSE, asset is assumed to always be connected to the grid. Default is FALSE.

CanLoadBreak BOOL If TRUE, asset can be excluded from power system while energized. If FALSE,
asset can only be excluded from power system when de-energized.

IsMetered BOOL If TRUE, asset has metering available for historical data recording. Default is
FALSE.

HistoricalRecordLength UDINT The number of values to buffer and calculate RunningAverage with. Default is 100.

UseMeteredData BOOL If TRUE, RunningAverage will be used for nominal load acceptance instead of
NominalPower during islanded operation. If FALSE, NominalPower will be used
for nominal load acceptance during islanded operation.

LoadP REAL Real-time real power measurement of load.

LoadQ REAL Real-time reactive power measurement of load.

NominalPower REAL The nominal amount of real power this load is expected to consume for use during
islanded operation. If 0, the load configuration will be considered invalid and will
not be brought online during islanded operation. Default is 0.

ExpectedPickup REAL The amount of expected power from this load when initially energized during
blackstart. If 0, NominalPower or RunningAverage will be used for load acceptance
criteria. Default is 0.

ResetLoadStatus BOOL A rising edge on ResetLoadStatus will deassert LoadUnAvailable, making the load
available to inclusion in islanded operations again. ExpectedConnectionStatus will
be set to the current value of ConnectionStatus.

LoadTimeOut TIME The time to wait before asserting LoadUnAvailable when ConnectionStatus does
not match ExpectedConnectionStatus. Minimum value is T#5S. Default is T#1M.

Date Code 20241023 Programming Reference


576 GridConnect
Function Blocks

Outputs
Name IEC 61131 Type Description

IncludedInMasterControl BOOL Asset is included in master control. Will assert when asset is included and not
excluded.

CloseCommand BOOL Command to close the connection.

OpenCommand BOOL Command to open the connection.

LoadUnAvailable BOOL If TRUE, the load cannot be included in islanded operations. This will be
TRUE when Offline is TRUE or when the ConnectionStatus does not match
ExpectedConnectionStatus for the duration of LoadTimeOut.

ExpectedConnectionStatus BOOL The expected state of ConnectionStatus. Will be TRUE for a closed connection.
Will be FALSE for an open connection. This output pin will be initialized
from Connect and Disconnect input pins. If Connect and Disconnect are
FALSE and GridConnect has not issued any open or close commands,
ExpectedConnectionStatus will follow the value of ConnectionStatus.

RunningAverage REAL A running average sampled on the evaluation period of LoadP if IsMetered is
TRUE. Includes the average of the last HistoricalRecordLength evaluation periods.
Is not retained through power cycles or settings changes.

MaxPMeteredValue REAL The maximum LoadP seen. Is not retained through power cycles or settings
changes.

Status STRING(255) Information about the status of this load function block.

fb_Capacitor (Function Block)


The Capacitor Control function block provides the control algorithms and I/O
interface for one capacitor in a solar generating facility.

Inputs
Name IEC 61131 Type Description

ConnectToMasterController POINTER Connect this input to a master controller instance.

Offline BOOL If TRUE, no communications are active to the device. If FALSE, communications
are working correctly.

RemoteEnabled BOOL Capacitor control device is available to remote master control (1 = Remote).
Default is FALSE.

Fault BOOL Capacitor control device is reporting a fault (1 = Fault). Default is FALSE.

OnStatus BOOL On/off status of the capacitor. Default is FALSE.

OnCommandInput BOOL Command to turn on the capacitor. Default is FALSE.

OffCommandInput BOOL Command to turn off the capacitor. Default is FALSE.

IncludeCommand BOOL Command to include capacitor in the master control. Default is FALSE.

ExcludeCommand BOOL Command to remove capacitor from the master control. Default is FALSE.

CapacitorV REAL Voltage at the capacitor terminals. Units are kV. Default is 0.

QRating REAL Reactive power rating of the capacitor. Units are kVAR. Default is 0.

Programming Reference Date Code 20241023


GridConnect 577
Simulator

Name IEC 61131 Type Description

VRating REAL Voltage rating of the capacitor. Units are kV. Default is 0.

SequenceNumber UINT Capacitor is dependent on another capacitor being closed first. Default is 0.
➤ 0 = Cap is not dependent on other Caps.
➤ 1 = Cap is the first to be turned on and the last to be turned off.
➤ 2 = Cap will only be turned on if Caps with a sequence number of 1 is ON first.
➤ 3 = Follows 2.
➤ ...
➤ g_c_CAP_MAX = Follows g_c_CAP_MAX – 1.

Outputs
IEC 61131
Name Description
Type

IncludedInMasterControl BOOL Capacitor is included in master control. Will


assert when capacitor is included and not
excluded.

OnCommand BOOL Pulse to turn on capacitor.

OffCommand BOOL Pulse to turn off capacitor.

Simulator
Function Blocks
The GridConnect library contains a built-in set of Simulator function blocks
to support learning, testing, and tuning of GridConnect integration. These
constructs are intended to be used to simulate the various inverter-based devices
that GridConnect would normally interact with and control. Therefore, the
GridConnect Simulator function blocks should take input from the outputs
of GridConnect POUs and should provide feedback as input to GridConnect
objects, as shown in Figure 17.9.

Figure 17.9 GridConnect Simulator Connecting to GridConnect Elements

fb_PCCSim (Function Block)


The Point of Common Coupling simulator to be used in conjunction with
GridConnect logical blocks for learning, testing, and tuning exercises. (All units
are in kilo unless explicitly mentioned otherwise.)

Date Code 20241023 Programming Reference


578 GridConnect
Simulator

PCCSim will accumulate the total combination of all "behind the meter assets"
and then apply the PCC parameters of restrictions or adjustments.

Assets behind PCC include the following:

➤ PV Inverters
➤ Battery(ies)
➤ Capacitor

Figure 17.10 fb_PCCSim System Accumulation

Noise inputs all have units of percent between 0 and 100, meaning it will affect
that parameter output by the percent defined. For example, if PNoise is 3, then
a PlantP output value of 100 would fluctuate between 97 and 103. Noise is
applied at the level of individual assets and accumulated at the PCC simulator
block.

Inputs

Name IEC 61131 Type Description

RealPowerLosses REAL Losses of real power behind the PCC. Units are kW.

ReactivePowerLosses REAL Losses of reactive power behind the PCC. Units are kVAR.

ForceUniversalIrradiance BOOL Enable/disable for the PCC to manage the capability output of all assets' maximum
capability.

UniversalIrradiance REAL Percentage between 0 to 100 that tells the asset its maximum power output based
upon its rating. For example, if UniversalIrradiance is 75 and the asset's rating is
100 kW, the maximum output of the asset would be 75 kW.

dVdQ REAL The relationship between voltage and VAR, or how many VARs it takes to create a
1-volt change. Units are volts/VAR. Default is 0.002.

NominalVoltage REAL Nominal voltage at PCC if reactive power flow is 0. Units are kV.

IrradianceNoise REAL Noise experienced in irradiance at PCC. Units are percentage.

PNoise REAL Noise experienced in real power flow at PCC. Units are percentage.

QNoise REAL Noise experienced in reactive power flow at PCC. Units are percentage.

NoiseTimePeriod TIME Time interval to adjust the noise output. Default is 0.

TimeScaleMultiplier REAL Time multiplier used to speed up behavior for testing purposes. A value of 1
operates in real time, a value 2 means 1 second is equivalent to 2 seconds. A value
of 60 means 1 second equates to 1 minute.

Programming Reference Date Code 20241023


GridConnect 579
Simulator

Outputs
Name IEC 61131 Type Description

ConnectToPlantSimulators POINTER TO Connection point at which all plant simulators attach.


fb_PCCSim

PlantP REAL Real power flow at PCC. Units are kW.

PlantQ REAL Reactive power flow at PCC. Units are kVAR.

PlantV REAL Voltage at PCC that accounts for VAR flow at PCC. Units are kV.

PlantPF REAL Power factor at PCC.

PlantFrequency REAL Frequency (in hertz) at PCC; reflects the nominal frequency input.

fb_PVInverterSim (Function Block)


The PV inverter simulator to be used in conjunction with GridConnect logical
blocks for learning, testing, and tuning exercises.

Inverter should output the given input unless it violates the following:

➤ The irradiance capability of the device


➤ The ramp rate of the inverter
➤ The power factor limit of the device

Real Power Evaluation


The real power output of the PV Inverter Simulator block is governed by the
system illustrated in Figure 17.11.

Figure 17.11 fb_PVInverterSim Real Power Evaluation System

Reactive Power Evaluation


The reactive power output of the PV Inverter Simulator block is governed by the
system illustrated in Figure 17.12.

Date Code 20241023 Programming Reference


580 GridConnect
Simulator

Figure 17.12 fb_PVInverterSim Reactive Power Evaluation System

Inputs

Name IEC 61131 Type Description

ConnectToPCCSim POINTER TO fb_PCCSim Connection to the Point of Common Coupling Simulator object.

On BOOL Control to turn the asset on/off; when FALSE, the asset outputs 0.
TRUE: ON.

RemoteEnabled BOOL When TRUE, the asset takes set points and processes them. When
FALSE, the asset output remains frozen at current values.

PSetpoint REAL Real power set point for the asset to issue. Units are kW.

QSetpoint REAL Reactive power set point for the asset to issue. Units are kVAR.

PFSetpoint REAL PF relationship between P and Q. Q output is calculated based upon


this relationship.

PRamprate REAL Ramp rate per second at which real power is allowed to change. A
value of 0 does not restrict changes. Units are kW/second.

QRamprate REAL Ramp rate per second at which reactive power is allowed to change. A
value of 0 does not restrict changes. Only enforced when in Qmode.
Units are kVAR/second.

PFRamprate REAL Ramp rate per second at which reactive power is allowed to change
according to the PF relationship between P and Q. A value of 0 does
not restrict changes. Only enforced when in PFmode.

QModeInput BOOL When TRUE, the asset operates in Qmode. The rising edge of this
input will set the asset to operate in Qmode.

PFModeInput BOOL When TRUE, the asset operates in PFmode. The rising edge of this
input will set the asset to operate in PFmode.

SetpointDelayTime TIME The time it takes for the asset to update its output once it has received a
new set point.

AssetAccuracy REAL A percentage between 50 and 150 that represents how accurately the
asset will output the desired set points. For example, if asset accuracy
is 105 and the set point is 100 kW, then the output is 105 kW.

IrradianceInput REAL If the PCC does not force irradiance, use this value. Percentage
between 0 to 100. Irradiance only affects real power output.

PRating REAL Real power capability of asset. Can be dynamically changed during
runtime. Units are kW.

Programming Reference Date Code 20241023


GridConnect 581
Simulator

Name IEC 61131 Type Description

QRating REAL Reactive power capability of asset. Can be dynamically changed during
runtime. Units are kVAR.

PFLeadLimit REAL Power factor limit of device. If a Q or PF set point was to make the
asset PF worse than this lead limit, then restrict Q output of asset to
maintain this limit.

PFLagLimit REAL Power factor limit of device. If a Q or PF set point was to make the
asset PF worse than this lag limit, then restrict Q output of asset to
maintain this limit.

Outputs

Name IEC 61131 Type Description

POutput REAL Real power output of the asset. Units are kW.

QOutput REAL Reactive power output of the asset. Units are kVAR.

PFOutput REAL Power factor output of the asset.

QMode BOOL Indicator that device is operating in Qmode. PF- and


Qmode outputs are exclusive and only one may be
true at any point in time.

PFMode BOOL Indicator that device is operating in PFmode. PF- and


Qmode outputs are exclusive and only one may be
true at any point in time.

Connected BOOL Diagnostic output to indicate whether the connection


to the PCC simulator was established successfully.

fb_BessSim (Function Block)


The battery energy storage simulator to be used in conjunction with
GridConnect logical blocks for learning, testing, and tuning exercises.

A positive set point for Setpoint causes battery discharge, and a negative set
point causes the battery to consume power and store charge.

For example, a discharge set point of 100 kW of 1 minute is 1.67 kWh;


similarly, a charge value would add this amount of capability back to the battery.
In this simulator, Q discharge does not affect state of charge (SOC).

Inverter should output the given input unless it violates the following:

➤ Ramp rate of the inverter


➤ Power factor limit of the device

Real Power Evaluation


The real power output of the BESS Inverter Simulator block is governed by the
system illustrated in Figure 17.13.

Date Code 20241023 Programming Reference


582 GridConnect
Simulator

Figure 17.13 fb_BessSim Real Power Evaluation System

Reactive Power Evaluation


The reactive power output of the BESS Inverter Simulator block is governed by
the system illustrated in Figure 17.14.

Figure 17.14 fb_BessSim Reactive Power Evaluation System

Inputs
Name IEC 61131 Type Description

ConnectToPCCSim POINTER TO fb_PCCSim Connection to the Point of Common Coupling Simulator object.

On BOOL Control to turn the asset on/off; when FALSE, the asset outputs 0.

RemoteEnabled BOOL When TRUE, the asset takes set points and processes them. When FALSE, the
asset output remains frozen at current values.

PSetpoint REAL Real power set point for the asset to issue. Units are kW.

Programming Reference Date Code 20241023


GridConnect 583
Simulator

Name IEC 61131 Type Description

QSetpoint REAL Reactive power set point for the asset to issue. Units are kVAR.

PFSetpoint REAL PF relationship between P and Q. Q output is calculated based upon this
relationship.

PRamprate REAL Ramp rate per second at which real power is allowed to change. A value of 0
does not restrict changes. Units are kW/second.

QRamprate REAL Ramp rate per second at which reactive power is allowed to change. A value
of 0 does not restrict changes. Only enforced when in Qmode. Units are
kVAR/second.

PFRamprate REAL Ramp rate per second at which reactive power is allowed to change according
to the PF relationship between P and Q. A value of 0 does not restrict
changes. Only enforced when in PFmode.

QModeInput BOOL When TRUE, the asset operates in Qmode. The rising edge of this input will
set the asset to operate in Qmode.

PFModeInput BOOL When TRUE, the asset operates in PFmode. The rising edge of this input will
set the asset to operate in PFmode.

SetpointDelayTime TIME The time it takes for the asset to update its output once it has received a new
set point.

InverterAccuracy REAL A percentage between 50 and 150 that represents how accurately the asset will
output the desired set points. For example, if asset accuracy is 105 and the set
point is 100 kW, then the output is 105 kW.

PRating REAL Real power capability of asset. Can be dynamically changed during runtime.
Units are in kW.

QRating REAL Reactive power capability of asset. Can be dynamically changed during
runtime. Units are in kVAR.

PFLeadLimit REAL Power factor limit of device. If a Q or PF set point was to make the asset PF
worse than this lead limit, then restrict Q output of asset to maintain this limit.

PFLagLimit REAL Power factor limit of device. If a Q or PF set point was to make the asset PF
worse than this lag limit, then restrict Q output of asset to maintain this limit.

EnableSOC BOOL When TRUE, the output is affected by the state of charge; when FALSE,
ignore SOC.

KWhRating REAL Kilowatt-hour rating of battery. Units are in kWh.

InitialSOC REAL Initial SOC of battery on first scan or reset. Units are in percent.

ResetSOC BOOL Rising-edge trigger to reset output StateOfCharge to InitialSOC.

MinSOC REAL Minimum SOC above which battery may deliver energy. Units are in percent.

Outputs

Name IEC 61131 Type Description

POutput REAL Real power output of the asset. Units are in kW.

QOutput REAL Reactive power output of the asset. Units are in kVAR.

PFOutput REAL Power factor output of the asset.

QMode BOOL Indicator that device is operating in Qmode. PF- and


Qmode outputs are exclusive and only one may be true
at any point in time.

Date Code 20241023 Programming Reference


584 GridConnect
Simulator

Name IEC 61131 Type Description

PFMode BOOL Indicator that device is operating in PFmode. PF- and


Qmode outputs are exclusive and only one may be true
at any point in time.

StateOfCharge REAL Present SOC of battery. Units are in percent.

Connected BOOL Diagnostic output to indicate whether the connection to


the PCC simulator was established successfully.

fb_ReciprocatingGeneratorSim (Function Block)


The reciprocating generator simulator to be used in conjunction with
GridConnect logical blocks for learning, testing, and tuning exercises.

Generator should output the given input unless it violates the following:

➤ ramp rate of the device


➤ power factor limit of the device

Start/Stop Commands
The generator implements a configurable startup delay and cool-down period
after a falling edge on GenTurnOn input. See Figure 17.15 for a generator's
operation during the start/stop process. Generator will only start to respond to
Psetpoint values once Synchronized is asserted.

Figure 17.15 Generator Real Power Start Stop

Real Power Evaluation


The real power output of the Generator Simulator block is governed by the
system illustrated in Figure 17.16.

Programming Reference Date Code 20241023


GridConnect 585
Simulator

Figure 17.16 Generator Real Power

Reactive Power Evaluation


The reactive power output of the Generator Simulator block is governed by the
system illustrated in Figure 17.17.

Figure 17.17 Generator Reactive Power

Date Code 20241023 Programming Reference


586 GridConnect
Simulator

Inputs

Name IEC 61131 Type Description

ConnectToPCCSim POINTER TO fb_PCCSim Connection to the Point of Common Coupling


Simulator object.

On BOOL Control to turn the asset on/off; when FALSE, asset


outputs 0.

RemoteEnabled BOOL When TRUE, the asset takes set points and
processes them. When FALSE, the asset output
remains frozen at current values.

PSetpoint REAL Real power set point for the asset to issue. Units are
kW.

QSetpoint REAL Reactive power set point for the asset to issue. Units
are kVAR.

PFSetpoint REAL PF relationship between P and Q. Q output is


calculated based upon this relationship.

PRamprate REAL Ramp rate per second at which real power is


allowed to change. A value of 0 does not restrict
changes. Units are kW/second.

QRamprate REAL Ramp rate per second at which reactive power is


allowed to change. A value of 0 does not restrict
changes. Only enforced when in Qmode. Units are
kVAR/second.

PFRamprate REAL Ramp rate per second at which reactive power is


allowed to change according to the PF relationship
between P and Q. A value of 0 does not restrict
changes. Only enforced when in PFmode.

QModeInput BOOL When TRUE, the asset operates in Qmode. The


rising edge of this input will set the asset to operate
in Qmode.

PFModeInput BOOL When TRUE, the asset operates in PF mode. The


rising edge of this input will set the asset to operate
in PFmode.

SetpointDelayTime TIME The time it takes for the asset to update its output
once it has received a new set point.

AssetAccuracy REAL A percentage between 50 and 150 that represents


how accurately the asset will output the desired set
points. For example, if asset accuracy is 105 and the
set point is 100 kW, then the output is 105 kW.

PRating REAL Real power capability of asset. Can be dynamically


changed during runtime. Units are in kW.

QRating REAL Reactive power capability of asset. Can by


dynamically changed during runtime. Units are in
kVAR.

PFLeadLimit REAL Power factor limit of device. If a Q or PF set point


was to make the asset PF worse than this lead limit,
then restrict Q output of asset to maintain this limit.

PFLagLimit REAL Power factor limit of device. If a Q or PF set point


was to make the asset PF worse than this lag limit,
then restrict Q output of asset to maintain this limit.

Programming Reference Date Code 20241023


GridConnect 587
Simulator

Name IEC 61131 Type Description

EnableFuelConsumption BOOL If TRUE, output is affected by the fuel level. If


FALSE, then ignore fuel level.

InitialFuelLevel REAL Initial fuel level on first scan or reset. Units are in
percent. Range is 0 to 100.

FuelCapacity REAL The amount of fuel this asset supports in gallons.


Defaults to 500.

ResetFuel BOOL Rising edge trigger to reset output FuelLevelPercent


and FuelLevelInGallons to InitialFuelLevel.

MinFuelLevel REAL Minimum fuel level above which generator may


deliver energy. Units are in percent. Defaults to 5.

FuelConsumptionRate REAL Gallons consumed per kilo-watt hour. Defaults to 5.

GenTurnOnDelay TIME The time wait to assert synchronized output after


GenTurnOn asserts. Defaults to T#5S.

GenCoolDownTime TIME The time to make a generator unavailable after


GenTurnOff de-asserts. Defaults to T#30S.

GenTurnOn BOOL If TRUE, turn generator on. If FALSE, generator


will be turned off after GenCoolDownTime expires.

Outputs

Name IEC 61131 Type Description

POutput REAL Real power output of the asset. Units are in kW.

QOutput REAL Reactive power output of the asset. Units are in kVAR.

PFOutput REAL Power factor output of the asset.

QMode BOOL Indicator that device is operating in Q mode. PF- and Qmode outputs are
exclusive and only one may be true at any point in time.

PFMode BOOL Indicator that device is operating in PF mode. PF- and Qmode outputs are
exclusive and only one may be true at any point in time.

FuelLevelPercent REAL Present fuel level of the generator. Units are in percentage.

FuelLevelInGallons REAL The number of gallons left in the tank. Units are in gallons.

Synchronized BOOL The generator is actively connected to the system and is actively responding
to setpoints.

CoolDown BOOL The generator is cooling down after being shut down. Generator is not
available.

Connected BOOL Diagnostic output to indicate whether connection to PCC simulator was
established successfully.

fb_CapSim (Function Block)


The capacitor simulator to be used in conjunction with GridConnect logical
blocks for learning, testing, and tuning exercises.

Date Code 20241023 Programming Reference


588 GridConnect
Simulator

Inputs
Name IEC 61131 Type Description

ConnectToPCCSim POINTER TO fb_PCCSim Connection to the Point of


Common Coupling Simulator
object.

CapOn BOOL Control to engage capacitor or to


logically disconnect it. TRUE: ON

CapQRating REAL Reactive power rating of capacitor.


Units are in kVAR.

Outputs
Name IEC 61131 Type Description

Connected BOOL Diagnostic output to indicate whether the connection


to the PCC simulator was established successfully.

fb_LoadSim (Function Block)


The load simulator to be used in conjunction with GridConnect logical blocks
for learning, testing, and tuning exercises.

Inputs
Name IEC 61131 Type Description

ConnectToPCCSim POINTER TO fb_PCCSim Connection to the Point of Common Coupling Simulator object.

On BOOL Control to turn load on/off; when FALSE, load outputs 0.

PSetpoint REAL Real power set point for load to consume. Range is greater than 0. Units are
kW.

QSetpoint REAL Reactive power set point load to consume. Load will consume VARs when
greater than 0 and produce VARs when less than 0. Units are kVAR.

PRamprate REAL Ramp rate per second that real power is allowed to change. A value of 0 does
not restrict changes. Units are kW/second.

QRamprate REAL Ramp rate per second that reactive power is allowed to change. A value of 0
does not restrict changes. Units are kVAR/second.

SetpointDelayTime TIME The time it takes for the load to update its output once it has received a new
set point.

PRating REAL Real power capability of asset. Can be dynamically changed during runtime.
Units are kW.

QRating REAL Reactive power capability of asset. Can by dynamically changed during
runtime. Units are kVAR.

IsControllable BOOL Determines if this load can be dynamically connected or disconnected from
the system during run time. Defaults to TRUE.

CanLoadBreak BOOL If TRUE, then load can disconnect while energized. If FALSE, then load can
only disconnect while de-energized. Defaults to TRUE.

CloseCommand BOOL Command to close connection for inclusion in power system. Defaults to
TRUE.

Programming Reference Date Code 20241023


GridConnect 589
Examples

Name IEC 61131 Type Description

OpenCommand BOOL Command to open connection for exclusion from power system. Defaults to
FALSE.

PowerSystemEnergized BOOL Indication that power system is energized with a grid forming source either
grid connected or islanded. Defaults to TRUE.

Outputs

Name IEC 61131 Type Description

Connected BOOL Diagnostic output to indicate whether connection to PCC simulator was
established successfully.

POutput REAL Real power output of the load. Units are kW.

QOutput REAL Reactive power output of the load. Units are kVAR.

LoadConnectionStatus BOOL If TRUE, load is connected to power system. If FALSE, load is disconnected
from power system.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Modeling a Solar Generation Facility


Objective
A user has a solar facility that needs to be controlled. The facility is laid out as
shown in Figure 17.18.

Date Code 20241023 Programming Reference


590 GridConnect
Examples

Figure 17.18 Solar Facility One-Line Diagram

Data Source Assumptions


Typically, all inputs to the function blocks used in this model would be
connected to data from an incoming communication channel. However, to
make the illustration of this example clearer, all inputs are contained in Global
Variable Lists.

Solution
Once the user has identified all the elements of the model and decided the source
for all required data, the only work remaining is to construct the model in a
program as shown in Code Snippet 17.1.
Code Snippet 17.1 prg_GridConnectMain
VAR
MasterController : fb_MasterPlantController;
Inverter1, Inverter2 : fb_PvInverter;
Storage1, Storage2 : fb_StorageInverter;
Capacitor1, Capacitor2 : fb_Capacitor;
hasRunOnce : BOOL;
END_VAR

(**** SETTINGS ****)


IF NOT hasRunOnce THEN
MasterController.QDeadband := 0; // kVAR
MasterController.QKp := 0.4;
MasterController.QKi := 0.04;
MasterController.QLimitHigh := 3000; // kVAR
MasterController.QLimitLow := –1300; // kVAR

MasterController.PFDeadband := 0.001; // PF
MasterController.PFKp := 0.2;
MasterController.PFKi := 0;
MasterController.PFLagLimit := 0.8; // PF
MasterController.PFLeadLimit := –0.8; // PF
MasterController.PFCompensationSetpoint := 1.0; // Unity PF

Programming Reference Date Code 20241023


GridConnect 591
Examples

MasterController.PFCompensationLowPowerCutoff := 15; // 15%


MasterController.PFCompensationGradient := –0.002; // PF / %kW
MasterController.PFCompensationLowPFLimit := 0.8; // +- 0.8 PF

MasterController.VDeadband := 0.05; // kV
MasterController.VKp := 0.3;
MasterController.VKi := 0.03;
MasterController.VLimitHigh := 42; // kV
MasterController.VLimitLow := 38; // kV
MasterController.dV_dQ := 0.0002; // kW/kVAR
MasterController.VCompensationV1 := 38; // kV
MasterController.VCompensationV2 := 40;
MasterController.VCompensationV3 := 40;
MasterController.VCompensationV4 := 41;
MasterController.VCompensationQ1 := 2000; // kVAR
MasterController.VCompensationQ2 := 0;
MasterController.VCompensationQ3 := 0;
MasterController.VCompensationQ4 := –2000;

MasterController.FRegulationF1 := 59; // Hz
MasterController.FRegulationF2 := 59.7;
MasterController.FRegulationF3 := 60.3;
MasterController.FRegulationF4 := 61;
MasterController.FRegulationP1 := 10; // % of plant rated kW
MasterController.FRegulationP2 := 0;
MasterController.FRegulationP3 := 0;
MasterController.FRegulationP4 := –10;

MasterController.PDeadband := 2; // kW
MasterController.PKp := 0.4;
MasterController.PKi := 0.04;

MasterController.PFRampSetpoint := 0.02; // PF/sec


MasterController.QRampSetpoint := 20;
MasterController.PLimitRampSetpoint := 50;
MasterController.PLimitDelay := T#60S;

MasterController.PlantPRating := 1000; // 1MW


MasterController.PlantQRating := 8000; // 800 kVAR
MasterController.PlantLowPowerCutoff := 5; // kW
MasterController.EvaluationPeriod := T#1S;
MasterController.ControlRetryPeriod := T#2S;
MasterController.CapacitorOperationPeriod := T#120S;
MasterController.InverterModeChangeControlDelay := T#30S;

// Inverter 1 Settings
Inverter1.IncludeCommand := TRUE;
Inverter1.ExcludeCommand := FALSE;
Inverter1.InverterPFLagLimit := 0.8;
Inverter1.InverterPFLeadLimit := –0.8;
Inverter1.PRating := 500; // kW
Inverter1.QRating := 450; // kVAR

// Inverter 2 Settings
Inverter2.IncludeCommand := TRUE;
Inverter2.ExcludeCommand := FALSE;
Inverter2.InverterPFLagLimit := 0.8;
Inverter2.InverterPFLeadLimit := –0.8;
Inverter2.PRating := 500; // kW
Inverter2.QRating := 450; // kVAR

// Battery 1 settings
Storage1.IncludeCommand := TRUE;
Storage1.ExcludeCommand := FALSE;
Storage1.InverterPFLagLimit := 0.8;
Storage1.InverterPFLeadLimit := –0.8;
Storage1.PRating := 200; // kW
Storage1.QRating := 150; // kVAR

Date Code 20241023 Programming Reference


592 GridConnect
Examples

// Battery 2 settings
Storage2.IncludeCommand := TRUE;
Storage2.ExcludeCommand := FALSE;
Storage2.InverterPFLagLimit := 0.8;
Storage2.InverterPFLeadLimit := –0.8;
Storage2.PRating := 200; // kW
Storage2.QRating := 150; // kVAR

// Capacitor 1 Settings
Capacitor1.IncludeCommand := TRUE;
Capacitor1.ExcludeCommand := FALSE;
Capacitor1.QRating := 200; // kVAR
Capacitor1.VRating := 7.2; // kW
Capacitor1.SequenceNumber := 0; // First to turn on

// Capacitor 2 Settings
Capacitor2.IncludeCommand := TRUE;
Capacitor2.ExcludeCommand := FALSE;
Capacitor2.QRating := 200; // kVAR
Capacitor2.VRating := 7.2; // kW
Capacitor2.SequenceNumber := 0; // First to turn on

hasRunOnce := TRUE;
END_IF

(**** MODE, STATUS, AND SET POINT CONTROLS ****)


MasterController.ControlMode :=
DINT_TO_INT(vtl_PlantControls.ReactiveControlMode.stVal);
MasterController.PLimitMode :=
DINT_TO_INT(vtl_PlantControls.RealPowerMode.stVal);
MasterController.Enable := vtl_PlantControls.Enable.stVal;
MasterController.EnableStorageDownrampControl :=
vtl_PlantControls.EnableDownrampControl.stVal;
MasterController.EmergencyStop := vtl_PlantControls.EmergencyStop.stVal;

MasterController.QSetpoint := vtl_PlantControls.QSetpoint.instMag;

MasterController.PFSetpoint := vtl_PlantControls.PFSetpoint.instMag;

MasterController.VSetpoint := vtl_PlantControls.VSetpoint.instMag;

MasterController.PSetpoint := vtl_PlantControls.PSetpoint.instMag;
MasterController.StoragePSetpoint := vtl_PlantControls.StoragePSetpoint.instMag;

(**** I/O ****)


// Master Controller I/O
MasterController.PlantP := vtl_POIData.PlantP.instCVal.mag;
MasterController.PlantQ := vtl_POIData.PlantQ.instCVal.mag;
MasterController.PlantPF := vtl_POIData.PlantPF.instCVal.mag;
MasterController.PlantV := vtl_POIData.PlantV.instCVal.mag;
MasterController.PlantF := vtl_POIData.PlantF.instCVal.mag;
MasterController.PlantMeasurementsGood := vtl_POIData.IsPoiDataGood.stVal;

// Inverter 1 I/O
Inverter1.Offline := vtl_InverterData.IsInverter1Offline.stVal;
Inverter1.RemoteEnabled :=
vtl_InverterData.IsInverter1RemoteEnabled.stVal;
Inverter1.Fault :=
vtl_InverterData.IsInverter1InFaultedState.stVal;
Inverter1.OnStatus := vtl_InverterData.IsInverter1On.stVal;
Inverter1.PFModeEnabled := vtl_InverterData.IsInverter1InPFMode.stVal;
Inverter1.QModeEnabled := vtl_InverterData.IsInverter1InQMode.stVal;
Inverter1.InverterP :=
DINT_TO_REAL(vtl_InverterData.Inverter1P.stVal);
Inverter1.InverterQ :=
DINT_TO_REAL(vtl_InverterData.Inverter1Q.stVal);
Inverter1.InverterPF :=
DINT_TO_REAL(vtl_InverterData.Inverter1PF.stVal)/1000;
Inverter1.PFSetpointFeedback :=

Programming Reference Date Code 20241023


GridConnect 593
Examples

DINT_TO_REAL(vtl_InverterData.Inverter1PFSetpointFeedback.stVal)/1000;
Inverter1.QSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Inverter1QSetpointFeedback.stVal);
Inverter1.PLimitSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Inverter1PLimitSetpointFeedback.stVal);
//NOTE: No ramp feedback available from inverters
vtl_InverterData.Inverter1PackedControls.stVal.0 := Inverter1.OnCommand;
vtl_InverterData.Inverter1PackedControls.stVal.1 := Inverter1.OffCommand;
vtl_InverterData.Inverter1PackedControls.stVal.2 := Inverter1.EmergencyStop;
vtl_InverterData.Inverter1PackedControls.stVal.3 := Inverter1.PFModeCommand;
vtl_InverterData.Inverter1PackedControls.stVal.4 := Inverter1.QModeCommand;
vtl_InverterData.Inverter1PFSetpoint.oper.setMag := Inverter1.PFSetMag*1000; // Move
significant figures left of decimal
vtl_InverterData.Inverter1PFSetpoint.oper.trigger := Inverter1.PFTrigger;
vtl_InverterData.Inverter1QSetpoint.oper.setMag := Inverter1.QSetMag;
vtl_InverterData.Inverter1QSetpoint.oper.trigger := Inverter1.QTrigger;
vtl_InverterData.Inverter1PSetpoint.oper.setMag := Inverter1.PLimitSetMag;
vtl_InverterData.Inverter1PSetpoint.oper.trigger := Inverter1.PLimitTrigger;
vtl_InverterData.Inverter1PFRampSetpoint.oper.setMag := Inverter1.PFRampSetMag;
vtl_InverterData.Inverter1PFRampSetpoint.oper.trigger := Inverter1.PFRampTrigger;
vtl_InverterData.Inverter1QRampSetpoint.oper.setMag := Inverter1.QRampSetMag;
vtl_InverterData.Inverter1QRampSetpoint.oper.trigger := Inverter1.QRampTrigger;
vtl_InverterData.Inverter1PRampSetpoint.oper.setMag := Inverter1.PLimitRampSetMag;
vtl_InverterData.Inverter1PRampSetpoint.oper.trigger := Inverter1.PLimitRampTrigger;

// Inverter 2 I/O
Inverter2.Offline := vtl_InverterData.IsInverter2Offline.stVal;
Inverter2.RemoteEnabled :=
vtl_InverterData.IsInverter2RemoteEnabled.stVal;
Inverter2.Fault :=
vtl_InverterData.IsInverter2InFaultedState.stVal;
Inverter2.OnStatus := vtl_InverterData.IsInverter2On.stVal;
Inverter2.PFModeEnabled := vtl_InverterData.IsInverter2InPFMode.stVal;
Inverter2.QModeEnabled := vtl_InverterData.IsInverter2InQMode.stVal;
Inverter2.InverterP :=
DINT_TO_REAL(vtl_InverterData.Inverter2P.stVal);
Inverter2.InverterQ :=
DINT_TO_REAL(vtl_InverterData.Inverter2Q.stVal);
Inverter2.InverterPF :=
DINT_TO_REAL(vtl_InverterData.Inverter2PF.stVal)/1000;
Inverter2.PFSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Inverter2PFSetpointFeedback.stVal)/1000;
Inverter2.QSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Inverter2QSetpointFeedback.stVal);
Inverter2.PLimitSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Inverter2PLimitSetpointFeedback.stVal);
//NOTE: No ramp feedback available from inverters
vtl_InverterData.Inverter2PackedControls.stVal.0 := Inverter2.OnCommand;
vtl_InverterData.Inverter2PackedControls.stVal.1 := Inverter2.OffCommand;
vtl_InverterData.Inverter2PackedControls.stVal.2 := Inverter2.EmergencyStop;
vtl_InverterData.Inverter2PackedControls.stVal.3 := Inverter2.PFModeCommand;
vtl_InverterData.Inverter2PackedControls.stVal.4 := Inverter2.QModeCommand;
vtl_InverterData.Inverter2PFSetpoint.oper.setMag := Inverter2.PFSetMag * 1000; // Move
significant figures left of decimal
vtl_InverterData.Inverter2PFSetpoint.oper.trigger := Inverter2.PFTrigger;
vtl_InverterData.Inverter2QSetpoint.oper.setMag := Inverter2.QSetMag;
vtl_InverterData.Inverter2QSetpoint.oper.trigger := Inverter2.QTrigger;
vtl_InverterData.Inverter2PSetpoint.oper.setMag := Inverter2.PLimitSetMag;
vtl_InverterData.Inverter2PSetpoint.oper.trigger := Inverter2.PLimitTrigger;
vtl_InverterData.Inverter2PFRampSetpoint.oper.setMag := Inverter2.PFRampSetMag;
vtl_InverterData.Inverter2PFRampSetpoint.oper.trigger := Inverter2.PFRampTrigger;
vtl_InverterData.Inverter2QRampSetpoint.oper.setMag := Inverter2.QRampSetMag;
vtl_InverterData.Inverter2QRampSetpoint.oper.trigger := Inverter2.QRampTrigger;
vtl_InverterData.Inverter2PRampSetpoint.oper.setMag := Inverter2.PLimitRampSetMag;
vtl_InverterData.Inverter2PRampSetpoint.oper.trigger := Inverter2.PLimitRampTrigger;

// Battery 1 I/O
Storage1.Offline := vtl_InverterData.IsStorage1Offline.stVal;
Storage1.RemoteEnabled :=

Date Code 20241023 Programming Reference


594 GridConnect
Examples

vtl_InverterData.IsStorage1RemoteEnabled.stVal;
Storage1.Fault :=
vtl_InverterData.IsStorage1InFaultedState.stVal;
Storage1.OnStatus := vtl_InverterData.IsStorage1On.stVal;
Storage1.PFModeEnabled := vtl_InverterData.IsStorage1InPFMode.stVal;
Storage1.QModeEnabled := vtl_InverterData.IsStorage1InQMode.stVal;
Storage1.InverterP :=
DINT_TO_REAL(vtl_InverterData.Storage1P.stVal);
Storage1.InverterQ :=
DINT_TO_REAL(vtl_InverterData.Storage1Q.stVal);
Storage1.InverterPF :=
DINT_TO_REAL(vtl_InverterData.Storage1PF.stVal)/1000;
Storage1.PFSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Storage1PFSetpointFeedback.stVal)/1000;
Storage1.QSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Storage1QSetpointFeedback.stVal);
Storage1.PLimitSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Storage1PLimitSetpointFeedback.stVal);
//NOTE: No ramp feedback available from inverters
vtl_InverterData.Storage1PackedControls.stVal.0 := Storage1.OnCommand;
vtl_InverterData.Storage1PackedControls.stVal.1 := Storage1.OffCommand;
vtl_InverterData.Storage1PackedControls.stVal.2 := Storage1.EmergencyStop;
vtl_InverterData.Storage1PackedControls.stVal.3 := Storage1.PFModeCommand;
vtl_InverterData.Storage1PackedControls.stVal.4 := Storage1.QModeCommand;
vtl_InverterData.Storage1PFSetpoint.oper.setMag := Storage1.PFSetMag * 1000; // Move
significant figures left of decimal
vtl_InverterData.Storage1PFSetpoint.oper.trigger := Storage1.PFTrigger;
vtl_InverterData.Storage1QSetpoint.oper.setMag := Storage1.QSetMag;
vtl_InverterData.Storage1QSetpoint.oper.trigger := Storage1.QTrigger;
vtl_InverterData.Storage1PSetpoint.oper.setMag := Storage1.PLimitSetMag;
vtl_InverterData.Storage1PSetpoint.oper.trigger := Storage1.PLimitTrigger;
vtl_InverterData.Storage1PFRampSetpoint.oper.setMag := Storage1.PFRampSetMag;
vtl_InverterData.Storage1PFRampSetpoint.oper.trigger := Storage1.PFRampTrigger;
vtl_InverterData.Storage1QRampSetpoint.oper.setMag := Storage1.QRampSetMag;
vtl_InverterData.Storage1QRampSetpoint.oper.trigger := Storage1.QRampTrigger;
vtl_InverterData.Storage1PRampSetpoint.oper.setMag := Storage1.PLimitRampSetMag;
vtl_InverterData.Storage1PRampSetpoint.oper.trigger := Storage1.PLimitRampTrigger;

// Battery 2 I/O
Storage2.Offline := vtl_InverterData.IsStorage2Offline.stVal;
Storage2.RemoteEnabled := vtl_InverterData.IsStorage2RemoteEnabled.stVal;
Storage2.Fault := vtl_InverterData.IsStorage2InFaultedState.stVal;
Storage2.OnStatus := vtl_InverterData.IsStorage2On.stVal;
Storage2.PFModeEnabled := vtl_InverterData.IsStorage2InPFMode.stVal;
Storage2.QModeEnabled := vtl_InverterData.IsStorage2InQMode.stVal;
Storage2.InverterP := DINT_TO_REAL(vtl_InverterData.Storage2P.stVal);
Storage2.InverterQ := DINT_TO_REAL(vtl_InverterData.Storage2Q.stVal);
Storage2.InverterPF := DINT_TO_REAL(vtl_InverterData.Storage2PF.stVal)/1000;
Storage2.PFSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Storage2PFSetpointFeedback.stVal)/1000;
Storage2.QSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Storage2QSetpointFeedback.stVal);
Storage2.PLimitSetpointFeedback :=
DINT_TO_REAL(vtl_InverterData.Storage2PLimitSetpointFeedback.stVal);
//NOTE: No ramp feedback available from inverters
vtl_InverterData.Storage2PackedControls.stVal.0 := Storage2.OnCommand;
vtl_InverterData.Storage2PackedControls.stVal.1 := Storage2.OffCommand;
vtl_InverterData.Storage2PackedControls.stVal.2 := Storage2.EmergencyStop;
vtl_InverterData.Storage2PackedControls.stVal.3 := Storage2.PFModeCommand;
vtl_InverterData.Storage2PackedControls.stVal.4 := Storage2.QModeCommand;
vtl_InverterData.Storage2PFSetpoint.oper.setMag := Storage2.PFSetMag * 1000; // Move
significant figures left of decimal
vtl_InverterData.Storage2PFSetpoint.oper.trigger := Storage2.PFTrigger;
vtl_InverterData.Storage2QSetpoint.oper.setMag := Storage2.QSetMag;
vtl_InverterData.Storage2QSetpoint.oper.trigger := Storage2.QTrigger;
vtl_InverterData.Storage2PSetpoint.oper.setMag := Storage2.PLimitSetMag;
vtl_InverterData.Storage2PSetpoint.oper.trigger := Storage2.PLimitTrigger;
vtl_InverterData.Storage2PFRampSetpoint.oper.setMag := Storage2.PFRampSetMag;
vtl_InverterData.Storage2PFRampSetpoint.oper.trigger := Storage2.PFRampTrigger;

Programming Reference Date Code 20241023


GridConnect 595
Glossary

vtl_InverterData.Storage2QRampSetpoint.oper.setMag := Storage2.QRampSetMag;
vtl_InverterData.Storage2QRampSetpoint.oper.trigger := Storage2.QRampTrigger;
vtl_InverterData.Storage2PRampSetpoint.oper.setMag := Storage2.PLimitRampSetMag;
vtl_InverterData.Storage2PRampSetpoint.oper.trigger := Storage2.PLimitRampTrigger;

// Capacitor 1 I/O
Capacitor1.Offline := vtl_CapacitorData.IsCapacitor1Offline.stVal;
Capacitor1.RemoteEnabled :=
vtl_CapacitorData.IsCapacitor1RemoteEnabled.stVal;
Capacitor1.Fault :=
vtl_CapacitorData.IsCapacitor1InFaultedState.stVal;
Capacitor1.OnStatus := vtl_CapacitorData.IsCapacitor1On.stVal;
Capacitor1.CapacitorV :=
DINT_TO_REAL(vtl_CapacitorData.Capacitor1Voltage.stVal);
vtl_CapacitorData.Capacitor1On.operPulse.ctlVal := Capacitor1.OnCommand;
vtl_CapacitorData.Capacitor1Off.operPulse.ctlVal := Capacitor1.OffCommand;

// Capacitor 2 I/O
Capacitor2.Offline := vtl_CapacitorData.IsCapacitor2Offline.stVal;
Capacitor2.RemoteEnabled :=
vtl_CapacitorData.IsCapacitor2RemoteEnabled.stVal;
Capacitor2.Fault :=
vtl_CapacitorData.IsCapacitor2InFaultedState.stVal;
Capacitor2.OnStatus := vtl_CapacitorData.IsCapacitor2On.stVal;
Capacitor2.CapacitorV :=
DINT_TO_REAL(vtl_CapacitorData.Capacitor2Voltage.stVal);
vtl_CapacitorData.Capacitor2On.operPulse.ctlVal := Capacitor2.OnCommand;
vtl_CapacitorData.Capacitor2Off.operPulse.ctlVal := Capacitor2.OffCommand;

(**** FUNCTION BLOCK EXECUTION ****)


MasterController();
Inverter1(ConnectToMasterController := MasterController.ConnectToPlantDevices);
Inverter2(ConnectToMasterController := MasterController.ConnectToPlantDevices);
Storage1(ConnectToMasterController := MasterController.ConnectToPlantDevices);
Storage2(ConnectToMasterController := MasterController.ConnectToPlantDevices);
Capacitor1(ConnectToMasterController := MasterController.ConnectToPlantDevices);

Glossary
A list of terms related to power system management.

➤ Duty Cycle: Refers to the ability of a generator to run at a stated power


level. For example, a 70-percent duty cycle may imply the asset can run
at a given value for 7 out of every 10 minutes. For the last 3 minutes in
that time period, it may need to run with no load or a reduced output.
➤ Incremental Reserve Margin: The ability of the power system or
a single generator to bring additional load online without negatively
impacting voltage or frequency. Typically used in consideration for load
acceptance during islanded operations.
➤ Island: Refers to a power system that is responsible for providing its own
voltage and frequency reference rather than relying on the reference from
external sources.
➤ Load Acceptance: The process of reviewing criteria to determine if a
load should be closed into the power system. Typically used when adding
loads in islanded operations.
➤ Spinning Reserve Margin: The amount of online generation overhead or
additional capacity a system or single generator has to run additional load
at its nominal value.

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 1 8

IPAliasRedundancy
Introduction
This library provides functionality to manage an additional IP alias (a second
IP address) added to a specified interface on an SEL Real-Time Automation
Controller (RTAC). The function blocks in this library are designed to work
in a redundancy scheme by using an IP alias to be shared between two RTAC
units. The two RTAC units will communicate with each other via the logic in
this library to decide when the IP alias should and should not be active on the
specified interface. The primary IP address for interfaces on the RTAC are still
configured via the web interface.

The two RTACs managing the IP alias communicate via an Ethernet or serial
connection. The library only supports the use of one or the other connection
type (do not use both simultaneously). If the RTACs communicate via Ethernet,
it is recommended that a separate interface than the managed interface is used
for communications. (This is not an absolute requirement—the two RTACs can
communicate via the same interface that is being managed—see Frequently
Asked Questions on page 598 for details.) Information between the two
RTACs is updated at least once a second regardless of which connection is used.

The redundancy logic operates in two modes. The first is a primary-primary


mode, in which the detection of a failover condition causes the IP alias to
activate on the inactive unit. In this mode, the previously inactive unit will
become the primary unit. If the previous primary unit becomes available again,
it will be the inactive unit and must wait for a condition to occur in which the IP
alias will become active. The second mode is a primary-backup mode, in which
the backup unit is designated on the function block. In this mode, if the primary
unit is no longer available, the backup unit will activate the IP alias. When the
primary unit is available again and reestablishes communication to the backup
unit, the IP alias on the backup unit will be deactivated and that IP alias will be
returned to the primary unit.

The function blocks in this library offer a maintenance mode in which the
unit will no longer participate in the IP alias redundancy logic. If the IP alias
is currently active on the unit when maintenance mode is activated, it will
be transferred to the other unit. Maintenance mode persists through project
settings changes and power cycles. This mode allows for configuration changes
or testing to be performed without affecting communication on the other unit
participating in the redundancy scheme.

The following conditions will cause the IP address to activate on the standby
unit:

➤ Managed Ethernet interface loss of link


➤ Loss of communication between RTACs (note that a unit with a broken
communications cable looks the same to the standby unit as a unit that
has lost power)
➤ Maintenance mode is activated

Date Code 20241023 Programming Reference


598 IPAliasRedundancy
Introduction

Frequently Asked Questions


Where do I configure the IP alias?
The IP alias is configured as an input on the function block. The IP alias cannot
be added through the web interface or any other settings mechanism. If the user
wishes to add other IP aliases for other functionality, refer to the ACSELERATOR
RTAC® SEL-5033 Instruction Manual for information about the IEC 61131
functions that manage IP aliases.

How long does the IP alias last?


The IP alias in this configuration is managed by the library. If it is detected
that both RTAC units have the alias active, one unit will deactivate its alias. IP
aliases do not last through power cycles, so when the RTAC first starts up it
will negotiate with the second RTAC about which unit should activate the IP
alias (provided it is able to communicate with the other RTAC). The IP alias will
remain through project send. If maintenance mode is activated, the IP alias will
be deactivated on the RTAC unit.

Is the interface on which the alias is being managed turned on and


off?
No, the interface with a managed IP alias will always maintain a link
connection. The Ethernet port will have more than one IP address active when
the alias is active. The IP address that is configured via the RTAC webpage will
always be active.

Can the managed IP alias interface be the same interface used to


communicate with the other RTAC unit?
Yes, the same interface can be used to both manage an IP alias and communicate
with the redundant RTAC. However, SEL recommends using a separate interface
to communicate with the redundant RTAC to increase the robustness of the
redundancy scheme.

Can the IP alias logic work with different RTAC hardware variants
such as the SEL-3530 and SEL-3555?
Yes, the interface control logic will work between any two RTACs of any
hardware combinations. This includes any combination of RTAC hardware
variants including the SEL-2240 Axion.

Why does RtacEthernetCommsGood not assert?


If you have trouble establishing the Ethernet link between the two RTACs, check
the following:

➤ Confirm both RTACs are configured in the same subnet.


➤ Confirm both RTACs are connected to the network.

Programming Reference Date Code 20241023


IPAliasRedundancy 599
Introduction

➤ Confirm IP addresses configured on the interface Control blocks.


➤ Confirm that the setting "LocalAPPort" matches the port number
in the Ethernet Listening access point that was added to the RTAC
configuration.

Why does RtacSerialCommsGood not assert?


If you have trouble establishing serial communications between two RTACs,
check the following:

➤ Confirm that the LocalSerialPort setting does not conflict with any other
configured serial ports in the RTAC configuration. If there is a conflict,
error messages are not generated as they are for other serial port conflicts.
➤ Confirm that the cable connections are secure.
➤ Confirm that the cable is wired correctly. Reference each RTAC hardware
instruction manual to ensure the pinout is correct. The connection is
designed to use RS-232. The user is not responsible for configuring any
additional parameters other than the physical serial port connections.

Why is my project unstable when I am trying to use a serial


connection?
If the LocalSerialPort setting is configured to a port number that does not exist
on the hardware being used, the RTAC will not run correctly.

Why does IPAliasActive not activate or deactivate exactly at the time


specified by the input CommStatusTimeout?
The library will detect failover conditions based on the CommStatusTimeout
input. Once the specified time-out has occurred, the library will take the actions
to activate or deactivate the IP alias. This involves reading system diagnostics
and changing IP addresses with the operating system. These actions do not
occur as quickly as contact I/O or other protocol operations. I/O and protocol
actions usually occur in hundreds of milliseconds or less. Making changes
to IP addresses on the RTAC will fluctuate between approximately one and
five seconds. System updates for IP address link status occur on a five-second
interval. For CommStatusTimeout inputs that are less than five seconds, there
will be some variation (as much as 5 seconds) in the time that the IP alias
actions occur. For CommStatusTimeout inputs that are greater than five seconds,
the variation should be less than one second in most cases. Task cycle time,
system burden, and processing power will all affect the end failover time in
small amounts. To obtain a failover time as close as possible to the specified
CommStatusTimeout value, make sure the CPU burden percentage is less than
80 percent. The failover functionality for IP address redundancy is intended for
SCADA and HMI redundancy-type applications. This library is not intended for
applications that require high-accuracy IP alias failover in less than two seconds.

Date Code 20241023 Programming Reference


600 IPAliasRedundancy
Introduction

How will other devices reach the IP alias if it is in a different


subnetwork from the primary IP alias on the controlled interface?
If the IP alias is not in the same subnetwork as the primary IP address, you
can add a static route in the RTAC web interface on the Static Routes page to
allow traffic to reach your IP alias. Refer to the ACSELERATOR RTAC SEL-5033
Instruction Manual for more information.

What happens if two RTACs, both with IPAliasActive set to TRUE,


attempt to communicate with one another?
If Backup is set to FALSE on both units, the two RTACs will negotiate which
RTAC has had IPAliasActive set to TRUE longer. This is determined by the time
stamp of when the alias last asserted in each device. The RTAC that has had
IPAliasActive = TRUE longer will retain that setting, and IPAliasActive will
be set to FALSE on the other RTAC. Inconsistent results may occur if the two
RTACs are not time-synchronized (with a minimum accuracy of one second)
with each other.

If Backup is set to TRUE on only one of the RTACs, the RTAC configured for
Backup will de-activate IPAliasActive regardless of the time the alias has been
active on either unit.

Special Considerations
➤ Copying function blocks from this library causes unwanted behavior. This
means the following:
1. The assignment operator ":=" must not be used on any function block
from this library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler


error such as:
// "C0328: Assignment not allowed for type
class_IpAliasRedundancyObject"
myIpAliasRedundancyObject := otherIpAliasRedundancyObject;

// This is fine
someVariable := myIpAliasRedundancyObject.value;
// As is this
pt_myIpAliasRedundancyObject :=
ADR(myIpAliasRedundancyObject);

2. Function blocks from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Function blocks in this library have memory allocated inside them. As
such, they should only be created in environments of permanent scope
(e.g., programs, global variable lists, or VAR_STAT sections).
➤ The two RTACs managing the IP alias can communicate with each
other through use of either an Ethernet or a serial connection. These
connections are not designed to be used simultaneously. Doing so may
cause undesired behavior.
➤ These function blocks are not supported on any network interface that is
bonded, bridged, part of a PRP pair, or where EtherCAT is enabled.

Programming Reference Date Code 20241023


IPAliasRedundancy 601
Supported Firmware Versions

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R140 or later.
Versions 3.5.0.3 and earlier can be used on RTAC firmware version R140 and
later.

Function Blocks
This library provides two function blocks. Both function blocks provide the
same redundancy functionality. The InterfaceControlWithSerialCheck function
block allows for the same redundancy configuration to be applied to two
RTACs, and the logic will identify which IP address and behavior should be
associated with which RTAC based upon the supplied RTAC serial numbers.

fb_InterfaceControl (Function Block)


This function block is designed to control the IP alias on a given interface on
the RTAC unit. It will communicate with another function block on a separate
RTAC unit to determine which RTAC unit should have the active IP alias. Each
function block must have unique parameters to ensure communications on each
project configuration.
This function block works together with an access point. When using this
function block, add an Ethernet incoming (listens for connections) access point.
The network connection type will be Raw TCP and the local port number setting
needs to match the LocalAPPort setting on the function block.

Inputs
Name IEC 61131 Type Description

ControlledInterface enum_interface_ID Interface that will be managed with ControlledIPAlias.

ControlledIPAlias STRING(18) IP address and CIDR value that will be managed on the ControlledInterface pin.

Backup BOOL If TRUE, the unit will operate in backup mode. If FALSE, the unit will operate
in primary mode.

RemoteRtacIP STRING(15) IP address of remote RTAC.

RemoteRtacPort UINT Port number of the other RTAC. This setting needs to match the LocalAPPort
setting on the remote RTAC.

LocalAPPort UINT Port number for RTAC-to-RTAC communications on the unit. This setting needs
to match the listening access point that is configured.

LocalClientConnectPort UINT Port number for the RTAC to use to create a TCP connection to the remote
RTAC (29459 by default).

LocalSerialPort SINT The communications port that will be used to communicate with the other
RTAC.

CommStatusTimeout TIME The amount of time after which the RTAC will activate the IP alias when RTAC-
to-RTAC communications is lost. This setting has a range of 500 ms to 1 hour.

EnterMaintenanceMode BOOL This pin on a rising edge will activate maintenance mode. When the unit is in
maintenance mode, it will not participate in redundancy logic.

Date Code 20241023 Programming Reference


602 IPAliasRedundancy
Function Blocks

Name IEC 61131 Type Description

ExitMaintenanceMode BOOL This pin on a rising edge will remove the unit from maintenance mode and allow
the unit to participate in managing the IP alias.

InterfaceLinkStatus SPS Connect to the system tags Ethernet link status, which shows the current value of
the managed interface.

Outputs
Name IEC 61131 Type Description

IPAliasActive BOOL This pin shows if the IP address that is assigned on "ControlledIPAlias"
is active on the RTAC unit.

MaintenanceMode BOOL This pin shows if the unit is currently in maintenance mode. If the unit
is in maintenance mode, the RTAC will not participate in redundancy
logic. Maintenance mode persists through power cycle and settings
changes on the unit. Once the unit is set to exit maintenance mode it will
participate in the redundancy scheme of the "ControlledInterfaceIP".

RtacEthernetCommsGood BOOL If both RTAC connections are communicating via the Ethernet
connection, this pin will be set to TRUE.

RtacSerialCommsGood BOOL If both RTAC connections are communicating via the serial connection,
this pin will be set to TRUE.

InvalidInputPin STRING Lists an incorrectly configured input pin.

CommunicationDataResetCounter WORD Lists the number of times internal data has been reset due to delayed
responses or corrupted received data.

fb_InterfaceControlWithSerialCheck (Function Block)


This function block is designed to control the IP alias on a given interface on
the RTAC unit. It will communicate with another function block on a separate
RTAC unit to determine which RTAC unit should have the active IP alias.
Each function block will have the exact same configuration and the logic will
associate functionality for each RTAC unit based on the serial numbers of each
RTAC unit as inputs to the logic.
This function block works together with an access point. When using this
function block, add an Ethernet incoming (listens for connections) access point.
The network connection type will be Raw TCP and the local port number setting
must match the LocalAPPort setting on the function block.

Inputs
Name IEC 61131 Type Description

ControlledInterface enum_interface_ID Interface that will be managed with ControlledIPAlias.

ControlledIPAlias String(18) IP address and CIDR value that will be managed on the Controlled_Interface
pin.

SerialNumber String(80) The serial number of the unit on which redundancy logic will operate.

Backup BOOL If TRUE, the unit will operate in backup mode. If FALSE, the unit will
operate in primary mode.

RemoteRtacIP STRING(15) IP address of remote RTAC.

Programming Reference Date Code 20241023


IPAliasRedundancy 603
Examples

Name IEC 61131 Type Description

RemoteRtacPort UINT Port number of the remote RTAC. This setting must match the LocalAPPort
setting on the remote RTAC.

LocalAPPort UINT Port number for RTAC-to-RTAC communications on the unit. This setting
needs to match the listening access point that is configured.

LocalClientConnectPort UINT Port number for the RTAC to use to create a TCP connection to the remote
RTAC (23459 by default).

LocalSerialPort SINT Communications port that will be used to communicate with the other RTAC.

CommStatusTimeout TIME Time without remote RTAC communications or link status before activating
IP alias. Range of 500 ms to 1 hour. Default is 5 seconds.

EnterMaintenanceMode BOOL A rising edge will activate maintenance mode.

ExitMaintenanceMode BOOL A rising edge will remove the unit from maintenance mode.

InterfaceLinkStatus SPS Connect to the system tags Ethernet link status, which shows the current value
of the managed interface.

Outputs
Name IEC 61131 Type Description

IPAliasActive BOOL This pin shows if the IP address that is assigned on "ControlledIPAlias"
is active on the RTAC unit.

MaintenanceMode BOOL This pin shows if the unit is currently in maintenance mode. If the unit
is in maintenance mode, the RTAC will not participate in redundancy
logic. Maintenance mode persists through power cycle and settings
change on the unit. Once the unit is set to exit maintenance mode, it will
participate in the redundancy scheme of the "ControlledInterfaceIP".

RtacEthernetCommsGood BOOL If both RTAC connections are communicating via the Ethernet
connection, this pin will be set to TRUE.

RtacSerialCommsGood BOOL If both RTAC connections are communicating via the serial connection,
this pin will be set to TRUE.

SerialNumberMismatch BOOL If the assigned and actual serial numbers do not match, this pin will be
TRUE. Redundancy logic will only function if this value is FALSE.

ProjectIDMismatch BOOL If the project IDs between the two RTAC units do not match, this output
will be TRUE. The value of this pin is retained through power cycles
and will only compare if Ethernet or serial communication is active
between the two RTAC units.

InvalidInputPin STRING Lists an incorrectly configured input pin.

CommunicationDataResetCounter WORD Lists the number of times internal data has been reset due to delayed
responses or corrupted received data.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Date Code 20241023 Programming Reference


604 IPAliasRedundancy
Examples

Using Interface Control to Manage an IP Alias


Objective
A user would like to use a single IP address between two RTACs for a client to
seamlessly communicate with redundant data concentrators. This example will
demonstrate how to configure two RTACs to share one IP address.

Assumptions
This example assumes the following:
➤ The IP alias and its associated subnet do not overlap with any other
configured subnets on any Ethernet interface or other IP aliases.
➤ The client will communicate with the RTAC on Ethernet Port 2.
➤ Both RTACs will communicate with each other on Ethernet Port 1.
➤ Both RTACs have IP addresses in the same subnet on Ethernet Port 1.
➤ Ethernet Port 1 on each RTAC will be connected directly to the other
RTAC or through a switch.
➤ Each RTAC configuration includes an Ethernet Listening, Raw TCP
access point that matches the LocalAPPort setting on the interface control
function block.
➤ Each RTAC collects data from the other RTAC through serial ports or an
Ethernet port.
➤ Any supported server protocol can be used to send data to the client via
the IP alias.
➤ If a serial connection is used, an RS-232 compatible cable that matches
the wiring diagram according to each connected serial port (as listed in
the specific RTAC hardware instruction manual) is used.

Solution
RTAC Project 1
The user creates an Ethernet listening access point as shown in Figure 18.1.

Figure 18.1 Ethernet Listening Access Point

The user creates a program as shown in Code Snippet 18.1:


Code Snippet 18.1 prg_InterfaceControlRTAC1
PROGRAM prg_InterfaceControlRTAC1
VAR
Port1Control : fb_InterfaceControl;
END_VAR

Port1Control(
ControlledInterface := Eth_02,
ControlledIPAlias := '10.55.55.55/24',
Backup := FALSE,

Programming Reference Date Code 20241023


IPAliasRedundancy 605
Examples

RemoteRtacIP := '192.168.25.8',
RemoteRTACPort := 3000,
LocalAPPort := 7500,
LocalClientConnectPort := 8788,
LocalSerialPort := 1,
CommStatusTimeout := T#5S,
InterfaceLinkStatus := SystemTags.Eth_02_Link
);

Figure 18.2 presents the same logic as Code Snippet 18.1 shown in CFC rather
than an ST program.

Figure 18.2 Interface Control in CFC

RTAC Project 2
The user creates an Ethernet listening access point as shown in Figure 18.3.

Figure 18.3 Ethernet Listening Access Point

The user creates a program as shown in Code Snippet 18.2:


Code Snippet 18.2 prg_InterfaceControlRTAC2
PROGRAM prg_InterfaceControlRTAC2
VAR
Port1Control : fb_InterfaceControl;
END_VAR

Port1Control(
ControlledInterface := Eth_02,
ControlledIPAlias := '10.55.55.55/24',
Backup := FALSE,
RemoteRtacIP := '192.168.25.7',
RemoteRTACPort := 7500,

Date Code 20241023 Programming Reference


606 IPAliasRedundancy
Examples

LocalAPPort := 3000,
LocalClientConnectPort := 8788,
LocalSerialPort := 1,
CommStatusTimeout := T#5S,
InterfaceLinkStatus := SystemTags.Eth_02_Link
);

Figure 18.2 presents the same logic as Code Snippet 18.2 shown in CFC rather
than an ST program.

Figure 18.4 Interface Control in CFC

Using Interface Control With the Same Configuration on Two RTACs


Objective
A user would like to use the exact same RTAC configuration on two
RTAC units to provide redundancy. This example shows how to use
InterfaceControlWithSerialCheck, which includes additional functionality to
verify the serial number of the RTAC that the logic executes on and to verify
that the ProjectID matches between the two RTACs. Even though two function
blocks are defined in the RTAC project, only one function block will manage the
IP alias (provided that the configured serial number matches the serial number
of the RTAC unit).

This example also provides the same functionality as the previous example for
managing an IP alias.

Assumptions
This example assumes the following:

➤ The IP alias and its associated subnet mask do not overlap with any other
configured subnets on any Ethernet interface or other IP aliases.
➤ The client will communicate with the RTAC on Ethernet Port 2.
➤ Both RTACs will communicate with each other on Ethernet Port 1.

Programming Reference Date Code 20241023


IPAliasRedundancy 607
Examples

➤ Both RTACs have IP addresses in the same subnet on Ethernet Port 1.


➤ Ethernet port 1 on each RTAC will be connected directly to the other
RTAC or through a switch.
➤ Each RTAC configuration includes an Ethernet Listening of Raw TCP
access point that matches the LocalAPPort setting on the interface control
function block.
➤ Each RTAC collects data from the other RTAC through serial ports or an
Ethernet port.
➤ Any supported server protocol can be used to send data to the client via
the IP alias.
➤ If a serial connection is used, then an RS-232 compatible cable that
matches the wiring diagram according to each connected serial port (as
listed in the specific RTAC hardware instruction manual) is used.

Solution
In each RTAC configuration, create one access point of type Ethernet incoming
listening that matches the settings of the LocalAPPort setting on each function
block.

Figure 18.5 Ethernet Listening Access Point for PortControlRTAC1

Figure 18.6 Ethernet Listening Access Point for PortControlRTAC2

The user creates a program as shown in Code Snippet 18.3:


Code Snippet 18.3 prg_InterfaceControlWithSerialCheck
PROGRAM prg_InterfaceControlWithSerialCheck
VAR
PortControlRTAC1 : fb_InterfaceControlWithSerialCheck;
PortControlRTAC2 : fb_InterfaceControlWithSerialCheck;
END_VAR

PortControlRTAC1(
ControlledInterface := Eth_02,
ControlledIPAlias := '10.55.55.55/24',
SerialNumber := '1122440328',
Backup := FALSE,
RemoteRtacIP := '192.168.25.8',
RemoteRTACPort := 3000,
LocalAPPort := 7500,
LocalClientConnectPort := 8788,
LocalSerialPort := 1,
CommStatusTimeout := T#5S,
InterfaceLinkStatus := SystemTags.Eth_02_Link
);

Date Code 20241023 Programming Reference


608 IPAliasRedundancy
Examples

PortControlRTAC2(
ControlledInterface := Eth_02,
ControlledIPAlias := '10.55.55.55/24',
SerialNumber := '1122680283',
Backup := FALSE,
RemoteRtacIP := '192.168.25.7',
RemoteRTACPort := 7500,
LocalAPPort := 3000,
LocalClientConnectPort := 8788,
LocalSerialPort := 1,
CommStatusTimeout := T#5S,
InterfaceLinkStatus := SystemTags.Eth_02_Link
);

Figure 18.7 presents the same logic as Code Snippet 18.3 shown in CFC rather
than an ST program.

Figure 18.7 InterfaceControlWithSerialCheck in CFC

Programming Reference Date Code 20241023


S E C T I O N 1 9

JSON_Utilities_SL
Introduction
The JSON_Utilities_SL library provides mechanisms to generate and parse
JSON (JavaScript Object Notation) data structures from any structure whose
characters are accessible by byte-wise operations (example structures include
Dynamic Vectors, STRINGs, and arrays of BYTEs). The JSON standard is fully
described at json.org.

Implementation Note
This library is provided as a member of the CODESYS® IIoT package as a
special offering available in the SEL RTAC. The functionality provided by this
resource is generally intended to operate in generic CODESYS® environments.
As such, some limitations may be encountered when implementing these
resources in the SEL RTAC. Any POUs or POU inputs that may be subject to
these limitations are marked accordingly in this document.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R151 or later.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_diMaxElements DINT 4096 Maximum number of JSON elements.

g_diMaxStringSize DINT 255 Maximum size of STRINGs (in bytes). Note: The allocated memory of the
JSONData object will be greater than g_diMaxStringSize * g_diMaxElements
bytes! Keep this value as small as possible.

g_diMaxFileSize DINT 32000 Maximum file size.

g_diMaxDepth DINT 50 Maximum object depth.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
Enumerations defined in this, the JSON Utilities SL library, provide control of
the various JSON parser/serializer mechanisms.

Date Code 20241023 Programming Reference


610 JSON_Utilities_SL
Enumerations

ERROR
Enumeration Description

NO_ERROR No error.

INDEX_OUT_OF_BOUNDS Array index was out of bounds.

NOT_FOUND The requested element cannot be found.

NULL_POINTER Null pointer.

MAX_STRING_SIZE_EXCEEDED Max size of Strings exceeded.

READ_ERROR Read error.

INVALID_HANDLE Invalid file handle.

FILE_OPEN_ERROR File open error.

INVALID_ENCODING Invalid encoding.

WRITE_ERROR Write error.

UNKNOWN_JSON_TYPE Unknown JSON type.

MAX_FILE_SIZE_EXCEEDED Max size of file exceeded.

INVALID_DECIMAL_PLACE Decimal place is < 0.

MAX_OBJECT_DEPTH_EXCEEDED Maximum object depth g_diMaxDepth


exceeded.

INVALID_KEY_PARENT Parent of a key must be an object.

INVALID_VALUE_PARENT Parent of a value must be an array or a key.

INVALID_LICENSE RTAC firmware does not adequately provide


IIoT information.

INVALID_STRUCTURE Invalid JSON structure.

Encoding
Enumeration Description

UTF_8 UTF-8 encoding.

UTF_16 UTF-16 encoding.

JSONType
Enumeration Description

KEY The element is a key which is stored as WSTRING.

WSTRING_VALUE Element is a WSTRING value.

LINT_VALUE Element is a LINT value.

LREAL_VALUE Element is a LREAL value.

BOOL_VALUE Element is a BOOL value.

NULL Element is NULL.

Programming Reference Date Code 20241023


JSON_Utilities_SL 611
Structures

Enumeration Description

JSON_ARRAY Element is an array.

JSON_OBJECT Element is an object.

NONE NO JSON type.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Structures defined in this, the JSON Utilities SL library, are positioned to be


provide functional access to JSON data.

JSONElement
Name IEC 61131 Type Description

value JSONValue Value of the element.

eType JSONType Type of the value.

diIndex DINT Index of this element in the data array.

diParentIndex DINT Index of the parent JSONElement, –1 for top-level


elements.

Unions
Unions provide a means to interchange datatypes sharing the same memory
space to facilitate accessing data commonalities in a functional manner.

Unions defined in this, the JSON Utilities SL library, are positioned to be


provide functional access to JSON data.

JSONElement
Name IEC 61131 Type Description

wsValue WSTRING(GParams.g_diMaxStringSize) Value as WSTRING.

xValue BOOL Value as BOOL.

lrValue LREAL Value as LREAL.

liValue LINT Value as LINT.

Functions
JSONElementToString (Function)
Converts a JSON element to WSTRING.

Date Code 20241023 Programming Reference


612 JSON_Utilities_SL
Interfaces

Inputs
Name IEC 61131 Type Description

element JSONElement The element to convert.

wsResult WSTRING(GParams.g_diMaxStringSize) The string representation of an


element.

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

Interfaces
This library provides the following interfaces.

IJSONData
Interface for JSONData.

Clear (Method)
Clears the underlying data array.

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

FindAllElementsByKey (Method)
Find all elements by key.

Inputs

Name IEC 61131 Type Description

wsKey WSTRING(GParams.g_diMaxStringSize) The key to search.

diStartIndex DINT Index of the array to start the


search.

pResult POINTER TO JSONElement Pointer to the result array.

udiMaxSize UDINT Maximum size of pResult.

Programming Reference Date Code 20241023


JSON_Utilities_SL 613
Interfaces

Outputs

Name IEC 61131 Type Description

udiResultSize UDINT The size of the result array.

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

FindFirstElementByKey (Method)
Find the first element in the data array by key.

Inputs

Name IEC 61131 Type Description

wsKey WSTRING(GParams.g_diMaxStringSize) The key to search.

diStartIndex DINT Index of the array to start the


search.

Outputs

Name IEC 61131 Type Description

jsonElement JSONElement The first element in the array with the requested
key.

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

FindFirstValueByKey (Method)
Find the first value of the requested key.

Inputs

Name IEC 61131 Type Description

wsKey WSTRING(GParams.g_diMaxStringSize) The key to search.

diStartIndex DINT Index of the array to start the


search.

Date Code 20241023 Programming Reference


614 JSON_Utilities_SL
Interfaces

Outputs
Name IEC 61131 Type Description

jsonElement JSONElement The first element in the array with the requested
key.

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

GetChildren (Method)
Get all children of an element.

Inputs
Name IEC 61131 Type Description

diIndex UDINT Index of the parent element.

pResult POINTER TO JSONElement Children of the parent element index.

udiMaxSize UDINT Maximum number of children.

Outputs
Name IEC 61131 Type Description

udiResultSize UDINT The size of the result array.

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

GetElementByIndex (Method)
Get an element by index.

Inputs
Name IEC 61131 Type Description

diIndex UDINT Index of the element.

Outputs
Name IEC 61131 Type Description

jsonElement JSONElement The element with the requested index.

Programming Reference Date Code 20241023


JSON_Utilities_SL 615
Interfaces

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

SetArray (Method)
Method to set an object.

Inputs

Name IEC 61131 Type Description

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

SetBool (Method)
Method to set BOOL values.

Inputs

Name IEC 61131 Type Description

bValue BOOL Value to be set.

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

SetKey (Method)
Method to set a key.

Date Code 20241023 Programming Reference


616 JSON_Utilities_SL
Interfaces

Inputs

Name IEC 61131 Type Description

wsKey WSTRING(GParams.g_diMaxStringSize) Value to be set.

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

SetLReal (Method)
Method to set LREAL values.

Inputs

Name IEC 61131 Type Description

lrValue LREAL Value to be set.

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Return Value

IEC 61131 Type Description

ERROR Resulting status of operation.

SetLRealRounded (Method)
Method to set rounded LREAL values. Rounding mode: Round halfway from
zero.

Inputs

Name IEC 61131 Type Description

lrValue LREAL Value to be set.

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

iDecimalPlaces INT Number of decimal places.

Programming Reference Date Code 20241023


JSON_Utilities_SL 617
Interfaces

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

SetLint (Method)
Method to set LINT values.

Inputs
Name IEC 61131 Type Description

liValue LREAL Value to be set.

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

SetNull (Method)
Method to set NULL values.

Inputs
Name IEC 61131 Type Description

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

SetObject (Method)
Method to set an object.

Inputs
Name IEC 61131 Type Description

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Date Code 20241023 Programming Reference


618 JSON_Utilities_SL
Function Blocks

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

SetString (Method)
Method to set WSTRING values.

Inputs
Name IEC 61131 Type Description

wsValue WSTRING(GParams.g_diMaxStringSize) Value to be set.

diIndex DINT Index of the element.

diParentIndex DINT Parent index, –1 if top level.

Return Value
IEC 61131 Type Description

ERROR Resulting status of operation.

Function Blocks
The JSON Utilities SL library provides various function block to construct and
parse data into respective structures.

JSONData (Function Block)


This function block contains the JSON data and provides methods to access and
set data.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ IJSONData

JSONFileReader (Function Block)


This functionality is not presently supported on the RTAC.

JSONFileWriter (Function Block)


This functionality is not presently supported on the RTAC.

Programming Reference Date Code 20241023


JSON_Utilities_SL 619
Function Blocks

JSONByteArrayReader (Function Block)


Function block for reading of JSON data arrays.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
JSONByteArrayReader.

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Action starts.

Falling edge: Resets outputs.

If a falling edge occurs before the function block has completed its
action, the outputs operate in the usual manner and are only reset if
either the action is completed or in the event of an error. In this case, the
corresponding output values (xDone, xError) are present at the outputs for
exactly one cycle.

pwData POINTER TO WORD Pointer to the data array with JSON data.

xIgnoreValueStringLength BOOL If True, the error is ignored and the value is shortened and xValueTrunked
will be TRUE.

Inputs/Outputs
Name IEC 61131 Type Description

jsonData JSONDataInternal JSONData object.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

xValueTruncated BOOL Minimum one String value was >


GParams.g_diMaxStringSize.

JSONByteArrayWriter (Function Block)


Function block for writing of JSON data arrays.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
JSONByteArrayWriter.

Date Code 20241023 Programming Reference


620 JSON_Utilities_SL
Function Blocks

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Action starts.

Falling edge: Resets outputs.

If a falling edge occurs before the function block has completed its action, the outputs
operate in the usual manner and are only reset if either the action is completed or in the
event of an error. In this case, the corresponding output values (xDone, xError) are present
at the outputs for exactly one cycle.

pwData POINTER TO WORD Pointer to the target array.

udiSize UDINT Size of target array.

Inputs/Outputs
Name IEC 61131 Type Description

jsonData JSONDataInternal JSONData object.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

FindFirstValueByKey (Function Block)


Finds the corresponding value of a key.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
JSONByteArrayWriter.

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Action starts.

Falling edge: Resets outputs.

If a falling edge occurs before the function block has completed its action, the outputs operate
in the usual manner and are only reset if either the action is completed or in the event of an
error. In this case, the corresponding output values (xDone, xError) are present at the outputs
for exactly one cycle.

wsKey WSTRING The key to search.

diStartIndex DINT Start index.

Programming Reference Date Code 20241023


JSON_Utilities_SL 621
Classes

Inputs/Outputs
Name IEC 61131 Type Description

jsonData JSONDataInternal JSONData object.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

jsonElement BOOL The corresponding value of the key.

eError ERROR Output error.

Classes
The JSON Utilities SL library provides the following classes.

JSONData (Class)
This class contains the JSON data and provides methods to access and set data.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ IJSONData

JSONBuilder (Class)
Class to support constructing a JSON structure.

Class Inputs and Outputs


Inputs/Outputs
Name IEC 61131 Type Description

pJsonData POINTER TO JSONData Pointer to the JSON data.

Outputs
Name IEC 61131 Type Description

diRootObj DINT Root of the JSON structure.

Date Code 20241023 Programming Reference


622 JSON_Utilities_SL
Classes

SetKey (Method)
Method to set key in a JSON data.

Inputs
Name IEC 61131 Type Description

wsKey WSTRING Key to be set.

diParentIndex DINT Index of parent for the new key.

Return Value
IEC 61131 Type Description

DINT Size of key added.

SetKeyWithArray (Method)
Method to set key with an array in a JSON data.

Inputs
Name IEC 61131 Type Description

wsKey WSTRING Key to be set.

diParentIndex DINT Index of parent for the new key.

Return Value
IEC 61131 Type Description

DINT Size of key added.

SetKeyWithObject (Method)
Method to set key and object in a JSON data.

Inputs
Name IEC 61131 Type Description

wsKey WSTRING Key to be set.

diParentIndex DINT Index of parent for the new key.

Return Value
IEC 61131 Type Description

DINT Size of key added.

Programming Reference Date Code 20241023


JSON_Utilities_SL 623
Classes

SetKeyWithValue (Method)
Method to set key and value in a JSON data.

Inputs
Name IEC 61131 Type Description

wsKey WSTRING Key to be set.

Value __SYSTEM.AnyType Value to be set.

diParentIndex DINT Index of parent for the new key.

Return Value
IEC 61131 Type Description

DINT Size of key added.

SetKeyWithValueNull (Method)
Method to set key and null value in a JSON data.

Inputs
Name IEC 61131 Type Description

wsKey WSTRING Key to be set.

diParentIndex DINT Index of parent for the new key.

Return Value
IEC 61131 Type Description

DINT Size of key added.

SetObject (Method)
Method to set an object value in a JSON data.

Inputs
Name IEC 61131 Type Description

diParentIndex DINT Index of parent for the new key.

Return Value
IEC 61131 Type Description

DINT Size of key added.

Date Code 20241023 Programming Reference


624 JSON_Utilities_SL
Examples

SetKeyWithValue (Method)
Method to set value in a JSON data.

Inputs
Name IEC 61131 Type Description

Value __SYSTEM.AnyType Value to be set.

diParentIndex DINT Index of parent for the new key.

Return Value
IEC 61131 Type Description

DINT Size of key added.

JSONDataFactory (Class)
Factory with a heap based extendable memory pool.

Class Inputs and Outputs


Inputs
Name IEC 61131 Type Description

uxiInstCount CAA.COUNT Factor for the size of the initial memory pool of JSONData objects. Should be equal to
the maximum number of created JSONData objects. Set to 1 and use a single instance of
JSONData to reduce memory usage.

Create (Method)
Method to create an instance of the function block JSONData.

Outputs
Name IEC 61131 Type Description

eError FBF.ERROR Output error.

Return Value
IEC 61131 Type Description

POINTER TO JSONDataInternal Pointer to the generated JSONData function block.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Programming Reference Date Code 20241023


JSON_Utilities_SL 625
Examples

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Extracting the Value Associated With a Key (ST)


Objective
You want to parse a JSON structure from a STRING(255), and you want to
extract the strings representing keys in the outermost MAP of the structure.

Assumptions
This example assumes that a JSON data structure defined by the user is to be
parsed. This JSON structure is to be defined as follows, with three keys in the
outermost MAP of the structure.

1 {
2 "fid": "SEL-3530-R146-V0-Z000002-D20200224",
3 "licensed features": {
4 "features": [
5 {"hmi": true},
6 {"library": "fileio"}
7 ]
8 },
9 "device name": "SEL-RTAC"
10 }

Solution
In order to appropriately extract the keys from this JSON structure, the string
must first be parsed, and because the exact number of key-strings in the JSON
structure is known, the keys can be loaded into an array of STRING(255)s with
that exact number of elements. Note, however, this is not an advisable operation
when the number of keys is either unknown or could change.
Code Snippet 19.1 prg_ExtractingValueAssociatedWithKey
PROGRAM prg_ExtractingValueAssociatedWithKey
VAR CONSTANT
// Define JSON as a string, note that linewrapping is acceptable.
c_JsonString : WSTRING(1024) := "{$"fid$":
$"SEL-3530-R146-V0-Z000002-D20200224$",$"licensed features$": {
$"features$": [{$"hmi$": true}, {$"library$": $"fileio$"}]},
$"device name$": $"SEL-RTAC$"}";
END_VAR
VAR
// Parser object which will interpret serialized JSON
reader : JSON.JSONByteArrayReader;
// Storage object which will manage all JSON elements
jsonDataStorage : JSON.JSONData;
// Single JSON element where the value will be extracted
jsonElement : JSON.JSONElement;

// The resulting string


valueWstring : WSTRING( JSON.GParams.g_diMaxStringSize );

execute : BOOL := TRUE;


END_VAR

Date Code 20241023 Programming Reference


626 JSON_Utilities_SL
Examples

// Run the reader


reader (
xExecute := execute ,
pwData := ADR ( c_JsonString ),
jsonData := jsonDataStorage
);

IF execute AND reader.xDone THEN


// Stop after the first scan
execute := FALSE ;
END_IF

IF reader . xDone THEN


// Get the JSON Element
jsonDataStorage.FindFirstValueByKey (
wsKey := "fid",
diStartIndex := 0,
jsonElement => jsonElement
);

// Convert the JSON Element to a Meaningful String


JSON.JSONElementToString (
element := JsonElement ,
wsResult := valueWstring
);
// valueWstring now contains:
// SEL-3530-R146-V0-Z000002-D20200224
END_IF

Programming Reference Date Code 20241023


S E C T I O N 2 0

MQTT_Client_SL
Introduction
The MQTT_Client_SL library provides mechanisms to publish and subscribe to
topics managed by an external MQTT broker.

Implementation Note
This library is provided as a member of the CODESYS® IIoT package as a
special offering available in the SEL RTAC. The functionality provided by this
resource is generally intended to operate in generic CODESYS® environments.
As such, some limitations may be encountered when implementing these
resources in the SEL RTAC. Any POUs or POU inputs that may be subject to
these limitations are marked accordingly in this document.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R151 or later.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_uiMaxTopicLevel UINT 10 The maximal count of levels per topic.

g_udiMaxQueuedPackets UDINT 1000 The maximal count of queued packets that are
possible to store.

g_udiMaxPacketSize UDINT 6000 Maximum size of an MQTT packet byte array,


MUST be smaller than 256 MB.

g_udiMaxPayloadSize UDINT 4096 Maximum size of an MQTT payload byte array,


MUST be less than max. Packet Size.

g_udiMaxPublishersAndSubscribers UDINT 20 Maximum number of publishers + subscribers.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Date Code 20241023 Programming Reference


628 MQTT_Client_SL
Enumerations

Enumerations defined in this, the MQTT Client library, are positioned to be


accessed by various external libraries in order to reduce redundant enumeration
descriptions.

COMMUNICATION_MODE
Enumeration Description

TCP Standard TCP/IP communication.

WEB_SOCKET TCP/IP communication via WebSocket (MQTT over WebSocket).

FILTER_MODE
Enumeration Description

FILTER_ON Filters the telegrams by topics.

FILTER_OFF Turns the filter off and receives ALL subscribed telegrams.

FILTER_NONE Receives no telegrams. In this mode you can only subscribe or


unsubscribe topics.

MQTT_ERROR
Enumeration Description

NO_ERROR No error.

TCP_INIT_ERROR Unable to initialize the TCP socket.

TCP_READ_ERROR Error while reading response.

TCP_WRITE_ERROR Error while sending the request.

MAX_RESPONSE_SIZE_EXCEEDED Size of incoming packet exceeds the maximum packet size.

DECODE_REMAINING_LENGTH_MALFORMED Malformation during Decoding of Remaining Length of Packet.

RESPONSE_PACKET_EMPTY The Response Packet is empty.

INVALID_PACKET_TYPE Invalid Packet Type in first byte of Fixed Header.

INVALID_PACKET_BIT_FLAGS Invalid Packet Bit Flags in first byte of Fixed Header.

INVALID_PACKET Invalid Packet.

KEEP_ALIVE_TIME_EXCEEDED Keep Alive Time is too much.

WRONG_SESSION_PRESENT_CONNACK Wrong Session Present in CONNACK packet.

UNACCEPTABLE_PROTOCOL_VERION Connection to Broker is Refused, because of Unacceptable Protocol


Version.

IDENTIFIER_REJECTED Connection to Broker is Refused, because of Rejection of Client Identifier.

SERVER_UNAVAILABLE Connection to Broker is Refused, because the Server Broker is not


available.

BAD_USER_NAME_PASSWORD Connection to Broker is Refused, because of Bad Username or Bad


Password.

NOT_AUTHORIZED Connection to Broker is Refused, because of Not Authorized access.

Programming Reference Date Code 20241023


MQTT_Client_SL 629
Functions

Enumeration Description

TOPIC_FILTER_EMPTY Topic Filter is empty (e.g., "removeme"), MUST be at least one character
long.

TOPIC_NAME_NOT_ALLOWED_WILDCARD Topic Name contains Wildcards, which is not allowed. Only Topic Filter
can contain these.

TOPIC_INVALID_LENGTH Topic Length out of valid range.

TOPIC_IS_EMPTY Topic name is empty.

SUBSCRIBE_FAILURE Subscription Failure.

ADD_MQTT_PACKET_COLLECTION_ERROR Collection Error while trying to add an MQTT packet to the stack.

ADD_SUBSCRIBER_COLLECTION_ERROR Collection Error while trying to add a subscriber to the stack.

REMOVE_SUBSCRIBER_COLLECTION_ERROR Collection Error while trying to remove a subscriber from the stack.

ACKNOWLEDGE_TIMEOUT Client waits for ping response from Server, but Server does not response
within a given time interval (2 * ping interval).

ALLOCATED_PAYLOAD_SIZE_EXCEEDED The Size of the received payload is more than given allocated memory.

MAX_NUMBER_OF_PACKETS_EXCEEDED The maximum size of packets has been exceeded.

CAN_NOT_ADD_ELEMENT_TO_QUEUE Cannot add the element to queue (maybe the maximum size has been
exceeded).

QUERYINTERFACE_ERROR Call of function __QUERYINTERFACE failed (internal error).

TIME_OUT Action returned with timeout error.

INVALID_LICENSE RTAC firmware does not adequately provide IIoT information.

CLIENT_NOT_CONNECTED The MQTT client is not connected to a broker.

RESOLVE_HOSTNAME_FAILED The hostname cannot be resolved.

MAX_REQUEST_SIZE_EXCEEDED Size of publish packet exceeds the maximum packet size.

MQTT_QOS
Enumeration Description

QoS0 Send Message 1x, if disconnected from server then send can fail.

QoS1 Send Message Nx, until Receive is acknowledged.

QoS2 Send Message 1x, if disconnected from server then send is always
successfully.

Functions
This library provides functions to perform UTF conversions, intended to allow
converting of UTF16 to UTF8 and vice-versa.

ConvertUTF16toUTF8 (Function)
This function converts a WSTRING (UTF16) to a STRING (UTF8).

Date Code 20241023 Programming Reference


630 MQTT_Client_SL
Classes

Inputs
Name IEC 61131 Type Description

sourceStart POINTER TO WORD Pointer to WSTRING.

targetStart POINTER TO BYTE Pointer to STRING.

dwTargetBufferSize DWORD Size of STRING.

bStrictConversion BOOL Require strict conversion technique.

Return Value
IEC 61131 Type Description

UDINT Number of WORD characters converted.

ConvertUTF8toUTF16 (Function)
This function converts a STRING (UTF8) to a WSTRING (UTF16).

Inputs
Name IEC 61131 Type Description

sourceStart POINTER TO BYTE Pointer to STRING.

targetStart POINTER TO WORD Pointer to WSTRING.

dwTargetBufferSize DWORD Size of WSTRING.

bStrictConversion BOOL Require strict conversion technique.

Return Value
IEC 61131 Type Description

UDINT Number of BYTE characters converted.

Classes
The MQTT Client SL library provides classes designed to be implemented to
provide a connection to the respective MQTT broker.

MQTTClient (Class)
Function block to connect with an MQTT broker.

Class Inputs and Outputs


The following tables describe the inputs and outputs associated with
MQTTClient.

Programming Reference Date Code 20241023


MQTT_Client_SL 631
Classes

Inputs

Name IEC 61131 Type Description

xEnable BOOL TRUE: Activates the defined operation.


FALSE: Aborts/resets the defined operation.

uiPort UINT Port of MQTT Broker Server.

xUseTLS BOOL TRUE: Encrypted Connection.


FALSE: Unencrypted Connection.

uiKeepAlive UINT Keep Alive Time in Seconds (optional).

pbWillMessage POINTER TO BYTE Pointer to the "Last Will" message (optional).

uiWillMessageSize UINT Size of "Last Will" message (optional).

xWillRetain BOOL TRUE: Saves the "Last Will" message on server. If Client subscribes later,
then it receives the last stack message from server.

eWillQoS MQTT_QOS QoS Level of "Last Will" message.

xCleanSession BOOL TRUE: Creates a new session.


FALSE: Uses already existing session if available.

wsUsername WSTRING(255) Username (optional).

wsPassword WSTRING(1024) User Password (optional).

wsWillTopic WSTRING(1024) Will Topic (optional).

sClientId STRING(255) Client ID, if empty then new ID is generated, allowed are only
these characters 0123456789abcdefghijklmnopqrstuvwxyz
ABCDEFGHIJKLMNOPQRSTUVWXYZ (optional).

tPingInterval TIME Interval time in seconds how often should be pinged, if Time <= 0 then no
pings.

hCert RTS_IEC_HANDLE Handle to the client certificate (optional).

itfTLSContext NBS.ITLSContext Encapsulates all the data necessary to handle encrypted TCP connections.

itfAsyncProperty NBS.IAsyncProperty Runs the connect process in its own background task. Use this property if the
connection setup takes longer than one task cycle (e.g., TLS connections)

udiTimeOut UDINT Defines the time (µs) after which the connection setup aborts with xError.

eCommunicationMode COMMUNICATION_MODE Communication mode: TCP or WEB_SOCKET; default: TCP.

COMMUNICATION_MODE.TCP: Configure the connection via the inputs:


sHostname, uiPort and itfTLSContext.

COMMUNICATION_MODE.WEB_SOCKET: Configure the connection


via the inputs sWebSocketUrl and itfTLSContext Additional Web- Socket
options can be set via the method SetWebSocketOptions.

sWebSocketUrl REFERENCE TO The uri of the websocket server (e.g., "ws://localhost:8080") ws-
STRING(1024) URI = ws:" //" host [ ":" port ] path [ "?" query ] wss-URI = wss:" //"
host [ ":" port ] path [ "?" query ]. The input is only relevant for
eCommunicationMode = COMMUNICATION_- MODE.WEB_SOCKET.

Inputs/Outputs

Name IEC 61131 Type Description

sHostname STRING(80) Host name of Broker MQTT Server (is IPAddress).

Date Code 20241023 Programming Reference


632 MQTT_Client_SL
Function Blocks

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eMQTTError MQTT_ERROR MQTT Error Type.

xConnectedToBroker BOOL FALSE when there is no Connection to


MQTT Broker Server, otherwise TRUE.

SetWebSocketOptions (Method)
Method to set additional websocket options if eCommunicationMode =
COMMUNICATION_ MODE.WEB_SOCKET.

Inputs
Name IEC 61131 Type Description

tPingInterval TIME Ping interval, T#0s: no ping.

httpProxySettings WEB_SOCKET.HttpProxySettings Optional HTTP proxy settings.

Return Value
IEC 61131 Type Description

BOOL Web socket options were set successfully.

Function Blocks
The MQTT Client SL library provides function blocks designed to be
implemented to provide unique subscription and publisher functionality.

MQTTPublish (Function Block)


Function block to publish (send) messages to an MQTT broker.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
MQTTPublish.

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Publish message.

udiTimeOut UDINT Timeout in microseconds, default: 10s.

Programming Reference Date Code 20241023


MQTT_Client_SL 633
Function Blocks

Name IEC 61131 Type Description

eQoS MQTT_QOS QoS Level of message.

xReDelivery BOOL TRUE: When packet got already send and now
should got resend.
FALSE: First time.

xRetain BOOL TRUE: Stores the message on server.

pbPayload POINTER TO BYTE Pointer to the message.

udiPayloadSize UDINT Size of message.

Inputs/Outputs
Name IEC 61131 Type Description

mqttClient MQTTClient Function block MQTTClient.

wsTopicName WSTRING(1024) Topic Name of message.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eMQTTError MQTT_ERROR MQTT Error Type.

MQTTSubscribe (Function Block)


Function block to subscribe (receive) messages from an MQTT broker.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
MQTTClient.

Inputs
Name IEC 61131 Type Description

xEnable BOOL TRUE: Subscribes the topic filter


wsTopicFilter.
FALSE: Unsubscribe topic filter.

eSubscribeQoS MQTT_QOS TRUE: QoS-Level for Subscribe.

pbPayload POINTER TO BYTE Pointer to memory for incoming payload.

udiMaxPayloadSize UDINT Maximum Size of incoming payload.

eFilterMode FILTER_MODE Filter mode for incoming telegrams. Default:


FILTER_MODE.FILTER_ON.

Date Code 20241023 Programming Reference


634 MQTT_Client_SL
Examples

Inputs/Outputs
Name IEC 61131 Type Description

mqttClient MQTTClient Function block MQTTClient.

wsTopicName WSTRING(1024) Topic Filter.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eMQTTError MQTT_ERROR MQTT Error Type.

xReceived BOOL FALSE as long as there is no message, TRUE


if a message got received, in new cycles then
again FALSE.

udiPayloadSize UDINT Size of the received message.

xSubscribeActive BOOL FALSE: When there is no active subscription.


TRUE: Subscriber is listening.

wsLastTopic WSTRING(1024) The real topic value from the publish packet
that is corresponding to this topic filter.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.
Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Publish/Subscribe Loopback (ST)


Objective
The goal of this example is to utilize an external broker (one running on another
host system, e.g., Eclipse Mosquitto) to provide a link between a publisher and
subscriber, both running on the local RTAC and demonstrate the basic premise
of relaying messages between MQTT client endpoints.

Assumptions
The following assumptions are made:
1. MQTT Broker is hosted with an IPv4 address of 192.168.1.10.
2. MQTT Broker is hosted with a TCP listening port of 1883.
3. No MQTT usernames or passwords are in use.

Programming Reference Date Code 20241023


MQTT_Client_SL 635
Examples

4. A common topic of rtac/data/topic-name shall be used.


5. For simplicity, the message will be published every ten (10) seconds.

Solution
Code Snippet 20.1 prg_MqttLoopback
PROGRAM prg_MqttLoopback
VAR CONSTANT
c_BrokerTcpPort : UINT := 1883;
END_VAR
VAR
// Function block to establish a connection to an MQTT broker.
mqttClient : MQTT.MQTTClient;
// Function block to subscribe MQTT topics.
mqttSubscriber : MQTT.MQTTSubscribe;
// Function block to publish MQTT topics.
mqttPublisher : MQTT.MQTTPublish;
// Interval timer set to assert for a single
// processing cycle every 10 seconds.
tenSecondTimer : TI := (PT:=T#10S);
// Publication Message Payload
publicationPayload : STRING(255) := 'hello, world!';
// Subscription Message Payload Placeholder
subscriptionPayload : STRING(255);
// Indicates if the MQTT Client is initialized and active.
initialized : BOOL;
END_VAR

// Run the MQTT Client - This maintains the active connection to the MQTT broker.
mqttClient(
xEnable := initialized AND Enable,
uiPort := c_BrokerTcpPort,
sHostname := brokerHostname
);

// Run the MQTT Subscriber - This will listen for any new messages associated with
// the subscribed topic.
mqttSubscriber(
xEnable := mqttClient.xConnectedToBroker AND Enable,
pbPayload := ADR( subscriptionPayload ),
udiMaxPayloadSize := SIZEOF( subscriptionPayload ),
mqttClient := mqttClient,
wsTopicFilter := exchangedTopic
);

// Run the Interval Timer


tenSecondTimer();

// Publish Message to Broker When Timer Asserts - This will maintain the necessary
// processes for the publisher, and will perform the publication action
// at appropriate intervals.
mqttPublisher(
xExecute := tenSecondTimer.Q AND mqttClient.xConnectedToBroker AND Enable,
mqttClient := mqttClient,
wsTopicName := exchangedTopic,
pbPayload := ADR( publicationPayload ),
udiPayloadSize := TO_UDINT( LEN( publicationPayload ))
);

IF NOT initialized THEN


// Enable MQTT After the First Scan
// Only Really Necessary on Slower Platforms Such as 3530, 2241, 3532, etc.
initialized := TRUE;
END_IF

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 2 1

MathComplex
Introduction
The MathComplex library allows the storage of complex numbers as well as
basic manipulations that can be performed on them.
All numbers in polar notation are expected to be in units of degrees and not
radians.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.
Versions 3.5.0.2 and earlier can be used on RTAC firmware version R132 and
later.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

struct_ComplexRect
This structure represents a complex number in rectangular coordinates.

Name IEC 61131 Type Description

Re LREAL The real component of this complex number.

Im LREAL The imaginary component of this complex number.

Functions
fun_ComplexAbs (Function)
This function returns the absolute value, or magnitude, of the provided complex
number.

Inputs
Name IEC 61131 Type Description

num struct_ComplexRect The number from which the absolute value is calculated.

Date Code 20241023 Programming Reference


638 MathComplex
Functions

Return Value
IEC 61131 Type Description

LREAL The absolute value of num.

Processing
This function returns a value equal to .

fun_ComplexAdd (Function)
This function returns the sum of two complex numbers.

Inputs
Name IEC 61131 Type Description

num1 struct_ComplexRect The first addend.

num2 struct_ComplexRect The second addend.

Return Value
IEC 61131 Type Description

struct_ComplexRect The result of num1 + num2.

fun_ComplexCmp (Function)
This function compares two complex values based on magnitude.

Inputs
Name IEC 61131 Type Description

num1 struct_ComplexRect The first value to compare.

num2 struct_ComplexRect The second value to compare.

Return Value
IEC 61131 Type Description

INT Returns –1 if the magnitude of num2 is larger than num1, 0 if the


magnitudes are equal, and 1 if the magnitude of num1 is larger than
num2.

Processing
This function calculates the absolute value of both provided inputs and then
provides its return based on which one is larger.

Programming Reference Date Code 20241023


MathComplex 639
Functions

fun_ComplexConjugate (Function)
This function returns the conjugate of the provided complex number.

Inputs
Name IEC 61131 Type Description

num struct_ComplexRect The number from which the conjugate is derived.

Return Value
IEC 61131 Type Description

struct_ComplexRect The complex conjugate of num.

Processing
This function returns a struct_ComplexRect with a negated imaginary
component.

fun_ComplexDivide (Function)
This function returns the quotient of num1 / num2.

Inputs
Name IEC 61131 Type Description

num1 struct_ComplexRect The dividend.

num2 struct_ComplexRect The divisor.

Return Value
IEC 61131 Type Description

struct_ComplexRect The quotient of num1 / num2.

Processing
This function performs the equivalent of providing a result
formatted as a single complex number.

fun_ComplexExp (Function)
Compute enum.

Date Code 20241023 Programming Reference


640 MathComplex
Functions

Inputs
Name IEC 61131 Type Description

num struct_ComplexRect The number e will be raised to.

Return Value
IEC 61131 Type Description

struct_ComplexRect The result of enum.

Processing
Performs the calculation .

fun_ComplexLn (Function)
Compute the natural logarithm of num.

Inputs
Name IEC 61131 Type Description

num struct_ComplexRect The number from which the natural log is


calculated.

Return Value
IEC 61131 Type Description

struct_ComplexRect The natural log of num.

Processing
This function returns an Re component of the natural log of the magnitude of
num and an Im component of the angle defined by the arctangent of num.Im and
num.Re.

fun_ComplexMultiply (Function)
This function returns the product of multiplying two complex numbers.

Inputs
Name IEC 61131 Type Description

num1 struct_ComplexRect The first factor.

num2 struct_ComplexRect The second factor.

Programming Reference Date Code 20241023


MathComplex 641
Functions

Return Value
IEC 61131 Type Description

struct_ComplexRect The product of num1 and num2.

fun_ComplexScale (Function)
This function multiplies a complex number by a scalar.

Inputs
Name IEC 61131 Type Description

num struct_ComplexRect The number to scale.

scalar LREAL The scalar.

Return Value
IEC 61131 Type Description

struct_ComplexRect The product of num and scalar.

fun_ComplexSubtract (Function)
This function returns the difference of two complex numbers.

Inputs
Name IEC 61131 Type Description

num1 struct_ComplexRect The minuend.

num2 struct_ComplexRect The subtrahend.

Return Value
IEC 61131 Type Description

struct_ComplexRect The difference of num1 – num2.

fun_ComplexZero (Function)
This function zeros the provided struct_ComplexRect.

Inputs/Outputs
Name IEC 61131 Type Description

num struct_ComplexRect The struct to be zeroed.

Date Code 20241023 Programming Reference


642 MathComplex
Benchmarks

struct_ComplexRect_TO_vector_t (Function)
This function converts a complex number stored as rectangular coordinates to a
complex number stored as polar coordinates. The angle returned by this function
will be between –180 and 180 degrees.

Inputs
Name IEC 61131 Type Description

num struct_ComplexRect The rectangular coordinates to be converted.

Return Value
IEC 61131 Type Description

vector_t num represented as polar coordinates.

vector_t_TO_struct_ComplexRect (Function)
This function converts a complex number stored as polar coordinates to a
complex number stored as rectangular coordinates.

Inputs
Name IEC 61131 Type Description

num vector_t The polar coordinates to be converted.

Return Value
IEC 61131 Type Description

struct_ComplexRect num represented as rectangular coordinates.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.
➤ SEL-3505
➢ R135-V0 firmware
➤ SEL-3530
➢ R135-V0 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R135-V0 firmware

Programming Reference Date Code 20241023


MathComplex 643
Examples

Benchmark Test Descriptions


BasicOps Performance
The times fun_ComplexAbs, fun_ComplexZero, and fun_ComplexConjugate
require to run, averaged over 1000 calls.

AlgebraicOps Performance
The times fun_ComplexAdd, fun_ComplexSubtract, fun_ComplexDivide,
fun_ComplexScale, and fun_ComplexMultiply require to run, averaged over
1000 calls.

Exponential Performance
The times fun_ComplexExp and fun_ComplexLn require to run, averaged over
1000 calls.

Conversion Performance
The times struct_ComplexRect_TO_vector_t and
vector_t_TO_struct_ComplexRect require to run, averaged over 1000 calls.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

fun_ComplexAbs 10 7 1

fun_ComplexConjugate 5 4 1

fun_ComplexZero 1 1 1

fun_ComplexAdd 2 2 1

fun_ComplexSubtract 2 2 1

fun_ComplexMultiply 2 2 1

fun_ComplexDivision 3 2 1

fun_ComplexScale 1 1 1

fun_ComplexExp 36 15 1

fun_ComplexLn 50 13 1

vector_t_TO_struct_ComplexRect 19 6 1

struct_ComplexRect_TO_vector_t 23 12 1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Date Code 20241023 Programming Reference


644 MathComplex
Examples

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Performing a Mathematical Operation on Two Complex Numbers


Objective
A user has a need to sum two complex numbers.

Solution
The usage shown in Code Snippet 21.1 would be the same for any other
operation as well.
Code Snippet 21.1 prg_ComplexAdd
PROGRAM prg_ComplexAdd
VAR
ComplexNumOne : struct_ComplexRect := (Re := 4.0, Im := 3.0);
ComplexNumTwo : struct_ComplexRect := (Re := 2.0, Im := 7.0);
ComplexResult : struct_ComplexRect;
END_VAR

ComplexResult := fun_ComplexAdd(ComplexNumOne, ComplexNumTwo);

Manipulating vector_t Structures


Objective
A user has data points received through an Axion module containing complex
numbers represented in polar notation as vector_t objects.

The user would like to perform some set of mathematical operations on them
and then prepare them to send to another device.

Solution
Code Snippet 21.2 prg_ComplexConvert
PROGRAM prg_ComplexConvert
VAR
DatumOne : vector_t := (ang := 36.87, mag := 35_614);
DatumTwo : vector_t := (ang := 53.13, mag := 17_735);
ComplexNumOne : struct_ComplexRect;
ComplexNumTwo : struct_ComplexRect;
ComplexResult : struct_ComplexRect;
DatumResult : vector_t;
END_VAR

ComplexNumOne := vector_t_TO_struct_ComplexRect(DatumOne);
ComplexNumTwo := vector_t_TO_struct_ComplexRect(DatumTwo);
ComplexResult := fun_ComplexAdd(ComplexNumOne, ComplexNumTwo);
//Scale from Kilovolts to Volts.
ComplexResult := fun_ComplexScale(ComplexResult, 1000);
DatumResult := struct_ComplexRect_TO_vector_t(ComplexResult);

Programming Reference Date Code 20241023


S E C T I O N 2 2

MathMatrix
Introduction
The MathMatrix library allows for the creation of matrices of complex numbers.
There are multiple desired workflows that exist when working with matrices and
the library provides several options for working with them.

The library is designed to facilitate two basic types of matrix operations:


operations that modify an existing matrix and operations that take one or more
matrices as arguments and place the result in a different matrix. Operations that
affect only the active matrix are completed using the methods on class_Matrix
objects. Operations that affect two or more matrices are performed by external
functions or special matrix manipulation classes.

The library also allows for operations of varying levels of required immediacy.
For work on large or highly variant sized matrices that can be completed over
multiple task cycles, it provides matrix manipulation classes that are loaded
with operator and result matrices, stimulated to run to completion, and given a
fixed number of steps or a fixed time slice. For operations that must complete
immediately, ideally on fixed sized matrices so the computation time can be
evaluated to validate timing requirements, functions provided by the library
accomplish the same work while guaranteeing the completion of the algorithm
before returning.

NOTE
Because of the cost of checking the system time, the time is not validated
at each step in the algorithm but rather after multiple steps have been
completed.

This library is dependent on the capabilities defined in the MathComplex


library for all operations (see the MathComplex library documentation for more
information on the operation of this library).

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_MathMatrixObject"
myMathMatrixObject := otherMathMatrixObject;

// This is fine
someVariable := myMathMatrixObject.value;

// As is this

Date Code 20241023 Programming Reference


646 MathMatrix
Supported Firmware Versions

pt_myMathMatrixObject := ADR(myMathMatrixObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).
➤ Though this library provides the capability to dynamically resize, create,
and destroy matrices, memory operations can be long running and care
should be taken to avoid unnecessary use of this type of operation on a
time-critical task.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.
Versions 3.5.0.1 and earlier can be used on RTAC firmware version R132 and
later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_MatrixState
Enumeration Description

NOT_INITIALIZED This matrix has no memory assigned to it, call SetSize()


to initialize.

NO_OPERATION The matrix is not locked to any operation.

MATRIX_SCALE The matrix is being scaled by one value.

EXTERNAL_OPERATION The matrix is being operated on by an external class.

MATRIX_ROW_STEP_MULT The matrix is multiplying a row by a scalar.

MATRIX_ROW_STEP_DIV The matrix is dividing a row by a scalar.

MATRIX_ROW_STEP_ADD The matrix is adding two rows together.

MATRIX_ROW_STEP_SUB The matrix is subtracting one row from another.

Functions
fun_DeleteMatrix (Function)
The user should call this after completing work on a matrix received through
fun_NewMatrix() before the matrix goes out of scope. It releases all system
resources.

Programming Reference Date Code 20241023


MathMatrix 647
Functions

Inputs/Outputs
Name IEC 61131 Type Description

pt_matrix POINTER TO class_Matrix The matrix to be deleted. This pointer must be


received through fun_NewMatrix.

Return Value
IEC 61131 Type Description

BOOL TRUE if the memory is successfully deallocated.

Processing
This function frees all system resources owned by this matrix. After completion
of the function, pt_matrix is NULL(0).

fun_MatrixAdd (Function)
This function adds two matrices and places the result in a third. The entire
operation will complete before the function returns.

Inputs/Outputs
Name IEC 61131 Type Description

matrix1 class_Matrix The first addend.

matrix2 class_Matrix The second addend.

result class_Matrix The sum of the two matrices.

Return Value
IEC 61131 Type Description

BOOL The matrix addition completed successfully.

Processing
This function sets the return value to TRUE if all conditions for performing the
addition are met as follows:

➤ matrix1 and matrix2 are initialized.


➤ All three matrices are not busy performing a stepwise operation.
➤ result is a separate matrix from both matrix1 and matrix2.
➤ matrix1 and matrix2 have the same dimensions.
➤ If necessary, result is successfully resized.
It then performs the addition.

Date Code 20241023 Programming Reference


648 MathMatrix
Functions

fun_MatrixCopyColumn (Function)
This function copies one column from one matrix to a column in a second
matrix. The entire operation will complete before the function returns.

Inputs
Name IEC 61131 Type Description

fromColumn UINT The column index of the column being copied


from.

toColumn UINT The column index of the column being copied to.

Inputs/Outputs
Name IEC 61131 Type Description

fromMatrix class_Matrix The matrix being copied from.

toMatrix class_Matrix The matrix being copied to.

Return Value
IEC 61131 Type Description

BOOL The column copy completed successfully.

Processing
This function sets the return value to TRUE if all conditions for performing the
copy are met as follows:

➤ Both matrices are initialized.


➤ Both matrices are not busy performing a stepwise operation.
➤ Both matrices have the same number of rows.
➤ The column indices provided are within the size of the matrices
referenced.

It then performs the copy.

fun_MatrixDeterminant (Function)
This function calculates the determinant of a square matrix. The entire operation
will complete before the function returns.

If the purpose behind calculating the determinant is a check before inverting a


matrix or as part of the process of solving a system of equations this class is not
the most optimal to use. In these cases, it is better to use the fun_MatrixInvert
or the fun_MatrixGaussianElim object instead as the overhead for all three is
similar.

Programming Reference Date Code 20241023


MathMatrix 649
Functions

Inputs/Outputs
Name IEC 61131 Type Description

original class_Matrix The matrix to calculate the determinant of. This


matrix is left unchanged.

workspace class_Matrix Memory to do the calculation in. If this is the same


size as original, no memory allocation will occur in
finding the determinant.

Outputs
Name IEC 61131 Type Description

determinant struct_ComplexRect The determinant of the matrix. Zero if the


matrix is not invertible.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the operation was attempted.

Processing
1. This function sets the return value to TRUE if all conditions for
performing the calculation are met as follows:
➤ original is initialized.
➤ original is a square matrix.
➤ workspace is a separate matrix from original.
➤ Neither matrix is busy performing some other operation.
➤ If necessary, workspace is successfully resized.
2. Copies the contents of original into workspace.
3. Reduces workspace to an identity matrix using elementary row
operations.
4. Calculates the determinant from the row operations performed.
5. If at any time the row operations cannot reduce workspace further and it
is still not an identity matrix, the operation is terminated and determinant
is set to zero.

fun_MatrixGaussianElim (Function)
This function simplifies a matrix to a diagonal ones matrix with trailing columns
using Gaussian elimination. The contents of coefficients are destroyed and the
contents of solutions are modified by this function. The entire operation will
complete before the function returns.

Date Code 20241023 Programming Reference


650 MathMatrix
Functions

Inputs/Outputs
Name IEC 61131 Type Description

coefficients class_Matrix The coefficients of the variables being solved for.

solutions class_Matrix The right hand side of the system of equations.

Outputs
Name IEC 61131 Type Description

error BOOL This algorithm cannot solve this system of


equations.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the Gaussian elimination was attempted and the
matrices could have been modified.

Processing
➤ This function sets the return value to TRUE if all conditions for
performing the calculation are met as follows:
➢ Both matrices are initialized.
➢ Both matrices are not busy performing a stepwise operation.
➢ coefficients is a separate matrix from solutions.
➢ coefficients has at least as many columns as rows.
➢ solutions has the same number of rows as coefficients.
➤ Reduces the first Rows • Rows of coefficients to an identity matrix using
elementary row operations.
➤ Performs the same row operations on solutions.
➤ If at any time the row operations cannot reduce coefficients further and
there is still not an identity matrix on the left the operation is terminated
and error is set.
➤ The contents of coefficients are destroyed and the contents of solutions
are modified by this method.

Output Combination Meanings


Error Return Description

FALSE FALSE This should never occur.

FALSE TRUE The Gaussian elimination completed successfully.

TRUE FALSE The matrix state prevented the Gaussian


elimination request.

TRUE TRUE The matrix is not invertible and cannot be reduced


by this Gaussian elimination algorithm.

Programming Reference Date Code 20241023


MathMatrix 651
Functions

fun_MatrixInvert (Function)
This function creates the inverse of a square matrix. original is destroyed in the
process so if the data are still desired, they must be copied before the function is
called. The entire operation will complete before the function returns.

One common use case for inverting a matrix is to solve a system of equations.
In this library that use case is discouraged unless solving the same system for
many solutions as Gaussian elimination performs the same functionality with
less overhead.

Inputs/Outputs
Name IEC 61131 Type Description

original class_Matrix The matrix to invert.

result class_Matrix The inverted matrix.

Outputs
Name IEC 61131 Type Description

error BOOL The inversion could not be attempted or original


cannot be inverted.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if inversion was attempted and the matrices could
have been modified.

Processing
1. This function sets the return value to TRUE if all conditions for
performing the calculation are met as follows:
➤ original is initialized.
➤ Both matrices are not busy performing a stepwise operation.
➤ result is a separate matrix from original.
➤ original is a square matrix.
➤ If necessary, result is successfully resized.
2. Sets result to an identity matrix.
3. Reduces original to an identity matrix using elementary row operations.
4. Performs the same row operations on result to create the inverse.
5. If at any time the row operations cannot reduce original further and it is
still not an identity matrix, the operation is terminated and error is set.

Date Code 20241023 Programming Reference


652 MathMatrix
Functions

Output Combination Meanings


Error Return Description

FALSE FALSE This should never occur.

FALSE TRUE The inversion completed successfully.

TRUE FALSE The matrix state prevented the inversion request.

TRUE TRUE The matrix is not invertible.

fun_MatrixMultiply (Function)
This function multiplies two matrices and places the result in a third. The entire
operation will complete before the function returns.

Inputs/Outputs
Name IEC 61131 Type Description

matrix1 class_Matrix The multiplier.

matrix2 class_Matrix The multiplicand.

result class_Matrix The product of the two matrices.

Return Value
IEC 61131 Type Description

BOOL The matrix multiplication completed successfully.

Processing
This function sets the return value to TRUE if all conditions for performing the
calculation are met as follows:

1. matrix1 and matrix2 are initialized.


2. All three matrices are not busy performing a stepwise operation.
3. result is a separate matrix from both matrix1 and matrix2.
4. The column count of matrix1 equals the row count of matrix2.

If necessary, it sets the size of result. It then performs the multiplication.

fun_MatrixSubtract (Function)
This function subtracts one matrix from another and places the result in a third.
The entire operation will complete before the function returns.

Programming Reference Date Code 20241023


MathMatrix 653
Functions

Inputs/Outputs
Name IEC 61131 Type Description

matrix1 class_Matrix The minuend.

matrix2 class_Matrix The subtrahend.

result class_Matrix The difference of the two matrices.

Return Value
IEC 61131 Type Description

BOOL The matrix subtraction completed successfully.

Processing
This function verifies that the subtraction can be performed:

➤ matrix1 and matrix2 are initialized.


➤ All three matrices are not busy performing a stepwise operation.
➤ result is a separate matrix from both matrix1 and matrix2.
➤ matrix1 and matrix2 have the same dimensions.
If necessary, the function resizes result. It then performs the subtraction.

fun_MatrixTranspose (Function)
This function places the transpose of a matrix into a result. The entire operation
will complete before the function returns.

Inputs
Name IEC 61131 Type Description

conjugate BOOL The result of this operation will be the Hermitian


Transpose. Before each element is placed in result,
it will be conjugated.

Inputs/Outputs
Name IEC 61131 Type Description

original class_Matrix The matrix whose transpose is calculated.

result class_Matrix The transpose of the original matrix.

Return Value
IEC 61131 Type Description

BOOL The matrix transpose completed successfully.

Date Code 20241023 Programming Reference


654 MathMatrix
Functions

Processing
This function verifies that the transpose can be performed:

1. original is initialized.
2. Both matrices are not busy performing a stepwise operation.
3. result is a separate matrix from original.

If necessary the function resizes result. It then performs the transpose. If


conjugate is TRUE, conjugate each element in result.

fun_Matrix_ATA (Function)
This function performs an optimization of the operation (ATA) transposing an
input matrix and multiplying it by itself. The entire operation will complete
before the function returns.

Inputs
Name IEC 61131 Type Description

conjugate BOOL The result of this operation will be calculated using


the Hermitian Transpose. Before the transpose step
is complete, each element will be conjugated.

Inputs/Outputs
Name IEC 61131 Type Description

original class_Matrix The matrix A.

result class_Matrix The matrix for the result.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the operation completed successfully.

Processing
This function verifies that the operation can be performed:

1. original is initialized.
2. Both matrices are not busy performing a stepwise operation.
3. result is a separate matrix from original.

If necessary, the function resizes result. It then performs the operation ATA. If
conjugate is TRUE, conjugate each element in the transpose before using it in
the multiply.

Programming Reference Date Code 20241023


MathMatrix 655
Classes

fun_NewMatrix (Function)
Request a new matrix from the system with all required resources.
Matrices received through this function must be freed through the
fun_DeleteMatrix() function before they leave scope.

Inputs
Name IEC 61131 Type Description

rows UINT The number of rows in the new matrix.

cols UINT The number of columns in the new matrix.

Return Value
IEC 61131 Type Description

POINTER TO class_Matrix The address of the new class_Matrix.

Processing
This function allocates system resources for a rows by cols matrix of
struct_ComplexRect objects.

Classes
This library provides the following classes as extensions of the IEC 61131
function block.

class_Matrix (Class)
This is the fundamental class for this library. It allows for the storage of
struct_ComplexRect objects ordered by row and column. It manages all required
system resources internally.

Initialization Inputs
Name IEC 61131 Type Description

rowCount UINT The number of rows this matrix begins with.

colCount UINT The number of columns this matrix begins with.

Outputs
Name IEC 61131 Type Description

pt_Data POINTER TO POINTER TO Pointer to an array of pointers (one for each row). Allows accessing the matrix
struct_ComplexRect with [row][col] syntax. Indexing starts at zero. This pointer should be re-read
before access after any resize operation.

Rows UINT The number of rows in the matrix.

Date Code 20241023 Programming Reference


656 MathMatrix
Classes

Name IEC 61131 Type Description

Cols UINT The number of columns in the matrix.

State enum_MatrixState The active matrix operation.

Clear (Method)
This method returns all system resources internal to this matrix and sets its size
to zero rows by zero columns. In addition, it clears all locks on the matrix and
resets all internal state machines.

This should typically be used only to free the system resources held by this
matrix before it goes out of scope.

MatrixRowAdd (Method)
This method adds one row to another inside this matrix, replacing the content of
the second row (Matrix[toRow] = Matrix[toRow] + Matrix[fromRow] • scalar).
The entire operation will complete before the method returns.

Inputs
Name IEC 61131 Type Description

fromRow UINT The first addend.

toRow UINT The second addend and the location of the result.

scalar struct_ComplexRect A constant that is multiplied against the value of


each entry in fromRow before adding it to the entry
in toRow.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method performed the addition.

Processing
1. Validates that the matrix is initialized and not in the middle of a stepwise
operation.
2. Validates that the provided row indices exist.
3. If the checks pass, multiplies fromRow by scalar and adds the result to
toRow.
4. fromRow remains unchanged.

MatrixRowDivide (Method)
This method divides each element in rowIndex by scalar and stores the results
back in rowIndex (Matrix[rowIndex] = Matrix[rowIndex] / scalar). The entire
operation will complete before the method returns.

Programming Reference Date Code 20241023


MathMatrix 657
Classes

Inputs

Name IEC 61131 Type Description

rowIndex UINT The row to be modified.

scalar struct_ComplexRect A constant used as the divisor against the value of


each entry in rowIndex.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method performed the division.

Processing
1. Validates that the matrix is initialized and not in the middle of a stepwise
operation.
2. Validates the row index provided exists.
3. If the checks pass, divides each entry in rowIndex by scalar.

MatrixRowMultiply (Method)
This method multiplies each element in rowIndex by scalar and stores the results
back in rowIndex (Matrix[rowIndex] = Matrix[rowIndex] • scalar). The entire
operation will complete before the method returns.

Inputs

Name IEC 61131 Type Description

rowIndex UINT The row to be modified.

scalar struct_ComplexRect A constant used as the multiplier against the value


of each entry in rowIndex.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method performed the multiplication.

Processing
1. Validates that the matrix is initialized and not in the middle of a stepwise
operation.
2. Validates the row index provided exists.
3. If the checks pass, multiplies each entry in rowIndex by scalar.

Date Code 20241023 Programming Reference


658 MathMatrix
Classes

MatrixRowSubtract (Method)
This method subtracts one row from another inside this matrix, replacing the
content of the second row (Matrix[toRow] = Matrix[toRow] – Matrix[fromRow]
• scalar). The entire operation will complete before the method returns.

Inputs

Name IEC 61131 Type Description

fromRow UINT The subtrahend.

toRow UINT The minuend and the location of the result.

scalar struct_ComplexRect A constant that is multiplied against the value of


each entry in fromRow before subtracting it from
the entry in toRow.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method performed the subtraction.

Processing
1. Validates that the matrix is initialized and not in the middle of a stepwise
operation.
2. Validates the row indices provided exist.
3. If the checks pass, multiplies fromRow by scalar and subtracts the result
from toRow.
4. fromRow remains unchanged.

MatrixScale (Method)
Multiplies each element in this matrix by a scalar. The entire operation will
complete before the method returns.

Inputs

Name IEC 61131 Type Description

scalar struct_ComplexRect A constant that is multiplied against the value of


each entry this matrix.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method scaled the matrix.

Programming Reference Date Code 20241023


MathMatrix 659
Classes

Processing
1. Validates that the matrix is initialized and not in the middle of a stepwise
operation.
2. If the checks pass, multiplies each element in the matrix by scalar,
placing the result in the same location.

MatrixStepRowAdd (Method)
This method adds one row to another inside this matrix, replacing the content of
the second row (Matrix[toRow] = Matrix[toRow] + Matrix[fromRow] • scalar).
The operation will perform the next steps operations of the complete addition.
This design allows for the completion of the algorithm over the course of
multiple task cycles for matrices large enough for completion time to be a
concern.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of operations to attempt this task cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method completed the addition.

Processing
1. Validates that the matrix is initialized and has begun a stepwise addition.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply fromRow by scalar and add the
result to toRow.
3. fromRow remains unchanged.
4. Performs, at most, the next steps operations toward completing the
addition algorithm.
5. Decrements steps by the number of operations consumed.
6. Returns TRUE and unlocks the matrix if the addition completed.
7. Returns FALSE if the addition was not attempted or steps was exhausted
before the algorithm completed.

MatrixStepRowDivide (Method)
This method divides each element in toRow by scalar and stores the results back
in toRow (Matrix[toRow] = Matrix[toRow] / scalar).
The operation will perform the next steps operations of the complete division.
This design allows for the completion of the algorithm over the course of
multiple task cycles for matrices large enough for completion time to be a
concern.

Date Code 20241023 Programming Reference


660 MathMatrix
Classes

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of operations to attempt this task cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method completed the division.

Processing
1. Validates that the matrix is initialized and has begun a stepwise division.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to divide each element in toRow by scalar.
3. Performs, at most, the next steps operations toward completing the
division algorithm.
4. Decrements steps by the number of operations consumed.
5. Returns TRUE and unlocks the matrix if the division completed.
6. Returns FALSE if the division was not attempted or steps was exhausted
before the algorithm completed.

MatrixStepRowMultiply (Method)
This method multiplies each element in toRow by scalar and stores the results
back in toRow (Matrix[toRow] = Matrix[toRow] • scalar).
The operation will perform the next steps operations of the complete
multiplication. This design allows for the completion of the algorithm over the
course of multiple task cycles for matrices large enough for completion time to
be a concern.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of operations to attempt this task cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method completed the multiplication.

Processing
1. Validates that the matrix is initialized and has begun a stepwise
multiplication.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply each entry in toRow by scalar.

Programming Reference Date Code 20241023


MathMatrix 661
Classes

3. Performs, at most, the next steps operations toward completing the


multiplication algorithm.
4. Decrements steps by the number of operations consumed.
5. Returns TRUE and unlocks the matrix if the multiplication completed.
6. Returns FALSE if the multiplication was not attempted or steps was
exhausted before the algorithm completed.

MatrixStepRowSubtract (Method)
This method subtracts one row from another inside this matrix, replacing the
content of the second row (Matrix[toRow] = Matrix[toRow] – Matrix[fromRow]
• scalar).
The operation will perform the next steps operations of the complete subtraction.
This design allows for the completion of the algorithm over the course of
multiple task cycles for matrices large enough for completion time to be a
concern.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of operations to attempt this task cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method completed the subtraction.

Processing
1. Validates that the matrix is initialized and has begun a stepwise
subtraction.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply fromRow by scalar and subtract
the result from toRow.
3. fromRow remains unchanged.
4. Performs, at most, the next steps operations toward completing the
subtraction algorithm.
5. Decrements steps by the number of operations consumed.
6. Returns TRUE and unlocks the matrix if the subtraction completed.
7. Returns FALSE if the subtraction was not attempted or steps was
exhausted before the algorithm completed.

MatrixStepScale (Method)
Multiplies each element in this matrix by a scalar.
The operation will perform the next steps operations of the complete scaling
operation. This design allows for the completion of the algorithm over the
course of multiple task cycles for matrices large enough for completion time to
be a concern.

Date Code 20241023 Programming Reference


662 MathMatrix
Classes

Inputs/Outputs

Name IEC 61131 Type Description

steps UDINT The number of operations to attempt this task cycle.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method completed the scaling operation.

Processing
1. Validates that the matrix is initialized and has begun a stepwise scaling
operation.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply each element in the matrix by
scalar.
3. Performs, at most, the next steps operations toward completing the
scaling algorithm.
4. Decrements steps by the number of operations consumed.
5. Returns TRUE and unlocks the matrix if the scaling operation completed.
6. Returns FALSE if the scaling operation was not attempted or steps was
exhausted before the algorithm completed.

MatrixTimedRowAdd (Method)
This method adds one row to another inside this matrix, replacing the content of
the second row (Matrix[toRow] = Matrix[toRow] + Matrix[fromRow] • scalar).

The operation will perform work for the next duration microseconds toward
completion of the addition. This design allows for the completion of the
algorithm over the course of multiple task cycles for matrices large enough for
completion time to be a concern.

Inputs/Outputs

Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method completed the addition.

Programming Reference Date Code 20241023


MathMatrix 663
Classes

Processing
1. Validates that the matrix is initialized and has begun a stepwise addition.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply fromRow by scalar and add the
result to toRow.
3. fromRow remains unchanged.
4. Performs work toward completing the addition algorithm, in groups of
steps, until duration microseconds is exceeded.
5. Decrements duration by the microseconds consumed.
6. Returns TRUE and unlocks the matrix if the addition completed.
7. Returns FALSE if the addition was not attempted or duration was
exhausted before the algorithm completed.

MatrixTimedRowDivide (Method)
This method divides each element in toRow by scalar and stores the results back
in toRow (Matrix[toRow] = Matrix[toRow] / scalar).

The operation will perform work for the next duration microseconds toward the
complete division. This design allows for the completion of the algorithm over
the course of multiple task cycles for matrices large enough for completion time
to be a concern.

Inputs/Outputs

Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method completed the division.

Processing
1. Validates that the matrix is initialized and has begun a stepwise division.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to divide each element in toRow by scalar.
3. Performs work toward completing the division algorithm, in groups of
steps, until duration microseconds is exceeded.
4. Decrements duration by the microseconds consumed.
5. Returns TRUE and unlocks the matrix if the division completed.
6. Returns FALSE if the division was not attempted or duration was
exhausted before the algorithm completed.

Date Code 20241023 Programming Reference


664 MathMatrix
Classes

MatrixTimedRowMultiply (Method)
This method multiplies each element in toRow by scalar and stores the results
back in toRow (Matrix[toRow] = Matrix[toRow] • scalar).
The operation will perform work for the next duration microseconds toward the
complete multiplication. This design allows for the completion of the algorithm
over the course of multiple task cycles for matrices large enough for completion
time to be a concern.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method completed the multiplication.

Processing
1. Validates that the matrix is initialized and has begun a stepwise
multiplication.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply each entry in toRow by scalar.
3. Performs work toward completing the multiplication algorithm, in groups
of steps, until duration microseconds is exceeded.
4. Decrements duration by the microseconds consumed.
5. Returns TRUE and unlocks the matrix if the multiplication completed.
6. Returns FALSE if the multiplication was not attempted or duration was
exhausted before the algorithm completed.

MatrixTimedRowSubtract (Method)
This method subtracts one row from another inside this matrix, replacing the
content of the second row (Matrix[toRow] = Matrix[toRow] – Matrix[fromRow]
• scalar).
The operation will perform work for the next duration microseconds toward the
complete subtraction. This design allows for the completion of the algorithm
over the course of multiple task cycles for matrices large enough for completion
time to be a concern.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Programming Reference Date Code 20241023


MathMatrix 665
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method completed the subtraction.

Processing
1. Validates that the matrix is initialized and has begun a stepwise
subtraction.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply fromRow by scalar and subtract
the result from toRow.
3. fromRow remains unchanged.
4. Performs work toward completing the subtraction algorithm, in groups of
steps, until duration microseconds is exceeded.
5. Decrements duration by the microseconds consumed.
6. Returns TRUE and unlocks the matrix if the subtraction completed.
7. Returns FALSE if the subtraction was not attempted or duration was
exhausted before the algorithm completed.

MatrixTimedScale (Method)
Multiplies each element in this matrix by a scalar.

The operation will perform work for the next duration microseconds toward
the complete scaling operation. This design allows for the completion of the
algorithm over the course of multiple task cycles for matrices large enough for
completion duration to be a concern.

Inputs/Outputs

Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the method completed the scaling operation.

Processing
1. Validates that the matrix is initialized and has begun a stepwise scaling
operation.
2. If the checks pass, this method uses the values provided in
StartMatrixOperation() to multiply each element in the matrix by
scalar.

Date Code 20241023 Programming Reference


666 MathMatrix
Classes

3. Performs work toward completing the scaling algorithm, in groups of


steps, until duration microseconds is exceeded.
4. Decrements duration by the microseconds consumed.
5. Returns TRUE and unlocks the matrix if the scaling operation completed.
6. Returns FALSE if the scaling operation was not attempted or duration
was exhausted before the algorithm completed.

RowSwap (Method)
This method exchanges the position of two rows in a given matrix.

Inputs
Name IEC 61131 Type Description

row1 UINT The first row to swap.

row2 UINT The second row to swap.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method performed the row swap.

Processing
1. Validates that the matrix is initialized and not performing any stepwise
operation.
2. If the checks pass, swaps the positions of row1 and row2.
3. Returns TRUE if the swap succeeded.
4. Returns FALSE if the swap failed.

SetSize (Method)
This method changes the storage capacity of the matrix modifying Rows and
Cols.

Inputs
Name IEC 61131 Type Description

rowCount UINT The new number of rows.

colCount UINT The new number of columns.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method resized the matrix.

Programming Reference Date Code 20241023


MathMatrix 667
Classes

Processing
1. Validates that the matrix is not performing any stepwise operation.
2. If either rowCount or colCount is zero, sets Rows and Cols to zero and
frees all system resources.
3. If both rowCount equals Rows and colCount equals Cols, leaves the
matrix unchanged.
4. If rowCount is greater than Rows, adds zeroed rows to the bottom of the
matrix.
5. If rowCount is less than Rows, removes rows from the bottom of the
matrix.
6. If colCount is greater than Cols, adds zeros to the end of each row.
7. If colCount is less than Cols, truncates each row to the new count.
8. Returns TRUE if the matrix is the newly requested size.
9. Returns FALSE if the matrix is not the newly requested size.
10. If the resize fails, the matrix retains all old values.

StartMatrixOperation (Method)
This method must be called to configure any stepwise or timed operation on
only this matrix. It accepts and stores the values used during the operation.

Inputs
Name IEC 61131 Type Description

operation enum_MatrixState The stepwise operation to begin.

fromRow UINT The row to use in the modification. Used only in


addition and subtraction.

toRow UINT The row to be modified.

scalar struct_ComplexRect The constant value to be used during the operation.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the method locked the matrix to the requested
operation.

Processing
1. Validates that the matrix is initialized and not performing any stepwise
operation.
2. Validates row indices required for the operation requested. For
addition and subtraction, both indices must be within the matrix.
For multiplication and division, only toRow is validated. For scaling
operations, no row index is validated.
3. Stores scalar for use during the operation.
4. Locks the matrix to prevent other operations from occurring.

Date Code 20241023 Programming Reference


668 MathMatrix
Classes

5. Returns TRUE if the operation is primed.


6. Returns FALSE if anything prevents the operation from being primed.

class_MatrixAdd (Class)
This class handles the locking handshakes and the state required to add two
class_Matrix objects over the course of multiple scans.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

LockMatrices (Method)
This method primes the class to perform a new addition (result = matrix1 +
matrix2). It must be called before each addition of two matrices to be performed.

Inputs/Outputs
Name IEC 61131 Type Description

matrix1 class_Matrix The first addend.

matrix2 class_Matrix The second addend.

result class_Matrix The sum of matrix1 and matrix2.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the addition operation is now ready.

Processing
1. Returns FALSE if either matrix1 or matrix2 is not initialized.
2. Returns FALSE if result is not a separate matrix from both matrix1 and
matrix2.
3. Returns FALSE if any of the three matrices is busy doing any stepwise
operation.
4. Returns FALSE if the dimensions of matrix1 do not match those of
matrix2.
5. Returns FALSE if result cannot be made to be the same dimensions as the
other two matrices.
6. Returns FALSE if it cannot lock all matrices involved in the operation.
7. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.
8. The contents of result are destroyed by this method.

Programming Reference Date Code 20241023


MathMatrix 669
Classes

ProcessSteps (Method)
This method performs the addition algorithm on three already locked-in
matrices.

The operation will perform the next steps sub-operations of the complete
addition algorithm.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the addition completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Adds each element in matrix1 to its corresponding element in matrix2 and
stores the sum in result.
3. Decrements steps by the number of operations performed.
4. Returns TRUE if the addition algorithm completed before steps was
exhausted.
5. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.

ProcessTimed (Method)
This method performs the addition algorithm on three already locked-in
matrices.

The operation will perform work for the next duration microseconds toward the
complete addition algorithm.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the addition completed.

Date Code 20241023 Programming Reference


670 MathMatrix
Classes

Processing
1. Validates that LockMatrices() has been successfully called.
2. Adds each element in matrix1 to its corresponding element in matrix2 and
stores the sum in result.
3. Performs work toward completing the addition algorithm, in groups of
steps, until duration microseconds is exceeded.
4. Decrements duration by the microseconds consumed.
5. Returns TRUE if the addition algorithm completed before duration was
exhausted.
6. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

class_MatrixCopyColumn (Class)
This class handles the locking handshakes and the state required to copy a
column from one class_Matrix object to another over the course of multiple
scans.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

LockMatrices (Method)
This method primes the class to perform a new column copy. It must be called
before each column copy to be performed.

Inputs
Name IEC 61131 Type Description

fromColumn UINT The index of the column to copy from.

toColumn UINT The index of the column to copy to.

Programming Reference Date Code 20241023


MathMatrix 671
Classes

Inputs/Outputs

Name IEC 61131 Type Description

fromMatrix class_Matrix The matrix to be copied from.

toMatrix class_Matrix The matrix to be copied to.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the copy operation is now ready.

Processing
1. Returns FALSE if either fromMatrix or toMatrix is not initialized.
2. Returns FALSE if either of the matrices is busy doing any stepwise
operation.
3. Returns FALSE if Rows of matrix1 does not match Rows of matrix2.
4. Returns FALSE if either index provided is outside of the corresponding
matrix.
5. Returns FALSE if it cannot lock all matrices involved in the operation.
6. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.

ProcessSteps (Method)
This method performs the copy algorithm on two already locked-in matrices.

The operation will perform the next steps sub-operations of the complete copy.

Inputs/Outputs

Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the copy completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Copies each element in column fromColumn of fromMatrix to its
corresponding element in column toColumn of toMatrix.

Date Code 20241023 Programming Reference


672 MathMatrix
Classes

3. Decrements steps by the number of sub-operations performed.


4. Returns TRUE if the copy algorithm completed before steps was
exhausted.
5. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.

ProcessTimed (Method)
This method performs the copy algorithm on two already locked-in matrices.

The operation will perform work for the next duration microseconds toward the
complete copy.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the copy completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Copies each element in column fromColumn of fromMatrix to its
corresponding element in column toColumn of toMatrix.
3. Performs work toward completing the copy algorithm, in groups of steps,
until duration microseconds is exceeded.
4. Decrements duration by the microseconds consumed.
5. Returns TRUE if the copy algorithm completed before duration was
exhausted.
6. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

Programming Reference Date Code 20241023


MathMatrix 673
Classes

class_MatrixDeterminant (Class)
This class handles the locking handshakes and the state required to calculate the
determinant of a matrix over the course of multiple scans.
If the purpose behind calculating the determinant is a check before inverting a
matrix or as part of the process of solving a system of equations this class is not
the most optimal to use. In these cases, it is better to use the class_MatrixInvert
or the class_MatrixGaussianElim object instead as the overhead for all three is
similar.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

LockMatrices (Method)
This method primes the class to calculate the determinant of a new matrix. It
must be called before each operation to be performed.

Inputs/Outputs
Name IEC 61131 Type Description

original class_Matrix The matrix to calculate the determinant of. This


matrix is left unchanged.

workspace class_Matrix Memory to do the calculation in. If this is the same


size as original, no memory allocation will occur in
finding the determinant.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the operation is now ready.

Processing
1. Returns FALSE if original is not initialized.
2. Returns FALSE if workspace is not a separate matrix from original.
3. Returns FALSE if either of the matrices is busy doing any stepwise
operation.
4. Returns FALSE if original is not a square matrix.
5. Returns FALSE if workspace cannot be resized to the correct dimensions.
6. Returns FALSE if it cannot lock all matrices involved in the operation.
7. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.
8. The contents of workspace are destroyed by this method.

Date Code 20241023 Programming Reference


674 MathMatrix
Classes

ProcessSteps (Method)
This method computes the determinant of an already locked-in matrix.

The operation will perform the next steps sub-operations of the complete task.

Inputs/Outputs

Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Outputs

Name IEC 61131 Type Description

determinant struct_ComplexRect The determinant of the matrix. Zero if the


calculation is incomplete or the matrix is not
invertible.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the operation completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Decrements steps by the number of sub-operations performed.
3. Returns TRUE and outputs the calculated determinant if the algorithm
completed before steps was exhausted.
4. Returns FALSE and outputs a determinant of zero if LockMatrices()
has not been called or steps was exhausted before completing the
algorithm.
5. In the case that the matrix is not invertible, outputs a determinant of zero.

ProcessTimed (Method)
This method computes the determinant of an already locked-in matrix.

The operation will perform work for the next duration microseconds toward the
complete matrix operation.

Inputs/Outputs

Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Programming Reference Date Code 20241023


MathMatrix 675
Classes

Outputs
Name IEC 61131 Type Description

determinant struct_ComplexRect The determinant of the matrix. Zero if the


calculation is incomplete or the matrix is not
invertible.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the operation completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Performs work toward completing the algorithm, in groups of steps, until
duration microseconds is exceeded.
3. Decrements duration by the microseconds consumed.
4. Returns TRUE and outputs the calculated determinant if the operation
completed before duration was exhausted.
5. Returns FALSE and outputs a determinant of zero if LockMatrices()
has not been called or duration was exhausted before completing the
algorithm.
6. In the case that the matrix is not invertible, outputs a determinant of zero.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

class_MatrixGaussianElim (Class)
This class handles the locking handshakes and the state required to simplify
the matrix to a diagonal ones matrix with trailing columns using Gaussian
elimination over the course of multiple scans. The contents of coefficients are
destroyed and the contents of solutions are modified by this class.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

Date Code 20241023 Programming Reference


676 MathMatrix
Classes

LockMatrices (Method)
This method primes the class to perform the Gaussian elimination. It must be
called before each calculation to be performed.

Inputs/Outputs

Name IEC 61131 Type Description

coefficients class_Matrix The coefficients of the variables being solved for.

solutions class_Matrix The right hand side of the system of equations.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the Gaussian elimination is now ready.

Processing
1. Returns FALSE if either matrix is not initialized.
2. Returns FALSE if coefficients is not a separate matrix from solutions.
3. Returns FALSE if either matrix is busy doing any stepwise operation.
4. Returns FALSE if coefficients has fewer columns than rows.
5. Returns FALSE if solutions is not one column with the same number of
rows as coefficients.
6. Returns FALSE if it cannot lock both matrices involved in the operation.
7. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.

ProcessSteps (Method)
This method performs Gaussian elimination on two already locked-in matrices.

The operation will perform the next steps sub-operations of the complete
calculation.

Inputs/Outputs

Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Outputs

Name IEC 61131 Type Description

error BOOL This algorithm cannot solve this system of equations.

Programming Reference Date Code 20241023


MathMatrix 677
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the Gaussian elimination completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Reduces the first Rows • Rows of coefficients to an identity matrix using
elementary row operations.
3. Performs the same row operations on solutions.
4. If at any time the row operations cannot reduce coefficients further and
there is still not an identity matrix on the left, the operation is terminated
and error is set.
5. Decrements steps by the number of operations performed.
6. Returns TRUE if the Gaussian elimination completed before steps was
exhausted.
7. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.
8. The contents of coefficients are destroyed and the contents of solutions
are modified by this method.

Output Combination Meanings

Error Return Description

FALSE FALSE This should never occur.

FALSE TRUE The Gaussian elimination completed successfully.

TRUE FALSE The matrix state prevented the Gaussian elimination request.

TRUE TRUE The matrix is not invertible and cannot be reduced by this
Gaussian elimination algorithm.

ProcessTimed (Method)
This method performs Gaussian elimination on two already locked-in matrices.

The operation will perform work for the next duration microseconds toward the
complete inversion algorithm.

Inputs/Outputs

Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Date Code 20241023 Programming Reference


678 MathMatrix
Classes

Outputs

Name IEC 61131 Type Description

error BOOL This algorithm cannot solve this system of equations.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the Gaussian elimination completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Reduces the first Rows • Rows of coefficients to an identity matrix using
elementary row operations.
3. Performs the same row operations on solutions.
4. If at any time the row operations cannot reduce coefficients further and
there is still not an identity matrix on the left, the operation is terminated
and error is set.
5. Performs work toward completing the algorithm, in groups of steps, until
duration microseconds is exceeded.
6. Decrements duration by the microseconds consumed.
7. Returns TRUE if the Gaussian elimination completed before duration
was exhausted.
8. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.
9. The contents of coefficients are destroyed and the contents of solutions
are modified by this method.

The table, listed for the previous method, is provided as reference for
interpreting output combinations.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

Programming Reference Date Code 20241023


MathMatrix 679
Classes

class_MatrixInvert (Class)
This class handles the locking handshakes and the state required to create the
inverse of a square matrix over the course of multiple scans. The contents of
original are destroyed in the process so if the data are still desired, they must be
copied before this class is used. The entire operation will complete before the
function returns.

One common use case for inverting a matrix is to solve a system of equations.
In this library that use case is discouraged unless solving the same system for
many solutions as Gaussian elimination performs the same functionality with
less overhead.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

LockMatrices (Method)
This method primes the class to invert a matrix. (result = original–1). It must be
called before each inversion to be performed.

Inputs/Outputs
Name IEC 61131 Type Description

original class_Matrix The matrix to invert.

result class_Matrix The inverted matrix.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the inversion operation is now ready.

Processing
1. Returns FALSE if original is not initialized.
2. Returns FALSE if result is not a separate matrix from original.
3. Returns FALSE if any of the matrices is busy doing any stepwise
operation.
4. Returns FALSE if original is not a square matrix.
5. Returns FALSE if result cannot be sized correctly to store the product.
6. Returns FALSE if it cannot lock all matrices involved in the operation.
7. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.
8. The contents of result are destroyed by this method.

Date Code 20241023 Programming Reference


680 MathMatrix
Classes

ProcessSteps (Method)
This method performs the inversion algorithm on two already locked-in
matrices.

The operation will perform the next steps sub-operations of the complete
inversion algorithm.

Inputs/Outputs

Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Outputs

Name IEC 61131 Type Description

error BOOL The matrix is not invertible.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the inversion completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Sets result to an identity matrix.
3. Reduces original to an identity matrix using elementary row operations.
4. Performs the same row operations on result to create the inverse.
5. If at any time the row operations cannot reduce original further and it is
still not an identity matrix, the operation is terminated and error is set.
6. Decrements steps by the number of operations performed.
7. Returns TRUE if the inversion algorithm completed before steps was
exhausted.
8. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.
9. The contents of original are destroyed by this method.

ProcessTimed (Method)
This method performs the inversion algorithm on two already locked-in
matrices.

The operation will perform work for the next duration microseconds toward the
complete inversion algorithm.

Programming Reference Date Code 20241023


MathMatrix 681
Classes

Inputs/Outputs

Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Outputs

Name IEC 61131 Type Description

error BOOL The matrix is not invertible.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the inversion completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Sets result to an identity matrix.
3. Reduces original to an identity matrix using elementary row operations.
4. Performs the same row operations on result to create the inverse.
5. If at any time the row operations cannot reduce original further and it is
still not an identity matrix, the operation is terminated and error is set.
6. Performs work toward completing the algorithm, in groups of steps, until
duration microseconds is exceeded.
7. Decrements duration by the microseconds consumed.
8. Returns TRUE if the inversion algorithm completed before duration was
exhausted.
9. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.
10. The contents of original are destroyed by this method.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

Date Code 20241023 Programming Reference


682 MathMatrix
Classes

class_MatrixMultiply (Class)
This class handles the locking handshakes and the state required to multiply two
class_Matrix objects over the course of multiple scans.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

LockMatrices (Method)
This method primes the class to perform a new multiply (result = matrix1 •
matrix2). It must be called before each multiply to be performed.

Inputs/Outputs
Name IEC 61131 Type Description

matrix1 class_Matrix The multiplicand.

matrix2 class_Matrix The multiplier.

result class_Matrix The matrix to store the product.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the multiply operation is now ready.

Processing
1. Returns FALSE if either matrix1 or matrix2 is not initialized.
2. Returns FALSE if result is not a separate matrix from both matrix1 and
matrix2.
3. Returns FALSE if any of the matrices are busy doing any stepwise
operation.
4. Returns FALSE if Cols of matrix1 does not match Rows of matrix2.
5. Returns FALSE if result cannot be sized correctly to store the product.
6. Returns FALSE if it cannot lock all matrices involved in the operation.
7. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.
8. The contents of result are destroyed by this method.

ProcessSteps (Method)
This method performs the multiplication algorithm on three already locked-in
matrices.

Programming Reference Date Code 20241023


MathMatrix 683
Classes

The operation will perform the next steps sub-operations of the complete
multiplication algorithm.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the multiplication completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Multiplies matrix1 by matrix2.
3. Decrements steps by the number of operations performed.
4. Returns TRUE if the multiply algorithm completed before steps was
exhausted.
5. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.

ProcessTimed (Method)
This method performs the multiplication algorithm on three already locked-in
matrices.

The operation will perform work for the next duration microseconds toward the
complete multiplication algorithm.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the multiplication completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Multiplies matrix1 by matrix2.

Date Code 20241023 Programming Reference


684 MathMatrix
Classes

3. Performs work toward completing the multiplication algorithm, in groups


of steps, until duration microseconds is exceeded.
4. Decrements duration by the microseconds consumed.
5. Returns TRUE if the multiply algorithm completed before duration was
exhausted.
6. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

class_MatrixSubtract (Class)
This class handles the locking handshakes and the state required to subtract one
class_Matrix object from another over the course of multiple scans.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

LockMatrices (Method)
This method primes the class to perform a new subtraction (result = matrix1 –
matrix2). It must be called before each subtraction to be performed.

Inputs/Outputs
Name IEC 61131 Type Description

matrix1 class_Matrix The minuend.

matrix2 class_Matrix The subtrahend.

result class_Matrix The difference of matrix1 – matrix2.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the subtraction operation is now ready.

Programming Reference Date Code 20241023


MathMatrix 685
Classes

Processing
1. Returns FALSE if either matrix1 or matrix2 is not initialized.
2. Returns FALSE if result is not a separate matrix from both matrix1 and
matrix2.
3. Returns FALSE any of the matrices are busy doing any stepwise
operation.
4. Returns FALSE if the dimensions of matrix1 do not match those of
matrix2.
5. Returns FALSE if result cannot be resized to match the dimensions of the
other two matrices.
6. Returns FALSE if it cannot lock all matrices involved in the operation.
7. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.
8. The contents of result are destroyed by this method.

ProcessSteps (Method)
This method performs the subtraction algorithm on three already locked-in
matrices.
The operation will perform the next steps sub-operations of the complete
subtraction algorithm.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the subtraction completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Subtracts each element in matrix2 from its corresponding element in
matrix1 and the difference in result.
3. Decrements steps by the number of sub-operations performed.
4. Returns TRUE if the subtraction algorithm completed before steps was
exhausted.
5. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.

ProcessTimed (Method)
This method performs the subtraction algorithm on three already locked-in
matrices.

Date Code 20241023 Programming Reference


686 MathMatrix
Classes

The operation will perform work for the next duration microseconds toward the
complete subtraction algorithm.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the subtraction completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Subtracts each element in matrix2 from its corresponding element in
matrix1 and stores the difference in result.
3. Performs work toward completing the subtraction algorithm, in groups of
steps, until duration microseconds is exceeded.
4. Decrements duration by the microseconds consumed.
5. Returns TRUE if the subtraction algorithm completed before duration
was exhausted.
6. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

class_MatrixTranspose (Class)
This class handles the locking handshakes and the state required to transpose a
class_Matrix object over the course of multiple scans.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

Programming Reference Date Code 20241023


MathMatrix 687
Classes

LockMatrices (Method)
This method primes the class to perform a new matrix transpose. It must be
called before each transpose to be performed.

Inputs
Name IEC 61131 Type Description

conjugate BOOL The result of this operation will be the Hermitian


Transpose. Before each element is placed in result, it
will be conjugated.

Inputs/Outputs
Name IEC 61131 Type Description

original class_Matrix The matrix to copy from.

result class_Matrix The matrix to copy to.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the transpose operation is now ready.

Processing
1. Returns FALSE if original is not initialized.
2. Returns FALSE if result is not a separate matrix from original.
3. Returns FALSE if either of the matrices is busy doing any stepwise
operation.
4. Returns FALSE if result cannot be resized to the correct dimensions.
5. Returns FALSE if it cannot lock all matrices involved in the operation.
6. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.
7. The contents of result are destroyed by this method.

ProcessSteps (Method)
This method transposes an already locked-in matrix.
The operation will perform the next steps sub-operations of the complete matrix
transpose.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Date Code 20241023 Programming Reference


688 MathMatrix
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the transpose completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Copies each element (i, j) from original to element (j, i) of result.
3. If conjugate was TRUE, conjugate each element in result.
4. Decrements steps by the number of sub-operations performed.
5. Returns TRUE if the transpose algorithm completed before steps was
exhausted.
6. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.

ProcessTimed (Method)
This method transposes an already locked-in matrix.

The operation will perform work for the next duration microseconds toward the
complete matrix transpose.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the transpose completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Copies each element (i, j) from original to element (j, i) of result.
3. If conjugate was TRUE, conjugate each element in result.
4. Performs work toward completing the transpose, in groups of steps, until
duration microseconds is exceeded.
5. Decrements duration by the microseconds consumed.
6. Returns TRUE if the transpose algorithm completed before duration was
exhausted.
7. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.

Programming Reference Date Code 20241023


MathMatrix 689
Classes

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

class_Matrix_ATA (Class)
This class handles the locking handshakes and the state required for an
optimization of the operation (ATA) transposing the input matrix and
multiplying it by the original matrix over the course of multiple scans.

Outputs
Name IEC 61131 Type Description

Busy BOOL This class has locked class_Matrix instances and is in


the middle of a calculation.

LockMatrices (Method)
This method primes the class to perform a new matrix operation ATA. It must be
called before each operation to be performed.

Inputs

Name IEC 61131 Type Description

conjugate BOOL The result of this operation will be calculated using


the Hermitian Transpose. Before the transpose step is
complete, each element will be conjugated.

Inputs/Outputs

Name IEC 61131 Type Description

original class_Matrix The matrix A.

result class_Matrix The matrix for the result.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the operation is now ready.

Date Code 20241023 Programming Reference


690 MathMatrix
Classes

Processing
1. Returns FALSE if original is not initialized.
2. Returns FALSE if result is not a separate matrix from original.
3. Returns FALSE if either of the matrices is busy doing any stepwise
operation.
4. Returns FALSE if result cannot be resized to the correct dimensions.
5. Returns FALSE if it cannot lock all matrices involved in the operation.
6. If all other checks succeeded, then stores required references, sets Busy to
TRUE, and returns TRUE.
7. The contents of result are destroyed by this method.

ProcessSteps (Method)
This method computes ATA of an already locked-in matrix.
The operation will perform the next steps sub-operations of the complete task.

Inputs/Outputs
Name IEC 61131 Type Description

steps UDINT The number of sub-operations to attempt this task


cycle.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the operation completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Decrements steps by the number of sub-operations performed.
3. Returns TRUE if the algorithm completed before steps was exhausted.
4. Returns FALSE if LockMatrices() has not been called or steps was
exhausted before completing the algorithm.

ProcessTimed (Method)
This method computes ATA of an already locked-in matrix.
The operation will perform work for the next duration microseconds toward the
complete matrix operation.

Inputs/Outputs
Name IEC 61131 Type Description

duration UDINT The number of microseconds to spend on this


calculation.

Programming Reference Date Code 20241023


MathMatrix 691
Benchmarks

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the operation completed.

Processing
1. Validates that LockMatrices() has been successfully called.
2. Performs work toward completing the algorithm, in groups of steps, until
duration microseconds is exceeded.
3. Decrements duration by the microseconds consumed.
4. Returns TRUE if the operation completed before duration was exhausted.
5. Returns FALSE if LockMatrices() has not been called or duration was
exhausted before completing the algorithm.

UnlockMatrices (Method)
This method unlocks any matrices locked by LockMatrices(). It only needs to
be called by the user if the matrix operation has been terminated early by calling
Clear() on any of the dependent matrices. In all other cases, the matrices will
be unlocked on completion of the algorithm.

Processing
1. Requests that all locked matrices free themselves for other operations.
2. Sets Busy to FALSE.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.
➤ SEL-3505
➢ R134 firmware
➤ SEL-3530
➢ R134 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V1 firmware

Benchmark Test Descriptions


Each benchmark is run on three different matrices: a 2 by 2, an 8 by 8, and a
64 by 64. All matrices used in the benchmarks are sized such that no memory
allocations occur during the benchmark run.

Date Code 20241023 Programming Reference


692 MathMatrix
Benchmarks

fun_DeleteMatrix
The posted time is the average execution time of 100 consecutive calls when
deleting a matrix.

fun_MatrixAdd
The posted time is the average execution time of 100 consecutive calls when
adding two matrices.

fun_MatrixCopyColumn
The posted time is the average execution time of 100 consecutive calls when
copying a column from one matrix to another.

fun_MatrixDeterminant
The posted time is the average execution time of 100 consecutive calls when
operating on a valid invertible matrix.

fun_MatrixGaussianElim
The posted time is the average execution time of 100 consecutive calls when
operating on a valid matrix that allows the algorithm to run to completion.

fun_MatrixInvert
The posted time is the average execution time of 100 consecutive calls when
inverting a matrix.

fun_MatrixMultiply
The posted time is the average execution time of 100 consecutive calls when
multiplying two matrices.

fun_MatrixSubtract
The posted time is the average execution time of 100 consecutive calls when
subtracting two matrices.

fun_MatrixTranspose
The posted time is the average execution time of 100 consecutive calls when
transposing a matrix.

fun_MatrixTranspose (Hermitian)
The posted time is the average execution time of 100 consecutive calls when
calculating the Hermitian transpose of a matrix.

Programming Reference Date Code 20241023


MathMatrix 693
Benchmarks

fun_Matrix_ATA
The posted time is the average execution time of 100 consecutive calls when
calculating ATA.

fun_Matrix_ATA (Hermitian)
The posted time is the average execution time of 100 consecutive calls when
calculating ATA when using the Hermitian transpose.

fun_NewMatrix
The posted time is the average execution time of 100 consecutive calls when
allocating a new matrix.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

fun_DeleteMatrix - 2x2 118 54 6

fun_DeleteMatrix - 8x8 105 49 4

fun_DeleteMatrix - 64x64 119 57 4

fun_MatrixAdd - 2x2 17 7 1

fun_MatrixAdd - 8x8 66 46 4

fun_MatrixAdd - 64x64 5408 3299 244

fun_MatrixCopyColumn - 2x2 7 2 1

fun_MatrixCopyColumn - 8x8 10 3 1

fun_MatrixCopyColumn - 64x64 61 36 1

fun_MatrixDeterminant - 2x2 69 41 3

fun_MatrixDeterminant - 8x8 1118 665 53

fun_MatrixDeterminant - 64x64 515458 292846 26267

fun_MatrixGaussianElim - 2x2 76 39 2

fun_MatrixGaussianElim - 8x8 1392 731 61

fun_MatrixGaussianElim - 64x64 516370 296721 26789

fun_MatrixInvert - 2x2 74 48 3

fun_MatrixInvert - 8x8 2092 1243 105

fun_MatrixInvert - 64x64 1034455 581496 52648

fun_MatrixMultiply - 2x2 26 15 2

fun_MatrixMultiply - 8x8 1002 626 51

fun_MatrixMultiply - 64x64 554947 325479 26534

fun_MatrixSubtract - 2x2 13 6 1

fun_MatrixSubtract - 8x8 90 41 4

Date Code 20241023 Programming Reference


694 MathMatrix
Examples

Platform (time in µs)


Operation Tested
SEL-3505 SEL-3530 SEL-3555

fun_MatrixSubtract - 64x64 5341 3066 242

fun_MatrixTranspose - 2x2 8 4 1

fun_MatrixTranspose - 8x8 29 12 1

fun_MatrixTranspose - 64x64 2447 1731 71

fun_MatrixTranspose (Hermitian) - 2x2 14 7 1

fun_MatrixTranspose (Hermitian) - 8x8 97 48 3

fun_MatrixTranspose (Hermitian) - 64x64 6071 3699 192

fun_Matrix_ATA - 2x2 26 15 1

fun_Matrix_ATA - 8x8 563 318 29

fun_Matrix_ATA - 64x64 308482 179945 13186

fun_Matrix_ATA (Hermitian) - 2x2 34 19 1

fun_Matrix_ATA (Hermitian) - 8x8 877 455 39

fun_Matrix_ATA (Hermitian) - 64x64 431940 239407 17341

fun_NewMatrix - 2x2 340 98 10

fun_NewMatrix - 8x8 87 39 5

fun_NewMatrix - 64x64 744 327 13

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.
Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Solving a System of Equations


Objective
The user desires to repeatably solve a system of equations for some set of
outputs. This example solves three equations for three unknowns.
For example, on a given scan the system of equations could be:

This becomes a 3x4 matrix which, after Gaussian elimination, appears as


follows:

Programming Reference Date Code 20241023


MathMatrix 695
Examples

By inspection the solution becomes:

Assumptions
Each scan the user has placed the values to use into a pair of arrays of
struct_ComplexRect objects, Values and Answers, before this program is called.

Solution
The user can call this program each scan to receive a solution for the provided
inputs, as shown in Code Snippet 22.1.
Code Snippet 22.1 prg_MatrixSolver
PROGRAM prg_MatrixSolver
VAR
(* Here are sample values to generate a matrix with a known solution
[[ 1 2 3 | 2 ]
[ 2 3 1 | 2 ]
[ 3 2 1 | 10 ]] *)
Values : ARRAY [0 .. 8] OF struct_ComplexRect :=
[(Re := 1), (Re := 2), (Re := 3),
(Re := 2), (Re := 3), (Re := 1),
(Re := 3), (Re := 2), (Re := 1)];
AnswerCol : ARRAY [0 .. 2] OF struct_ComplexRect :=
[(Re := 2), (Re := 2), (Re := 10)];
// The result should be [5, -3, 1]
Solution : ARRAY [0 .. 2] OF struct_ComplexRect;

CoefficientsMatrix : MathMatrix.class_Matrix(3, 3);


SolutionsMatrix : MathMatrix.class_Matrix(3, 1);
pt_Data : POINTER TO POINTER TO struct_ComplexRect;
Unsolved : BOOL;

Row : UINT;
Col : UINT;
END_VAR

//Load each row of the matrix


FOR Row := 0 to CoefficientsMatrix.Rows - 1 DO
pt_Data := CoefficientsMatrix.pt_Data;
// Load all but the answer column of the matrix
FOR Col := 0 TO CoefficientsMatrix.Cols - 1 DO
pt_Data[Row][Col] := Values[Row*(CoefficientsMatrix.Cols) + Col];
END_FOR
// Load the answer column after the final increment above
pt_Data := SolutionsMatrix.pt_Data;
pt_Data[Row][0] := AnswerCol[Row];
END_FOR

fun_MatrixGaussianElim(CoefficientsMatrix, SolutionsMatrix, error => Unsolved);


FOR Row := 0 to SolutionsMatrix.Rows - 1 DO
// If a solution was successfully found update the solution array.
IF NOT Unsolved THEN
pt_Data := SolutionsMatrix.pt_Data;
Solution[Row] := pt_Data[Row][0];
END_IF
END_FOR

Date Code 20241023 Programming Reference


696 MathMatrix
Examples

Manipulating a Matrix Across Multiple Scans


Objective
The user needs to manipulate a set of data in matrix form but has some set of
timing constraints that cause concern regarding the completion of the operations.

Assumptions
The user has created an enumeration to assist in managing the data flow to the
desired outcome.
Code Snippet 22.2 enum_States
TYPE enum_States :
(
IDLE,
BUILD_MATRICES,
SUM_MATRICES,
SCALE_RESULT,
STORE_RESULT,
ERROR
);
END_TYPE

Solution
The user can call this program each scan, as shown in Code Snippet 22.3,
to receive a solution for the provided inputs. When Begin is set to true, the
calculation will commence. When the program has copied the answer into
Solution, the program sets the Complete flag to true.
Code Snippet 22.3 prg_MatrixManipulation
PROGRAM prg_MatrixManipulation
VAR CONSTANT
c_StepsPerScan : UDINT := 5;
END_VAR
VAR
State : enum_States := IDLE;

Values1 : ARRAY [0 .. 11] OF struct_ComplexRect;


Values2 : ARRAY [0 .. 11] OF struct_ComplexRect;
Solution : ARRAY [0 .. 11] OF struct_ComplexRect;

Matrix1 : MathMatrix.class_Matrix(4, 3);


Matrix2 : MathMatrix.class_Matrix(4, 3);
MatrixEnd : MathMatrix.class_Matrix(4, 3);
Adder : MathMatrix.class_MatrixAdd;
Scalar : struct_ComplexRect := (Re := 2, Im := 0);
pt_Data1 : POINTER TO POINTER TO struct_ComplexRect;
pt_Data2 : POINTER TO POINTER TO struct_ComplexRect;

Row : UINT;
Col : UINT;
Steps : UDINT;
Scans : UDINT;
Begin : BOOL;
Complete : BOOL;
END_VAR

Steps := c_StepsPerScan;
Scans := Scans + 1;
WHILE Steps > 0 DO
CASE State OF

Programming Reference Date Code 20241023


MathMatrix 697
Examples

IDLE:
IF Begin THEN
State := BUILD_MATRICES;
Row := 0;
Col := 0;
Scans := 1;
pt_Data1 := Matrix1.pt_Data;
pt_Data2 := Matrix2.pt_Data;
Begin := FALSE;
Complete := FALSE;
Steps := Steps - 1;
ELSE
Scans := Scans - 1;
Steps := 0;
END_IF
BUILD_MATRICES:
// This is a state machine to load the matrix a few values at a time
Steps := Steps - 1;
pt_Data1[Row][Col] := Values1[Row*(Matrix1.Cols) + Col];
pt_Data2[Row][Col] := Values2[Row*(Matrix1.Cols) + Col];
Col := Col + 1;
IF Col = Matrix1.Cols THEN
Col := 0;
Row := Row + 1;
IF Row = Matrix1.Rows THEN
IF Adder.LockMatrices(Matrix1, Matrix2, MatrixEnd) THEN
State := SUM_MATRICES;
ELSE
State := ERROR;
END_IF
END_IF
END_IF
SUM_MATRICES:
IF Adder.ProcessSteps(steps) THEN
IF MatrixEnd.StartMatrixOperation(MATRIX_SCALE, 0, 0, Scalar) THEN
State := SCALE_RESULT;
ELSE
State := ERROR;
END_IF
END_IF
SCALE_RESULT:
IF MatrixEnd.MatrixStepScale(steps) THEN
State := STORE_RESULT;
Row := 0;
Col := 0;
END_IF
STORE_RESULT:
Steps := Steps - 1;
Solution[Row*(MatrixEnd.Cols) + Col] := MatrixEnd.pt_Data[Row][Col];
Col := Col + 1;
IF Col = MatrixEnd.Cols THEN
Col := 0;
Row := Row + 1;
IF Row = MatrixEnd.Rows THEN
State := IDLE;
Complete := TRUE;
Steps := 0;
END_IF
END_IF
ERROR:
Steps := 0;
END_CASE
END_WHILE

Date Code 20241023 Programming Reference


698 MathMatrix
Examples

Troubleshooting a Matrix
Objective
The user has designed a solution with matrices to perform some set of
calculations and something is not going as desired. The user would like to have
additional insight into the matrix element values for online troubleshooting.

Assumptions
This solution assumes a static matrix size. This is not required but if the
Rows and Cols variables of the matrix do not match the sizes provided for the
troubleshooting variable, the user must realize that only data up to the size of the
matrix are valid.

Solution
The user can add an additional pointer variable to provide additional insight
during runtime. The syntax for this pointer is shown in Code Snippet 22.4.
Code Snippet 22.4 prg_MatrixTroubleshoot
PROGRAM prg_MatrixTroubleshoot
VAR CONSTANT
c_Rows : UINT := 2;
c_Cols : UINT := 6;
END_VAR
VAR
Values1 : ARRAY [0 .. 11] OF struct_ComplexRect;

Matrix1 : MathMatrix.class_Matrix(c_Rows, c_Cols);

(* This is the troubleshooting variable that has been added. To be valid it must be
reassigned each time the memory allocated to the matrix could change, so the safest
usage is to assign it immediately before using it. *)
pt_Raw : POINTER TO ARRAY [0 .. c_Rows-1] OF
POINTER TO ARRAY [0 .. c_Cols-1] OF struct_ComplexRect;
END_VAR

// Load the matrix


(* The SysMemCpy command allows the movement of large quantities of contiguous data with
a single instruction. This can greatly increase the performance of large data copies.
If the destination and the source could overlap then the SysMemMove call facilitates
this with a little more overhead. *)
SysMemCpy(Matrix1.pt_Data[0], ADR(Values1),
c_Cols*SIZEOF(struct_ComplexRect));
SysMemCpy(Matrix1.pt_Data[1], ADR(Values1[6]),
c_Cols*SIZEOF(struct_ComplexRect));

(* Here is where we find some meaningful work up to the point of interest


for troubleshooting. *)

// Assign the troubleshooting variable. Now the data can be seen in online mode.
// This line is where a breakpoint would be added.
pt_Raw := Matrix1.pt_Data;

(* There is probably additional work to be accomplished after the point of interest as well *)

Programming Reference Date Code 20241023


S E C T I O N 2 3

PacketEncoding
Introduction
The PacketEncoding library provides functions and classes to decode from and
encode to common data representations.

Various functions translate bytes of data to and from classes that facilitate
storing information in an easy-to-use manner.

Special Considerations
Copying classes from this library causes unwanted behavior. This means the
following:

1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such
as:
// "C0328: Assignment not allowed for type class_VectorObject"
myVectorObject := otherVectorObject;

// This is fine
someVariable := myVectorObject.value;
// As is this
pt_myVectorObject := ADR(myVectorObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.0.4 and earlier can be used on RTAC firmware version R132 and
later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Date Code 20241023 Programming Reference


700 PacketEncoding
Enumerations

enum_Asn1ClassType
Enumeration Value Description

UNIVERSAL 0 The type is native to ASN.1.

APPLICATION 1 The type is only valid for one specific application.

CONTEXT_SPECIFIC 2 The meaning of this type depends on the context.

SPECIAL_PRIVATE 3 This type is defined in private specifications.

enum_Asn1UniversalClassTags
Enumeration Value

EOC 00

BOOLEAN 01

INTEGER 02

BIT_STRING 03

OCTET_STRING 04

NULL 05

OBJECT_IDENTIFIER 06

OBJECT_DESCRIPTOR 07

EXTERNAL 08

REAL_FLOAT 09

ENUMERATED 10

EMBEDDED_PDV 11

UTF8_STRING 12

RELATIVE_OID 13

RESERVED_1 14

RESERVED_2 15

SEQUENCE 16

SET 17

NUMERIC_STRING 18

PRINTABLE_STRING 19

T61_STRING 20

VIDEOTEX_STRING 21

IA5_STRING 22

UTC_TIME 23

GENERALIZED_TIME 24

GRAPHIC_STRING 25

VISIBLE_STRING 26

Programming Reference Date Code 20241023


PacketEncoding 701
Structures

Enumeration Value

GENERAL_STRING 27

UNIVERSAL_STRING 28

CHARACTER_STRING 29

BMP_STRING 30

LONG_FORM 31

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

struct_Asn1Index
Name IEC 61131 Type Description

Class enum_Asn1ClassType The class as defined by the first two


Identifier bits.

Constructed BOOL TRUE for constructed entries, FALSE for


primitive entries.

TagNumber enum_Asn1UniversalClassTags The type of the entry.

BytesInValue UDINT The number of content bytes.

Index UDINT The starting location of the content bytes


as a byte offset from the beginning of the
parsed byte array.

Functions
This library provides the following functions.

fun_IndexAsn1Packet
Walk the provided byte array and populate a class_Asn1IndexVector with
the size, starting index, and type of each first level entry in an ASN.1 packet
as defined by the "Basic Encoding Rules" (BER), the superset of encoding
algorithms explained in the ASN.1 standard.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The packet to parse.

numBytes UDINT The number of bytes in the provided packet.

Date Code 20241023 Programming Reference


702 PacketEncoding
Functions

Inputs/Outputs
Name IEC 61131 Type Description

parsedData class_Asn1IndexVector The vector for storing the list of data types
and indices.

Return Value
IEC 61131 Type Description

BOOL TRUE if all data objects were indexed successfully.

Processing
The fun_IndexAsn1Packet() function does the following:
➤ Validates pt_data for readability.
➤ Clears all data from parsedData.
➤ Locates the beginning of each first-level data entry in the packet.
➤ Stores the class, tag number, and length in bytes of each entry found as
well as whether the entry is primitive or constructed.
➤ Stores the index zero for any objects of length zero.
➤ Stores the index of the first content byte of the entry as a byte offset from
pt_data for all other data types.
This is accomplished by traversing the entire byte array from the beginning to
the end. Any failure in parsing data results in an error and the function stops
attempting to parse the provided data. The algorithm in use takes the first byte
and interprets it to find the type of data being encoded. If the function finds a
tag type of 0b11111 the next bytes are interpreted as the type of the data. If more
than 32 bits of data are used to encode the type, then this method will return an
error. The function interprets the next bytes as the length of the data.
Three length definitions are allowed:
1. A value less than 0x80 is a direct reference to the length. The function
tags the next byte as the index and skips to the end of the object as
defined by its length.
2. A value of 0x80 indicates that the length is not predefined. This value
is only allowed for constructed types. The function tags the next byte
as the index and immediately terminates the object. The function parses
subsequent objects for length and ignores the content until it finds one
End-of-Content object for each previously recorded length 0x80. The
length becomes the accumulation of all the sizes of the child objects,
including their headers.
3. A value between 0x81 and 0x84 indicates that one to four subsequent
bytes define the length of the object as an unsigned integer. The function
stores those bytes as the length and places the index directly after them.
It then skips to the end of the object as defined by its length and the next
object begins.
Though values larger than 0x84 are legal, they define numbers of bytes larger
than this library can index and result in an error.

Programming Reference Date Code 20241023


PacketEncoding 703
Functions

This process repeats for each object found until the end of the provided data.
If the final length sends the function beyond the end of the array or unclosed
length 0x80 objects remain, the function returns an error.

0101FF02038765430904A73546FF048180<128 Octets>
Becomes
0101FF BOOLEAN length 1 index 2
0203876543 INTEGER length 3 index 5
0904A73546FF REAL_FLOAT length 4 index 10
048180<128 Octets> OCTET_STRING length 128 index 17

fun_DecodeAsn1_Boolean
Decode a Boolean encoded in ASN.1 following the Basic Encoding Rules.

Inputs
Name IEC 61131 Type Description

data BYTE The byte to parse. This should be the byte at the
index returned by fun_IndexAsn1Packet().

Inputs/Outputs
Name IEC 61131 Type Description

value BOOL The result of parsing the data.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful parsing of the Boolean.

Processing
The fun_DecodeAsn1_Boolean() function does the following:

1. Parses the provided byte into a Boolean.


2. Returns TRUE if the function encountered no errors during parsing.

This function recognizes any non-zero value as TRUE and only the value of zero
as FALSE.

0b11001100 = TRUE
0b00000001 = TRUE
0b00000000 = FALSE

fun_DecodeAsn1_Integer
Decode an integer encoded in ASN.1 following the "Basic Encoding Rules."

Date Code 20241023 Programming Reference


704 PacketEncoding
Functions

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The byte array to parse. This should be


the address of the Index returned by
fun_IndexAsn1Packet().

numBytes UDINT The number of bytes in the provided data. This


should be the BytesInValue returned by
fun_IndexAsn1Packet().

Inputs/Outputs
Name IEC 61131 Type Description

value DINT The result of parsing the data.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful parsing of the integer.

Processing
The fun_DecodeAsn1_Integer() function does the following:

1. Validates pt_data for readability.


2. Parses the bytes provided into an integer.
3. Returns FALSE if rollover prevents the function from returning the exact
value.
4. Returns TRUE if the function encounters no errors during parsing.

This function expects the provided bytes to be an integer represented in two's


complement notation using the least number of bytes possible. It only parses
numbers represented by four or fewer bytes.

0x80 = –128
0xFF80 results in an error because it uses more bytes than necessary.
0x7F7F = 32639
0x007F7F results in an error because it uses more bytes than necessary.

fun_DecodeAsn1_Enumerated
Decode an enumeration encoded in ASN.1 following the "Basic Encoding
Rules."

Programming Reference Date Code 20241023


PacketEncoding 705
Functions

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The byte array to parse. This should be


the address of the Index returned by
fun_IndexAsn1Packet().

numBytes UDINT The number of bytes in the provided data. This


should be the BytesInValue returned by
fun_IndexAsn1Packet().

Inputs/Outputs
Name IEC 61131 Type Description

value DINT The result of parsing the data.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful parsing of the enumeration.

Processing
The fun_DecodeAsn1_Enumerated() function does the following:

1. Validates pt_data for readability.


2. Parses the bytes provided into an integer.
3. Returns FALSE if rollover prevents returning the exact value.
4. Returns TRUE if the function encountered no errors during parsing.

This function expects the provided bytes to be an integer represented in two's


complement notation using the least number of bytes possible. It only parses
numbers represented by four or fewer bytes.

0x80 = -128
0xFF80 results in an error because it uses more bytes than necessary.
0x7F7F = 32639
0x007F7F results in an error because it uses more bytes than necessary.

fun_DecodeAsn1_Object_Identifier
Decode an Object Identifier (OID) encoded in ASN.1 following the "Basic
Encoding Rules" to a list of UDINTs.

Date Code 20241023 Programming Reference


706 PacketEncoding
Functions

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The byte array to parse. This should


be the address of the index returned by
fun_IndexAsn1Packet().

numBytes UDINT The number of bytes in the provided data. This


should be the BytesInValue returned by
fun_IndexAsn1Packet().

Inputs/Outputs
Name IEC 61131 Type Description

value class_DwordVector The vector for storing the list of OID entries.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful parsing of the OID.

Processing
The fun_DecodeAsn1_Object_Identifier() function does the following:

1. Validates pt_data for readability.


2. Clears all data from value.
3. Parses the bytes provided into an OID.
4. Returns FALSE if rollover prevents the function from returning exact
values.
5. Returns TRUE if the function encountered no errors during parsing.

This function expects the provided bytes to appear as a sequence of unsigned


integers represented in the fewest bytes possible. Any byte with the value 1 as its
most significant bit indicates that the next byte is part of the same integer value.
A value of one in the most significant bit of the final byte of the referenced
data indicates the OID would extend beyond numBytes and the function returns
FALSE. If any unsigned integer begins with 0x80, the number is represented
by more bytes than required and the function returns FALSE. The function also
returns FALSE if any unsigned integer requires more than 32 bits to contain its
value.

After finding the first unsigned integer, the function parses it into two distinct
values. For this example, consider val to be the first unsigned integer found. If
val is between 0 and 39, the OID begins with 0.val. If val is between 40 and 79,
the OID begins with 1.(val-40). Finally, if val is greater than 79 the OID begins
with 2.(val-80).

0x2B0601040181F84F01952A0D040100
Broken into parts
0x2B 0x06 0x01 0x04 0x01 0x81F84F 0x01 0x952A 0x0D 0x04
0x01 0x00

Programming Reference Date Code 20241023


PacketEncoding 707
Functions

Extra formatting stripped


0x2B => 40 & 3 => 1.3
0x81F84F => 0b1_111_1000_100_1111 => 31823
0x952A => 0b1_0101_010_1010 => 2730
1.3.6.1.4.1.31823.1.2730.13.4.1.0

fun_DecodeAsn1_Real
Decode a floating point number encoded as ASN.1 in base 2, 8, or 16 according
to the "Basic Encoding Rules."

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The byte array to parse. This should


be the address of the index returned by
fun_IndexAsn1Packet().

numBytes UDINT The number of bytes in the provided data.


This should be the BytesInValue returned by
fun_IndexAsn1Packet().

Inputs/Outputs
Name IEC 61131 Type Description

value REAL The decoded floating point number.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful parsing of the number.

Processing
The fun_DecodeAsn1_Real() function does the following:
1. Validates pt_data for readability.
2. Validates the format and base found in pt_data.
3. Parses the bytes provided into a real.
4. Returns TRUE if the function encounters no errors during parsing.
The ASN.1 standard allows reals to be encoded through the use of both binary
values and character-based encodings. This function only decodes reals that are
encoded as binary values in base 2, 8, or 16.
The decoding of a real happens in eight steps:
1. This function checks for any special values (see Special Bit Patterns for
Reals for details).
2. If numBytes is two, this function returns FALSE because there are no
valid real encodings of length two.

Date Code 20241023 Programming Reference


708 PacketEncoding
Functions

3. This function checks the first byte to ensure it can be parsed. Bit 8 must
be one. Bit 7 stores the sign of the value. Bits 6–5 represent the base
of the number (B): 0b00 is base 2, 0b01 is base 8, 0b10 is base 16, and
0b11 is invalid. Bits 4–3 are interpreted as an unsigned number defining
a power of two by which to shift the result (F). Bits 2–1 help delineate
the length of the exponent in bytes. A value of 0b00 means one byte of
exponent, 0b01 two bytes, 0b10 three bytes, and 0b11 means the next
byte defines the length as a value from 0–255.
4. Because ASN.1 states the exponent must be represented in the fewest
bytes possible, this function rounds any value with an exponent of three
or more bytes to positive/negative zero or infinity because it cannot
represent numbers that large or small.
5. The exponent is parsed as a two's complement number (E) and saved.
6. The function interprets as many as the first four of the remaining bytes as
an unsigned integer.
7. Each byte greater than four results in the addition of eight to F, truncating
the mantissa (M) to a size this function can handle.
8. Finally, the function calculates the result as (M • 2F • BE), then adds the
appropriate sign.

0xD40C4567 M = 17767 E = 12 B = 8 F = 1
0x8DFF7F01030307 M = 16974599 E = –129 B = 2 F = 3
0x8DFF7F01030307AD M = 16974599 E = –129 B = 2 F = 11

Table 23.1 Special Bit Patterns for Reals

Length Bit Pattern Value

0 N/A +0.0

1 0b01000011 –0.0

1 0b01000000 +Infinity

1 0b01000001 –Infinity

1 0b01000010 NaN

fun_SerializeAsn1_Boolean
Place the provided Boolean value as the next entry in an ASN.1 BER message.

Inputs
Name IEC 61131 Type Description

value BOOL The value to use as the payload of this Boolean.

Inputs/Outputs
Name IEC 61131 Type Description

message class_ByteVector The message to which value is appended.

Programming Reference Date Code 20241023


PacketEncoding 709
Functions

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the Boolean.

Processing
The fun_SerializeAsn1_Boolean() function does the following:

1. Serializes value and appends it as the next entry in message.


2. Returns TRUE if value was added to message.

This function appends 0x010100 for FALSE and 0x010101 for TRUE.

fun_SerializeAsn1_Integer
Place the integer value provided as the next entry in an ASN.1 BER message.

Inputs
Name IEC 61131 Type Description

value DINT The value to use as the payload of this integer.

Inputs/Outputs
Name IEC 61131 Type Description

message class_ByteVector The message to which value is appended.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the integer.

Processing
The fun_SerializeAsn1_Integer() function does the following:

1. Serializes value and appends it as the next entry in message.


2. Returns TRUE if value was added to message.

This function determines the fewest number of bytes necessary to encode the
provided integer by checking the most significant byte and the next bit for all
ones or all zeros and dropping the byte from the number. This process can be
repeated as many as three times. After this process completes, it appends the
following to the message: 0x02, the number of significant bytes, and the bytes
themselves.

Date Code 20241023 Programming Reference


710 PacketEncoding
Functions

–1 0x0201FF
1 0x020101
134217728 0x02040F000000
–134217728 0x0204F8000000

fun_SerializeAsn1_Enumerated
Place the integer value provided as the next entry in an ASN.1 BER message.

Inputs
Name IEC 61131 Type Description

value DINT The value to use as the payload of this enumeration.

Inputs/Outputs
Name IEC 61131 Type Description

message class_ByteVector The message to which value is appended.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the enumeration.

Processing
The fun_SerializeAsn1_Enumerated() function does the following:

1. Serializes value and appends it as the next entry in message.


2. Returns TRUE if value was added to message.

This function determines the fewest number of bytes necessary to encode the
provided integer by checking the most significant byte and the next bit for all
ones or all zeros and dropping the byte from the number. This process can be
repeated as many as three times. After this process completes, it appends the
following to the message: 0x02, the number of significant bytes, and the bytes
themselves.

–1 0x0201FF
1 0x020101
134217728 0x02040F000000
–134217728 0x0204F8000000

fun_SerializeAsn1_Real
Place the real provided as the next entry in an ASN.1 BER message.

Programming Reference Date Code 20241023


PacketEncoding 711
Functions

Inputs
Name IEC 61131 Type Description

value REAL The value to use as the payload of this real.

Inputs/Outputs
Name IEC 61131 Type Description

message class_ByteVector The message to which value is appended.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the real.

Processing
The fun_SerializeAsn1_Real() function does the following:

1. Serializes value as a base 2 floating point number and appends it as the


next entry in message.
2. Returns true if value was added to message.

This function serializes every real as a base 2 binary encoded real. First, it
checks for any special value encodings as listed in Special Bit Patterns for
Reals. If this real is not a special case, this method breaks the real into its
constituent parts. This process consists of four steps:

1. The sign is pulled from Bit 32, the exponent from Bits 31 to 24, and the
mantissa from Bits 23 to 1.
2. If the exponent is zero, the mantissa is saved as is. Otherwise, the
function prepends a one to the mantissa as the 24th bit.
3. If the exponent is zero, a value of one is added to it. Then the function
subtracts 127 subtracted from the exponent to turn it into a two's
complement, signed number; the function also subtracts 23 from it to
remove the decimal point from the mantissa.
4. The function generates a descriptive byte where Bit 8 is one, Bit 7 is one
for negative and zero for positive, Bits 6–2 are zero, and Bit 1 is one for
an exponent requiring a two byte representation and zero for an exponent
requiring one byte.

This function then appends 0x09; a length of 0x00, 0x01, 0x05 or 0x06; the
descriptive byte; the exponent; and the mantissa to message.

2.25 0x090580EA900000
–2.25 0x0905C0EA900000
1.25E-38 0x090681FF6B881CEA
1.25E-41 0x090681FF6B0022D8

Date Code 20241023 Programming Reference


712 PacketEncoding
Functions

fun_SerializeAsn1_Object_Identifier
Place the OID provided as the next entry in an ASN.1 BER message.

Inputs/Outputs
Name IEC 61131 Type Description

value class_DwordVector The OID to append to message.

message class_ByteVector The message to which value is appended.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the OID.

Processing
The fun_SerializeAsn1_Object_Identifier() function does the
following:

1. Serializes all dwords in value to construct the next entry in message.


2. Returns FALSE if value cannot be serialized.
3. Returns TRUE if value was added to message.

This function starts by adding the first two OID sub entries together ((40 •
OID1) + OID2). Using that result as the first sub entry, it builds a list where
each OID sub entry is reduced to the minimum number of seven-bit segments
needed to represent it as an unsigned value. The function prepends a one to each
seven-bit segment except the least significant seven-bit segment of every sub
entry, which the function prepends with a zero. Once all sub entries have been
encoded, the function appends the following to message: 0x06, the number of
bytes representing the sub entries encoded in the same manner as the sub entries
themselves, and the sub entry list.

1.3.6.1.4.1.31823.1.2730.13.4.4.213268340
Insert Extra formatting
OID Enumeration => 0x06
1.3 => 40 & 3 => 0x2B
.6.1.4.1 => 0x06010401
.31823 => 0x7C4F => 0x81F84F
.1 => 0x01
.2730 => 0x0AAA => 0x952A
.13.4.4 => 0x0D0404
.213268340 => 0xCB63774 => 0xE5D8EE74
length => 18 => 0x12
Construct as Enumeration, Length, SubEntry list
0x06122B0601040181F84F01952A0D0404E5D8EE74

fun_SerializeAsn1_Bit_String
Place the bit string provided as the next entry in an ASN.1 BER message.

Programming Reference Date Code 20241023


PacketEncoding 713
Functions

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The bit string to insert.

numBytes UDINT The number of bytes in the string.

ignoreBits USINT The number of bits of invalid data terminating


the string. (Range: 0–7)

Inputs/Outputs
Name IEC 61131 Type Description

message class_ByteVector The message to which the bit string is appended.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the bit string.

Processing
The fun_SerializeAsn1_Bit_String() function does the following:

1. Validates pt_data for read access.


2. Limits ignoreBits to a maximum of seven.
3. Appends an entry containing all bytes prescribed to message, masking the
last ignoreBits bits of the last byte by replacing then with zero.
4. Returns true if the entire bit string was added to message.

This function appends 0x03, numBytes plus one for the ignoreBits information
as the length, ignoreBits, and the data found at pt_data to message, zeroing the
final ignoreBits bits.

fun_BeginAsn1Constructed_Bit_String
Place the codes necessary to begin a constructed bit string in an ASN.1 BER
message.

For each call to this method the user must call fun_AppendAsn1_Eoc() before
the message can be considered complete. Only bit strings should be appended to
message until the call to fun_AppendAsn1_Eoc().

Inputs/Outputs
Name IEC 61131 Type Description

message class_ByteVector The message to which the entry is appended.

Date Code 20241023 Programming Reference


714 PacketEncoding
Functions

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the entry.

Processing
The fun_BeginAsn1Constructed_Bit_String() function:

1. Appends the beginning of a constructed bit string to message, (0x2380).


2. Returns TRUE if the entry was added to message.

fun_AppendAsn1_Eoc
Place the codes necessary to end a variable length entry in an ASN.1 BER
message.

To ensure proper packet construction, the user must call this function once for
each variable length entry begun.

Inputs/Outputs
Name IEC 61131 Type Description

message class_ByteVector The message to which the entry is appended.

Return Value
IEC 61131 Type Description

BOOL TRUE for successful appending of the EOC.

Processing
The fun_AppendAsn1_Eoc() function does the following:

1. Appends the End-of-Content entry to message, 0x0000).


2. Returns TRUE if the EOC was added to message.

fun_EncodeBase64_MIME
Encodes a byte vector into base64-MIME format. See base64 and MIME
descriptions in RFC 2045 for complete definition of these encodings and their
usage. A common example is encoding the bytes of a file to be sent as email
attachments.

Programming Reference Date Code 20241023


PacketEncoding 715
Functions

Inputs/Outputs
Name IEC 61131 Type Description

source class_ByteVector The raw byte data to encode.

encoded class_ByteVector The encoded output of source.

Return Value
IEC 61131 Type Description

BOOL TRUE if data was successfully encoded; returns FALSE only if source
was empty.

Processing
The fun_EncodeBase64_MIME() function does the following:

1. Encodes the raw-bytes of source, writing the base64-MIME encoded


output to encoded. Note that source will not be modified as a result of
calling this function.
2. Returns TRUE if input was encoded successfully; returns FALSE only if
source was empty.

This function encodes a raw byte vector in base64-MIME. The output encoded
will be approximately 133% the size of source.

source := Drink plenty of Ovaltine


encoded := RHJpbmsgcGxlbnR5IG9mIE92YWx0aW5l

fun_DecodeBase64_MIME
Decodes a byte vector encoded in base64-MIME format. See base64 and MIME
descriptions in RFC 2045 for complete definition of these encodings and their
usage.

Inputs/Outputs
Name IEC 61131 Type Description

source class_ByteVector The base64-MIME encoded data to decode.

decoded class_ByteVector The decoded output of source.

Return Value
IEC 61131 Type Description

BOOL TRUE if data was successfully decoded without any corruption detected.
Returns FALSE if source contains only invalid characters or if the
number of valid characters in source is not a multiple of four.

Date Code 20241023 Programming Reference


716 PacketEncoding
Classes

Processing
The fun_DecodeBase64_MIME() function does the following:
1. Decodes the base64-MIME encoded input of source, placing output in
decoded. Invalid, non-base64 characters in source are ignored. Note that
source will not be modified as a result of calling this function.
2. Processes valid base64 characters in groups of four. It fails only if
terminal characters are incorrectly placed or if the number of valid
characters is not a multiple of four.
3. Stops processing after the first group of four characters containing a
terminal character.
4. If source is empty, then the function will return TRUE.
This function decodes a base64-MIME encoded string. The size of decoded will
be approximately 75% of source.

source := RHJpbmsgcGxlbnR5IG9mIE92YWx0aW5l
decoded := Drink plenty of Ovaltine

Classes
Classes are a particular implementation of a Function Block(FB). They provide
Methods and Properties, which a normal FB does not provide.

class_Asn1IndexVector (Class)
This class provides a DynamicVector structured specifically to store indexing
information about a byte array encoded in ASN.1.

NOTE
For more information on the I_Vector interface, see the DynamicVectors
library documentation.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_Vector

GetAt (Method)
Provides a copy of the element at the specified index.

Inputs
Name IEC 61131 Type Description

index UDINT The index of the desired element in the vector.

Programming Reference Date Code 20241023


PacketEncoding 717
Classes

Outputs

Name IEC 61131 Type Description

element struct_Asn1Index The element at the specified index. If the return


value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if index is valid and the element is copied. FALSE if index is
invalid or an error occurs.

SetAt (Method)
This method provides write access to any element within the vector.

Inputs

Name IEC 61131 Type Description

index UDINT The index at which to set the value of an element.

value struct_Asn1Index The new element value.

Return Value

IEC 61131 Type Description

BOOL TRUE if the element is successfully modified. If index is invalid, the


vector is not modified and the method returns FALSE.

Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.

Outputs

Name IEC 61131 Type Description

element struct_Asn1Index A copy of the former last element in the vector. If


the return value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if element is successfully copied and removed from the vector.
FALSE if the size is zero or an error occurs.

Date Code 20241023 Programming Reference


718 PacketEncoding
Benchmarks

Push (Method)
This method appends a copy of the provided element to the end of the vector.

Inputs
Name IEC 61131 Type Description

element struct_Asn1Index The element to copy to the end of the vector.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the vector. FALSE if an


error occurs.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.
➤ SEL-3505
➢ R134 firmware
➤ SEL-3530
➢ R134 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V1 firmware

Benchmark Test Descriptions


fun_IndexAsn1Packet
The posted time is the average execution time of 100 consecutive calls. The byte
string parsed is loaded with two Boolean values and three integer values.

fun_DecodeAsn1_Boolean
The posted time is the average execution time of 100 consecutive calls.

fun_DecodeAsn1_Integer
The posted time is the average execution time of 100 consecutive calls.

fun_DecodeAsn1_Enumerated
The posted time is the average execution time of 100 consecutive calls.

Programming Reference Date Code 20241023


PacketEncoding 719
Benchmarks

fun_DecodeAsn1_Object_Identifier
The posted time is the average execution time of 100 consecutive calls. The
encoded object identifier that is decoded has a value of (1, 17, 19).

fun_DecodeAsn1_Real
The posted time is the average execution time of 100 consecutive calls.

fun_SerializeAsn1_Boolean
The posted time is the average execution time of 100 consecutive calls.

fun_SerializeAsn1_Integer
The posted time is the average execution time of 100 consecutive calls.

fun_SerializeAsn1_Enumerated
The posted time is the average execution time of 100 consecutive calls.

fun_SerializeAsn1_Real
The posted time is the average execution time of 100 consecutive calls.

fun_SerializeAsn1_Object_Identifier
The posted time is the average execution time of 100 consecutive calls. The
object identifier encoded has a value of (1, 17, 19).

fun_SerializeAsn1_Bit_String
The posted time is the average execution time of 100 consecutive calls. The bit
string encoded has an ASCII value of "Hello World".

fun_BeginAsn1Constructed_Bit_String
The posted time is the average execution time of 100 consecutive calls.

fun_AppendAsn1_Eoc
The posted time is the average execution time of 100 consecutive calls.

fun_EncodeBase64_MIME—No Memory Allocation


The posted time is the average execution time of 100 consecutive calls when
encoding a sequence of 100 random bytes. For this benchmark, the encoded
vector is sized such that no memory allocation is required during the benchmark
run.

Date Code 20241023 Programming Reference


720 PacketEncoding
Benchmarks

fun_EncodeBase64_MIME—Internal Memory Allocation


The posted time is the average execution time of 100 consecutive calls when
encoding a sequence of 100 random bytes. For this benchmark, the encoded
vector is empty with no memory allocated, thus requiring memory allocations
during the benchmark run.

fun_DecodeBase64_MIME—No Memory Allocation


The posted time is the average execution time of 100 consecutive calls when
decoding a sequence of 100 randomly encoded bytes. Note that because the
output is 100 bytes, the input vector is more than 100 bytes. For this benchmark,
the decoded vector is sized such that no memory allocation is required during
the benchmark run.

fun_DecodeBase64_MIME—Internal Memory Allocation


The posted time is the average execution time of 100 consecutive calls when
decoding a sequence of 100 randomly encoded bytes. Note that because the
output is 100 bytes, the input vector is more than 100 bytes. For this benchmark,
the encoded vector is empty with no memory allocated, thus requiring memory
allocations during the benchmark run.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

fun_IndexAsn1Packet 30 15 1

fun_DecodeAsn1_Boolean 1 1 1

fun_DecodeAsn1_Integer 3 2 1

fun_DecodeAsn1_Enumerated 2 2 1

fun_DecodeAsn1_Object_Identifier 19 8 1

fun_DecodeAsn1_Real 10 5 1

fun_SerializeAsn1_Boolean 4 2 1

fun_SerializeAsn1_Integer 8 4 1

fun_SerializeAsn1_Enumerated 8 5 1

fun_SerializeAsn1_Real 6 3 1

fun_SerializeAsn1_Object_Identifier 159 42 4

fun_SerializeAsn1_Bit_String 18 9 1

fun_BeginAsn1Constructed_Bit_String 8 3 1

fun_AppendAsn1_Eoc 6 3 1

fun_EncodeBase64_MIME - No Allocation 432 234 25

fun_EncodeBase64_MIME - Allocation 637 291 28

Programming Reference Date Code 20241023


PacketEncoding 721
Examples

Platform (time in µs)


Operation Tested
SEL-3505 SEL-3530 SEL-3555

fun_DecodeBase64_MIME - No Allocation 430 240 21

fun_DecodeBase64_MIME - Allocation 699 307 25

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Decoding an ASN.1 Packet for All Integer Values


Objective
A user has a system that sends packets of data containing a mixture of integer
values and octet string descriptions. She needs to use the integers to make
decisions but has no need of the strings on this RTAC. This solution parses the
packet and collects the four integer values it contains.

Assumptions
This example shows the parsing of a static byte array. To truly use this
functionality, the user would need to populate that array after collecting the data
from the network.

Solution
The user can create the program found in Code Snippet 23.1 to parse the byte
array.
Code Snippet 23.1 prg_ParseBytesForIntegers
PROGRAM prg_ParseBytesForIntegers
VAR
PacketBytes : ARRAY [0 .. 99] OF BYTE :=
[
(*The string Value1*)
16#04, 16#06, 16#56, 16#61, 16#6C, 16#75, 16#65, 16#31,
(*The integer 10_000*)
16#02, 16#02, 16#27, 16#10,
(*The string Value2*)
16#04, 16#06, 16#56, 16#61, 16#6C, 16#75, 16#65, 16#32,
(*The integer -50_000*)
16#02, 16#03, 16#FF, 16#3C, 16#B0,
(*The string Value3*)
16#04, 16#06, 16#56, 16#61, 16#6C, 16#75, 16#65, 16#33,
(*The integer 15*)
16#02, 16#01, 16#0F,
(*The string Value4*)
16#04, 16#06, 16#56, 16#61, 16#6C, 16#75, 16#65, 16#34,
(*The integer 1_500_000_000*)

Date Code 20241023 Programming Reference


722 PacketEncoding
Examples

16#02, 16#04, 16#59, 16#68, 16#2F, 16#00,


(*This is the end of the meaningful data. The array here is bigger than required
as a reminder that this may need to be populated with different values that take
more or less space.*)
50(0)];
// The number of bytes of valid data. This will come from the network socket.
ValidByteCount : UDINT := 50;

// Containers for parsed data.


IndexList : class_Asn1IndexVector;
IndexObject : struct_Asn1Index;

// Iterator counts.
ListPosition : UDINT;
ObjectCount : UDINT;

//The result array.


IntArray : ARRAY [0 .. 3] OF DINT;

// Flags for any errors that might be encountered.


Parsed : BOOL;
CorrectCount : BOOL;
ValidInts : ARRAY [0 .. 3] OF BOOL;
END_VAR

// Reset the ValidInts array in case there are less Integers this pass.
FOR ObjectCount := 0 TO 3 DO
ValidInts[ObjectCount] := FALSE;
END_FOR
// First parse the current packet for its indexes.
Parsed := fun_IndexAsn1Packet(ADR(PacketBytes), ValidByteCount, IndexList);
IF Parsed THEN
// If that worked walk the indices and parse each integer found.
ObjectCount := 0;
ListPosition := 0;
WHILE ListPosition < IndexList.Size DO
IndexList.GetAt(ListPosition, element => IndexObject);
IF IndexObject.Class = UNIVERSAL AND IndexObject.Asn1Class = INTEGER THEN
// Make sure we are inside the bounds of our array.
IF ObjectCount > 3 THEN
// Set an error flag to indicate too many integers found.
CorrectCount := FALSE;
EXIT;
END_IF
ValidInts[ObjectCount] := fun_DecodeAsn1_Integer(
// Begin at the Index found.
ADR(PacketBytes[IndexObject.Index]),
// Walk the number of bytes specified.
IndexObject.BytesInValue,
// Place the result in the storage array.
IntArray[ObjectCount]);
ObjectCount := ObjectCount + 1;
END_IF
ListPosition := ListPosition + 1;
END_WHILE
IF ObjectCount <> 4 THEN
// Set an error flag if too few integers found.
CorrectCount := FALSE;
END_IF
END_IF

Decoding an OID Found Three Layers Deep in an ASN.1 Packet


Objective
A user receives a package with an OID nested three layers deep inside. He needs
to decode that OID before making a work decision.

Programming Reference Date Code 20241023


PacketEncoding 723
Examples

Assumptions
This example shows the parsing of a static byte array. To truly use this
functionality the user would need to populate that array after collecting the data
from the network.

Solution
The user can create the program found in Code Snippet 23.2 to parse the byte
array.
Code Snippet 23.2 prg_ParseThreeTiers
PROGRAM prg_ParseThreeTiers
VAR
PacketBytes : ARRAY [0 .. 99] OF BYTE :=
[
(*Constructed sequence*)
16#30, 16#13,
(*Constructed sequence*)
16#30, 16#11,
(*OID 1.3.6.1.4.1.31823.1.2730.13.4.1.0*)
16#06, 16#0F, 16#2B, 16#06, 16#01, 16#04, 16#01, 16#81, 16#F8,
16#4F, 16#01, 16#95, 16#2A, 16#0D, 16#04, 16#01, 16#00,
(*This is the end of the meaningful data. The array here is bigger than
required as a reminder that this may need to be populated with different values
that take more or less space. *)
79(0)];
// The number of bytes of valid data. This will come from the network socket.
ValidByteCount : UDINT := 21;

// Containers for each tier.


Tier1Objects : class_Asn1IndexVector;
Tier2Objects : class_Asn1IndexVector;
Tier3Objects : class_Asn1IndexVector;
IndexObjectT1 : struct_Asn1Index;
IndexObjectT2 : struct_Asn1Index;
IndexObjectT3 : struct_Asn1Index;

// Flags to allow for separation of logic


ParsedL1 : BOOL;
ParsedL2 : BOOL;
ParsedL3 : BOOL;
ValidOid : BOOL;

// Container for the OID


Oid : PacketEncodings.class_DwordVector;
END_VAR

// Reset from last scan


ParsedL2 := FALSE;
ParsedL3 := FALSE;
ValidOid := FALSE;

// Parse the first tier.


ParsedL1 := fun_IndexAsn1Packet(ADR(PacketBytes), ValidByteCount,
Tier1Objects);
IF ParsedL1 THEN
IF Tier1Objects.GetAt(0, element => IndexObjectT1) THEN
IF IndexObjectT1.Constructed THEN
ParsedL2 := fun_IndexAsn1Packet(
// The new starting index is the original offset plus the
// index identified in the previous level.
ADR(PacketBytes[IndexObjectT1.Index]),
// Only parse the bytes prescribed by the previous object.
IndexObjectT1.BytesInValue, Tier2Objects);
END_IF

Date Code 20241023 Programming Reference


724 PacketEncoding
Examples

END_IF
END_IF
IF parsedL2 THEN
IF Tier2Objects.GetAt(0, element => IndexObjectT2) THEN
IF IndexObjectT2.Constructed THEN
ParsedL3 := fun_IndexAsn1Packet(
// The new starting index is the original offset plus the
// offset of the first tier object plus
// index identified in the previous level.
ADR(PacketBytes[IndexObjectT1.Index + IndexObjectT2.Index]),
// Only parse the bytes prescribed by the previous object.
IndexObjectT2.BytesInValue, Tier3Objects);
END_IF
END_IF
END_IF
IF ParsedL3 THEN
IF Tier3Objects.GetAt(0, element => IndexObjectT3) THEN
IF IndexObjectT3.ClassEnum = UNIVERSAL AND
IndexObjectT3.Asn1Class = OBJECT_IDENTIFIER THEN
ValidOid := fun_DecodeAsn1_Object_Identifier(
// Here the starting index is based on all three tiers.
ADR(PacketBytes[ IndexObjectT1.Index
+ IndexObjectT2.Index
+ IndexObjectT3.Index]),
IndexObjectT3.BytesInValue,
Oid);
END_IF
END_IF
END_IF
IF ValidOid THEN
; // Do any necessary work based on the OID here.
END_IF

Encoding Data as an ASN.1 Packet


Objective
A user needs to package some integer and real data points. She also needs to
intersperse the data with Boolean flags based on the validity of the data.

Once the data are packaged the user needs to send the information to Port 1000
of a listening server.

Assumptions
The RTAC also has access to the SELEthernetControllers library. The listening
server must know the format of the incoming data.

Solution
The user can create the program found in Code Snippet 23.3 to build the data
package.
Code Snippet 23.3 prg_EncodeOutboundData
PROGRAM prg_EncodeOutboundData
VAR
// The storage for the outbound packet.
Packet : PacketEncodings.class_ByteVector;

// The integers to encode.


MyInts : ARRAY [1 .. 3] OF DINT := [–70, 45, 9000];

Programming Reference Date Code 20241023


PacketEncoding 725
Examples

MyIntsValid : ARRAY [1 .. 3] OF BOOL := [FALSE, TRUE, TRUE];

// The reals to encode.


MyReals : ARRAY [1 .. 3] OF REAL := [1045.99, 45.2, 7];
MyRealsValid : ARRAY [1 .. 3] OF BOOL := [TRUE, FALSE, TRUE];

// Infrastructure required to place the packet on the wire.


MySocket : class_TcpClient;
LocalIP : SELEthernetController.INADDR := (ulAddr := 0);
DestinationIP : SELEthernetController.INADDR;
SocketInitialized : BOOL;

// Counting variable.
i : UDINT;
END_VAR

// Make sure the socket is configured correctly.


IF NOT SocketInitialized THEN
MySocket.bootstrap_SetLocalIP(1000, localIP);
fun_StringToInaddr('10.10.10.10', ipAddr => DestinationIP);
MySocket.SetIP(destinationIP, 1000);
MySocket.Open();
SocketInitialized := TRUE;
END_IF

// Build the packet.


Packet.Recycle();
FOR i := 1 TO 3 DO
fun_SerializeAsn1_Integer(myInts[i], Packet);
fun_SerializeAsn1_Boolean(myIntsValid[i], Packet);
END_FOR
FOR i := 1 TO 3 DO
fun_SerializeAsn1_Real(myReals[i], Packet);
fun_SerializeAsn1_Boolean(myRealsValid[i], Packet);
END_FOR

// Send the data.


MySocket.SendData(Packet.pt_Data, UDINT_TO_DINT(Packet.Size));

Encoding Raw Binary Data in Base64-MIME


Objective
A user needs to encode and store some binary data from the file system in
base64-MIME encoding. For illustrative purposes, the user saves their data to a
file.

Assumptions
The RTAC has access to the DynamicVectors and FileIo libraries and has a file
called binaryData.data in the /FILES folder of the virtual file system.

Date Code 20241023 Programming Reference


726 PacketEncoding
Examples

Solution
The user can create the program found in Code Snippet 23.4 to encode their data
in base64-MIME and store the encoded data to the local file system.
Code Snippet 23.4 prg_Base64_Example
PROGRAM prg_Base64_Example
VAR_INPUT
alarm : BOOL;
END_VAR
VAR
//State flags for file io operations
complete : BOOL := FALSE;
firstRead : BOOL := TRUE;
writeFile : BOOL := FALSE;
error : BOOL;
errorString : STRING(255);

//Location of the binary data the user wishes to encode


dataFile : STRING(255) := 'binaryData.data';
//Temporary location for the raw binary data
rawData : class_ByteVector;
//Temporary location for the encoded data
encodedData : class_ByteVector;
//File io objects
fileReader : class_FileReader();
fileWriter : class_Filewriter('encodedData.txt');
END_VAR

IF alarm THEN
IF NOT complete THEN
IF firstRead THEN
fileReader.ReadFile(dataFile);
firstRead := FALSE;
ELSIF fileReader.BytesInBuffer > 0 THEN
rawData.Recycle();
fileReader.AppendToVector(0,rawData);
//encode the raw data in base64-MIME
PacketEncodings.fun_EncodeBase64_MIME(source := rawData, encoded := encodedData);
writeFile := TRUE;
END_IF

IF writeFile THEN
fileWriter.AppendVector(encodedData);
writeFile := FALSE;
complete := TRUE;
END_IF

//log any errors


IF fileReader.Error THEN
error := TRUE;
errorString := fileReader.ErrorDesc;
END_IF
IF fileWriter.Error THEN
error := TRUE;
errorString := fileWriter.ErrorDesc;
END_IF
END_IF
END_IF

//called each scan to complete the read/write ops


fileReader.Run();
fileWriter.Run();

Programming Reference Date Code 20241023


S E C T I O N 2 4

PowerMetering
Introduction
This library provides objects for performing common power metering functions.
These functions provide event times for minimum and maximum thresholds,
accumulated energy over time, demand over a configurable length of time,
and KYZ/KY accumulators. Example applications include use of these
function blocks with Axion analog input, digital input, and/or CT/PT (current
transformer/potential transformer) modules.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.1.0 and later can be used on RTAC firmware version R132 and
later.

Function Blocks
fb_Maximum
Compare input value to stored maximum value, update output if greater, and
record the date/time of occurrence.

Initialization Inputs
Name IEC 61131 Type Description

settingsChange BOOL Flag to prevent setting outputs based on provided initial values; a value of TRUE results in
setting Maximum to zero and the time stamp to the present time.

initialValue REAL Maximum value to use for initialization if settingsChange is FALSE.

initialTime timestamp_t Time stamp value to use for initialization if settingsChange is FALSE.

Inputs
Name IEC 61131 Type Description

EN BOOL Flag to enable or disable maximum comparison.

AnalogQuantity REAL Value to check against Maximum.

Reset BOOL Flag to reset Maximum and time stamp.

Date Code 20241023 Programming Reference


728 PowerMetering
Function Blocks

Outputs
Name IEC 61131 Type Description

Maximum REAL Maximum value.

EventTime timestamp_t The moment at which Maximum was last


updated.

Processing
➤ If settingsChange is FALSE, the function block initializes to the values
passed in.
➤ If settingsChange is TRUE or after reset is deasserted, Maximum is set to
zero and will take on the next AnalogQuantity received.
➤ Compare the input AnalogQuantity to the stored Maximum value.
➤ If the input is greater than the stored value for two or more samples,
update Maximum and record the date and time of occurrence.

fb_Minimum
Compare input real value to stored minimum value, update output if greater, and
record the date/time of occurrence.

Initialization Inputs
Name IEC 61131 Type Description

settingsChange BOOL Flag to prevent setting outputs based on provided initial values; a value of TRUE results in
setting Minimum to zero and the time stamp to the present time.

initialValue REAL Minimum value to use for initialization if settingsChange is FALSE.

initialTime timestamp_t Time stamp value to use for initialization if settingsChange is FALSE.

minimumThreshold REAL Lowest value this function block will record.

Inputs
Name IEC 61131 Type Description

EN BOOL Flag to enable or disable maximum comparison.

AnalogQuantity REAL Value to check against Minimum.

Reset BOOL Flag to reset Minimum and time stamp.

Outputs
Name IEC 61131 Type Description

Minimum REAL Minimum value.

EventTime timestamp_t The date and time that Minimum was last updated.

Programming Reference Date Code 20241023


PowerMetering 729
Function Blocks

Processing
➤ If settingsChange is FALSE, the function block initializes to the values
passed in.
➤ If settingsChange is TRUE or after reset is deasserted, Minimum is set to
zero and will take on the next AnalogQuantity received.
➤ Compare the input AnalogQuantity to the stored Minimum value.
➤ If the input is less than the stored value and greater than
minimumThreshold for two or more samples, update Minimum and record
the date and time of occurrence.
➤ This function block will work with any values but is designed for use
alongside fb_Maximum with positive numbers.

fb_Energy
Collect energy input over time, accumulating positive and negative values in
separate registers.

Initialization Inputs
Name IEC 61131 Type Description

settingsChange BOOL Flag to prevent setting outputs based on provided


initial values; a value of TRUE results in setting
EnergyIn and EnergyOut to zero.

initialValueIn REAL EnergyIn value to use for initialization, if


settingsChange is FALSE.

initialValueOut REAL EnergyOut value to use for initialization, if


settingsChange is FALSE.

rolloverThreshold REAL Rollover value for this function block.

Inputs
Name IEC 61131 Type Description

EN BOOL Flag to enable or disable energy accumulation.

AnalogQuantity REAL Value to use for accumulating energy.

Reset BOOL Flag to reset EnergyIn and EnergyOut.

Outputs
Name IEC 61131 Type Description

EnergyIn REAL Accumulated energy in.

EnergyOut REAL Accumulated energy out.

Date Code 20241023 Programming Reference


730 PowerMetering
Function Blocks

Processing
➤ If settingsChange is FALSE, the function block initializes to the values
passed in.
➤ If settingsChange is TRUE or after reset is deasserted, EnergyIn and
EnergyOut are set to zero.
➤ Maintain the accumulated IN/OUT energy. A negative power value is
considered IN energy while a positive power value is considered OUT
energy. Receiving a positive power value (OUT) will not affect the
accumulated IN value and vice versa.
➤ Update no more frequently than once a second regardless of the RTE
cycle time.
➤ Restart either output to zero when it exceeds rolloverThreshold.

fb_Demand
Calculates demand.

Initialization Inputs
Name IEC 61131 Type Description

settingsChange BOOL Flag to prevent setting outputs based on provided


initial values; a value of TRUE results in setting
Demand to zero.

initialValue REAL Demand value to use for initialization, if


settingsChange is FALSE.

demandType Demand_Enum The calculation method this function block will


use; either ROLLING or THERMAL.

timeConstant Time_Constant_Enum The time constant this function block will use
during demand calculations, MIN5, MIN10,
MIN15, MIN20, MIN30, MIN60.

Inputs
Name IEC 61131 Type Description

EN BOOL Flag to enable or disable demand calculation.

AnalogQuantity REAL Value to use for calculating demand.

Reset BOOL Flag to reset Demand.

Outputs
Name IEC 61131 Type Description

Demand REAL Demand value.

Programming Reference Date Code 20241023


PowerMetering 731
Function Blocks

Processing
➤ If settingsChange is FALSE, the function block initializes to the values
passed in.
➤ If settingsChange is TRUE or after reset is deasserted, Demand is set to
zero.
➤ Update no more frequently than once a second regardless of the RTE
cycle time.
➤ Thermal demand output updates with each call to the function block.
➤ Thermal demand is a logarithmic average of the power used, with more-
recent load weighted more heavily than less-recent load. For a steady
state transition, this block outputs Demand of 90% of the change after
timeConstant has passed.
➤ Rolling demand output only updates once every 5 minutes.
➤ Rolling demand averages input over periods of 5 minutes and
outputs Demand as an average of enough 5 minute averages to equal
timeConstant.

fb_KYZ
Accumulate a count of transitions from only a Y of true to only a Z of true or
back again.

Initialization Inputs
Name IEC 61131 Type Description

settingsChange BOOL Flag to prevent setting outputs based on provided


initial values; a value of TRUE results in setting CV
and ROV to zero.

initialCV BCR Initial accumulator state, if settingsChange is


FALSE.

initialROV UDINT Initial roll over value, if settingsChange is FALSE.

maxValue UDINT The value of the accumulator at which roll over


occurs.

Inputs
Name IEC 61131 Type Description

EN BOOL Flag to enable or disable the KYZ accumulator.

Y SPS Terminal Y.

Z SPS Terminal Z.

Reset BOOL Flag to reset the state of the KYZ block.

Date Code 20241023 Programming Reference


732 PowerMetering
Function Blocks

Outputs
Name IEC 61131 Type Description

CV BCR The number of transitions from Y to Z or Z to Y.

ROV UDINT The number of times CV has reset to zero.

Processing
➤ If settingsChange is FALSE, the function block initializes to the values
passed in.
➤ If settingsChange is TRUE or after reset is deasserted, CV is set to the
default state and ROV is set to zero.
➤ Monitor Y and Z when EN is TRUE and Reset is FALSE.
➤ Define a countable state as Y and Z being in opposite states with qualities
of good.
➤ Define a countable transition as the present inputs being in a countable
state and the present state of the inputs is opposite to the previous counted
state of the inputs.
➤ Count only at times when both Y and Z report good quality (i.e., q.validity
= good).
➤ Set the CV quality attribute based on the input with the least quality (i.e.,
if input Y.q.validity is invalid and Z.q.validity is good, then CV.q.validity
is invalid).
➤ Override the quality of CV to invalid if the block is disabled or being
reset.
➤ Increment ROV and the accumulator to zero when the accumulator
equals maxValue. The practical implication is that maxValue declared at
initialization is never reported, but instead the accumulator rolls over to
zero allowing the total count to be calculated as CV + ROV • maxValue.

fb_KY
Accumulate a count of transitions of a single variable Y.

Initialization Inputs
Name IEC 61131 Type Description

settingsChange BOOL Flag to prevent setting outputs based on provided


initial values; a value of TRUE results in setting CV
and ROV to zero.

initialCV BCR Initial accumulator state, if settingsChange is


FALSE.

initialROV UDINT Initial roll over value, if settingsChange is FALSE.

maxValue UDINT The value of the accumulator at which roll over


occurs.

Programming Reference Date Code 20241023


PowerMetering 733
Benchmarks

Inputs
Name IEC 61131 Type Description

EN BOOL Flag to enable or disable the KY accumulator.

Y SPS Terminal Y.

Reset BOOL Flag to reset the state of the KY block.

Outputs
Name IEC 61131 Type Description

CV BCR The number of transitions of Y.

ROV UDINT The number of times CV has reset to zero.

Processing
➤ If settingsChange is FALSE, the function block initializes to the values
passed in.
➤ If settingsChange is TRUE or after reset is deasserted, CV is set to the
default state and ROV is set to zero.
➤ Monitor Y when EN is TRUE and Reset is FALSE.
➤ Define a countable transition as the present input being opposite its
previous value.
➤ Count only at times when Y reports good quality (i.e., q.validity = good).
➤ Set the CV quality attribute as the quality of the input.
➤ Override the quality of CV to invalid if the block is disabled or being
reset.
➤ Increment ROV and the accumulator to zero when the accumulator
equals maxValue. The practical implication is that maxValue declared at
initialization is never reported, but instead the accumulator rolls over to
zero allowing the total count to be calculated as CV + ROV • maxValue.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.
➤ SEL-3505
➢ R135-V1 firmware
➤ SEL-3530
➢ R135-V2 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R135-V0 firmware

Date Code 20241023 Programming Reference


734 PowerMetering
Benchmarks

Benchmark Test Descriptions


fb_Maximum
The posted time is the average execution time of 100 calls in which a new
maximum value was observed. This constitutes the longest running time for this
call.

fb_Minimum
The posted time is the average execution time of 100 calls in which a new
minimum value was observed. This constitutes the longest running time for this
call.

fb_Energy
The posted time is the average execution time of 100 calls at the top of the
second. This constitutes the longest running time for this call.

fb_Demand (Thermal)
The posted time is the average execution time of 100 calls at the top of the
second. This constitutes the longest running time for this call.

fb_Demand (Rolling)
The posted time is the average execution time of 100 calls at a 5-minute
boundary. This constitutes the longest running time for this call.

fb_KYZ
The posted time is the average execution time of 100 calls where the block
incremented. This constitutes the longest running time for this call.

fb_KY
The posted time is the average execution time of 100 calls where the block
incremented. This constitutes the longest running time for this call.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

fb_Maximum 5 3 2

fb_Minimum 4 3 1

fb_Energy 4 3 1

fb_Demand(Thermal) 5 3 1

Programming Reference Date Code 20241023


PowerMetering 735
Examples

Platform (time in µs)


Operation Tested
SEL-3505 SEL-3530 SEL-3555

fb_Demand(Rolling) 5 3 1

fb_KYZ 1 1 1

fb_KY 1 1 1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Maximum
Objective
A user has an analog variable and wants to determine the greatest observed
value of the analog.

Assumptions
The following example provides code for two different situations. The first
program assumes there is no requirement for nonvolatile variables while the
second program assumes there is a requirement that variables are retained
through power loss.

Solution
The user can create a program as shown in Code Snippet 24.1. Note that this
example does not use retain variables.

Code Snippet 24.1 prg_Maximum_Example


PROGRAM prg_Maximum_Example
VAR
En : BOOL;
Value : REAL;
InitValue : REAL;
Reset : BOOL;
Maximum : REAL;
Max_Event : timestamp_t;

Max1 : fb_Maximum( settingsChange := TRUE,


initialValue := InitValue,
initialTime := Max_Event);
END_VAR

//Call the Maximum function with the desired value


Max1(EN:=En, AnalogQuantity:=Value, Reset:=Reset);

Date Code 20241023 Programming Reference


736 PowerMetering
Examples

// Assign the outputs


Maximum := Max1.Maximum;
Max_Event := Max1.EventTime;

Solution With Retain Variables


Retain variables allow variable values to remain consistent through removal and
restoration of power and program downloads. The user can create a program as
shown in Code Snippet 24.1. RETAIN_UID must be initialized on the first run.
See Retain Variables on page 744 for more details on retain variables.
Code Snippet 24.2 prg_Maximum_Retain_Example
VAR_GLOBAL RETAIN
// If Event Time is not desired to be retained a REAL value can be used
Max1Retain : MV;
RETAIN_VERSION : DWORD;
END_VAR
VAR_GLOBAL
// Modify this when the retain value should not be used.
VERSION : DWORD:=1;
END_VAR

PROGRAM prg_Maximum_Retain_Example
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;

Max1 : fb_Maximum( settingsChange := RETAIN_VERSION <> VERSION,


initialValue := Max1Retain.instMag,
initialTime := Max1Retain.t);
(*If VERSION has been modified, Maximum value will be reset to zero,
*otherwise the retain values will be used. settingsChange should be evaluated
*from constants or retain variables only. *)
END_VAR

//Update the retain variable first thing


RETAIN_VERSION := VERSION;

//Call the Maximum function with the desired value


Max1(EN:=En, AnalogQuantity:=Value, Reset:=Reset);

// Assign the outputs to the retain variables


Max1Retain.instMag := Max1.Maximum;
Max1Retain.t := Max1.EventTime;

Minimum
Objective
A user has an analog variable and wants to determine the smallest observed
value of the analog.

Assumptions
The following example provides code for two different situations. The first
program assumes there is no requirement for nonvolatile variables, and the
second program assumes there is a requirement that variables are retained
through power loss.

Programming Reference Date Code 20241023


PowerMetering 737
Examples

Solution
The user can create a program as shown in Code Snippet 24.3. Note that this
example does not use retain variables.
Code Snippet 24.3 prg_Minimum_Example
PROGRAM prg_Minimum_Example
VAR
En : BOOL;
InitValue : REAL;
Value : REAL;
Reset : BOOL;
Minimum : REAL;
MinThreshold : REAL := 50000;
Min_Event : timestamp_t;

Min1 : fb_Minimum( settingsChange := TRUE,


initialValue := InitValue,
initialTime := Min_Event,
minimumThreshold := MinThreshold);
END_VAR

//Call the Minimum function with the desired value


Min1(EN := En, AnalogQuantity := Value, Reset := Reset);

// Assign the outputs


Minimum := Min1.Minimum;
Min_Event := Min1.EventTime;

Solution With Retain Variables


Retain variables allow variable values to remain consistent through removal and
restoration of power and program downloads. The user can create a program as
shown in Code Snippet 24.4. RETAIN_UID must be initialized on the first run.
See Retain Variables on page 744 for more details on retain variables.
Code Snippet 24.4 prg_Minimum_Retain_Example
VAR_GLOBAL RETAIN
// If Event Time is not desired to be retained a REAL value can be used
Min1Retain : MV;
RETAIN_VERSION : DWORD;
END_VAR
VAR_GLOBAL
// Modify this when the retain value should not be used.
VERSION : DWORD := 1;
END_VAR

PROGRAM prg_Minimum_Example_Retain
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
MinThreshold : REAL := 50000;

Min1 : fb_Minimum( settingsChange := RETAIN_VERSION <>


VERSION,
initialValue := Min1Retain.instMag,
initialTime := Min1Retain.t,
minimumThreshold := MinThreshold);
(*If VERSION has been modified, Minimum value will be reset to zero,
*otherwise the retain values will be used. settingsChange should be evaluated
*from constants or retain variables only. *)
END_VAR

//Update the retain variable first thing

Date Code 20241023 Programming Reference


738 PowerMetering
Examples

RETAIN_VERSION := VERSION;

//Call the Minimum function with the desired value


Min1(EN:=En, AnalogQuantity:=Value, Reset:=Reset);

// Assign the outputs to the retain variables


Min1Retain.instMag := Min1.Minimum;
Min1Retain.t := Min1.EventTime;

Energy
Objective
A user has a power quantity and wants to keep track of energy flow. Positive
power value is considered to be "out" and negative power is considered to be
"in."

Assumptions
The following example provides code for two different situations. The first
program assumes there is no requirement for nonvolatile variables while the
second program assumes there is a requirement that variables are retained
through power loss.

Solution
The user can create a program as shown in Code Snippet 24.5. Note that this
example does not use retain variables.
Code Snippet 24.5 prg_Energy_Example
PROGRAM prg_Energy_Example
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
InitIn : REAL;
InitOut : REAL;
Threshold : REAL;
EnergyIn : REAL;
EnergyOut : REAL;

Energy1 : fb_Energy( settingsChange := TRUE,


initialValueIn := InitIn,
initialValueOut := InitOut,
rollOverThreshold := Threshold);
END_VAR

//Call the Energy function with the desired value


Energy1(EN := En, AnalogQuantity := Value, Reset := Reset);

// Assign the outputs


EnergyIn := Energy1.EnergyIn;
EnergyOut := Energy1.EnergyOut;

Programming Reference Date Code 20241023


PowerMetering 739
Examples

Solution With Retain Variables


Retain variables allow variable values to remain consistent through removal and
restoration of power and program downloads. The user can create a program as
shown in Code Snippet 24.6. RETAIN_UID must be initialized on the first run.
See Retain Variables on page 744 for more details on retain variables.
Code Snippet 24.6 prg_Energy_Retain_Example
VAR_GLOBAL RETAIN
EnergyIn : REAL;
EnergyOut : REAL;
RETAIN_VERSION : DWORD;
END_VAR
VAR_GLOBAL
// Modify this when the retain value should not be used.
VERSION : DWORD := 1;
END_VAR

PROGRAM prg_Energy_Example_Retain
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
Threshold : REAL;

Energy1 : fb_Energy( settingsChange := (RETAIN_VERSION <>


VERSION),
initialValueIn := EnergyIn,
initialValueOut := EnergyOut,
rollOverThreshold := Threshold);
(*If VERSION has been modified, the energy values will be reset to zero,
*otherwise the retain values will be used. settingsChange should be evaluated
*from constants or retain variables only. *)
END_VAR

//Update the retain variable first thing


RETAIN_VERSION := VERSION;

//Call the Energy function with the desired value


Energy1(EN := En, AnalogQuantity := Value, Reset := Reset);

// Assign the outputs to the retain variables


EnergyIn := Energy1.EnergyIn;
EnergyOut := Energy1.EnergyOut;

Demand
Objective
A user wants to calculate demand on an analog quantity.

Assumptions
The following example provides code for two different situations. The first
program assumes there is no requirement for nonvolatile variables while the
second program assumes there is a requirement that variables are retained
through power loss.

Date Code 20241023 Programming Reference


740 PowerMetering
Examples

Solution
The user can create a program as shown in Code Snippet 24.7. Note that this
example does not use retain variables.
Code Snippet 24.7 prg_Demand_Example
PROGRAM prg_Demand_Example
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
InitValue : REAL;
DemandTherm : REAL;
DemandRolling : REAL;

Demand1 : fb_Demand( settingsChange := TRUE,


initialValue := InitValue,
DemandType := THERMAL,
timeConstant := MIN10);

Demand2 : fb_Demand( settingsChange := TRUE,


initialValue := InitValue,
DemandType := ROLLING,
timeConstant := MIN20);
END_VAR

//Call the Demand function with the desired values


Demand1(EN := En, AnalogQuantity := Value, Reset := Reset);
Demand2(EN := En, AnalogQuantity := Value, Reset := Reset);

// Assign the outputs


DemandTherm := Demand1.Demand;
DemandRolling := Demand2.Demand;

Solution With Retain Variables


Retain variables allow variable values to remain consistent through removal and
restoration of power and program downloads. The user can create a program as
shown in Code Snippet 24.8. RETAIN_UID must be initialized on the first run.
See Retain Variables on page 744 for more details on retain variables.
Code Snippet 24.8 prg_Demand_Retain_Example
VAR_GLOBAL RETAIN
DemandTherm : REAL;
DemandRolling : REAL;
RETAIN_VERSION : DWORD;
END_VAR
VAR_GLOBAL
// Modify this when the retain value should not be used.
VERSION : DWORD := 1;
END_VAR

PROGRAM prg_Demand_Example_Retain
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;

Demand1 : fb_Demand( settingsChange := (RETAIN_VERSION <> VERSION),


initialValue := DemandTherm,
DemandType := THERMAL,
timeConstant := MIN10);

Demand2 : fb_Demand( settingsChange := (RETAIN_VERSION <> VERSION),

Programming Reference Date Code 20241023


PowerMetering 741
Examples

initialValue := DemandRolling,
DemandType := ROLLING,
timeConstant := MIN20);
(*If VERSION has been modified, the demand values will be reset to zero,
*otherwise the retain values will be used. settingsChange should be evaluated
*from constants or retain variables only. *)
END_VAR

//Update the retain variable first thing


RETAIN_VERSION := VERSION;

//Call the Demand function with the desired value


Demand1(EN := En, AnalogQuantity := Value, Reset := Reset);
Demand2(EN := En, AnalogQuantity := Value, Reset := Reset);

// Assign the outputs to the retain variables


DemandTherm := Demand1.Demand;
DemandRolling := Demand2.Demand;

KYZ
Objective
A user has two inputs connected to the Y and Z terminal of a meter and wants to
count the number of transitions.

Assumptions
The following example provides code for two different situations. The first
program assumes there is no requirement for nonvolatile variables while the
second program assumes there is a requirement that variables are retained
through power loss.

Solution
The user can create a program as shown in Code Snippet 24.9. Note that this
example does not use retain variables.
Code Snippet 24.9 prg_KYZ_Example
PROGRAM prg_KYZ_Example
VAR
//Terminal for Y and Z pulses
DI_Y_Terminal : SPS;
DI_Z_Terminal : SPS;
//Enabling and Rest Conditions
Enable : BOOL;
Reset : BOOL;

//Placeholder for DNP Tag


DNP_Counter1 : BCR;
DNP_Counter2 : BCR;
//Additional Outputs
RollOver1 : UDINT;
RollOver2 : UDINT;

//The KYZ blocks ignore their initial values because settingsChange is true.
KYZ_12bit : fb_KYZ( settingsChange := TRUE, initialCV := DNP_Counter1,
initialROV := 0, maxValue := 4095);

KYZ_32bit : fb_KYZ( settingsChange := TRUE, initialCV := DNP_Counter2,


initialROV := 0, maxValue := 4294967295);

Date Code 20241023 Programming Reference


742 PowerMetering
Examples

END_VAR

//Call the function block every cycle and assign outputs


KYZ_12bit( EN := Enable, Y := DI_Y_Terminal, Z := DI_Z_Terminal, Reset := Reset,
CV => DNP_Counter1, ROV => RollOver1);

KYZ_32bit( EN := Enable, Y := DI_Y_Terminal, Z := DI_Z_Terminal, Reset := Reset,


CV => DNP_Counter2, ROV => RollOver2);

Solution With Retain Variables


Retain variables allow variable values to remain consistent through removal and
restoration of power and program downloads. The user can create a program as
shown in Code Snippet 24.10. RETAIN_UID must be initialized on the first run.
See Retain Variables on page 744 for more details on retain variables.
Code Snippet 24.10 prg_KYZ_Retain_Example
VAR_GLOBAL RETAIN
//Persistent storage for counter values
Counter : BCR;
RollOver : UDINT;
RETAIN_VERSION : DWORD;
END_VAR
VAR_GLOBAL
// Modify this when the retain value should not be used.
VERSION : DWORD := 1;
END_VAR

PROGRAM prg_KYZ_Retain_Example
VAR
//Block inputs
DI_Y_Terminal : SPS;
DI_Z_Terminal : SPS;
Enable : BOOL;
Reset : BOOL;

//Placeholder for DNP output tags


DNP_Counter : BCR;

KYZ_12bit : fb_KYZ( settingsChange := (RETAIN_VERSION <> VERSION),


initialCV := Counter, initialROV := RollOver,
maxValue := 4095);
(*If VERSION has been modified, the counter values will be reset to zero,
*otherwise the retain values will be used. settingsChange should be evaluated
*from constants or retain variables only. *)
END_VAR

//Update the retain variable first thing


RETAIN_VERSION := VERSION;

//Call the function block every cycle and assign outputs


KYZ_12bit( EN := Enable, Y := DI_Y_Terminal, Z := DI_Z_Terminal, Reset := Reset,
CV => Counter, ROV => RollOver);

//Copy output to outbound communication channels


DNP_Counter := Counter;

KY
Objective
A user has one input connected to the Y terminal of a meter and wants to count
the number of transitions.

Programming Reference Date Code 20241023


PowerMetering 743
Examples

Assumptions
The following example provides code for two different situations. The first
program assumes there is no requirement for nonvolatile variables while the
second program assumes there is a requirement that variables are retained
through power loss.

Solution
The user can create a program as shown in Code Snippet 24.11. Note that this
example does not use retain variables.
Code Snippet 24.11 prg_KY_Example
PROGRAM prg_KY_Example
VAR
//Terminal for Y pulses
DI_Y_Terminal : SPS;
Enable : BOOL;
Reset : BOOL;

//Placeholder for DNP Tag


DNP_Counter1 : BCR;
DNP_Counter2 : BCR;
//Additional Outputs
RollOver1 : UDINT;
RollOver2 : UDINT;

//The KY blocks ignore their initial values because settingsChange is true.


KY_12bit : fb_KY( settingsChange := TRUE, initialCV := DNP_Counter1,
initialROV := 0, maxValue := 4095);

KY_32bit : fb_KY( settingsChange := TRUE, initialCV := DNP_Counter2,


initialROV := 0, maxValue := 4294967295);
END_VAR

//Call the function block every cycle and assign outputs


KY_12bit( EN := Enable, Y := DI_Y_Terminal, Reset := Reset,
CV => DNP_Counter1, ROV => RollOver1);

KY_32bit( EN := Enable, Y := DI_Y_Terminal, Reset := Reset,


CV => DNP_Counter2, ROV => RollOver2);

Solution With Retain Variables


Retain variables allow variable values to remain consistent through removal and
restoration of power and program downloads. The user can create a program as
shown in Code Snippet 24.12. RETAIN_UID must be initialized on the first run.
See Retain Variables on page 744 for more details on retain variables.
Code Snippet 24.12 prg_KY_Retain_Example
VAR_GLOBAL RETAIN
//Persistent storage for counter values
Counter : BCR;
RollOver : UDINT;
RETAIN_VERSION : DWORD;
END_VAR
VAR_GLOBAL
// Modify this when the retain value should not be used.
VERSION : DWORD := 1;
END_VAR

PROGRAM prg_KY_Retain_Example

Date Code 20241023 Programming Reference


744 PowerMetering
Retain Variables

VAR
//Terminal for Y pulses
DI_Y_Terminal : SPS;
//Enabling and Rest Conditions
Enable : BOOL;
Reset : BOOL;

//Placeholder for DNP output tags


DNP_Counter : BCR;

KY_12bit : fb_KY(
settingsChange := (RETAIN_VERSION <> VERSION),
initialCV := Counter, initialROV := RollOver,
maxValue := 4095);
(*If VERSION has been modified, the counter values will be reset to zero,
*otherwise the retain values will be used. settingsChange should be evaluated
*from constants or retain variables only. *)
END_VAR

//Update the retain variable first thing


RETAIN_VERSION := VERSION;

//Call the function block every cycle and assign outputs


KY_12bit( EN := Enable, Y := DI_Y_Terminal, Reset := Reset,
CV => Counter, ROV => RollOver);

//Copy output to outbound communication channels


DNP_Counter := Counter;

Retain Variables
Note on Usage
Retain variables allow values to persist through removal and restoration of
power, a reboot, and some program downloads. To accomplish this, retain
variables point to a specific location in nonvolatile memory. This results in a
situation where changing the definition of any retain variable (e.g., creating
or deleting variables or changing variable order), can result in the variables
pointing to a different location in memory, meaning an incorrect value would
be used in logic. Therefore, you should initialize all retain variables when you
change or add any retain variable declarations. Furthermore, it is best practice to
keep all retain variables in the same global variable list to avoid the opportunity
of the lists being reordered.

Programming Reference Date Code 20241023


S E C T I O N 2 5

PowerSystemAutomation
Introduction
The PowerSystemAutomation library includes function blocks that can be used
for bay control applications and other power system automation applications.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_SynchronismCheckObject"
mySynchronismCheckObject := otherSynchronismCheckObject;

// This is fine
someVariable := mySynchronismCheckObject.value;
// As is this
pt_mySynchronismCheckObject := ADR(mySynchronismCheckObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, Global Variable Lists, or VAR_STAT sections).
➤ This library is not intended for use on the SEL-3505 or SEL-3505-3 class
of RTACs.

Supported Firmware Versions


This library must be used with an RTAC device that is running firmware version
R145 or later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Date Code 20241023 Programming Reference


746 PowerSystemAutomation
Function Blocks

enum_SlipFreqStatus
This enumeration defines the status of the slip frequency.

Enumeration Description

UnderSlipFreqMin Absolute value of the slip frequency is less than the minimum
allowed slip frequency set by the user.

PositiveSlipFreq The slip frequency is in the range between the minimum and
maximum slip frequency settings set by the user, and the
synchronizing frequency is higher than the reference frequency.

NegativeSlipFreq The slip frequency is in the range between the minimum and
maximum slip frequency settings set by the user, and the
synchronizing frequency is lower than the reference frequency.

OverSlipFreqMax Absolute value of the slip frequency is greater than the maximum
allowed slip frequency set by the user.

Function Blocks
fb_SynchronismCheck (Function Block)
The SynchronismCheck function block provides functionality to indicate
synchrony between two voltage sources. To appropriately determine
synchronism, each voltage source must provide simultaneous magnitudes and
angles. Thus, this function block requires time stamps with each measurement to
validate time-alignment. Additionally, this function block assumes that voltage
magnitudes are represented on the same scale (primary or secondary).

The Synchronized Boolean output is set to TRUE when the synchronizing


voltage is within the allowed phase and magnitude with the reference voltage.
The following describes how the CircuitBreakerCloseTimeMs setting value
dictates the behavior of the Synchronized output:

➤ No-compensation mode (CircuitBreakerCloseTimeMs = 0): The


Synchronized output is set to TRUE if the absolute value of the angle
between the synchronizing voltage and the reference voltage is lower than
the maximum angle difference set by the user, and voltage magnitudes,

Programming Reference Date Code 20241023


PowerSystemAutomation 747
Function Blocks

time stamps, and the slip frequency are within acceptable range (see
Processing on page 749). Figure 25.1 illustrates the operation of
the Synchronized output in no-compensation mode. The gray triangle
indicates the area where the Synchronized output is set to TRUE.

Figure 25.1 Synchronism-Check Without Circuit Breaker Close Time


Compensation
➤ Compensation mode (CircuitBreakerCloseTimeMs > 0): The logic
compensates for the circuit breaker close time. The circuit breaker close
time is converted to degrees (AdvancedAngle) and this angle is added
to the phase of the synchronizing voltage. This new phasor is called
VSynchAdv and represents the position of the synchronizing voltage when
the circuit breaker actually closes. In this mode, the Synchronized output
is set to TRUE when all of the following are true:
➢ The AdvancedVoltage leads the reference voltage by an angle less
than or equal to the maximum angle difference set by the user.
➢ The frequency of the synchronizing voltage is less than or greater than
(depending on the value of the input pin PositiveSlipRequired) the
frequency of the reference voltage.
➢ The voltage magnitudes, time stamps, and slip frequency are within
acceptable ranges (see Processing on page 749).
Figure 25.2 illustrates the operation of the Synchronized output in
compensation mode. VSynchAdv is a phasor that leads VSynch by
AdvancedAngle degrees, as shown in the image to the left. The gray
triangle shown in the image to the right indicates the area where the
Synchronized output is set to TRUE.

Figure 25.2 Synchronism-Check With Circuit Breaker Close Time


Compensation

Date Code 20241023 Programming Reference


748 PowerSystemAutomation
Function Blocks

When using the fb_SynchronismCheck function block, consider the following:

➤ Set the RTAC task cycle time equal to the power system's nominal
frequency or faster.
➤ When using C37.118 Synchrophasor data for the voltage and frequency
measurements, ensure the data rate is at least 30 messages per second for
60 Hz systems or 25 messages per second for 50 Hz systems.
➤ When Fundamental tags from two different Axion AC analog input
modules supply the reference voltage and synchronizing voltage inputs,
set the Reference Angle setting on both modules to No Reference.
Selecting No Reference prevents the module from applying self-
reference offsets to their angle measurements, allowing for appropriate
angle comparison between modules.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block.

VRef Vector_t Reference voltage.

VRefTime Timestamp_t Reference voltage time stamp.

FreqRef REAL Reference frequency.

VSynch Vector_t Synchronizing voltage.

VSynchTime Timestamp_t Synchronizing voltage time stamp.

FreqSynch REAL Synchronizing frequency.

VSynchMagComp REAL Adjust VSynch magnitude to VRef magnitude to account for differences in potential
transformer connections. Range is all positive real numbers, including zero. Default
value is 1.0.

VSynchAngComp REAL Adjust VSynch angle to be in phase with VRef angle. Default value is 0.

BlockSynchCheck BOOL Set to TRUE to block synchronism check.

VoltageMax REAL Voltage window high limit.

VoltageMin REAL Voltage window low limit.

VoltageDiffMax REAL Maximum absolute value of the difference between synchronizing and reference
voltage magnitudes.

MaxSynchAngle REAL Maximum angle (degrees) for synchronism check.

CircuitBreakerCloseTimeMs REAL Circuit breaker close time, in milliseconds. Range is all positive real numbers,
including zero.

MinimumSlipFreq REAL Minimum value allowed for the slip frequency (Hz). Default value is 0.005 Hz.
Range is from 0 to MaximumSlipFreq.

MaximumSlipFreq REAL Maximum value allowed for the slip frequency (Hz). Range is from 0.005 Hz to 0.5
Hz. Default value is 0.1 Hz.

PositiveSlipRequired BOOL If TRUE, in order for Synchronized to assert, the slip between the Synch and
Reference voltages must be positive. If FALSE, Synchronized will assert as long as
the absolute value of the slip is between the minimum and maximum slip.

Programming Reference Date Code 20241023


PowerSystemAutomation 749
Function Blocks

Outputs
Name IEC 61131 Type Description

ENO BOOL TRUE when the function block is enabled.

SynchCheckLogicEnabled BOOL The synchronism-check logic is enabled. For more details, refer to Processing
on page 749.

SlipStatus enum_SlipFreqStatus Shows the status of the slip frequency.

AngleDiff REAL Angle difference between the synchronizing and reference voltages.

SlipFrequency REAL Absolute value of the slip frequency. The slip frequency is the difference
between FreqRef and FreqSynch.

VSynchCompensated Vector_t The compensated synchronizing voltage.

VSynchAdv Vector_t The synchronizing voltage compensated for the circuit breaker close time.
If a close command is sent to the breaker in the present processing interval,
VSynchAdv is the position in which VSynchCompensated will be when the
breaker actually closes.

Synchronized BOOL TRUE when the synchronizing voltage and the reference voltage are
synchronized.

SynchTimeRemaining TIME When Synchronized is TRUE, this output shows an estimation of the
remaining time that the system will remain synchronized.

Processing
1. When the following conditions are met, ENO output is set to TRUE:
➤ MaximumSlipFrequency, MinimumSlipFrequency, VSynchMagComp,
and CircuitBreakerCloseTimeMs inputs are within range
requirements.
➤ VoltageMax > VoltageMin
➤ MaximumSlipFreq > MinimumSlipFreq
➤ EN = TRUE.
2. When ENO is TRUE, the compensated synchronizing voltage
VSynchCompensated is calculated as follows:
➤ VSynchCompensated.MAG = VSynch.MAG × VSynchMAGcomp
➤ VSynchCompensated.ANG = VSynch.ANG − VSynchAngComp
3. When BlockSynchCheck is set to FALSE and the following conditions
are met for at least 200 ms plus one RTAC processing interval,
SynchCheckLogicEnabled output is set to TRUE:
➤ VoltageMin ≤ VRef.MAG ≤ VoltageMax.
➤ VoltageMin ≤ VSynchCompensated.MAG ≤ VoltageMax.
➤ |VRef.MAG − VSynchCompensated.MAG| ≤ VoltageDiffMax.
➤ VSyncTime is equal to VRefTime ±1 microsecond.

Date Code 20241023 Programming Reference


750 PowerSystemAutomation
Function Blocks

➤ VRefTime and VSynchTime update at a period of at least 40 ms plus


one RTAC processing interval.
➤ ENO = TRUE.
4. If SynchCheckLogicEnabled is TRUE, the following outputs are
calculated:
➤ SlipFrequency = |FreqSynch − FreqRef |.
➤ SlipStatus =
➢ UnderSlipFreqMin, if SlipFrequency < MinimumSlipFreq
➢ OverSlipFreqMax, if SlipFrequency > MaximumSlipFreq
➢ PositiveSlipFreq, if FreqSynch > FreqRef
➢ NegativeSlipFreq, if FreqSynch < FreqRef
➤ AngleDiff :

Equation 25.1
➤ AdvancedAngle:

Equation 25.2
➤ VSynchAdv:
➢ VSynchAdv.MAG = VSynchCompensated.MAG
➢ VSynchAdv.ANG = VSynchCompensated.ANG + AdvancedAngle

5. The Synchronized output indicates that the synchronizing voltage and


reference voltage are within allowed phase range, magnitude range, and
frequency range. The Synchronized output is set to TRUE based on the
corresponding following conditions:
➤ If CircuitBreakerCloseTimeMs = 0: In this case, there is no circuit
breaker close time compensation. Synchronized is set to TRUE if the
following conditions are met:
➢ |AngleDiff | ≤ MaxSynchAngle
➢ SynchCheckLogicEnabled = TRUE
➤ If CircuitBreakerCloseTimeMs > 0: In this case, the AdvancedAngle is
added to the synchronizing voltage angle to compensate for the circuit
breaker close time. Synchronized is set to TRUE if the following
conditions are met:
➢ 0 ≤ VSynchAdv.ANG − VRef.ANG ≤ MaxSynchAngle
➢ SlipStatus = PositiveSlipFreq or NegativeSlipFreq (depending on
the value of PositiveSlipRequired)
➢ SynchCheckLogicEnabled = TRUE
6. If CircuitBreakerCloseTimeMs > 0 AND Synchronized = TRUE, then
SynchTimeRemaining is calculated as follows:

Equation 25.3

Programming Reference Date Code 20241023


PowerSystemAutomation 751
Function Blocks

fb_DisconnectSwitchControl (Function Block)


The DisconnectSwitchControl function block provides logic that generates
the output signals necessary for performing open and close disconnect switch
operations. This function block is designed to be used for Bay Control
applications. The function block receives the local disconnect switch operation
signal (e.g., from the Axion SEL Touchscreen) or a remote switch operation
command (e.g., via a communication protocol) and generates the corresponding
open and close pulses for the digital outputs that directly control the disconnect
switch. This function block also provides an alarm output when switch operation
failures are detected.
The DisconnectSwitchControl function block requires a LocalMode Boolean
input to supervise the local and remote switch control operations. The Axion
Bay Controller provides a Global Local/Remote Mode setting that can be
connected to this function block LocalMode input. This connection aligns
the Local/Remote control of the Axion Bay Controller Touchscreen and this
function block so that both properly indicate their mode and execute Local/
Remote controls appropriately. Alternatively, when systems require more local/
remote control granularity, e.g., the RTAC is controlling multiple bays and one
bay requires local control and the second bay requires remote control, users can
map custom user logic to the function block LocalMode input.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block.

CloseSignalLocal BOOL Close command signal issued locally (e.g., via the SEL Touchscreen).

CloseSignalRemote BOOL Close command signal issued remotely (e.g., via communication protocol).

LocalMode BOOL When TRUE, this function block does not process remote close commands. When
FALSE, this function block does not process local open commands.

BlockCloseControl BOOL When TRUE, close control commands are blocked.

CloseLatchReset BOOL When TRUE, the CloseSignal output is reset. This input is typically set to
CloseSealInTimeout OR SwitchIsClosed to ensure that CloseSignal remains
asserted for the duration of the expected disconnect switch operate time, or if an
alarm is detected.

CloseImmobilityPickupTime TIME Maximum time to wait for the disconnect close operation to initiate. If the
disconnect close operation does not initiate within this time, an alarm condition
is declared. Default value is 300 milliseconds. For more information on how
to set this value, refer to Disconnect Switch Open and Close Control Logic on
page 762 of this document.

CloseImmobilityReset BOOL When TRUE, the close immobility timer resets. This signal indicates that the
switch has moved from its initial position and is in progress to complete the close
operation. This input is typically assigned to NOT SwitchIsOpen.

CloseSealInPickupTime TIME Set longer than the highest expected close operate time of the disconnect switch.
This timer starts when the CloseSignal output asserts. Default value is 4 seconds.
For more information on how to set this value, refer to Disconnect Switch Open and
Close Control Logic on page 762 of this document.

OpenSignalLocal BOOL Open command signal issued locally (e.g., via the SEL Touchscreen).

OpenSignalRemote BOOL Open command signal issued remotely (e.g., via communication protocol).

BlockOpenControl BOOL When TRUE, open control commands are blocked.

Date Code 20241023 Programming Reference


752 PowerSystemAutomation
Function Blocks

Name IEC 61131 Type Description

OpenLatchReset BOOL When TRUE, the OpenSignal output is reset. This input is typically set to
OpenSealInTimeout OR SwitchIsOpen to ensure that OpenSignal remains asserted
for the duration of the expected disconnect switch operate time, or if an alarm is
detected.

OpenImmobilityPickupTime TIME Maximum time to wait for the disconnect open operation to initiate. If the
disconnect open operation does not initiate within this time, an alarm condition
is declared. Default value is 300 milliseconds. For more information on how
to set this value, refer to Disconnect Switch Open and Close Control Logic on
page 762 of this document.

OpenImmobilityReset BOOL When TRUE, the open immobility timer resets. This signal indicates that the
switch has moved from its initial position and is in progress to complete the open
operation. This input is typically assigned to NOT SwitchIsClosed.

OpenSealInPickupTime TIME Set longer than the highest expected open operate time of the disconnect switch.
This timer starts when the OpenSignal output asserts. Default value is 4 seconds.
For more information on how to set this value, refer to Disconnect Switch Open and
Close Control Logic on page 762 of this document.

AlarmPickupTime TIME Set longer than the highest expected operate time of the disconnect switch. This
timer starts when the disconnect switch initiates the open or close operation.
Default value is 5 seconds. For more information on how to set this value, refer to
Disconnect Switch Open and Close Control Logic on page 762 of this document.

Auxiliary89A BOOL State of the normally open disconnect switch auxiliary contact. This auxiliary
contact is typically wired to a digital input.

Auxiliary89B BOOL State of the normally closed disconnect switch auxiliary contact. This auxiliary
contact is typically wired to a digital input.

Outputs
Name IEC 61131 Type Description

ENO BOOL TRUE when the function block is enabled.

CloseSignal BOOL Successful close signal. Once this output asserts, it latches until a rising edge
is detected in the CloseLatchReset input.

ClosePulseStart BOOL Asserts for one processing interval when CloseSignal transitions to TRUE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operSet element of the digital output controlling the
disconnect switch close operation.

ClosePulseEnd BOOL Asserts for one processing interval when CloseSignal transitions to FALSE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operClear element of the digital output controlling the
disconnect switch close operation.

CloseImmobilityTimeOut BOOL Asserts for one second when CloseImmobilityReset input does not assert
within CloseImmobilityPickupTime after asserting the CloseSignal output.
This indicates that the switch has not moved the minimum distance to
transition from the open state to the in-progress state.

CloseSealInTimeOut BOOL Asserts for one processing interval after the CloseSealInPickupTime expires
following the assertion of CloseSignal. This signal may be assigned to the
CloseLatchReset input to reset the CloseSignal output.

RemoteCloseControlIsBlocked BOOL Asserts for one processing interval when a remote close command is blocked
by the BlockCloseControl input.

OpenSignal BOOL Successful open signal. Once this output asserts, it latches until a rising edge
is detected in the OpenLatchReset input signal.

Programming Reference Date Code 20241023


PowerSystemAutomation 753
Function Blocks

Name IEC 61131 Type Description

OpenPulseStart BOOL Asserts for one processing interval when OpenSignal transitions to TRUE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operSet element of the digital output controlling the
disconnect switch open operation.

OpenPulseEnd BOOL Asserts for one processing interval when OpenSignal transitions to FALSE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operClear element of the digital output controlling the
disconnect switch open operation.

OpenImmobilityTimeOut BOOL Asserts for one second when OpenImmobilityReset input does not assert
within OpenImmobilityPickupTime after asserting the OpenSignal output. This
indicates that the switch has not moved the minimum distance to transition
from the close state to the in-progress state.

OpenSealInTimeOut BOOL Asserts for one processing interval after the OpenSealInPickupTime expires
following the assertion of OpenSignal. This signal may be assigned to
OpenLatchReset input to reset the OpenSignal output.

RemoteOpenControlIsBlocked BOOL Asserts for one processing interval when a remote open command is blocked
by the BlockOpenControl input.

SwitchIsOpen BOOL The disconnect switch is in the open position.

SwitchIsClosed BOOL The disconnect switch is in the closed position.

SwitchOperationInProgress BOOL The switch is transitioning between the open and closed position.

DisconnectAlarm BOOL Asserts for 1 second when an immobility condition is detected. Asserts
for a minimum of 5 seconds, until the alarm condition is cleared, when the
switch remains in the SwitchInProgress position for a time greater than the
AlarmPickupTime input.

Processing

Figure 25.3 Disconnect Switch Close Logic

Date Code 20241023 Programming Reference


754 PowerSystemAutomation
Function Blocks

Figure 25.4 Disconnect Switch Open Logic

Figure 25.5 Disconnect Switch Alarm Logic

Disconnect Switch Operation


A disconnect switch may be in one of three possible positions: open, closed, or
intermediate. The table below illustrates the state of auxiliary contacts 89A and
89B for each of these positions:

Disconnect State Open Closed Intermediate Illegitimate Position

Normally Open 89A Open Closed Open Closed

Normally Closed 89B Closed Open Open Closed

If an operation of the disconnect switch is in progress, the state of the


disconnect switch is intermediate. The DisconnectAlarmTimer timer monitors
the intermediate state and issues an alarm if the disconnect switch remains
in the intermediate state longer than the AlarmPickupTime time. The
DisconnectAlarmTimer timer also monitors for an illegitimate condition, with
the disconnect switch auxiliary contacts (Auxillary89A and Auxillary89B)
showing the disconnect main contact to be open and closed simultaneously.
Figure 25.6 shows how the state of the auxiliary contacts changes for an open-
to-close operation. The close-to-open scenario would be similar.

Programming Reference Date Code 20241023


PowerSystemAutomation 755
Function Blocks

Figure 25.6 Disconnect Switch in Transition

When configuring the DisconnectSwitchControl, take the following


considerations into account:

➤ Set CloseSealInPickupTime to a value 10 to 15 percent longer than the


maximum Expected Disconnect Operate Time shown in Figure 25.6.
Proceed similarly with OpenSealInPickupTime.
➤ Set CloseImmobilityPickupTime to a value 10 to 15 percent longer
than the T1 time shown in Figure 25.6. Proceed similarly with
OpenImmobilityPickupTime.
➤ Set AlarmPickupTime to a value 10 to 15 percent longer than the
Intermediate State shown in Figure 25.6.

fb_BreakerOpenControl (Function Block)


The BreakerOpenControl function block provides logic that generates the output
signal necessary for performing a circuit breaker open operation. This function
block is designed to be used for Bay Control applications. The function block
lets you map the following signals:

➤ A local open signal (typically from the Axion SEL Touchscreen).


➤ A remote open signal command (e.g., via a communication protocol).
➤ A local mode input that supervises the local and remote open signal
operations. The Axion Bay Controller provides a global local/remote
mode setting that can be connected to this input. This connection aligns
the Local/Remote control of the Axion Bay Controller touchscreen and
this function block so that both properly indicate their mode and execute
Local/Remote controls appropriately. Alternatively, when systems require
more local/remote control granularity, e.g., the RTAC is controlling
multiple bays and one bay requires local control and the second bay
requires remote control, users can map custom user logic to this input.
➤ The condition to block the open operation.
➤ The condition that unlatches the open signal.

Date Code 20241023 Programming Reference


756 PowerSystemAutomation
Function Blocks

The function block monitors the signals listed above to produce the circuit
breaker open signal to be assigned to the digital output that controls the circuit
breaker open operation.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block.

OpenSignalLocal BOOL Open command signal issued locally (e.g., via the SEL Touchscreen).

OpenSignalRemote BOOL Breaker open command issued remotely (e.g., via communication protocol).

LocalMode BOOL When TRUE, this function block does not process remote open commands. When
FALSE, this function block does not process local open commands.

BlockOpenControl BOOL When TRUE, breaker open commands are blocked.

OpenLatchReset BOOL When TRUE, the OpenSignal output signal is reset. The feedback from the circuit
breaker 52A and 52B contacts is typically used to unlatch the open signal.

OpenFailPickupTime TIME Maximum time to wait for the circuit breaker to open. Default value is 500 milliseconds.

Outputs
Name IEC 61131 Type Description

ENO BOOL TRUE when the function block is enabled.

OpenSignal BOOL Successful open signal. Once this output asserts, it latches until the rising edge
of the OpenLatchReset or BlockOpenControl input is detected.

OpenPulseStart BOOL Asserts for one processing interval when OpenSignal transitions to TRUE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operSet element of the digital output controlling the circuit
breaker open operation.

OpenPulseEnd BOOL Asserts for one processing interval when OpenSignal transitions to FALSE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operClear element of the digital output controlling the circuit
breaker open operation.

RemoteOpenControlIsBlocked BOOL Asserts for one processing interval when a remote circuit breaker open
operation is blocked by the BlockOpenControl input.

OpenFailTimeout BOOL Asserts if OpenSignal remains asserted longer than the amount of
time specified in OpenFailPickupTime. This signal may be assigned to
OpenLatchReset to reset OpenSignal.

Programming Reference Date Code 20241023


PowerSystemAutomation 757
Function Blocks

Processing

Figure 25.7 Breaker Open Logic

fb_BreakerCloseControl (Function Block)


The BreakerCloseControl function block provides logic that generates the output
signal necessary for performing a circuit breaker close operation. This function
block is designed to be used for Bay Control applications. The function block
lets you map the following signals:

➤ A local close signal (typically from the Axion SEL Touchscreen).


➤ A remote close signal command (e.g., via a communication protocol).
➤ A local mode input that supervises the local and remote close signal
operations. The Axion Bay Controller provides a global local/remote
mode setting that can be connected to this input. This connection aligns
the Local/Remote control of the Axion Bay Controller touchscreen and
this function block so that both properly indicate their mode and execute
Local/Remote controls appropriately. Alternatively, when systems require
more local/remote control granularity, e.g., the RTAC is controlling
multiple bays and one bay requires local control and the second bay
requires remote control, users can map custom user logic to this input.
➤ The condition to block the close operation.
➤ The condition that unlatches the close signal.

The function block monitors the signals listed above to produce the circuit
breaker close signal to be assigned to the digital output that controls the circuit
breaker close operation.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block.

CloseSignalLocal BOOL Close command signal issued locally (e.g., via the SEL Touchscreen).

Date Code 20241023 Programming Reference


758 PowerSystemAutomation
Function Blocks

Name IEC 61131 Type Description

CloseSignalRemote BOOL Breaker close command issued remotely (e.g., via communication protocol).

LocalMode BOOL When TRUE, this function block does not process remote close commands. When
FALSE, this function block does not process local close commands.

BlockCloseControl BOOL When TRUE, breaker close commands are blocked.

CloseLatchReset BOOL When TRUE, the CloseSignal output signal is reset. The feedback from the circuit
breaker 52A and 52B contacts is typically used to unlatch the close signal.

CloseFailPickupTime TIME Maximum time to wait for the circuit breaker to close. Default value is 1 second.

Outputs
Name IEC 61131 Type Description

ENO BOOL TRUE when the function block is enabled.

CloseSignal BOOL Successful close signal. Once this output asserts, it latches until the rising
edge of the CloseLatchReset or BlockCloseControl input is detected.

ClosePulseStart BOOL Asserts for one processing interval when CloseSignal transitions to TRUE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operSet element of the digital output controlling the circuit
breaker close operation.

ClosePulseEnd BOOL Asserts for one processing interval when CloseSignal transitions to FALSE.
This output may be mapped to the ctlVal member of the OperSPC tag
structure of the operClear element of the digital output controlling the circuit
breaker close operation.

RemoteCloseControlIsBlocked BOOL Asserts for one processing interval when a remote circuit breaker close
operation is blocked by the BlockCloseControl input.

CloseFailTimeout BOOL Asserts if CloseOutput remains asserted longer than the amount of
time specified in CloseFailPickupTime. This signal may be assigned to
CloseLatchReset to reset CloseSignal.

Processing

Figure 25.8 Breaker Close Logic

Programming Reference Date Code 20241023


PowerSystemAutomation 759
Examples

Timer Symbols
The timer symbols used in the logic diagrams follow the conventions shown
below:

Name Symbol Function

Time-Delayed ➤ X is a time-delay pickup value.


Pickup/Dropout ➤ Y is a time-delay dropout value.
➤ B asserts time X after input A asserts.
➤ B will not assert if A does not remain asserted for time X.
➤ If X is zero, B will assert when A asserts.
➤ If Y is zero, B will deassert when A deasserts.

Edge Trigger Timer


➤ Rising edge of A starts timer.
➤ Output B will assert time X after the rising edge of A if Reset is
false.
➤ B will remain asserted for time Y or until Reset asserts.
➤ If Y is zero, B will assert for a single processing interval.
➤ Input A is ignored when the timers are running.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Synchronism Check Based on Axion AC Modules Measurements


Objective
A user wants to perform synchronism check on both sides of a circuit breaker.
The potential transformers on the bus side of the circuit breaker are connected to
the three-phase voltage input channels of an SEL-2245-41 Axion AC metering
module, and the Phase A potential transformer of the line side of the circuit
breaker is connected to the VS input of the same AC metering module. A digital
output contact shall assert when the system is synchronized. The system is
considered to be synchronized when the bus voltage leads the line voltage by
15 degrees or less. The circuit breaker close time is 33 ms (2 power cycles at 60
Hz).

Figure 25.9 shows a diagram of the system.

Date Code 20241023 Programming Reference


760 PowerSystemAutomation
Examples

Figure 25.9 Synchronism Check Using Axion AC Input Modules

The user wants to block the synchronism-check function if any of the following
conditions are true:
➤ The system is unbalanced (negative-sequence voltage or zero-sequence
voltage is greater than 5 percent of the positive-sequence voltage).
➤ The breaker is closed.
➤ The EtherCAT network disables.

Assumptions
This example assumes the following:
➤ An SEL-2245-41 Metering module, an SEL-2244-2 Digital Input module,
and an SEL-2244-3 Digital Output module are contained in the EtherCAT
I/O network. Those modules have default names.
➤ The Phase A potential transformer on the line side of the circuit breaker is
connected to the VA input of the AC metering module.
➤ The Phase A potential transformer of the bus side of the circuit breaker is
connected to the VS input of the AC metering module.
➤ A 52A auxiliary contact of the circuit breaker is wired to the first digital
input channel of the SEL-2244-2.
➤ Voltages are represented in secondary scale of the potential transformers.
➤ Potential transformers on the bus side and the line side of the circuit
breaker are wired in wye configuration.

Solution
Code Snippet 25.1 prg_Synchronism Check — Axion
PROGRAM prg_SynchCheck
VAR
SynchCheckBreaker1 : fb_SynchronismCheck;
BlockingLogic : BOOL;
VNominalSecondary : SINT := 68;
END_VAR

Programming Reference Date Code 20241023


PowerSystemAutomation 761
Examples

// SynchCheck blocking logic


BlockingLogic := SEL_24DI_1_ECAT.INPUT_001.stVal OR
SEL_CTPT_1_ECAT.V0_FUND.MAG > 0.05*SEL_CTPT_1_ECAT.V1_FUND.MAG OR
SEL_CTPT_1_ECAT.V2_FUND.MAG > 0.05*SEL_CTPT_1_ECAT.V1_FUND.MAG OR
ECAT_POU.Client_State <> 5;

// Instantiate the Synchronism Check function block


SynchCheckBreaker1(EN := TRUE,
VRef := SEL_CTPT_1_ECAT.VA_FUND,
VRefTime := SEL_CTPT_1_ECAT.TIMESTAMP_FUND,
FreqRef := SEL_CTPT_1_ECAT.FREQ_FUND,
VSynch := SEL_CTPT_1_ECAT.VS_FUND,
VSynchTime := SEL_CTPT_1_ECAT.TIMESTAMP_FUND,
FreqSynch := SEL_CTPT_1_ECAT.VS_FREQ_FUND,
BlockSynchCheck := BlockingLogic,
VoltageMax := 1.05*VNominalSecondary,
VoltageMin := 0.95*VNominalSecondary,
VoltageDiffMax := 0.05*VNominalSecondary,
MaxSynchAngle := 15,
CircuitBreakerCloseTimeMs := 33.33);

// Assert a DO contact when the system is synchronized


SEL_10DO_1_ECAT.OUTPUT_001.operSet.ctlVal := SynchCheckBreaker1.Synchronized;
SEL_10DO_1_ECAT.OUTPUT_001.operClear.ctlVal := NOT SynchCheckBreaker1.Synchronized;

Synchronism Check Based on Synchrophasor Data


Objective
A user wants to perform synchronism check on both sides of a circuit breaker
using a remote RTAC. A protective relay is measuring the voltages at the line
side and bus side of the circuit breaker and streaming the measurements to the
RTAC via IEEE C37.118 Synchrophasor protocol. DNP control command shall
be issued when the system is synchronized. The system is considered to be
synchronized when the bus voltage leads the line voltage by 15 degrees or less.
The circuit breaker close time is 33 ms (2 power cycles at 60 Hz).

Assumptions
This example assumes the following:

➤ An IEEE C37.118 Synchrophasor client named SynchMeasurements


is added into the RTAC project. The RTAC receives synchrophasor
data from PMU1 and PMU2. PMU1 contains the reference voltage
measurements, and PMU2 contains the synchronizing voltage
measurements.
➤ A DNP client exists in the project. The DNP client is used to send the
synchronized signal to an external device.
➤ Voltages are represented in secondary scale of the potential transformers.
➤ Potential transformers on the bus side and the line side of the circuit
breaker are wired in wye configuration.
Code Snippet 25.2 prg_Synchronism Check — Synchrophasors
PROGRAM prg_SynchCheck
VAR
SynchCheckBreaker1 : fb_SynchronismCheck;
BlockingLogic : BOOL;
VNominalSecondary : SINT := 68;
END_VAR

Date Code 20241023 Programming Reference


762 PowerSystemAutomation
Examples

// SynchCheck blocking logic


BlockingLogic := SynchMeasurements_PMU1.QUALITY.validity <> good OR
SynchMeasurements_PMU2.QUALITY.validity <> good;

// Instantiate the Synchronism Check function block


SynchCheckBreaker1(EN := TRUE,
VRef := SynchMeasurements_PMU1.VA.instCVal,
VRefTime := SynchMeasurements_PMU1.TIMESTAMP,
FreqRef := SynchMeasurements_PMU1.FREQ.instMag,
VSynch := SynchMeasurements_PMU2.VA.instCVal,
VSynchTime := SynchMeasurements_PMU2.TIMESTAMP,
FreqSynch := SynchMeasurements_PMU2.FREQ.instMag,
BlockSynchCheck := BlockingLogic,
VoltageMax := 1.05*VNominalSecondary,
VoltageMin := 0.95*VNominalSecondary,
VoltageDiffMax := 0.05*VNominalSecondary,
MaxSynchAngle := 15,
CircuitBreakerCloseTimeMs := 33.33);

// Send DNP control when the system is synchronized


DNPclient_DNP.BO_00000.operTrip.ctlVal := SynchCheckBreaker1.Synchronized;

Disconnect Switch Open and Close Control Logic


Objective
A user wants to control the opening and closing of a disconnect switch.

➤ An operator sends the local open and close control commands from an
SEL Touchscreen.
➤ SCADA sends the remote open and close control commands via DNP3
protocol.
➤ A local pushbutton is used to select between local and remote modes. The
pushbutton is wired to the first digital input of an SEL-2244-2.
➤ The 89A and 89B auxiliary contacts are wired to the second and third
digital input channels of the SEL-2244-2, respectively.
➤ The disconnect switch open and close motor controls are wired to the first
and second digital outputs of an SEL-2244-3, respectively.
➤ The disconnect switch takes a maximum of 4.5 seconds to complete the
open or close operation. The open or close command should reset when
this time is reached or when there is confirmation that the open or close
operation was completed successfully.
➤ An alarm shall be sent back to the touchscreen if the disconnect switch
fails to initiate the open or close operation or if it remains in the in-
progress state longer than 4 seconds.
➤ Two Boolean Global variables called InterlockOpen and InterlockClose
are used to block the open and close control commands, respectively.

Solution
NOTE
To support control of the disconnect switch from the SEL Touchscreen in the
Bay Controller, the disconnect switch mode must be changed from its default
of "MONITOR" to "CONTROL." This change can be made in the Disconnect
Switches tab of the Bay Configuration 1 page under the SEL_Touchscreen.

Programming Reference Date Code 20241023


PowerSystemAutomation 763
Examples

Code Snippet 25.3 prg_DisconnectSwitch


PROGRAM prg_DisconnectSwitch
VAR
Switch1_Control : fb_DisconnectSwitchControl;
END_VAR

// Instantiate the Disconnect Switch Control function block


Switch1_Control(
EN := TRUE,
CloseSignalLocal :=
SEL_Touchscreen. Bay_Configuration_1_Two_Position_Disconnect_1_Close_Command.stVal,
CloseSignalRemote := DNPclient_DNP.BO_00000.operClose.ctlVal,
LocalMode := SEL_24DI_1_ECAT.INPUT_001.stVal,
BlockCloseControl := InterlockClose,
CloseLatchReset := Switch1_Control.CloseSealInTimeout OR
Switch1_Control.SwitchIsClosed,
CloseImmobilityPickupTime := T#1S,
CloseImmobilityReset := NOT Switch1_Control.SwitchIsOpen,
CloseSealInPickupTime := T#4.5S,
OpenSignalLocal :=
SEL_Touchscreen.Bay_Configuration_1_Two_Position_Disconnect_1_Open_Command.stVal,
OpenSignalRemote := DNPclient_DNP.BO_00000.operTrip.ctlVal,
BlockOpenControl := InterlockOpen,
OpenLatchReset := Switch1_Control.OpenSealInTimeout OR
Switch1_Control.SwitchIsOpen,
OpenImmobilityPickupTime := T#1S,
OpenImmobilityReset := NOT Switch1_Control.SwitchIsClosed,
OpenSealInPickupTime := T#4.5S,
AlarmPickupTime := T#4S,
Auxiliary89A := SEL_24DI_1_ECAT.INPUT_002.stVal,
Auxiliary89B := SEL_24DI_1_ECAT.INPUT_003.stVal
);

// Assign the outputs of the function block


SEL_16DO_1_ECAT.OUTPUT_001.operSet.ctlVal := Switch1_Control.OpenPulseStart;
SEL_16DO_1_ECAT.OUTPUT_001.operClear.ctlVal := Switch1_Control.OpenPulseEnd;
SEL_16DO_1_ECAT.OUTPUT_002.operSet.ctlVal := Switch1_Control.ClosePulseStart;
SEL_16DO_1_ECAT.OUTPUT_002.operClear.ctlVal := Switch1_Control.ClosePulseEnd;

Circuit Breaker Open and Close Control Logic


Objective
A user wants to control the opening and closing of a circuit breaker.

➤ An operator sends the local open and close control commands from an
SEL Touchscreen.
➤ SCADA sends the remote open and close control commands via DNP3
protocol.
➤ A local pushbutton is used to select between local and remote modes. The
pushbutton is wired to the first digital input of an SEL-2244-2.
➤ The 52A and 52B auxiliary contacts are wired to the second and third
digital input channels of the SEL-2244-2.
➤ The circuit breaker open and close coils are wired to the first and second
digital outputs of an SEL-2244-3, respectively.
➤ An alarm shall be sent back to the touchscreen if the circuit breaker does
not complete the open or close operation within 1 second.
➤ Two Boolean Global variables called InterlockOpen and InterlockClose
are used to block the open and close control commands, respectively.

Date Code 20241023 Programming Reference


764 PowerSystemAutomation
Examples

NOTE
To support control of the breaker points from the SEL Touchscreen in the Bay
Controller, the breaker mode must be changed from its default of "MONITOR"
to "CONTROL." This change can be made in the Breakers tab of the Bay
Configuration 1 page under the SEL_Touchscreen.

Solution
Code Snippet 25.4 prg_CircuitBreaker
PROGRAM prg_CircuitBreaker
VAR
CB_Open_Control : fb_BreakerOpenControl;
CB_Close_Control : fb_BreakerCloseControl;
END_VAR

// Instantiate the Breaker Open Control function block


CB_Open_Control(
EN := TRUE,
OpenSignalLocal := SEL_Touchscreen.Bay_Configuration_1_Breaker_1_Open_Command.stVal,
OpenSignalRemote := DNPclient_DNP.BO_00000.operTrip.ctlVal,
LocalMode := SEL_24DI_1_ECAT.INPUT_001.stVal,
BlockOpenControl := InterlockOpen,
OpenLatchReset := SEL_24DI_1_ECAT.INPUT_003.stVal,
OpenFailPickupTime := T#1S
);

// Instantiate the Breaker Close Control function block


CB_Close_Control(
EN := TRUE,
CloseSignalLocal := SEL_Touchscreen.Bay_Configuration_1_Breaker_1_Close_Command.stVal,
CloseSignalRemote := DNPclient_DNP.BO_00000.operClose.ctlVal,
LocalMode := SEL_24DI_1_ECAT.INPUT_001.stVal,
BlockCloseControl := InterlockClose,
CloseLatchReset := SEL_24DI_1_ECAT.INPUT_002.stVal,
CloseFailPickupTime := T#1S
);

// Assign the outputs of the open and close function blocks


SEL_16DO_1_ECAT.OUTPUT_001.operSet.ctlVal := CB_Open_Control.OpenPulseStart;
SEL_16DO_1_ECAT.OUTPUT_001.operClear.ctlVal := CB_Open_Control.OpenPulseEnd;
SEL_16DO_1_ECAT.OUTPUT_002.operSet.ctlVal := CB_Close_Control.ClosePulseStart;
SEL_16DO_1_ECAT.OUTPUT_002.operClear.ctlVal := CB_Close_Control.ClosePulseEnd;

Axion Bay Controller Applies Global Local/Remote Control for Breaker


Control
Objective
A breaker contained within a substation bay applies the Axion Bay Controllers
Global Local/Remote Control to provide control supervision to the breaker open
and close operations.

Programming Reference Date Code 20241023


PowerSystemAutomation 765
Examples

Assumptions
➤ An SEL-2241 RTAC project contains an SEL touchscreen device and the
Enable Global Local/Remote Control Mode setting is set to True.
➤ Two SEL touchscreen operation buttons are dedicated to switch the
touchscreen control between Local and Remote control modes using
a Set/Reset Latch. This latch output maps to both the Breaker Control
LocalMode and the SEL_Touchscreen_POU.Local input pin.
➤ An operator sends the local open and close control commands from the
SEL touchscreen display.
➤ SCADA sends the remote open and close control commands that are
mapped to Global Variables tags RemoteBreakerOpenCommand and
RemoteBreakerCloseCommand.
➤ Circuit breaker status and control contact outputs are mapped to Global
Variable tags BreakerIsOpen, BreakerIsClosed, OpenBreakerControl, and
CloseBreakerControl.
➤ No interlocking logic is required for this breaker control.

Solution
Code Snippet 25.5 prg_GlobablLocalRemoteCircuitBreakerControlSupervision
PROGRAM prg_GlobablLocalRemoteCircuitBreakerControlSupervision
VAR
CB_Open_Control : fb_BreakerOpenControl;
CB_Close_Control : fb_BreakerCloseControl;
LocalModeActiveSR : SR;
END_VAR

// Configure the local mode set/reset latch


LocalModeActiveSR(
SET1 := SEL_Touchscreen.Bay_Configuration_1_Operation_Button_1_Command.stVal,
RESET := SEL_Touchscreen.Bay_Configuration_1_Operation_Button_2_Command.stVal
);
// Assign the local mode Latch output to the SEL Touchscreen POU
SEL_Touchscreen_POU.Local := LocalModeActiveSR.Q1;

// Instantiate the breaker open control function block


CB_Open_Control(
EN := TRUE,
OpenSignalLocal := SEL_Touchscreen.Bay_Configuration_1_Breaker_1_Open_Command.stVal,
OpenSignalRemote := RemoteBreakerOpenCommand,
LocalMode := LocalModeActiveSR.Q1,
OpenLatchReset := BreakerIsOpen,
OpenFailPickupTime := T#1S
);

// Instantiate the breaker close control function block


CB_Close_Control(
EN := TRUE,
CloseSignalLocal := SEL_Touchscreen.Bay_Configuration_1_Breaker_1_Close_Command.stVal,
CloseSignalRemote := RemoteBreakerCloseCommand,
LocalMode := LocalModeActiveSR.Q1,
CloseLatchReset := BreakerIsClosed,
CloseFailPickupTime := T#1S
);

// Assign the outputs of the open and close function blocks


OpenBreakerControl := CB_Open_Control.OpenSignal;
CloseBreakerControl := CB_Close_Control.CloseSignal;

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 2 6

PowerSystemModel
Introduction
The PowerSystemModel library provides the ability to instantiate, describe,
and connect different power system elements. With each scan of the logic
engine task, it will collect the available measured information and determine
which nodes are connected. The model provides a single voltage quantity for all
devices connected without impedance (an electrical node) and a current for each
branch that can be directly calculated using Kirchhoff's current law.

The PowerSystemModel library works with the C37.118 synchrophasor stream


to provide a more detailed snapshot of the system than can be provided by the
raw data alone. Internally the model treats all data and parameters as three-phase
data at base units (e.g., ohms and amperes) and it uses those three-phase data to
perform its calculations. Each monitored input contains a quality_t structure. If
validity inside this structure is set to anything other than GOOD, that measured
value is not used in the calculations during this scan. Once all inputs have been
validated, the model expands existing current and voltage data to as many nodes
and branches as possible, and where sufficient data is available, provides a
sanity check on the measured values and breaker states.

The PowerSystemModel library is primarily designed to support the following


two use cases: extending system observability given a sparsely metered system
and validating measurements and topology given a densely metered system. The
breaker-and-a-half configuration, shown in Figure 26.1, is used to illustrate the
different use cases.

Figure 26.1 Differing Levels of Observability

Observability Extension: Figure 26.1a shows current meters installed on all


three breakers. By combining these measurements and the topology information,
the power system model can calculate the current injected into both of the
unmetered lines.

Error Detection: Figure 26.1b shows current meters installed on two of the three
breakers and both lines. By combining these measurements and the topology
information, the power system model can calculate the current flow through the
unmetered breaker and detect if a metering error has likely occurred.

Date Code 20241023 Programming Reference


768 PowerSystemModel
Introduction

Error Detection and Identification: Figure 26.1c shows fully redundant current.
By combining these measurements and the topology information, the power
system model can validate each of the redundant measurements, detect any
inconsistencies, and provide an indicator that one of the meters within the
collection is providing incorrect data.

Glossary
These terms are used throughout this document to describe the functionality
provided by this library.

Conducting Equipment. Any piece of electrical equipment that is designed


to carry current or that is conductively connected to the network. This does not
include containers that hold this equipment. For example, a power transformer
is not conducting equipment even though it can hold multiple power transformer
ends which are themselves conducting equipment.

Connectivity Node. A representation of the connecting point for two or more


terminals. The model will create these anywhere two or more terminals are
connected via the bootstrap methods. At no time should the user ever instantiate
a connectivity node.

Model. In this library, the model is a collection of conducting equipment that is


connected and the data that describes that equipment.

Power Transformer End. A transformer winding. A given transformer may


have two or more windings.

Terminal. The part of a piece of electrical equipment that is meant to connect


it to other equipment. Every piece of conducting equipment has at least one
terminal and all terminals should be attached to at least one other terminal
at a connectivity node. These also serve as anchoring points for various
measurement devices.

Placing a System Into the Model


As an example, the user desires to represent a substation using this library. The
high-voltage side of the substation being modeled is represented by the one-line
diagram shown in Figure 26.2:

Figure 26.2 High-Voltage End of a Substation

Programming Reference Date Code 20241023


PowerSystemModel 769
Introduction

To begin with, the user must identify the individual pieces of conducting
equipment represented by this diagram. This defines what objects must be
created within the library to model this system, as seen in Figure 26.3. Note that
every piece of conducting equipment in the model has one or more terminals
that are implicitly created with the object—the bus can be represented as only a
single terminal.

Figure 26.3 High-Voltage Components Identified

To tie each of the pieces of equipment together, we introduce the idea of a


connectivity node. These nodes provide a location to tie together as many
terminals as desired. In the library the user does not need to create these
nodes. They are created automatically when two or more terminals are
connected. Figure 26.4 shows how this might be conveyed. As before, there is a
connectivity node where the terminals of the three lines join the terminal of the
bus.

Figure 26.4 Model Tied Together With Connectivity Nodes

Figure 26.5 shows the user indicating where data are fed into (classes named
as Measurements) and read out of (classes named as Report) the model. Each
of these I/O points is tied to a terminal that it monitors. The direction of current
flow is standardized as being positive when flow is moving through the terminal
from the conducting equipment into the connectivity node. For example; if
current was flowing from left-to-right through a breaker, a measurement point
on the left terminal would read as a negative value flowing into the conducting
equipment, away from the connectivity node; and a measurement point on the
right terminal would read as a positive value flowing away from the conducting
equipment, into the connectivity node.

Date Code 20241023 Programming Reference


770 PowerSystemModel
Supported Firmware Versions

Though current and voltage values may be read in from measurements in


whatever units desired, they must be scaled to volts or amperes with the correct
sign for use in the model. Measurement classes provide a scalar that must
be correctly populated to translate the units and directionality being fed into
the model from the synchrophasor stream into the required magnitudes and
directions.

Figure 26.5 Tied Model With Measurement Points Identified

Finally, some objects need to be part of a container to define their interaction


with other objects. For example, all conducting equipment must be placed in a
nominal voltage and transformer ends must be placed in a transformer with other
transformer ends, as shown in Figure 26.6.

Figure 26.6 All Objects Defined for One Side of the Substation

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Version 3.5.1.0 can be used on RTAC firmware version R134 through R147.

Version 3.5.0.0 can be used on RTAC firmware version R132 and later.

Programming Reference Date Code 20241023


PowerSystemModel 771
Enumerations

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_ValueSource
Enumeration Description

UNAVAILABLE The value is not measured and cannot be calculated by the


installed system.

MEASURED The value is reported exactly as measured.

DIRECT_ASSOCIATION The value was achieved through comparing like values


connected without impedance.

CALCULATED The value was achieved through linear extrapolation based on


provided parameters.

UNTRUSTED The value measured here conflicts with other measured values
or the provided parameters. This can be set if a measured
value is too different from a calculated value or switch that
reports open has a calculated current.

enum_WindingConnection
Enumeration Description

DELTA A Delta winding.

WYE A Wye winding.

ZIGZAG A ZigZag winding.

WYE_NEUTRAL A Wye winding with neutral brought out for grounding.

ZIGZAG_NEUTRAL A ZigZag winding with neutral brought out for grounding.

AUTO An Autotransformer common winding.

INDEPENDENT An independent winding for single-phase connections.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

This library makes use of several ACSELERATOR RTAC Data Types for data
input, output, and storage. The layout of these structures can be found in the
ACSELERATOR RTAC SEL-5033 Software Instruction Manual.

CMV. A communications structure for moving phasors.

MV. A communications structure for moving analog values.

quality_t. A communications structure for indicating data health.

Date Code 20241023 Programming Reference


772 PowerSystemModel
Classes

SPS. A communications structure for moving binary points.

vector_t. A structure for storing phasors as an angle and a magnitude.

Classes
Classes are a particular implementation of a function block. They are generally
initialized using bootstrap methods and provide methods and properties, which
normal function blocks do not provide.

class_PowerSystemModel (Class)
This class contains the working algorithms for the model. It stores the
connections of objects to each other, controls the order of operations each scan,
and provides a centralizing point for all other features.

For the model to do its work, all elements must be tied to it before calling
run. In general, this means that all terminals must be tied first using
bootstrap_ConnectTerminals(). Then individual objects should be
configured using their assorted bootstrap_Set and bootstrap_Configure methods.
Finally, objects can be grouped in containers and transformers and meters can be
added using bootstrap_Add methods.

Inputs
Name IEC 61131 Type Description

Filename STRING The name of the log file for this model's
initialization.

ABCRotation BOOL The rotation of the phases in this model. True


indicates that after the A-phase current crosses a
reference angle, B-phase current will cross it next.

bootstrap_ConnectTerminals (Method)
Call this method to connect two terminals to each other. A terminal can be
used as an argument to this method more than once to connect more than two
terminals to each other.

If Terminal A is connected to Terminal B and then Terminal A is connected to


Terminal C, Terminal B is implicitly connected to Terminal C and the two do not
need to be connected by an explicit call to this method.

This is the first bootstrap method to be called. It must be called after all objects
are instantiated and before any other bootstrap method and before Run().

Inputs
Name IEC 61131 Type Description

pt_terminal1 POINTER TO class_Terminal The first terminal to connect.

pt_terminal2 POINTER TO class_Terminal The second terminal to connect.

Programming Reference Date Code 20241023


PowerSystemModel 773
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the terminals are connected together and added to
the model.

Processing
This method is intended to be called before processing to link objects together in
the model. It performs the following actions:
➤ Stores a reference to the model in both objects.
➤ Connects the two terminals together at a connectivity node.
➤ Connects both terminals to any other terminals already attached to the
connectivity node.
➤ Returns FALSE if the references are not stored, either because the objects
are no longer in the initialization phase or a terminal is already attached to
another model.

bootstrap_FinalizeConnections (Method)
To ensure proper tying of all model objects, this method must be called after all
terminals have been connected by bootstrap_ConnectTerminals and before
calling any other bootstrap methods or Run(). It switches the model out of the
terminal connection state in preparation for all other work.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the model has been successfully tied together.

Processing
This method prompts the model to perform the following actions:
➤ Disable the connection of additional terminals.
➤ Enable the insertion of objects (e.g., class_Breakers,
class_ACLineSegments, and others) into containers (i.e.,
class_VoltageLevels and class_PowerTransformers).
➤ Build internal linking structures required for additional processing.
➤ Return FALSE if bootstrap_ConnectTerminals() has not been
successfully called or if the system state prevented the final connections.

bootstrap_ValidateModel (Method)
This verifies the state of all objects and that the model itself can operate without
error. Until this method is called, no work is done by the Run() method.
Upon completion of this method, the model is ready to write out a log file
summarizing the configuration of the model. This file will be completed during
the first few iterations of the calls to the Run() method. Its format can be seen
in Log File Format on page 829.

Date Code 20241023 Programming Reference


774 PowerSystemModel
Classes

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the model is ready to monitor inputs and update
outputs.

Processing
This method is intended to be called before ever calling Run() to finalize all
model configuration. It prompts the model to perform the following actions:

➤ Disable the attachment of any additional containers.


➤ Check that all model objects have every reference required for
calculations.
➤ Return FALSE if the model is unable to calculate model state due to a
configuration error. Any such error will be described in the file filename.

Run (Method)
This method drives all work done by the model. It should be called once per task
scan after all configuration information has been processed.

Processing
Each time Run() is called, it performs the following tasks:

➤ Checks that the model has been validated and deemed healthy.
➤ Updates the measurements from all inputs configured during bootstrap.
➤ Determines the observability of the system. This decides which current
values can be calculated and which cannot be based on the switch states
and valid measurement values available.
➤ Calculates the current through all observable pieces of conducting
equipment and the voltage at all observable terminals. If measurements
beyond the minimum required for observability are available, the method
uses all available information to generate a minimum mean squared error
estimate.
➤ If measurements are deemed to be too far from calculated values, the
resulting output will be flagged as UNTRUSTED. Likewise, any switch
reporting as open with more than minimal current running through it will
be reported as UNTRUSTED.
➤ Once all measurements are calculated and outputs are flagged, the
time-aligned values will be placed in the outputs of all user-provided
measurement points and all switches and breakers.

class_ConductingEquipment
This class is never instantiated by the user. This is a category of object that is
extended to allow objects of multiple types to be treated as if they are the same
for the purpose of grouping and analysis. Classes that extend this class can be
added to class_VoltageLevels.

Programming Reference Date Code 20241023


PowerSystemModel 775
Classes

class_Measurement
This class is never instantiated by the user. This is a category of object that is
extended to allow objects of multiple types to be treated as if they are the same
for the purpose of grouping and analysis. Classes that extend this class can be
added to terminals for both input and output of measurement values.

class_Terminal
The point on a piece of conducting equipment that connects to other conducting
equipment. Terminals are used to join all objects together and provide explicit
points of contact for measurement units.

This class is never instantiated by the user. All instantiated conducting


equipment already have terminals as member objects. The user must be aware
that terminals exist to facilitate calling bootstrap methods to tie the model
together and to attach measurement points.

bootstrap_AddMeasurement (Method)
Call this method to tie a measurement point to a specific terminal.

This is the last type of bootstrap method to be called. It must be called after all
terminals are connected and all configure and set bootstrap methods have been
completed.

Inputs/Outputs

Name IEC 61131 Type Description

measurement class_Measurement The measurement to be applied to this terminal.

Return Value

IEC 61131 Type Description

BOOL The measurement was successfully added to the terminal.

Processing
This method stores a reference to the provided measurement at this terminal
unless the objects are no longer in the initialization phase or the terminal is
attached to a bus or junction and the measurement is a current measurement.
After being attached, these measurement inputs and outputs will be used with all
operations acting on the model.

class_Switch
Instantiate one instance of this class for any non-load breaking switch in the
model. The instance tracks the open-close state of that device. Before this class
can be used, one or both of its bootstrap methods must be called.

Date Code 20241023 Programming Reference


776 PowerSystemModel
Classes

If none of the variables being monitored are healthy on a given scan, the switch
will be analyzed per its TypicallyClosed value and the StO_Quality will be set
to UNAVAILABLE. If only one value is available, because only one bootstrap
method is called or only one monitored value is healthy, that value will be used
as the open-close state. If both values are bootstrapped and healthy and the two
values conflict, the switch will be analyzed per its TypicallyClosed value and the
StO_Quality will be set to UNTRUSTED.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_ConductingEquipment

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

TypicallyClosed BOOL This switch is closed under normal operating


conditions. This is the value that will be used if
there is no communication with the switch.

Inputs/Outputs

Name IEC 61131 Type Description

pt_TerminalA POINTER TO The first terminal of this switch, used to attach it inside the model.
class_Terminal

pt_TerminalB POINTER TO The second terminal of this switch, used to attach it inside the model.
class_Terminal

StIn_IsClosed BOOL The switch is reporting as closed.

StIn_IsClosedQOk BOOL The channel communicating switch state is healthy.

StO_IsClosed BOOL The state the model calculates the switch to be in. The model may override an open
condition if current is still detected across the link.

StO_Quality enum_ValueSource The confidence level in the StO_IsClosed flag.

bootstrap_ConfigureIsOpenInput (Method)
Call this method to provide a reference to the value the switch should monitor to
detect an open condition.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Programming Reference Date Code 20241023


PowerSystemModel 777
Classes

Inputs/Outputs

Name IEC 61131 Type Description

stIn_IsOpen SPS The variable that will be monitored to determine


the open status of this switch.

Return Value

IEC 61131 Type Description

BOOL The switch was successfully configured.

Processing
This method is intended to be called before processing to associate a data
location with the switch. It performs the following actions:

➤ Stores a reference to the provided variable to be used later.


➤ Returns FALSE if the reference is not stored because the switch already
had this bootstrap method called.

bootstrap_ConfigureIsClosedInput (Method)
Call this method to provide a reference to the value the switch should monitor to
detect a closed condition.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs/Outputs

Name IEC 61131 Type Description

stIn_IsClosed SPS The variable that will be monitored to determine


the closed status of this switch.

Return Value

IEC 61131 Type Description

BOOL The switch was successfully configured.

Processing
This method is intended to be called before processing to associate a data
location with the switch. It performs the following actions:

➤ Stores a reference to the provided variable to be used later.


➤ Returns FALSE if the reference is not stored because the switch already
had this bootstrap method called.

Date Code 20241023 Programming Reference


778 PowerSystemModel
Classes

class_Breaker
Instantiate one instance of this class for any load breaking device in the model.
The instance tracks open-close state of that device. Before this class can be used,
one or both of its bootstrap methods must be called.
If none of the variables being monitored are healthy on a given scan, the breaker
will be analyzed per its TypicallyClosed value and the StO_Quality will be set
to UNAVAILABLE. If only one value is available, because only one bootstrap
method is called or only one monitored value is healthy, that value will be used
as the open-close state. If both values are bootstrapped and healthy and the two
values conflict, the breaker will be analyzed per its TypicallyClosed value and
the StO_Quality will be set to UNTRUSTED.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.
➤ class_ConductingEquipment
➤ class_Switch

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

TypicallyClosed BOOL This breaker is closed under normal operating


conditions. This is the value that will be used if
there is no communication with the breaker.

Outputs
Name IEC 61131 Type Description

pt_TerminalA POINTER TO class_Terminal The first terminal of this breaker, used to attach it inside the model.

pt_TerminalB POINTER TO class_Terminal The second terminal of this breaker, used to attach it inside the model.

StIn_IsClosed BOOL The breaker is reporting as closed.

StIn_IsClosedQOk BOOL The channel communicating breaker state is healthy.

StO_IsClosed BOOL The state the model calculates the breaker to be in. The model may override
an open condition if current is still detected across the link.

StO_Quality enum_ValueSource The confidence level in the StO_IsClosed flag.

bootstrap_ConfigureIsOpenInput (Method)
Call this method to provide a reference to the value the breaker should monitor
to detect an open condition.
This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Programming Reference Date Code 20241023


PowerSystemModel 779
Classes

Inputs/Outputs

Name IEC 61131 Type Description

stIn_IsOpen SPS The variable that will be monitored to determine


the open status of this breaker.

Return Value

IEC 61131 Type Description

BOOL The breaker was successfully configured.

Processing
This method is intended to be called before processing to associate a data
location with the breaker. It performs the following actions:

➤ Stores a reference to the provided variable to be used later.


➤ Returns FALSE if the reference is not stored because the breaker already
had this bootstrap method called.

bootstrap_ConfigureIsClosedInput (Method)
Call this method to provide a reference to the value the breaker should monitor
to detect a closed condition.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs/Outputs

Name IEC 61131 Type Description

stIn_IsClosed SPS The variable that will be monitored to determine


the closed status of this breaker.

Return Value

IEC 61131 Type Description

BOOL The breaker was successfully configured.

Processing
This method is intended to be called before processing to associate a data
location with the breaker. It performs the following actions:

➤ Stores a reference to the provided variable to be used later.


➤ Returns FALSE if the reference is not stored because the breaker already
had this bootstrap method called.

Date Code 20241023 Programming Reference


780 PowerSystemModel
Classes

class_EnergySource
This class is a terminating element. It represents an edge of the model being
worked on. Instantiate one instance of this class anywhere it is desired to model
all elements beyond this point as a metered source of electrical power.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_ConductingEquipment

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

Outputs

Name IEC 61131 Type Description

pt_Terminal POINTER TO class_Terminal The terminal of this source, used to attach it


inside the model.

class_EnergyConsumer
This class is a terminating element. It represents an edge of the model being
worked on. Instantiate one instance of this class anywhere it is desired to model
all elements beyond this point as a metered electrical load.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_ConductingEquipment

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

Programming Reference Date Code 20241023


PowerSystemModel 781
Classes

Outputs
Name IEC 61131 Type Description

pt_Terminal POINTER TO class_Terminal The terminal of this load, used to attach it


inside the model.

class_ShuntCompensator
This class is a terminating element. It represents an edge of the model being
worked on. Instantiate one instance of this class anywhere it is desired to model
a shunt capacitor, inductor, or resistor. The provided values are used during all
operations on the model.

Inputs to this class must be in units of siemens.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_ConductingEquipment

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

conductanceAPhase LREAL The real part of the shunt admittance of the A-


phase.

susceptanceAPhase LREAL The reactive part of the shunt admittance of the


A-phase.

conductanceBPhase LREAL The real part of the shunt admittance of the B-


phase.

susceptanceBPhase LREAL The reactive part of the shunt admittance of the


B-phase.

conductanceCPhase LREAL The real part of the shunt admittance of the C-


phase.

susceptanceCPhase LREAL The reactive part of the shunt admittance of the


C-phase.

conductanceABPhase LREAL The real part of the shunt admittance due to


mutual coupling between the A-phase and the
B-phase.

susceptanceABPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the A-phase and
the B-phase.

conductanceACPhase LREAL The real part of the shunt admittance due to


mutual coupling between the A-phase and the
C-phase.

Date Code 20241023 Programming Reference


782 PowerSystemModel
Classes

Name IEC 61131 Type Description

susceptanceACPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the A-phase and
the C-phase.

conductanceBCPhase LREAL The real part of the shunt admittance due to


mutual coupling between the B-phase and the
C-phase.

susceptanceBCPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the B-phase and
the C-phase.

Outputs

Name IEC 61131 Type Description

pt_Terminal POINTER TO class_Terminal The terminal of this compensator, used to


attach it inside the model.

class_ACLineSegment
Instantiate one instance of this class at each location where it is desired to
model the connection between two points as having impedance. Each instance
defaults to zero impedance and zero shunt admittance unless an appropriate
bootstrapping method is called.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_ConductingEquipment

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

Outputs

Name IEC 61131 Type Description

pt_TerminalA POINTER TO class_Terminal The first terminal of this line, used to attach
it inside the model.

pt_TerminalB POINTER TO class_Terminal The second terminal of this line, used to


attach it inside the model.

Programming Reference Date Code 20241023


PowerSystemModel 783
Classes

bootstrap_SetNominalLineImpedance1Line (Method)
Call this method to set the line impedance using a 1-line model. Arguments of
this method must be in units of ohms.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs
Name IEC 61131 Type Description

resistance LREAL The real part of the positive-sequence series


impedance.

reactance LREAL The reactive part of the positive-sequence series


impedance.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the impedance was set based on the provided
values.

Processing
This method sets the impedance of the line based on the provided values and
returns TRUE, unless the impedance of the line was set previously or the model
is no longer in the initialization phase.

bootstrap_SetNominalLineImpedance3Phase (Method)
Call this method to set the line impedance using three-phase data. Arguments of
this method must be in units of ohms.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs
Name IEC 61131 Type Description

resistanceAPhase LREAL The real part of the series impedance of the A-


phase.

reactanceAPhase LREAL The reactive part of the series impedance of


the A-phase.

resistanceBPhase LREAL The real part of the series impedance of the B-


phase.

reactanceBPhase LREAL The reactive part of the series impedance of


the B-phase.

resistanceCPhase LREAL The real part of the series impedance of the C-


phase.

Date Code 20241023 Programming Reference


784 PowerSystemModel
Classes

Name IEC 61131 Type Description

reactanceCPhase LREAL The reactive part of the series impedance of


the C-phase.

resistanceABPhase LREAL The real part of the series impedance due to


mutual coupling between the A-phase and the
B-phase.

reactanceABPhase LREAL The reactive part of the series impedance due


to mutual coupling between the A-phase and
the B-phase.

resistanceACPhase LREAL The real part of the series impedance due to


mutual coupling between the A-phase and the
C-phase.

reactanceACPhase LREAL The reactive part of the series impedance due


to mutual coupling between the A-phase and
the C-phase.

resistanceBCPhase LREAL The real part of the series impedance due to


mutual coupling between the B-phase and the
C-phase.

reactanceBCPhase LREAL The reactive part of the series impedance due


to mutual coupling between the B-phase and
the C-phase.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the impedance was set based on the provided
values.

Processing
This method sets the impedance of the line based on the provided values and
returns TRUE, unless the impedance of the line was set previously or the model
is no longer in the initialization phase.

bootstrap_SetNominalLineImpedanceWZeroSequence (Method)
Call this method to set the line impedance using a positive- and zero-sequence
data model. Arguments of this method must be in units of ohms.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs

Name IEC 61131 Type Description

resistancePosSequence LREAL The real part of the positive-sequence series


impedance.

reactancePosSequence LREAL The reactive part of the positive-sequence


series impedance.

Programming Reference Date Code 20241023


PowerSystemModel 785
Classes

Name IEC 61131 Type Description

resistanceZeroSequence LREAL The real part of the zero-sequence series


impedance.

reactanceZeroSequence LREAL The reactive part of the zero-sequence series


impedance.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the impedance was set based on the provided
values.

Processing
This method sets the impedance of the line based on the provided values and
returns TRUE, unless the impedance of the line was set previously or the model
is no longer in the initialization phase.

bootstrap_SetNominalShuntAdmittance1Line (Method)
Call this method to set the shunt admittance of the line using a one-line model.
Arguments of this method must be in units of siemens.
This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs
Name IEC 61131 Type Description

conductance LREAL The real part of the positive-sequence shunt


admittance.

susceptance LREAL The reactive part of the positive-sequence


shunt admittance.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the admittance was set based on the provided
values.

Processing
This method sets the admittance of the line based on the provided values and
returns TRUE, unless the admittance of the line was set previously or the model
is no longer in the initialization phase.

bootstrap_SetNominalShuntAdmittance3Phase (Method)
Call this method to set the line's shunt admittance using three-phase data.
Arguments of this method must be in units of siemens.

Date Code 20241023 Programming Reference


786 PowerSystemModel
Classes

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs

Name IEC 61131 Type Description

conductanceAPhase LREAL The real part of the shunt admittance of the A-


phase.

susceptanceAPhase LREAL The reactive part of the shunt admittance of the


A-phase.

conductanceBPhase LREAL The real part of the shunt admittance of the B-


phase.

susceptanceBPhase LREAL The reactive part of the shunt admittance of the


B-phase.

conductanceCPhase LREAL The real part of the shunt admittance of the C-


phase.

susceptanceCPhase LREAL The reactive part of the shunt admittance of the


C-phase.

conductanceABPhase LREAL The real part of the shunt admittance due to


mutual coupling between the A-phase and the
B-phase.

susceptanceABPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the A-phase and
the B-phase.

conductanceACPhase LREAL The real part of the shunt admittance due to


mutual coupling between the A-phase and the
C-phase.

susceptanceACPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the A-phase and
the C-phase.

conductanceBCPhase LREAL The real part of the shunt admittance due to


mutual coupling between the B-phase and the
C-phase.

susceptanceBCPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the B-phase and
the C-phase.

Return Value

IEC 61131 Type Description

BOOL Returns true if the admittance was set based on the provided values.

Processing
This method sets the admittance of the line based on the provided values and
returns TRUE, unless the admittance of the line was set previously or the model
is no longer in the initialization phase.

Programming Reference Date Code 20241023


PowerSystemModel 787
Classes

bootstrap_SetNominalShuntAdmittanceWZeroSequence (Method)
Call this method to set the line's shunt admittance using a positive- and zero-
sequence data model. Arguments of this method must be in units of siemens.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs

Name IEC 61131 Type Description

conductancePosSequence LREAL The real part of the positive-sequence


shunt admittance.

susceptancePosSequence LREAL The reactive part of the positive-


sequence shunt admittance.

conductanceZeroSeqeunce LREAL The real part of the zero-sequence shunt


admittance.

susceptanceZeroSequence LREAL The reactive part of the zero-sequence


shunt admittance.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the admittance was set based on the provided
values.

Processing
This method sets the admittance of the line based on the provided values and
returns TRUE, unless the admittance of the line was set previously or the model
is no longer in the initialization phase.

class_PowerTransformerEnd
Instantiate one instance of this class for each transformer winding desired in the
model.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_ConductingEquipment

Date Code 20241023 Programming Reference


788 PowerSystemModel
Classes

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power


system.

Description STRING A human-readable description of this


object.

NominalRatio REAL The modifier to use as the expected


change between this winding and others
in the system.

ConnectionType enum_WindingConnection The wiring configuration of the winding.

Outputs
Name IEC 61131 Type Description

pt_Terminal POINTER TO class_Terminal The terminal of this transformer winding,


used to attach it into the model.

bootstrap_AddTapChanger (Method)
Call this method to add a tap changer that will modify the NominalRatio of this
transformer end.
This is the last type of bootstrap method to be called. It must be called after all
terminals are connected and all configure and set bootstrap methods have been
completed.

Inputs/Outputs
Name IEC 61131 Type Description

tapChanger class_TapChanger The tap changer that will modify this winding.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the tap changer is added to this winding.

Processing
This method links the provided tap changer to this winding and returns true,
unless another tap changer has already been set, the tap changer is already
modifying another transformer end, or the model is no longer in the initialization
phase.

bootstrap_SetNominalEndImpedance1Line (Method)
Call this method to set the impedance of the transformer winding from a 1-line
model. Arguments of this method must be in units of ohms.

Programming Reference Date Code 20241023


PowerSystemModel 789
Classes

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs
Name IEC 61131 Type Description

resistance LREAL The real part of the positive-sequence series


impedance.

reactance LREAL The reactive part of the positive-sequence series


impedance.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the impedance was set based on the provided
values.

Processing
This method sets the impedance of the transformer end based on the provided
values and returns TRUE, unless the impedance of the transformer end was set
previously or the model is no longer in the initialization phase.

bootstrap_SetNominalEndImpedance3Phase (Method)
Call this method to set the impedance of the transformer winding from three-
phase data. Arguments of this method must be in units of ohms.
This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs
Name IEC 61131 Type Description

resistanceAPhase LREAL The real part of the series impedance of the A-


phase.

reactanceAPhase LREAL The reactive part of the series impedance of


the A-phase.

resistanceBPhase LREAL The real part of the series impedance of the B-


phase.

reactanceBPhase LREAL The reactive part of the series impedance of


the B-phase.

resistanceCPhase LREAL The real part of the series impedance of the B-


phase.

reactanceCPhase LREAL The reactive part of the series impedance of


the B-phase.

resistanceABPhase LREAL The real part of the series impedance due to


mutual coupling between the A-phase and the
B-phase.

Date Code 20241023 Programming Reference


790 PowerSystemModel
Classes

Name IEC 61131 Type Description

reactanceABPhase LREAL The reactive part of the series impedance due


to mutual coupling between the A-phase and
the B-phase.

resistanceACPhase LREAL The real part of the series impedance due to


mutual coupling between the A-phase and the
C-phase.

reactanceACPhase LREAL The reactive part of the series impedance due


to mutual coupling between the A-phase and
the C-phase.

resistanceBCPhase LREAL The real part of the series impedance due to


mutual coupling between the B-phase and the
C-phase.

reactanceBCPhase LREAL The reactive part of the series impedance due


to mutual coupling between the B-phase and
the C-phase.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the impedance was set based on the provided
values.

Processing
This method sets the impedance of the transformer end based on the provided
values and returns TRUE, unless the impedance of the transformer end was set
previously or the model is no longer in the initialization phase.

bootstrap_SetNominalEndImpedanceWZeroSequence (Method)
Call this method to set the impedance of the transformer winding from a
positive- and zero-sequence data model. Arguments of this method must be in
units of ohms.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs

Name IEC 61131 Type Description

resistancePosSequence LREAL The real part of the positive-sequence series


impedance.

reactancePosSequence LREAL The reactive part of the positive-sequence


series impedance.

resistanceZeroSequence LREAL The real part of the zero-sequence series


impedance.

reactanceZeroSequence LREAL The reactive part of the zero-sequence series


impedance.

Programming Reference Date Code 20241023


PowerSystemModel 791
Classes

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the impedance was set based on the provided
values.

Processing
This method sets the impedance of the transformer end based on the provided
values and returns TRUE, unless the impedance of the transformer end was set
previously or the model is no longer in the initialization phase.

bootstrap_SetNominalShuntAdmittance1Line (Method)
Call this method to set the shunt admittance of the transformer end from a 1-line
model. Arguments of this method must be in units of siemens.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs

Name IEC 61131 Type Description

conductance LREAL The real part of the positive-sequence shunt


admittance.

susceptance LREAL The reactive part of the positive-sequence shunt


admittance.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the admittance was set based on the provided
values.

Processing
This method sets the admittance of the transformer end based on the provided
values and returns TRUE, unless the admittance of the transformer end was set
previously or the model is no longer in the initialization phase.

bootstrap_SetNominalShuntAdmittance3Phase (Method)
Call this method to set the shunt admittance of the transformer winding from
three-phase data. Arguments of this method must be in units of siemens.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Date Code 20241023 Programming Reference


792 PowerSystemModel
Classes

Inputs

Name IEC 61131 Type Description

conductanceAPhase LREAL The real part of the shunt admittance of the A-


phase.

susceptanceAPhase LREAL The reactive part of the shunt admittance of the


A-phase.

conductanceBPhase LREAL The real part of the shunt admittance of the B-


phase.

susceptanceBPhase LREAL The reactive part of the shunt admittance of the


B-phase.

conductanceCPhase LREAL The real part of the shunt admittance of the C-


phase.

susceptanceCPhase LREAL The reactive part of the shunt admittance of the


C-phase.

conductanceABPhase LREAL The real part of the shunt admittance due to


mutual coupling between the A-phase and the
B-phase.

susceptanceABPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the A-phase and
the B-phase.

conductanceACPhase LREAL The real part of the shunt admittance due to


mutual coupling between the A-phase and the
C-phase.

susceptanceACPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the A-phase and
the C-phase.

conductanceBCPhase LREAL The real part of the shunt admittance due to


mutual coupling between the B-phase and the
C-phase.

susceptanceBCPhase LREAL The reactive part of the shunt admittance due


to mutual coupling between the B-phase and
the C-phase.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the admittance was set based on the provided
values.

Processing
This method sets the admittance of the transformer end based on the provided
values and returns TRUE, unless the admittance of the transformer end was set
previously or the model is no longer in the initialization phase.

Programming Reference Date Code 20241023


PowerSystemModel 793
Classes

bootstrap_SetNominalShuntAdmittanceWZeroSequence (Method)
Call this method to set the shunt admittance of the transformer end from a
positive- and zero-sequence data model. Arguments of this method must be in
units of siemens.

Inputs
Name IEC 61131 Type Description

conductancePosSequence LREAL The real part of the positive-sequence


shunt admittance.

susceptancePosSequence LREAL The reactive part of the positive-


sequence shunt admittance.

conductanceZeroSeqeunce LREAL The real part of the zero-sequence shunt


admittance.

susceptanceZeroSequence LREAL The reactive part of the zero-sequence


shunt admittance.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the admittance was set based on the provided
values.

Processing
This method sets the admittance of the transformer end based on the provided
values and returns TRUE, unless the admittance of the transformer end was set
previously or the model is no longer in the initialization phase.

class_BusbarSection
Instantiate one instance of this class for each location of a bus desired to be
modeled.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_ConductingEquipment

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

Date Code 20241023 Programming Reference


794 PowerSystemModel
Classes

Outputs
Name IEC 61131 Type Description

pt_Terminal POINTER TO class_Terminal The terminal of this bus, used to attach it


into the model.

class_Junction
Instantiate one instance of this class for each location of a non-bus intersection
of three or more terminals that requires a name.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.
➤ class_ConductingEquipment

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

Outputs
Name IEC 61131 Type Description

pt_Terminal POINTER TO class_Terminal The terminal of this junction, used to attach


it into the model.

class_TapChanger
Instantiate one instance of this class for each class_PowerTransformerEnd
requiring a dynamic transformer ratio.

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

DefaultStep INT The step value this tap changer will use if communication with the device is unhealthy. A
value of zero leaves the PowerTransformer winding at its default NominalRatio.

StepSize REAL The size of each step in percentage.

StepHighLimit INT The maximum multiplier this tap changer allows.

StepLowLimit INT The minimum multiplier this tap changer allows.

Programming Reference Date Code 20241023


PowerSystemModel 795
Classes

Outputs
Name IEC 61131 Type Description

StIn_RatioModifier REAL The measured value of the tap changer as a percentage.

StIn_RatioModifierQOk BOOL The health of the communications channel providing the ratio modifier. This will be
FALSE if the value is out of bounds or the communication is flagged as invalid.

bootstrap_ConfigureInputs (Method)
Call this method to provide a reference to all required variables the tap changer
should monitor for its state.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs/Outputs

Name IEC 61131 Type Description

ratioModifier INS The variable that will report the step position of the
tap changer.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if the variables are successfully tied to the tap changer.

Processing
This method stores references to the provided variables and returns true, unless
it has already been called for this tap changer.

class_PowerTransformer
Instantiate one instance of this class for each set of correlated windings to be
modeled. This class acts as a container for class_PowerTransformerEnd objects
and relates them to each other.

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

PowerFactorRating REAL The information required to derive the maximum angle from real power this transformer
allows before its behavior becomes non-linear.

RealPowerRating REAL The maximum real power this transformer can handle.

Date Code 20241023 Programming Reference


796 PowerSystemModel
Classes

bootstrap_AddWinding (Method)
Call this method to attach a class_PowerTransformerEnd to this transformer as
one of multiple windings.
This is the last type of bootstrap method to be called. It must be called after all
terminals are connected and all configure and set bootstrap methods have been
completed.

Inputs/Outputs
Name IEC 61131 Type Description

winding class_PowerTransformerEnd The winding to add to this transformer.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the winding was added successfully.

Processing
This method attaches the transformer end to this transformer and returns
true, unless the transformer end is already attached to a transformer, the
transformer has ends attached to a different model, or the model is no longer in
the initialization stage.

class_VoltageLevel
Instantiate one voltage level for each nominal voltage desired in the model. The
model uses values provided here in per-unit calculations.

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

NominalVoltage REAL The voltage value to be used in per-unit


calculations for all equipment added to this voltage
level.

bootstrap_AddEquipment (Method)
Call this method for each piece of equipment that should be associated with this
container.

Inputs/Outputs
Name IEC 61131 Type Description

equipment class_ConductingEquipment The equipment to add to the container.

Programming Reference Date Code 20241023


PowerSystemModel 797
Classes

Return Value

IEC 61131 Type Description

BOOL The equipment was successfully added to the container.

Processing
This method is intended to be called before processing to associate equipment
with this container. It performs the following actions:

➤ Stores a reference to the object so that it can be accessed as part of the


container later.
➤ If the equipment can be stored in only one of this container type, prompts
the equipment to store a reference to the container as well.
➤ Returns FALSE if the object cannot be added to the container because
either the objects are no longer in the initialization phase or the equipment
was already added to a conflicting container.

class_CurrentMeasurement
Current measurement objects can be added to any class_Terminal except one
correlating to a bus or junction. Measurements are complex phasors that must
be scaled to present the current injection from the equipment out, in amperes.
Instantiate one instance of this class for each set of current meter data that the
model needs to account for.

class_CurrentMeasurement objects also reports three-phase current values after


data manipulation.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_Measurement

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

ScaleFactor REAL A multiplier applied as values enter the model.

MaxError REAL The maximum error percentage allowed on this


meter before it is flagged as UNTRUSTED. Default
is 1%.

MinimumValue REAL The minimum value in amperes that will be used


as the denominator in calculating percentage error.
Default is 1 ampere.

Date Code 20241023 Programming Reference


798 PowerSystemModel
Classes

Outputs

Name IEC 61131 Type Description

StIn_IsEnabled BOOL The values read by this measurement are


allowed by the operator to be used in model
calculations.

StIn_QOk BOOL The values provided to this measurement


object are healthy.

StIn_PhaseA vector_t A-phase values as measured for three-phase


inputs, or a decomposition to vectors for
PosSequence or Sequence input.

StIn_PhaseB vector_t B-phase values as measured for three-phase


inputs, or a decomposition to vectors for
PosSequence or Sequence input.

StIn_PhaseC vector_t C-phase values as measured for three-phase


inputs, or a decomposition to vectors for
PosSequence or Sequence input.

StIn_PosSequence vector_t PosSequence is calculated for three-phase


inputs, or as a measured PosSequence input.

StIn_ZeroSequence vector_t ZeroSequence is calculated for three-phase


inputs, or as a measured ZeroSequence
input.

StIn_NegSequence vector_t NegSequence is calculated for three-phase


inputs, or as a measured NegSequence
input.

StO_PhaseAQuality enum_ValueSource The confidence level in the reported A-


phase value.

StO_PhaseBQuality enum_ValueSource The confidence level in the reported B-


phase value.

StO_PhaseCQuality enum_ValueSource The confidence level in the reported C-


phase value.

StO_PhaseA vector_t The A-phase value after adjustments.

StO_PhaseB vector_t The B-phase value after adjustments.

StO_PhaseC vector_t The C-phase value after adjustments.

bootstrap_ConfigureInputsPosSequence (Method)
Call this method to provide a reference to all required variables the measurement
should monitor for its state. This method configures this measurement's inputs
to be read from a single value, positive-sequence. It ensures that values read will
be converted from positive-sequence to three-phase for later calculations by the
model.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Programming Reference Date Code 20241023


PowerSystemModel 799
Classes

Inputs/Outputs

Name IEC 61131 Type Description

enable BOOL The variable that will report the state of the manual
override of this measurement.

posSequence CMV The variable that will be monitored to determine


the positive-sequence value of this measurement.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if references to the variables are stored for future use.

Processing
This method stores references to the data locations provided as well as the type
of data expected and returns true, unless the measurement has already been
given other inputs.

bootstrap_ConfigureInputsSequence (Method)
Call this method to provide a reference to all required variables the measurement
should monitor for its state. This method configures this measurement's inputs
to be read from three values: positive-, negative-, and zero-sequence. It ensures
that values read will be converted from sequence to three-phase for later
calculations by the model.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs/Outputs

Name IEC 61131 Type Description

enable BOOL The variable that will report the state of the manual
override of this measurement.

posSequence CMV The variable that will be monitored to determine


the positive-sequence value of this measurement.

zeroSequence CMV The variable that will be monitored to determine


the zero-sequence value of this measurement.

negSequence CMV The variable that will be monitored to determine


the negative-sequence value of this measurement.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if references to the variables are stored for future use.

Date Code 20241023 Programming Reference


800 PowerSystemModel
Classes

Processing
This method stores references to the data locations provided as well as the type
of data expected and returns true, unless the measurement has already been
given other inputs.

bootstrap_ConfigureInputsThreePhase (Method)
Call this method to provide a reference to all required variables the measurement
should monitor for its state. This method configures this measurement's inputs to
be read from three-phase values. It ensures that values read will be used directly
in later calculations by the model.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs/Outputs

Name IEC 61131 Type Description

enable BOOL The variable that will report the state of the manual
override of this measurement.

phaseA CMV The variable that will be monitored to determine the


A-phase value of this measurement.

phaseB CMV The variable that will be monitored to determine the


B-phase value of this measurement.

phaseC CMV The variable that will be monitored to determine the


C-phase value of this measurement.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if references to the variables are stored for future use.

Processing
This method stores references to the data locations provided as well as the type
of data expected and returns true, unless the measurement has already been
given other inputs.

class_VoltageMeasurement
Voltage measurement objects can be added to any class_Terminal.
Measurements are complex phasors that must be scaled to present the voltage in
volts. Instantiate one instance of this class for each set of voltage meter data that
the model needs to account for.

class_VoltageMeasurement objects also reports three-phase voltage values after


data manipulation.

Programming Reference Date Code 20241023


PowerSystemModel 801
Classes

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_Measurement

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

ScaleFactor REAL A multiplier applied as values enter the model.

MaxError REAL The maximum error percentage allowed on this


meter before it is flagged as UNTRUSTED. Default
is 1%.

MinimumValue REAL The minimum value in volts that will be used as


the denominator in calculating percentage error.
Default is 1 volt.

Outputs

Name IEC 61131 Type Description

StIn_IsEnabled BOOL The values read by this measurement are


allowed by the operator to be used in model
calculations.

StIn_QOk BOOL The values provided to this measurement


object are healthy.

StIn_PhaseA vector_t A-phase values as measured for three-phase


inputs, or a decomposition to vectors for
PosSequence or Sequence input.

StIn_PhaseB vector_t B-phase values as measured for three-phase


inputs, or a decomposition to vectors for
PosSequence or Sequence input.

StIn_PhaseC vector_t C-phase values as measured for three-phase


inputs, or a decomposition to vectors for
PosSequence or Sequence input.

StIn_PosSequence vector_t PosSequence is calculated for three-phase


inputs, or as a measured PosSequence input.

StIn_ZeroSequence vector_t ZeroSequence is calculated for three-phase


inputs, or as a measured ZeroSequence input.

StIn_NegSequence vector_t NegSequence is calculated for three-phase


inputs, or as a measured NegSequence input.

StO_PhaseAQuality enum_ValueSource The confidence level in the reported A-phase


value.

StO_PhaseBQuality enum_ValueSource The confidence level in the reported B-phase


value.

Date Code 20241023 Programming Reference


802 PowerSystemModel
Classes

Name IEC 61131 Type Description

StO_PhaseCQuality enum_ValueSource The confidence level in the reported C-phase


value.

StO_PhaseA vector_t The A-phase value after adjustments.

StO_PhaseB vector_t The B-phase value after adjustments.

StO_PhaseC vector_t The C-phase value after adjustments.

bootstrap_ConfigureInputsPosSequence (Method)
Call this method to provide a reference to all required variables the measurement
should monitor for its state. This method configures this measurement's inputs
to be read from a single value, positive-sequence. It ensures that values read will
be converted from positive-sequence to three-phase for later calculations by the
model.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs/Outputs

Name IEC 61131 Type Description

enable BOOL The variable that will report the state of the manual
override of this measurement.

posSequence CMV The variable that will be monitored to determine


the positive-sequence value of this measurement.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if references to the variables are stored for future use.

Processing
This method stores references to the data locations provided as well as the type
of data expected and returns true, unless the measurement has already been
given other inputs.

bootstrap_ConfigureInputsSequence (Method)
Call this method to provide a reference to all required variables the measurement
should monitor for its state. This method configures this measurement's inputs
to be read from three values: positive-, negative-, and zero-sequence. It ensures
that values read will be converted from sequence to three-phase for later
calculations by the model.

This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Programming Reference Date Code 20241023


PowerSystemModel 803
Classes

Inputs/Outputs
Name IEC 61131 Type Description

enable BOOL The variable that will report the state of the manual
override of this measurement.

posSequence CMV The variable that will be monitored to determine


the positive-sequence value of this measurement.

zeroSequence CMV The variable that will be monitored to determine


the zero-sequence value of this measurement.

negSequence CMV The variable that will be monitored to determine


the negative-sequence value of this measurement.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if references to the variables are stored for future use.

Processing
This method stores references to the data locations provided as well as the type
of data expected and returns true, unless the measurement has already been
given other inputs.

bootstrap_ConfigureInputsThreePhase (Method)
Call this method to provide a reference to all required variables the measurement
should monitor for its state. This method configures this measurement's inputs to
be read from three-phase values. It ensures that values read will be used directly
in later calculations by the model.
This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.

Inputs/Outputs
Name IEC 61131 Type Description

enable BOOL The variable that will report the state of the manual
override of this measurement.

phaseA CMV The variable that will be monitored to determine the


A-phase value of this measurement.

phaseB CMV The variable that will be monitored to determine the


B-phase value of this measurement.

phaseC CMV The variable that will be monitored to determine the


C-phase value of this measurement.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if references to the variables are stored for future use.

Date Code 20241023 Programming Reference


804 PowerSystemModel
Classes

Processing
This method stores references to the data locations provided as well as the type
of data expected and returns true, unless the measurement has already been
given other inputs.

class_ReportedCurrent3Phase
Reported current objects can be added to any class_Terminal except one
correlating to a bus or junction. Reports are complex phasors that present the
current injection from the equipment out, in amperes. Instantiate one instance
of this class for each unmonitored location where knowledge of the current is
desired.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_Measurement

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

PerPhaseMaxThreshold REAL The value that, if exceeded by the results of any phase, will flag a possible error
condition. This value is compared directly against the final unscaled output.

Outputs

Name IEC 61131 Type Description

StO_PhaseAQuality enum_ValueSource The confidence level in the


reported A-phase value.

StO_PhaseBQuality enum_ValueSource The confidence level in the


reported B-phase value.

StO_PhaseCQuality enum_ValueSource The confidence level in the


reported C-phase value.

StO_PhaseA vector_t The A-phase value after


adjustments.

StO_PhaseB vector_t The B-phase value after


adjustments.

StO_PhaseC vector_t The C-phase value after


adjustments.

PhaseAThresholdExceeded BOOL The magnitude of the A-phase


value reported exceeds the
provided threshold.

Programming Reference Date Code 20241023


PowerSystemModel 805
Classes

Name IEC 61131 Type Description

PhaseBThresholdExceeded BOOL The magnitude of the B-phase


value reported exceeds the
provided threshold.

PhaseCThresholdExceeded BOOL The magnitude of the C-phase


value reported exceeds the
provided threshold.

class_ReportedCurrentSequence
Reported current objects can be added to any class_Terminal except one
correlating to a bus or junction. Reports are complex phasors that present the
current injection from the equipment out, in amperes. Instantiate one instance
of this class for each unmonitored location where knowledge of the current is
desired.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_Measurement

Inputs

Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

positiveSeqMaxThreshold REAL The value that, if exceeded by the positive-sequence results, will flag a possible
error condition. This value is compared directly against the final unscaled output.

zeroSeqMaxThreshold REAL The value that, if exceeded by the zero-sequence results, will flag a possible error
condition. This value is compared directly against the final unscaled output.

negativeSeqMaxThreshold REAL The value that, if exceeded by the negative-sequence results, will flag a possible
error condition. This value is compared directly against the final unscaled output.

Outputs

Name IEC 61131 Type Description

StO_Quality enum_ValueSource The confidence level in the


reported sequence values.

StO_PosSequence vector_t The calculated positive-sequence


value.

StO_ZeroSequence vector_t The calculated negative-sequence


value.

StO_NegSequence vector_t The calculated zero-sequence


value.

Date Code 20241023 Programming Reference


806 PowerSystemModel
Classes

Name IEC 61131 Type Description

positiveSeqThresholdExceeded BOOL The magnitude of the positive-


sequence value reported exceeds
the provided threshold.

zeroSeqThresholdExceeded BOOL The magnitude of the zero-


sequence value reported exceeds
the provided threshold.

negativeSeqThresholdExceeded BOOL The magnitude of the negative-


sequence value reported exceeds
the provided threshold.

class_ReportedVoltage3Phase
Voltage report objects can be added to any class_Terminal. Reports are complex
phasors that present voltage in volts. Instantiate one instance of this class for
each unmonitored location where knowledge of the voltage is desired.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_Measurement

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

PerPhaseMaxThreshold REAL The value that, if exceeded by the results of any phase, will flag a possible error
condition. This value is compared directly against the final unscaled output.

Outputs
Name IEC 61131 Type Description

StO_PhaseAQuality enum_ValueSource The confidence level in the


reported A-phase value.

StO_PhaseBQuality enum_ValueSource The confidence level in the


reported B-phase value.

StO_PhaseCQuality enum_ValueSource The confidence level in the


reported C-phase value.

StO_PhaseA vector_t The A-phase value after


adjustments.

StO_PhaseB vector_t The B-phase value after


adjustments.

StO_PhaseC vector_t The C-phase value after


adjustments.

Programming Reference Date Code 20241023


PowerSystemModel 807
Classes

Name IEC 61131 Type Description

PhaseAThresholdExceeded BOOL The magnitude of the A-phase


value reported exceeds the
provided threshold.

PhaseBThresholdExceeded BOOL The magnitude of the B-phase


value reported exceeds the
provided threshold.

PhaseCThresholdExceeded BOOL The magnitude of the C-phase


value reported exceeds the
provided threshold.

class_ReportedVoltageSequence
Voltage report objects can be added to any class_Terminal. Reports are complex
phasors that present voltage in volts. Instantiate one instance of this class for
each unmonitored location where knowledge of the voltage is desired. All values
presented are in the base units used by the library.

Extended Classes
Extending a class provides full inheritance of all that classes features (methods,
variables, properties). A class may only extend one other class directly, but class
extension can be tiered indefinitely.

➤ class_Measurement

Inputs
Name IEC 61131 Type Description

Name STRING The name of this object on the power system.

Description STRING A human-readable description of this object.

positiveSeqMaxThreshold REAL The value that, if exceeded by the positive-sequence results, will flag a possible
error condition. This value is compared directly against the final unscaled output.

zeroSeqMaxThreshold REAL The value that, if exceeded by the zero-sequence results, will flag a possible error
condition. This value is compared directly against the final unscaled output.

negativeSeqMaxThreshold REAL The value that, if exceeded by the negative-sequence results, will flag a possible
error condition. This value is compared directly against the final unscaled output.

Outputs
Name IEC 61131 Type Description

StO_Quality enum_ValueSource The confidence level in the reported sequence values.

StO_PosSequence vector_t The calculated positive-sequence value.

StO_ZeroSequence vector_t The calculated negative-sequence value.

StO_NegSequence vector_t The calculated zero-sequence value.

positiveSeqThresholdExceeded BOOL The magnitude of the positive-sequence value reported exceeds the
provided threshold.

Date Code 20241023 Programming Reference


808 PowerSystemModel
Benchmarks

Name IEC 61131 Type Description

zeroSeqThresholdExceeded BOOL The magnitude of the zero-sequence value reported exceeds the provided
threshold.

negativeSeqThresholdExceeded BOOL The magnitude of the negative-sequence value reported exceeds the
provided threshold.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3505
➢ R135-V0 firmware
➤ SEL-3530
➢ R135-V0 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R135-V0 firmware

Benchmark Test Descriptions


Substation Example
The posted time is the average execution time of 100 consecutive calls to the
Run() method after initializing the system shown in Modeling a Substation on
page 809.

Distribution Network Example


The posted time is the average execution time of 100 consecutive calls to the
Run() method after initializing the system shown in Modeling a Distribution
Network on page 816.

Ring Network Example


The posted time is the average execution time of 100 consecutive calls to the
Run() method after initializing the system shown in Modeling a Ring Network
on page 823.

Programming Reference Date Code 20241023


PowerSystemModel 809
Examples

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

Substation Example Run() Time 327,803 198,856 12,858

Distribution Example Run() Time 266,256 161,899 9,550

Ring Network Example Run() Time 164,639 97,313 6,689

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.
Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Modeling a Substation
Objective
A user has a substation that needs to be monitored. The substation is laid out as
seen in Figure 26.7.

Figure 26.7 Example Substation Model

Assumptions
Typically, all inputs to a model would be assigned directly from a
communications channel; however, for ease in compilation for this example all
inputs are pulled from a GVL shown below in Code Snippet 26.1:
Code Snippet 26.1 gvl_TagHarness
VAR_GLOBAL
OpenStateValues : ARRAY [1..g_c_NumSwitches+g_c_NumBreakers] OF SPS
:= [(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),

Date Code 20241023 Programming Reference


810 PowerSystemModel
Examples

(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good))
];
TapChangerValue : INS := (stVal := 1, q := (validity := good));
EnableBits : ARRAY [1..g_c_NumVoltageMeters+g_c_NumCurrentMeters] OF
BOOL
:= [g_c_NumVoltageMeters(TRUE), g_c_NumCurrentMeters(TRUE)];
PhaseAValues : ARRAY [1..g_c_NumVoltageMeters+g_c_NumCurrentMeters] OF
CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2000)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1000))
];
PhaseBValues : ARRAY [1..g_c_NumVoltageMeters+g_c_NumCurrentMeters] OF
CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2000)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1000))
];
PhaseCValues : ARRAY [1..g_c_NumVoltageMeters+g_c_NumCurrentMeters] OF
CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2000)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1000))
];
END_VAR

Programming Reference Date Code 20241023


PowerSystemModel 811
Examples

Solution
Once the user has identified all the elements of the model and decided the source
for all required data there are only two other elements the user must create for
the model to do its work. First, all configuration and bootstrap methods must
be called before calling Run(). In this example this is shown as completed in a
GVL, Code Snippet 26.3, which allows the configuration to complete before any
task cycles begin. Second, the user must create a program that calls the model
instance's Run() method, as shown in Code Snippet 26.2.
Code Snippet 26.2 prg_RunModel
PROGRAM prg_RunModel
VAR
i : UDINT;
FirstRun : BOOL := TRUE;
END_VAR

IF FirstRun THEN
FirstRun := FALSE;

FOR i := 1 TO g_c_NumSwitches DO
g_Switches[i].Name := g_c_SwitchNames[i];
g_Switches[i].TypicallyClosed := g_c_SwitchTypicallyClosedValues[i];
END_FOR

FOR i := 1 TO g_c_NumBreakers DO
g_Breakers[i].Name := g_c_BreakerNames[i];
g_Breakers[i].TypicallyClosed :=
g_c_BreakerTypicallyClosedValues[i];
END_FOR

FOR i := 1 TO g_c_NumVoltageMeters DO
g_VoltageMeters[i].Name := g_c_VoltageMeterNames[i];
g_VoltageMeters[i].ScaleFactor := g_c_VoltageMeterScaleFactors[i];
END_FOR

FOR i := 1 TO g_c_NumCurrentMeters DO
g_CurrentMeters[i].Name := g_c_CurrentMeterNames[i];
g_VoltageMeters[i].ScaleFactor := g_c_CurrentMeterScaleFactors[i];
END_FOR
END_IF

g_Model1.Run();

Code Snippet 26.3 gvl_Bootstrap


VAR_GLOBAL CONSTANT
g_c_NumSwitches : UDINT := 10;
g_c_NumBreakers : UDINT := 8;
g_c_ConnectionCount : UDINT := 28;
g_c_NumVoltageMeters : UDINT := 2;
g_c_NumCurrentMeters : UDINT := 10;
g_c_AreaCount : UDINT := 45;
g_c_ConfigurationCount : UDINT := 39;

g_c_SwitchNames : ARRAY [1..g_c_NumSwitches] OF STRING


:= ['Sw_Source1', 'Sw_Source2', 'Sw_Bus1Bkr', 'Sw_Bus1Transformer',
'Sw_Bus2Transformer', 'Sw_Bus2Bkr', 'Sw_Load1', 'Sw_Load2',
'Sw_Load3', 'Sw_Load4'];
g_c_SwitchTypicallyClosedValues : ARRAY [1..g_c_NumSwitches] OF BOOL
:= [8(TRUE), FALSE, TRUE];
g_c_BreakerNames : ARRAY [1..g_c_NumBreakers] OF STRING
:= ['Bkr_Source1', 'Bkr_Source2', 'Bkr_TransformerHigh', 'Bkr_TransformerLow',
'Bkr_Load1', 'Bkr_Load2', 'Bkr_Load3', 'Bkr_Load4'];
g_c_BreakerTypicallyClosedValues : ARRAY [1..g_c_NumBreakers] OF BOOL
:= [6(TRUE), FALSE, TRUE];
g_c_VoltageMeterNames : ARRAY [1..g_c_NumVoltageMeters] OF STRING

Date Code 20241023 Programming Reference


812 PowerSystemModel
Examples

:= ['Bus1Voltage', 'Bus2Voltage'];
g_c_VoltageMeterScaleFactors : ARRAY [1..g_c_NumVoltageMeters] OF REAL
:= [2(1000)];
g_c_CurrentMeterNames : ARRAY [1..g_c_NumCurrentMeters] OF STRING
:= ['Source1', 'Source2', 'Bus1CurrentOut', 'TransformerCurrentHigh',
'TransformerCurrentLow', 'Bus2CurrentIn', 'Load1', 'Load2', 'Load3', 'Load4'];
g_c_CurrentMeterScaleFactors : ARRAY [1..g_c_NumCurrentMeters] OF REAL
:= [2(1), 2(-1), 2(1), 4(-1)];
END_VAR
VAR_GLOBAL
// Instantiate any desired models here:
g_Model1 : class_PowerSystemModel :=
(Filename := 'GlobalModel1.log', ABCRotation := TRUE);
// Instantiate all other components:
g_Source1 : class_EnergySource :=
(Name := 'Source1', Description := 'Line from elsewhere');
g_Source2 : class_EnergySource :=
(Name := 'Source2', Description := 'Another line');
g_Load1 : class_EnergyConsumer := (Name := 'Load1');
g_Load2 : class_EnergyConsumer := (Name := 'Load2');
g_Load3 : class_EnergyConsumer := (Name := 'Load3');
g_Load4 : class_EnergyConsumer := (Name := 'Load4');
g_Bus1 : class_BusbarSection := (Name := 'Bus1');
g_Bus2 : class_BusbarSection := (Name := 'Bus2');
g_Switches : ARRAY [1..g_c_NumSwitches] OF class_Switch;
g_Breakers : ARRAY [1..g_c_NumBreakers] OF class_Breaker;
g_VoltageMeters : ARRAY [1..g_c_NumVoltageMeters] OF
class_VoltageMeasurement;
g_CurrentMeters : ARRAY [1..g_c_NumCurrentMeters] OF
class_CurrentMeasurement;
g_Source1Line : class_ACLineSegment := (Name := 'Line1');
g_Source2Line : class_ACLineSegment := (Name := 'Line2');
g_TransformerA : class_PowerTransformer := (Name := 'InboundTransformer');
g_TransformerAHighVoltage : class_PowerTransformerEnd :=
(Name := 'TransEndHigh', ConnectionType := WYE, NominalRatio := 1.0);
g_TransformerALowVoltage : class_PowerTransformerEnd :=
(Name := 'TransEndLow', ConnectionType := WYE, NominalRatio := 0.5);
g_TransformerATapChanger : class_TapChanger := (DefaultStep := 0, StepSize := 0.05,
StepHighLimit := 16, StepLowLimit := -16);
g_HighVoltage : class_VoltageLevel;
g_LowVoltage : class_VoltageLevel;
(* Tie object terminals together.
** This should be done immediately after instantiating objects.
** This must be done before adding objects to containers. *)
g_ObjectsTied : ARRAY [1 .. g_c_ConnectionCount] OF BOOL
:= [ g_Model1.bootstrap_ConnectTerminals(
g_Source1.pt_Terminal,
g_Source1Line.pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Source1Line.pt_TerminalB,
g_Switches[1].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Source2.pt_Terminal,
g_Source2Line.pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Source2Line.pt_TerminalB,
g_Switches[2].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[1].pt_TerminalB,
g_Breakers[1].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[2].pt_TerminalB,
g_Breakers[2].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Bus1.pt_Terminal,
g_Breakers[1].pt_TerminalB),
g_Model1.bootstrap_ConnectTerminals(
g_Bus1.pt_Terminal,
g_Breakers[2].pt_TerminalB),

Programming Reference Date Code 20241023


PowerSystemModel 813
Examples

g_Model1.bootstrap_ConnectTerminals(
g_Bus1.pt_Terminal,
g_Switches[3].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[3].pt_TerminalB,
g_Breakers[3].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Breakers[3].pt_TerminalB,
g_Switches[4].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[4].pt_TerminalB,
g_TransformerAHighVoltage.pt_Terminal),
g_Model1.bootstrap_ConnectTerminals(
g_TransformerALowVoltage.pt_Terminal,
g_Switches[5].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[5].pt_TerminalB,
g_Breakers[4].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Breakers[4].pt_TerminalB,
g_Switches[6].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Bus2.pt_Terminal,
g_Switches[6].pt_TerminalB),
g_Model1.bootstrap_ConnectTerminals(
g_Bus2.pt_Terminal,
g_Breakers[5].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Bus2.pt_Terminal,
g_Breakers[6].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Bus2.pt_Terminal,
g_Breakers[7].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Bus2.pt_Terminal,
g_Breakers[8].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Breakers[5].pt_TerminalB,
g_Switches[7].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Breakers[6].pt_TerminalB,
g_Switches[8].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Breakers[7].pt_TerminalB,
g_Switches[9].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Breakers[8].pt_TerminalB,
g_Switches[10].pt_TerminalA),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[7].pt_TerminalB,
g_Load1.pt_Terminal),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[8].pt_TerminalB,
g_Load2.pt_Terminal),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[9].pt_TerminalB,
g_Load3.pt_Terminal),
g_Model1.bootstrap_ConnectTerminals(
g_Switches[10].pt_TerminalB,
g_Load4.pt_Terminal)
];
// Finish connecting terminals and enable population of containers.
g_TerminalsComplete : BOOL := g_Model1.bootstrap_FinalizeConnections();
// Set object configuration:
g_ConfigsSet : ARRAY [1 .. g_c_ConfigurationCount] OF BOOL := [
g_Switches[1].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[1]),
g_Switches[2].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[2]),

Date Code 20241023 Programming Reference


814 PowerSystemModel
Examples

g_Switches[3].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[3]),
g_Switches[4].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[4]),
g_Switches[5].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[5]),
g_Switches[6].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[6]),
g_Switches[7].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[7]),
g_Switches[8].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[8]),
g_Switches[9].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[9]),
g_Switches[10].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[10]),
g_Breakers[1].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[11]),
g_Breakers[2].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[12]),
g_Breakers[3].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[13]),
g_Breakers[4].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[14]),
g_Breakers[5].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[15]),
g_Breakers[6].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[16]),
g_Breakers[7].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[17]),
g_Breakers[8].bootstrap_ConfigureIsOpenInput
(stIn_IsOpen := OpenStateValues[18]),
g_CurrentMeters[1].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[1], phaseA := PhaseAValues[1],
phaseB := PhaseBValues[1], phaseC := PhaseCValues[1]),
g_CurrentMeters[2].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[2], phaseA := PhaseAValues[2],
phaseB := PhaseBValues[2], phaseC := PhaseCValues[2]),
g_CurrentMeters[3].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[3], phaseA := PhaseAValues[3],
phaseB := PhaseBValues[3], phaseC := PhaseCValues[3]),
g_CurrentMeters[4].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[4], phaseA := PhaseAValues[4],
phaseB := PhaseBValues[4], phaseC := PhaseCValues[4]),
g_CurrentMeters[5].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[5], phaseA := PhaseAValues[5],
phaseB := PhaseBValues[5], phaseC := PhaseCValues[5]),
g_CurrentMeters[6].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[6], phaseA := PhaseAValues[6],
phaseB := PhaseBValues[6], phaseC := PhaseCValues[6]),
g_CurrentMeters[7].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[7], phaseA := PhaseAValues[7],
phaseB := PhaseBValues[7], phaseC := PhaseCValues[7]),
g_CurrentMeters[8].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[8], phaseA := PhaseAValues[8],
phaseB := PhaseBValues[8], phaseC := PhaseCValues[8]),
g_CurrentMeters[9].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[9], phaseA := PhaseAValues[9],
phaseB := PhaseBValues[9], phaseC := PhaseCValues[9]),
g_CurrentMeters[10].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[10], phaseA := PhaseAValues[10],
phaseB := PhaseBValues[10], phaseC := PhaseCValues[10]),
g_VoltageMeters[1].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[11], phaseA := PhaseAValues[11],
phaseB := PhaseBValues[11], phaseC := PhaseCValues[11]),
g_VoltageMeters[2].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits[12], phaseA := PhaseAValues[12],
phaseB := PhaseBValues[12], phaseC := PhaseCValues[12]),
g_Source1Line.bootstrap_SetNominalLineImpedance1Line

Programming Reference Date Code 20241023


PowerSystemModel 815
Examples

(resistance := 1.2, reactance := 12),


g_Source1Line.bootstrap_SetNominalShuntAdmittance1Line
(conductance := 12, susceptance := 1.2),
g_Source2Line.bootstrap_SetNominalLineImpedance1Line
(resistance := 1.2, reactance := 12),
g_Source2Line.bootstrap_SetNominalShuntAdmittance1Line
(conductance := 12, susceptance := 1.2),
g_TransformerAHighVoltage.bootstrap_SetNominalEndImpedance3Phase(
reactanceAPhase := 10, resistanceAPhase := 1,
reactanceBPhase := 10, resistanceBPhase := 1,
reactanceCPhase := 10, resistanceCPhase := 1,
reactanceABPhase := 1, resistanceABPhase := 0.1,
reactanceACPhase := 1, resistanceACPhase := 0.1,
reactanceBCPhase := 1, resistanceBCPhase := 0.1),
g_TransformerAHighVoltage.bootstrap_SetNominalShuntAdmittance3Phase(
conductanceAPhase := 10, susceptanceAPhase := 1,
conductanceBPhase := 10, susceptanceBPhase := 1,
conductanceCPhase := 10, susceptanceCPhase := 1,
conductanceABPhase := 1, susceptanceABPhase := 0.1,
conductanceACPhase := 1, susceptanceACPhase := 0.1,
conductanceBCPhase := 1, susceptanceBCPhase := 0.1),
g_TransformerALowVoltage.bootstrap_SetNominalEndImpedance3Phase(
reactanceAPhase := 10, resistanceAPhase := 1,
reactanceBPhase := 10, resistanceBPhase := 1,
reactanceCPhase := 10, resistanceCPhase := 1,
reactanceABPhase := 1, resistanceABPhase := 0.1,
reactanceACPhase := 1, resistanceACPhase := 0.1,
reactanceBCPhase := 1, resistanceBCPhase := 0.1),
g_TransformerALowVoltage.bootstrap_SetNominalShuntAdmittance3Phase(
conductanceAPhase := 10, susceptanceAPhase := 1,
conductanceBPhase := 10, susceptanceBPhase := 1,
conductanceCPhase := 10, susceptanceCPhase := 1,
conductanceABPhase := 1, susceptanceABPhase := 0.1,
conductanceACPhase := 1, susceptanceACPhase := 0.1,
conductanceBCPhase := 1, susceptanceBCPhase := 0.1),
g_TransformerATapChanger.bootstrap_ConfigureInputs
(ratioModifier := TapChangerValue)
];
(* Add objects to containers as desired.
** This should be the last configuration done. *)
g_AreaLoaded : ARRAY [1 .. g_c_AreaCount] OF BOOL
:= [ g_TransformerA.bootstrap_AddWinding(winding :=
g_TransformerAHighVoltage),
g_TransformerA.bootstrap_AddWinding(winding :=
g_TransformerALowVoltage),
g_TransformerALowVoltage.bootstrap_AddTapChanger
(tapChanger := g_TransformerATapChanger),
g_HighVoltage.bootstrap_AddEquipment(equipment :=
g_TransformerAHighVoltage),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Source1),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Source2),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Bus1),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Switches[1]),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Switches[2]),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Switches[3]),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Switches[4]),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Breakers[1]),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Breakers[2]),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Breakers[3]),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Source1Line),
g_HighVoltage.bootstrap_AddEquipment(equipment := g_Source2Line),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_TransformerALowVoltage),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Bus2),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Switches[5]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Switches[6]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Switches[7]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Switches[8]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Switches[9]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Switches[10]),

Date Code 20241023 Programming Reference


816 PowerSystemModel
Examples

g_LowVoltage.bootstrap_AddEquipment(equipment := g_Breakers[4]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Breakers[5]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Breakers[6]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Breakers[7]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Breakers[8]),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Load1),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Load2),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Load3),
g_LowVoltage.bootstrap_AddEquipment(equipment := g_Load4),
g_Breakers[1].pt_TerminalB^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[1]),
g_Breakers[2].pt_TerminalB^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[2]),
g_Breakers[3].pt_TerminalA^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[3]),
g_TransformerAHighVoltage.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[4]),
g_TransformerALowVoltage.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[5]),
g_Breakers[4].pt_TerminalB^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[6]),
g_Breakers[5].pt_TerminalA^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[7]),
g_Breakers[6].pt_TerminalA^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[8]),
g_Breakers[7].pt_TerminalA^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[9]),
g_Breakers[8].pt_TerminalA^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters[10]),
g_Bus1.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters[1]),
g_Bus2.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters[2])
];
// Finalize all model configuration.
g_ModelValidated : BOOL := g_Model1.bootstrap_ValidateModel();
END_VAR

Modeling a Distribution Network


Objective
A user would like to monitor the power used on some distribution lines. The
layout of the lines is as seen in Figure 26.8.

Figure 26.8 Distribution Network of Interest

Programming Reference Date Code 20241023


PowerSystemModel 817
Examples

Assumptions
Typically, all inputs to a model would be assigned directly from a
communication channel; however, for ease in compilation for this example all
inputs are pulled from a GVL shown in Code Snippet 26.4. Because the user
needs to add single-phase monitoring, they must create dummy inputs for the
non-existent phases as the input sources for both voltage and current.
Code Snippet 26.4 gvl_TagHarness
VAR_GLOBAL
g_DummyVoltage : CMV
:= (q:=(validity:=invalid), instCVal:=(ang:=0, mag:=0));
g_DummyCurrent : CMV
:= (q:=(validity:=good), instCVal:=(ang:=0, mag:=0));
OpenStateValues2 : ARRAY [1..g_c_NumSwitches2+g_c_NumBreakers2] OF SPS
:= [(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good))
];
TapChangerValueN : INS := (stVal := 0, q := (validity := good));
TapChangerValueS : INS := (stVal := 0, q := (validity := good));
EnableBits2 : ARRAY [1..g_c_NumVoltageMeters2+g_c_NumCurrentMeters2] OF BOOL
:= [g_c_NumVoltageMeters2(TRUE), g_c_NumCurrentMeters2(TRUE)];
PhaseAValues2 : ARRAY [1..g_c_NumVoltageMeters2+g_c_NumCurrentMeters2] OF CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.5)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.25)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.25)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=25)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=5)),
(q:=(validity:=invalid), instCVal:=(ang:=0, mag:=0)),
(q:=(validity:=invalid), instCVal:=(ang:=0, mag:=0))
];
PhaseBValues2 : ARRAY [1..g_c_NumVoltageMeters2+g_c_NumCurrentMeters2] OF CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.5)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.25)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.25)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=25)),
(q:=(validity:=invalid), instCVal:=(ang:=0, mag:=0)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=5)),
(q:=(validity:=invalid), instCVal:=(ang:=0, mag:=0))
];
PhaseCValues2 : ARRAY [1..g_c_NumVoltageMeters2+g_c_NumCurrentMeters2] OF CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.5)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.25)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=0.25)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=25)),
(q:=(validity:=invalid), instCVal:=(ang:=0, mag:=0)),
(q:=(validity:=invalid), instCVal:=(ang:=0, mag:=0)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=5))
];
END_VAR

Date Code 20241023 Programming Reference


818 PowerSystemModel
Examples

Solution
Once the user has identified all the elements of the model and decided the source
for all required data there are only two other elements the user must create for
the model to do its work. First, all configuration and bootstrap methods must
be called before calling Run(). In this example this is shown as completed in a
GVL, Code Snippet 26.6, which allows the configuration to complete before any
task cycles begin. Second, the user must create a program that calls the model
instance's Run() method, Code Snippet 26.5:
Code Snippet 26.5 prg_RunModel
PROGRAM prg_RunModel
VAR
i : UDINT;
FirstRun : BOOL := TRUE;
END_VAR

IF FirstRun THEN
FirstRun := FALSE;

FOR i := 1 TO g_c_NumSwitches2 DO
g_Switches2[i].Name := g_c_Switches2Names[i];
g_Switches2[i].TypicallyClosed := g_c_Switches2TypicallyClosedValues[i];
END_FOR

FOR i := 1 TO g_c_NumBreakers2 DO
g_Breakers2[i].Name := g_c_Breakers2Names[i];
g_Breakers2[i].TypicallyClosed := g_c_Breakers2TypicallyClosedValues[i];
END_FOR

FOR i := 1 TO g_c_NumVoltageMeters2 DO
g_VoltageMeters2[i].Name := g_c_VoltageMeters2Names[i];
g_VoltageMeters2[i].ScaleFactor := g_c_VoltageMeters2ScaleFactors[i];
END_FOR

FOR i := 1 TO g_c_NumCurrentMeters2 DO
g_CurrentMeters2[i].Name := g_c_CurrentMeters2Names[i];
g_CurrentMeters2[i].ScaleFactor := g_c_CurrentMeters2ScaleFactors[i];
END_FOR
END_IF

g_Model2.Run();

Code Snippet 26.6 gvl_Bootstrap


VAR_GLOBAL CONSTANT
g_c_NumSwitches2 : UDINT := 4;
g_c_NumBreakers2 : UDINT := 2;
g_c_ConnectionCount2 : UDINT := 28;
g_c_NumVoltageMeters2 : UDINT := 4;
g_c_NumCurrentMeters2 : UDINT := 5;
g_c_AreaCount2 : UDINT := 49;
g_c_ConfigurationCount2 : UDINT := 37;
g_c_SeriesRealImpedancePerMile : LREAL := 0.186;
g_c_SeriesReactiveImpedancePerMile : LREAL := 0.415;
g_c_ShuntRealAdmittancePerMile : LREAL := 0;
g_c_ShuntReactiveAdmittancePerMile : LREAL := 1.044E-5;

g_c_Switches2Names : ARRAY [1..g_c_NumSwitches2] OF STRING


:= ['Sw_SourceS', 'Sw_SourceTrans', 'Sw_LineN', 'Sw_Lines'];
g_c_Switches2TypicallyClosedValues : ARRAY [1..g_c_NumSwitches2] OF BOOL
:= [4(TRUE)];
g_c_Breakers2Names : ARRAY [1..g_c_NumBreakers2] OF STRING
:= ['Bkr_LineN', 'Bkr_LineS'];
g_c_Breakers2TypicallyClosedValues : ARRAY [1..g_c_NumBreakers2] OF BOOL
:= [2(TRUE)];
g_c_VoltageMeters2Names : ARRAY [1..g_c_NumVoltageMeters2] OF STRING

Programming Reference Date Code 20241023


PowerSystemModel 819
Examples

:= ['TransformerOutVolts', 'ALineVoltage', 'BLineVoltage', 'CLineVoltage'];


g_c_VoltageMeters2ScaleFactors : ARRAY [1..g_c_NumVoltageMeters2] OF REAL
:= [3(1000)];
g_c_CurrentMeters2Names : ARRAY [1..g_c_NumCurrentMeters2] OF STRING
:= ['CurrentN', 'CurrentS', 'CurrentA', 'Current B', 'CurrentC'];
g_c_CurrentMeters2ScaleFactors : ARRAY [1..g_c_NumCurrentMeters2] OF REAL
:= [1, 4(-1)];
END_VAR
VAR_GLOBAL
// Instantiate any desired models here:
g_Model12 : class_PowerSystemModel :=
(Filename := 'GlobalModel12.log', ABCRotation := TRUE);
// Instantiate all other components:
g_SourceN : class_EnergySource := (Name := 'Source1', Description := 'North Line');
g_SourceS : class_EnergySource := (Name := 'Source2', Description := 'South Line');
g_LoadAB : class_EnergyConsumer := (Name := 'LoadAB');
g_LoadBC : class_EnergyConsumer := (Name := 'LoadBC');
g_LoadCA : class_EnergyConsumer := (Name := 'LoadCA');
g_LoadA : class_EnergyConsumer := (Name := 'LoadA');
g_LoadB : class_EnergyConsumer := (Name := 'LoadB');
g_LoadC : class_EnergyConsumer := (Name := 'LoadC');
g_Bus : class_BusbarSection := (Name := 'Bus');
g_Junction1 : class_Junction := (Name := 'Source Line Junction');
g_Junction2 : class_Junction := (Name := 'Junction N Shunt');
g_Junction3 : class_Junction := (Name := 'Junction S Shunt');
g_Junction4 : class_Junction := (Name := 'Junction two phase split');
g_Junction5 : class_Junction := (Name := 'Junction one phase split');
g_Switches2 : ARRAY [1..g_c_NumSwitches2] OF class_Switch;
g_Breakers2 : ARRAY [1..g_c_NumBreakers2] OF class_Breaker;
g_VoltageMeters2 : ARRAY [1..g_c_NumVoltageMeters2] OF
class_VoltageMeasurement;
g_CurrentMeters2 : ARRAY [1..g_c_NumCurrentMeters2] OF
class_CurrentMeasurement;
g_LineN1 : class_ACLineSegment := (Name := 'LineN1');
g_LineN2 : class_ACLineSegment := (Name := 'LineN2');
g_LineS1 : class_ACLineSegment := (Name := 'LineS1');
g_LineS2 : class_ACLineSegment := (Name := 'LineS2');
g_TransformerIn : class_PowerTransformer := (Name := 'InboundTransformer');
g_TransformerN : class_PowerTransformer := (Name := 'LineNTransformer');
g_TransformerS : class_PowerTransformer := (Name := 'LineSTransformer');
g_TransformerInHigh : class_PowerTransformerEnd :=
(Name := 'InHighVolts', ConnectionType := WYE, NominalRatio := 1.0);
g_TransformerInLow : class_PowerTransformerEnd :=
(Name := 'InLowVolts', ConnectionType := WYE, NominalRatio := 0.2);
g_TransformerNHigh : class_PowerTransformerEnd :=
(Name := 'LineNHighVolts', ConnectionType := WYE, NominalRatio := 1.0);
g_TransformerNLow : class_PowerTransformerEnd :=
(Name := 'LineNLowVolts', ConnectionType := WYE, NominalRatio := 0.21739);
g_TransformerNTap : class_TapChanger := (DefaultStep := 0, StepSize := 0.05,
StepHighLimit := 16, StepLowLimit := -16);
g_TransformerSHigh : class_PowerTransformerEnd :=
(Name := 'LineSHighVolts', ConnectionType := WYE, NominalRatio := 1.0);
g_TransformerSLow : class_PowerTransformerEnd :=
(Name := 'LineSLowVolts', ConnectionType := WYE, NominalRatio := 0.21739);
g_TransformerSTap : class_TapChanger := (DefaultStep := 0, StepSize := 0.05,
StepHighLimit := 16, StepLowLimit := -16);
g_HighVoltage2 : class_VoltageLevel;
g_MidVoltage2 : class_VoltageLevel;
g_LowVoltage2 : class_VoltageLevel;
g_NorthShunt : class_ShuntCompensator
:= ( Name := 'North Line Shunt Cap',
conductanceAPhase := 0,
susceptanceAPhase := 25,
conductanceBPhase := 0,
susceptanceBPhase := 25,
conductanceCPhase := 0,
susceptanceCPhase := 25
);
g_SouthShunt : class_ShuntCompensator

Date Code 20241023 Programming Reference


820 PowerSystemModel
Examples

:= ( Name := 'South Line Shunt Cap',


conductanceAPhase := 0,
susceptanceAPhase := 25,
conductanceBPhase := 0,
susceptanceBPhase := 25,
conductanceCPhase := 0,
susceptanceCPhase := 25
);
(* Tie object terminals together.
** This should be done immediately after instantiating objects.
** This must be done before adding objects to containers. *)
g_ObjectsTied2 : ARRAY [1 .. g_c_ConnectionCount2] OF BOOL
:= [ g_Model2.bootstrap_ConnectTerminals
(g_Junction1.pt_Terminal, g_SourceN.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals
(g_Junction1.pt_Terminal, g_Switches2[1].pt_TerminalB),
g_Model2.bootstrap_ConnectTerminals
(g_SourceS.pt_Terminal, g_Switches2[1].pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals
(g_Junction1.pt_Terminal, g_Switches2[2].pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Switches2[2].pt_TerminalB,
g_TransformerInHigh.pt_Terminal),
// The equipment between the transformers
g_Model2.bootstrap_ConnectTerminals(
g_Bus.pt_Terminal,
g_TransformerInLow.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Bus.pt_Terminal,
g_Switches2[3].pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Switches2[3].pt_TerminalB,
g_Breakers2[1].pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Breakers2[1].pt_TerminalB,
g_TransformerNHigh.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Bus.pt_Terminal,
g_Switches2[4].pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Switches2[4].pt_TerminalB,
g_Breakers2[2].pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Breakers2[2].pt_TerminalB,
g_TransformerSHigh.pt_Terminal),
// The equipment on the north line after the transformer
g_Model2.bootstrap_ConnectTerminals(
g_TransformerNLow.pt_Terminal,
g_LineN1.pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Junction2.pt_Terminal,
g_LineN1.pt_TerminalB),
g_Model2.bootstrap_ConnectTerminals(
g_Junction2.pt_Terminal,
g_NorthShunt.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Junction2.pt_Terminal,
g_LineN2.pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Junction4.pt_Terminal,
g_LineN2.pt_TerminalB),
g_Model2.bootstrap_ConnectTerminals(
g_Junction4.pt_Terminal,
g_LoadAB.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Junction4.pt_Terminal,
g_LoadBC.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Junction4.pt_Terminal,

Programming Reference Date Code 20241023


PowerSystemModel 821
Examples

g_LoadCA.pt_Terminal),
// The equipment on the south line after the transformer
g_Model2.bootstrap_ConnectTerminals(
g_TransformerSLow.pt_Terminal,
g_LineS1.pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Junction3.pt_Terminal,
g_LineS1.pt_TerminalB),
g_Model2.bootstrap_ConnectTerminals(
g_Junction3.pt_Terminal,
g_SouthShunt.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Junction3.pt_Terminal,
g_LineS2.pt_TerminalA),
g_Model2.bootstrap_ConnectTerminals(
g_Junction5.pt_Terminal,
g_LineS2.pt_TerminalB),
g_Model2.bootstrap_ConnectTerminals(
g_Junction5.pt_Terminal,
g_LoadA.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Junction5.pt_Terminal,
g_LoadB.pt_Terminal),
g_Model2.bootstrap_ConnectTerminals(
g_Junction5.pt_Terminal,
g_LoadC.pt_Terminal)
];
// Finish connecting terminals and enable population of containers.
g_TerminalsComplete2 : BOOL := g_Model2.bootstrap_FinalizeConnections();
// Set object configuration:
g_ConfigsSet2 : ARRAY [1 .. g_c_ConfigurationCount2] OF BOOL
:= [ g_Switches2[1].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues2[1]),
g_Switches2[2].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues2[2]),
g_Switches2[3].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues2[3]),
g_Switches2[4].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues2[4]),
g_Breakers2[1].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues2[5]),
g_Breakers2[2].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues2[6]),
g_CurrentMeters2[1].bootstrap_ConfigureInputsThreePhase(
enable := EnableBits2[1], phaseA := PhaseAValues2[1],
phaseB := PhaseBValues2[1], phaseC := PhaseCValues2[1]),
g_CurrentMeters2[2].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[2], phaseA := PhaseAValues2[2],
phaseB := PhaseBValues2[2], phaseC := PhaseCValues2[2]),
g_CurrentMeters2[3].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[3], phaseA := PhaseAValues2[3],
phaseB := g_DummyCurrent, phaseC := g_DummyCurrent),
g_CurrentMeters2[4].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[4], phaseA := g_DummyCurrent,
phaseB := PhaseBValues2[4], phaseC := g_DummyCurrent),
g_CurrentMeters2[5].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[5], phaseA := g_DummyCurrent,
phaseB := g_DummyCurrent, phaseC := PhaseCValues2[5]),
g_VoltageMeters2[1].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[6], phaseA := PhaseAValues2[6],
phaseB := PhaseBValues2[6], phaseC := PhaseCValues2[6]),
g_VoltageMeters2[2].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[7], phaseA := PhaseAValues2[7],
phaseB := g_DummyVoltage, phaseC := g_DummyVoltage),
g_VoltageMeters2[3].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[8], phaseA := g_DummyVoltage,
phaseB := PhaseBValues2[8], phaseC := g_DummyVoltage),
g_VoltageMeters2[4].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits2[9], phaseA := g_DummyVoltage,

Date Code 20241023 Programming Reference


822 PowerSystemModel
Examples

phaseB := g_DummyVoltage, phaseC := PhaseCValues2[9]),


g_LineN1.bootstrap_SetNominalLineImpedance1Line
(resistance := g_c_SeriesRealImpedancePerMile * 45,
reactance := g_c_SeriesReactiveImpedancePerMile * 45),
g_LineN1.bootstrap_SetNominalShuntAdmittance1Line
(conductance := g_c_ShuntRealAdmittancePerMile * 45,
susceptance := g_c_ShuntReactiveAdmittancePerMile * 45),
g_LineN2.bootstrap_SetNominalLineImpedance1Line
(resistance := g_c_SeriesRealImpedancePerMile * 2,
reactance := g_c_SeriesReactiveImpedancePerMile * 2),
g_LineN2.bootstrap_SetNominalShuntAdmittance1Line
(conductance := g_c_ShuntRealAdmittancePerMile * 2,
susceptance := g_c_ShuntReactiveAdmittancePerMile * 2),
g_LineS1.bootstrap_SetNominalLineImpedance1Line
(resistance := g_c_SeriesRealImpedancePerMile * 37,
reactance := g_c_SeriesReactiveImpedancePerMile * 37),
g_LineS1.bootstrap_SetNominalShuntAdmittance1Line
(conductance := g_c_ShuntRealAdmittancePerMile * 37,
susceptance := g_c_ShuntReactiveAdmittancePerMile * 37),
g_LineS2.bootstrap_SetNominalLineImpedance1Line
(resistance := g_c_SeriesRealImpedancePerMile * 2,
reactance := g_c_SeriesReactiveImpedancePerMile * 2),
g_LineS2.bootstrap_SetNominalShuntAdmittance1Line
(conductance := g_c_ShuntRealAdmittancePerMile * 2,
susceptance := g_c_ShuntReactiveAdmittancePerMile * 2),
g_TransformerInHigh.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_TransformerInHigh.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_TransformerInLow.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_TransformerInLow.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_TransformerNHigh.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_TransformerNHigh.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_TransformerNLow.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_TransformerNLow.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_TransformerSHigh.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_TransformerSHigh.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_TransformerSLow.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_TransformerSLow.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_TransformerNTap.bootstrap_ConfigureInputs
(ratioModifier := TapChangerValueN),
g_TransformerSTap.bootstrap_ConfigureInputs
(ratioModifier := TapChangerValueS)
];
(* Add objects to containers as desired. This should be the last configuration done. *)
g_AreaLoaded2 : ARRAY [1 .. g_c_AreaCount2] OF BOOL
:= [ g_TransformerIn.bootstrap_AddWinding(winding := g_TransformerInHigh),
g_TransformerIn.bootstrap_AddWinding(winding := g_TransformerInLow),
g_TransformerN.bootstrap_AddWinding(winding := g_TransformerNHigh),
g_TransformerN.bootstrap_AddWinding(winding := g_TransformerNLow),
g_TransformerNLow.bootstrap_AddTapChanger(tapChanger := g_TransformerNTap),
g_TransformerS.bootstrap_AddWinding(winding := g_TransformerSHigh),
g_TransformerS.bootstrap_AddWinding(winding := g_TransformerSLow),
g_TransformerSLow.bootstrap_AddTapChanger(tapChanger := g_TransformerSTap),
g_HighVoltage2.bootstrap_AddEquipment(equipment := g_TransformerInHigh),
g_HighVoltage2.bootstrap_AddEquipment(equipment := g_SourceN),
g_HighVoltage2.bootstrap_AddEquipment(equipment := g_SourceS),
g_HighVoltage2.bootstrap_AddEquipment(equipment := g_Junction1),
g_HighVoltage2.bootstrap_AddEquipment(equipment := g_Switches2[1]),

Programming Reference Date Code 20241023


PowerSystemModel 823
Examples

g_HighVoltage2.bootstrap_AddEquipment(equipment := g_Switches2[2]),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_TransformerInLow),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_Bus),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_Switches2[3]),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_Switches2[4]),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_Breakers2[1]),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_Breakers2[2]),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_TransformerNHigh),
g_MidVoltage2.bootstrap_AddEquipment(equipment := g_TransformerSHigh),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_TransformerNLow),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_TransformerSLow),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LineN1),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LineN2),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LineS1),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LineS2),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_Junction2),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_Junction3),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_Junction4),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_Junction5),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_NorthShunt),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_SouthShunt),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LoadAB),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LoadBC),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LoadCA),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LoadA),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LoadB),
g_LowVoltage2.bootstrap_AddEquipment(equipment := g_LoadC),
g_Breakers2[1].pt_TerminalB^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters2[1]),
g_Breakers2[2].pt_TerminalB^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters2[2]),
g_LoadA.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters2[3]),
g_LoadB.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters2[4]),
g_LoadC.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters2[5]),
g_Bus.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters2[1]),
g_LoadA.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters2[2]),
g_LoadB.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters2[3]),
g_LoadC.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters2[4])
];
// Finalize all model configuration.
g_ModelValidated2 : BOOL := g_Model2.bootstrap_ValidateModel();
END_VAR

Modeling a Ring Network


Objective
A user would like to monitor the power supplied on a ring network as seen in
Figure 26.9.

Date Code 20241023 Programming Reference


824 PowerSystemModel
Examples

Figure 26.9 Ring of Network of Interest

Assumptions
Typically, all inputs to a model would be assigned directly from a
communication channel; however, for ease in compilation for this example all
inputs are pulled from a GVL shown in Code Snippet 26.7.
Code Snippet 26.7 gvl_TagHarness
VAR_GLOBAL
OpenStateValues3 : ARRAY [1..1+g_c_NumBreakers3] OF SPS
:= [(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good)),
(stVal:=FALSE, q:=(validity:=good))
];
EnableBits3 : ARRAY [1..g_c_NumVoltageMeters3+g_c_NumCurrentMeters3] OF BOOL
:= [g_c_NumVoltageMeters3(TRUE), g_c_NumCurrentMeters3(TRUE)];
PhaseAValues3 : ARRAY [1..g_c_NumVoltageMeters3+g_c_NumCurrentMeters3] OF CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=10)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2))
];
PhaseBValues3 : ARRAY [1..g_c_NumVoltageMeters3+g_c_NumCurrentMeters3] OF CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=10)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),

Programming Reference Date Code 20241023


PowerSystemModel 825
Examples

(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),


(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2))
];
PhaseCValues3 : ARRAY [1..g_c_NumVoltageMeters3+g_c_NumCurrentMeters3] OF CMV
:= [(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=600)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=10)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=1)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=4)),
(q:=(validity:=good), instCVal:=(ang:=0, mag:=2))
];
END_VAR

Solution
Once the user has identified all the elements of the model and decided the source
for all required data there are only two other elements the user must create for
the model to do its work. First, the user must call all configuration and bootstrap
methods before calling Run(). In this example, this is shown as completed in a
GVL, Code Snippet 26.9, which allows the configuration to complete before any
task cycles begin. Second, the user must create a program that calls the model
instance's Run() method, Code Snippet 26.8:
Code Snippet 26.8 prg_RunModel
PROGRAM prg_RunModel
VAR
i : UDINT;
FirstRun : BOOL := TRUE;
END_VAR

IF FirstRun THEN
FirstRun := FALSE;

FOR i := 1 TO g_c_NumBreakers3 DO
g_Breakers3[i].Name := g_c_Breakers3Names[i];
g_Breakers3[i].TypicallyClosed := g_c_Breakers3TypicallyClosedValues[i];
END_FOR

FOR i := 1 TO g_c_NumVoltageMeters3 DO
g_VoltageMeters3[i].Name := g_c_VoltageMeters3Names[i];
g_VoltageMeters3[i].ScaleFactor := g_c_VoltageMeters3ScaleFactors[i];
END_FOR

FOR i := 1 TO g_c_NumCurrentMeters3 DO
g_CurrentMeters3[i].Name := g_c_CurrentMeters3Names[i];
g_CurrentMeters3[i].ScaleFactor := g_c_CurrentMeters3ScaleFactors[i];
END_FOR
END_IF

g_Model3.Run();

Code Snippet 26.9 gvl_Bootstrap


VAR_GLOBAL CONSTANT
g_c_NumBreakers3 : UDINT := 8;
g_c_ConnectionCount3 : UDINT := 21;
g_c_NumVoltageMeters3 : UDINT := 3;
g_c_NumCurrentMeters3 : UDINT := 7;
g_c_AreaCount3 : UDINT := 40;
g_c_ConfigurationCount3 : UDINT := 31;

Date Code 20241023 Programming Reference


826 PowerSystemModel
Examples

g_c_Breakers3Names : ARRAY [1..g_c_NumBreakers3] OF STRING


:= ['Bkr_W', 'Bkr_WNW', 'Bkr_NW', 'Bkr_NE', 'Bkr_ESE', 'Bkr_SE',
'Bkr_SW', 'Bkr_WSW'];
g_c_Breakers3TypicallyClosedValues : ARRAY [1..g_c_NumBreakers3] OF BOOL
:= [8(TRUE)];
g_c_VoltageMeters3Names : ARRAY [1..g_c_NumVoltageMeters3] OF STRING
:= ['Volts_W', 'Volts_E', 'Volts_S'];
g_c_VoltageMeters3ScaleFactors : ARRAY [1..g_c_NumVoltageMeters3] OF REAL
:= [3(1)];
g_c_CurrentMeters3Names : ARRAY [1..g_c_NumCurrentMeters3] OF STRING
:= ['CurrentW' ,'CurrentNW', 'CurrentE', 'CurrentSE', 'CurrentS',
'CurrentSW', 'CurrentRing'];
g_c_CurrentMeters3ScaleFactors : ARRAY [1..g_c_NumCurrentMeters3] OF REAL
:= [1, 3(-1), 1, -1, 1];
END_VAR
VAR_GLOBAL
// Instantiate any desired models here:
g_Model3 : class_PowerSystemModel :=
(Filename := 'GlobalModel3.log', ABCRotation := TRUE);
// Instantiate all other components:
g_Source12K : class_EnergySource := (Name := 'Utility');
g_Source600 : class_EnergySource := (Name := 'Generation');
g_Load120 : class_EnergyConsumer := (Name := 'Load120');
g_Load600_1 : class_EnergyConsumer := (Name := 'LargeLoad1');
g_Load600_2 : class_EnergyConsumer := (Name := 'LargeLoad2');
g_Load240 : class_EnergyConsumer := (Name := 'Load240');
g_JunctionW : class_Junction := (Name := 'W Junction');
g_JunctionE : class_Junction := (Name := 'E Junction');
g_JunctionS : class_Junction := (Name := 'S Junction');
g_Switch : class_Switch := (Name := 'Sw_Generation');
g_Breakers3 : ARRAY [1..g_c_NumBreakers3] OF class_Breaker;
g_VoltageMeters3 : ARRAY [1..g_c_NumVoltageMeters3] OF class_VoltageMeasurement;
g_CurrentMeters3 : ARRAY [1..g_c_NumCurrentMeters3] OF class_CurrentMeasurement;
g_Transformer12Kto600 : class_PowerTransformer := (Name := 'Transformer12K');
g_Transformer600to120 : class_PowerTransformer := (Name := 'Transformer120');
g_Transformer600to240 : class_PowerTransformer := (Name := 'Transformer240');
g_12Kin600 : class_PowerTransformerEnd :=
(Name := '12K Winding', ConnectionType := WYE, NominalRatio := 1.0);
g_12Kout600 : class_PowerTransformerEnd :=
(Name := '600 Winding', ConnectionType := WYE, NominalRatio := 0.05);
g_600in120 : class_PowerTransformerEnd :=
(Name := '600 Winding 120', ConnectionType := WYE, NominalRatio := 1.0);
g_600out120 : class_PowerTransformerEnd :=
(Name := '120 Winding', ConnectionType := WYE, NominalRatio := 0.2);
g_600in240 : class_PowerTransformerEnd :=
(Name := '600 Winding 240', ConnectionType := WYE, NominalRatio := 1.0);
g_600out240 : class_PowerTransformerEnd :=
(Name := '240 Winding', ConnectionType := WYE, NominalRatio := 0.4);
g_12KVolts : class_VoltageLevel;
g_600Volts : class_VoltageLevel;
g_240Volts : class_VoltageLevel;
g_120Volts : class_VoltageLevel;
(* Tie object terminals together.
** This should be done immediately after instantiating objects.
** This must be done before adding objects to containers. *)
g_ObjectsTied3 : ARRAY [1 .. g_c_ConnectionCount3] OF BOOL
:= [ g_Model3.bootstrap_ConnectTerminals(g_Source12K.pt_Terminal,
g_Breakers3[1].pt_TerminalA),

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[1].pt_TerminalB,
g_12Kin600.pt_Terminal),
g_Model3.bootstrap_ConnectTerminals(g_JunctionW.pt_Terminal,
g_12Kout600.pt_Terminal),
g_Model3.bootstrap_ConnectTerminals(g_JunctionW.pt_Terminal,
g_Breakers3[2].pt_TerminalA),

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[2].pt_TerminalB,
g_600in120.pt_Terminal),

Programming Reference Date Code 20241023


PowerSystemModel 827
Examples

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[2].pt_TerminalB,
g_Breakers3[3].pt_TerminalA),

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[3].pt_TerminalB,
g_Breakers3[4].pt_TerminalA),
g_Model3.bootstrap_ConnectTerminals(g_JunctionE.pt_Terminal,
g_Breakers3[4].pt_TerminalB),
g_Model3.bootstrap_ConnectTerminals(g_JunctionE.pt_Terminal,
g_Load600_1.pt_Terminal),
g_Model3.bootstrap_ConnectTerminals(g_JunctionE.pt_Terminal,
g_Breakers3[5].pt_TerminalA),

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[5].pt_TerminalB,
g_600in240.pt_Terminal),

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[5].pt_TerminalB,
g_Breakers3[6].pt_TerminalA),
g_Model3.bootstrap_ConnectTerminals(g_JunctionS.pt_Terminal,
g_Breakers3[6].pt_TerminalB),
g_Model3.bootstrap_ConnectTerminals(g_JunctionS.pt_Terminal,
g_Switch.pt_TerminalB),
g_Model3.bootstrap_ConnectTerminals(g_Switch.pt_TerminalA,
g_Source600.pt_Terminal),
g_Model3.bootstrap_ConnectTerminals(g_JunctionS.pt_Terminal,
g_Breakers3[7].pt_TerminalA),

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[7].pt_TerminalB,
g_Load600_2.pt_Terminal),

g_Model3.bootstrap_ConnectTerminals(g_Breakers3[7].pt_TerminalB,
g_Breakers3[8].pt_TerminalA),
g_Model3.bootstrap_ConnectTerminals(g_JunctionW.pt_Terminal,
g_Breakers3[8].pt_TerminalB),
g_Model3.bootstrap_ConnectTerminals(g_600out120.pt_Terminal,
g_Load120.pt_Terminal),
g_Model3.bootstrap_ConnectTerminals(g_600out240.pt_Terminal,
g_Load240.pt_Terminal)
];
// Finish connecting terminals and enable population of containers.
g_TerminalsComplete3 : BOOL :=g_Model3.bootstrap_FinalizeConnections();
// Set object configuration:
g_ConfigsSet3 : ARRAY [1 .. g_c_ConfigurationCount3] OF BOOL
:= [ g_Switch.bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[1]),
g_Breakers3[1].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[2]),
g_Breakers3[2].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[3]),
g_Breakers3[3].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[4]),
g_Breakers3[4].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[5]),
g_Breakers3[5].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[6]),
g_Breakers3[6].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[7]),
g_Breakers3[7].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[8]),
g_Breakers3[8].bootstrap_ConfigureIsOpenInput(
stIn_IsOpen := OpenStateValues3[9]),
g_CurrentMeters3[1].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[1], phaseA := PhaseAValues3[1],
phaseB := PhaseBValues3[1], phaseC := PhaseCValues3[1]),
g_CurrentMeters3[2].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[2], phaseA := PhaseAValues3[2],
phaseB := PhaseBValues3[2], phaseC := PhaseCValues3[2]),
g_CurrentMeters3[3].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[3], phaseA := PhaseAValues3[3],

Date Code 20241023 Programming Reference


828 PowerSystemModel
Examples

phaseB := PhaseBValues3[3], phaseC := PhaseCValues3[3]),


g_CurrentMeters3[4].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[4], phaseA := PhaseAValues3[4],
phaseB := PhaseBValues3[4], phaseC := PhaseCValues3[4]),
g_CurrentMeters3[5].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[5], phaseA := PhaseAValues3[5],
phaseB := PhaseBValues3[5], phaseC := PhaseCValues3[5]),
g_CurrentMeters3[6].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[6], phaseA := PhaseAValues3[6],
phaseB := PhaseBValues3[6], phaseC := PhaseCValues3[6]),
g_CurrentMeters3[7].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[7], phaseA := PhaseAValues3[7],
phaseB := PhaseBValues3[7], phaseC := PhaseCValues3[7]),
g_VoltageMeters3[1].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[8], phaseA := PhaseAValues3[8],
phaseB := PhaseBValues3[8], phaseC := PhaseCValues3[8]),
g_VoltageMeters3[2].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[9], phaseA := PhaseAValues3[9],
phaseB := PhaseBValues3[9], phaseC := PhaseCValues3[9]),
g_VoltageMeters3[3].bootstrap_ConfigureInputsThreePhase
(enable := EnableBits3[10], phaseA := PhaseAValues3[10],
phaseB := PhaseBValues3[10], phaseC := PhaseCValues3[10]),
g_12Kin600.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_12Kin600.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_12Kout600.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_12Kout600.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_600in240.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_600in240.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_600out240.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_600out240.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_600in120.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_600in120.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1),
g_600out120.bootstrap_SetNominalEndImpedance1Line(
reactance := 10, resistance := 1),
g_600out120.bootstrap_SetNominalShuntAdmittance1Line(
conductance := 10, susceptance := 1)
];
(* Add objects to containers as desired. ** This should be the last configuration done. *)
g_AreaLoaded3 : ARRAY [1 .. g_c_AreaCount3] OF BOOL
:= [ g_Transformer12Kto600.bootstrap_AddWinding(winding := g_12Kin600),
g_Transformer12Kto600.bootstrap_AddWinding(winding := g_12Kout600),
g_Transformer600to240.bootstrap_AddWinding(winding := g_600in240),
g_Transformer600to240.bootstrap_AddWinding(winding := g_600out240),
g_Transformer600to120.bootstrap_AddWinding(winding := g_600in120),
g_Transformer600to120.bootstrap_AddWinding(winding := g_600out120),
g_12KVolts.bootstrap_AddEquipment(equipment := g_12Kin600),
g_12KVolts.bootstrap_AddEquipment(equipment := g_Breakers3[1]),
g_12KVolts.bootstrap_AddEquipment(equipment := g_Source12K),
g_600Volts.bootstrap_AddEquipment(equipment := g_12Kout600),
g_600Volts.bootstrap_AddEquipment(equipment := g_600in240),
g_600Volts.bootstrap_AddEquipment(equipment := g_600in120),
g_600Volts.bootstrap_AddEquipment(equipment := g_JunctionW),
g_600Volts.bootstrap_AddEquipment(equipment := g_JunctionE),
g_600Volts.bootstrap_AddEquipment(equipment := g_JunctionS),
g_600Volts.bootstrap_AddEquipment(equipment := g_Source600),
g_600Volts.bootstrap_AddEquipment(equipment := g_Load600_1),
g_600Volts.bootstrap_AddEquipment(equipment := g_Load600_2),
g_600Volts.bootstrap_AddEquipment(equipment := g_Breakers3[2]),
g_600Volts.bootstrap_AddEquipment(equipment := g_Breakers3[3]),

Programming Reference Date Code 20241023


PowerSystemModel 829
Log File Format

g_600Volts.bootstrap_AddEquipment(equipment := g_Breakers3[4]),
g_600Volts.bootstrap_AddEquipment(equipment := g_Breakers3[5]),
g_600Volts.bootstrap_AddEquipment(equipment := g_Breakers3[6]),
g_600Volts.bootstrap_AddEquipment(equipment := g_Breakers3[7]),
g_600Volts.bootstrap_AddEquipment(equipment := g_Breakers3[8]),
g_600Volts.bootstrap_AddEquipment(equipment := g_Switch),
g_240Volts.bootstrap_AddEquipment(equipment := g_600out240),
g_240Volts.bootstrap_AddEquipment(equipment := g_Load240),
g_120Volts.bootstrap_AddEquipment(equipment := g_600out120),
g_120Volts.bootstrap_AddEquipment(equipment := g_Load120),
g_JunctionW.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters3[1]),
g_JunctionE.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters3[1]),
g_JunctionS.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_VoltageMeters3[1]),
g_12Kout600.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters3[1]),
g_600in120.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters3[2]),
g_Load600_1.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters3[3]),
g_600in240.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters3[4]),
g_Switch.pt_TerminalB^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters3[5]),
g_Load600_2.pt_Terminal^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters3[6]),
g_Breakers3[4].pt_TerminalB^.bootstrap_AddMeasurement
(measurement := g_CurrentMeters3[7])
];
// Finalize all model configuration.
g_ModelValidated3 : BOOL := g_Model3.bootstrap_ValidateModel();
END_VAR

Log File Format


A log file is written to a file defined by the class_PowerSystemModel object's
Filename variable. This file is written in four parts.

First is a summary of connections. This should show a count of terminals,


equipment, and nodes (locations where terminals are tied). Next is a list of
quantities for each type of equipment. These two sets of numbers can be
compared to the system desired to be modeled to validate that all pieces
of the model are tied together. Third, any errors that might have been
encountered during validation are printed. This prints any errors detected in a
particular device, followed by the name of the device in which the errors were
encountered. Finally, a summary of windings per transformer is provided. A
sample log file for Modeling a Substation on page 809 with an added voltage
tying error is presented below:

This model is constructed from 50 terminals connected to 30 pieces of equipment by 22 nodes.

This model is comprised of the following equipment:


Energy Sources: 2
Energy Consumers: 4
Switches: 10
Breakers: 8
Lines: 2
Buses and Junctions: 2
Shunt Compensators: 0
Transformers: 1

Date Code 20241023 Programming Reference


830 PowerSystemModel
Log File Format

Conducting equipment TransEndLow not in Voltage Level.


Errors in transformer winding TransEndLow.
Transformer InboundTransformer tied to model with 2 windings.

Programming Reference Date Code 20241023


S E C T I O N 2 7

PowerSystemProtection
Introduction
The power system protection library provides function blocks that implement
various protection elements for power systems. This library is intended to be
used in conjunction with the SEL-2245-42 AC Protection Module.

Special Considerations
This library is not supported on the SEL-3505 class of RTACs. This is because
the SEL-3505 does not support the Axion AC Protection Module. However, this
library is not prevented from running on an SEL-3505; doing so has not been
tested and has no guarantee on expected behavior.
The fb_ValphaUnderVoltage requires the SEL-3555, SEL-3560, or SEL-3350
class of RTACs, because it is intended to collect the samples and channel
information from the Axion Wave Server.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.
Library version 3.5.0.0 is meant to be used with the AC Protection Module,
which is not supported until RTAC firmware R137. However, there are no
explicit checks to enforce this, and the library version 3.5.0.0 can be imported
and used in logic in RTAC projects targeting firmware version R132 or later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_LineBusStates
Given the voltage levels on the bus side and line side of a breaker, the line side
and bus side can each be either live or dead. This enumeration represents the
four permutations that result from the two monitored locations, each in one of
two states. There are also permutations provided for when one of the states can
be confirmed, but not the other.

Enumeration Description

DLDB Dead-Line, Dead-Bus

DLLB Dead-Line, Live-Bus

Date Code 20241023 Programming Reference


832 PowerSystemProtection
Function Blocks

Enumeration Description

DLUB Dead-Line, Undefined-Bus (bus voltage is above dead threshold, but not
above live threshold)

LLDB Live-Line, Dead-Bus

LLLB Live-Line, Live-Bus

LLUB Live-Line, Undefined-Bus (bus voltage is above dead threshold, but not
above live threshold)

ULDB Undefined-Line, Dead-Bus (line voltage is above dead threshold, but not
above live threshold)

ULLB Undefined-Line, Live-Bus (bus voltage is above dead threshold, but not
above live threshold)

ULUB Undefined-Line, Undefined-Bus (bus voltage and Line Voltage are both
above dead threshold and below live threshold, or the computation is
being blocked because of an error)

enum_PTConnectionType
This enumeration defines the potential transformer wiring configuration.

Enumeration Description

WYE Wye-connected wiring configuration.

DELTA Delta-connected wiring configuration.

Function Blocks
fb_DefiniteTime (Function Block)
This function block implements instantaneous and definite-time overcurrent
protection functionality.

The settings inputs (starting with Set) are read on the first call to the function
block after EN becomes TRUE or on the first call to the function block. All
changes to the settings inputs during runtime are ignored until the next rising
edge of EN is detected.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block.

SetPickupSetting REAL Pickup current of the protection element. This is the minimum current required to initiate
the operation of the protection element.

SetDelayTime TIME Time delay for definite-time overcurrent protection element. This should be set to a
multiple of the RTAC processing scan time on which this object is instantiated and
represents the amount of time OperatingQuantity must exceed PickupSetting prior to
asserting the protection element output.

OperatingQuantity REAL The fundamental magnitude of the current. This quantity may be phase (A, B, or C),
ground, or negative-sequence current measurement.

Programming Reference Date Code 20241023


PowerSystemProtection 833
Function Blocks

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

PickupSetting REAL Pickup current value used in the protection element,


read from SetPickupSetting.

DelayTime TIME Definite-time overcurrent time delay value used in


the protection element, read from SetDelayTime.

ElementPickup BOOL Instantaneous overcurrent protection element has


operated. Set to TRUE when OperatingQuantity >=
PickupSetting.

PickupTimeOut BOOL Definite-time overcurrent protection element has


operated. Set to TRUE when OperatingQuantity >
PickupSetting for a time longer than DelayTime.

Processing
➤ If OperatingQuantity >= PickupSetting, then set ElementPickup to TRUE.
➤ If ElementPickup has been TRUE for longer than DelayTime, then set
PickupTimeOut TRUE.
➤ When OperatingQuantity < PickupSetting, reset the elapsed time in the
timer to 0 and set the ElementPickup to FALSE.

fb_InverseTimeCurveUser (Function Block)


This function block defines a custom characteristic curve of an inverse-time
overcurrent protection element. It implements the analytic equations for the
operating time and reset time specified in Section 4.2 of IEEE C37.112-1996,
IEEE Standard Inverse-Time Characteristic Equations for Overcurrent Relays.
This function block allows the user to apply constants to Equation 27.1 and
Equation 27.2 to define an inverse-time overcurrent characteristic curve.

The actual operating time or reset time of the function block is guaranteed to be
within ±1% of the calculated value or ±(2 × ProcessingIntervalRTAC).

The settings inputs (starting with Set) are read on the first call to the function
block after EN becomes TRUE. All changes to the settings inputs during runtime
are ignored until the next rising edge of EN is detected.

Equations

Equation 27.1

Equation 27.2

Date Code 20241023 Programming Reference


834 PowerSystemProtection
Function Blocks

where:

➤ M is the applied multiple of pickup current


➢ for operating time, M > 1
➢ for reset time, M < 1

Inputs

Name IEC 61131 Type Description

EN BOOL Enable this function block.

SetPickupSetting REAL Pickup current magnitude of the protection element. If OperatingQuantity goes above this
quantity, the protection element initiates its operation. This input is read once on first call to
the function block. All changes to this input during runtime are ignored.

SetTimeDial REAL Time-dial setting. This input adjusts the protection element to a predetermined trip time
at a specified current, as described in IEEE C37.112-1996, IEEE Standard Inverse-Time
Characteristic Equations for Overcurrent Relays. This input is read once on first call to the
function block. All changes to this input during runtime are ignored.

OperatingQuantity REAL The fundamental magnitude of the current. This quantity may be phase (A, B, or C), ground,
or negative-sequence current measurement.

SetA REAL Sets user-defined A parameter for inverse curve calculation (see Equation 27.1).

SetB REAL Sets user-defined B parameter for inverse curve calculation (see Equation 27.1).

SetC REAL Sets user-defined C parameter for inverse curve calculation (see Equation 27.1).

SetR REAL Sets user-defined R parameter for inverse curve calculation (see Equation 27.2).

Outputs

Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

PickupSetting REAL Pickup current value used in the protection element. This value is read from SetPickupSetting
on first run of the function block.

TimeDial REAL Time-dial setting value used in the protection element. This value is read from SetTimeDial on
first run of the function block.

ElementPickup BOOL The protection element has initiated operation. Set to TRUE if OperatingQuantity >
PickupSetting.

PickupTimeOut BOOL The protection element has operated. Set to TRUE when the operating time expires.

ElementReset BOOL The protection element has reset (refer to section 3.2 of IEEE C37.112-1996, IEEE Standard
Inverse-Time Characteristic Equations for Overcurrent Relays).

Aval REAL Value being used that was set from SetA.

Bval REAL Value being used that was set from SetB.

Cval REAL Value being used that was set from SetC.

Rval REAL Value being used that was set from SetR.

Programming Reference Date Code 20241023


PowerSystemProtection 835
Function Blocks

Processing

Predefined Inverse-Time Overcurrent Function Blocks


The function blocks listed below implement the U.S. and IEC inverse-time
overcurrent curves, in accordance with IEEE C37.112-1996, IEEE Standard
Inverse-Time Characteristic Equations for Overcurrent Relays.

The curve type, operating type, and reset time equations associated with each
function block are listed in Table 27.1 and Table 27.2.

The settings inputs (starting with Set) are read on the first call to the function
block after EN becomes TRUE. All changes to the settings inputs during runtime
are ignored until the next rising edge of EN is detected.

Date Code 20241023 Programming Reference


836 PowerSystemProtection
Function Blocks

Table 27.1 IEC Equations Associated With Predefined Inverse-Time Overcurrent Function Blocks

Curve Function Block Name Operating Time (sec) Reset Time (sec)

C1–Standard Inverse fb_InverseTimeCurveC1

C2–Very Inverse fb_InverseTimeCurveC2

C3–Extremely Inverse fb_InverseTimeCurveC3

C4–Long-Time Inverse fb_InverseTimeCurveC4

C5–Short-Time Inverse fb_InverseTimeCurveC5

Table 27.2 U.S. Equations Associated With Predefined Inverse-Time Overcurrent Function Blocks

Curve Function Block Name Operating Time (sec) Reset Time (sec)

U1–Moderately Inverse fb_InverseTimeCurveU1

U2–Inverse fb_InverseTimeCurveU2

U3–Very Inverse fb_InverseTimeCurveU3

U4–Extremely Inverse fb_InverseTimeCurveU4

U5–Short-Time Inverse fb_InverseTimeCurveU5

where:

➤ TD = time-dial setting
➤ M = applied multiple of pickup current
➢ for operating time, M > 1
➢ for reset time, M < 1

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block.

SetPickupSetting REAL Pickup current magnitude of the protection element. If OperatingQuantity goes above this
quantity, the protection element initiates its operation. This input is read once on first call to
the function block. All changes to this input during runtime are ignored.

SetTimeDial REAL Time-dial setting. This input adjusts the protection element to a predetermined trip time
at a specified current, as described in IEEE C37.112-1996, IEEE Standard Inverse-Time
Characteristic Equations for Overcurrent Relays. This input is read once on first call to the
function block. All changes to this input during runtime are ignored.

OperatingQuantity REAL The fundamental magnitude of the current. This quantity may be phase (A, B, or C), ground,
or negative-sequence current measurement.

Programming Reference Date Code 20241023


PowerSystemProtection 837
Function Blocks

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

PickupSetting REAL Pickup current value used in the protection element. This value is read from SetPickupSetting
on first run of the function block.

TimeDial REAL Time-dial setting value used in the protection element. This value is read from SetTimeDial on
first run of the function block.

ElementPickup BOOL The protection element has initiated operation. Set to TRUE if OperatingQuantity >
PickupSetting.

PickupTimeOut BOOL The protection element has operated. Set to TRUE when the operating time expires.

ElementReset BOOL The protection element has reset (refer to section 3.2 of IEEE C37.112-1996, IEEE Standard
Inverse-Time Characteristic Equations for Overcurrent Relays).

Processing
The calculations for these predefined curves happen exactly the same as for
the fb_InverseTimeCurveUser (Function Block) on page 833, except that the
coefficients used are hard-coded instead of user-settable.

fb_LossOfPotential (Function Block)


Fuses often protect the secondary windings of the power system potential
transformers. The loss-of-potential logic is used to detect blown potential
transformer fuses. The output of this function block should be used to disable
protection elements that rely on voltage inputs so that voltage-based protection
is performed securely and does not cause tripping to occur when the transformer
fuse is blown.

The function block declares a loss-of-potential condition if V1 drops in


magnitude by at least ten percent and there is no corresponding change in the
magnitude or angle of I1 or I0. A loss-of-potential condition persisting for 15
power cycles causes the loss-of-potential output to latch. The output resets when
V1 returns to a level greater than 85 percent nominal voltage and V0 is less than
10 percent of the positive-sequence voltage (V1).

This function block is intended to be used with the SEL-2245-42 AC Protection


Module.

When using the LossOfPotential function block, make sure that the RTAC task
cycle time is set to 4 ms.

The settings inputs (starting with Set) are read on the first call to the function
block after EN becomes TRUE. All changes to the settings inputs during runtime
are ignored until the next rising edge of EN is detected.

Date Code 20241023 Programming Reference


838 PowerSystemProtection
Function Blocks

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block.

SetNominalFrequency DINT(50..60) The nominal frequency (Hz) of the power system (50 or 60). Recommend setting this
input equal to the RTAC system tag: SystemTags.Nominal_Frequency.stVal

SetAmpsNominal REAL The maximum nominal amperage expected (usually 1 A or 5 A secondary).

SetVoltsNominal REAL The nominal line-to-line voltage.

VoltsPosSeq vector_t The positive-sequence fundamental voltage vector.

VoltsZeroSeq vector_t The zero-sequence voltage fundamental vector.

AmpsZeroSeq vector_t The zero-sequence current fundamental vector.

AmpsPosSeq vector_t The positive-sequence current fundamental vector.

AmpsNegSeq vector_t The negative-sequence current fundamental vector.

AmpsPhaseA vector_t The fundamental Phase A current.

AmpsPhaseB vector_t The fundamental Phase B current.

AmpsPhaseC vector_t The fundamental Phase C current.

FundQok BOOL The fundamental quantities above are reporting good quality. If values are being read
from the SEL-2245-42 module, then enable the QUALITY_FUND tag on the module and
assign that tag to this input.

FundTimeStamp timestamp_t The time stamp of the fundamental quantity measurements. Assign the
TIMESTAMP_FUND. tag on the SEL-2245-42 module to this input.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

ErrorDesc STRING(80) Displays an error description if one exists

NominalFrequency DINT[50,60] The nominal frequency of the power system (Hz).

AmpsNominal REAL The magnitude of the maximum nominal amperage expected, read once from
SetAmpsNominal.

VoltsNominal REAL The magnitude of the nominal line-to-line voltage. This value is read once from
SetVoltsNominal.

LossOfPotential BOOL Loss-of-potential condition detected. If ENO is FALSE, then this value returns to the default
TRUE state. Use this output to disable protection elements that use voltage to trip.

Programming Reference Date Code 20241023


PowerSystemProtection 839
Function Blocks

Processing

Figure 27.1 Loss-of-Potential Logic

fb_OverVoltage (Function Block)


Asserts OverVoltage when the measured voltage is higher than the threshold
setting and the function block is enabled.

Date Code 20241023 Programming Reference


840 PowerSystemProtection
Function Blocks

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block. This should be set


to FALSE if the quantity being measured is bad
quality or a loss-of-potential condition is detected.

ThresholdVoltage REAL The voltage to compare the magnitude against.

MeasuredVoltage REAL The magnitude of the voltage to measure.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

OverVoltage BOOL The MeasuredVoltage is exceeding the voltage


threshold.

Processing
The OverVoltage and ENO outputs are computed based on the input states
according to the following logic diagram:

Figure 27.2 Overvoltage Logic

fb_UnderVoltage (Function Block)


Asserts UnderVoltage when the measured voltage is lower than the threshold
setting and the function block is enabled.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block. This should be set


to FALSE if the quantity being measured is bad
quality or a loss-of-potential condition is detected.

ThresholdVoltage REAL The voltage to compare the magnitude against.

MeasuredVoltage REAL The magnitude of the voltage to measure.

Programming Reference Date Code 20241023


PowerSystemProtection 841
Function Blocks

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

UnderVoltage BOOL The MeasuredVoltage is presently less than the


threshold voltage.

Processing
The UnderVoltage and ENO outputs are computed based on the input states
according to the following logic diagram:

Figure 27.3 Undervoltage Logic

fb_BusLineVoltageCheck (Function Block)


Checks the single-phase voltage levels on the bus side and line side of a breaker.
The line side and bus side can both be either "live" or "dead", and this function
block provides the logic to decide which permutation the voltages on each
side of the breaker are in (see Enumerations on page 1232 for the listed
enumeration).

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block. This should be set


to FALSE if the quantity being measured is bad
quality or a loss-of-potential condition is detected.

LineDeadThreshold REAL The voltage at which to declare the line dead.

LineLiveThreshold REAL The voltage at which to declare the line live.

BusDeadThreshold REAL The voltage at which to declare the bus dead.

BusLiveThreshold REAL The voltage at which to declare the bus live.

LineVoltage REAL The measured voltage of the line.

BusVoltage REAL The measured voltage of the bus.

Date Code 20241023 Programming Reference


842 PowerSystemProtection
Function Blocks

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

ErrorDesc STRING(80) Displays an error description, if one exists.

LineBusState enum_LineBusStates The decided permutation.

Processing
➤ If LineDeadThreshold >LineLiveThreshold, then an error is displayed in
ErrorDesc.
➤ If BusDeadThreshold > BusLiveThreshold, then an error is displayed in
ErrorDesc.
➤ When the following conditions are met, ENO is set to TRUE:
➢ LineDeadThreshold ≤ LineLiveThreshold.
➢ BusDeadThreshold ≤ BusLiveThreshold.
➢ EN = TRUE.
➤ If ENO = TRUE, then the bus and line states are computed independently
using this logic:
➢ If the voltage is below the associated dead threshold, declare it dead.
➢ If the voltage is above the associated live threshold, declare it live.
➢ If neither of the above conditions are TRUE, declare it dead.
➤ If ENO = FALSE, then the LineBusState is set to ULUB (undefined bus,
undefined line).

fb_ConductorThermalOverload (Function Block)


This function block estimates the temperature of a conductor by measuring
the current flowing through that conductor and the ambient temperature and
declares an overload condition when the approximated temperature exceeds the
provided maximum temperature.
The settings inputs (starting with Set) are read on the first call to the function
block after EN becomes TRUE or on the or first call to the function block. All
changes to the settings inputs during runtime are ignored until the next rising
edge of EN is detected.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the computations of this function block.

SetInitialTemp REAL Given in °C; the assumed initial temperature of the line. This initializes the output
CalculatedTemp on the first scan that EN is set to TRUE.

SetTimeConstant TIME The time constant (Ʈ) which represents the heating/cooling constant of the
conductor associated with the thermal capacity of the line.

SetRatedCurrent REAL The amount of current which the conductor is rated to carry continuously. Units
must match with the MeasuredCurrent.

Programming Reference Date Code 20241023


PowerSystemProtection 843
Function Blocks

Name IEC 61131 Type Description

SetReferenceAmbientTemp REAL The ambient temperature in °C at which MaxConductorTemp was measured.

SetMaxConductorTemp REAL Given in °C; the steady state temperature if rated current flows continuously.

MeasuredCurrent REAL The rms current presently measured flowing in the conductor. Units must match the
RatedCurrent value provided.

AmbientTemp REAL The ambient dry-bulb temperature in °C. The highest measured air temperature
experienced by the conductor over its span.

Outputs
Name IEC 61131 Type Description

ENO BOOL This function block is active.

TimeConstant TIME The value (Ʈ) read from SetTimeConstant.

RatedCurrent REAL The value read from SetRatedCurrent.

ReferenceAmbientTemp REAL The value read from SetReferenceAmbientTemp.

MaxConductorTemp REAL The value read from SetMaxConductorTemp.

CalculatedTemp REAL Based on the parameters provided, this is the calculated temperature of the
conductor, given in °C. Initialized by SetInitialTemp.

TimeToOverload TIME Assuming the inputs MeasuredCurrent and AmbientTemp remain at their present
value, this is the amount of time remaining until an overload condition is declared.

Overloaded BOOL MaxConductorTemperature has been reached.

Processing
This section describes the formulas used by this function block to calculate the
outputs.

Input Validation Before Enabling


Inputs are read once and the ENO output is set to TRUE at the rising edge of the
following combination of input conditions: EN = TRUE AND SetRatedCurrent
> 0.
Once set, the values used by the function block are displayed on the outputs and
will not be read again until the rising edge described above is again detected.

Temperature Calculation
An internal model is employed which assumes that the thermal dissipation
capacity of the conductor varies only with environmental temperature, which
can either be entered manually, or a temperature sensor can be used to measure
the actual environmental air temperature.
In the following, the uppercase Latin character T is used for temperature (°C)
and the uppercase Greek Ʈ for time constant. Lowercase t is used to represent
time.
Most of the internal temperatures used in the equations are relative to ambient
temperature. These relative temperatures are represented by TΔ.

Date Code 20241023 Programming Reference


844 PowerSystemProtection
Function Blocks

The temperature rise beyond ambient that is experienced by the conductor


at steady-state when carrying the maximum rated current is given by
Equation 27.3.

Equation 27.3

where the MaxConductorTemp and ReferenceAmbientTemp are provided by


the manufacturer. MaxConductorTemp is the temperature experienced by the
conductor at steady-state when carrying rated current when the surrounding air
is at the ReferenceAmbientTemp.

The assumed maximum line temperature for this scan is shown as


TCalculatedTempk, and the correlating calculated temperature is given in
Equation 27.4.

Equation 27.4

Equation 27.5 shows the thermal differential equation, where h is the heat
transfer coefficient of the conductor surface and A is the area of the surface of
the conductor.

Equation 27.5

Equation 27.6 and Equation 27.7 show the solution of Equation 27.5 in time-
domain and discrete domain, respectively.

Equation 27.6

Equation 27.7

We can use a particular solution to find the relation between the coefficients
R, h, and A: if rated current In flows for a long amount of time (infinite), the
steady state temperature of the conductor is TΔn. Substituting these values in
Equation 27.6, the following equation can be obtained:

Equation 27.8

Substituting Equation 27.8 in Equation 27.7:

Equation 27.9

Equation 27.3 and Equation 27.4 may be expressed as follows:

Programming Reference Date Code 20241023


PowerSystemProtection 845
Function Blocks

Equation 27.10

Equation 27.11

Equation 27.12

Substituting Equation 27.10, Equation 27.11, and Equation 27.12 in


Equation 27.9, we get the equation that is used by this function block to
calculate the temperature of the conductor:

Equation 27.13

where:
TCalculatedk ≡ CalculatedTemp
TMaxConductor ≡ MaxConductorTemp
TReference ≡ ReferenceAmbientTemp
TAmbient ≡ AmbientTemp
I ≡ MeasuredCurrent
In ≡ RatedCurrent

Time to Overload Calculation


When the generation of heat exceeds the estimated thermal dissipation capacity,
the estimated temperature of the conductor is raised at a rate provided by the
user (TimeConstant), which models the thermal capacity of the line.

On each execution of the function block, a new estimated line temperature - TΔk
is calculated using Equation 27.13.

The CalculatedTemp is then compared to the MaxConductorTemp setting for


this function block. If the new estimated temperature is higher than the value of
TempThreshold, Overloaded is set to True and TimeToOverload is set to 0.

Internally, the predicted steady-state temperature that will result if the


inputs remain unchanged from their present state (Tss) is calculated using
Equation 27.14.

Equation 27.14

While the steady-state temperature Tss > TMaxConductor and TCalculatedk <
TMaxConductor, there is an imminent overload condition. The time to the overload
is calculated using Equation 27.15:

Equation 27.15

Date Code 20241023 Programming Reference


846 PowerSystemProtection
Function Blocks

If the internal steady-state temperature is lower than TempThreshold, the


TimeToOverload output is set to the maximum value stored by type TIME.

fb_OverFrequency (Function Block)


This function block implements the overfrequency protection element (81O).
Use this function block to build protection schemes that monitor a frequency
input for overfrequency events, such as turbine abnormal frequency conditions.
This function block also provides a time-delayed frequency element that uses
pickup and dropout timers to delay assertions/deassertions of the overfrequency
time-delayed element output.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block.

OperatingQuantity LREAL Input source frequency magnitude in Hz.

PickupValue LREAL Overfrequency pickup value in Hz.

Hysteresis LREAL Hysteresis value in Hz. Used to prevent element from chattering when operating at or
near the pickup value.

PickupDelay TIME The time that the delayed frequency element, PickupTimeout, waits before asserting.

DropoutDelay TIME The time that the delayed frequency element, PickupTimeout, waits to deassert after the
deassertion of the overfrequency condition.

FrequencyOk BOOL When true, the OperatingQuantity frequency signal is healthy.

FrequencyFrozen BOOL When true, the OperatingQuantity frequency signal is frozen.

Supervision BOOL Supervision for the frequency element. When False, the element is blocked from
operating.

UnderVoltageBlock BOOL Undervoltage supervision block. When True, the element is blocked from operating.

HealthAlarm BOOL Health alarm detected for the hardware or system that is providing the operating quantity.
When True, the element is blocked from operating.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

OverFrequencyPU BOOL The overfrequency protection element has operated.

ElementUnblocked BOOL Element is unblocked and outputs are valid.

PickupTimeout BOOL The overfrequency pickup delay based on the PickupDelay and DropoutDelay inputs.

Programming Reference Date Code 20241023


PowerSystemProtection 847
Function Blocks

Processing

Figure 27.4 Overfrequency Logic

The comparator referenced in Figure 27.4 is SELUtils


fb_OverComparatorWithHysteresis.

fb_UnderFrequency (Function Block)


This function block implements the underfrequency protection element
(81U). Use this function block to implement protection schemes that monitor
a frequency input for underfrequency events, such as load shedding for
transmission or distribution systems. This function block also provides a
time-delayed frequency element that uses pickup and dropout timers to delay
assertions and deassertions of the underfrequency time-delayed element output.

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block.

OperatingQuantity LREAL Input source frequency magnitude in Hz.

PickupValue LREAL Underfrequency pickup value in Hz.

Hysteresis LREAL Hysteresis value in Hz. Used to prevent element from chattering when operating at or
near the pickup value.

PickupDelay TIME The time that the delayed frequency element, PickupTimeout, waits before asserting.

DropoutDelay TIME The time that the delayed frequency element, PickupTimeout, waits to deassert after the
deassertion of the underfrequency condition.

FrequencyOk BOOL When true, the OperatingQuantity frequency signal is healthy.

FrequencyFrozen BOOL When true, the OperatingQuantity frequency signal is frozen.

Supervision BOOL Supervision for the frequency element. When False, the element is blocked from
operating.

Date Code 20241023 Programming Reference


848 PowerSystemProtection
Function Blocks

Name IEC 61131 Type Description

UnderVoltageBlock BOOL Undervoltage supervision block. When True, the element is blocked from operating.

HealthAlarm BOOL Health alarm detected for the hardware or system that is providing the operating quantity.
When True, the element is blocked from operating.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

UnderFrequencyPU BOOL The underfrequency protection element has operated.

ElementUnblocked BOOL Element is unblocked and outputs are valid.

PickupTimeout BOOL The underfrequency pickup delay based on the PickupDelay and DropoutDelay inputs.

Processing

Figure 27.5 Underfrequency Logic

The comparator referenced in Figure 27.5 is SELUtils


fb_UnderComparatorWithHysteresis.

fb_FrequencyElement (Function Block)


This function block implements a frequency element that uses the pickup value
and the system nominal frequency to select and execute the fb_OverFrequency
or the fb_UnderFrequency function block. When the pickup value input
is greater than the nominal frequency, this function block executes the
overfrequency function block, asserting the element pickup if the measured
frequency is greater than the pickup input. When the pickup value input
is less than the nominal frequency input, this function block executes the
underfrequency logic, asserting the element pickup if the measured frequency
is less than the pickup input. This function block also provides a time-delayed
frequency element that uses pickup and dropout timers to configure faster or
slower assertions or deassertions of the frequency element time-delayed output.

Programming Reference Date Code 20241023


PowerSystemProtection 849
Function Blocks

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block.

OperatingQuantity LREAL Input source frequency magnitude in Hz.

PickupValue LREAL Frequency element pickup value in Hz.

Hysteresis LREAL Hysteresis value in Hz. Used to prevent element from chattering when operating at or
near the pickup value.

NominalFrequency DINT The nominal frequency (Hz) of the power system (50 or 60). Recommend setting this
input equal to the RTAC system tag, SystemTags.Nominal_Frequency.stVal

PickupDelay TIME The time that the delayed frequency element output waits to assert after the assertion of
the over- or underfrequency condition.

DropoutDelay TIME The time in seconds that the frequency element waits to deassert after the deassertion of
the over- or underfrequency condition.

FrequencyOk BOOL Frequency signal is healthy.

FrequencyFrozen BOOL Frequency signal is frozen.

Supervision BOOL Supervision for the frequency element. When False, the element is blocked from
operating.

UnderVoltageBlock BOOL Undervoltage supervision block. When True, the element is blocked from operating.

HealthAlarm BOOL Health alarm detected for the hardware or system that is providing the operating quantity.
When True, the element is blocked from operating.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

Element Pickup BOOL The frequency protection element has operated.

ElementUnblocked BOOL Element is unblocked and outputs are valid.

PickupTimeout BOOL The frequency protection element delayed based on the PickupDelay and DropoutDelay
inputs.

Date Code 20241023 Programming Reference


850 PowerSystemProtection
Function Blocks

Processing
➤ ENO is set to True when the following conditions are met:
➢ EN is equal to True.
➢ NominalFrequency is equal to 50 or 60 Hz.
➢ PickupValue is not equal to the NominalFrequency.
➤ If ENO is True and PickupValue > Nominal Frequency, all inputs are
passed to fb_OverFrequency and the following values are mapped to the
fb_OverFrequency outputs.
➢ ElementUnblocked is mapped from the ElementUnblocked of the
OverFrequency function block.
➢ ElementPickup is mapped from OverFrequencyPU of the
OverFrequency function block.
➢ PickupTimeout is mapped from the PickupTimout of the
OverFrequency function block.

➤ If ENO is True and PickupValue < Nominal Frequency, all inputs are
passed to fb_UnderFrequency and the following values are mapped to the
fb_UnderFrequency outputs.
➢ ElementUnblocked is mapped from the ElementUnblocked of the
UnderFrequency function block.
➢ ElementPickup is mapped from UnderFrequencyPU of the
UnderFrequency function block.
➢ PickupTimeout is mapped from PickupTimeout of the
UnderFrequency function block.

fb_AlphaVoltageSupervision (Function Block)


This function block provides an undervoltage supervision status to supervise
frequency elements for system undervoltage conditions.

This function block requires the use of the Axion Wave Server 3 kHz voltage
channel and sample data to calculate the 3 kHz alpha tracking voltage quantity
(Valpha). The following equations are used to produce the Valpha voltage based
on the PT Connection input. The Va, Vb, and Vc channels in the following
equations are individual samples provided from the Axion Wave Server Sample
Stream. These samples produce the 3 kHz Valpha signal that is compared against
the voltage supervision threshold.

PTConnectionType Valpha Calculation

WYE

DELTA

The UnderVoltageDetected output asserts when Valpha is less than the voltage
supervision threshold for longer than a cycle of the MeasuredFrequency input.
If MeasuredFrequency is equal to zero or the FrequencyOk input is FALSE,
the NominalFrequency is used for the cycle time. See Calculate the Voltage
Supervision Threshold Setting Values on page 853 for guidelines on setting
the VoltageSupervisionThreshold.

Programming Reference Date Code 20241023


PowerSystemProtection 851
Function Blocks

Inputs
Name IEC 61131 Type Description

EN BOOL Enable this function block.

SampleStructure struct_SampleStream Sample structure produced by the Axion Wave Server. For more
information, see Axion Wave Server of the ACSELERATOR RTAC
SEL-5033 Software Instruction Manual.

ChannelInfo struct_ChannelInfo Channel Information produced by the Axion Wave Server. For more
information, see Axion Wave Server of the ACSELERATOR RTAC
SEL-5033 Software Instruction Manual.

VaIndex USINT The index location in the Axion Wave Server of the A-phase voltage
channel. Used to collect channel and sample values within the
SampleStructure and ChannelInfo.

VbIndex USINT The index location in the Axion Wave Server of the B-phase voltage
channel. Used to collect channel and sample values within the
SampleStructure and ChannelInfo.

VcIndex USINT The index location in the Axion Wave Server of the C-phase voltage
channel. Used to collect channel and sample values within the
SampleStructure and ChannelInfo.

VoltageSupervisionThreshold LREAL The voltage supervision threshold in secondary volts used to assert and
deassert the undervoltage supervision output.

MeasuredFrequency LREAL Frequency source used for the cycle time calculation

NominalFrequency DINT The nominal frequency (Hz) of the power system (50 or 60).
Recommend setting this input equal to the RTAC system tag,
SystemTags.Nominal_Frequency.stVal

FrequencyOk BOOL Frequency signal is healthy.

HealthAlarm BOOL Health alarm detected for the hardware or system that is providing the
operating quantity. When True, the element is blocked from operating.

PTConnectionType enum_PTConnectionType Connection type of the potential transformers used to determine the
calculation for the Valpha quantity.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

UnderVoltageDetected BOOL The Valpha calculation is less than the VoltageSupervisionThreshold for more than
a power system cycle.

UnderVoltageQualityBad BOOL The function block failed to produce a valid Valpha calculation. See
UnderVoltageErrorMessage for more details.

UnderVoltageErrorMessage STRING The error description for why the UnderVoltageQuality is bad.

Date Code 20241023 Programming Reference


852 PowerSystemProtection
Function Blocks

Processing
➤ If EN = True and the NominalFrequency input is equal to 50 or 60, set
ENO = True and check the following:
➢ HealthAlarm = False and both the SampleStructure and ChannelInfo
contains sample and channel information. If any of these checks fail,
UnderVoltageQualityBad = True and UnderVoltageErrorMessage
provides more detailed information.
➢ If PTConnectionType = WYE
➣ VaIndex, VbIndex, and VcIndex are non-default and within the
provided range of the Axion Wave Server ChannelInfo. If any
channel index is invalid, UnderVoltageQualityBad = True and
UnderVoltageErrorMessage provides more detailed information.
➣ Calculate the alpha voltage by using the voltage sample stream
from the Axion Wave Server with the following equation:

➢ If PTConnectionType = DELTA
➣ VAIndex and VBIndex return a non-default index value and are
within the channel info provided by the Axion Wave Server. If
any channel index is invalid, UnderVoltageQualityBad = True and
UnderVoltageErrorMessage provides more detailed information.
➣ Calculate alpha voltage by using the voltage sample stream from
the Axion Wave Server with the following equation:

➢ Calculate the Cycle Time displayed in Figure 27.6 by using the


following logic:
➣ If MeasuredFrequency > 0 AND FrequencyOk = True,

➣ Otherwise,

➢ Set UnderVoltageQualityBad = False and clear


UnderVoltageErrorMessage.
➢ Execute the logic shown in Figure 27.6.

Figure 27.6 Voltage Supervision Logic

➤ If EN = FALSE or the NominalFrequency is not equal to 50 or 60, ENO =


FALSE
➢ Set UnderVoltageQualityBad = TRUE and the
UnderVoltageErrorMessage indicates that function block is not
providing voltage supervision.

Programming Reference Date Code 20241023


PowerSystemProtection 853
Function Blocks

Calculate the Voltage Supervision Threshold Setting Values


Because this function block supports both wye- and delta-connected PT inputs,
Valpha can have different values depending on the nominal voltage input. The
following calculations assume an rms secondary phase-to-neutral value of 67 V
for PT inputs, although the VoltageSupervisionThreshold setting is a peak value.
Further, IEEE C37.117 recommends an undervoltage set point of 50 percent to
70 percent of nominal voltage to block frequency elements. In the following
examples, a voltage level of 60 percent is used. Update the 67 V and 60 percent
value to match your system nominal voltage and desired undervoltage set point.

Case 1: Wye-Connected PTs


A wye-connected PT provides VA, VB, and VC as phase-to-neutral voltages.
Use the following equation to calculate the peak nominal value of the Valpha
calculation.

Equation 27.16

The voltage supervision threshold input can be calculated using the desired
undervoltage set point.

Equation 27.17

Case 2: Delta Connected PTs


In this case, PRCTPT module inputs VA and VC terminals measure VAB and
VCB, respectively. Valpha is calculated according to the following equation.

Equation 27.18

Because Valpha is based on a line-to-line value calculation, the following


equation provides the conversion from line-to-neutral voltage to line-to-line
voltage.

Equation 27.19

Next, the rms magnitude Valpha can be derived from the following equation.

Equation 27.20

Next, the Valpha peak value can be derived.

Equation 27.21

Date Code 20241023 Programming Reference


854 PowerSystemProtection
Benchmarks

Last, the voltage supervision threshold input can be calculated using the desired
undervoltage set point.

Equation 27.22

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3530/SEL-2241
➢ R136 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R136 firmware

Benchmark Test Descriptions


Execution Time of Overcurrent Function Blocks
The posted time is the average execution time of 1000 consecutive calls to the
function blocks where the operating quantity alternates between a value that is
barely above the pickup threshold, to a value of 0.

This test is performed on the following function blocks:

➤ fb_DefiniteTime
➤ fb_InverseTimeCurveUser (The performance results for this function
block are also valid for any of the other inverse time curve blocks for the
specific curves.)

Execution Time of Voltage Element Function Blocks


The posted time is the average execution time of 1000 consecutive calls to the
function blocks.

This test is performed on the following function blocks:

➤ fb_BusLineVoltageCheck
➤ fb_OverVoltage
➤ fb_UnderVoltage

Execution Time of LossOfPotential Function Block


The posted time is the average execution time of 1000 consecutive calls to the
fb_LossOfPotential function block.

Programming Reference Date Code 20241023


PowerSystemProtection 855
Examples

Execution Time of Thermal Overload Function Blocks


The posted time is the average execution time of 1000 consecutive calls to the
function blocks.

This test is performed on the fb_ConductorThermalOverload function block.

Benchmark Results
Platform (time in µs)
Operation Tested SEL-3530
SEL-3555
SEL-2241

fb_DefiniteTime 3.1 0.5

fb_InverseTimeCurveUser 12.6 0.9

fb_LossOfPotential 10.8 0.4

fb_BusLineVoltageCheck 5.2 0.3

fb_OverVoltage 0.9 0.1

fb_UnderVoltage 1.1 0.1

fb_ConductorThermalOverload 15.0 0.8

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Date Code 20241023 Programming Reference


856 PowerSystemProtection
Examples

Create a Three-Phase Definite-Time Overcurrent Element


Objective
The user would like to create a program that implements a Three-Phase Definite-
Time Overcurrent element that asserts when any phase is detected overcurrent.
The diagram is shown below.

Assumptions
This example assumes the user has an AC protection module setup to get current
input measurements.

Solution
The user can create a program shown in Code Snippet 27.1:
Code Snippet 27.1 prg_50Element
PROGRAM prg_50Element
VAR
// 50 protection elements
AProtection : PowerSystemProtection.fb_DefiniteTime;
BProtection : PowerSystemProtection.fb_DefiniteTime;
CProtection : PowerSystemProtection.fb_DefiniteTime;

// User defined inputs to 50 element


SET50P : REAL := 100;
SET50PTD : TIME := T#1S;

// Program Outputs
O50PT : BOOL;
END_VAR

AProtection(OperatingQuantity := SEL_prCTPT_1_ECAT.IA_FUND.mag,
SetPickupSetting := SET50P,
SetDelayTime := SET50PTD);
BProtection(OperatingQuantity := SEL_prCTPT_1_ECAT.IB_FUND.mag,
SetPickupSetting := SET50P,
SetDelayTime := SET50PTD);
CProtection(OperatingQuantity := SEL_prCTPT_1_ECAT.IC_FUND.mag,
SetPickupSetting := SET50P,
SetDelayTime := SET50PTD);

Programming Reference Date Code 20241023


PowerSystemProtection 857
Examples

O50PT := AProtection.PickupTimeout OR
BProtection.PickupTimeout OR
CProtection.PickupTimeout;

Create a Three-Phase Inverse-Time Overcurrent Element


Objective
The user would like to create a program with behavior of 51 Three-Phase
Inverse-Time Overcurrent ORMODE outputs.

Assumptions
This example assumes the user has an SEL-2245-42 AC Protection Module
configured in the RTAC project to obtain fundamental measurements.

NOTE
The module is assumed to have the name: "SEL_prCTPT_1_ECAT".

Solution
The user can create a program shown in Code Snippet 27.2:
Code Snippet 27.2 prg_51Element
PROGRAM prg_51Element
VAR
// Inverse Time Curve Function Blocks
Aphase : PowerSystemProtection.fb_InverseTimeCurveC2;
Bphase : PowerSystemProtection.fb_InverseTimeCurveC2;
Cphase : PowerSystemProtection.fb_InverseTimeCurveC2;
Nphase : PowerSystemProtection.fb_InverseTimeCurveC2;
// Phase Overcurrent Settings
Set51PPU : REAL := 0;
Set51PTD : REAL := 1.0;
// Neutral Overcurrent Settings
Set51NPU : REAL := 0;
Set51NTD : TIME := T#1S;
// OR Mode Outputs
O51PT : BOOL;
O51PR : BOOL;
O51P : BOOL;
END_VAR

Aphase( OperatingQuantity :=SEL_prCTPT_1_ECAT.IA_FUND.mag,


SetPickupSetting := Set51PPU,
SetTimeDial := Set51PTD );

Bphase( OperatingQuantity :=SEL_prCTPT_1_ECAT.IB_FUND.mag,


SetPickupSetting := Set51PPU,
SetTimeDial := Set51PTD );

Cphase( OperatingQuantity :=SEL_prCTPT_1_ECAT.IC_FUND.mag,


SetPickupSetting := Set51PPU,
SetTimeDial := Set51PTD );

O51P := Aphase.ElementPickup AND


Bphase.ElementPickup AND
Cphase.ElementPickup;

O51PT := Aphase.PickupTimeOut AND


Bphase.PickupTimeOut AND

Date Code 20241023 Programming Reference


858 PowerSystemProtection
Examples

Cphase.PickupTimeOut;

O51PR := Aphase.ElementReset AND


Bphase.ElementReset AND
Cphase.ElementReset;

Detect a Loss-of-Potential Condition


Objective
The user would like to detect an overvoltage condition of Phase A voltage
and, when one or more of the PT fuses or breakers is blown, prevent Phase A
overvoltage detection from enabling LED 1 on an RTAC/Axion.

Assumptions
This example assumes the user has an SEL-2245-42 AC Protection Module
configured in the RTAC project to obtain fundamental measurements.

NOTE
The module is assumed to have the name: "SEL_prCTPT_1_ECAT".

For voltage Phase A overvoltage detection, the current and voltage phasors are
assumed to be:
Current Phase A: 4 A Ð 0
Current Phase B: 4 A Ð –120
Current Phase C: 4 A Ð 120
Voltage Phase A: 70 V Ð 0
Voltage Phase B: 67 V Ð –120
Voltage Phase C: 67 V Ð 120

A loss-of-potential condition can be triggered by using the following values and


the LED 1 will turn off:
Current Phase A: 4 A Ð 0
Current Phase B: 4 A Ð –120
Current Phase C: 4 A Ð 120
Voltage Phase A: 70 V Ð 0
Voltage Phase B: 0 V Ð –120
Voltage Phase C: 67 V Ð 120

Solution
The user can create a program shown in Code Snippet 27.3:
Code Snippet 27.3 prg_LopDetection
PROGRAM prg_LopDetection
VAR
LossOfPotential : PowerSystemProtection.fb_LossOfPotential;
PhaseAOverVoltage : PowerSystemProtection.fb_OverVoltage;

Initialized : BOOL;
END_VAR

IF NOT Initialized THEN


// Assign all Set inputs and run once to initialize.
LossOfPotential.SetAmpsNominal := 5;
LossOfPotential.SetNominalFrequency := SystemTags.Nominal_Frequency.stVal;

Programming Reference Date Code 20241023


PowerSystemProtection 859
Examples

LossOfPotential.SetVoltsNominal := 66.4;
LossOfPotential.EN := TRUE;
LossOfPotential();

PhaseAOverVoltage.ThresholdVoltage := 69;
END_IF

LossOfPotential.FundQok := SEL_prCTPT_1_ECAT.QUALITY_FUND;
LossOfPotential.FundTimeStamp := SEL_prCTPT_1_ECAT.TIMESTAMP_FUND;

LossOfPotential.AmpsNegSeq := SEL_prCTPT_1_ECAT.I2_FUND;
LossOfPotential.AmpsPosSeq := SEL_prCTPT_1_ECAT.I1_FUND;
LossOfPotential.AmpsZeroSeq := SEL_prCTPT_1_ECAT.I0_FUND;

LossOfPotential.AmpsPhaseA := SEL_prCTPT_1_ECAT.IA_FUND;
LossOfPotential.AmpsPhaseB := SEL_prCTPT_1_ECAT.IB_FUND;
LossOfPotential.AmpsPhaseC := SEL_prCTPT_1_ECAT.IC_FUND;

LossOfPotential.VoltsPosSeq := SEL_prCTPT_1_ECAT.V1_FUND;
LossOfPotential.VoltsZeroSeq := SEL_prCTPT_1_ECAT.V0_FUND;

LossOfPotential();

// When loss of potential is detected, the overvoltage element will be disabled.


PhaseAOverVoltage.EN := NOT LossOfPotential.LossOfPotential;
PhaseAOverVoltage.MeasuredVoltage := SEL_prCTPT_1_ECAT.VA_FUND.mag;
PhaseAOverVoltage();

IF PhaseAOverVoltage.OverVoltage THEN
SystemTags.Aux_LED_01.operSet.ctlVal := TRUE;
SystemTags.Aux_LED_01.operClear.ctlVal := FALSE;
ELSE
SystemTags.Aux_LED_01.operSet.ctlVal := FALSE;
SystemTags.Aux_LED_01.operClear.ctlVal := TRUE;
END_IF

Detect a Thermal Overload for a Single Phase


Objective
The user would like to detect when Phase A has exceeded a maximum conductor
temperature and turn on LED 1.

Assumptions
This example assumes the user has an SEL-2245-42 AC Protection Module
configured in the RTAC project to obtain rms measurements.
The AmbientTemperature pin values can be forced by the user to observe
functionality. Values greater than 20.3°C will cause a thermal overload condition
when the MeasuredCurrent is set to 100 A.

NOTE
The module is assumed to have the name: "SEL_prCTPT_1_ECAT".

Solution
The user can create a program shown in Code Snippet 27.4:
Code Snippet 27.4 prg_ThermalElementExample
PROGRAM prg_ThermalElementExample

Date Code 20241023 Programming Reference


860 PowerSystemProtection
Examples

VAR
ThermalOverload :
PowerSystemProtection.fb_ConductorThermalOverload :=
(SetInitialTemp := 20,
// This is an unrealistic time constant for a real system, but will demonstrate
// the behavior of the function block on the order of seconds for this example.
SetTimeConstant := T#1S,
SetRatedCurrent := 105,
SetReferenceAmbientTemp := 20,
SetMaxConductorTemp := 24);
// This value can be force changed to view behavior of function block.
AmbientTemp : REAL := 21;
END_VAR

ThermalOverload.AmbientTemperature := AmbientTemp;
ThermalOverload.MeasuredCurrent := SEL_prCTPT_1_ECAT.IA_RMS;
ThermalOverload();

IF ThermalOverload.Overloaded THEN
SystemTags.Aux_LED_01.operSet.ctlVal := TRUE;
SystemTags.Aux_LED_01.operClear.ctlVal := FALSE;
ELSE
SystemTags.Aux_LED_01.operSet.ctlVal := FALSE;
SystemTags.Aux_LED_01.operClear.ctlVal := TRUE;
END_IF

Build Alpha Voltage Supervision Blocking Element


Objective
A user wants to provide a blocking element when the Valpha voltage quantity is
set to 60 percent of the nominal input voltage.

Assumptions
This example assumes the following:

➤ An SEL-2245-42 AC Protection Module (PRCTPT) named


SEL_PRCTPT_1 is configured in the RTAC project and attached to the
EtherCAT I/O network.
➢ The PRCTPT FREQ and QUALITY_FREQ tags are enabled.
➤ The RTAC project includes an Axion Wave Server, and the PRCTPT
module has voltage channels enabled.
➤ Nominal secondary voltage is 67 V.
➤ The PRCTPT modules configured with wye PT connections.
➤ The HealthAlarm input asserts when the EtherCAT I/O Client State is not
equal to 5.

Solution
Code Snippet 27.5 prg_ValphaUnderVoltageSupervision
PROGRAM prg_ValphaUnderVoltageSupervision
VAR
VoltageBlockingSupervision : fb_AlphaVoltageSupervision;
Samples : struct_SampleStream;
ChannelInfo : struct_channelInfo;
VaChannelIndex, VbChannelIndex, VcChannelIndex : USINT;
FirstScanDone : BOOL := FALSE;
UnderVoltagePresent : BOOL;

Programming Reference Date Code 20241023


PowerSystemProtection 861
Examples

ReasonForBadQuality : STRING;
END_VAR

// On the first scan collect all PRCTPT channel voltage


// index within Axion Wave Server
IF NOT FirstScanDone THEN
SEL_Axion_WAVE_POU.Samples.GetChannelIndex(DeviceName := 'SEL_PRCTPT_1',
ChannelName := 'VA', ChannelIndex => VaChannelIndex);
SEL_Axion_WAVE_POU.Samples.GetChannelIndex(DeviceName := 'SEL_PRCTPT_1',
ChannelName := 'VB', ChannelIndex => VbChannelIndex);
SEL_Axion_WAVE_POU.Samples.GetChannelIndex(DeviceName := 'SEL_PRCTPT_1',
ChannelName := 'VC', ChannelIndex => VcChannelIndex);
FirstScanDone := TRUE;
END_IF

// Collect channel info and Sample data from the Axion Wave Server
SEL_Axion_WAVE_POU.Samples.GetChannelInfo ( ChannelInfo => ChannelInfo ) ;
SEL_Axion_WAVE_POU.Samples.GetSamples (Samples => Samples);

// Call the Voltage Blocking Supervision each processing interval


VoltageBlockingSupervision(EN := TRUE,
SampleStructure := Samples,
ChannelInfo := ChannelInfo,
VaIndex := VaChannelIndex,
VbIndex := VbChannelIndex,
VcIndex := VcChannelIndex,
VoltageSupervisionThreshold := 92.4,
MeasuredFrequency := SEL_PRCTPT_1_ECAT.FREQ,
NominalFrequency := SystemTags.Nominal_Frequency.stVal,
FrequencyOk := SEL_PRCTPT_1_ECAT.QUALITY_FREQ,
HealthAlarm := ECAT_POU.Client_State <> 5,
PTConnectionType := enum_PTConnectionType.Wye);

// Only update the Undervoltage variable if quality is good


// Otherwise update the error string
IF NOT VoltageBlockingSupervision.UnderVoltageQualityBad THEN
UnderVoltagePresent := VoltageBlockingSupervision.UnderVoltageDetected;
ELSE
ReasonForBadQuality := VoltageBlockingSupervision.UnderVoltageErrorMessage;
END_IF

Underfrequency Protection Using the Frequency Element


Objective
A user wants to close an Axion digital output when an underfrequency event is
detected. Two frequency elements are desired to provide two levels of protection
for two time-delayed digital output assertions.

Assumptions
This example assumes the following:.

➤ An SEL-2245-42 AC Protection Module (PRCTPT) named


SEL_PRCTPT_1 is configured in the RTAC project and attached to the
EtherCAT I/O network.
➢ The PRCTPT FREQ and QUALITY_FREQ tags are enabled
and mapped to the frequency element OperatingQuantity and
FrequencyOk inputs, respectively.
➤ An SEL 10-Digital Output module named SEL_10DO_1 is included in
the RTAC project and attached to the EtherCAT I/O network.

Date Code 20241023 Programming Reference


862 PowerSystemProtection
Examples

➤ Nominal frequency is 60 Hz.


➤ The first frequency element is desired to assert digital output OUT001
after 5 seconds of the frequency dropping less than 59.4 Hz.
➤ The second frequency element is desired to assert digital output OUT001
after 10 power system (60 Hz) cycles of the frequency dropping less than
59.1 Hz.
➤ No hysteresis is required because of the 1-second dropout delay on
frequency elements.
➤ No frequency frozen element is provided to the frequency elements
function blocks.
➤ The HealthAlarm input is asserted (blocking the frequency element from
operating) when the EtherCAT I/O Client State is not equal to 5.
➤ The user has previously implemented the fb_AlphaVoltageSupervision
function for undervoltage supervision. This is included as a GVL tag
named VoltageSupervision. The UnderVoltageDetected output is provided
to the UnderVoltageBlock inputs of both frequency elements.
➤ No additional supervision logic is required by the user.

Solution
Code Snippet 27.6 prg_UnderFrequencyProtectionScheme
PROGRAM prg_UnderFrequencyProtectionScheme
VAR
SlowUnderFreqElement: fb_FrequencyElement;
FastUnderFreqElement : fb_FrequencyElement;
END_VAR

// Configure the longer delayed under frequency element


SlowUnderFreqElement(EN := TRUE,
OperatingQuantity := SEL_PRCTPT_1_ECAT.FREQ,
PickupValue := 59.4,
NominalFrequency := 60,
PickupDelay := T#5s,
DropoutDelay := T#1s,
FrequencyOk := SEL_PRCTPT_1_ECAT.QUALITY_FREQ,
Supervision := TRUE,
UnderVoltageBlock := VoltageSupervision.UnderVoltageDetected,
HealthAlarm := ECAT_POU.Client_State <> 5);

// Configure the short time delayed under frequency element


FastUnderFreqElement(EN := TRUE,
OperatingQuantity := SEL_PRCTPT_1_ECAT.FREQ,
PickupValue := 59.1,
NominalFrequency := 60,
PickupDelay := T#0.166S,
DropoutDelay := T#1s,
FrequencyOk := SEL_PRCTPT_1_ECAT.QUALITY_FREQ,
Supervision := TRUE,
UnderVoltageBlock := VoltageSupervision.UnderVoltageDetected,
HealthAlarm := ECAT_POU.Client_State <> 5);

// Assign frequency element outputs to the Axion digtial outputs


IF FastUnderFreqElement.PickupTimeOut OR SlowUnderFreqElement.PickupTimeOut THEN
SEL_10DO_1_ECAT.OUTPUT_001.operSet.ctlVal := TRUE;
SEL_10DO_1_ECAT.OUTPUT_001.operClear.ctlVal := FALSE;
ELSE
SEL_10DO_1_ECAT.OUTPUT_001.operSet.ctlVal := FALSE;
SEL_10DO_1_ECAT.OUTPUT_001.operClear.ctlVal := TRUE;
END_IF

Programming Reference Date Code 20241023


S E C T I O N 2 8

Queue
Introduction
The purpose of this library is to implement the data structure queue, and a
double-ended queue (a deque).

Queues
A queue is a fundamental data structure in computer science and is implemented
within this library as an object.

The term "queue" is often used interchangeably with the term FIFO (first-in,
first-out), which is a more descriptive name. The queue is often used as a buffer,
allowing information to be queued up to be processed in the same order that it
was received in, but at a different rate. This library defines the front of a queue
as the oldest element pushed into the queue and the back of the queue is the
newest element pushed into the queue.

This is easily visualized and remembered by using the common image of


customers standing in a line, also known as a queue. The customer that has been
in line the longest is at the front of the queue, and people awaiting service are
added to the back of the queue.

All queues in this library assume that all elements within the queue are the same
size.

Double-Ended Queues (Deques)


This library provides a double-ended queue implementation (a deque). A deque
can do anything that a standard queue can do but can have items added or
removed from either the front or the back.

With a deque, the library assembly can move priority information to the front
of a queue or balance several parallel queues by removing items from the back
of one queue and reassigning them to the back of other queues. These are
operations that cannot be performed on a pure queue.

The deque implementation used in this library also ensures that all the data
within the queue are kept in contiguous memory, which is not guaranteed in all
queue implementations.

Special Considerations
Classes in this library have memory allocated inside them. As such, they should
only be created in environments of permanent scope (e.g., Programs, Global
Variable Lists, or VAR_STAT sections).

Date Code 20241023 Programming Reference


864 Queue
Supported Firmware Versions

Copying classes from this library causes unwanted behavior. This means the
following:

1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_QueueObject"
myQueueObject := otherQueueObject;

// This is fine
someVariable := myQueueObject.value;
// As is this
pt_myQueueObject := ADR(myQueueObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.0.0 and earlier can be used on RTAC firmware version R132 and
later.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_p_DefaultQueueSize UDINT 32 The default number of elements that a queue can hold.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_DequeType
This enumeration is used for specifying the desired type of deque to the
fun_NewTypeDeque() function.

Enumeration Description

BYTE_DEQUE Enumeration for class_ByteDeque.

WORD_DEQUE Enumeration for class_WordDeque.

DWORD_DEQUE Enumeration for class_DwordDeque.

Programming Reference Date Code 20241023


Queue 865
Functions

Enumeration Description

LWORD_DEQUE Enumeration for class_LwordDeque.

REAL_DEQUE Enumeration for class_RealDeque.

LREAL_DEQUE Enumeration for class_LrealDeque.

POINTER_DEQUE Enumeration for class_PointerDeque.

Functions
fun_NewDeque (Function)
This function creates a new class_BaseDeque and returns a pointer to the newly
created deque. The returned POINTER TO BYTE must be cast to the correct
type before it is used. A deque created with this function must be destroyed with
fun_DeleteDeque() when it is no longer needed.

Inputs
Name IEC 61131 Type Description

elementSize UDINT The size of each element in the deque.

Return Value
IEC 61131 Type Description

POINTER TO BYTE Pointer to the newly created deque. This pointer is null if the deque
could not be created.

Processing
➤ Creates a new deque with the specified elementSize and returns a pointer
to the newly created deque.
➤ Returns a null pointer if the deque could not be created.

fun_NewTypeDeque (Function)
This function creates a new deque of the type specified and returns a pointer
to the newly created deque. The returned POINTER TO BYTE must be cast to
the correct type before it is used. A deque created with this function must be
destroyed with fun_DeleteDeque() when it is no longer needed.

Inputs
Name IEC 61131 Type Description

dequeType enum_DynamicDequeType The desired type of deque.

Date Code 20241023 Programming Reference


866 Queue
Interfaces

Return Value
IEC 61131 Type Description

POINTER TO BYTE Pointer to the newly created deque. This pointer is null if the deque
could not be created.

Processing
➤ Creates a new deque of the type specified and returns a pointer to the
newly created deque.
➤ Returns a null pointer if the deque could not be created.

fun_DeleteDeque (Function)
This function deletes a deque created with fun_NewDeque() or
fun_NewTypeDeque(). After deletion, any pointers to the deleted deque are no
longer valid.

Inputs
Name IEC 61131 Type Description

deque I_Deque The deque to delete.

Return Value
IEC 61131 Type Description

BOOL TRUE if deque is successfully deleted. FALSE if an error occurs.

Interfaces
This library provides the following interface.

I_Queue (Interface)
This interface is implemented by any class that provides a queue data type.

Programming Reference Date Code 20241023


Queue 867
Interfaces

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

ElementSize UDINT R The number of bytes required for each


element in the queue.

MaxSize UDINT R The number of elements this queue can


hold before a reallocation for additional
memory is required.

Size UDINT R The number of elements in the queue.

Clear (Method)
Deallocates all memory associated with the queue. Call this method only if
the queue is instantiated with limited scope (i.e., if it is instantiated as a local
variable of a function or method).

Return Value

IEC 61131 Type Description

BOOL TRUE if the queue successfully deallocates its internal memory.


FALSE if an error occurs.

EraseFront (Method)
This method deletes the specified number of elements from the front of the
queue.

Inputs

Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the front of


the queue.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully removed from the queue.

Processing
➤ Removes as many as numToErase elements from the front of the queue.
➤ If the Size of the queue is less than numToErase, only Size elements are
removed from the queue.

Date Code 20241023 Programming Reference


868 Queue
Interfaces

Front (Method)
This method copies the specified number of elements from the front of the queue
to the provided pointer location. The queue is not modified.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the front


of the queue.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully copied.

Processing
➤ Copies as many as numToCopy elements from the front of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

PopFront (Method)
This method copies the specified number of elements from the front of the queue
to the provided pointer location and deletes them from the queue.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the front of


the queue.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
queue. Zero if the queue was not modified.

Programming Reference Date Code 20241023


Queue 869
Interfaces

Processing
➤ Copies as many as numToPop elements from the front of the queue to
pt_destination.
➤ If the Size of the queue is less than numToPop, only Size elements are
copied to pt_destination.
➤ Removes the copied elements from the queue.
➤ If pt_destination is invalid or the elements cannot be copied, the queue is
not modified and zero is returned.

PushBack (Method)
This method copies elements from the specified pointer location and pushes
them onto the back of the queue.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the back of


the queue.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the queue. Zero if
an error occurred and the queue was not modified.

Processing
➤ If the queue is not large enough to contain the new elements, additional
memory is allocated to enlarge the queue.
➤ Copies the elements from pt_source and pushes them onto the back of the
queue.
➤ If pt_source is invalid or numToPush is zero, the queue is not modified
and zero is returned.

Recycle (Method)
This method removes all elements from the queue without modifying the
memory allocated to the queue.

Return Value
IEC 61131 Type Description

BOOL TRUE if the queue successfully removes all elements. FALSE if an


error occurs.

Date Code 20241023 Programming Reference


870 Queue
Classes

Processing
All elements are removed from the queue.

➤ After recycling, the Size of the queue is zero.


➤ The MaxSize is unchanged after a call to Recycle().
➤ This method neither allocates nor frees any memory.

Classes
class_Deque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque can handle objects of arbitrary size, so long as
the number of bytes required for each element is the same.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Queue

Initialization Inputs
Name IEC 61131 Type Description

elementSize UDINT The number of bytes required for each element that
this deque can hold. If zero, defaults to one.

numElements UDINT The number of elements to allocate initially. If zero,


g_p_DefaultQueueSize is used.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Programming Reference Date Code 20241023


Queue 871
Classes

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the back


of the queue.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Date Code 20241023 Programming Reference


872 Queue
Classes

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.
➤ Removes the copied elements from the deque.
➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs

Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Programming Reference Date Code 20241023


Queue 873
Classes

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs
Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value
IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize 2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

Date Code 20241023 Programming Reference


874 Queue
Classes

class_ByteDeque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque operates only on elements of type BYTE.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_Queue

Initialization Inputs
Name IEC 61131 Type Description

numElements UDINT The number of elements to allocate initially. If zero,


use g_p_DefaultQueueSize.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the back


of the queue.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Programming Reference Date Code 20241023


Queue 875
Classes

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

BackByte (Method)
This method provides the element at the back of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element BYTE A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

Date Code 20241023 Programming Reference


876 Queue
Classes

FrontByte (Method)
This method provides the element at the front of the deque without modifying
the deque.

Outputs

Name IEC 61131 Type Description

element BYTE A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.
➤ Removes the copied elements from the deque.
➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

Programming Reference Date Code 20241023


Queue 877
Classes

PopBackByte (Method)
This method provides a copy of the element at the back of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element BYTE A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PopFrontByte (Method)
This method provides a copy of the element at the front of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element BYTE A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PushBackByte (Method)
This method appends a copy of the provided element to the back of the deque.

Inputs
Name IEC 61131 Type Description

element BYTE The element to append to the back of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Date Code 20241023 Programming Reference


878 Queue
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

PushFrontByte (Method)
This method appends a copy of the provided element to the front of the deque.

Inputs
Name IEC 61131 Type Description

element BYTE The element to append to the front of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Programming Reference Date Code 20241023


Queue 879
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs

Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value

IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize 2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

Date Code 20241023 Programming Reference


880 Queue
Classes

class_DwordDeque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque operates only on elements of type DWORD.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_Queue

Initialization Inputs
Name IEC 61131 Type Description

numElements UDINT The number of elements to allocate initially. If zero,


g_p_DefaultQueueSize is used.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the


back of the queue.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Programming Reference Date Code 20241023


Queue 881
Classes

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

BackDword (Method)
This method provides the element at the back of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element DWORD A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

Date Code 20241023 Programming Reference


882 Queue
Classes

FrontDword (Method)
This method provides the element at the front of the deque without modifying
the deque.

Outputs

Name IEC 61131 Type Description

element DWORD A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.
➤ Removes the copied elements from the deque.
➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

Programming Reference Date Code 20241023


Queue 883
Classes

PopBackDword (Method)
This method provides a copy of the element at the back of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element DWORD A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PopFrontDword (Method)
This method provides a copy of the element at the front of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element DWORD A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PushBackDword (Method)
This method appends a copy of the provided element to the back of the deque.

Inputs
Name IEC 61131 Type Description

element DWORD The element to append to the back of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Date Code 20241023 Programming Reference


884 Queue
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

PushFrontDword (Method)
This method appends a copy of the provided element to the front of the deque.

Inputs
Name IEC 61131 Type Description

element DWORD The element to append to the front of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Programming Reference Date Code 20241023


Queue 885
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs

Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value

IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize 2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

Date Code 20241023 Programming Reference


886 Queue
Classes

class_LwordDeque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque operates only on elements of type DWORD.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_Queue

Initialization Inputs
Name IEC 61131 Type Description

numElements UDINT The number of elements to allocate initially. If zero,


use g_p_DefaultQueueSize.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the back


of the queue.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Programming Reference Date Code 20241023


Queue 887
Classes

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

BackLword (Method)
This method provides the element at the back of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element LWORD A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

Date Code 20241023 Programming Reference


888 Queue
Classes

FrontLword (Method)
This method provides the element at the front of the deque without modifying
the deque.

Outputs

Name IEC 61131 Type Description

element LWORD A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.
➤ Removes the copied elements from the deque.
➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

Programming Reference Date Code 20241023


Queue 889
Classes

PopBackLword (Method)
This method provides a copy of the element at the back of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element LWORD A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PopFrontLword (Method)
This method provides a copy of the element at the front of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element LWORD A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PushBackLword (Method)
This method appends a copy of the provided element to the back of the deque.

Inputs
Name IEC 61131 Type Description

element LWORD The element to append to the back of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Date Code 20241023 Programming Reference


890 Queue
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

PushFrontLword (Method)
This method appends a copy of the provided element to the front of the deque.

Inputs
Name IEC 61131 Type Description

element LWORD The element to append to the front of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Programming Reference Date Code 20241023


Queue 891
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs

Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value

IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize 2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

Date Code 20241023 Programming Reference


892 Queue
Classes

class_LrealDeque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque operates only on elements of type LREAL.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_Queue

Initialization Inputs
Name IEC 61131 Type Description

numElements UDINT The number of elements to allocate initially. If zero,


use g_p_DefaultQueueSize.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the back


of the queue.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Programming Reference Date Code 20241023


Queue 893
Classes

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

BackLreal (Method)
This method provides the element at the back of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element LREAL A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

Date Code 20241023 Programming Reference


894 Queue
Classes

FrontLreal (Method)
This method provides the element at the front of the deque without modifying
the deque.

Outputs

Name IEC 61131 Type Description

element LREAL A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value

IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value

IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.
➤ Removes the copied elements from the deque.
➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

Programming Reference Date Code 20241023


Queue 895
Classes

PopBackLreal (Method)
This method provides a copy of the element at the back of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element LREAL A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PopFrontLreal (Method)
This method provides a copy of the element at the front of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element LREAL A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PushBackLreal (Method)
This method appends a copy of the provided element to the back of the deque.

Inputs
Name IEC 61131 Type Description

element LREAL The element to append to the back of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Date Code 20241023 Programming Reference


896 Queue
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

PushFrontLreal (Method)
This method appends a copy of the provided element to the front of the deque.

Inputs
Name IEC 61131 Type Description

element LREAL The element to append to the front of the deque.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Programming Reference Date Code 20241023


Queue 897
Classes

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs

Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value

IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize 2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

Date Code 20241023 Programming Reference


898 Queue
Classes

class_PointerDeque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque operates only on elements of type POINTER
TO ANY.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Queue

Initialization Inputs

Name IEC 61131 Type Description

numElements UDINT The number of elements to allocate initially. If zero,


use g_p_DefaultQueueSize.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the back


of the queue.

Programming Reference Date Code 20241023


Queue 899
Classes

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

BackPointer (Method)
This method provides the element at the back of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element POINTER TO BYTE A copy of the element at the back of the deque.
If the return value is FALSE, this value is
undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Date Code 20241023 Programming Reference


900 Queue
Classes

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

FrontPointer (Method)
This method provides the element at the front of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element POINTER TO BYTE A copy of the element at the front of the deque.
If the return value is FALSE, this value is
undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.

Programming Reference Date Code 20241023


Queue 901
Classes

➤ Removes the copied elements from the deque.


➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

PopBackPointer (Method)
This method provides a copy of the element at the back of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element POINTER TO BYTE A copy of the element at the back of the deque.
If the return value is FALSE, this value is
undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PopFrontPointer (Method)
This method provides a copy of the element at the front of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element POINTER TO BYTE A copy of the element at the front of the deque.
If the return value is FALSE, this value is
undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PushBackPointer (Method)
This method appends a copy of the provided element to the back of the deque.

Inputs
Name IEC 61131 Type Description

element POINTER TO BYTE The element to append to the back of the deque.

Date Code 20241023 Programming Reference


902 Queue
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

PushFrontPointer (Method)
This method appends a copy of the provided element to the front of the deque.

Inputs
Name IEC 61131 Type Description

element POINTER TO BYTE The element to append to the front of the deque.

Programming Reference Date Code 20241023


Queue 903
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs
Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value
IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize 2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

Date Code 20241023 Programming Reference


904 Queue
Classes

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

class_RealDeque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque operates only on elements of type REAL.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Queue

Initialization Inputs
Name IEC 61131 Type Description

numElements UDINT The number of elements to allocate initially. If zero,


use g_p_DefaultQueueSize.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the back


of the queue.

Programming Reference Date Code 20241023


Queue 905
Classes

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

BackReal (Method)
This method provides the element at the back of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element REAL A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Date Code 20241023 Programming Reference


906 Queue
Classes

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

FrontReal (Method)
This method provides the element at the front of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element REAL A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.

Programming Reference Date Code 20241023


Queue 907
Classes

➤ Removes the copied elements from the deque.


➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

PopBackReal (Method)
This method provides a copy of the element at the back of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element REAL A copy of the element at the back of the deque.


If the return value is FALSE, this value is
undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PopFrontReal (Method)
This method provides a copy of the element at the front of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element REAL A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PushBackReal (Method)
This method appends a copy of the provided element to the back of the deque.

Inputs
Name IEC 61131 Type Description

element REAL The element to append to the back of the deque.

Date Code 20241023 Programming Reference


908 Queue
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

PushFrontReal (Method)
This method appends a copy of the provided element to the front of the deque.

Inputs
Name IEC 61131 Type Description

element REAL The element to append to the front of the deque.

Programming Reference Date Code 20241023


Queue 909
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs
Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value
IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize 2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

Date Code 20241023 Programming Reference


910 Queue
Classes

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

class_WordDeque
This class implements a double-ended queue that internally handles dynamic
allocation of memory. This deque operates only on elements of type WORD.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_Queue

Initialization Inputs
Name IEC 61131 Type Description

numElements UDINT The number of elements to allocate initially. If zero,


use g_p_DefaultQueueSize.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Data POINTER TO BYTE R A pointer to the first element in the deque. This implementation of deque
ensures that all elements are in contiguous memory. The pointer value
returned by this method is only valid until the next operation is performed on
the deque, since any modification to the contents of this object can cause the
storage location to move.

pt_Self POINTER TO BYTE R The THIS pointer for the class.

Back (Method)
This method copies the specified number of elements from the back of the queue
to the provided pointer location. The queue is not modified.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToCopy UDINT The number of elements to copy from the back


of the queue.

Programming Reference Date Code 20241023


Queue 911
Classes

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied.

Processing
➤ Copies as many as numToCopy elements from the back of the queue to
pt_destination.
➤ If the Size of the queue is less than numToCopy, only Size elements are
copied to pt_destination.
➤ If pt_destination is invalid or the elements cannot be copied, zero is
returned.

BackWord (Method)
This method provides the element at the back of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element WORD A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

EraseBack (Method)
This method deletes the specified number of elements from the back of the
deque.

Inputs
Name IEC 61131 Type Description

numToErase UDINT The number of elements to erase from the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully removed from the back of the
deque.

Date Code 20241023 Programming Reference


912 Queue
Classes

Processing
➤ Removes as many as numToErase elements from the back of the deque.
➤ If the Size of the deque is less than numToErase, then only Size elements
are removed from the deque.

FrontWord (Method)
This method provides the element at the front of the deque without modifying
the deque.

Outputs
Name IEC 61131 Type Description

element WORD A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied. FALSE if the size is zero
or an error occurs.

PopBack (Method)
This method copies the specified number of elements from the back of the deque
to the provided pointer location and deletes them from the deque.

Inputs
Name IEC 61131 Type Description

pt_destination POINTER TO BYTE A pointer to the destination to which the


elements are copied.

numToPop UDINT The number of elements to pop off the back of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully copied and removed from the
deque. Zero if the deque was not modified.

Processing
➤ Copies as many as numToPop elements from the back of the deque to
pt_destination.
➤ If the Size of the deque is less than numToPop, only Size elements are
copied to pt_destination.

Programming Reference Date Code 20241023


Queue 913
Classes

➤ Removes the copied elements from the deque.


➤ If pt_destination is invalid or the elements cannot be copied, the deque is
not modified and zero is returned.

PopBackWord (Method)
This method provides a copy of the element at the back of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element WORD A copy of the element at the back of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PopFrontWord (Method)
This method provides a copy of the element at the front of the deque and
removes that element from the deque.

Outputs
Name IEC 61131 Type Description

element WORD A copy of the element at the front of the deque. If the
return value is FALSE, this value is undefined.

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully copied and removed from the
deque. FALSE if the size is zero or an error occurs.

PushBackWord (Method)
This method appends a copy of the provided element to the back of the deque.

Inputs
Name IEC 61131 Type Description

element WORD The element to append to the back of the deque.

Date Code 20241023 Programming Reference


914 Queue
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

PushFront (Method)
This method copies elements from the specified pointer location and pushes
them onto the front of the deque.

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.

numToPush UDINT The number of elements to push onto the front of


the deque.

Return Value
IEC 61131 Type Description

UDINT The number of elements successfully pushed onto the deque. Zero if
an error occurred and the deque was not modified.

Processing
➤ If the deque is not large enough to contain the new elements, additional
memory is allocated to enlarge the deque.
➤ Copies the elements from the specified pointer and pushes them onto the
front of the deque.
➤ If pt_source is invalid or numToPush is zero, the deque is not modified
and zero is returned.

PushFrontWord (Method)
This method appends a copy of the provided element to the front of the deque.

Inputs
Name IEC 61131 Type Description

element WORD The element to append to the front of the deque.

Programming Reference Date Code 20241023


Queue 915
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the element is successfully added to the deque. FALSE if an


error occurs.

Processing
If pushing element to the deque requires more memory than is currently
available in the deque, the library allocates additional memory.

Resize (Method)
This method resizes the deque so that it can hold the specified number of
elements. If reducing the size of the deque to less than Size, elements are deleted
from the back of the deque.

Inputs
Name IEC 61131 Type Description

newMaxSize UDINT The new maximum number of elements the deque


can hold before a memory allocation is required.

Return Value
IEC 61131 Type Description

BOOL TRUE if the deque was resized. FALSE if an error occurred and the
deque was not modified.

Processing
➤ If newMaxSize is zero, all elements in the deque are deleted. This is the
same functionality as the Clear() method.
➤ If newMaxSize is equal to MaxSize, the deque is not modified.
➤ If newMaxSize is smaller than Size, elements are removed from the back
of the deque in order to resize the deque.
➤ If newMaxSize is greater than or equal to Size, the deque is resized and
retains all existing elements.

Resize2 (Method)
This method provides identical functionality to the Resize method but
additionally updates the Size property to reflect the requested newMaxSize.

Processing
➤ The deque Size property will be updated to reflect the new maximum size
declared by newMaxSize.

Date Code 20241023 Programming Reference


916 Queue
Benchmarks

NOTE
This does not initialize the associated memory space. Push or pop operations
should be avoided until the memory space is initialized by the user.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134 firmware
➤ SEL-3530
➢ R134 firmware
➤ SEL-3505
➢ R134 firmware

Benchmark Test Descriptions


Benchmarks are only performed on the Typed queues as the performance of the
generic queues will depend entirely on the size of an individual element of the
created queue. Tests postfixed with _TYPE_ will call the typed version of the
method dealing with only a single element.

Back_TYPE_
The posted time is the average execution time of 100 calls when the
Back_TYPE_() method copies one element from a deque containing 100
elements.

Back—100 Elements
The posted time is the average execution time of 100 calls when the Back()
method copies 100 elements from a deque containing 100 elements.

Clear
The posted time is the average execution time of 100 calls when clearing a
deque containing 100 elements.

EraseBack—1 Element
The posted time is the average execution time of 100 calls when the EraseBack
method removes one element from a deque containing 100 elements.

Programming Reference Date Code 20241023


Queue 917
Benchmarks

EraseBack—100 Elements
The posted time is the average execution time of 100 calls when the EraseBack()
method removes 100 elements from a deque containing 100 elements.

EraseFront—1 Element
The posted time is the average execution time of 100 calls when the
EraseFront() method removes one element from a deque containing 100
elements.

EraseFront—100 Elements
The posted time is the average execution time of 100 calls when the
EraseFront() method removes 100 elements from a deque containing 100
elements.

Front_TYPE_
The posted time is the average execution time of 100 calls when the
Front_TYPE_() method copies one element from a deque containing 100
elements.

Front—100 Elements
The posted time is the average execution time of 100 calls when the Front()
method copies 100 elements from a deque containing 100 elements.

PopBack_TYPE_
The posted time is the average execution time of 100 calls when popping one
element from a deque containing 100 elements.

PopBack—100 Elements
The posted time is the average execution time of 100 calls when popping 100
elements from the deque in a single method call. The deque is constructed
such that it has at least one resize caused by pushing prior to starting the pop
measurement.

PopFront_TYPE_
The posted time is the average execution time of 100 calls when popping one
element from a deque containing 100 elements.

PopFront—100 Elements
The posted time is the average execution time of 100 calls when popping 100
elements from the deque in a single method call. The deque is constructed
such that it has at least one resize caused by pushing prior to starting the pop
measurement.

Date Code 20241023 Programming Reference


918 Queue
Benchmarks

PushBack_TYPE_
The posted time is the average execution time of 100 calls when pushing an
element onto a deque without causing a resize.

PushBack—100 Elements
The posted time is the average execution time of 100 calls when pushing 100
elements onto a deque and causing a resize.

PushFront_TYPE_
The posted time is the average execution time of 100 calls when pushing an
element onto a deque without causing a resize.

PushFront—100 Elements
The posted time is the average execution time of 100 calls when pushing 100
elements onto a deque and causing a resize.

Recycle
The posted time is the average execution time of 100 calls when recycling a
deque containing 100 elements.

Resize—Enlarging
The posted time is the average execution time of 100 calls when resizing a full
deque from 32 elements to 64 elements.

Resize—Shrinking
The posted time is the average execution time of 100 calls when resizing a full
deque from 64 elements to 32 elements.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3555 SEL-3530 SEL-3505

Back - Byte 1 7 53

Back - Dword 1 5 16

Back - LReal 1 6 17

Back - Lword 1 4 23

Back - Pointer 1 5 26

Back - Real 1 6 28

Back - Word 1 6 19

Back 100 - Byte 1 3 16

Programming Reference Date Code 20241023


Queue 919
Benchmarks

Platform (time in µs)


Operation Tested
SEL-3555 SEL-3530 SEL-3505

Back 100 - Dword 1 3 8

Back 100 - LReal 1 6 10

Back 100 - Lword 1 4 14

Back 100 - Pointer 1 2 13

Back 100 - Real 1 5 14

Back 100 - Word 1 3 9

Clear - Byte 3 24 57

Clear - Dword 2 15 69

Clear - LReal 2 33 55

Clear - Lword 2 15 61

Clear - Pointer 2 16 61

Clear - Real 2 24 60

Clear - Word 2 17 58

EraseBack 1 - Byte 1 2 3

EraseBack 1 - Dword 1 2 3

EraseBack 1 - LReal 1 2 3

EraseBack 1 - Lword 1 2 2

EraseBack 1 - Pointer 1 2 3

EraseBack 1 - Real 1 2 2

EraseBack 1 - Word 1 1 2

EraseBack 100 - Byte 1 1 1

EraseBack 100 - Dword 1 1 1

EraseBack 100 - LReal 1 1 2

EraseBack 100 - Lword 1 1 2

EraseBack 100 - Pointer 1 1 1

EraseBack 100 - Real 1 1 1

EraseBack 100 - Word 1 1 1

EraseFront 1 - Byte 1 3 12

EraseFront 1 - Dword 1 2 10

EraseFront 1 - LReal 1 5 7

EraseFront 1 - Lword 1 4 10

EraseFront 1 - Pointer 1 3 10

EraseFront 1 - Real 1 4 13

EraseFront 1 - Word 1 3 8

EraseFront 100 - Byte 1 2 2

Date Code 20241023 Programming Reference


920 Queue
Benchmarks

Platform (time in µs)


Operation Tested
SEL-3555 SEL-3530 SEL-3505

EraseFront 100 - Dword 1 1 6

EraseFront 100 - LReal 1 2 2

EraseFront 100 - Lword 1 2 3

EraseFront 100 - Pointer 1 2 4

EraseFront 100 - Real 1 2 4

EraseFront 100 - Word 1 1 5

Front - Byte 1 10 11

Front - Dword 1 4 12

Front - LReal 1 6 16

Front - Lword 1 4 14

Front - Pointer 1 4 13

Front - Real 1 6 13

Front - Word 1 4 12

Front 100 - Byte 1 4 4

Front 100 - Dword 1 3 6

Front 100 - LReal 1 5 11

Front 100 - Lword 1 4 9

Front 100 - Pointer 1 3 7

Front 100 - Real 1 3 6

Front 100 - Word 1 3 5

PopBack - Byte 1 4 6

PopBack - Dword 1 3 15

PopBack - LReal 1 7 7

PopBack - Lword 1 3 7

PopBack - Pointer 1 4 9

PopBack - Real 1 5 10

PopBack - Word 1 4 19

PopBack 100 - Byte 1 3 4

PopBack 100 - Dword 1 4 16

PopBack 100 - LReal 1 9 7

PopBack 100 - Lword 1 4 8

PopBack 100 - Pointer 1 4 7

PopBack 100 - Real 1 5 7

PopBack 100 - Word 1 3 13

PopFront - Byte 1 5 8

Programming Reference Date Code 20241023


Queue 921
Benchmarks

Platform (time in µs)


Operation Tested
SEL-3555 SEL-3530 SEL-3505

PopFront - Dword 1 5 10

PopFront - LReal 1 7 16

PopFront - Lword 1 6 13

PopFront - Pointer 1 5 11

PopFront - Real 1 6 11

PopFront - Word 1 5 8

PopFront 100 - Byte 1 3 5

PopFront 100 - Dword 1 4 6

PopFront 100 - LReal 1 5 10

PopFront 100 - Lword 1 4 8

PopFront 100 - Pointer 1 4 7

PopFront 100 - Real 1 4 7

PopFront 100 - Word 1 3 5

PushBack - Byte 1 4 6

PushBack - Dword 1 3 7

PushBack - LReal 1 4 7

PushBack - Lword 1 3 6

PushBack - Pointer 1 3 6

PushBack - Real 1 3 6

PushBack - Word 1 3 5

PushBack 100 - Byte 4 86 84

PushBack 100 - Dword 4 29 89

PushBack 100 - LReal 4 40 106

PushBack 100 - Lword 4 29 98

PushBack 100 - Pointer 4 29 89

PushBack 100 - Real 4 63 88

PushBack 100 - Word 4 29 85

PushFront - Byte 1 5 15

PushFront - Dword 1 5 19

PushFront - LReal 1 8 11

PushFront - Lword 1 6 16

PushFront - Pointer 1 5 20

PushFront - Real 1 8 19

PushFront - Word 1 5 15

PushFront 100 - Byte 6 49 137

Date Code 20241023 Programming Reference


922 Queue
Examples

Platform (time in µs)


Operation Tested
SEL-3555 SEL-3530 SEL-3505

PushFront 100 - Dword 4 34 117

PushFront 100 - LReal 4 40 165

PushFront 100 - Lword 4 32 152

PushFront 100 - Pointer 4 40 123

PushFront 100 - Real 4 32 124

PushFront 100 - Word 4 61 104

Recycle - Byte 1 1 2

Recycle - Dword 1 1 2

Recycle - LReal 1 1 2

Recycle - Lword 1 1 2

Recycle - Pointer 1 1 2

Recycle - Real 1 1 2

Recycle - Word 1 1 1

Resize Down - Byte 3 30 103

Resize Down - Dword 3 22 124

Resize Down - LReal 3 44 80

Resize Down - Lword 3 23 78

Resize Down - Pointer 3 22 89

Resize Down - Real 3 31 92

Resize Down - Word 3 22 153

Resize Up - Byte 3 24 117

Resize Up - Dword 3 22 102

Resize Up - LReal 3 34 84

Resize Up - Lword 3 23 125

Resize Up - Pointer 3 22 133

Resize Up - Real 3 28 133

Resize Up - Word 3 22 79

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Programming Reference Date Code 20241023


Queue 923
Examples

Simple Deque Operation


This example demonstrates basic operation of a deque.

Objective
This example comprises the following steps:
Step 1. Add a series of UINT values to a UINT deque; the first as a single
value, and the second from an array of values.
Step 2. Remove one value from the front.
Step 3. Remove a group of five values from the front.
Step 4. Remove one value from the back.
Step 5. Push four values onto the front.
Step 6. Remove six values from the back.
Step 7. Remove the remaining value individually from the front until the
deque is empty again.

Sequence of Operations
The operations that make up the solution are outlined here in detail. After each
operation, the expected state of the deque is shown. The notation used in this
example assumes the front of the deque is on the left and the back is on the right.
1. The deque begins empty.

2. The first value pushed to the back of the deque is 0.

3. An array of values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10], is pushed onto the back of


the deque.

4. Five values are popped off of the front of the deque and into an array.

The resulting array contains [0, 1, 2, 3, 4].


5. The value at the back, 10, is then popped off.

6. An array with four values, [11, 12, 13, 14], are then pushed onto the front.

7. Six values are then popped off the back into an array.

The resulting array that was popped off contains [14, 5, 6, 7, 8, 9].
8. The values 11, 12, and 13 are then obtained by popping the remaining
values off the front of the deque one at a time, leaving it empty again.

Date Code 20241023 Programming Reference


924 Queue
Examples

Solution
The implementation of this example is shown in Code Snippet 28.1.
Code Snippet 28.1 prg_BasicDeque
PROGRAM prg_BasicDeque
VAR CONSTANT
c_NumPushStep3 : UDINT := 10;
c_NumPopStep4 : UDINT := 5;
c_NumPushStep6 : UDINT := 4;
c_NumPopStep7 : UDINT := 6;
END_VAR
VAR
Run : BOOL := TRUE; // Used to force the steps to only run once.
Ok : BOOL := FALSE; // Is true if the operation completed
MyDeque : class_WordDeque(numElements := 0); // Uses default internal allocation

(* Arrays to push*)
Step3ArrayToPush : ARRAY[1..c_NumPushStep3] OF UINT := [1,2,3,4,5,6,7,8,9,10];
Step6ArrayToPush : ARRAY[1..c_NumPushStep6] OF UINT := [11,12,13,14];

(* Results *)
Step4ArrayPopped : ARRAY[1..c_NumPopStep4] OF UINT; // Expect : [0,1,2,3,4]
Step5Popped : UINT; // Expect : 10
Step7ArrayPopped : ARRAY[1..c_NumPopStep7] OF UINT; // Expect : [14,5,6,7,8,9]
Step8val1, Step8val2, Step8val3 : UINT; // Expect: 11, 12, 13
END_VAR

IF Run THEN
(* Step 1: The queue begins empty. *)
Ok := TRUE;
(* Step 2: Push 0 into back of deque. Ok if push returns TRUE. *)
Ok := Ok AND MyDeque.PushBackWord(0);
(* Step 3: Push array to back of deque. Ok if the number popped is as requested. *)
Ok := Ok AND (c_NumPushStep3 =
MyDeque.PushBack(ADR(Step3ArrayToPush),c_NumPushStep3));
(* Step 4: Pop 5 values from front. Ok if number popped is as requested. *)
Ok := Ok AND (c_NumPopStep4 =
MyDeque.PopFront(ADR(Step4ArrayPopped),c_NumPopStep4));
(* Step 5: Pop one number of the back of the queue. *)
Ok := Ok AND MyDeque.PopBackWord(element => Step5Popped);
(* Step 6: Add 4 new values to the front. Ok if push adds number requested. *)
Ok := Ok AND (c_NumPushStep6 =
MyDeque.PushFront(ADR(Step6ArrayToPush),c_NumPushStep6));
(* Step 7: Pop 6 values from the back to an array. Ok if number popped is as requested. *)
Ok := Ok AND (c_NumPopStep7 =
MyDeque.PopBack(ADR(Step7ArrayPopped),c_NumPopStep7));
(* Step 8 : Pop the last 3 values from the front. Each operation OK if it returns TRUE. *)
Ok := Ok AND MyDeque.PopFrontWord(element => Step8val1);
Ok := Ok AND MyDeque.PopFrontWord(element => Step8val2);
Ok := Ok AND MyDeque.PopFrontWord(element => Step8val3);
Run := FALSE; // Only run 1 time.
END_IF

Generate a Deque Dynamically


This example demonstrates operation of the function fun_NewTypeDeque,
PushFront, EraseBack, Resize, and fun_DeleteDeque.

Programming Reference Date Code 20241023


Queue 925
Examples

Objective
This example comprises the following steps:

Step 1. Dynamically generate a deque of type REAL.


Step 2. Push values to the front of the deque.
Step 3. Erase a group of five values from the back.
Step 4. Check size of deque after erasing.
Step 5. Store remaining values in an array.
Step 6. Resize the deque to hold two values.
Step 7. Check size of deque after resizing.
Step 8. Store remaining values in an array.
Step 9. Wait 10 seconds.
Step 10. Dynamically delete deque.

Sequence of Operations
The operations that make up the solution are outlined here in detail. After each
operation, the expected state of the deque is shown. The notation used in this
example assumes the front of the deque is on the left and the back is on the right.

1. A new empty deque is generated.

2. An array of values, [1, 2, 3, 4, 5, 6, 7, 8, 9, 0], is pushed onto the front of


the deque.

3. The new size of the deque is checked.


The resulting number is 10.
4. Five values are deleted from the back.

5. The new size of the deque is checked.


The resulting number is 5.
6. The remaining values in deque are stored in an array.

7. The deque is resized to 2.

8. The new size of the deque is checked.


The resulting number is 2.
9. The remaining values in deque are stored in an array.

10. Wait 10 seconds.


11. The deque is deleted.

Date Code 20241023 Programming Reference


926 Queue
Examples

Solution
The implementation of this example is shown in Code Snippet 28.2.
Code Snippet 28.2 prg_DequeExample
PROGRAM prg_DequeExample
VAR CONSTANT
c_newDequeSize : UDINT := 10;
c_newDequeErase: UDINT := 5;
c_newDequeResize : UDINT := 2;
END_VAR
VAR
// Used to force the steps to only run once
createNewDeque : BOOL := TRUE;
// Pointer for the dynamically created deque
pt_NewDeque : POINTER TO Queue.class_RealDeque;
// Values to add to new deque
ArrayToPush : ARRAY[1..c_newDequeSize] OF REAL :=
[1,2,3,4,5,6,7,8,9,0];
// Values remaining in deque after calling the erase method
arrayAfterErase : ARRAY[1..c_newDequeErase] OF REAL; // Expect : [1,2,3,4,5]
// Values remaining in deque after resize method
arrayAfterResize : ARRAY[1..c_newDequeResize] OF REAL; // Expect : [1,2]
// Variable to verify that values have been pushed
sizeAfterPush : UDINT;
// Variable to verify that values have been erased
sizeAfterErase : UDINT;
// Variable to verify that deque has been resized
sizeAfterResize : UDINT;
// Timer to trigger the elimination of deque
deleteNewDeque : TEX;
// Variable to store return value of fun_DeleteDeque
newDequeDeleted : BOOL;
END_VAR

IF createNewDeque THEN
// Create a new deque of type REAL
pt_NewDeque := Queue.fun_NewTypeDeque(dequeType := REAL_DEQUE);
// Push REAL values from the array
pt_NewDeque^.PushFront(ADR(ArrayToPush),c_newDequeSize);
// Verify size after pushing values
sizeAfterPush := pt_NewDeque^.Size;
// Erase the last five elements of the deque
pt_NewDeque^.EraseBack(c_newDequeErase);
// Verify size after erasing
sizeAfterErase := pt_NewDeque^.Size;
// Store remaining values in deque in array
pt_NewDeque^.Front(ADR(ArrayAfterErase),c_newDequeErase);
// Resize the deque to hold two elements. Truncate data right of the first two elements
pt_NewDeque^.Resize(c_newDequeResize);
// Verify size after rezising
sizeAfterResize := pt_NewDeque^.Size;
// Store remaining values in deque in array
pt_NewDeque^.Front(ADR(arrayafterResize),c_newDequeResize);
// Only run 1 time
createNewDeque := FALSE;
END_IF

// Wait for 10 seconds before deleting


deleteNewDeque(IN := NOT createNewDeque,PT := T#10S);
// Verify that the deque is not empty
IF deleteNewDeque.Q AND NOT newDequeDeleted THEN
// Delete deque using fun_DeleteDeque function
newDequeDeleted := Queue.fun_DeleteDeque(pt_NewDeque^);
END_IF

Programming Reference Date Code 20241023


S E C T I O N 2 9

Quicksort
Introduction
This library implements the Quicksort algorithm for sorting arrays of objects.
Due to the strongly typed nature of IEC 61131, the sorting is provided with
multiple functions, one for each of the following datatypes:
➤ USINT
➤ SINT
➤ UINT
➤ INT
➤ UDINT
➤ DINT
➤ ULINT
➤ LINT
➤ REAL
➤ LREAL
This library also allows the sorting of arbitrary objects implementing the
I_Comparable interface. All functions sort in ascending order.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.
Version 3.5.0.0 can be used on RTAC firmware version R132 and later.

Functions
The following functions are provided by this library.

fun_SortUSINT (Function)
This function takes a pointer to an array of USINTs and sorts the array in-place
by value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO USINT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Date Code 20241023 Programming Reference


928 Quicksort
Functions

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error


occurred.

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.
➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortSINT (Function)
This function takes a pointer to an array of SINTs and sorts the array in-place by
value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO SINT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.
➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

Programming Reference Date Code 20241023


Quicksort 929
Functions

fun_SortUINT (Function)
This function takes a pointer to an array of UINTs and sorts the array in-place by
value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO UINT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortINT (Function)
This function takes a pointer to an array of INTs and sorts the array in-place by
value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO INT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error


occurred.

Date Code 20241023 Programming Reference


930 Quicksort
Functions

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortUDINT (Function)
This function takes a pointer to an array of UDINTs and sorts the array in-place
by value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO UDINT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortDINT (Function)
This function takes a pointer to an array of DINTs and sorts the array in-place by
value.

Programming Reference Date Code 20241023


Quicksort 931
Functions

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO DINT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortULINT (Function)
This function takes a pointer to an array of ULINTs and sorts the array in-place
by value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO ULINT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Date Code 20241023 Programming Reference


932 Quicksort
Functions

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortLINT (Function)
This function takes a pointer to an array of LINTs and sorts the array in-place by
value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO LINT Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortREAL (Function)
This function takes a pointer to an array of REALs and sorts the array in-place
by value.

Programming Reference Date Code 20241023


Quicksort 933
Functions

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO REAL Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortLREAL (Function)
This function takes a pointer to an array of LREALs and sorts the array in-place
by value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO LREAL Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Date Code 20241023 Programming Reference


934 Quicksort
Interfaces

Processing
This function uses the Quicksort algorithm to perform an in-place sorting of the
array.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two,
sorting of the array occurs through use of the Quicksort algorithm, and
the function returns the value TRUE.

fun_SortI_Comparable (Function)
This function takes a pointer to an array of I_Comparable objects and sorts the
array in-place by value.

Inputs
Name IEC 61131 Type Description

arrayPointer POINTER TO I_Comparable Pointer to the array to sort.

arraySize UDINT The number of elements in the array.

Return Value
IEC 61131 Type Description

BOOL TRUE if the sort completed successfully. FALSE if an error occurred.

Processing
This function sorts the array in-place using the Quicksort algorithm.

➤ The function returns FALSE and does not attempt to sort the array if the
arrayPointer is invalid.
➤ The function returns FALSE and does not attempt to sort the array if any
members of the array pointed to by arrayPointer are invalid.
➤ If arrayPointer is valid and arraySize is less than two, the function
returns true without sorting the array. Specifically, arrays of size zero or
one are considered already sorted.
➤ If arrayPointer is valid and arraySize is greater than or equal to two, the
array is sorted using an in-place Quicksort algorithm and true is returned.

Interfaces
This library provides the following interfaces.

Programming Reference Date Code 20241023


Quicksort 935
Interfaces

I_Comparable (Interface)
This interface is implemented by any class needing to be sortable. Any libraries
needing to sort arbitrary objects can create a class that implements this interface.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_Self POINTER TO BYTE R Provides the THIS pointer for the class.

CompareTo (Method)
This method compares this object to another object of the same type. If the
compare object is not of the same class, exceptions will occur.

Inputs

Name IEC 61131 Type Description

compare I_Comparable The object to compare.

Return Value

IEC 61131 Type Description

INT Returns a signed integer representing the sorting order. A negative value means this object goes before the compare
object. Zero means this object is equivalent to the compare object. A positive value means this object goes after the
compare object.

Processing
Compares this object to another object of the same type.

➤ Returns a negative value if this object goes before the compare object.
➤ Returns zero if this object is equivalent to the compare object.
➤ Returns a positive value if this object goes after the compare object.

Date Code 20241023 Programming Reference


936 Quicksort
Benchmarks

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3530
➢ R134 firmware
➤ SEL-3354
➢ Intel Pentium 1.4 GHz
➢ 1 GB DDR ECC SDRAM
➢ SEL-3532 RTAC Conversion Kit
➢ R132 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V0 firmware

Benchmark Test Descriptions


All benchmark tests are based on an average of 100 calls in the described
environment containing 1000 elements for each DATATYPE having a Quicksort
method where DATATYPE is selected from the following types:

➤ SINT
➤ USINT
➤ INT
➤ UINT
➤ DINT
➤ UDINT
➤ LINT
➤ ULINT
➤ REAL
➤ LREAL
Sorting performance any I_Comparable object will depend on the
implementation, so this document does not attempt to characterize that behavior.

DATATYPE InOrderSort
The average time for completion of the sort method when all data are presorted.

DATATYPE ReverseOrderSort
The average time for completion of the sort method when all data are in reverse
order.

Programming Reference Date Code 20241023


Quicksort 937
Benchmarks

DATATYPE RandomOrderSort
The average time for completion of the sort method when data are in random
order.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3530 SEL-3354 SEL-3555

SINT InOrderSort 1483 258 86

SINT ReverseOrderSort 1519 269 95

SINT RandomOrderSort 1756 343 141

USINT InOrderSort 1472 257 87

USINT ReverseOrderSort 1499 268 96

USINT RandomOrderSort 1728 345 142

INT InOrderSort 1317 233 78

INT ReverseOrderSort 1471 275 97

INT RandomOrderSort 1789 376 160

UINT InOrderSort 1327 233 76

UINT ReverseOrderSort 1476 271 94

UINT RandomOrderSort 1799 367 156

DINT InOrderSort 1317 229 76

DINT ReverseOrderSort 1469 272 94

DINT RandomOrderSort 1819 368 155

UDINT InOrderSort 1313 232 76

UDINT ReverseOrderSort 1461 271 92

UDINT RandomOrderSort 1800 368 157

LINT InOrderSort 1549 282 93

LINT ReverseOrderSort 1720 323 112

LINT RandomOrderSort 2159 444 181

ULINT InOrderSort 1552 275 91

ULINT ReverseOrderSort 1730 316 111

ULINT RandomOrderSort 2133 458 200

REAL InOrderSort 1460 242 78

REAL ReverseOrderSort 1634 283 97

REAL RandomOrderSort 2042 392 170

LREAL InOrderSort 1674 280 78

LREAL ReverseOrderSort 1863 314 97

LREAL RandomOrderSort 2323 444 168

Date Code 20241023 Programming Reference


938 Quicksort
Examples

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Sorting an Array of Integers


Objective
Code Snippet 29.1 demonstrates sorting a simple array of INTs.

Solution
Code Snippet 29.1 prg_SortInt
PROGRAM prg_SortInt
VAR
intArray : ARRAY [1..5] OF INT;
END_VAR

// Populate the array with unsorted values.


intArray[1] := 5;
intArray[2] := 2;
intArray[3] := 0;
intArray[4] := -1;
intArray[5] := -4;
// Sort the array.
fun_SortINT(ADR(intArray), 5);

Programming Reference Date Code 20241023


S E C T I O N 3 0

RecordingTriggers
Introduction
This library provides various function blocks to detect specific conditions
in analog and digital signals to initiate the capture of data in oscillography
recording devices, such as RTAC Recording Groups or SEL-2245 analog input
modules.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.0.3 and earlier can be used on RTAC firmware version R132 and
later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_DigitalTriggerModes
This enumeration defines the operating mode of the fb_DigitalTrigger function
block.

Enumeration Description

LEVEL Level mode

RISING_EDGE Rising-Edge mode

FALLING_EDGE Falling-Edge mode

RISING_FALLING_EDGE Rising/Falling-Edge mode

Structures
The Recording Trigger ACSELERATOR RTAC extension uses
struct_RecordingTriggerOutputInfo to group Recording Trigger information.
See the ACSELERATOR RTAC SEL-5033 software instruction manual for
additional details.

Date Code 20241023 Programming Reference


940 RecordingTriggers
Function Blocks

struct_RecordingTriggerOutputInfo
Name IEC 61131 Type Description

ChannelID STRING(64) The recording trigger channel identifier.

TriggerID STRING(64) The recording trigger identifier.

TriggerOuputInfo SPS The status of the recording trigger output.

Function Blocks
fb_HighThreshold (Function Block)
This function block monitors the value of an analog signal and compares it
against a predefined threshold value to detect if the signal is above the threshold.
This function block has two operating modes. The operating mode is selected
by setting the initialization argument risingEdgeMode to TRUE or FALSE when
the function block is instantiated.

1. Level mode: The output of the function block asserts when the value
of the analog signal first becomes greater than or equal to the threshold
value. The output of the function block remains asserted until the value
of the signal becomes less than or equal to the threshold value minus the
hysteresis value.
2. Rising-Edge mode: The output of the function block asserts for one
RTAC processing interval when the value of the analog signal first
becomes greater than or equal to the threshold value.

Initialization Inputs
Name IEC 61131 Type Description

risingEdgeMode BOOL Defines the operating mode of the function block. When TRUE, the function block is in
Rising-Edge mode. When FALSE, the function block is in Level mode.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block. Default is TRUE.

InSignal LREAL Analog signal to observe.

Threshold LREAL Minimum value of the analog signal required to


assert the trigger output of the function block.

PickupTime TIME (Optional) The time for which InSignal must be


greater than or equal to the Threshold level before
asserting the trigger output. Default is 0 seconds.

Programming Reference Date Code 20241023


RecordingTriggers 941
Function Blocks

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Hysteresis LREAL R/W The value of the hysteresis. Write to this


property to set the value of the hysteresis
when in Level mode.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

TriggerOut BOOL High-threshold condition is detected.

Processing
➤ Compare InSignal to Threshold.
➤ If the function block was initialized in Rising-Edge mode
(risingEdgeMode = TRUE):
➢ If InSignal becomes greater than or equal to Threshold for a time
greater than or equal to PickupTime, then assert TriggerOut for one
RTAC processing interval.
➤ If the function block was initialized in Level mode (risingEdgeMode =
FALSE):
➢ If InSignal becomes greater than or equal to Threshold for a time
greater than or equal to PickupTime, then assert TriggerOut.
➢ If TriggerOut is asserted AND InSignal becomes less than or equal to
(Threshold-Hysteresis), then deassert TriggerOut.

fb_LowThreshold (Function Block)


This function block monitors the value of an analog signal and compares it
against a predefined threshold value to detect if the signal is below the threshold.
This function block has two operating modes. The operating mode is selected
by setting the initialization argument risingEdgeMode to TRUE or FALSE when
the function block is instantiated.
This function block includes an optional MinimumActiveTriggerSetpoint input to
block the low threshold trigger from operating if InSignal is less than or equal to
this value.
1. Level mode: The output of the function block asserts when the value
of the analog signal first becomes less than or equal to the threshold
value. The output of the function block remains asserted until the value
of the signal becomes greater than or equal to the threshold value plus the
hysteresis value.
2. Rising-Edge mode: The output of the function block asserts for one
RTAC processing interval when the value of the analog signal first
becomes less than or equal to the threshold value.

Date Code 20241023 Programming Reference


942 RecordingTriggers
Function Blocks

Initialization Inputs
Name IEC 61131 Type Description

risingEdgeMode BOOL Defines the operating mode of the function block. When TRUE, the function block is in
Rising-Edge mode. When FALSE, the function block is in Level mode.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block. Default is TRUE.

InSignal LREAL Analog signal to observe.

Threshold LREAL Maximum value of the analog signal required to assert the trigger output of
the function block.

MinimumActiveTriggerSetpoint LREAL (Optional) The minimum value that InSignal must exceed to activate the low
threshold logic. Default is –999,999.

PickupTime TIME (Optional) The time for which InSignal must be less than or equal to the
Threshold level before asserting the trigger output. Default is 0 seconds.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Hysteresis LREAL R/W The value of the hysteresis. Write to this


property to set the value of the hysteresis
when in Level mode.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

TriggerOut BOOL Low-threshold condition is detected.

Programming Reference Date Code 20241023


RecordingTriggers 943
Function Blocks

Processing
➤ If InSignal is greater than MinimumActiveTriggerSetpoint, compare
InSignal to Threshold.
➤ If the function block was initialized in Rising-Edge mode
(risingEdgeMode = TRUE):
➢ If InSignal becomes less than or equal to Threshold, then the
PickupTime timer starts.
➢ If InSignal becomes greater than Threshold before the expiration of
the PickupTime timer, the PickupTime timer resets.
➢ When the PickupTime timer expires, then assert TriggerOut for one
RTAC processing interval.
➤ If the function block was initialized in Level mode (risingEdgeMode =
FALSE):
➢ If InSignal becomes less than or equal to Threshold, then the
PickupTime timer starts.
➢ If InSignal becomes greater than Threshold before the expiration of
the PickupTime timer, the PickupTime timer resets.
➢ When the PickupTime timer expires:
➣ If InSignal is equal to or less than MinimumActiveTriggerSetpoint,
then assert TriggerOut for one RTAC processing interval.
➣ If InSignal is greater than MinimumActiveTriggerSetpoint, then
assert TriggerOut.
➢ If TriggerOut is asserted:
➣ If InSignal becomes greater than or equal to Threshold +
Hysteresis, then deassert TriggerOut.

fb_RateOfChange (Function Block)


This function block monitors the value of an analog signal to detect if the signal
rate-of-change exceeds a user-defined rate over a user-defined time period. The
analog signal is sampled at fixed intervals determined by SamplingPeriod and
its magnitude is compared to the previous sample. If the absolute value of the
difference differs by RateOfChange or more, the output of the function block
asserts. This function block has two operating modes. The operating mode is
selected by setting the initialization argument risingEdgeMode to TRUE or
FALSE when the function block is instantiated.

➤ Level mode: The output of the function block asserts when the rate-of-
change condition is detected and remains asserted until the rate-of-change
condition clears.
➤ Rising-Edge mode: The output of the function block asserts for one
RTAC processing interval when a rate-of-change condition is first
detected. The output will not assert again until the rate-of-change
condition clears and a new rate-of-change is detected.

Because the sampling is done at fixed intervals, if an analog signal transition


exceeds the RateOfChange value and returns below RateOfChange in between
two consecutive samples, the trigger output will not assert for this condition.

Date Code 20241023 Programming Reference


944 RecordingTriggers
Function Blocks

Initialization Inputs
Name IEC 61131 Type Description

risingEdgeMode BOOL Defines the operating mode of the function block. When TRUE, the function block is in
Rising-Edge mode. When FALSE, the function block is in Level mode.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block. Default is TRUE.

InSignal LREAL Analog signal to observe.

RateOfChange LREAL Minimum change of the analog signal over a SamplingPeriod time required to set the trigger
output of the function block.

SamplingPeriod TIME Time period at which the analog signal is sampled to detect a rate-of-change condition. This
input should be set to a multiple of the RTAC processing scan time on which this object is
instantiated.

PickupTime TIME (Optional) The time the rate-of-change condition must be present before asserting the trigger
output. Default is 0 seconds.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

TriggerOut BOOL A rate-of-change condition is detected.

Sample_DN BOOL This output asserts for one RTAC processing cycle
when the analog signal is sampled and the rate-of-
change calculation logic is executed.

Processing
The following logic is performed every SamplingPeriod time interval k):

➤ Calculate the analog input change:


Deltak = |InSignalk − InSignalk−1|
➤ Assert Sample_DN for one RTAC processing interval.
➤ If the function block was initialized in Rising-Edge mode (RisingEdge =
TRUE):
➢ If Deltak ≥ RateOfChange for a time greater than or equal to
PickupTime, then assert TriggerOut for one RTAC processing interval.
➤ If the function block was initialized in Level mode (RisingEdge =
FALSE):
➢ If Deltak ≥ RateOfChange for a time greater than or equal to
PickupTime, then assert TriggerOut.
➢ If TriggerOut is asserted AND Deltak < RateOfChange, then deassert
TriggerOut.

Programming Reference Date Code 20241023


RecordingTriggers 945
Function Blocks

fb_DigitalTrigger (Function Block)


This function block monitors the status of a digital signal. The operation of
the output of the function block depends on the operating mode. This function
block has four operating modes. The operating mode is selected by setting the
initialization argument OpMode to the correspondent enumerated value (see
Enumerations on page 939) when the function block is instantiated. The
supported operating modes are listed below.

➤ Rising-Edge Mode: The output of the function block asserts for one
RTAC processing interval when the monitored digital signal changes from
FALSE to TRUE.
➤ Falling-Edge Mode: The output of the function block asserts for one
RTAC processing interval when the monitored digital signal changes from
TRUE to FALSE.
➤ Rising-/Falling-Edge Mode: The output of the function block asserts for
one RTAC processing interval when a change of state is detected in the
monitored digital signal.
➤ Level Mode: The output of the function block remains asserted as long as
the input signal is asserted.

Initialization Inputs
Name IEC 61131 Type Description

OpMode enum_DigitalTriggerModes Defines the operating mode of the


function block.

Inputs
Name IEC 61131 Type Description

EN BOOL Enables the function block. Default is TRUE.

InSignal BOOL Digital signal to observe.

PickupTime TIME (Optional) The time for which the input signal must
be asserted before asserting trigger output. Default is 0
seconds.

DropoutTime TIME (Optional) The time for which the input signal must be
deasserted after transitioning from TRUE to FALSE
before asserting the trigger output. Default is 0 seconds.

Outputs
Name IEC 61131 Type Description

ENO BOOL The function block is enabled.

TriggerOut BOOL Trigger condition is detected.

Date Code 20241023 Programming Reference


946 RecordingTriggers
Benchmarks

Processing
➤ If the function block was initialized in Rising-Edge mode (OpMode =
RISING_EDGE):
➢ If InSignal changes from FALSE to TRUE and remains TRUE for
a period equal to PickupTime, then assert TriggerOut for one RTAC
processing interval.
➤ If the function block was initialized in Falling-Edge mode (OpMode =
FALLING_EDGE):
➢ If InSignal changes from TRUE to FALSE and remains FALSE for a
period equal to DropoutTime, then assert TriggerOut for one RTAC
processing interval.
➤ If the function block was initialized in Rising-/Falling-Edge mode
(OpMode = RISING_ FALLING_EDGE):
➢ If InSignal transitions from FALSE to TRUE and remains TRUE for
a period equal to PickupTime, then assert TriggerOut for one RTAC
processing interval.
➢ Subsequently, if InSignal transitions from TRUE to FALSE and
remains FALSE for a period equal to DropoutTime, then assert
TriggerOut for one RTAC processing interval.
➤ If the function block was initialized in Level mode (OpMode = LEVEL):
➢ If InSignal asserts and remains asserted for a period equal to
PickupTime, then TriggerOut is asserted.
➢ Subsequently, InSignal deasserts and remains deasserted for a period
equal to DropoutTime, then TriggerOut is deasserted.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3505
➢ R139-V0 firmware
➤ SEL-3530
➢ R139-V0 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R139-V0 firmware

Benchmark Test Descriptions


The posted time is the average execution time of 1000 consecutive calls to the
following function blocks.

Programming Reference Date Code 20241023


RecordingTriggers 947
Examples

This testing is performed on the following function blocks:

➤ fb_HighThreshold
➤ fb_LowThreshold
➤ fb_RateOfChange
➤ fb_DigitalTriggers

Execution Time of High-Threshold Function Block


fb_HighThreshold. The time necessary to determine if a high-threshold
condition occurred.

Execution Time of Low-Threshold Function Block


fb_LowThreshold. The time necessary determine if a low-threshold condition
occurred.

Execution Time of Rate of Change Function Block


fb_RateOfChange. The time necessary determine if a rate-of-change condition
occurred.

Execution Time of Digital Triggers Function Block


The time necessary to determine if a digital trigger condition occurred.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

fb_HighThreshold 1 1 1

fb_LowThreshold 2 1 1

fb_RateOfChange 2 1 1

fb_DigitalTriggers 1 1 1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Date Code 20241023 Programming Reference


948 RecordingTriggers
Examples

fb_HighThreshold: Rising-Edge Mode


Objective
A user is using an Axion DC analog input module to read an analog signal. The
user wants to assert RTAC Output OUT201 when the value of the analog signal
exceeds 75.

Assumptions
This example assumes that there is an Axion analog input module configured in
the RTAC project.

Solution
To assert Output OUT201 when the analog signal is greater than or equal to 75,
the user can create a program as shown in Code Snippet 30.1.
Code Snippet 30.1 Rising-Edge Mode
PROGRAM Example_HighThreshold
VAR
HighTrigger_pulse: fb_HighThreshold(risingEdgeMode := TRUE)
:= (EN:= TRUE, Threshold := 75);
END_VAR

HighTrigger_pulse(InSignal := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag);

//Assert OUT201 if the function block output has triggered:


IF HighTrigger_pulse.TriggerOut THEN
SystemTags.OUT201.operSet.ctlVal := TRUE;
SystemTags.OUT201.operClear.ctlVal := FALSE;
END_IF

fb_HighThreshold: Level Mode


Objective
A user is using an Axion DC analog input module to read an analog signal.
The user wants to assert the Alarm variable when the value of the analog signal
exceeds 100. The Alarm variable deasserts when the analog signal drops to 95 or
below.

Assumptions
This example assumes that there is an Axion analog input module configured in
the RTAC project, and a global variable named Alarm exists in the project.

Solution
To assert the Alarm variable when the analog signal is greater than or equal to
100, and deassert the variable when the analog signal drops to 95 or below, the
user can create a program as shown in Code Snippet 30.2.
Code Snippet 30.2 Level Mode
PROGRAM Example_HighThreshold
VAR
HighTrigger_level: fb_HighThreshold(risingEdgeMode := FALSE)

Programming Reference Date Code 20241023


RecordingTriggers 949
Examples

:= (EN:= TRUE, Threshold := 100, Hysteresis:=5);


END_VAR

HighTrigger_level(InSignal := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag);

//Assert Level if the function block output has triggered:


IF HighTrigger_level.TriggerOut THEN
Alarm := TRUE;
ELSE
Alarm := FALSE;
END_IF

fb_LowThreshold: Rising-Edge Mode


Objective
A user is using an Axion DC analog input module to read an analog signal. The
user wants to assert RTAC Output OUT201 when the value of the analog signal
drops below 50.

Assumptions
This example assumes that there is an Axion analog input module configured in
the RTAC project.

Solution
To assert Output OUT201 when the analog signal is less than or equal to 50, the
user can create a program as shown in Code Snippet 30.3.
Code Snippet 30.3 Rising-Edge Mode
PROGRAM Example_LowThreshold
VAR
LowTrigger_pulse: fb_LowThreshold(risingEdgeMode := TRUE)
:= (EN:= TRUE, Threshold := 50);
END_VAR

LowTrigger_pulse(InSignal := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag);

//Assert OUT201 if the function block output has triggered:


IF LowTrigger_pulse.TriggerOut THEN
SystemTags.OUT201.operSet.ctlVal := TRUE;
SystemTags.OUT201.operClear.ctlVal := FALSE;
END_IF

fb_LowThreshold: Level Mode


Objective
A user is using an Axion DC analog input module to read an analog signal.
The user wants to assert the Alarm variable when the value of the analog signal
drops below 25. The Alarm variable deasserts when the analog signal becomes
equal to 28 or higher.

Assumptions
This example assumes that there is an Axion analog input module configured in
the RTAC project, and a global variable named Alarm exists in the project.

Date Code 20241023 Programming Reference


950 RecordingTriggers
Examples

Solution
To assert the Alarm variable when the analog signal is less than or equal to 25,
and deassert the variable when the analog signal becomes greater than or equal
to 28, the user can create a program as shown in Code Snippet 30.4.
Code Snippet 30.4 Level Mode
PROGRAM Example_LowThreshold
VAR
LowTrigger_level: fb_LowThreshold(risingEdgeMode := FALSE)
:= (EN:= TRUE, Threshold := 25, Hysteresis:=3);
END_VAR

LowTrigger_level(InSignal := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag);

//Assert Level if the function block output has triggered:


IF LowTrigger_level.TriggerOut THEN
Alarm := TRUE;
ELSE
Alarm := FALSE;
END_IF

fb_RateOfChange
Objective
A user is using a Modbus client on the RTAC to read a temperature value from
the field. The user wants to assert the RTAC output OUT201 when the rate-of-
change of the temperature exceeds 10°C per minute.

Assumptions
This example assumes that there is a Modbus client in the RTAC project,
and it is configured to read a temperature, in Celsius, from a measurement
device installed on the field. The name of the Modbus client in the project is
myModbus_MODBUS and the temperature of interest is mapped in the Modbus
Holding Register Address 0.

Solution
To assert Output OUT201 when the rate-of-change of the temperature is greater
than or equal to 10°C per minute, the user can create a program as shown in
Code Snippet 30.5:
Code Snippet 30.5 Rate-of-Change Example
PROGRAM Example_RateOfChange
VAR
TemperatureRoC: fb_RateOfChange(risingEdgeMode := FALSE)
:= (EN:=TRUE, RateOfChange:=10, SamplingPeriod:=T#1M);
END_VAR

TemperatureRoC(InSignal := myModbus_MODBUS.HREG_00000.Status.stVal);
//Assert OUT201 if the function block output has triggered:
IF TemperatureRoC.TriggerOut THEN
SystemTags.OUT201.operSet.ctlVal := TRUE;
SystemTags.OUT201.operClear.ctlVal := FALSE;
ELSE
SystemTags.OUT201.operSet.ctlVal := FALSE;
SystemTags.OUT201.operClear.ctlVal := TRUE;

Programming Reference Date Code 20241023


RecordingTriggers 951
Examples

END_IF

fb_DigitalTrigger
Objective
A user is monitoring the status of a circuit breaker using a digital input channel
in the RTAC. The user wants to generate an oscillography event file when the
circuit breaker trips or closes (rising edge and falling edge).

Assumptions
This example assumes the following:

➤ The circuit breaker is wired to the Digital Input IN201.


➤ The oscillography is generated by using an RTAC recording group. The
name of the recording group in the RTAC project is recGroup.

Solution
To trigger the recording group when a change of state occurs on Input IN201,
the user can create a program as shown in Code Snippet 30.6.
Code Snippet 30.6 DigitalTrigger Example
PROGRAM Example_DigitalTrigger
VAR
BreakerStatusChange: fb_DigitalTrigger(OpMode := RISING_FALLING_EDGE)
:= (EN:= TRUE);
END_VAR

BreakerStatusChange(InSignal := SystemTags.IN201.stVal);

//Trigger Recording Group:


recGroup_POU.Event_Trigger := BreakerStatusChange.TriggerOut;

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 3 1

ReportGenerator
Introduction
The ReportGenerator library is intended for use by extensions that support
the extension text editor object but can be broadly applied as an advanced file
writer/manager.
The term report, as used in this document, refers to the contents of a
Queue.class_ByteDeque instance at the time of calling the MakeReport() method
plus ASCII 16#20(Newline) characters and report management metadata as
deemed necessary by the configured ReportMethod input.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R145-V0 or later.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_ReportGeneratorObject"
myReportGeneratorObject := otherReportGeneratorObject;

// This is fine
someVariable := myReportGeneratorObject.value;
// As is this
pt_myReportGeneratorObject := ADR(myReportGeneratorObject);

2. Classes from this library must never be VAR_INPUT or


VAR_OUTPUT members in function blocks, functions, or methods.
Place them in the VAR_IN_OUT section or use pointers instead.
➤ Classes in this library have memory allocated inside them. As such,
they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).
➤ All file read operations are done completely into RAM. This means that
the reading of large files that exceed the available RAM will not work as
expected.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Date Code 20241023 Programming Reference


954 ReportGenerator
Classes

enum_ReportMethods
Enumeration Description

SINGLE_REPORT_FILES Each new report is placed in a dedicated file. The file name contains the user settable
fileName input followed by a time stamp representing the RTAC system time when
the report was triggered.

MULTIPLE_REPORT_FILES New triggered reports are appended to the same file. When the number of reports
added to the file equals the user-configured MaxReports setting, a new file is created
to contain the new report. File names contain a time stamp that reflects the RTAC
system time when the oldest report in the file was triggered. This time stamp has a
resolution in seconds.

Each report within the file is given a footer consisting a single ASCII
16#20(Newline) character followed by 32 bytes of meta-data, (to be used for report
rotation management), followed by a single ASCII 16#20(Newline) character.

MULTIPLE_REPORT_MANAGED_FILE New triggered reports are appended to a single file. When the number of reports
added to the file equals the user-configured MaxReports setting, the oldest report is
deleted from the file, prior to appending the new report.

Each report within the file is given a footer consisting of a single ASCII
16#20(Newline) character followed by 32 bytes of meta-data, (to be used for report
rotation management), followed by a single ASCII 16#20(Newline) character.

enum_FileType
Enumeration Description

TXT File names are given a ".txt" extension.

HTML File names are given a ".html" extension.

CSV File names are given a ".csv" extension.

Classes
This library provides the following classes as extensions of the IEC 61131
function block.

class_ReportGenerator (Class)
This class facilitates the writing and management of user-defined reports within
one or more files.

Outputs
Name IEC 61131 Type Description

Initialized BOOL TRUE if the class instance is initialized and ready


to accept new report requests via the MakeReport()
method.

Busy BOOL TRUE if the class instance is performing file


management or file write activities.

Programming Reference Date Code 20241023


ReportGenerator 955
Classes

Name IEC 61131 Type Description

Error BOOL TRUE if an internal processing error has occurred

ErrorMessage STRING(255) A text description of the last error encountered by


this class instance.

Initialize (Method)
Call this method to assign the inputs and in/out variable for this class instance.
This method must be called whenever new project settings are sent to the RTAC
or power to the RTAC is cycled.

Inputs

Name IEC 61131 Type Description

Directory STRING(100) The directory in which to store and manage report files. 100 characters max. /
delimits the folder path. It cannot contain any file path manipulation variables (\
\, /./, /../).

FileName STRING(100) The name of the report, 100 characters max

FileType enum_FileType TXT, HTML, or CSV. Defines the file name extension. Does not affect formatting
of report content.

ReportMethod enum_ReportMethods Method of report vs file creation.

MaxReports UINT For ReportMethod other than a SINGLE_REPORT_FILES MaxReports is the


maximum number of reports that can be contained within a single file.

LogRuntimeErrors BOOL If TRUE, runtime errors are logged in the RTAC SOE viewer.

InstanceName STRING(100) Context identification string for use with SOE logging.

NOTE
FileName and Directory settings may contain all printable ASCII characters
between 16#20(Space) and 16#7E(tilde) except for ", ', :, <, %, >, ?, \, and |.

NOTE
The specified directory should already exist prior to calling Initialize(). If not,
the outputs may reflect an error condition until the first report is created.

Inputs/Outputs

Name IEC 61131 Type Description

Report Queue.class_ByteDeque A class_ByteDeque instance that will contain the full content of the report. It is
the users' responsibility to populate the queue prior to calling the MakeReport()
method.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if initialization completes without error.

Date Code 20241023 Programming Reference


956 ReportGenerator
Classes

Processing
➤ If the Initialized class output is TRUE:
➢ Returns FALSE.
➤ If the Initialized output is FALSE:
➢ Maps input variables to internal class variables.
➢ Assigns internal reference to manage the operation of the Report
class_ByteDeque instance.
➢ Validates FileType, ReportMethod, and MaxReports inputs against
specified bounds.
➢ Returns TRUE if inputs are valid.
➢ Sets Initialized class output to the return value.

MakeReport (Method)
Call this method to generate a new report.

Return Value

IEC 61131 Type Description

BOOL Returns TRUE if no errors encountered.

Processing
➤ If the Busy output is FALSE:
➢ The current RTAC system time is saved and may subsequently be
appended to a new file name depending upon the Report Method and
state of the active file. See description of enum_ReportMethods and
the processing section of the Run method for more information.
➢ Empties the contents of the Report class_ByteDeque instance into a
local queue.
➤ If the Busy output is TRUE:
➢ Returns FALSE.

Run (Method)
Call this method every task cycle to allow for the execution of asynchronous file
operations.

The term active file is used here to describe a file in the RTAC file system
that the next triggered report is written to.

Processing—General
➤ No work is done until the Initialized output is TRUE.
➤ If Initialized is TRUE, work is done, regardless of the state of Error.

Programming Reference Date Code 20241023


ReportGenerator 957
Classes

Processing—SINGLE_REPORT_FILES Mode
➤ FileName and Directory name settings are validated within the Run
method, after each call of MakeReport. Invalid settings assert the Error
output and are described via the ErrorDescription output.
➤ If MakeReport() has been called and returns TRUE, creates a new file
and assigns a file name of {ReportName}_{RTAC system timestamp}.
{FileType} and writes contents of internal report queue to the file.

Processing—MULTIPLE_REPORT_FILES Mode
➤ FileName and Directory name settings are validated within the Run
method, after each call of MakeReport. Invalid settings assert the Error
output and are described via the ErrorDescription output.
➤ Reports are written to the active file from top to bottom of the file in
order of newest to oldest report.
➤ If MakeReport() has been called and returns TRUE, and no active file
exists or the active file already contains a number of reports equal to
MaxReports:
➢ Creates a new file with name of {ReportName}_{RTACsystem
timestamp}.{FileType}.
➢ Writes contents of Report queue to the top of the file, followed by the
footer.
➤ If MakeReport() has been called and returns TRUE, and the active file
contains less than MaxReports reports:
➢ Writes by contents of Report queue to the top of the file, followed by
the footer.
➤ If the RTAC is rebooted or settings changed, the reference to the
active file is reset to NULL and a new file is created on the next call to
MakeReport().

Processing—MULTIPLE_REPORT_MANAGED_FILE Mode
➤ FileName and Directory name settings are validated on the first call to
Run after the initial call to MakeReport. Invalid settings assert the Error
output and are described via the ErrorDescription output.
➤ Reports are written to the active file from top to bottom of the file in
order of newest to oldest report.
➤ If MakeReport() is called and returns TRUE:
➢ Writes contents of Report queue to the top of a file with file name of
{ReportName}.{FileType}, followed by the footer.
➢ If the file already contains MaxReports reports, deletes the oldest
report and associated footer from the bottom of the file.

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 3 2

SELEthernetController
Introduction
The SELEthernetController library provides the ability to stream data through
TCP and UDP ports. It provides client and server functionality for both TCP and
UDP connections.

Various methods are used to initiate new read or write operations.

Special Considerations
➤ Copying classes from this library causes unwanted behavior. This means
the following:

1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_SocketObject"
mySocketObject := otherSocketObject;

// This is fine
someVariable := mySocketObject.value;
// As is this
pt_mySocketObject := ADR(mySocketObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_ IN_OUT section or use pointers instead.

➤ Classes in this library have memory allocated inside them. As such,


they should only be created in environments of permanent scope (e.g.,
Programs, GlobalVariable Lists, or VAR_STAT sections).
➤ Opening and closing large numbers of Ethernet connections can take
significant time. Take great care when using this library on a system with
hard real-time requirements.
➤ This library does not have the ability to open ports in the RTAC firewall
to allow inbound communication. This means that for the library to
receive UDP packets or act as a TCP server, those ports must be opened
as Ethernet Incoming Access Points in the ACSELERATOR RTAC project.
➤ Use of localhost addresses (for example, 127.0.0.1) is disallowed for
configured IP destinations when used with class_TcpClient instances.
Attempting to use a localhost address in these configurations will result
in an enum_SocketState.ERROR when accessing the State property after
attempting to open the connection.

Date Code 20241023 Programming Reference


960 SELEthernetController
Supported Firmware Versions

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Version 3.5.2.0 must be used on RTAC firmware version R150 and later.

Version 3.5.1.0 can be used on RTAC firmware versions R143 through R149.

Versions 3.5.0.6 and earlier can be used on RTAC firmware versions R133
through R142.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_SocketState
Enumeration Description

LISTENING The server socket is ready to receive communication requests.

OPEN The socket is ready to send and receive UDP data.

CONNECTED The socket has an active client server TCP session.

CLOSED The socket will no longer allow communication.

ERROR The socket has encountered an error and needs reconfiguration.

Aliases
This section lists aliases that this library defines.

SESSION_HANDLE
Alias IEC 61131 Type

SESSION_HANDLE POINTER TO BYTE

Functions
This library provides the following functions.

fun_StringToInaddr
Convert basic strings to the INADDR type this library uses. Strings provided
to this function must be in the format xxx.xxx.xxx.xxx, where xxx is a number
between 0 and 255.

Programming Reference Date Code 20241023


SELEthernetController 961
Functions

Inputs
Name IEC 61131 Type Description

ipAddrString STRING(15) The string to convert to an INADDR.

Outputs
Name IEC 61131 Type Description

ipAddr INADDR The converted INADDR.

Return Value
IEC 61131 Type Description

BOOL TRUE if the string could be converted.

Processing
The fun_StringToInaddr() function does the following:
➤ Parses the provided string into four bytes.
➤ Outputs those bytes ordered in an INADDR.
➤ Returns FALSE and outputs an IP address of 0.0.0.0 if the string could
not be converted.

fun_InaddrToString
Converts an INADDR to a string in the format xxx.xxx.xxx.xxx, where xxx is a
number between 0 and 255.

Inputs
Name IEC 61131 Type Description

ipAddr INADDR The INADDR to convert to a string.

Return Value
IEC 61131 Type Description

STRING(15) The resulting IP address as a string.

Processing
The fun_InaddrToString() function does the following:
➤ Parses the provided INADDR by its four bytes.
➤ Returns a string in the format xxx.xxx.xxx.xxx, where xxx is a number
between 0 and 255.

Date Code 20241023 Programming Reference


962 SELEthernetController
Classes

Classes
Classes are a particular implementation of a Function Block (FB). They provide
methods and properties, which a normal FB does not provide.

class_UdpSocket (Class)
This class provides a socket for sending and receiving using through use of the
UDP protocol. Once enabled, the class creates, binds, sends, and receives to the
configured ports.

Initialization Inputs
Name IEC 61131 Type Description

maxPacketSize DINT The maximum packet size, in bytes, to obtain through use of this socket. A value of zero or
less results in the class imposing no limit on inbound packet size.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

State enum_SocketState R The state of this socket.

LocalPort UINT R The port number with which this


socket interfaces locally.

LocalIPAddr INADDR R The IP address with which this socket


interfaces locally.

pt_Error POINTER TO STRING R An error message describing any


present error condition.

bootstrap_SetLocalIP (Method)
Perform a one-time setting of the local IP address and port this socket will use.

Inputs
Name IEC 61131 Type Description

localPort UINT The port number through which this socket receives
and sends data through.

localIPAddr INADDR The IP address on the local box this socket uses.
Use 0.0.0.0 to allow all local IP addresses.

Return Value
IEC 61131 Type Description

BOOL TRUE if the IP address and port number are set.

Programming Reference Date Code 20241023


SELEthernetController 963
Classes

Processing
The bootstrap_SetLocalIP() method does the following:

➤ Immediately returns FALSE if the port and IP address are already set.
➤ Sets the IP address and port on the local machine for use by this socket.

Open (Method)
Configure the class_UdpSocket to allow communication.

Return Value
IEC 61131 Type Description

BOOL TRUE if the port is ready to send data.

Processing
The Open() method does the following:

➤ Opens the port for sending and receiving communication.


➤ Returns FALSE if the socket was unable to bind.

Close (Method)
Unconfigure the class_UdpSocket to disable communication.

Processing
The Close() method does the following:

➤ Discards any unread messages.


➤ Makes the socket unable to send or receive data.
➤ Forces reopening of the socket before processing additional
communication.

SendData (Method)
Send a block of data to the socket.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The data to send.

numBytes DINT The quantity of data in bytes.

destIPAddr INADDR The IP address to which data are sent.

destPort UINT The destination port to which data are sent.

Date Code 20241023 Programming Reference


964 SELEthernetController
Classes

Return Value
IEC 61131 Type Description

DINT The number of bytes sent.

Processing
The SendData() method does the following:
➤ Sends data if Open() has been successfully called.
➤ Validates access to the pointer provided.
➤ Limits numBytes to a positive number.
➤ Sends numBytes of data, starting at pt_data, to the socket.
➤ Returns the number of bytes successfully sent.

SendQueuedData (Method)
Send a block of data to the socket from the front of a queue.

Inputs
Name IEC 61131 Type Description

destIPAddr INADDR The IP address to which data are sent.

destPort UINT The destination port to which data are sent.

Inputs/Outputs
Name IEC 61131 Type Description

queue class_ByteDeque The queued data to send.

Return Value
IEC 61131 Type Description

DINT The number of bytes sent.

Processing
The SendQueuedData() method does the following:
➤ Sends data if Open() has been successfully called.
➤ Sends all data, starting at the front of queue, to the socket.
➤ Returns the number of bytes successfully sent.
➤ Removes bytes sent from the front of queue.

ReceiveFrom (Method)
Overwrites data with the first packet available to the socket.

Programming Reference Date Code 20241023


SELEthernetController 965
Classes

Inputs/Outputs
Name IEC 61131 Type Description

data class_ByteVector The container to which the data are written.

Outputs
Name IEC 61131 Type Description

fromIpAddr INADDR The IP address from which the data came.

fromPort UINT The port from which the data came.

Return Value
IEC 61131 Type Description

DINT The number of bytes loaded.

Processing
The ReceiveFrom() method does the following:
➤ Does nothing if the socket is not open or a new packet is not available.
➤ Deletes any data found in data.
➤ Places the first packet—as many as maxPacketSize bytes—from this
socket in data.
➤ Returns the number of bytes loaded into data.

ReceiveToQueueFrom (Method)
Overwrites data with the first packet available to the socket.

Inputs/Outputs
Name IEC 61131 Type Description

data class_ByteDeque The container to which the data are written.

Outputs
Name IEC 61131 Type Description

fromIpAddr INADDR The IP address from which the data came.

fromPort UINT The port from which the data came.

Return Value
IEC 61131 Type Description

DINT The number of bytes loaded.

Date Code 20241023 Programming Reference


966 SELEthernetController
Classes

Processing
The ReceiveToQueueFrom() method does the following:

➤ Does nothing if the socket is not open or a new packet is not available.
➤ Deletes any data found in data.
➤ Places the first packet—as many as maxPacketSize bytes—from this
socket in data.
➤ Returns the number of bytes loaded into data.

class_TcpClient (Class)
This class provides a client socket for the TCP protocol. Once enabled, the
class creates, binds, and sends to the configured port. Because TCP is session-
based communication, the client should close the session upon completion of the
communication to conserve server resources.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

State enum_SocketState R The state of this socket.

LocalPort UINT R The port number provided by the user


for use locally. A value of zero means
an OS-chosen port value will be used.

LocalIPAddr INADDR R The IP address with which this socket


interfaces locally.

DestIPAddr INADDR R The IP address to which any triggered


message is sent.

DestPort UINT R The port number to which any


triggered message is sent.

pt_Error POINTER TO STRING R An error message describing any


present error condition.

bootstrap_SetLocalIP (Method)
Perform a one-time setting of the local IP address and port this socket will use.

Inputs

Name IEC 61131 Type Description

localPort UINT The port number through which this socket receives
and sends data. If this value is zero then the OS will
choose a random outgoing port.

localIPAddr INADDR The IP address on the local box this socket uses.
Use 0.0.0.0 to allow all local IP addresses.

Programming Reference Date Code 20241023


SELEthernetController 967
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the IP address and port number are set.

Processing
The bootstrap_SetLocalIP() method does the following:
➤ Immediately returns FALSE if the port and IP address are already set.
➤ Sets the IP address and port on the local machine for use by this socket.

SetIP (Method)
Set the IP address and port to be used on the next Open() request.

Inputs
Name IEC 61131 Type Description

destIPAddr INADDR The IP address to which data is sent.

destPort UINT The destination port to which data is sent.

Processing
The SetIP() method does the following:
➤ Sets the IP address and port that will become the new destination the next
time Open() is called.

Open (Method)
Configure the class_TcpClient to allow communication.

Return Value
IEC 61131 Type Description

BOOL TRUE if the port is ready to send data.

Processing
The Open() method does the following:
➤ Opens the port for sending and receiving communication, if SetIP() has
been successfully run.
➤ Returns FALSE if the socket was unable to connect or another error was
encountered.

Close (Method)
Unconfigure the class_TcpClient, to disable communication.

Date Code 20241023 Programming Reference


968 SELEthernetController
Classes

Inputs

Name IEC 61131 Type Description

forceClose BOOL Close the session without waiting for confirmation.

Processing
The Close() method does the following:

➤ Discards any unread data.


➤ Allows server to retain session until all data are read, if forceClose is
FALSE.
➤ Makes the socket unable to send data or receive replies.
➤ Forces reopening of the socket before processing additional
communication.

SendData (Method)
Send a block of data to the socket.

Inputs

Name IEC 61131 Type Description

pt_data POINTER TO BYTE The data to send.

numBytes DINT The quantity of data in bytes.

Return Value

IEC 61131 Type Description

DINT The number of bytes sent.

Processing
The SendData() method does the following:

➤ Does nothing if the socket is not open.


➤ Validates access to the pointer provided.
➤ Limits numBytes to a positive number.
➤ Sends all provided data to the socket.
➤ Returns the number of bytes successfully sent.

SendQueuedData (Method)
Send a block of data to the socket from the front of a queue.

Programming Reference Date Code 20241023


SELEthernetController 969
Classes

Inputs/Outputs

Name IEC 61131 Type Description

queue class_ByteDeque The data to send.

Return Value

IEC 61131 Type Description

DINT The number of bytes sent.

Processing
The SendQueuedData() method does the following:

➤ Does nothing if the socket is not open.


➤ Sends all provided data, starting at the front of queue, to the socket.
➤ Returns the number of bytes successfully sent.
➤ Removes bytes sent from the front of queue.

ReceiveData (Method)
Appends a block of data from the socket to data.

Inputs

Name IEC 61131 Type Description

numBytes DINT The number of bytes requested.

Inputs/Outputs

Name IEC 61131 Type Description

data class_ByteVector The container to which the data are written.

Return Value

IEC 61131 Type Description

DINT The number of bytes loaded.

Processing
The ReceiveData() method does the following:

➤ Does nothing if the socket is not open.


➤ Requests data from the socket until there are either no more or it reaches
numBytes, whichever happens first.

Date Code 20241023 Programming Reference


970 SELEthernetController
Classes

➤ Appends all data retrieved to data.


➤ Returns the number of bytes appended.

ReceiveToQueue (Method)
Pushes a block of data from the socket to the back of queue.

Inputs

Name IEC 61131 Type Description

numBytes DINT The number of bytes requested.

Inputs/Outputs

Name IEC 61131 Type Description

queue class_ByteDeque The container to which the data are written.

Return Value

IEC 61131 Type Description

DINT The number of bytes loaded.

Processing
The ReceiveToQueue() method does the following:

➤ Does nothing if the socket is not open.


➤ Requests data from the socket until there are either no more or it reaches
numBytes, whichever happens first.
➤ Pushes all data retrieved to the back of queue.
➤ Returns the number of bytes pushed.

class_TcpServer (Class)
This class provides a listening socket for the TCP protocol. Once enabled the
class creates, binds, and receives on the configured port.

Initialization Inputs
Name IEC 61131 Type Description

maxSessions USINT The maximum number of concurrent sessions to


allow on this socket. This will be forced to at least
one.

Programming Reference Date Code 20241023


SELEthernetController 971
Classes

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

State enum_SocketState R The state of this socket.

LocalPort UINT R The port number with which this socket interfaces locally.

LocalIPAddr INADDR R The IP address with which this socket interfaces locally.

NumSessions USINT R The number of client sessions connected to this server block.

SessionState enum_SocketState R The state of the selected session. CLOSED if nothing is connected
or CONNECTED if data can still be read from the socket.

DestIPAddr INADDR R The IP address to which any triggered message is sent.

DestPort UINT R The port to which any triggered message is sent.

pt_Error POINTER TO STRING R An error message describing any present error condition.

bootstrap_SetLocalIP (Method)
Perform a one-time setting of the local IP address and port this socket will use.

Inputs

Name IEC 61131 Type Description

localPort UINT The port number through which this socket receives
and sends data.

localIPAddr INADDR The IP address on the local box this socket uses.
Use 0.0.0.0 to allow all local IP addresses.

Return Value

IEC 61131 Type Description

BOOL TRUE if the IP address and port number are set.

Processing
The bootstrap_SetLocalIP() method does the following:

➤ Immediately returns FALSE if the port and IP address are already set.
➤ Sets the IP address and port on the local machine used by this socket.

Open (Method)
Configure the class_TcpServer to allow for communication.

Date Code 20241023 Programming Reference


972 SELEthernetController
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the port is ready to receive connections.

Processing
The Open() method does the following:

➤ Configures the server to receive client connections.


➤ Returns FALSE if the socket was unable to bind.

Close (Method)
Unconfigure the class_TcpServer to disable communication.

Inputs
Name IEC 61131 Type Description

forceClose BOOL Close the session without waiting for confirmation.

Processing
The Close() method does the following:

➤ Discards any unread data.


➤ Closes all open client sessions: gracefully if forceClose is FALSE.
➤ Makes the socket unable to send data or receive replies.
➤ Forces reconfiguration of the socket before attempting additional
communication.

AcceptNextSession (Method)
Accept the next new inbound data session. This does not change the active
session.

Return Value
IEC 61131 Type Description

SESSION_HANDLE The descriptor to allow further communication through this


session.

Processing
The AcceptNextSession() method does the following:

➤ Does nothing if the socket is not open for listening.


➤ Accepts the next outstanding client session to as many as maxSessions.

Programming Reference Date Code 20241023


SELEthernetController 973
Classes

➤ Updates NumSessions based on the sessions accepted.


➤ Returns the value RTS_INVALID_HANDLE if there are no outstanding
sessions.
➤ Returns the handle to the accepted session.

SetSession (Method)
Select the session from which the class reads data from and replies to.

Inputs

Name IEC 61131 Type Description

sessionID SESSION_HANDLE The identifier of the desired session as


returned by AcceptNextSession().

Return Value

IEC 61131 Type Description

BOOL TRUE if the session exists.

Processing
The SetSession() method does the following:

➤ Selects the read and write session tied to sessionID.


➤ Sets DestIPAddr and DestPort to the values for the selected session.
➤ Returns FALSE and sets DestIPAddr to 0.0.0.0, DestPort to 0, and
SessionState to closed if sessionID does not represent an active
session.

GetSessionInfo (Method)
Get the IP address and port number related to a session handle.

Inputs

Name IEC 61131 Type Description

sessionID SESSION_HANDLE The identifier of a session as returned by


AcceptNextSession().

Outputs

Name IEC 61131 Type Description

sessionIPAddr INADDR The IP address attached to sessionID.

sessionPort UINT The port number attached to sessionID.

Date Code 20241023 Programming Reference


974 SELEthernetController
Classes

Processing
The GetSessionInfo() method does the following:
➤ Outputs the IP address and port number tied to sessionID.
➤ Sets sessionIPAddr to 0.0.0.0 and sessionPort to 0, if sessionID does not
represent an active session.

CloseSession (Method)
Close the selected session and clear any pending data.

Inputs
Name IEC 61131 Type Description

forceClose BOOL Close the session without waiting for confirmation.

Processing
The CloseSession() method does the following:
➤ Closes the active session.
➤ Sets DestIPAddr and DestPort to zero.
➤ Discards any unread data.
➤ Allows client to retain session until all data are read, if forceClose is
FALSE.
➤ Decrements NumSessions.

SendData (Method)
Send a block of data to the socket.

Inputs
Name IEC 61131 Type Description

pt_data POINTER TO BYTE The data to send.

numBytes DINT The quantity of data in bytes.

Return Value
IEC 61131 Type Description

DINT The number of bytes sent.

Processing
The SendData() method does the following:
➤ Does nothing if no valid session has been selected.
➤ Validates access to the pointer provided.

Programming Reference Date Code 20241023


SELEthernetController 975
Classes

➤ Limits numBytes to a positive number.


➤ Sends all provided data to the socket.
➤ Returns the number of bytes successfully sent.

SendQueuedData (Method)
Send a block of data to the socket from the front of a queue.

Inputs/Outputs
Name IEC 61131 Type Description

queue class_ByteDeque The data to send.

Return Value
IEC 61131 Type Description

DINT The number of bytes sent.

Processing
The SendQueuedData() method does the following:

➤ Does nothing if the socket is not open.


➤ Sends all provided data, starting at the front of the queue, to the socket.
➤ Returns the number of bytes successfully sent.
➤ Removes bytes sent from the front of queue.

ReceiveData (Method)
Receive a block of data from the active session.

Inputs
Name IEC 61131 Type Description

numBytes DINT The number of bytes requested.

Inputs/Outputs
Name IEC 61131 Type Description

data class_ByteVector The container to which the data are written.

Return Value
IEC 61131 Type Description

DINT The number of bytes loaded into data.

Date Code 20241023 Programming Reference


976 SELEthernetController
Classes

Processing
The ReceiveData() method does the following:

➤ Does nothing if no valid session has been selected.


➤ Checks for available data in the selected session.
➤ Requests data from the socket until there are no more or it reaches
numBytes, whichever happens first.
➤ Appends all data retrieved to data.
➤ Returns the number of bytes appended.

ReceiveToQueue (Method)
Pushes a block of data from the socket to the back of queue.

Inputs

Name IEC 61131 Type Description

numBytes DINT The number of bytes requested.

Inputs/Outputs

Name IEC 61131 Type Description

queue class_ByteDeque The container to which the data are written.

Return Value

IEC 61131 Type Description

DINT The number of bytes loaded.

Processing
The ReceiveToQueue() method does the following:

➤ Does nothing if the socket is not open.


➤ Requests data from the socket until there are no more or it reaches
numBytes, whichever happens first.
➤ Pushes all data retrieved to the back of queue.
➤ Returns the number of bytes pushed.

Programming Reference Date Code 20241023


SELEthernetController 977
Benchmarks

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V0 firmware
➤ SEL-3530
➢ R134-V0 firmware
➤ SEL-3505
➢ R134-V0 firmware

Benchmark Test Descriptions


fun_StringToInaddr
The posted time is the average execution time of 100 consecutive calls for the
string "192.168.100.100".

fun_InaddrToString
The posted time is the average execution time of 100 consecutive calls for the IP
address 192.168.100.100.

class_UdpSocket.Open
The posted time is the average execution time of 100 successful method calls to
open a socket.

class_UdpSocket.Close
The posted time is the average execution time of 100 successful method calls to
close a socket.

class_UdpSocket.SendData
The posted time is the average execution time of 100 consecutive calls when
sending 504 bytes of data, resulting in a 512-byte total packet size.

class_UdpSocket.SendQueuedData
The posted time is the average execution time of 100 consecutive calls when
sending 504 bytes of data, resulting in a 512-byte total packet size.

Date Code 20241023 Programming Reference


978 SELEthernetController
Benchmarks

class_UdpSocket.ReceiveFrom
The posted time is the average execution time of 100 consecutive calls when
receiving 504 bytes of data, resulting in a 512-byte total packet size.

class_UdpSocket.ReceiveToQueueFrom
The posted time is the average execution time of 100 consecutive calls when
receiving 504 bytes of data, resulting in a 512-byte total packet size.

class_TcpClient.SetIP
The posted time is the average execution time of 100 consecutive calls.

class_TcpClient.Open
The posted time is the average execution time of 100 successful method calls to
open a socket.

class_TcpClient.Close
The posted time is the average execution time of 100 successful method calls to
close a socket.

class_TcpClient.SendData
The posted time is the average execution time of 100 consecutive calls when
sending 1400 bytes of data.

class_TcpClient.SendQueuedData
The posted time is the average execution time of 100 consecutive calls when
sending 1400 bytes of data.

class_TcpClient.ReceiveData
The posted time is the average execution time of 100 consecutive calls when
receiving 1400 bytes of data.

class_TcpClient.ReceiveToQueue
The posted time is the average execution time of 100 consecutive calls when
receiving 1400 bytes of data.

class_TcpServer.Open
The posted time is the average execution time of 100 successful method calls to
open a socket.

Programming Reference Date Code 20241023


SELEthernetController 979
Benchmarks

class_TcpServer.Close
The posted time is the average execution time of 100 successful method calls to
close a socket.

class_TcpServer.AcceptNextSession
The posted time is the average execution time of 100 successful method calls
when there is another session to accept.

class_TcpServer.SetSession
The posted time is the average execution time of 100 consecutive calls.

class_TcpServer.GetSessionInfo
The posted time is the average execution time of 100 consecutive calls.

class_TcpServer.CloseSession
The posted time is the average execution time of 100 successful method calls to
close a session.

class_TcpServer.SendData
The posted time is the average execution time of 100 consecutive calls when
sending 1400 bytes of data.

class_TcpServer.SendQueuedData
The posted time is the average execution time of 100 consecutive calls when
sending 1400 bytes of data.

class_TcpServer.ReceiveData
The posted time is the average execution time of 100 consecutive calls when
receiving 1400 bytes of data.

class_TcpServer.ReceiveToQueue
The posted time is the average execution time of 100 consecutive calls when
receiving 1400 bytes of data.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3555 SEL-3530 SEL-3505

fun_StringToInaddr 2 12 18

fun_InaddrToString 6 40 63

Date Code 20241023 Programming Reference


980 SELEthernetController
Examples

Platform (time in µs)


Operation Tested
SEL-3555 SEL-3530 SEL-3505

class_UdpSocket.Open 25 150 330

class_UdpSocket.Close 13 65 117

class_UdpSocket.SendData 26 150 380

class_UdpSocket.SendQueuedData 25 160 380

class_UdpSocket.ReceiveFrom 12 90 200

class_UdpSocket.ReceiveToQueueFrom 12 100 220

class_TcpClient.SetIP 1 1 1

class_TcpClient.Open 67 740 1200

class_TcpClient.Close 41 310 660

class_TcpClient.SendData 1 3 6

class_TcpClient.SendQueuedData 1 3 5

class_TcpClient.ReceiveData 8 80 110

class_TcpClient.ReceiveToQueue 7 80 110

class_TcpServer.Open 36 200 400

class_TcpServer.Close 20 100 140

class_TcpServer.AcceptNextSession 20 97 130

class_TcpServer.SetSession 2 4 6

class_TcpServer.GetSessionInfo 2 5 14

class_TcpServer.CloseSession 33 320 690

class_TcpServer.SendData 1 3 6

class_TcpServer.SendQueuedData 1 3 5

class_TcpServer.ReceiveData 9 80 110

class_TcpServer.ReceiveToQueue 8 75 110

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Sending Data Out a UDP Socket


Objective
A user has an array of bytes formatted to place on the network and needs to send
it to a specific IP address and port via UDP.

Programming Reference Date Code 20241023


SELEthernetController 981
Examples

Solution
The user can create the program shown in Code Snippet 32.1 to send the byte
array out each task cycle.
Code Snippet 32.1 prg_UdpOut
PROGRAM prg_UdpOut
VAR
// Configuration Information – Uses any available interface.
LocalIPAddress : STRING(15) := '0.0.0.0';
LocalPortNumber : UINT := 5000;
DestinationIPAddress : STRING(15) := '10.10.10.10';
DestinationPortNumber : UINT := 5000;

// Data to send each task cycle.


Data : ARRAY [1 .. 1000] OF BYTE;

// Socket to send data on.


UdpSocket : class_UdpSocket(maxPacketSize := 1024);

// Initialization variables.
SocketInitialized : BOOL := FALSE;
LocalIP : SELEthernetController.INADDR;
DestIP : SELEthernetController.INADDR;
END_VAR

IF NOT SocketInitialized THEN


fun_StringToInaddr(LocalIPAddress, ipAddr => LocalIP);
fun_StringToInaddr(DestinationIPAddress, ipAddr => DestIP);
UdpSocket.bootstrap_SetLocalIP(LocalPortNumber, LocalIP);
UdpSocket.Open();
SocketInitialized := TRUE;
ELSE
UdpSocket.SendData(ADR(Data[1]), SIZEOF(Data),
DestIP, DestinationPortNumber);
END_IF

Creating a UDP Server


Objective
A user would like the RTAC to be able to receive data from multiple clients over
the UDP protocol.

After some internal validation of a received packet, the server will reply with OK
in ASCII if the packet was correctly formatted.

Assumptions
This solution assumes that the ACSELERATOR RTAC project containing the
provided code includes an Access Point opening at the desired port and that the
inbound packets are not larger than 1024 bytes.

Date Code 20241023 Programming Reference


982 SELEthernetController
Examples

Solution
The user can create the program shown in Code Snippet 32.2 to receive one
inbound data packet each task cycle.
Code Snippet 32.2 prg_UdpServer
PROGRAM prg_UdpServer
VAR
// Configuration Information – Uses any available interface.
LocalIPAddress : STRING(15) := '0.0.0.0';
LocalPortNumber : UINT := 1515;

// Storage for inbound and outbound messages.


DataIn : SELEthernetController.class_ByteVector;
DataOut : STRING(2) := 'OK';

// The socket and its initialization data.


UdpSocket : class_UdpSocket(maxPacketSize := 1024);
SocketInitialized : BOOL := FALSE;
LocalIP : SELEthernetController.INADDR;

// Workbench variables for storing current client information.


DestIP : SELEthernetController.INADDR;
DestPort : UINT;
PacketValid : BOOL;
END_VAR

IF NOT SocketInitialized THEN


fun_StringToInaddr(LocalIPAddress, ipAddr => LocalIP);
UdpSocket.bootstrap_SetLocalIP(LocalPortNumber, LocalIP);
UdpSocket.Open();
SocketInitialized := TRUE;
ELSE
IF 0 <> UdpSocket.ReceiveFrom(DataIn, fromIpAddr => DestIP, fromPort
=> DestPort) THEN
; // Set PacketValid based on the contents of DataIn.
IF PacketValid THEN
UdpSocket.SendData(ADR(DataOut), 2, DestIP, DestPort);
END_IF
END_IF
END_IF

Creating a TCP Client


Objective
A user would like the RTAC to be able to send data to a TCP server for
modification.

Assumptions
For this use case, we assume that the server doubles any data that are sent to it.

Programming Reference Date Code 20241023


SELEthernetController 983
Examples

Solution
The user can create the program defined in Code Snippet 32.3 to send packets to
the remote server and receive data in reply.
Code Snippet 32.3 prg_TcpClient
PROGRAM prg_TcpClient
VAR
// Configuration Information – Uses any available interface.
LocalIPAddress : STRING(15) := '0.0.0.0';
LocalPortNumber : UINT := 2442;
DestinationIPAddress : STRING(15) := '10.10.10.10';
DestinationPortNumber : UINT := 2442;

// Storage for data being sent and received.


DataOut : ARRAY [1 .. 200] OF BYTE;
DataIn : SELEthernetController.class_ByteVector;

// The socket and its initialization state.


TcpClient : class_TcpClient;
SocketInitialized : BOOL := FALSE;

// IP address variables.
LocalIP : SELEthernetController.INADDR;
DestIP : SELEthernetController.INADDR;

// Flags used in manipulating the state of the function.


IsSending : BOOL;
DataSent : DINT;
DataReceived : DINT;
END_VAR

IF NOT SocketInitialized THEN


fun_StringToInaddr(LocalIPAddress, ipAddr => LocalIP);
fun_StringToInaddr(DestinationIPAddress, ipAddr => DestIP);
TcpClient.bootstrap_SetLocalIP(LocalPortNumber, LocalIP);
TcpClient.SetIP(DestIP, DestinationPortNumber);
TcpClient.Open();
SocketInitialized := TRUE;
IsSending := TRUE;
ELSE
IF IsSending THEN
DataSent := TcpClient.SendData(ADR(DataOut[1]), 200);
DataIn.Recycle();
IsSending := FALSE;
DataReceived := 0;
ELSE
// Here we request the total data expected minus anything
// already received and add it to anything already received.
// This allows the reception of data to cross multiple cycles.
DataReceived := DataReceived +
TcpClient.ReceiveData((DataSent * 2)
– DataReceived, DataIn);
IF DataReceived = (2 * DataSent) THEN
; // Do some work based the server's reply.
IsSending := TRUE;
END_IF
END_IF
END_IF

Parsing Network Traffic With a Deque


This example demonstrates using a deque for network communication.

Date Code 20241023 Programming Reference


984 SELEthernetController
Examples

Objective
Parse the data stream of information sent from a TCP server to the TCP client on
the RTAC. Increment a counter every time the characters "SEL" are seen in the
stream.

Assumptions
This example assumes that there is a server to connect to and streams data
through the connection once the connection is established. It also assumes that
the library Queue has been inserted in the project.

Solution
The deque is used as storage for information received from a TCP socket. The
received data are then searched for the string 'SEL' and a counter is incremented
every time the string is found. As it searches for the string, data are discarded
from the front of the deque. This implementation is shown in Code Snippet 32.4.
Code Snippet 32.4 prg_SELSearch
PROGRAM prg_SELSearch
VAR
// Configuration Information – Uses any available interface.
LocalIPAddress : STRING(15) := '0.0.0.0';
LocalPortNumber : UINT := 2442;
DestinationIPAddress : STRING(15) := '10.10.10.10';
DestinationPortNumber : UINT := 2442;

// The socket and its initialization state.


TcpClient : class_TcpClient;
SocketInitialized : BOOL := FALSE;
// IP address variables.
LocalIP : SELEthernetController.INADDR;
DestIP : SELEthernetController.INADDR;
// Deque to hold received data.
DataIn : Queue.class_ByteDeque(0);
// The string to search for in the incoming data.
TargetString : STRING := 'SEL';
// A temporary string used to find the targetString.
Peek : STRING(3);
// A flag for breaking the search loop.
Searching : BOOL;
// Counter for the number of times the targetString is found.
Counter : UDINT := 0;
END_VAR

IF NOT SocketInitialized THEN


fun_StringToInaddr(LocalIPAddress, ipAddr => LocalIP);
fun_StringToInaddr(DestinationIPAddress, ipAddr => DestIP);
TcpClient.bootstrap_SetLocalIP(LocalPortNumber, LocalIP);
TcpClient.SetIP(DestIP, DestinationPortNumber);
TcpClient.Open();
SocketInitialized := TRUE
ELSE
// Read new data from the socket.
IF 0 <> TcpClient.ReceiveToQueue(10_000, DataIn) THEN
searching := TRUE;
WHILE searching DO
// See if the string 'SEL' appears in the front of the deque.
IF 3 = DataIn.Front(ADR(peek), 3) THEN
IF peek = TargetString THEN
(* The string 'SEL' was found, increment the counter
and erase the string from the deque. *)

Programming Reference Date Code 20241023


SELEthernetController 985
Examples

Counter := Counter + 1;
DataIn.EraseFront(3);
ELSE
(* The string wasn't found, erase the first character
and continue looking. *)
DataIn.EraseFront(1);
END_IF
ELSE
Searching := FALSE;
END_IF
END_WHILE
END_IF
END_IF

Configuring a Simple TCP Server With Sessions


Objective
Parse all input data from several clients looking for the string "Hello." When the
string is found that client receives a reply "World$N$R".

The server handles accepting and tracking all sessions and iterates across them
to allow each time to process.

Assumptions
This example assumes that Port 10024 is open through use of an Access Point
configured as Ethernet Incoming and set to receive Raw TCP. It also assumes
that the client can access that port through any intermediary firewalls. It also
assumes that the library Queue has been inserted in the project.

All error checking has been omitted to facilitate the brevity of this
implementation.

There must be a structure defined to hold session related data. Code Snippet 32.5
shows an example for this implementation.
Code Snippet 32.5 Session Structure
TYPE struct_SessionInfo :
STRUCT
// There is a connected session stored here.
Active : BOOL := FALSE;
// The Handle for this session.
Handle : SESSION_HANDLE := RTS_INVALID_HANDLE;
// Deque containing incoming data ready for consumption.
ReceiveDeque : class_ByteDeque(0);
// Deque containing data ready to be sent to the telnet client.
SendDeque : class_ByteDeque(0);
END_STRUCT
END_VAR

Solution
Instantiate a class_TcpServer and associated data control objects as seen in Code
Snippet 32.6. Allow this program to run every task scan.

Date Code 20241023 Programming Reference


986 SELEthernetController
Examples

Verification
To verify that this solution is functional, start running the server on the RTAC
and then attach with a raw TCP connection on port 10024. Any instance of the
word "Hello" should be followed immediately by the echo "World."
Characters other than new-lines should eventually echo "Usage : Hello."
The code as written should accept as many as five concurrent sessions with more
allowed after a given session disconnects.
Code Snippet 32.6 prg_SimpleServer
PROGRAM prg_SimpleServer
VAR CONSTANT
// The maximum number of sessions allowed for this server.
_c_NumSessions : USINT := 5;
// The maximum bytes to read per scan.
_c_NumBytes : DINT := 1024;
END_VAR
VAR
// Configuration Information
// Uses any available interface.
LocalIPAddress : STRING(15) := '0.0.0.0';
LocalPortNumber : UINT := 10024;
ListenIPAddr : SELEthernetController.INADDR;

SocketInitialized : BOOL := FALSE;


TcpServer : class_TcpServer(_c_NumSessions);

Sessions : ARRAY [1 .. _c_NumSessions] of struct_SessionInfo;

Peek : STRING(5);
Reply : STRING(7) := 'World$R$N';
Reply2 : STRING(15) := 'Usage : Hello$R$N';

tempSession : SESSION_HANDLE;
sendByteCount : DINT;
numSend : DINT;
i : UDINT;
END_VAR

IF NOT SocketInitialized THEN


IF SELEthernetController.fun_StringToInaddr(LocalIPAddress, ipAddr =>
ListenIPAddr) THEN
TcpServer.bootstrap_SetLocalIP(LocalPortNumber, ListenIPAddr);
IF TcpServer.Open() THEN
SocketInitialized := TRUE;
END_IF
END_IF
ELSE
// Clean up any session that is in error.
IF TcpServer.SessionState = ERROR THEN
TcpServer.CloseSession(TRUE);
END_IF

// Accept any new sessions if possible.


FOR i := 1 TO _c_NumSessions DO
IF NOT Sessions[i].Active THEN
// There is a session object available,
// see if there is a new session pending.
tempSession := TcpServer.AcceptNextSession();
IF tempSession <> RTS_INVALID_HANDLE THEN
Sessions[i].Handle := tempSession;
Sessions[i].Active := TRUE;
Sessions[i].SendDeque.Recycle();
Sessions[i].ReceiveDeque.Recycle();
ELSE
// There are no outstanding sessions. Stop asking.

Programming Reference Date Code 20241023


SELEthernetController 987
Examples

EXIT;
END_IF
END_IF
END_FOR

// Cycle through all current sessions and process their data.


FOR i := 1 TO _c_NumSessions DO
IF Sessions[i].Active THEN
IF TcpServer.SetSession(Sessions[i].Handle) THEN
// Read any data from the socket.
TcpServer.ReceiveToQueue(_c_NumBytes,
Sessions[i].ReceiveDeque);

// Here is where meaningful work would be added.


WHILE Sessions[i].ReceiveDeque.Size >= 5 DO
// See if the string 'SEL' appears in the front of the deque.
IF 5 = Sessions[i].ReceiveDeque.Front(ADR(Peek), 5)
THEN
IF peek = 'Hello' THEN
Sessions[i].SendDeque.PushBack(ADR(Reply), 7);
Sessions[i].ReceiveDeque.EraseFront(5);
ELSIF peek[0] <> 10 and peek[0] <> 13 THEN
// The string wasn't found, erase the first
// character and continue looking.
Sessions[i].SendDeque.PushBack(ADR(Reply2),
15);
Sessions[i].ReceiveDeque.EraseFront(1);
ELSE
Sessions[i].ReceiveDeque.EraseFront(1);
END_IF
ELSE
EXIT;
END_IF
END_WHILE

TcpServer.SendQueuedData(Sessions[i].SendDeque);

// If the session closed while working with it, clean up.


IF TcpServer.SessionState = CLOSED THEN
Sessions[i].Handle := RTS_INVALID_HANDLE;
Sessions[i].Active := FALSE;
END_IF
ELSE
// If the session closed while doing other work, clean up.
Sessions[i].Handle := RTS_INVALID_HANDLE;
Sessions[i].Active := FALSE;
END_IF
END_IF
END_FOR
END_IF

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 3 3

SELRand
Introduction
The SELRand library contains a set of functions that return pseudo-random
numbers for testing and other non-cryptographic purposes. A pseudo-random
number generator is a math function that takes advantage of its previous result
and large number manipulations to perform operations that are not immediately
predictable. The beginning value for each use of the sequence is called the seed.
Generally, the seed is created from some measurement expected to have a wide
range of variance. Commonly, this can be noise on a wire, small units of time,
quantity and value of user input, or some other equally unpredictable quantity.
Pseudo-random number generators do tend to be cyclic in nature, but they can
have very large cycle times and excellent distribution.

These functions are not intended to be used for implementing any security
feature.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.0.0 and earlier can be used on RTAC firmware version R132 and
later.

Functions
fun_Rand (Function)
This function randomly seeds itself and returns a pseudo-random number in the
range of 0 inclusive to 232 exclusive.

Return Value
IEC 61131 Type Description

UDINT A random number between 0 inclusive to 232 exclusive.

Processing
At the first call of this function, it randomly seeds itself. It will continually
return pseudorandom values with each use.

Date Code 20241023 Programming Reference


990 SELRand
Functions

fun_RandRepeatable (Function)
This function always seeds itself with the same value and returns a pseudo-
random number in the range of 0 inclusive to 232 exclusive.

Return Value
IEC 61131 Type Description

UDINT A random number between 0 inclusive to 232 exclusive.

Processing
At the first call of this function, it seeds itself, always with the same value. It
then returns the same sequence of pseudo-random values with each use.

fun_RandRanged (Function)
This function randomly seeds itself and returns a pseudo-random number
between minimum to maximum, inclusive.

Inputs
Name IEC 61131 Type Description

minimum UDINT The lower limit of the return value.

maximum UDINT The upper limit of the return value.

Return Value
IEC 61131 Type Description

UDINT A random number between minimum and maximum, inclusive.

Processing
At the first call of this function, randomly seeds itself. It then continually returns
pseudorandom values within the requested range.

fun_RandRangedRepeatable (Function)
This function always seeds itself with the same value and subsequently returns a
pseudorandom number between minimum to maximum, inclusive.

Inputs
Name IEC 61131 Type Description

minimum UDINT The lower limit of the return value.

maximum UDINT The upper limit of the return value.

Programming Reference Date Code 20241023


SELRand 991
Benchmarks

Return Value
IEC 61131 Type Description

UDINT A random number between minimum and maximum, inclusive.

Processing
At the first call of function, it seeds itself, always with the same value. It then
continually returns the same sequence of pseudo-random values within the
requested range.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3530
➢ R134-V0 firmware
➤ SEL-3354
➢ Intel Pentium 1.4 GHz
➢ 1 GB DDR ECC SDRAM
➢ SEL-3532 RTAC Conversion Kit
➢ R132-V0 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V0 firmware

Benchmark Test Descriptions


All benchmark tests are based on an average of 100 calls to the function.

fun_Rand()
The posted time is the average execution time of 100 consecutive calls.

fun_RandRanged()
The posted time is the average execution time of 100 consecutive calls with a
range of 1 to 100.

fun_RandRepeatable()
The posted time is the average execution time of 100 consecutive calls.

Date Code 20241023 Programming Reference


992 SELRand
Examples

fun_RandRangedRepeatable()
The posted time is the average execution time of 100 consecutive calls with a
range of 1 to 100.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3530 SEL-3354 SEL-3555

fun_Rand() 1 1 1

fun_RandRanged() 2 1 1

fun_RandRepeatable() 1 1 1

fun_RandRangedRepeatable() 1 1 1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Getting a Random Integer Between 10 and 50


Objective
A user knows the input for a function will vary between 10 and 50 and would
like to demonstrate the behavior of a function in a non-linear progression.

Assumptions
This example assumes that there is a user specified IEC 61131 function that is
defined as shown in Code Snippet 33.1.
Code Snippet 33.1 fun_SomeFunction
FUNCTION fun_SomeFunction :REAL
VAR_INPUT
num : UDINT;
END_VAR

Programming Reference Date Code 20241023


SELRand 993
Examples

Solution
The user can create the program in Code Snippet 33.2 to run the function 1000
times with assorted input.
Code Snippet 33.2 prg_RandomWalk
PROGRAM prg_RandomWalk
VAR
i : UDINT;
results : ARRAY [1 .. 1000] OF REAL;
randomNum : UDINT;
END_VAR

FOR i := 1 to 1000 DO
//This gives a random number from 10 to 50;
randomNum := fun_RandRanged(10, 51);
//Call the function with the random number
results[i] := fun_SomeFunction(randomNum);
END_FOR

Testing With Assorted Input


Objective
A user wants to vary inputs for testing but would like to be able to recreate the
inputs in case something goes wrong.

Assumptions
This example assumes that there is a user-specified IEC 61131 function that is
defined as shown in Code Snippet 33.3.
Code Snippet 33.3 fun_TestFunction
FUNCTION fun_TestFunction :REAL
VAR_INPUT
num : UDINT;
END_VAR

Solution
The user can create the program in Code Snippet 33.4 to run the function 1000
times with assorted input but a set order.
Code Snippet 33.4 prg_RandomTest
PROGRAM prg_RandomTest
VAR
i : UDINT;
results : ARRAY [1 .. 1000] OF REAL;
randomNum : UDINT;
END_VAR

FOR i := 1 TO 1000 DO
//This gives a random number;
randomNum := fun_RandRepeatable();
//Call the function with the random number
results[i] := fun_TestFunction(randomNum);
END_FOR

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 3 4

SELServerSimulators
Introduction
This library provides simulators for various SEL devices using the SEL Fast
Meter protocol. Since this library is primarily a testing and debugging tool,
not all commands may be supported for a particular device. There may also be
variances in the responses generated when compared to the real device.

Special Considerations
Classes in this library have memory allocated inside them. As such, they should
only be created in environments of permanent scope (e.g., Programs, Global
Variable Lists, or VAR_STAT sections).

Copying classes from this library causes unwanted behavior. This means the
following:

1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_Object"
myObject := otherObject;

// This is fine
someVariable := myObject.value;
// As is this
pt_myObject := ADR(myObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.

Supported Devices
This library contains simulators for the following devices:

➤ SEL-351

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Version 3.5.0.1 can be used on RTAC firmware version R132 and later.

Date Code 20241023 Programming Reference


996 SELServerSimulators
Enumerations

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_PointType
This enumeration defines all possible point types for a relay.

Enumeration Description

DIGITAL A digital (Boolean) point.

INT16 An analog point stored as a 16-bit integer value.

FLOAT32 An analog point stored as a 32-bit floating-point value.

FLOAT64 An analog point stored as a 64-bit floating-point value.

STRING80 A point stored as a string of as many as 80 characters.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Because of the significant number of values in these structures, this document


does not provide a complete list of the values.

struct_SEL351_Analog
This structure defines the analog points available on an SEL-351. For example,
this structure might contain the following:

Name IEC 61131 Type Description

_FREQ class_SELServerFloat32 System frequency

_IA class_SELServerFloat32 Phase A current magnitude

_IB class_SELServerFloat32 Phase B current magnitude

_IC class_SELServerFloat32 Phase C current magnitude

struct_SEL351_Binary
This structure defines the digital points available on an SEL-351.

struct_SEL351_Strings
This structure defines the string points available on an SEL-351.

Programming Reference Date Code 20241023


SELServerSimulators 997
Interfaces

Interfaces
I_Session
This interface defines a set of methods for interacting with a client session. A
session is a generic object that allows for reading and writing of bytes.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Active BOOL R TRUE if the session is active and able to send


and receive bytes.

Echo BOOL R TRUE if the session is expecting ASCII


characters sent to the server to be echoed back.

Close (Method)
Closes the session to the client.

Inputs

Name IEC 61131 Type Description

forceClose BOOL Close the session without waiting for confirmation.

ReadData (Method)
Read data from the client.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE Pointer to where the incoming data are written.

numBytes UDINT The maximum number of bytes to read.

Return Value

IEC 61131 Type Description

UDINT The number of bytes read from the session.

WriteData (Method)
Write data to the client.

Date Code 20241023 Programming Reference


998 SELServerSimulators
Interfaces

Inputs
Name IEC 61131 Type Description

pt_source POINTER TO BYTE Pointer from where the outgoing data are read.

numBytes UDINT The number of bytes to read from pt_source and


write to the session.

Return Value
IEC 61131 Type Description

UDINT The number of bytes written to the session.

I_SessionManager
This interface defines a set of methods for an object that is able to manage
multiple I_SessionProvider objects and their sessions.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

numSessions UDINT R The total number of sessions managed


by this object.

AddSessionProvider (Method)
Adds an I_SessionProvider to this session manager.

Inputs
Name IEC 61131 Type Description

sessionProvider I_SessionProvider The object that is providing sessions to be


managed.

Return Value
IEC 61131 Type Description

BOOL TRUE if the session provider was successfully added to the session
manager. FALSE if an error occurred.

NextSession (Method)
Iterates over all I_Session objects referenced within the session manager and
returns the next session.

Programming Reference Date Code 20241023


SELServerSimulators 999
Interfaces

Return Value
IEC 61131 Type Description

I_Session Reference to the next session object.

Run (Method)
This method processes all session activity and must be called once per scan.

I_SessionProvider
This interface defines a set of methods for an object that can provide I_Session
objects to an I_SessionManager object.

GetSessions (Method)
Provides pointers to all I_Session objects available from this provider.

Inputs/Outputs
Name IEC 61131 Type Description

sessionVector class_PointerVector All I_Session references in the session provider


are written to this vector.

Run (Method)
This method processes all session activity and must be called once per scan.

I_SELServerPoint
This interface defines common methods for all analog and digital points.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

PointName STRING R The name of the point.

PointType enum_PointType R The type of the point.

stValAsString STRING R The point value as a string.

I_SELServerAnalogPoint
This interface defines common methods unique to analog points. This interface
extends I_SELServerPoint.

Date Code 20241023 Programming Reference


1000 SELServerSimulators
Classes

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

ChannelType BYTE R The channel type of the point.

ScaleFactorOffset WORD R The scale factor offset of the point.

ScaleFactorType BYTE R The scale factor type of the point.

stValAsInt INT R The point value as an integer.

stValAsLreal LREAL R The point value as a long real.

stValAsReal REAL R The point value as a real.

Classes
class_TelnetServer
This object implements a Telnet server. This server will create and manage
an internal object for each Telnet session. These internal objects implement
I_Session and can be accessed via the I_SessionProvider interface. This server is
not intended to be used as a generic Telnet server and should only be used within
the context of this library.
This Telnet server automatically attempts to negotiate the following Telnet
features:

➤ Binary Transmission
➤ Suppress Go Ahead
➤ Echo
No other Telnet features are supported.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_SessionProvider

Initialization Inputs
Name IEC 61131 Type Description

listenIP STRING(15) The local IP address for the server to listen on. Set
to 0.0.0.0 to listen on all available interfaces.

listenPort UINT The local port number on which the server listens.

numSessions USINT The maximum number of Telnet sessions to


support.

Programming Reference Date Code 20241023


SELServerSimulators 1001
Classes

Destroy (Method)
This method deallocates all memory allocated by this object. This method must
be called before the object goes out of scope, otherwise a memory leak will
result.

Return Value
IEC 61131 Type Description

BOOL TRUE if all memory was successfully deallocated.

class_SELServerInt16
This class defines an analog point represented as a 16-bit integer value.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_SELServerAnalogPoint

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

stVal INT R/W The value of the point.

Initialize (Method)
This method initializes the point.

Inputs
Name IEC 61131 Type Description

pointName STRING The name of the point.

initialStVal REAL The initial stVal of the point.

scaleFactorType BYTE The scale factor type for the point.

scaleFactorOffset WORD The scale factor offset for the point.

class_SELServerFloat32
This class defines an analog point represented as a 32-bit floating point value.

Date Code 20241023 Programming Reference


1002 SELServerSimulators
Classes

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_SELServerAnalogPoint

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

stVal REAL R/W The value of the point.

Initialize (Method)
This method initializes the point.

Inputs
Name IEC 61131 Type Description

pointName STRING The name of the point.

initialStVal INT The initial stVal of the point.

scaleFactorType BYTE The scale factor type for the point.

scaleFactorOffset WORD The scale factor offset for the point.

class_SELServerFloat64
This class defines an analog point represented as a 64-bit floating point value.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_SELServerAnalogPoint

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

stVal LREAL R/W The value of the point.

Programming Reference Date Code 20241023


SELServerSimulators 1003
Classes

Initialize (Method)
This method initializes the point.

Inputs
Name IEC 61131 Type Description

pointName STRING The name of the point.

initialStVal LREAL The initial stVal of the point.

scaleFactorType BYTE The scale factor type for the point.

scaleFactorOffset WORD The scale factor offset for the point.

class_SELServerDigital
This class defines a digital point.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.
➤ I_SELServerPoint

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

stVal BOOL R/W The value of the point.

Initialize (Method)
This method initializes the point.

Inputs
Name IEC 61131 Type Description

pointName STRING The name of the point.

initialStVal INT The initial stVal of the point.

index UINT The index value for the digital point. This is used for determining the order of the Relay Word
bits. The index is zero for the MSB in Row 0, 8 for the MSB in Row 1, etc.

class_SELServerString
This class defines a point represented as a string.

Date Code 20241023 Programming Reference


1004 SELServerSimulators
Classes

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ I_SELServerPoint

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

stVal STRING R/W The value of the point.

Initialize (Method)
This method initializes the point.

Inputs

Name IEC 61131 Type Description

pointName STRING The name of the point.

initialStVal STRING The initial stVal of the point.

class_SEL351ServerSimulator
This class implements a server simulating an SEL-351 relay with firmware
version R515. The following ASCII commands are supported:

➤ 2AC ➤ CAL ➤ CHI ➤ ID


➤ ACC ➤ CAS ➤ DNA ➤ QUIT
➤ BNA ➤ CEV ➤ EXIT ➤ SNS

The following binary commands are supported:

➤ A546 ➤ A5C1 ➤ A5CD ➤ A5D2


➤ A5B9 ➤ A5C2 ➤ A5CE ➤ A5D3
➤ A5C0 ➤ A5C3 ➤ A5D1

Some commands have optional parameters that may not be supported by the
simulator.

Programming Reference Date Code 20241023


SELServerSimulators 1005
Classes

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

RefNum UINT R/W The reference number for the next event.
This value will be incremented by the
simulator each time an event is created.

Input
Inputs

Name IEC 61131 Type Description

Analog struct_SEL351_Analog Analog points for an SEL-351.

Binary struct_SEL351_Binary Relay Word bits for an SEL-351.

Strings struct_SEL351_String Strings for an SEL-351.

Outputs

Name IEC 61131 Type Description

ENO BOOL TRUE if the simulator is initialized and enabled. FALSE


if initialization failed or an error occurred during runtime.

bootstrap_AddSessionManager
This method assigns the session manager that will manage all I_Session objects
for this simulator. This method assumes that the session manager already
contains all desired sessions. Once a session manager is added here, more
session providers should not be added to the session manager.

Inputs

Name IEC 61131 Type Description

sessionManager I_SessionManager The session manager containing I_Session objects


for the simulator.

CreateEvent (Method)
This method creates a new event within the simulator. When the event is created,
it will be automatically assigned the next available record number. The event
created by this method will contain four samples per cycle. The analog values,
Relay Word bit values, and relay settings will consist of internal hard-coded
values and will not match the values already set in the simulator.

Date Code 20241023 Programming Reference


1006 SELServerSimulators
Classes

Inputs

Name IEC 61131 Type Description

refNum UINT Reference number of the event

event STRING(8) Type of event

location REAL Location of the fault

current UINT Peak current detected during the fault

group USINT Group number

shot UINT Number of reclose events

targets STRING Target elements for the event

Return Value

IEC 61131 Type Description

BOOL TRUE if the event was successfully created.

DeleteEvent (Method)
This method deletes an event from the simulator that was created with
CreateEvent().

Inputs

Name IEC 61131 Type Description

recNum UINT The record number for the event as provided by the
CHI command.

Return Value

IEC 61131 Type Description

BOOL TRUE if the event was successfully deleted. FALSE if the event did
not exist or an error occurred.

Destroy (Method)
This method deallocates all memory allocated by this object. This method must
be called before the object goes out of scope; otherwise, a memory leak will
result.

Return Value

IEC 61131 Type Description

BOOL TRUE if all memory was successfully deallocated.

Programming Reference Date Code 20241023


SELServerSimulators 1007
Examples

Run (Method)
This method handles processing communication between the server and all
connected clients. This method must be called once per scan.

Processing
The Run() method does the following:

➤ Reads any pending requests from clients.


➤ If a valid command is received, the applicable response is generated and
sent to the client.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Simulating an SEL-351
Objective
This example creates a simulator for an SEL-351 Relay on an RTAC. Changing
analog and digital values is also demonstrated.

Assumptions
This example assumes that an Access Point has been defined for TCP Port 23
on the RTAC. This is necessary for the simulator to communicate via Telnet to
other RTACs or to a user's interactive Telnet session.

Solution
The program shown in Code Snippet 34.1 shows a minimal example of running
a simulator of the SEL-351. This example instantiates a Telnet server that can
handle as many as ten simultaneous connections. On the first scan, the system
frequency of the simulator is set to 60 Hz and the daylight-saving time Relay
Word bit is set to TRUE.
Code Snippet 34.1 prg_SEL351
PROGRAM prg_SEL351
VAR
// Create a Telnet server. The server will bind to any available IP address. The server
// will listen on port 23 and allow up to 10 simultaneous connections.
TelnetServer : class_TelnetServer('0.0.0.0', 23, 10);
// Create the session manager for the simulator.
SessionManager : class_SessionManager();
// The SEL-351 simulator object.
Sel351 : class_SEL351ServerSimulator();

Date Code 20241023 Programming Reference


1008 SELServerSimulators
Examples

FirstScan : BOOL := TRUE;


END_VAR

IF FirstScan then
// Add the Telnet server as a session provider to the session manager.
SessionManager.AddSessionProvider(TelnetServer);
// Add the session manager to the SEL-351 simulator.
Sel351.bootstrap_AddSessionManager(SessionManager);
// Set the simulator frequency to 60 Hz.
Sel351.Analog._FREQ.stVal := 60;
// Set the daylight saving time Relay Word bit to true.
Sel351.Binary._DST.stVal := TRUE;
FirstScan := FALSE;
END_IF

// Process communication on each scan.


Sel351.Run();

Simulating Multiple SEL-351 Relays


Objective
This example creates two simulators for SEL-351 Relays on a single RTAC.

Assumptions
This example assumes that an Access Point has been defined for TCP Port 23
on the RTAC. This is necessary for the simulators to communicate via Telnet
to other RTACs or to a user's interactive Telnet session. For this example, it is
necessary to use two network interfaces on the RTAC, one with the IP address
192.168.0.100 and the other with 192.168.1.100.

Solution
The program shown in Code Snippet 34.2 shows an example of running two
distinct SEL-351 simulators on the same RTAC. One simulator listens on the
network interface with the IP address 192.168.0.100 and the other listens on the
second interface with address 192.168.1.100.
Code Snippet 34.2 prg_SEL351
PROGRAM prg_SEL351
VAR
// Create a Telnet server for each relay. Each server binds to a specific IP address.
// Both servers listen on port 23 and allow up to 10 simultaneous connections.
TelnetServer1 : class_TelnetServer('192.168.0.100', 23, 10);
TelnetServer2 : class_TelnetServer('192.168.1.100', 23, 10);
// Create a session manager for each simulator.
SessionManager1 : class_SessionManager();
SessionManager2 : class_SessionManager();
// The SEL-351 simulator objects.
Sel351_1 : class_SEL351ServerSimulator();
Sel351_2 : class_SEL351ServerSimulator();
FirstScan : BOOL := TRUE;
END_VAR

IF FirstScan then
// Add a Telnet server as a session provider to the respective session manager.
SessionManager1.AddSessionProvider(TelnetServer1);
SessionManager2.AddSessionProvider(TelnetServer2);
// Add the respective session manager to the SEL-351 simulator.
Sel351_1.bootstrap_AddSessionManager(SessionManager1);

Programming Reference Date Code 20241023


SELServerSimulators 1009
Examples

Sel351_2.bootstrap_AddSessionManager(SessionManager2);
// Set the first simulator frequency to 60 Hz.
Sel351_1.Analog._FREQ.stVal := 60;
// Set the second simulator frequency to 50 Hz.
Sel351_2.Analog._FREQ.stVal := 50;
FirstScan := FALSE;
END_IF

// Process communication on each scan.


Sel351_1.Run();
Sel351_2.Run();

Simulating an SEL-351 on Multiple Ports


Objective
This example creates a simulator for an SEL-351 relay on an RTAC that listens
on multiple network ports.

Assumptions
This example assumes that an Access Point has been defined for TCP Ports 23
and 8023 on the RTAC. This is necessary for the simulator to communicate via
Telnet to other RTACs or to a user's interactive Telnet session.

Solution
The program shown in Code Snippet 34.3 shows an example of running a
simulator of the SEL-351 that listens on Ports 23 and 8023. This example
instantiates two Telnet servers, one on each port, that can handle as many as ten
simultaneous connections each. Connections to these simulators will be allowed
on all network interfaces.
Code Snippet 34.3 prg_SEL351
PROGRAM prg_SEL351
VAR
// Create a Telnet server. The server will bind to any available IP address. The server
// will listen on port 23 and allow up to 10 simultaneous connections. Connections will
// be accepted on all interfaces due to the 0.0.0.0 IP address.
TelnetServer1 : class_TelnetServer('0.0.0.0', 23, 10);
// Create another server to listen on port 8023.
TelnetServer2 : class_TelnetServer('0.0.0.0', 8023, 10);
// Create the session manager for the simulator.
SessionManager : class_SessionManager();
// The SEL-351 simulator object.
Sel351 : class_SEL351ServerSimulator();
FirstScan : BOOL := TRUE;
END_VAR

IF FirstScan then
// Add both Telnet servers as session providers to the session manager.
SessionManager.AddSessionProvider(TelnetServer1);
SessionManager.AddSessionProvider(TelnetServer2);
// Add the session manager to the SEL-351 simulator.
Sel351.bootstrap_AddSessionManager(sessionManager);
FirstScan := FALSE;
END_IF

// Process communication on each scan.


Sel351.Run();

Date Code 20241023 Programming Reference


1010 SELServerSimulators
Examples

Creating Events on an SEL-351 Simulator


Objective
This example creates a simulator and an event for an SEL-351 Relay on an
RTAC. After adding an event, it can be viewed by issuing a CHI or CEV
command via Telnet.

Assumptions
This example assumes that an Access Point has been defined for TCP Port 23
on the RTAC. This is necessary for the simulator to communicate via Telnet to
other RTACs or to a user's interactive Telnet session.

Solution
The program shown in Code Snippet 34.4 shows a minimal example of running
a simulator of the SEL-351 and adding an event. This example instantiates a
Telnet server that can handle as many as ten simultaneous connections. On the
first scan, an event is created. The event date and time will be set to the present
date and time of the RTAC system.
Code Snippet 34.4 prg_SEL351
PROGRAM prg_SEL351
VAR
// Create a Telnet server. The server will bind to any available IP address. The server
// will listen on port 23 and allow up to 10 simultaneous connections.
TelnetServer : class_TelnetServer('0.0.0.0', 23, 10);
// Create the session manager for the simulator.
SessionManager : class_SessionManager();
// The SEL-351 simulator object.
Sel351 : class_SEL351ServerSimulator();
FirstScan : BOOL := TRUE;
END_VAR

IF FirstScan then
// Add the Telnet server as a session provider to the session manager.
SessionManager.AddSessionProvider(TelnetServer);
// Add the session manager to the SEL-351 simulator.
Sel351.bootstrap_AddSessionManager(SessionManager);
// Add an event to the simulator. The reference number is 1, type is TRIG, location of
// zero, maximum current of zero, group 1, shot 1, and no targets. Other event values
// are set automatically.
Sel351.CreateEvent(1, 'TRIG', 0, 0, 1, 1, '');
FirstScan := FALSE;
END_IF

// Process communication on each scan.


Sel351.Run();

Programming Reference Date Code 20241023


S E C T I O N 3 5

SELString
Introduction
The purpose of this library is to provide a single object for performing string
manipulations. It is intended to allow for a variety of string manipulations
without requiring lengths to be predefined.
References to ASCII characters within this document are given in base-10.
Whitespace for the scope of this document includes the following: spaces (32),
tabs (9), newlines (10), and carriage returns (13). Invalid Characters are any
characters that fall in the ASCII range 0–8, 11, 12, 14–27, or ≥127.
This document refers to iterator methods in a state called locked out. This refers
to the state of the object being such that the user cannot retrieve non-NULL(0)
values from Next() or Previous() without a new call to Begin(), End(), or
Position().

Special Considerations
Classes in this library have memory allocated inside them. As such, they should
only be created in environments of permanent scope (e.g., Programs, Global
Variable Lists, or VAR_STAT sections).
Copying classes from this library causes unwanted behavior. This means the
following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_SELStringObject"
mySELStringObject := otherSELStringObject;

// This is fine
someVariable := mySELStringObject.value;
// As is this
pt_mySELStringObject := ADR(mySELStringObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.
This library can return NULL(0) pointers. Any pointer returned by the
library should be validated to be non-NULL(0) before use, as shown in Code
Snippet 35.5.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Date Code 20241023 Programming Reference


1012 SELString
Global Parameters

Versions 3.5.0.3 and earlier can be used on RTAC firmware version R132 and
later.

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_p_MaxIec61131StringSize UDINT 255 The largest size IEC 61131 string that this library can
convert from/to.

g_p_SELStringInitialSize UDINT 80 The number of bytes to initially allocate for a


class_SELString.

g_p_SELStringListInitialSize UDINT 16 The number of entries to initially allocate for a


class_SELStringList.

Functions
fun_SELString_IsValidChar (Function)
This function takes a character in the form of a BYTE and returns TRUE if it is
a valid printable character; otherwise, this function returns FALSE.

Inputs
Name IEC 61131 Type Description

character BYTE Byte to be evaluated as a printable character.

Return Value
IEC 61131 Type Description

BOOL TRUE if character is a valid printable character.

Processing
If character is an invalid character, this function returns FALSE; otherwise, this
function returns TRUE.

fun_SELString_IsWhitespace (Function)
This function takes a character in the form of a BYTE and returns TRUE if it is
a whitespace character; otherwise, this function returns FALSE.

Inputs
Name IEC 61131 Type Description

character BYTE Character to be evaluated for being whitespace.

Programming Reference Date Code 20241023


SELString 1013
Functions

Return Value
IEC 61131 Type Description

BOOL TRUE if character is a whitespace character.

Processing
➤ If character is a whitespace character, this function returns TRUE;
otherwise, this function returns FALSE.

fun_ByteIsAlpha (Function)
This function determines whether an input byte is an alphabetic character (i.e.,
A–Z or a–z).

Inputs
Name IEC 61131 Type Description

Input BYTE Byte to be tested as an alphabetic character.

Return Value
IEC 61131 Type Description

BOOL TRUE if Input is an alphabetic character.

Example in Structured Text:


Result := fun_ByteIsAlpha(TO_BYTE(16#A)); // Newline character; Result
is FALSE
Result := fun_ByteIsAlpha(TO_BYTE(16#30)); // '0'; Result is FALSE
Result := fun_ByteIsAlpha(TO_BYTE(16#41)); // 'A'; Result is TRUE

Processing
The fun_ByteIsAlpha function performs the following action:
➤ If the decimal representation of Input is within the ASCII ranges ([65–
90] and [97–122]) for alphabetic characters, the function returns TRUE.
Anything outside that range, returns FALSE.

fun_ByteIsNumeric (Function)
This function determines whether an input byte is a numeric character (i.e., 0–9).

Inputs
Name IEC 61131 Type Description

Input BYTE Byte to be tested as a numeric character.

Date Code 20241023 Programming Reference


1014 SELString
Functions

Return Value
IEC 61131 Type Description

BOOL TRUE if Input is a numeric character.

Example in Structured Text:

Result := fun_ByteIsNumeric(TO_BYTE(16#A)); // Newline character;


Result is FALSE

Result := fun_ByteIsNumeric(TO_BYTE(16#30)); // '0'; Result is TRUE

Result := fun_ByteIsNumeric(TO_BYTE(16#41)); // 'A'; Result is FALSE

Processing
The fun_ByteIsNumeric function performs the following action:

➤ If the decimal representation of Input is within the ASCII ranges for


numeric characters [48–57], function returns TRUE. If the decimal
representation is anything outside that range, returns FALSE.

fun_ByteIsAlphaNumeric (Function)
This function determines whether an input byte is an alphanumeric character
(i.e., A–Z, a–z, or 0–9).

Inputs
Name IEC 61131 Type Description

Input BYTE Byte to be tested as an alphanumeric character.

Return Value
IEC 61131 Type Description

BOOL TRUE if Input is an alphabetic or numeric character.

Example in Structured Text:

Result := fun_ByteIsAlphaNumeric(TO_BYTE(16#A)); // Newline


character; Result is FALSE

Result := fun_ByteIsAlphaNumeric(TO_BYTE(16#30)); // '0'; Result is


TRUE

Result := fun_ByteIsAlphaNumeric(TO_BYTE(16#41)); // 'A'; Result is


TRUE

Programming Reference Date Code 20241023


SELString 1015
Functions

Processing
The fun_ByteIsAlphaNumeric function performs the following action:

➤ If the decimal representation of Input is within the ASCII ranges for


alphabetic and numeric characters ([48–90], [65–90], and [97–122]),
returns TRUE. If the decimal representation is anything outside that
range, returns FALSE.

fun_LowercaseByte (Function)
This function returns the input byte as its lowercase equivalent if the input is an
alphabetic character (i.e., A–Z).

Inputs
Name IEC 61131 Type Description

Input BYTE The byte to be cast to lowercase if applicable.

Return Value
IEC 61131 Type Description

BYTE The byte in lowercase if applicable.

Example in Structured Text:

Result := fun_LowercaseByte(TO_BYTE('A')); // Result is 'a'

Result := fun_LowercaseByte(TO_BYTE('a')); // Result is 'a'

Processing
The fun_LowercaseByte function performs the following action:

➤ If Input is a valid uppercase character, it is cast to lowercase.


➤ Lowercase or numeric characters remain unchanged.
➤ Non-printable characters and non-alphanumeric characters remain
unchanged.

fun_UppercaseByte (Function)
This function returns the input byte as its uppercase equivalent if the input is an
alphabetic character (i.e., a–z).

Inputs
Name IEC 61131 Type Description

Input BYTE The byte to be cast to uppercase if applicable.

Date Code 20241023 Programming Reference


1016 SELString
Classes

Return Value
IEC 61131 Type Description

BYTE The byte in uppercase if applicable.

Example in Structured Text:


Result := fun_UppercaseByte(TO_BYTE('A')); // Result is 'A'
Result := fun_UppercaseByte(TO_BYTE('a')); // Result is 'A'

Processing
The fun_UppercaseByte function performs the following action:

➤ If Input is a valid lowercase character, it is cast to uppercase.


➤ Uppercase or numeric characters remain unchanged.
➤ Non-printable characters and non-alphanumeric characters remain
unchanged.

Classes
class_SELString (Class)
class_SELString exists as the single class required to perform string
manipulations. This class maintains a sequence of characters and is initialized to
an empty set of characters.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

pt_First POINTER TO BYTE R Obtains a pointer to the first character in


the class_SELString.

Size UDINT R The number of characters in this


class_SELString.

FromString (Method)
This method takes an IEC 61131 string, str, as an input to be stored within the
class_SELString.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(g_p_MaxIec61131StringSize) The IEC 61131 string to be


stored and manipulated within
the SELString.

Programming Reference Date Code 20241023


SELString 1017
Classes

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The FromString method performs the following actions:

➤ Accepts any valid IEC 61131 string up to g_p_MaxIec61131StringSize


characters in size.
➤ Accepts all characters from the beginning of str until an invalid character,
an end-of-string character, or g_p_MaxIec61131StringSize characters are
reached; and no following characters.
➤ Replaces all current characters within class_SELString with characters
from str.
➤ Populates all available characters with the leading characters in str if the
library runs out of memory. In this case, this method returns a pointer to
an error string.
➤ Returns 0 on success.

FromByteArray (Method)
This method takes a pointer to the beginning of a byte array and the number
of bytes to be copied. It then stores the byte array within the class_SELString
object. This method stores any values represented in the byte array—it does not
check for valid characters.

Inputs
Name IEC 61131 Type Description

pt_byteArray POINTER TO BYTE The address returned by calling ADR() on the


byte array to copy data from.

numBytes UDINT The number of bytes to be copied from the byte


array.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The FromByteArray method performs the following actions:

➤ Accepts all characters from the beginning of pt_byteArray until numBytes


bytes.
➤ Replaces all current characters within this class_SELString with bytes
from pt_byteArray.

Date Code 20241023 Programming Reference


1018 SELString
Classes

➤ Populates all available characters with the leading bytes in pt_byteArray


if the library runs out of memory and returns a pointer to an applicable
error string.
➤ Returns 0 on success.

CopyTo (Method)
This method copies the contents of this object into the class_SELString provided
by the user. Both the input and this class_SELString will contain duplicate
contents following this method call.

Inputs/Outputs

Name IEC 61131 Type Description

str class_SELString The class_SELString to which this object's contents


will be copied.

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The CopyTo method performs the following actions:

➤ Replaces all current characters within the class_SELString specified str


with the contents of this class_SELString.
➤ Populates as many characters as possible in str with the content of this
class_SELString if the library runs out of memory and returns a pointer to
an applicable error string.
➤ Returns 0 on success.

ToString (Method)
This method outputs an IEC 61131 string representation of the data being stored
within the SELString.

Return Value

IEC 61131 Type Description

STRING(g_p_MaxIec61131StringSize) An IEC 61131 string equivalent of the data


stored within the SELString.

Programming Reference Date Code 20241023


SELString 1019
Classes

Processing
The ToString method performs the following actions:

➤ Returns an IEC 61131 string, up to g_p_MaxIec61131StringSize


characters in size, that represents the first g_p_MaxIec61131StringSize
characters of this class_SELString.
➤ If nothing has been assigned to this class_SELString, then the return
value is an empty IEC 61131 string.
➤ The character immediately following the last character inserted into the
IEC 61131 string is a string terminator character.

ToByteArray (Method)
This method copies the contents of the class_SELString to the address provided.
It stops copying once maxBytes is reached or the class_SELString is completely
copied.

Inputs

Name IEC 61131 Type Description

pt_destination POINTER TO BYTE The destination to which the content is copied.

maxBytes UDINT The maximum number of bytes to copy.

Return Value

IEC 61131 Type Description

UDINT The number of bytes successfully copied to the destination.

Processing
The ToByteArray method performs the following actions:

➤ Writes the contents of the class_SELString to the address provided.


➤ Copying stops when one of the following occurs:
1. The number of bytes copied is equal to maxBytes.
2. All bytes in the class_SELString have been copied.
➤ The number of bytes copied before encountering one of the above criteria
is returned as an integer. This will be 0 if class_SELString is empty or
maxBytes is 0.
➤ No termination byte is appended.

Replace (Method)
This method replaces every occurrence of the string before with the string after.

Date Code 20241023 Programming Reference


1020 SELString
Classes

Inputs/Outputs
Name IEC 61131 Type Description

before class_SELString The class_SELString containing the combination of


characters to be replaced.

after class_SELString The class_SELString containing the combination of


characters that will replace all characters of before.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The Replace method performs the following actions:

➤ Does not modify before or after.


➤ Is case sensitive.
➤ Replaces all occurrences of before with after in a single pass. This
prevents an infinite loop in cases like before="abc" and after="abcabc"
and produces a reliable output in cases like before="abcbcbef" and
after="bcb".
➤ If before or after is this object, then this method leaves all objects
unchanged. It then returns a pointer to an applicable IEC 61131 error
string.
➤ If the library runs out of memory, this method exits immediately in an
undefined state. It returns a pointer to an applicable IEC 61131 error
string.
➤ Returns 0 on success.

Split (Method)
This method splits the class_SELString into multiple class_SELStrings
wherever sep occurs and places the result in a class_SELStringList.

Inputs/Outputs
Name IEC 61131 Type Description

sep class_SELString The combination of characters defining where the


string will split.

stringlist class_SELStringList The string list to be populated.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Programming Reference Date Code 20241023


SELString 1021
Classes

Processing
The Split method performs the following actions:

➤ Creates divisions at every occurrence of sep. For example:


➢ In "tgeadadagt", using a sep of "ada" results in "tge", "dagt".
➢ In "tgeadadagt", using a sep of "ad" results in "tge", "", "agt".
➢ In "decide", using a sep of "de" results in "", "ci", "".
➤ Is case sensitive.
➤ If the class_SELString was never assigned a string or contains an empty
string, it fills stringlist with only an empty string in the first position.
➤ Erases any prior contents of stringlist.
➤ If sep does not exist in this class_SELString, it places the full
class_SELString into the first position.
➤ If sep is empty, it places each character of this class_SELString into its
own string. Example: "Hello" becomes: "H", "e", "l", "l", "o".
➤ Adds substrings to stringlist in order from left to right.
➤ Empties this class_SELString object.
➤ If sep is this object, leaves all objects unchanged. It then returns a pointer
to an applicable IEC 61131 error string.
➤ Returns a pointer to an applicable IEC 61131 error string if the
class_SELStringList specified for stringlist contains the class_SELString
to be split, or the class_SELString specified for sep.
➤ If the library runs out of memory, it assigns as many class_SELStrings
to stringlist as available, clearing itself of all characters that were
transferred. All characters not transferred to new class_SELStrings
remain in this class_SELString. It then returns a pointer to an applicable
IEC 61131 error string.
➤ Returns 0 on success.

Trim (Method)
This method removes excess whitespace from this class_SELString. In this
method, whitespace includes any character that results in TRUE being returned
from fun_SELString_IsWhitespace.

Processing
The Trim method performs the following actions:

➤ Removes all whitespace from the beginning of the string to the first non-
whitespace character.
➤ Removes all whitespace from the last non-whitespace character to the end
of the string.
➤ Replaces any number of consecutive whitespace characters with a single
space character.
➤ Leaves a class_SELStrings containing no whitespace and empty strings
unchanged.
➤ Replaces strings containing only whitespace with an empty string.

Date Code 20241023 Programming Reference


1022 SELString
Classes

Append (Method)
This method appends the input, str, onto the end of this class_SELString. The
input, str, is empty upon completion of this method.

Inputs/Outputs

Name IEC 61131 Type Description

str class_SELString The class_SELString containing the characters that


will be appended to this class_SELString.

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The Append method performs the following actions:

➤ Adds all characters from str after the last character of this
class_SELString.
➤ Removes all characters from str.
➤ If this class_SELString is empty, moves the characters from str to this
class_SELString.
➤ If str is empty, changes nothing in either class_SELString.
➤ Changes nothing if str is this object. It then returns a pointer to an
applicable IEC 61131 error string.
➤ Always appends as many characters as possible. If the library runs out
of memory, str is empty upon completion and it returns a pointer to an
applicable IEC 61131 error string.
➤ Returns 0 on success.

AppendByteArray (Method)
This method takes a pointer to the beginning of a byte array and the number
of bytes to be copied. It then stores the byte array onto the end of this
class_SELString.

Inputs

Name IEC 61131 Type Description

pt_byteArray POINTER TO BYTE The address returned by calling ADR() on the


byte array to copy data from.

numBytes UDINT The number of bytes to copy from the byte array.

Programming Reference Date Code 20241023


SELString 1023
Classes

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The AppendByteArray method performs the following actions:

➤ Adds numBytes characters from pt_byteArray after the last character of


this class_SELString.
➤ If this class_SELString is empty, adds numBytes characters from
pt_byteArray to this class_SELString.
➤ If numBytes is 0, changes nothing in this class_SELString.
➤ Always appends as many characters as possible. If the library runs out of
memory, it returns a pointer to an applicable IEC 61131 error string.
➤ Returns 0 on success.

AppendString (Method)
This method appends the characters of the input, str, onto the end of this
class_SELString.

Inputs/Outputs

Name IEC 61131 Type Description

str STRING(g_p_MaxIec61131StringSize) The IEC 61131 string containing


the characters that will be appended
to this class_SELString.

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The AppendString method performs the following actions:

➤ Adds all characters from str after the last character of this
class_SELString.
➤ If this class_SELString is empty, adds the characters from str to this
class_SELString.
➤ If str is empty, changes nothing in this class_SELString.
➤ Always appends as many characters as possible. If the library runs out of
memory, it returns a pointer to an applicable IEC 61131 error string.
➤ Returns 0 on success.

Date Code 20241023 Programming Reference


1024 SELString
Classes

Prepend (Method)
This method prepends the input, str, onto the beginning of this class_SELString.
The input, str, is empty upon completion of this method.

Inputs/Outputs
Name IEC 61131 Type Description

str class_SELString The class_SELString containing the characters to be


prepended to this class_SELString.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The Prepend method performs the following actions:
➤ Adds all characters from str before the first character of this
class_SELString.
➤ Removes all characters from str.
➤ If this class_SELString is empty, moves the characters from str to this
class_SELString.
➤ If str is empty, changes nothing in either class_SELString.
➤ Changes nothing if str is this object. It then returns a pointer to an
applicable IEC 61131 error string.
➤ If the library runs out of memory, leaves all objects unchanged and
returns a pointer to an applicable IEC 61131 error string.
➤ Returns 0 on success.

PrependString (Method)
This method prepends the characters of the input, str, to the beginning of this
class_SELString.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(g_p_MaxIec61131StringSize) The IEC 61131 string containing


the characters to be prepended to
this class_SELString.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Programming Reference Date Code 20241023


SELString 1025
Classes

Processing
The PrependString method performs the following actions:

➤ Adds all characters from str before the first character of this
class_SELString.
➤ If this class_SELString is empty, adds the characters from str to this
class_SELString.
➤ If str is empty, changes nothing in this class_SELString.
➤ If the library runs out of memory, leaves all objects unchanged and
returns a pointer to an applicable IEC 61131 error string.
➤ Returns 0 on success.

Insert (Method)
This method inserts the input class_SELString, str, into this class_SELString at
the index specified by the user. The input str is empty upon completion of this
method.

Inputs
Name IEC 61131 Type Description

index UDINT The index where str will be inserted.

Inputs/Outputs
Name IEC 61131 Type Description

str class_SELString The class_SELString containing the characters that


will be inserted to this class_SELString.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The Insert method performs the following actions:

➤ Inserts at index, where an index of zero corresponds to immediately


before the first character and is incremented by one for each character
thereafter.
➤ Removes all characters from str.
➤ Inserts all characters from str into this class_SELString at position index.
➤ If index is larger than the size of this class_SELString, appends str at the
end of this class_SELString.
➤ If this class_SELString is empty, moves the characters from str to this
class_SELString.

Date Code 20241023 Programming Reference


1026 SELString
Classes

➤ If str is empty, changes nothing in either class_SELString.


➤ Changes nothing if str is this object. It then returns a pointer to an
applicable IEC 61131 error string.
➤ If the library runs out of memory, places all characters of str into
this class_SELString, truncates the result, and returns a pointer to an
applicable IEC 61131 error string.
➤ Returns 0 on success.

Find (Method)
This method returns the first position after the provided index where the
character combination provided in str exists. If the character combination does
not exist after the provided index, a –1 is returned.

Inputs

Name IEC 61131 Type Description

index UDINT The index where this class_SELString will begin to


search.

Inputs/Outputs

Name IEC 61131 Type Description

str class_SELString The class_SELString containing the characters that are


being searched for within this class_SELString.

Return Value

IEC 61131 Type Description

DINT The index of the first match of str within this object. If str cannot be
found, this method will return '–1'. (This value is always ≥ '–1')

Processing
The Find method performs the following actions:

➤ Begins its search at index, where an index of zero corresponds to


immediately before the first character and is incremented by one for each
character thereafter. The same is true of the return value.
➤ Is case sensitive.
➤ Returns the index of the first occurrence of str appearing after the given
index.
➤ If index is larger than the size of this class_SELString, returns –1.
➤ If str cannot be found, returns –1.
➤ If str is empty, returns –1.
➤ If str is this object, then –1 is returned.

Programming Reference Date Code 20241023


SELString 1027
Classes

FindString (Method)
This method returns the first position after the provided index where the
character combination provided in str exists. If the character combination does
not exist after the provided index, a –1 is returned.

Inputs
Name IEC 61131 Type Description

index UDINT The index where this class_SELString will begin to


search.

Inputs/Outputs
Name IEC 61131 Type Description

str STRING(g_p_MaxIec61131StringSize) The IEC 61131 string containing the characters that are being searched for
within this class_SELString.

Return Value
IEC 61131 Type Description

DINT The index of the first match of str within this object. If str cannot be
found, this method will return '–1'. (This value is always ≥ '–1')

Processing
The FindString method performs the following actions:
➤ Begins its search at index, where an index of zero corresponds to
immediately before the first character and is incremented by one for each
character thereafter. The same is true of the return value.
➤ Is case sensitive.
➤ Returns the index of the first occurrence of str appearing after the given
index.
➤ If index is larger than the size of this class_SELString, returns –1.
➤ If str cannot be found, returns –1.
➤ If str is empty, returns –1.
➤ If str system state prevents the search, then –1 is returned.

Clear (Method)
This method removes all character data from the class_SELString.

Return Value
IEC 61131 Type Description

BOOL Success indicator of clear operation; TRUE if memory is cleared


without errors.

Date Code 20241023 Programming Reference


1028 SELString
Classes

Processing
The Clear method performs the following actions:

➤ Removes all character data within the class_SELString.


➤ Resets the size of the class_SELString to zero.
➤ Resets the return value of ToString to an empty string.
➤ Any used memory is returned to the library.

Item (Method)
This method returns the character at the requested index.

Inputs

Name IEC 61131 Type Description

index UDINT The index of the character being requested.

Return Value

IEC 61131 Type Description

BYTE The ASCII value of the character at the requested index. If index is
out of range, returns NULL(0).

Processing
The Item method performs the following actions:

➤ Treats the first character as index zero with each additional character
being an addition of one.
➤ Returns the character positioned at the user requested index.
➤ If index is greater than or equal to the number of characters in this
class_SELString, returns NULL.
➤ Returns NULL on an empty string.

Begin (Method)
This method is used in conjunction with Next() and Previous(). This
method places the internal iterator on the first character of this class_SELString
object.

Processing
The Begin method places the iterator such that:

➤ The iterator is not locked out.


➤ A subsequent Next() returns the first character.

Programming Reference Date Code 20241023


SELString 1029
Classes

➤ A subsequent Previous() returns NULL and leaves the iterator locked


out.
➤ For an empty string, Next() and Previous() return NULL and leave
the iterator locked out.

End (Method)
This method is used in conjunction with Next() and Previous(). This
method places the internal iterator immediately after the last character of this
class_SELString object.

Processing
The End method places the iterator such that:
➤ The iterator is not locked out.
➤ A subsequent Previous() returns the last character.
➤ A subsequent Next() returns NULL and leaves the iterator locked out.
➤ For an empty string Next() and Previous() return NULL and leave
the iterator locked out.

Position (Method)
This method is used in conjunction with Next() and Previous(). This
method places the internal iterator on the character at index.

Inputs
Name IEC 61131 Type Description

index UDINT The location where the character iterator will be


assigned.

Processing
The Position method places the iterator such that:
➤ The first character in the class_SELString is index zero with each
additional character being an addition of one.
➤ An index greater than or equal to the number of characters in this
class_SELString leaves the iterator locked out.
➤ Otherwise, the iterator is not locked out.
➤ A subsequent Next() returns the character at the provided index.
➤ A subsequent Previous() returns the character immediately before the
provided index.
➤ For an empty string Next() and Previous() return NULL and leave
the iterator locked out.

Next (Method)
This method is used in conjunction with Begin(), Position(), End(), and
Previous(). This method returns the character at the current internal iterator
position then increments the iterator.

Date Code 20241023 Programming Reference


1030 SELString
Classes

Return Value
IEC 61131 Type Description

BYTE The ASCII value of the character at the current iterator position. If no
character exists, returns NULL(0).

Processing
The Next method performs the following actions:

➤ Returns the character at the current internal iterator position and then
increments the iterator.
➤ Returns NULL if the iterator is locked out.
➤ Locks out the iterator for subsequent calls to Next() and Previous() if
the iterator increments to a position greater than the number of characters
in this class_SELString.
➤ Locks out the iterator if any method other than Next() or Previous()
has been called since the last Begin(), End(), or Position().

Previous (Method)
This method is used in conjunction with Begin(), Position(), End(), and
Next(). This method decrements the current internal iterator position and then
returns the character at the new position.

Return Value
IEC 61131 Type Description

BYTE The ASCII value of the character at the decremented iterator position.
If no character exists, returns NULL(0).

Processing
The Previous method performs the following actions:

➤ Decrements the internal iterator position then returns the character new
position.
➤ Returns NULL if the iterator is locked out.
➤ Locks out the iterator for subsequent calls to Next() and Previous() if
the iterator decrements to a position less than index 0.
➤ Locks out the iterator if any method other than Next() or Previous()
has been called since the last Begin(), End(), or Position().

ToAsciiHex (Method)
This method copies an ASCII-encoded hexadecimal representation of the
contents of this object into the class_SELString provided by the user. For
example, a character of 'A' (raw byte content of 65, hex 0x41) is converted to a
'4' and a '1' (raw byte content of 52 and 49) when appended to str.

Programming Reference Date Code 20241023


SELString 1031
Classes

Inputs/Outputs

Name IEC 61131 Type Description

str class_SELString The class_SELString to which the ASCII-encoded


hexadecimal representation of this object's contents will
be copied.

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The ToAsciiHex method performs the following actions:

➤ Empties the class_SELString specified by str as per Clear().


➤ Iterates through this class_SELString one character at a time and appends
two characters to the class_SELString specified by str, representing an
ASCII-encoded hexadecimal copy of the raw byte content from this
class_SELString.
➤ If the library encounters an error, a pointer to a string describing that error
is returned.
➤ Returns 0 on success.

FromAsciiHex (Method)
This method takes an ASCII-encoded hexadecimal class_SELString, str, as an
input to be interpreted as raw hexadecimal data and stores the converted data
within this class_SELString object. For example, two sequential characters of '4'
and '1' (raw data of 52 and 49) are interpreted as hexadecimal 0x41 and stored in
this class_SELString as raw byte content of 65 (the character 'A').

Inputs/Outputs

Name IEC 61131 Type Description

str class_SELString The class_SELString whose ASCII-encoded hexadecimal data will be used to fill this object. Must be
of an even length and only contain characters that are considered to be ASCII representations of valid
hex digits (0–9, A–F, a–f).

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Date Code 20241023 Programming Reference


1032 SELString
Classes

Processing
The FromAsciiHex method performs the following actions:

➤ Empties this class_SELString as per Clear().


➤ Validates that the class_SELString specified as str contains an even
number of characters; returns an error string and does no work if the
string is of an odd length of characters.
➤ Iterates through the class_SELString specified as str two characters at a
time and uses fun_IsValidHexChar to validate that each character can be
interpreted as a valid hex digit. Returns an error string if any unexpected
characters are encountered.
➤ Converts each pair of characters into a single byte and appends those raw
data onto this class_SELString.
➤ Returns 0 on success.

StartsWith (Method)
This method searches for an exact match passed as an IEC 61131 string at the
beginning of the class_SELString. It returns TRUE if an exact match was found
and FALSE if no match was found. This method is case-sensitive.

Inputs

Name IEC 61131 Type Description

str STRING(g_p_MaxIec61131StringSize) The IEC 61131 string containing the characters that are being searched for
at the beginning of the class_SELString.

Return Value

IEC 61131 Type Description

BOOL TRUE if str is located at the beginning of the class_SELString.

Processing
The StartsWith method performs the following actions:

➤ Calls the method FindString starting at index zero.


➤ If the method FindString finds a match at index zero, returns TRUE.
➤ If the method FindString does not find a match at index zero, returns
FALSE.
➤ Returns FALSE on an empty IEC 61131 string.

EndsWith (Method)
This method searches for an exact match to the passed in IEC 61131 string at the
end of the class_SELString. It returns TRUE if the exact match was found and
returns FALSE if no match was found. This method is case-sensitive.

Programming Reference Date Code 20241023


SELString 1033
Classes

Inputs

Name IEC 61131 Type Description

str STRING(g_p_MaxIec61131StringSize) The IEC 61131 string containing the characters that are being searched for
at the end of the class_SELString.

Return Value

IEC 61131 Type Description

BOOL TRUE if str is located at the end of the class_SELString.

Processing
The EndsWith method performs the following actions:

➤ Calculates the index to start looking for an exact match.


➤ Calls the method FindString at that index.
➤ If the method FindString finds a match at the calculated index, returns
TRUE.
➤ If the method FindString does not find a match, returns FALSE.
➤ Returns FALSE on an empty IEC 61131 string.

Strip (Method)
This method removes excess whitespace characters from the beginning and end
of the class_SELString. In this method, whitespace includes any character that
results in TRUE being returned from fun_SELString_IsWhitespace.

Processing
The Strip method performs the following actions:

➤ Removes all whitespace from the beginning of the string to the first non-
whitespace character.
➤ Removes all whitespace from the last non-whitespace character to the end
of the string.
➤ Leaves a class_SELString containing no whitespace and empty strings
unchanged.
➤ Replaces strings containing only whitespace with an empty string.

LeftStrip (Method)
This method removes all whitespace from the beginning of this
class_SELString to the first non-whitespace character. In this method,
whitespace includes any character that results in TRUE being returned from
fun_SELString_IsWhitespace.

Date Code 20241023 Programming Reference


1034 SELString
Classes

Processing
The LeftStrip method performs the following actions:

➤ Removes all whitespace from the beginning of the string to the first non-
whitespace character.
➤ Leaves a class_SELString containing no whitespace and empty strings
unchanged.
➤ Replaces strings containing only whitespace with an empty string.

RightStrip (Method)
This method removes all whitespace from the last non-whitespace
character to the end of the class_SELString. In this method, whitespace
includes any character that results in TRUE being returned from
fun_SELString_IsWhitespace.

Processing
The RightStrip method performs the following actions:

➤ Removes all whitespace from the last non-whitespace character to the end
of the string.
➤ Leaves a class_SELString containing no whitespace and empty strings
unchanged.
➤ Replaces strings containing only whitespace with an empty string.

LeftJustify (Method)
This method justifies the class_SELString to the left. The method takes two
inputs: the size that the class_SELString shall be extended to, and the character
to append to the end of the class_SELString to achieve the specified length.

Inputs

Name IEC 61131 Type Description

newSize UDINT The size that the class_SELString shall have


after appending the paddingCharacter.

paddingCharacter STRING(1) The ASCII representation of the character that


is being used to justify the class_SELString to
the left.

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Programming Reference Date Code 20241023


SELString 1035
Classes

Processing
The LeftJustify method performs the following actions:

➤ Appends the paddingCharacter as many times as needed to reach the


newSize.
➤ Validates that paddingCharacters are those outlined in
fun_SELString_IsValidChar.
➤ If paddingCharacter is invalid, leaves all objects unchanged and returns a
pointer to an applicable invalid character error string.
➤ Leaves a class_SELStrings of size g_p_SELStringInitialSize unchanged.
➤ If the library runs out of memory, leaves all objects unchanged and
returns a pointer to an applicable IEC 61131 error string.
➤ Returns 0 on success.

RightJustify (Method)
This method justifies the class_SELString to the right. It takes two inputs: the
size that the class_SELString shall be extended to, and the character to prepend
to the beginning of the class_SELString to achieve the specified length.

Inputs
Name IEC 61131 Type Description

newSize UDINT The size that the class_SELString shall have


after prepending the paddingCharacter.

paddingCharacter STRING(1) The ASCII representation of the character that


is being used to justify the class_SELString to
the right.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The RightJustify method performs the following actions:

➤ Prepends the paddingCharacter as many times as needed to reach the


newSize.
➤ Validates that paddingCharacters are those outlined in
fun_SELString_IsValidChar.
➤ If paddingCharacter is invalid, leaves all objects unchanged and returns a
pointer to an applicable invalid character error string.
➤ Leaves a class_SELStrings of size g_p_SELStringInitialSize unchanged.
➤ If the library runs out of memory, leaves all objects unchanged and
returns a pointer to an applicable IEC 61131 error string.
➤ Returns 0 on success.

Date Code 20241023 Programming Reference


1036 SELString
Classes

Count (Method)
This method counts the number of occurrences of a given class_SELString. It
returns a DINT representing the total number of appearances.

Inputs
Name IEC 61131 Type Description

str class_SELString The class_SELString containing the characters that


are being counted within the class_SELString object.

Return Value
IEC 61131 Type Description

DINT Numeric value representing the number of occurrences of a


class_SELString in a given class_SELString.

Processing
The Count method performs the following actions:
➤ Counts the number of times that the Find method returns a positive value.
➤ If str is not found, returns 0.
➤ If str is this object, returns –1.
➤ An empty str returns –2.

class_SELStringList (Class)
class_SELStringList exists to store and perform operations on a list of strings
using 0-based indexing.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Size UDINT R The number of class_SELString objects in this


class_SELStringList.

Append (Method)
This method adds the requested string to the end of the list.

Inputs/Outputs
Name IEC 61131 Type Description

str class_SELString The string to be added to the end of the


class_SELStringList.

Programming Reference Date Code 20241023


SELString 1037
Classes

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The Append method performs the following actions:
➤ Places str at the end of the current list (position zero for an empty list)
and increments the size of the list.
➤ Empties the contents of str.
➤ Allows empty strings to be added to the list.
➤ If the object str is already a member of the list, empties the contents of str
and places the contents of str at the end of the list.
For example: If this list is ["dog","cat","bird"] and Item 1 ("cat") is
appended, the new list is: ["dog","","bird","cat"].
➤ If the library runs out of memory, it leaves this object and str unchanged
and returns a pointer to an applicable IEC 61131 error string.
➤ Returns 0 on success.

Insert (Method)
This method inserts the requested string into the list at the position specified.

Inputs
Name IEC 61131 Type Description

index UDINT The location where str will be inserted.

Inputs/Outputs
Name IEC 61131 Type Description

str class_SELString The class_SELString to be inserted into the


class_SELStringList.

Return Value
IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Processing
The Insert method performs the following actions:
➤ Places the index zero immediately before the first class_SELString and
increments by one for each string thereafter.
➤ Empties the contents of str.

Date Code 20241023 Programming Reference


1038 SELString
Classes

➤ Allows empty strings to be added to the list.


➤ When index is equal to the length of list or more, behaves the same as
Append().
➤ If the object str is already a member of the list, empties the contents of str
and places the contents of str at the requested location.
For example: If this list is ["dog","cat","bird"] and Item 0 ("dog") is
inserted at Position 2, the new list is: ["","cat","dog","bird"].
➤ Increases the size of the list by one.
➤ If the library runs out of memory, removes the final class_SELString from
this object and inserts str at the desired index except in the case where str
would be appended, in which case the Insert method behaves the same
as Append(). It then returns a pointer to an applicable IEC 61131 error
string.
➤ Returns 0 on success.

RemoveLast (Method)
This method removes the last string in the list.

Processing
The RemoveLast method performs the following actions:
➤ Removes the last class_SELString from the class_SELStringList.
➤ Decrements the size of the class_SELStringList.
➤ Does nothing if the class_SELStringList is empty.
➤ Returns the freed memory.

Clear (Method)
This method removes all class_SELString objects from the list.

Return Value
IEC 61131 Type Description

BOOL Success indicator of clear operation; TRUE if memory is cleared


without errors.

Processing
The Clear method performs the following actions:
➤ Removes all class_SELStrings in the class_SELStringList.
➤ Sets the size of the class_SELStringList to zero.
➤ Causes all other methods to respond that there are no objects in the list.
➤ Returns the freed memory.

Item (Method)
This method returns a pointer to the class_SELString at the requested index.

Programming Reference Date Code 20241023


SELString 1039
Classes

Inputs
Name IEC 61131 Type Description

index UDINT The location of the desired string in the list.

Return Value
IEC 61131 Type Description

POINTER TO class_SELString A pointer to the class_SELString located at index. If


index does not exist, returns NULL(0).

Processing
The Item method performs the following actions:
➤ Returns a pointer to the class_SELString that exists at index.
➤ Returns NULL if index is outside the bounds of the list.

Begin (Method)
This method is used in conjunction with Next() and Previous(). This
method places the internal iterator on the first string in the list.

Processing
The Begin method places the iterator in a location to comply with the following
items:
➤ The iterator is not locked out.
➤ A subsequent Next() returns the first string in the list.
➤ A subsequent Previous() returns NULL and leaves the iterator locked
out.
➤ For an empty list Next() and Previous() return NULL and leave the
iterator locked out.

End (Method)
This method is used in conjunction with Next() and Previous(). This
method places the internal iterator immediately after the last string in the list.

Processing
The End method places the iterator in a location to comply with the following
items:
➤ The iterator is not locked out.
➤ A subsequent Next() returns NULL and leaves the iterator locked out.
➤ A subsequent Previous() returns the first string in the list.
➤ For an empty list Next() and Previous() return NULL and leave the
iterator locked out.

Date Code 20241023 Programming Reference


1040 SELString
Classes

Position (Method)
This method is used in conjunction with Next() and Previous(). This
method places the internal iterator on the string at index.

Inputs
Name IEC 61131 Type Description

index UDINT List location of the desired string.

Processing
The Position method places the iterator in a location to comply with the
following items:
➤ The first string in the class_SELStringList is index zero with each
additional string being an addition of one.
➤ An index greater than or equal to the number of strings in this
class_SELStringList leaves the iterator locked out.
➤ Otherwise, the iterator is not locked out.
➤ A subsequent Next() returns the string at the provided index.
➤ A subsequent Previous() returns the string immediately before the
provided index.
➤ For an empty string list, Next() and Previous() return NULL and
leave the iterator locked out.

Next (Method)
This method is used in conjunction with Begin(), Position(), End(), and
Previous(). This method returns the string at the current internal iterator
position then increments the iterator.

Return Value
IEC 61131 Type Description

POINTER TO class_SELString A pointer to the string at the current iterator position.


If no string exists, returns NULL(0).

Processing
The Next method performs the following actions:
➤ Returns the string at the current internal iterator position and then
increments the iterator.
➤ Returns NULL if the iterator is locked out.
➤ Locks out the iterator for subsequent calls to Next() and Previous() if
the iterator increments to a position greater than the number of strings in
this class_SELStringList.
➤ Locks out the iterator if any method other than Next() or Previous()
has been called since the last Begin(), End(), or Position().

Programming Reference Date Code 20241023


SELString 1041
Classes

Previous (Method)
This method is used in conjunction with Begin(), Position(), End(), and
Previous().This method decrements the internal iterator position and returns a
pointer to the string at the new position.

Return Value

IEC 61131 Type Description

POINTER TO class_SELString A pointer to the string at the decremented iterator


position. If no string exists, returns NULL(0).

Processing
The Previous method performs the following actions:

➤ Decrements the internal iterator position and returns a pointer to the string
at the new position.
➤ Returns NULL if the iterator is locked out.
➤ Locks out the iterator for subsequent calls to Next() and Previous() if
the iterator decrements below position 0.
➤ Locks out the iterator if any method other than Next() or Previous()
has been called since the last Begin(), End(), or Position().

Join (Method)
This method creates a single class_SELString containing the full list of
class_SELStrings, each separated from the other by the provided str. This object
is empty upon successful completion.

Inputs/Outputs

Name IEC 61131 Type Description

outStr class_SELString The user provided class_SELString in which this method will join all class_SELStrings within
the stringlist separated by str. Any existing content of this string will be overwritten.

str class_SELString The class_SELString to be inserted between each entry in the class_SELStringList.

Return Value

IEC 61131 Type Description

POINTER TO STRING A pointer to an error string or zero on success.

Date Code 20241023 Programming Reference


1042 SELString
Benchmarks

Processing
The Join method performs the following actions:
➤ Loads the outStr class_SELString with the full list of class_SELStrings
separated by str.
Example: If the class_SELStringList contains: ["b","n","n","s"] and str is
"a" then the return value is "bananas".
➤ Loads the outStr class_SELString with an empty string, if empty.
➤ Loads the outStr class_SELString containing the full list of strings
if str is an empty string. For example: If the stringlist contains
["H","e","l","l","o"] and str is empty, the return value is "Hello".
➤ Empties this class_SELStringList as per Clear().
➤ If str is a member of this list, loads the outStr class_SELString with
undefined values.
➤ If the library runs out of memory, the output class_SELString will contain
all class_SELStrings in the list that were loaded prior to the error. This
class_SELStringList object will be cleared.
➤ Returns 0 on success.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.
➤ SEL-3530-4
➢ R132 firmware
➤ SEL-3354
➢ Intel Pentium 1.4 GHz
➢ 1 GB DDR ECC SDRAM
➢ SEL-3532 RTAC Conversion Kit
➢ R132 firmware

Benchmark Test Descriptions class_SELString


The posted time for each test is the average execution time of 50 consecutive
calls for the test as described. The maximum number of characters used in any
test was g_p_StringSize. All times are recorded in microseconds.

FromString Replace
This test calls FromString() and replaces g_p_StringSize characters with
g_p_StringSize different characters.

FromString Populate
This test calls FromString() on an empty class_SELString and populates it
with g_p_StringSize characters.

Programming Reference Date Code 20241023


SELString 1043
Benchmarks

FromString Depopulate
This test calls FromString() on a class_SELString with g_p_StringSize
characters and populates it with zero characters.

ToString
This test calls ToString() on a class_SELString with g_p_StringSize
characters.

FromByteArray Replace
This test calls FromString() and replaces g_p_StringSize characters with
g_p_StringSize different characters.

FromByteArray Populate
This test calls FromString() on an empty class_SELString and populates it
with g_p_StringSize characters.

FromByteArray Depopulate
This test calls FromString() on a class_SELString with g_p_StringSize
characters and populates it with zero characters.

ToByteArray
This test calls ToString() on a class_SELString with g_p_StringSize
characters.

Replace 1 Char Not Found


This test calls Replace() with a before of length one in a class_SELString of
length g_p_StringSize without finding the result. It is designed to show the cost
of a one-pass search of a string.

Replace 1 Char Max Found


This test calls Replace() with a before of length one in a class_SELString of
length g_p_StringSize, finding the result on every character. It is designed to
show the cost of a one-pass search and replace on a string.

Replace Max/2 Found


This test calls Replace() with a before of "aaaaaaab" and current of
"aaaaaaaaaaaaaab" but with sizes of g_p_StringSize/2 and g_p_StringSize
respectively. It is designed to show the cost of heavy recursive searching on a
string.

Date Code 20241023 Programming Reference


1044 SELString
Benchmarks

Replace Max Char Found


This test calls Replace() with a before of "aaaaaaab" and current of "aaaaaaab"
but with sizes of g_p_StringSize. It is designed to show the cost of a one-pass
ordered search on a string.

Split 0 Char
This test calls Split() with an empty separator in a class_SELString of length
g_p_StringSize. It is designed to show the cost of splitting a string into its
constituent characters.

Split 1 Char Not Found


This test calls Split() with a one character separator in a length
g_p_StringSize class_SELString without finding the result. It is designed to
show the cost of a one-pass search conversion of a string to a string list.

Split 1 Char Found


This test calls Split() with a one character separator in a length
g_p_StringSize class_SELString, finding the result in every character. It is
designed to show the cost of converting a complete list to empty strings.

Split Max/2 Found


This test calls Split() with a sep of "aaaaaaab" and current of
"aaaaaaaaaaaaab" but with sizes of g_p_StringSize/2 and g_p_StringSize
respectively. It is designed to show the cost of heavy recursive searching and
character removal using Split().

Split Max Found


This test calls Split() with a sep of "aaaaaaab" and current of "aaaaaaab"
but with sizes of g_p_StringSize. It is designed to show the cost of a one-pass
ordered search and character removal on a string using Split().

Trim No Whitespace
This test calls Trim() on a length g_p_StringSize class_SELString containing
no whitespace. It is designed to show the cost of searching for whitespace.

Trim Every Other Whitespace


This test calls Trim() on a length g_p_StringSize class_SELString where every
other character is whitespace. It is designed to show the cost of searching for and
ignoring whitespace.

Trim All Whitespace


This test calls Trim() on a length g_p_StringSize class_SELString containing
only whitespace. It is designed to show the cost of removal of whitespace.

Programming Reference Date Code 20241023


SELString 1045
Benchmarks

Trim Half Whitespace


This test calls Trim() on a length g_p_StringSize class_SELString containing
whitespace to remove at the head, in the middle, and at the end of the
class_SELString. It is designed to show a more composite cost of whitespace
removal.

Size
This test calls Size() on a length g_p_StringSize class_SELString.

Append
This test calls Append() with varying length class_SELString.

AppendString
This test calls AppendString() with a g_p_MaxIec61131StringSize length
string.

Prepend
This test calls Prepend() with varying length class_SELString.

PrependString
This test calls PrependString() with a g_p_MaxIec61131StringSize length
string.

Insert Either End


This test calls Insert() on the ends of a class_SELString.

Insert Middle
This test calls Insert() to place one character in the middle of a
class_SELString.

Find 1 Char
This test calls Find() for a single character not found in a length
g_p_StringSize class_SELString.

Find Max/2
This test calls Find() searching for "aaaaaaab" while having a current of
"aaaaaaaaaaaaab" but with sizes of g_p_StringSize/2 and g_p_StringSize
respectively. It is designed to show the cost of heavy recursive searching using
Find().

Date Code 20241023 Programming Reference


1046 SELString
Benchmarks

Find Max
This test calls Find() searching for a length g_p_StringSize string inside a
length g_p_StringSize class_SELString.

FindString 1 Char
This test calls FindString() for a single character not found in a length
g_p_StringSize class_SELString.

FindString Max/2
This test calls FindString() searching for "aaaaaaab" of size
g_p_StringSize/2 while having a current of "aaaaaaaaaaaaab" or size of
g_p_StringSize. It is designed to show the cost of heavy recursive searching
using FindIecString().

FindString Max
This test calls FindString() searching for a length g_p_StringSize string
inside a length g_p_StringSize class_SELString.

Clear
This test calls Clear() on a class_SELString of length g_p_StringSize.

Item Either End


This test calls Item() on both ends of a length g_p_StringSize
class_SELString.

Item Middle
This test calls Item() requesting the middle of a length g_p_StringSize
class_SELString.

Begin
This test calls Begin().

End
This test calls End() on a length g_p_StringSize class_SELString.

Position Either End


This test calls Position() on both ends of a length g_p_StringSize
class_SELString.

Programming Reference Date Code 20241023


SELString 1047
Benchmarks

Position Middle
This test calls Position() requesting the middle of a length g_p_StringSize
class_SELString.

Next
This test calls Next() while both locked out and responsive.

Previous
This test calls Previous() while both locked out and responsive.

Benchmark Results class_SELString


Platform (time in µs)
Operation Tested
SEL-3354 SEL-3530

FromString Replace 9 89

FromString Populate 45 274

FromString Depopulate 16 79

ToString 8 75

FromByteArray Replace 7 75

FromByteArray Populate 42 241

FromByteArray Depopulate 16 77

ToByteArray 7 65

Replace 1 Char Not Found 16 165

Replace 1 Char Max Found 70 701

Replace Max/2 Found 535 4701

Replace Max Char Found 19 181

Split 0 Char 103 633

Split 1 Char Not Found 17 176

Split 1 Char Found 127 951

Split Max/2 Found 534 4673

Split Max Found 25 169

Trim No Whitespace 11 87

Trim Every Other Whitespace 11 92

Trim All Whitespace 29 206

Trim Half Whitespace 20 155

Size 1 1

Append 1 4

Date Code 20241023 Programming Reference


1048 SELString
Benchmarks

Platform (time in µs)


Operation Tested
SEL-3354 SEL-3530

AppendString 49 272

Prepend 1 4

PrependString 45 276

Insert Either End 2 4

Insert Middle 1 6

Find 1 Char 16 170

Find Max/2 521 4617

Find Max 8 71

FindString 1 Char 16 164

FindString Max/2 567 4796

FindString Max 67 430

Clear 16 77

Item Either End 1 1

Item Middle 1 4

Begin 1 1

End 1 1

Position Either End 1 1

Position Middle 1 4

Next 1 1

Previous 1 1

Benchmark Test Descriptions class_SELStringList


The posted time for each test is the average execution time of 50 consecutive
calls for the test as described. The maximum number of characters used in any
test was g_p_StringSize. A maximum size class_SELStringList tested was
also g_p_StringSize long, each string containing one character. All times were
recorded in microseconds.

Append
This test calls Append() on a class_SELStringList of g_p_StringSize
class_SELStrings.

Insert Either End


This test calls Insert() on both ends of a class_SELStringList of
g_p_StringSize class_SELStrings.

Programming Reference Date Code 20241023


SELString 1049
Benchmarks

Insert Middle
This test calls Insert() requesting the middle of a class_SELStringList of
length g_p_StringSize.

RemoveLast
This test calls RemoveLast() on a class_SELStringList of g_p_StringSize
class_SELStrings.

Size
This test calls Size() on a class_SELStringList of g_p_StringSize
class_SELStrings.

Clear 1 Large String


This test calls Clear() on a class_SELStringList of one class_SELString of
length g_p_StringSize.

Clear Max Strings


This test calls Clear() on a class_SELStringList containing the g_p_StringSize
number of one character class_SELStrings.

Item Either End


This test calls Item() requesting both ends of a class_SELStringList containing
the g_p_StringSize number of one character class_SELStrings.

Item Middle
This test calls Item() requesting the middle of a class_SELStringList
containing g_p_StringSize number of one character class_SELStrings.

Begin
This test calls Begin().

End
This test calls End() on a class_SELStringList of g_p_StringSize
class_SELStrings.

Position Either End


This test calls Position() requesting each end of a class_SELStringList
containing g_p_StringSize class_SELStrings.

Date Code 20241023 Programming Reference


1050 SELString
Benchmarks

Position Middle
This test calls Position() requesting the middle class_SELString of a
class_SELStringList containing g_p_StringSize class_SELStrings.

Next
This test calls Next() while both locked out and responsive.

Previous
This test calls Previous() while both locked out and responsive.

Join Max Empties


This test calls Join() with a str of length one on a class_SELStringList
containing g_p_StringSize empty strings.

Join Max 1 Chars


This test calls Join() with a str of length zero on a class_SELStringList
containing g_p_StringSize one character strings.

This test calls Join() with a str of length g_p_StringSize on a


class_SELStringList containing two empty strings.

Benchmark Results class_SELStringList


Platform (time in µs)
Operation Tested
SEL-3354 SEL-3530

Append 1 4

Insert Either End 1 5

Insert Middle 2 14

RemoveLast 17 80

Size 1 1

Clear 1 Large String 15 79

Clear Max Strings 59 372

Item Either End 1 1

Item Middle 1 4

Begin 1 1

End 1 1

Position Either End 1 2

Position Middle 1 4

Next 1 1

Programming Reference Date Code 20241023


SELString 1051
Examples

Platform (time in µs)


Operation Tested
SEL-3354 SEL-3530

Previous 1 1

Join Max Empties 100 814

Join Max 1 Chars 103 930

Join Max Str 47 317

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

class_SELString Examples
The following examples demonstrate simple uses of class_SELString.

FromString
Code Snippet 35.1 SELString FromString Example
PROGRAM prg_FromStringExample
VAR
normalString : STRING := 'This is a normal string';
selString : class_SELString;
END_VAR

// Populate the selString with the contents of normalString.


selString.FromString(normalString);

ToString
Code Snippet 35.2 SELString ToString Example
PROGRAM prg_ToStringExample
VAR
normalString : STRING := 'This is a normal string';
selString : class_SELString;
END_VAR

// Populate the SELString.


selString.FromString('This is a string');
// Converts the SELString to a normal string.
normalString := selString.ToString();

Date Code 20241023 Programming Reference


1052 SELString
Examples

FromByteArray ToByteArray
If data is being read-in from, or out to a communication buffer, it is likely to
contain nonprintable characters that are deliberately ignored by the FromString
and ToString methods. This example shows how to accomplish the same thing,
using the FromByteArray and ToByteArray methods, which are able to accept
all byte values.
Code Snippet 35.3 SELString To/From ByteArray Example
PROGRAM prg_ToAndFromByteArrayExample
VAR CONSTANT
c_StringLength : UDINT := 80;
END_VAR
VAR
InputString : STRING(c_StringLength) := 'This is a normal string';
OutputString : STRING(c_StringLength);
NumberBytesRead : UDINT;
SelString : class_SELString;
END_VAR

// Populate the SELString.


SelString.FromByteArray(ADR(InputString), c_StringLength);
// Converts the SELString to a byte array .
NumberBytesRead := SelString.ToByteArray(ADR(OutputString), c_StringLength);
// Append the null character on the end, since it is omitted by
// ToByteArray.
OutputString[c_StringLength] := 0;

Replace
Code Snippet 35.4 SELString Replace Example
PROGRAM prg_ReplaceExample
VAR
normalString : STRING := 'This is a normal string';
selString : class_SELString;
before : class_SELString;
after : class_SELString;
END_VAR

// Create an SELString with the text to be replaced.


before.FromString('normal');
// Create an SELString with the desired replacement text.
after.FromString('SEL');
// Populate the SELString.
selString.FromString(normalString);
// Replace the text in the SELString. This SELString now contains 'This is a SEL string'.
selString.Replace(before, after);

Split
Code Snippet 35.5 SELString Split Example
PROGRAM prg_SplitExample
VAR
normalString : STRING := 'This is a normal string';
selString : class_SELString;
selStringSpace : class_SELString;
selStringList : class_SELStringList;

pt_FirstString : POINTER TO class_SELString;


pt_SecondString : POINTER TO class_SELString;

Programming Reference Date Code 20241023


SELString 1053
Examples

firstString : STRING;
secondString : STRING;
END_VAR

// Populate the SELString.


selString.FromString(normalString);
// Create an SELString containing the delimiter.
selStringSpace.FromString(' ');
// Split the SELString into a list of SELStrings, where each SELString in the list
// is a word from the original SELString.
selString.Split(selStringSpace, selStringList);
// Get the items from the list
pt_FirstString := selStringList.Item(0);
pt_SecondString := selStringList.Item(1);
// Dereference the pointers and convert to IEC 61131 Strings
// Check for a valid pointer before deference
IF 0 <> pt_FirstString THEN
firstString := pt_FirstString^.ToString();
ELSE
; // Error Message
END_IF

IF 0 <> pt_SecondString THEN


secondString := pt_SecondString^.ToString();
ELSE
; // Error Message
END_IF

Trim
Code Snippet 35.6 SELString Trim Example
PROGRAM prg_TrimExample
VAR
selString : class_SELString;
END_VAR

// Populate the SELString.


selString.FromString(' This string has excess whitespace.
');
// Trim the extra whitespace, resulting in:
// 'This string has excess whitespace.'.
selString.Trim();

Size
Code Snippet 35.7 SELString Size Example
PROGRAM prg_SizeExample
VAR
selString : class_SELString;
size : UDINT;
END_VAR

// Populate the SELString.


selString.FromString('This is a string.');
// Get the size of the string.
size := selString.Size;

Append
Code Snippet 35.8 SELString Append Example
PROGRAM prg_AppendExample

Date Code 20241023 Programming Reference


1054 SELString
Examples

VAR
firstString : class_SELString;
secondString : class_SELString;
END_VAR

// Populate the first string.


firstString.FromString('This is a ');
// Populate the second string.
secondString.FromString('string.');
// Append the second string to the first string.
firstString.Append(secondString);

Prepend
Code Snippet 35.9 SELString Prepend Example
PROGRAM prg_PrependExample
VAR
firstString : class_SELString;
secondString : class_SELString;
END_VAR

// Populate the first string.


firstString.FromString('This is a ');
// Populate the second string.
secondString.FromString('string.');
// Prepend the first string to the second string.
secondString.Prepend(firstString);

Insert
Code Snippet 35.10 SELString Insert Example
PROGRAM prg_InsertExample
VAR
firstString : class_SELString;
secondString : class_SELString;
END_VAR

// Populate the first string.


firstString.FromString('This is a string ');
// Populate the second string.
secondString.FromString('SEL ');
// Insert the first string to the second string.
firstString.Insert(10, secondString);

Find
Code Snippet 35.11 SELString Find Example
PROGRAM prg_FindExample
VAR
firstString : class_SELString;
secondString : class_SELString;
index : DINT;
END_VAR

// Populate the first string.


firstString.FromString('This is an SEL string. ');
// Populate the second string.
secondString.FromString('SEL ');
// Find the index of the string 'SEL' in the first string.
index := firstString.Find(0, secondString);

Programming Reference Date Code 20241023


SELString 1055
Examples

Clear
Code Snippet 35.12 SELString Clear Example
PROGRAM prg_ClearExample
VAR
selString : class_SELString;
END_VAR

// Populate the string.


selString.FromString('This is an SEL string.');
// Clear the contents of the string.
selString.Clear();

Item
Code Snippet 35.13 SELString Item Example
PROGRAM prg_ItemExample
VAR
selString : class_SELString;
character : BYTE;
END_VAR

// Populate the string.


selString.FromString('This is an SEL string.');
// Get the ASCII value of the character located at index 11.
character := selString.Item(11);

Begin, End, Position, Next, and Previous


Code Snippet 35.14 SELString Iterator Example
PROGRAM prg_IteratorExample
VAR
selString : class_SELString;
firstCharacter : BYTE;
middleCharacter : BYTE;
lastCharacter : BYTE;
END_VAR

// Populate the string.


selString.FromString('This is an SEL string.');
// Get the first character.
selString.Begin();
firstCharacter := selString.Next();
// Get a middle character.
selString.Position(11);
middleCharacter := selString.Next();
// Get the last character
selString.End();
lastCharacter := selString.Previous();

CopyTo
Code Snippet 35.15 SELString CopyTo Example
PROGRAM prg_CopyTo
VAR
selString : class_SELString;
copiedSELString : class_SELString;
END_VAR

// Populate the SELString.


selString.FromString('This is a string.');

Date Code 20241023 Programming Reference


1056 SELString
Examples

// Copy resulting in:


// 'This is a string.'
selString.CopyTo(copiedSELString);

AppendByteArray
Code Snippet 35.16 SELString AppendByteArray Example
PROGRAM prg_AppendByteArray
VAR
selString : class_SELString;
stringToAppend : STRING := 'with appended content';
lenStringToAppend : UDINT := INT_TO_UDINT(LEN(stringToAppend));
RUNONCE : BOOL := TRUE;
END_VAR

IF RUNONCE THEN
// Populate SELString
selString.FromString('This is a string ');
// AppendByteArray resulting in:
// 'This is a string with appended content.'
selString.AppendByteArray(ADR(stringToAppend), lenStringToAppend);
END_IF
RUNONCE := FALSE;

ToAsciiHex
Code Snippet 35.17 SELString ToAsciiHex Example
PROGRAM prg_ToAsciiHex
VAR
stringInAscii : STRING := 'A';
asciiSELString1 : class_SELString;
hexSELString1 : class_SELString;
asciiSELString2 : class_SELString;
hexSELString2 : class_SELString;
stringInHEX1 : STRING;
stringInHEX2 : STRING;
END_VAR

//Using FromString to populate the SELString.


asciiSELString1.FromString(stringInAscii);
// ToAsciiHex, resulting in:
// hexSELString1 == 41
asciiSELString1.ToAsciiHex(hexSELString1);
// Verify content of hexSELString1
stringInHEX1 := hexSELString1.ToString();

// Using FromByteArray to populate the SELString.


asciiSELString2.FromByteArray(ADR(stringInAscii), INT_TO_UDINT(LEN(stringInAscii)));
// ToAsciiHex, resulting in:
// hexSELString2 == 41
asciiSELString2.ToAsciiHex(hexSELString2);
// Verify content of hexSELString2
stringInHEX2 := hexSELString2.ToString();

FromAsciiHex
Code Snippet 35.18 SELString FromAsciiHex Example
PROGRAM prg_FromAsciiHex
VAR
stringInHEX : STRING := '41';
hexSELString1 : class_SELString;

Programming Reference Date Code 20241023


SELString 1057
Examples

asciiSELString1 : class_SELString;
hexSELString2 : class_SELString;
asciiSELString2 : class_SELString;
stringInAscii1 : STRING;
stringInAscii2 : STRING;
END_VAR

// Using FromString to populate the SELString.


hexSELString1.FromString(stringInHEX);
// FromAsciiHex, resulting in:
// asciiSELString1 == A
asciiSELString1.FromAsciiHex(hexSELString1);
// Verify content of hexSELString1
stringInAscii1 := asciiSELString1.ToString();

// Using FromByteArray to populate the SELString.


hexSELString2.FromByteArray(ADR(stringInHEX), INT_TO_UDINT(LEN(stringInHEX)));
// FromAsciiHex, resulting in:
// asciiSELString2 == A
asciiSELString2.FromAsciiHex(hexSELString2);
// Verify content of hexSELString2
stringInAscii2 := asciiSELString2.ToString();

Strip
Code Snippet 35.19 SELString Strip Example
PROGRAM prg_StripExample
VAR
selString : class_SELString;
END_VAR

// Populate the SELString.


selString.FromString(' This string has excess whitespace.
');
// Strip the extra leading/trailing whitespace, resulting in:
// 'This string has excess whitespace.'.
selString.Strip();

LeftStrip
Code Snippet 35.20 SELString LeftStrip Example
PROGRAM prg_LeftStripExample
VAR
selString : class_SELString;
END_VAR

// Populate the SELString.


selString.FromString(' This string has excess whitespace on the
left.');
// LeftStrip resulting in:
// 'This string has excess whitespace on the left.'.
selString.LeftStrip();

RightStrip
Code Snippet 35.21 SELString RightStrip Example
PROGRAM prg_RightStripExample
VAR
selString : class_SELString;
END_VAR

// Populate the SELString.

Date Code 20241023 Programming Reference


1058 SELString
Examples

selString.FromString('This string has excess whitespace on the right.


');
// RightStrip resulting in:
// 'This string has excess whitespace on the right.'.
selString.RightStrip();

StartsWith and EndsWith


Code Snippet 35.22 SELString StartsWith and EndsWith Example
PROGRAM prg_startsAndEndsWith
VAR
selString : class_SELString;
firstNormalString : STRING := 'abc';
secondNormalString: STRING := 'def';
startsWith : BOOL;
endsWith : BOOL;
END_VAR

// Populate the SELString.


selString.FromString('abcdef');
// Check if selString starts with firstNormalString
// StartsWith is TRUE
startsWith := selString.StartsWith(firstNormalString);
// Check if selString ends with secondNormalString
// EndsWith is TRUE
endsWith := selString.EndsWith(secondNormalString);

LeftJustify and RightJustify


Code Snippet 35.23 SELString LeftJustify and RightJustify Example
PROGRAM prg_JustifyExample
VAR
SELStringOne : class_SELString;
SELStringTwo : class_SELString;
END_VAR

// Populate the SELStrings.


SELStringOne.FromString('This is a string.');
SELStringTwo.FromString('This is a string.');
// Increase the size of SELStringOne to 30, using
// '.' as the padding character.
// LeftJustify resulting in:
// 'This is a string..............'
SELStringOne.LeftJustify(30,'.');
// Increase the size of SELStringOne to 40, using
// '*' as the padding character.
// RightJustify resulting in:
// '***********************This is a string.'
SELStringTwo.RightJustify(40,'*');

class_SELStringList Examples
The following examples demonstrate simple uses of class_SELStringList.

Size
Code Snippet 35.24 SELStringList Size Example
PROGRAM prg_SizeExample
VAR
selString : class_SELString;

Programming Reference Date Code 20241023


SELString 1059
Examples

selStringList : class_SELStringList;
listSize : UDINT;
END_VAR

// Populate the string.


selString.FromString('This is an SEL string.');
// Append the string to the string list.
selStringList.Append(selString);
// Get the size of the string list.
listSize := selStringList.Size;

Append
Code Snippet 35.25 SELStringList Append Example
PROGRAM prg_AppendExample
VAR
selString : class_SELString;
selStringList : class_SELStringList;
END_VAR

// Populate the string.


selString.FromString('This is an SEL string.');
// Append the string to the string list.
selStringList.Append(selString);

Insert
Code Snippet 35.26 SELStringList Insert Example
PROGRAM prg_InsertExample
VAR
selString1 : class_SELString;
selString2 : class_SELString;
selString3 : class_SELString;
selStringList : class_SELStringList;
END_VAR

// Populate the strings.


selString1.FromString('String 1');
selString2.FromString('String 2');
selString3.FromString('String 3');

// Append the strings to the list.


selStringList.Append(selString1);
selStringList.Append(selString2);
// Insert a string to the list at index 1.
selStringList.Insert(1, selString3);

RemoveLast
Code Snippet 35.27 SELStringList RemoveLast Example
PROGRAM prg_RemoveLastExample
VAR
selString1 : class_SELString;
selString2 : class_SELString;
selStringList : class_SELStringList;
END_VAR

// Populate the strings.


selString1.FromString('String 1');
selString2.FromString('String 2');

// Append the strings to the list.

Date Code 20241023 Programming Reference


1060 SELString
Examples

selStringList.Append(selString1);
selStringList.Append(selString2);
// Remove the last string from the list.
selStringList.RemoveLast();

Clear
Code Snippet 35.28 SELStringList Clear Example
PROGRAM prg_ClearExample
VAR
selString1 : class_SELString;
selString2 : class_SELString;
selStringList : class_SELStringList;
END_VAR

// Populate the strings.


selString1.FromString('String 1');
selString2.FromString('String 2');

// Append the strings to the list.


selStringList.Append(selString1);
selStringList.Append(selString2);
// Clear all strings from the list
selStringList.Clear();

Item
Code Snippet 35.29 SELStringList Item Example
PROGRAM prg_ItemExample
VAR
selStringList : class_SELStringList;
firstString : class_SELString;
middleString : class_SELString;
lastString : class_SELString;

ptFirstString : POINTER TO class_SELString;


ptMiddleString : POINTER TO class_SELString;
ptLastString : POINTER TO class_SELString;
END_VAR

// Populate the strings.


firstString.FromString('The first string.');
middleString.FromString('The middle string.');
lastString.FromString('The last string.');

// Add the strings to the list.


selStringList.Append(firstString);
selStringList.Append(middleString);
selStringList.Append(lastString);

// Get pointers to each of the strings.


ptFirstString := selStringList.Item(0);
ptMiddleString := selStringList.Item(1);
ptLastString := selStringList.Item(2);

Begin, End, Position, Next, and Previous


Code Snippet 35.30 SELStringList Iterator Example
PROGRAM prg_IteratorExample
VAR
selStringList : class_SELStringList;
firstString : class_SELString;

Programming Reference Date Code 20241023


SELString 1061
Examples

middleString : class_SELString;
lastString : class_SELString;

ptFirstString : POINTER TO class_SELString;


ptMiddleString : POINTER TO class_SELString;
ptLastString : POINTER TO class_SELString;
END_VAR

// Populate the strings.


firstString.FromString('The first string.');
middleString.FromString('The middle string.');
lastString.FromString('The last string.');

// Add the strings to the list.


selStringList.Append(firstString);
selStringList.Append(middleString);
selStringList.Append(lastString);

// Get the first string.


selStringList.Begin();
ptFirstString := selStringList.Next();
// Get the middle string.
selStringList.Position(1);
ptMiddleString := selStringList.Next();
// Get the last string.
selStringList.End();
ptLastString := selStringList.Previous();

Join
Code Snippet 35.31 SELStringList Join Example
PROGRAM prg_JoinExample
VAR
selStringList : class_SELStringList;
firstString : class_SELString;
middleString : class_SELString;
lastString : class_SELString;
delimiter : class_SELString;
joinedString : class_SELString;
END_VAR

// Populate the strings.


firstString.FromString('The');
middleString.FromString('joined');
lastString.FromString('string.');
delimiter.FromString(' ');

// Add the strings to the list.


selStringList.Append(firstString);
selStringList.Append(middleString);
selStringList.Append(lastString);

// Get the joined string, 'The joined string.'


selStringList.Join(joinedString, delimiter);

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 3 6

SELUtils
Introduction
The SELUtils library is a collection of utility functions and function blocks
provided to meet common RTAC user workflows.
The SELUtils library is included in RTAC projects by default, granting access
to the common functions without the need for users to first add the library to a
project. The SELUtils library does not automatically resolve to the latest version
following a project upgrade; instead, the library will remain at its previous
fixed version in the project to ensure that no functional changes are made when
going online with an RTAC. To force the SELUtils library to resolve to the latest
version, use of the Clean Project function in ACSELERATOR RTAC® SEL-5033
Software.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC
with firmware version R145 or higher.
The SELUtils library is automatically included in RTAC projects built for R143-
V0 or later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
Enumerations defined in this, the SELUtils library, are positioned to be
accessed by various external libraries in order to reduce redundant enumeration
descriptions.

enum_EtherCATClientStatus
This enumeration defines the states for the EtherCAT client status of the SEL
Axion.

Enumeration Value Description

BEGINNING_BOOT_SEQUENCE 1 SEL Axion EtherCAT network is in the process of booting.

READING_SETTINGS 2 SEL Axion module settings are being read over the EtherCAT network.

ADDRESSING_NETWORK 3 SEL Axion EtherCAT network is being addressed.

VERIFYING_NETWORK 4 SEL Axion EtherCAT network is being verified.

OPERATIONAL 5 SEL Axion EtherCAT network is operational and online.

Date Code 20241023 Programming Reference


1064 SELUtils
Enumerations

Enumeration Value Description

CLIENT_FAILED 11 SEL Axion EtherCAT client has failed.

NETWORK_FAILED 12 SEL Axion EtherCAT network has failed.

CLIENT_OVER_BURDENED 13 SEL Axion EtherCAT client burden has exceeded an acceptable value of 70%.

PROCESSING_INTERVAL_EXCEEDED 14 SEL Axion EtherCAT processing has exceeded the defined interval.

enum_FilenameScheme
Enumeration Description

SEL_FILEIO_LOCAL SEL IEC 61131-3 FileIO library file naming scheme


requirements for the local RTAC file system.
Invalid characters: ", ', :, <, %, >, ?, \, |, //, /./, /../

SEL_FILEIO_REMOTE SEL IEC 61131-3 FileIO library file naming scheme


requirements for remote server file systems.
Invalid characters: ", '

IEEE_COMNAME IEEE COMNAME (C37.232-2011) file naming scheme


requirements.
Invalid characters: ?, ", /, \, <, >, *, |, :, ;, [, ], $, %, {, }

enum_RegExOutputTypes
Enumeration Description

JSON_OUTPUT RegEx output file should be generated according to JSON format.

enum_SEL2488AntStatus
This enumeration defines states for the antenna status of an SEL-2488 Satellite-
Synchronized Network Clock polled over SNMP.

Enumeration Value Description

OK 1 OK status.

SHORT 2 There is an electrical short in the antenna connection.

OPEN 3 There is an electrical open in the antenna connection.

enum_SEL2488DSTStatus
This enumeration defines states for the daylight-saving time function of an
SEL-2488 polled over SNMP.

Enumeration Value Description

OFF 1 The daylight-saving time function is turned off.

INACTIVE 2 The daylight-saving time function is turned on, but is not


presently active.

ACTIVE 3 The daylight-saving time function is turned on and is


presently active.

Programming Reference Date Code 20241023


SELUtils 1065
Enumerations

enum_SEL2488IPAddrType
This enumeration defines states for the IP address type of an Ethernet port on an
SEL-2488 polled over SNMP.

Enumeration Value Description

UNKNOWN 0 The IP address type for the Ethernet port is unknown.

IPV4 1 The IP address type for the Ethernet port is IPv4.

IPV6 2 The IP address type for the Ethernet port is IPv6.

IPV4Z 3 The IP address type for the Ethernet port is IPv4Z.

IPV6Z 4 The IP address type for the Ethernet port is IPv6Z.

DNS 5 The IP address type for the Ethernet port is DNS.

enum_SEL2488MediaType
This enumeration defines states for the Ethernet port media of an SEL-2488
polled over SNMP.

Enumeration Value Description

BASET 1 The Ethernet port is BASE-T.

BASEFX 2 The Ethernet port is BASE-FX.

BASELX10 3 The Ethernet port is BASE-LX10.

enum_SEL2488PortStatus
This enumeration defines states for the Ethernet port status of an SEL-2488
polled over SNMP.

Enumeration Value Description

ENABLED 1 The Ethernet port is enabled.

DISABLED 2 The Ethernet port is disabled.

enum_SEL2488PTPState
This enumeration defines states for the PTP state of an SEL-2488 polled over
SNMP.

Enumeration Value Description

INITIALIZING 1 PTP functionality is in its initialization state.

FAULTY 2 PTP functionality is faulty.

DISABLED 3 PTP functionality is disabled.

LISTENING 4 PTP functionality is listening.

PRE_MASTER 5 PTP functionality is operating as pre-master.

Date Code 20241023 Programming Reference


1066 SELUtils
Structures

Enumeration Value Description

MASTER 6 PTP functionality is operating as master.

PASSIVE 7 PTP functionality is operating passively.

UNCALIBRATED 8 PTP functionality is uncalibrated.

SLAVE 9 PTP functionality is operating as slave.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Structures defined in this, the SELUtils library, are positioned to be accessed by


various external libraries in order to reduce redundant structure descriptions.

struct_RegExRule
Name IEC 61131 Type Description

Label STRING(255) Label to be associated with the particular rule specified; will be used to identify
respondent data in resultant RegEx file.

pt_RegEx POINTER TO BYTE Pointer to the first byte of a Regular Expression characterization string; must meet
the Perl5 RegEx syntax requirements; characters that should be escaped (not treated
as control characters) should be preceded by a double-backslash (e.g., \\)

RegExLength UDINT Number of characters that are contained in the string of Regular Expression
characters referenced by the pt_RegEx pointer.

Instances UINT Number of instances that the Regular Expression should be applied to find
sequential results.

Global Constants
This section lists values of math and global constants provided for facilitating
work.

Table 36.1

Name Data Type Value and Description

PI REAL 3.14159265358979323846
Numeric value for mathematical
constant Pi

FLOAT_MAX REAL 3.4028234663852885981170418E+38


Largest floating point

FLOAT_MIN REAL 1.1754943508222875079687365E-38


Smallest positive normal floating point

ULINT_MAX REAL 16#FFFF_FFFF_FFFF_FFFF


Largest ULINT

LINT_MAX REAL 16#7FFF_FFFF_FFFF_FFFF


Largest LINT

Programming Reference Date Code 20241023


SELUtils 1067
Functions

Name Data Type Value and Description

LINT_MAX REAL 16#7FFF_FFFF_FFFF_FFFF


Largest LINT

LINT_MIN REAL –16#8000_0000_0000_0000


Smallest LINT

UDINT_MAX REAL 16#FFFF_FFFF


Largest UDINT

DINT_MAX REAL 16#7FFF_FFFF


Largest DINT

DINT_MIN REAL –16#8000_0000


Smallest DINT

UINT_MAX REAL 16#FFFF


Largest UINT

INT_MAX REAL 16#7FFF


Largest INT

INT_MIN REAL –16#8000


Smallest INT

SINT_MAX REAL 16#7F


Largest SINT

SINT_MIN REAL –16#80


Smallest SINT

INFINITY REAL FLOAT_MAX2


Force positive infinity by calculating
overflow

g_c_SYM_ALPHA vector_t 1Ð120°


symmetrical components alpha

g_c_SYM_ALPHA_SQUARED vector_t 1Ð−120°


symmetrical components alpha-squared

g_c_ONE_THIRD REAL 1/3


One-over-Three

g_c_ROOT_TWO REAL
Square-Root-of-Two

g_c_INV_ROOT_TWO REAL

One-over-Square-Root-of-Two

g_c_ROOT_THREE REAL
Square-Root-of-Three

g_c_INV_ROOT_THREE REAL

One-over-Square-Root-of-Three

Functions
This library provides various utility functions, subroutines that can be utilized by
the user.

Date Code 20241023 Programming Reference


1068 SELUtils
Functions

fun_IsValidReal (Function)
This function accepts a value of type REAL and returns TRUE if it is a valid
number. The function outputs a STRING representation of the value. If the
number is valid, the STRING representation will be the result of calling
REAL_TO_STRING on the input. Otherwise, the function will return FALSE
and the STRING representation will be 'Infinity', '-Infinity', or 'NaN'
("Not a Number"), as the value dictates.

Inputs
Name IEC 61131 Type Description

inReal REAL The value to validate.

Outputs
Name IEC 61131 Type Description

stringRepresentation STRING STRING representation of inReal.

Return Value
IEC 61131 Type Description

BOOL TRUE if the value inReal is a valid number.

Processing
➤ The function converts inReal to a STRING and assigns the result to
output stringRepresentation. If inReal is not a valid number, the STRING
representation will be 'Infinity', '–Infinity', or 'NaN' ("Not a
Number"), as the value dictates.
➤ If inReal is a valid number, the function returns TRUE. Otherwise, the
function returns FALSE.

fun_IsValidLreal (Function)
This function accepts a value of type LREAL and returns TRUE if it is a
valid number. The function outputs a STRING representation of the value. If
the number is valid, the STRING representation will be the result of calling
LREAL_TO_STRING on the input. Otherwise, the function will return FALSE
and the STRING representation will be 'Infinity', '-Infinity', or 'NaN'
("Not a Number"), as the value dictates.

Inputs
Name IEC 61131 Type Description

inLreal LREAL The value to validate.

Programming Reference Date Code 20241023


SELUtils 1069
Functions

Outputs
Name IEC 61131 Type Description

stringRepresentation STRING STRING representation of inLreal.

Return Value
IEC 61131 Type Description

BOOL TRUE if the value inLreal is a valid number.

Processing
➤ The function converts inLreal to a STRING and assigns the result to
output stringRepresentation. If inLreal is not a valid number, the STRING
representation will be 'Infinity', '-Infinity', or 'NaN' ("Not a
Number"), as the value dictates.
➤ If inLreal is a valid number, the function returns TRUE. Otherwise, the
function returns FALSE.

fun_IsValidFilename (Function)
Function to validate a STRING(255) input representing a filename, returns
TRUE if valid filename without any invalid characters, FALSE otherwise.
Invalid character set is designated by the enum_FilenameScheme input.

Inputs
Name IEC 61131 Type Description

Filename STRING(255) Filename which should be validated.

NameScheme enum_FilenameScheme Filename validation scheme which name


should be validated against.

Return Value
IEC 61131 Type Description

BOOL Indicator of valid filename, TRUE when input does not contain any
illegal characters, FALSE otherwise.

Processing
➤ The function validates that each character in the input string is a valid,
printable ASCII character.
➤ The function validates that none of the invalid characters described by the
NameScheme input are contained within the input string.

Date Code 20241023 Programming Reference


1070 SELUtils
Functions

fun_IsValidHexChar (Function)
This function takes a BYTE and determines if it is a valid representation of a
hexadecimal digit in ASCII range 48–57 (0–9), 65–70 (A–F), or 97–102 (a–f).

Inputs
Name IEC 61131 Type Description

character BYTE Byte to be evaluated as a hexadecimal digit.

Return Value
IEC 61131 Type Description

BOOL TRUE if character is a valid hexadecimal notation digit.

Processing
If character is within the ASCII range for hexadecimal digits ( 48–57 (0–9), 65–
70 (A–F), or 97–102 (a–f)), this function returns TRUE. Otherwise, it returns
FALSE.

fun_IsValidHexString (Function)
This function takes a STRING(255) and returns TRUE if all characters are valid
hexadecimal digits (0–9), (A–F), or (a–f). Otherwise, it returns FALSE.

Inputs
Name IEC 61131 Type Description

Input STRING String to be evaluated as hexadecimal digits.

Return Value
IEC 61131 Type Description

BOOL TRUE if Input contains only valid hexadecimal digits.

Processing
➤ Compares each element of the string using fun_IsValidHexChar.
➤ Returns TRUE if all characters in STRING are valid hexadecimal digits;
otherwise, returns FALSE.

Programming Reference Date Code 20241023


SELUtils 1071
Functions

FORMAT_SIGNIFICANT_FIGURES (Function)
This function returns a string evaluation of the provided number, presenting only
the specified number of significant figures. Digits that are not significant are set
to zero where appropriate. The function accepts any standard numeric type such
as INT, REAL, etc.

Inputs
Name IEC 61131 Type Description

IN ANY_NUM Value whose significant figures should be


evaluated.

Figures USINT(1..6) Number of significant figures to evaluate.

Return Value
IEC 61131 Type Description

STRING The formatted number represented as a STRING.

Example in Structured Text: (* Result in VarStr is '50.1' *)

aReal := 50.123;

VarStr := FORMAT_SIGNIFICANT_FIGURES(aReal, Figures := 3);

Example in Structured Text: (* Result in VarStr is '5010' *)

anLreal := 5012.3;

VarStr := FORMAT_SIGNIFICANT_FIGURES(anLreal, Figures := 3);

Processing
➤ The number IN is formatted as a STRING. If the input type is REAL, a
maximum of 5 decimal places of precision are retained. If the input type
is LREAL, a maximum of 13 decimal places of precision are retained.
➤ The evaluated string is processed from left to right to determine which
characters will be retained and which will be set to zero in order to
maintain significance.
➤ If zeros trailing the decimal place are encountered, the decimal and any
trailing zeros are removed.
➤ The formatted STRING is returned.

REAL_IS_ZERO (Function)
This function takes a REAL or LREAL variable and evaluates whether the
value contained in the variable represents zero (accounting for floating-point
offset, errors, and "negative-zero", which all evaluate to zero in a floating-
point system). This function will return TRUE if the value is determined to be
equivalent to zero for computational purposes, and return FALSE otherwise.

Date Code 20241023 Programming Reference


1072 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

IN ANY_REAL The REAL or LREAL variable whose value should


be verified as zero.

Return Value
IEC 61131 Type Description

BOOL TRUE if the REAL can effectively be considered zero; FALSE


otherwise.

Processing
➤ The number IN is converted to an LREAL.
➤ If the absolute value of the number is less than the floating-point
minimum (FLOAT_MIN, see Table 36.1), the function evaluates as
TRUE; otherwise, it evaluates as FALSE.

REAL_APPROX_EQUAL (Function)
This function takes two REAL or LREAL variables and evaluates whether the
values contained in the variables are equal when accounting for floating-point
precision limitations.

This function will return TRUE if the values are determined to be equivalent and
will return FALSE otherwise. The allowed error for any comparison is ±1 bit.
Both inputs must be of the same type. If the inputs are not the same type (i.e,.
one REAL and one LREAL), the result will be FALSE.

Inputs
Name IEC 61131 Type Description

IN1 ANY_REAL The first REAL or LREAL variable whose value


should be tested for near equality.

IN2 ANY_REAL The second REAL or LREAL variable whose value


should be tested for near equality.

Return Value
IEC 61131 Type Description

BOOL TRUE if the two inputs are approximately equal (within one bit
difference between the two values); FALSE otherwise. If the inputs are
not of the same IEC 61131 type, the result will be FALSE.

Programming Reference Date Code 20241023


SELUtils 1073
Functions

Processing
➤ The bits of both numbers IN1 and IN2 are packed into integer values to
allow for literal bit comparisons.
➤ If the difference between the two values is less than or equal to 1,
REAL_APPROX_EQUAL returns TRUE; otherwise, it returns FALSE.

REAL_TO_FORMATTED_STRING (Function)
This function takes a REAL variable, a BOOLEAN specifying either standard
or scientific notation, and the desired number of decimals to display. It returns
a formatted STRING representing the value of the floating-point number
provided.

Inputs
Name IEC 61131 Type Description

inReal REAL The value to format as a STRING.

useScientificNotation BOOL Set to FALSE for standard notation and TRUE


for scientific notation.

decimals UINT(0..5) The number of decimal places to include in the


range [0..5].

Return Value
IEC 61131 Type Description

STRING(255) The formatted number represented as a STRING.

Processing
➤ The number inReal is converted to a STRING in either standard or
scientific notation, specified by the useScientificNotation parameter, and
with the number of decimal places specified in the decimals parameter.
➤ If the number of decimal places specified is outside of the range [0..5], it
defaults to 3.
➤ The formatted STRING is returned.

LREAL_TO_FORMATTED_STRING (Function)
This function takes an LREAL variable, a BOOLEAN specifying either standard
or scientific notation, and the desired number of decimals to display. It returns
a formatted STRING representing the value of the floating-point number
provided.

Date Code 20241023 Programming Reference


1074 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

inLreal LREAL The value to format as a STRING.

useScientificNotation BOOL Set to FALSE for standard notation and TRUE


for scientific notation.

decimals UINT(0..13) The number of decimal places to include in the


range [0..13].

Return Value
IEC 61131 Type Description

STRING(255) The formatted number represented as a STRING.

Processing
➤ The number inLreal is converted to a STRING in either standard or
scientific notation, specified by the useScientificNotation parameter, and
with the number of decimal places specified in the decimals parameter.
➤ If the number of decimal places specified is outside of the range [0..13], it
defaults to 3.
➤ The formatted STRING is returned.

MV_TO_FORMATTED_STRING (Function)
This function takes an MV variable, a BOOLEAN specifying either standard or
scientific notation, the desired number of decimals to display, and a STRING as
a delimiter. It returns a formatted STRING representing the .instMag component
of the MV provided, its time stamp, and its quality.

Inputs
Name IEC 61131 Type Description

inMV MV The value to format as a STRING.

useScientificNotation BOOL Set to FALSE for standard notation and TRUE for scientific notation.

decimals UINT(0..5) The number of decimal places to include in the range [0..5].

delimiterString STRING The character used to separate the contents of the resultant string. If the
character is an empty string, the output will be in the form: magnitude
[YYYY-MM-DD-hh:mm:ss.000000 / quality].

Return Value
IEC 61131 Type Description

STRING(255) The formatted number represented as a STRING.

Programming Reference Date Code 20241023


SELUtils 1075
Functions

Processing
➤ The .instMag attribute taken from measured value inMV is converted
to a STRING in either standard or scientific notation, specified
by the useScientificNotation parameter, and with the number
of decimal places specified in the decimals parameter using the
REAL_TO_FORMATTED_STRING function.
➤ The time when the value was measured is taken using the function
TIMESTAMP_TO_STRING and added to the formatted string.
➤ The quality when the value was measured is taken using the function
VALIDITY_TO_STRING and added to the formatted string.
➤ If an empty string is used as the delimiter, the formatted
STRING is returned in the format: Numeric value
[YYYY-MM-DD-hh:mm:ss.000000 / quality]
➤ If a comma is used as a delimiter, the formatted STRING is returned in
the format: Numeric value,YYYY-MM-DD-hh:mm:ss.000000,quality

CMV_TO_FORMATTED_STRING (Function)
This function takes a CMV variable, a BOOLEAN specifying either standard
or scientific notation, the desired number of decimals to display, a BOOLEAN
specifying either polar or rectangular coordinates, and a STRING as a delimiter.
It returns a formatted STRING representing the values of the instCVal.mag
and instCVal.ang components of the CMV provided in polar or rectangular
coordinates, its time stamp and its quality.

Inputs
Name IEC 61131 Type Description

inCMV CMV The value to format as a STRING.

useScientificNotation BOOL Set to FALSE for standard notation and TRUE for scientific notation.

decimals UINT(0..5) The number of decimal places to include in the range [0..5].

useRectangularCoordinates BOOL Set to FALSE for polar coordinates and TRUE for rectangular coordinates.

delimiterString STRING The character used to separate the contents of the resultant string. If the
character is an empty string, the output will be in the form: (magnitude, angle°)
[YYYY-MM-DD- hh:mm:ss.000000 / quality].

Return Value
IEC 61131 Type Description

STRING(255) The formatted number represented as a STRING.

Date Code 20241023 Programming Reference


1076 SELUtils
Functions

Processing
➤ The .instCVal.mag attribute taken from complex measured value
inCMV is converted to a STRING in either standard or scientific
notation, specified by the useScientificNotation parameter, and with the
number of decimal places specified in the decimals parameter using the
REAL_TO_FORMATTED_STRING function.
➤ The .instCVal.ang attribute taken from complex measured value inCMV is
converted to a STRING using two decimal places.
➤ If useRectangularCoordinates is set to TRUE, the rectangular coordinates
are obtained using the function vector_t_TO_struct_ComplexRect.
➤ The time when the value was measured is taken using the function
TIMESTAMP_TO_STRING and added to the formatted string.
➤ The quality when the value was measured is taken using the function
VALIDITY_TO_STRING and added to the formatted string.
➤ If useRectangularCoordinates is set to TRUE, and a comma is used
as the delimiter, the formatted STRING is returned in the format: real
±imaginary,YYYY-MM-DD-hh: mm:ss.000000,quality.
➤ If useRectangularCoordinates is set to FALSE, and an empty string is
used as the delimiter, the formatted STRING is returned in the format:
(magnitude, angle°) [YYYY-MM-DD-hh:mm:ss.000000 / quality].
➤ If useRectangularCoordinates is set to FALSE, and a comma is
used as a delimiter, the formatted STRING is returned in the format:
magnitude,angle°,YYYY-MM-DD-hh:mm:ss.000000,quality.

INS_TO_FORMATTED_STRING (Function)
This function takes an INS variable, a BOOLEAN specifying either standard or
scientific notation, the desired number of decimals to display, and a STRING as
a delimiter. It returns a formatted STRING representing the value of the .stVal
component of the INS provided, its time stamp, and its quality.

Inputs
Name IEC 61131 Type Description

inINS INS The value to format as a STRING.

useScientificNotation BOOL Set to FALSE for standard notation and TRUE for scientific notation.

decimals UINT(0..5) The number of decimal places to include in the range [0..5].

delimiterString STRING The character used to separate the contents of the resultant string. If the
character is an empty string, the output will be in the form: Numeric Value
[YYYY-MM-DD-hh:mm:ss.000000 / quality].

Return Value
IEC 61131 Type Description

STRING(255) The formatted number represented as a STRING.

Programming Reference Date Code 20241023


SELUtils 1077
Functions

Processing
➤ The .stVal attribute taken from the value inINS is converted to
a STRING in either standard or scientific notation, specified
by the useScientificNotation parameter, and with the number
of decimal places specified in the decimals parameter using the
REAL_TO_FORMATTED_STRING function and DINT_TO_REAL
conversion operator. Note that the number of decimals is only considered
if useScientificNotation is TRUE.
➤ The time when the value was measured is taken using the function
TIMESTAMP_TO_STRING and added to the formatted string.
➤ The quality when the value was measured is taken using the function
VALIDITY_TO_STRING and added to the formatted string.
➤ If an empty string is used as the delimiter, the formatted STRING
is returned in the format: Numeric value [YYYY-MM-DD-
hh:mm:ss.000000 / quality]
➤ If a comma is used as a delimiter, the formatted STRING is returned in
the format: Numeric value,YYYY-MM-DD-hh:mm:ss.000000,quality

SPS_TO_FORMATTED_STRING (Function)
This function takes an SPS variable, a BOOLEAN specifying either Boolean
(TRUE/FALSE) or numeric notation (1/0), and a STRING as a delimiter. It
returns a formatted STRING representing the .stVal component of the SPS
provided, its time stamp, and its quality.

Inputs
Name IEC 61131 Type Description

inSPS SPS The value to format as a STRING.

useScientificNotation BOOL Set to FALSE for Boolean notation (TRUE/FALSE) for numeric notation (1/0).

delimiterString STRING The character used to separate the contents of the resultant string. If the
character is an empty string, the output will be in the form: Boolean State
[YYYY-MM-DD-hh:mm:ss.000000 / quality].

Return Value
IEC 61131 Type Description

STRING(255) The formatted Boolean represented as a STRING.

Processing
➤ The .stVal attribute taken from the status inSPS is converted to a
STRING in either Boolean or numeric notation, specified by the
useNumericNotation parameter.
➤ If the numeric notation is set to TRUE, the formatted STRING is returned
with a 1 or a 0 for the status of the BOOLEAN attribute.
➤ The time when the value was measured is taken using the function
TIMESTAMP_TO_STRING and added to the formatted string.

Date Code 20241023 Programming Reference


1078 SELUtils
Functions

➤ The quality when the value was measured is taken using the function
VALIDITY_TO_STRING and added to the formatted string.
➤ If an empty string is used as the delimiter, the formatted STRING
is returned in the format: Boolean Status [YYYY-MM-DD-
hh:mm:ss.000000 / quality]
➤ If a comma is used as a delimiter, the formatted STRING is returned in
the format: Boolean Status,YYYY-MM-DD-hh:mm:ss.000000,quality

BCR_TO_FORMATTED_STRING (Function)
This function takes a BCR variable, a BOOLEAN specifying either standard or
scientific notation, the desired number of decimals to display, and a STRING as
a delimiter. It returns a formatted STRING representing the value of the .actVal
and the .frVal components of the BCR provided, its time stamp, and its quality.

Inputs
Name IEC 61131 Type Description

inBCR BCR The value to format as a STRING.

useScientificNotation BOOL Set to FALSE for standard notation and TRUE for scientific notation.

decimals UINT(0..5) The number of decimal places to include in the range [0..5].

delimiterString STRING The character used to separate the contents of the resultant string. If the character
is an empty string, the output will be in the form: Numeric Value / Numeric Value
[YYYY-MM-DD-hh:mm:ss.000000 / quality].

Return Value
IEC 61131 Type Description

STRING(255) The formatted values represented as a STRING.

Processing
➤ The .actVal and .frVal components taken from the value inBNC are
converted to a STRING in either standard or scientific notation,
specified by the useScientificNotation parameter, and with the number
of decimal places specified in the decimals parameter using the
REAL_TO_FORMATTED_STRING function and UDINT_TO_REAL
conversion operator. Note that the number of decimals is only considered
if useScientificNotation is TRUE.
➤ The time when the value was measured is taken using the function
TIMESTAMP_TO_STRING and added to the formatted string.
➤ The quality when the value was measured is taken using the function
VALIDITY_TO_STRING and added to the formatted string.
➤ If an empty string is used as the delimiter, the formatted STRING is
returned in the format: Numeric value / Numeric value [YYYY-MM-
DD-hh:mm:ss.000000 / quality]
➤ If a comma is used as a delimiter, the formatted STRING is returned
in the format: Numeric value,Numeric value,YYYY-MM-DD-
hh:mm:ss.000000,quality

Programming Reference Date Code 20241023


SELUtils 1079
Functions

TIMESTAMP_TO_STRING (Function)
This function takes a timestamp_t structure and returns it as a STRING
in the form YYYY-MM-DD-hh:mm:ss.000000. For example,
2018-08-02-23:43:07.364814 represents the August 2nd, 2018, at 43 minutes, 7
seconds, and 364814 microseconds into the 23rd hour.

Inputs
Name IEC 61131 Type Description

inTimestamp timestamp_t The time stamp to convert to a STRING.

Return Value
IEC 61131 Type Description

STRING(80) The timestamp_t structure represented as a STRING.

Processing
➤ The timestamp_t structure is returned as a STRING in the form YYYY-
MM-DD-hh: mm:ss.000000.

TIMESTAMP_TO_UTC (Function)
This function takes a timestamp_t structure and returns a timeStamp_t adjusted
to UTC time, based on the offsets in the timeStamp_t that is passed in.
The resulting timeStamp_t structure will be identical to the structure passed in,
except that the DST and UTC offsets will be set to zero, and the time will be
adjusted to UTC.

Inputs
Name IEC 61131 Type Description

timeStampIn timeStamp_t The time stamp to convert to a UTC.

Return Value
IEC 61131 Type Description

timeStamp_t The timestamp_t structure adjusted to UTC.

Processing
➤ The returned timestamp_t structure contains a time stamp in UTC that is
derived from the time stamp, DST offset (taking into account the DST
enabled and active statuses), and UTC offset of the timestamp_t structure
that is passed in. The DST and UTC offset for the returned timestamp_t
structure are set to zero.

Date Code 20241023 Programming Reference


1080 SELUtils
Functions

fun_WrapTo360 (Function)
This function takes a REAL representing an angle in degrees and returns a
REAL wrapped between 0 and 360 degrees. This function will apply formatting
to ensure that angles conform with the limits of 0 and 360 (inclusive of zero).
Inputs with angles which do not conform will be adjusted accordingly. Such
examples of these angles are:

➤ Negative angles (i.e., −45°)


➤ Angles whose absolute value is greater than 360 (i.e., ±520°)

Inputs
Name IEC 61131 Type Description

Input REAL The REAL input representing an angle to be


wrapped.

Return Value
IEC 61131 Type Description

REAL The REAL variable whose angle has been wrapped between 0
and 360 degrees.

Example in Structured Text: (* Result in VarAng is 270 *)

VarAng := fun_WrapTo360(–90);

Processing
➤ The magnitude, time, and quality attributes are directly mapped from
input to output, and the angle will be wrapped to fit within the boundaries
of 0 and 360 degrees.

fun_WrapTo180 (Function)
This function takes a REAL representing an angle in degrees and returns
a REAL wrapped between –180 and 180 degrees. This function will apply
formatting to ensure that angles conform with the limits of –180 and 180
(inclusive of 180). Inputs with angles which do not conform will be adjusted
accordingly. Such examples of these angles are:

➤ Angles evaluated between 180 and 360 degrees (i.e., −270°)


➤ Angles whose absolute value is greater than 360 (i.e., ±520°)

Inputs
Name IEC 61131 Type Description

Input REAL The REAL input representing an angle to be


wrapped.

Programming Reference Date Code 20241023


SELUtils 1081
Functions

Return Value
IEC 61131 Type Description

REAL The REAL variable whose angle has been wrapped between –
180 and 180 degrees.

Example in Structured Text: (* Result in VarAng is –90 *)

VarAng := fun_WrapTo180(270);

Processing
➤ The magnitude, time, and quality attributes are directly mapped from
input to output, and the angle will be wrapped to fit within the boundaries
of –180 and 180 degrees.

fun_dateTime_t_TO_ULINT (Function)
This function takes a dateTime_t structure and returns a ULINT representing the
time since epoch (1970-01-01:00:00:00.000000) in units of microseconds.

Inputs
Name IEC 61131 Type Description

Input dateTime_t The date time to convert to a ULINT.

Return Value
IEC 61131 Type Description

ULINT Representation of Input in units of microseconds since epoch


(1970-01- 01:00:00:00.000000).

Processing
➤ Both dateTime and uSec structure components are converted to ULINT
representations and scaled such that they represent microseconds before
being added together and returned.

fun_ULINT_TO_dateTime_t (Function)
This function takes a ULINT representing microseconds since epoch
(1970-01-01:00:00:00.000000) and returns a dateTime_t structure evaluation of
the ULINT.

Date Code 20241023 Programming Reference


1082 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

Input ULINT The ULINT storing time in units of microseconds


since epoch (1970-01-01:00:00:00.000000) to be
converted.

Return Value
IEC 61131 Type Description

dateTime_t Representation of Input ULINT in microseconds.

Processing
➤ Both dateTime and uSec structure components are constructed using a
decomposition of the ULINT.

fun_AddTIME (Function)
This function adds an input TIME quantity to an input dateTime_t quantity and
returns an adjusted dateTime_t quantity.

Inputs
Name IEC 61131 Type Description

TimeToAdd TIME Amount of time to add to the reference input.

DateTimeIn dateTime_t Reference input time stamp to be adjusted by


TimeToAdd.

Return Value
IEC 61131 Type Description

dateTime_t The effective addition of TimeToAdd and DateTimeIn.

Processing
➤ Both the dateTime_t value and the TIME are converted to their ULINT
representations before the TIME value is added to the dateTime_t value.
➤ If the resultant ULINT experiences a rollover in the positive direction
(effectively passes zero and becomes a very small number) the ULINT
will be forced to , thus preparing the returned dateTime_t to
represent the maximum supported time for the dateTime_t structure.
➤ The resultant ULINT is converted back to a dateTime_t structure.

Programming Reference Date Code 20241023


SELUtils 1083
Functions

fun_AddLTIME (Function)
This function adds an input LTIME quantity to an input dateTime_t quantity and
returns an adjusted dateTime_t quantity.

Inputs
Name IEC 61131 Type Description

TimeToAdd LTIME Amount of time to add to the reference input.

DateTimeIn dateTime_t Reference input time stamp to be adjusted by


TimeToAdd.

Return Value
IEC 61131 Type Description

dateTime_t The effective addition of TimeToAdd and DateTimeIn.

Processing
➤ Both the dateTime_t value and the LTIME are converted to their ULINT
representations before the LTIME value is added to the dateTime_t value.
➤ If the resultant ULINT experiences a rollover in the positive direction
(effectively passes zero and becomes a very small number) the ULINT
will be forced to , thus preparing the returned dateTime_t to
represent the maximum supported time for the dateTime_t structure.
➤ The resultant ULINT is converted back to a dateTime_t structure.

fun_SubtractTIME (Function)
This function subtracts an input TIME quantity from an input dateTime_t
quantity and returns an adjusted dateTime_t quantity.

Inputs
Name IEC 61131 Type Description

TimeToSubtract TIME Amount of time to subtract from the reference


input.

DateTimeIn dateTime_t Reference input time stamp to be adjusted by


TimeToSubtract.

Return Value
IEC 61131 Type Description

dateTime_t The effective subtraction of TimeToSubtract from


DateTimeIn.

Date Code 20241023 Programming Reference


1084 SELUtils
Functions

Processing
➤ Both the dateTime_t value and the TIME are converted to their ULINT
representations before the TIME value is subtracted from the dateTime_t
value.
➤ If the resultant ULINT experiences a rollover in the negative direction
(effectively passes zero and becomes a very large number) the ULINT
will be forced to zero, thus preparing the returned dateTime_t to represent
the epoch.
➤ The resultant ULINT is converted back to a dateTime_t structure.

fun_SubtractLTIME (Function)
This function subtracts an input LTIME quantity from an input dateTime_t
quantity and returns an adjusted dateTime_t quantity.

Inputs
Name IEC 61131 Type Description

TimeToSubtract LTIME Amount of time to subtract from the reference


input.

DateTimeIn dateTime_t Reference input time stamp to be adjusted by


TimeToSubtract.

Return Value
IEC 61131 Type Description

dateTime_t The effective subtraction of TimeToSubtract from


DateTimeIn.

Processing
➤ Both the dateTime_t value and the LTIME are converted to their ULINT
representations before the LTIME value is subtracted from the dateTime_t
value.
➤ If the resultant ULINT experiences a rollover in the negative direction
(effectively passes zero and becomes a very large number) the ULINT
will be forced to zero, thus preparing the returned dateTime_t to represent
the epoch.
➤ The resultant ULINT is converted back to a dateTime_t structure.

fun_Checksum (Function)
This function accepts a pointer to BYTE and array length input and evaluates
the sum of ASCII encoded values, returning a string representing the summation
as a hex string. The resulting string will be clamped to the range of a WORD
variable (0 to 65535), and thus will always be 4 ASCII characters in length.

Programming Reference Date Code 20241023


SELUtils 1085
Functions

Inputs
Name IEC 61131 Type Description

pt_Byte POINTER TO BYTE Pointer to the first character in a string or array


of bytes whose values should be evaluated using
a checksum.

Length UDINT Number of bytes in array which should be


evaluated in the checksum.

Return Value
IEC 61131 Type Description

STRING(4) The hex string representing the output sum of all input bytes.

Example in Structured Text: (* Result in VarString is '0902' *)

InString := '"FID=SEL-351-7-R405-V0-Z010006-D20120203",';

VarString := fun_Checksum(ADR(InString), TO_UDINT(LEN(InString)));

Processing
➤ The ASCII values of each character in the input string are summed.
➤ The summation result is converted to a string representing the number in
hex.

fun_GetBit (Function)
This function allows a bit-level read operation from a bit pattern stored in a
BYTE, WORD, DWORD, or LWORD data type. Returns FALSE and does no
work if the BitIndex input is out of bounds for the given datatype.

Inputs
Name IEC 61131 Type Description

InPattern ANY_BIT Input bit pattern to be analyzed. Accepts BYTE,


WORD, DWORD, and LWORD data types.

BitIndex UINT Zero-based index of bit status to retrieve from


InPattern.

Outputs
Name IEC 61131 Type Description

BitStatus BOOL Boolean status of the bit at BitIndex.

Date Code 20241023 Programming Reference


1086 SELUtils
Functions

Return Value
IEC 61131 Type Description

BOOL TRUE if bit status was successfully retrieved.

Processing
➤ Loads BitStatus with the status of the InPattern bit at BitIndex if the
following are true:
➢ The data type of the variable passed into InPattern is included in the
specified list.
➢ The BitIndex is within the range of allowed bit indexes for that data
type. (BYTE : 0–7, WORD : 0–15, DWORD : 0–31, LWORD : 0–63)

fun_SetBit (Function)
This function allows a bit-level write operation to a bit pattern stored in a BYTE,
WORD, DWORD, or LWORD data type. Returns FALSE and does no work if
the BitIndex input is out of bounds for the given datatype.

Inputs
Name IEC 61131 Type Description

InPattern ANY_BIT Input bit pattern to be written to. Accepts BYTE,


WORD, DWORD, and LWORD data types.

BitIndex UINT Zero-based index of bit to overwrite within


InPattern.

SetVal BOOL The value with which to overwrite the InPattern bit
at BitIndex.

Return Value
IEC 61131 Type Description

BOOL TRUE if bit was successfully overwritten.

Processing
➤ Overwrites the InPattern bit at BitIndex with SetVal if the following are
true:
➢ The data type of the variable passed into InPattern is included in the
specified list.
➢ The BitIndex is within the range of allowed bit indexes for that data
type. (BYTE : 0–7, WORD : 0–15, DWORD : 0–31, LWORD : 0–63)

VALIDITY_TO_STRING (Function)
This function takes a validity_t enumeration and returns the validity as a
STRING (good , invalid, reserved, questionable, or undefined).

Programming Reference Date Code 20241023


SELUtils 1087
Functions

Inputs
Name IEC 61131 Type Description

inValidity validity_t The validity_t enumeration to convert to a


STRING.

Return Value
IEC 61131 Type Description

STRING(80) The validity represented as a STRING.

Processing
➤ The validity_t enumeration is returned as a STRING (good , invalid,
reserved, or questionable).
➤ undefined will be returned for a malformed validity_t.

BYTE_TO_ASCII (Function)
This function takes a BYTE and returns the STRING character representation of
the ASCII character code of the BYTE.

Inputs
Name IEC 61131 Type Description

character BYTE The BYTE for which the ASCII representation


should be evaluated.

Return Value
IEC 61131 Type Description

STRING(1) The ASCII representation of the input BYTE.

Example in Structured Text: (* Result in VarString is 'A' *)


VarString := BYTE_TO_ASCII(65);

Processing
➤ The ASCII character code representation of the input BYTE is evaluated
as a STRING(1).

BYTES_TO_IPv4_STRING (Function)
This function accepts a source IP address represented as a four-character string
whose bytes each represent a single octet in the IP. It returns a period-delimited
string of each octet in decimal notation.

Date Code 20241023 Programming Reference


1088 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

IpAddressBytes STRING(4) Four bytes (STRING[4]) whose numeric values


represent each octet in IP.

Return Value
IEC 61131 Type Description

STRING(15) The formatted IP address as a.b.c.d where each letter is an


IPv4 octet.

Example in Structured Text: (* Result in VarString is '192.168.1.2' *)

VarString := BYTES_TO_IPv4_STRING( '$C0$AB$01$02' );

Processing
➤ Each byte of the input string is evaluated as a hex number and its decimal
equivalent is placed in the IPv4 string.

BYTES_TO_MAC_ADDRESS_STRING (Function)
This function accepts a source MAC address represented as a six-character
string whose bytes each represent a single octet in the MAC address. It returns a
hyphen-delimited string of each octet encoded in hex.

Inputs
IEC 61131
Name Description
Type

MacAddressBytes STRING(6) Six bytes (STRING[6]) whose numeric values


represent each octet in MAC address.

Return Value
IEC 61131 Type Description

STRING(17) The formatted MAC as a STRING in the form of 'AA-BB-CC-DD-EE-


FF'.

Example in Structured Text: (* Result in VarString is '00-B0-D0-63-C2-26' *)

VarString :=
BYTES_TO_MAC_ADDRESS_STRING( '$00$B0$D0$63$C2$26' );

Processing
➤ The originating bytes are converted to a hex equivalent and padded with
delimiting hyphens to present the MAC in ASCII.

Programming Reference Date Code 20241023


SELUtils 1089
Functions

BYTE_TO_HEX_STRING (Function)
This function takes a BYTE and returns the STRING of the byte's numeric
representation encoded in hexadecimal.

Inputs
Name IEC 61131 Type Description

Input BYTE The BYTE for which the hex representation should
be evaluated.

Return Value
IEC 61131 Type Description

STRING(2) The hexadecimal representation of the numeric value of the input


BYTE.

Example in Structured Text: (* Result in VarString is '9C' *)

VarString := BYTE_TO_HEX_STRING(156);

Processing
➤ The hex-encoded numeric representation of the input BYTE is evaluated
as a STRING.

HEX_STRING_TO_BYTE (Function)
This function takes a STRING(2) representing the two-character ASCII
representation of a single byte and returns the BYTE equivalent.

Inputs
Name IEC 61131 Type Description

Input STRING(2) The hexadecimal STRING whose value should be


converted to a plain byte.

Return Value
IEC 61131 Type Description

BYTE The byte representation of the HEX input.

Example in Structured Text: (* Result in VarByte is 156 *)

VarByte := HEX_STRING_TO_BYTE('9C');

Date Code 20241023 Programming Reference


1090 SELUtils
Functions

Processing
➤ The string representing the HEX ASCII characters is converted to a BYTE.
➤ Single-character strings are considered as two-character strings by
appending a leading zero.
➤ If an invalid character is found in the string, the function returns zero.

WORD_TO_HEX_STRING (Function)
This function takes a WORD and returns the STRING of the word's numeric
representation encoded in hexadecimal.

Inputs
Name IEC 61131 Type Description

Input WORD The WORD for which the hexadecimal


representation should be evaluated.

Return Value
IEC 61131 Type Description

STRING(4) The hexadecimal representation of the numeric value of the input


WORD.

Example in Structured Text: (* Result in VarString is '019C' *)


VarString := WORD_TO_HEX_STRING(412);

Processing
➤ The hex-encoded numeric representation of the input WORD is evaluated
as a STRING.

HEX_STRING_TO_WORD (Function)
This function takes a STRING(4) representing the four-character evaluation of a
single word and returns the word equivalent.

Inputs
Name IEC 61131 Type Description

Input STRING(4) The HEX STRING for which the word representation
should be evaluated.

Return Value
IEC 61131 Type Description

WORD The WORD representation of the HEX input.

Programming Reference Date Code 20241023


SELUtils 1091
Functions

Example in Structured Text: (* Result in VarWord is 412 *)

VarWord := HEX_STRING_TO_WORD('019C');

Processing
➤ The string representing the HEX ASCII characters is converted to a WORD.
➤ Strings whose length is less than four are considered as a four-character
string by appending the required leading zeros.
➤ If an invalid character is found in the string, the function returns zero.

DWORD_TO_HEX_STRING (Function)
This function takes a DWORD and returns the STRING of the doubleword's
numeric representation encoded in hexadecimal.

Inputs
Name IEC 61131 Type Description

Input DWORD The DWORD for which the hexadecimal


representation should be evaluated.

Return Value
IEC 61131 Type Description

STRING(8) The hexadecimal representation of the numeric value of the input


DWORD.

Example in Structured Text: (* Result in VarString is '052AD8EB' *)

VarString := DWORD_TO_HEX_STRING(86694123);

Processing
➤ The hex-encoded numeric representation of the input DWORD is
evaluated as a STRING.

HEX_STRING_TO_DWORD (Function)
This function takes a STRING(8) representing the eight-character evaluation of
a doubleword in hexadecimal notation and returns the DWORD equivalent.

Inputs
Name IEC 61131 Type Description

Input STRING(8) The HEX STRING for which the DWORD


representation should be evaluated.

Date Code 20241023 Programming Reference


1092 SELUtils
Functions

Return Value
IEC 61131 Type Description

DWORD The DWORD representation of the HEX input.

Example in Structured Text: (* Result in VarDword is 86694123 *)

VarDword := HEX_STRING_TO_DWORD('052AD8EB');

Processing
➤ The string representing the HEX ASCII characters is converted to a
DWORD.
➤ Strings whose length is less than eight are considered as an eight-
character string by appending the required leading zeros.
➤ If an invalid character is found in the string, the function returns zero.

LWORD_TO_HEX_STRING (Function)
This function takes an LWORD and returns the STRING of the LWORD's
numeric representation encoded in hexadecimal.

Inputs
Name IEC 61131 Type Description

Input LWORD The LWORD for which the hexadecimal


representation should be evaluated.

Return Value
IEC 61131 Type Description

STRING(16) The hexadecimal representation of the numeric value of the input


LWORD.

Example in Structured Text: (* Result in VarString is 'A123400014560089' *)

VarString := LWORD_TO_HEX_STRING(11611194633376628873);

Processing
➤ The hex-encoded numeric representation of the input LWORD is
evaluated as a STRING.

HEX_STRING_TO_LWORD (Function)
This function takes a STRING(16) representing the sixteen-character ASCII
representation of a single LWORD and returns the LWORD equivalent.

Programming Reference Date Code 20241023


SELUtils 1093
Functions

Inputs
Name IEC 61131 Type Description

Input STRING(16) The hexadecimal STRING whose value should be


converted to a plain LWORD.

Return Value
IEC 61131 Type Description

LWORD The LWORD representation of the HEX input.

Example in Structured Text: (* Result in VarLword is


11611194633376628873 *)

VarLword := HEX_STRING_TO_LWORD('A123400014560089');

Processing
➤ The string representing the HEX ASCII characters is converted to an
LWORD.
➤ Strings whose length is less than sixteen are considered as a sixteen-
character string by appending the required leading zeros.
➤ If an invalid character is found in the string, the function returns zero.

fun_GenerateUUID4 (Function)
This function generates a Universally Unique Identifier (UUID) as a 36-
character long string of the format: "XXXXXXXX-XXXX-XXXX-XXXX-
XXXXXXXXXXXX", where all X characters are hexadecimal (0–9, A–F)
characters. The UUID is generated by constructing four random UDINTs (32-
bit values) and using their respective bytes converted to hexadecimal string
equivalent.

Return Value
IEC 61131 Type Description

STRING(36) String representing the UUID.

Example in Structured Text:

VarString := fun_GenerateUUID4();

Processing
➤ Four random UDINT values are generated using SELRand.
➤ A bitmask is applied to set the four most significant bits of the seventh
byte to 0x0100, setting the hexadecimal character to '4'.

Date Code 20241023 Programming Reference


1094 SELUtils
Functions

➤ A bitmask is applied to set the two most significant bits of the ninth byte
to 0x10, setting the hexadecimal character to be one of '8', '9', 'A', or 'B'.
➤ Each byte is placed into the required UUID format with appropriate
delimiting hyphen characters.

fun_PadString (Function)
This function pads a string with a character (either appending or prepending)
repeatedly until the length of the concatenated string is equal to the desired total
length.

Inputs
Name IEC 61131 Type Description

InString STRING(255) The input string that should be appended or optionally prepended with padded characters.

Character STRING(1) Single character that should be appended (or optionally prepended) to the input string
iteratively to create a string length equal to TotalLength.

TotalLength INT Control to specify the total number of characters that the output should be; if the input length
is of greater value, the input string will be returned. A negative TotalLength value forces the
function to prepend padded characters rather than appending them.

Return Value
IEC 61131 Type Description

STRING(255) Padded string that is appended (or prepended) with the repeated Character input until the string's
length is equal to the TotalLength input (unless the input string is of greater length than TotalLength).

Example in Structured Text: (* Result in VarString is '001' *)


VarString := fun_PadString(InString:='1', Character:='0', TotalLength:= –3);
Example in Structured Text: (* Result in VarString is '7XX' *)
VarString := fun_PadString(InString:='7', Character:='X', TotalLength:=3);

Processing
➤ Determination is made whether operation appends or prepends.
➤ If the TotalLength input is greater than the initial length of the InString,
the Character input will be concatenated with the InString until the length
of the joined string is equal to TotalLength.

ComposeApparentPower (Function)
This function takes two REAL inputs representing the voltage and current
magnitudes with a third REAL input representing a scale factor (multiplier)
and returns the evaluated magnitude of apparent (the combination of real and
reactive power components) power. The formula for this calculation is evaluated
as follows where S is the apparent power value.

Programming Reference Date Code 20241023


SELUtils 1095
Functions

Inputs
Name IEC 61131 Type Description

Voltage REAL The REAL input representing the voltage


magnitude.

Current REAL The REAL input representing the current


magnitude.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

REAL The apparent power calculated from input current and voltage.

Example in Structured Text: (* Result in S is 1.6 *)

S := ComposeApparentPower(8, 2, 0.1);

Processing
➤ The apparent power is calculated as the product of the current and
voltage.

MVComposeApparentPower (Function)
This function takes two MV inputs representing the voltage and current
magnitudes with a third REAL input representing a scale factor (multiplier)
and returns the evaluated magnitude of apparent (the combination of real and
reactive power components) power. The formula for this calculation is evaluated
as follows, where S is the apparent power value.

Inputs
Name IEC 61131 Type Description

Voltage MV The MV input representing the voltage magnitude.

Current MV The MV input representing the current magnitude.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

MV The apparent power calculated from input current and voltage.

Date Code 20241023 Programming Reference


1096 SELUtils
Functions

Example in Structured Text: (* Input mv_v.instMag is 8, and mv_i.instMag is 2 -


Resulting S.instMag is 1.6 *)

S := MVComposeApparentPower(mv_v, mv_i, 0.1);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, the function
returns without execution.
➤ The apparent power is calculated as the product of the current and
voltage.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

CMVComposeApparentPower (Function)
This function takes two CMV inputs providing complex (magnitude/angle)
representations of the voltage and current with a third REAL input representing
a scale factor (multiplier) for the calculation and returns the evaluated apparent
(the combination of real and reactive power components) power. The formula
for this calculation is evaluated as follows, where S is the apparent power value.

Inputs
Name IEC 61131 Type Description

Voltage CMV The CMV input representing the voltage magnitude


and angle.

Current CMV The CMV input representing the current magnitude


and angle.

Scale REAL The REAL input representing the scale factor (a


multiplier) for the magnitude.

Return Value
IEC 61131 Type Description

CMV The apparent power magnitude and angle calculated from input
current and voltage.

Example in Structured Text: (* Input cmv_v.instCVal.mag is 8,


cmv_v.instCVal.ang is 5, cmv_i.instCVal.mag is 2, and cmv_i.instCVal.ang is 0
*) (* Resulting S.instCVal.mag is 1.6 and S.instCVal.ang is 5 *)

S := CMVComposeApparentPower(cmv_v, cmv_i, 0.1);

Programming Reference Date Code 20241023


SELUtils 1097
Functions

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The apparent power magnitude is calculated as the product of the current
and voltage magnitudes
➤ The apparent power angle is calculated as the difference between the
voltage and current angles.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

ComposePF (Function)
This function takes two REAL inputs representing the voltage and current angles
measured in degrees and a scale factor (multiplier) and returns the evaluated
magnitude of power factor. The formula for this calculation is evaluated as
follows, where PF is the power factor value.

The formula will evaluate the sign (indicating direction of power flow)
according to the angle difference between the values. Should the absolute value
of the angle difference be between 0 and 90 degrees, the sign will be positive.
All other values will result in a negative quantity.

Inputs
Name IEC 61131 Type Description

Voltage Angle REAL The REAL input representing the voltage angle in
degrees.

Current Angle REAL The REAL input representing the current angle in
degrees.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

REAL The power factor calculated from input voltage and current angles.

Example in Structured Text: (* Result in Pf is 5 *)

Pf := ComposePF(60, 0, 10);

Processing
➤ The power factor is calculated using the formula shown above.

Date Code 20241023 Programming Reference


1098 SELUtils
Functions

CMVComposePF (Function)
This function takes two CMV inputs representing the voltage and current angles
measured in degrees and a scale factor (multiplier) and returns the evaluated
magnitude of power factor. The formula for this calculation is evaluated as
follows, where PF is the power factor value.

The formula will evaluate the sign (indicating direction of power flow)
according to the angle difference between the values. Should the absolute value
of the angle difference be between 0 and 90 degrees, the sign will be positive.
All other values will result in a negative quantity.

Inputs
Name IEC 61131 Type Description

Voltage CMV The CMV input representing the voltage magnitude


and angle.

Current CMV The CMV input representing the current magnitude


and angle.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

MV The power factor calculated from input voltage and current angles.

Example in Structured Text: (* Input cmv_v.instCVal.mag is 8,


cmv_v.instCVal.ang is 60, cmv_i.instCVal.mag is 2, and cmv_i.instCVal.ang is 0
*) (* Resulting Pf.instMag is 5 *)

Pf := CMVComposePF(cmv_v, cmv_i, 10);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The power factor is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

Programming Reference Date Code 20241023


SELUtils 1099
Functions

ComposeVAR (Function)
This function takes four REAL inputs representing the voltage magnitude, current
magnitude, voltage angle, and current angle with a fifth input representing a
scale factor multiplier and returns the evaluated magnitude of reactive power.
The formula for this calculation is evaluated as follows, where Q is the reactive
power value.

Inputs
Name IEC 61131 Type Description

VoltageMagnitude REAL The REAL input representing the voltage


magnitude.

CurrentMagnitude REAL The REAL input representing the current


magnitude.

VoltageAngle REAL The REAL input representing the voltage angle.

CurrentAngle REAL The REAL input representing the current angle.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

REAL The reactive power calculated from input voltage and current.

Example in Structured Text: (* Result in Q is 11.312 *)

Q := ComposeVAR(8, 2, 0, –45, 1);

Processing
➤ The reactive power is calculated using the formula shown above.

MVComposeVAR (Function)
This function takes four MV inputs representing the voltage magnitude, current
magnitude, voltage angle, and current angle with a fifth input representing a
scale factor multiplier and returns the evaluated magnitude of reactive power.
The formula for this calculation is evaluated as follows, where Q is the reactive
power value.

Date Code 20241023 Programming Reference


1100 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

VoltageMagnitude MV The MV input representing the voltage magnitude.

CurrentMagnitude MV The MV input representing the current magnitude.

VoltageAngle MV The MV input representing the voltage angle.

CurrentAngle MV The MV input representing the current angle.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

MV The reactive power calculated from input voltage and current.

Example in Structured Text: (* Input mv_v.instMag is 8, mv_i.instMag is 2,


mv_vang.instMag is 0, and mv_iang.instMag is –45 *) (* Result in Q.instMag is
11.312 *)

Q := MVComposeVAR(mv_v, mv_i, mv_vang, mv_iang, 1);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The reactive power is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

CMVComposeVAR (Function)
This function takes two CMV inputs representing the voltage and current
magnitudes and angles with a third input representing a scale factor multiplier
and returns the evaluated magnitude of reactive power as an MV. The formula for
this calculation is evaluated as follows, where Q is the reactive power value.

Programming Reference Date Code 20241023


SELUtils 1101
Functions

Inputs
Name IEC 61131 Type Description

Voltage CMV The CMV input representing the voltage magnitude


and angle.

Current CMV The CMV input representing the current magnitude


and angle.

Scale REAL The REAL input representing the scale factor (a


multiplier) for the magnitude.

Return Value
IEC 61131 Type Description

MV The reactive power calculated from input voltage and current.

Example in Structured Text: (* Input mv_v.instCVal.mag is 8,


mv_v.instCVal.ang is 45, mv_i.instCVal.mag is 2, and mv_i.instCVal.ang is 0 –
Result in Q.instMag is 11.312 *)

Q := CMVComposeVAR(mv_v, mv_i, 1);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The reactive power is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

ComposeWatts (Function)
This function takes three REAL inputs representing the voltage, current,
and power factor magnitudes with a fourth input representing a scale factor
magnitude and returns the evaluated magnitude of real power. The formula for
this calculation is evaluated as follows, where P is the reactive power value.

Inputs
Name IEC 61131 Type Description

Voltage REAL The REAL input representing the voltage


magnitude.

Current REAL The REAL input representing the current


magnitude.

Date Code 20241023 Programming Reference


1102 SELUtils
Functions

Name IEC 61131 Type Description

PF REAL The REAL input representing the power factor.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

REAL The real power calculated from input voltage, current, and power
factor.

Example in Structured Text: (* Result in P is 11.312 *)

P := ComposeWatts(8, 2, 0.707, 1);

Processing
➤ The real power is calculated using the formula shown above.

MVComposeWatts (Function)
This function takes three MV inputs representing the voltage, current, and power
factor magnitudes with a fourth input representing a scale factor magnitude and
returns the evaluated magnitude of real power. The formula for this calculation
is evaluated as follows, where P is the reactive power value.

Inputs
Name IEC 61131 Type Description

Voltage MV The MV input representing the voltage magnitude.

Current MV The MV input representing the current magnitude.

PF MV The MV input representing the power factor.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

MV The real power calculated from input voltage, current, and power
factor.

Example in Structured Text: (* Input mv_v.instMag is 8, mv_i.instMag is 2, and


mv_pf.instMag is 0.707 *) (* Result in P.instMag is 11.312 *)

P := MVComposeWatts(mv_v, mv_i, mv_pf, 1);

Programming Reference Date Code 20241023


SELUtils 1103
Functions

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The real power is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

CMVComposeWatts (Function)
This function takes two CMV inputs representing the voltage and current
magnitudes and angles and a third input representing a scale factor magnitude
and returns the evaluated magnitude of real power as an MV. The formula for this
calculation is evaluated as follows, where P is the reactive power value.

Inputs
Name IEC 61131 Type Description

Voltage CMV The CMV input representing the voltage


magnitude.

Current CMV The CMV input representing the current


magnitude.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

MV The real power calculated from input voltage and current.

Example in Structured Text: (* Input mv_v.instCVal.mag is 8,


mv_v.instCVal.ang is 45, mv_i.instCVal.mag is 2, and mv_i.instCVal.ang is 0 *)
(* Result in P.instMag is 11.312 *)
P := CMVComposeWatts(mv_v, mv_i, 1);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The real power is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

Date Code 20241023 Programming Reference


1104 SELUtils
Functions

WATT_VAR_TO_VA (Function)
This function takes two REAL inputs representing the real and reactive power
magnitudes and returns the evaluated magnitude of apparent (combined real and
reactive) power. The formula for this calculation is evaluated as follows, where
S is the apparent power value.

Inputs
Name IEC 61131 Type Description

Watts REAL The REAL input representing the real power


magnitude.

VARs REAL The REAL input representing the reactive power


magnitude.

Return Value
IEC 61131 Type Description

REAL The apparent power calculated from input real and reactive power
magnitudes.

Example in Structured Text: (* Result in S is 5 *)

S := WATT_VAR_TO_VA(4000, 3000, 0.001);

Processing
➤ The apparent power magnitude is calculated using the formula shown
above.

MV_WATT_VAR_TO_VA (Function)
This function takes two MV inputs representing the real and reactive power
magnitudes and returns the evaluated magnitude of apparent (combined real and
reactive) power. The formula for this calculation is evaluated as follows, where
S is the apparent power value.

Inputs
Name IEC 61131 Type Description

Watts MV The MV representing the real power magnitude.

VARs MV The MV representing the reactive power magnitude.

Programming Reference Date Code 20241023


SELUtils 1105
Functions

Return Value
IEC 61131 Type Description

MV The apparent power magnitude calculated from input real and


reactive power magnitudes.

Example in Structured Text: (* Input mv_p.instMag is 4000, and mv_q.instMag


is 3000 *) (* Resulting S.instMag is 5 *)

S := MV_WATT_VAR_TO_VA(mv_p, mv_q, 0.001);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The apparent power magnitude is calculated using the formula shown
above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

VA_WATT_TO_VAR (Function)
This function takes two REAL inputs representing the apparent and real power
magnitudes and returns the evaluated magnitude of reactive (imaginary) power.
The formula for this calculation is evaluated as follows, where Q is the reactive
power value.

Inputs
Name IEC 61131 Type Description

VAs REAL The REAL input representing the apparent power


magnitude.

Watts REAL The REAL input representing the real power


magnitude.

Return Value
IEC 61131 Type Description

REAL The reactive (imaginary) power magnitude calculated from input real
and apparent power magnitudes.

Example in Structured Text: (* Result in Q is 3 *)

Q := VA_WATT_TO_VAR(5000, 4000, 0.001);

Date Code 20241023 Programming Reference


1106 SELUtils
Functions

Processing
➤ The reactive power is calculated using the formula shown above.

MV_VA_WATT_TO_VAR (Function)
This function takes two MV inputs representing the apparent and real power
magnitudes and returns the evaluated magnitude of reactive (imaginary) power.
The formula for this calculation is evaluated as follows, where Q is the reactive
power value.

Inputs
Name IEC 61131 Type Description

VAs MV The MV representing the apparent power magnitude.

Watts MV The MV representing the real power magnitude.

Return Value
IEC 61131 Type Description

MV The reactive (imaginary) power magnitude calculated from input real


and apparent power magnitudes.

Example in Structured Text: (* Input mv_s.instMag is 5000, and mv_p.instMag


is 4000 *) (* Resulting Q.instMag is 3 *)
Q := MV_VA_WATT_TO_VAR(mv_s, mv_p, 0.001);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The reactive power is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

VA_VAR_TO_WATT (Function)
This function takes two REAL inputs representing the apparent and reactive
power magnitudes and returns the evaluated magnitude of real (active) power.
The formula for this calculation is evaluated as follows, where P is the reactive
power value.

Programming Reference Date Code 20241023


SELUtils 1107
Functions

Inputs
Name IEC 61131 Type Description

VAs REAL The REAL input representing the apparent power


magnitude.

VARs REAL The REAL input representing the reactive power


magnitude.

Return Value
IEC 61131 Type Description

REAL The real (active) power magnitude calculated from input real and
apparent power magnitudes.

Example in Structured Text: (* Result in P is 4 *)

P := VA_VAR_TO_WATT(5000, 3000, 0.001);

Processing
➤ The real power is calculated using the formula shown above.

MV_VA_VAR_TO_WATT (Function)
This function takes two MV inputs representing the apparent and reactive power
magnitudes and returns the evaluated magnitude of real (active) power. The
formula for this calculation is evaluated as follows, where P is the real power
value.

Inputs
Name IEC 61131 Type Description

VAs MV The MV representing the apparent power magnitude.

VARs MV The MV representing the reactive power magnitude.

Return Value
IEC 61131 Type Description

MV The real (active) power magnitude calculated from input real and
apparent power magnitudes.

Example in Structured Text: (* Input mv_s.instMag is 5000, and mv_q.instMag


is 3000 *) (* Resulting P.instMag is 4 *)

P := MV_VA_VAR_TO_WATT(mv_s, mv_q, 0.001);

Date Code 20241023 Programming Reference


1108 SELUtils
Functions

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The real power is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

MV_VA_W_VAR_TO_PF (Function)
This function takes three MV inputs representing the apparent power, real power,
and reactive power measured in VA, W, and VAR and a scale factor (multiplier).
It returns the evaluated magnitude of the power factor. The formula for this
calculation is evaluated as follows, where PF is the power factor value.

Worth noting is the fact that this function follows the convention where a
"lagging" power factor is the result of a measured positive real power and a
positive reactive power, or a negative real power and a negative reactive power.

Conversely, a "leading" power factor is found when the measured real power is
positive and the reactive power is negative, or when the measured real power is
negative and the reactive power is positive.

According to this convention, lagging values are represented as positive


numbers while leading values are represented as negative.

Inputs
Name IEC 61131 Type Description

ApparentPower MV The MV input representing the apparent power in


VA.

RealPower MV The MV input representing the real power in W.

ReactivePower MV The MV input representing the reactive power in


VAR.

Scale REAL The REAL input representing the scale factor (a


multiplier).

Return Value
IEC 61131 Type Description

MV The power factor calculated from the relation between real power and
apparent power.

Example in Structured Text: (* Input ApparentPower.instMag is 1922,


RealPower.instMag is 1784, ReactivePower.instMag is 175, and Scale is 1 *)

(* Resulting PF.instMag is 0.928 *)

Programming Reference Date Code 20241023


SELUtils 1109
Functions

PF := MV_VA_W_VAR_TO_PF(ApparentPower, RealPower,
ReactivePower, Scale);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The .instMag attributes of the MV input values are verified to be valid
REALs with the function fun_IsValidReal.
➤ The power factor is calculated using the formula shown above.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.

VLL_TO_VLN (Function)
This function takes a single REAL input representing the line-to-line voltage
magnitude and returns the evaluated magnitude of the line-to-neutral voltage.
The formula for this calculation is evaluated as follows.

Inputs
Name IEC 61131 Type Description

VLL REAL The REAL input representing the line-to-line voltage


magnitude.

Return Value
IEC 61131 Type Description

REAL The line-to-neutral voltage calculated from input line-to-line voltage.

Example in Structured Text: (* Result in Vneutral is 5.7735 *)


Vneutral := VLL_TO_VLN(10);

Processing
➤ The line-to-neutral voltage magnitude is calculated using the formula
shown above.

MV_VLL_TO_VLN (Function)
This function takes a single MV input representing the line-to-line voltage
magnitude and returns the evaluated magnitude of the line-to-neutral voltage.
The formula for this calculation is evaluated as follows. This formula is only
valid under balanced, three-phase system conditions.

Date Code 20241023 Programming Reference


1110 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

VLL MV The MV representing the line-to-line voltage


magnitude.

Return Value
IEC 61131 Type Description

MV The line-to-neutral voltage calculated from input line-to-line voltage.

Example in Structured Text: (* Input mv_vline.instMag is 10 *) (* Resulting


Vneutral.instMag is 5.7735 *)
Vneutral := MV_VLL_TO_VLN(mv_vline);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The line-to-neutral voltage magnitude is calculated using the formula
shown above.

CMV_VLL_TO_VLN (Function)
This function takes a single CMV input representing the line-to-line voltage
magnitude and angle and returns the evaluated magnitude and angle of the line-
to-neutral voltage. The formula for this calculation is evaluated as follows. This
formula is only valid under balanced, three-phase system conditions.

Inputs
Name IEC 61131 Type Description

VLL CMV The CMV representing the line-to-line voltage


magnitude.

Return Value
IEC 61131 Type Description

CMV The line-to-neutral voltage calculated from input line-to-line voltage.

Programming Reference Date Code 20241023


SELUtils 1111
Functions

Example in Structured Text: (* Input cmv_vline.instCVal.mag is 10,


cmv_vline.instCVal. ang is 0 *) (* Resulting Vneutral.instCVal.mag is 5.7735
and Vneutral.instCVal.ang is –30 *)

Vneutral := CMV_VLL_TO_VLN(cmv_vline);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The line-to-neutral voltage magnitude is calculated using the formula
shown above.
➤ The line-to-neutral voltage angle is calculated by subtracting an
additional thirty degrees.

VLN_TO_VLL (Function)
This function takes a single REAL input representing the line-to-neutral voltage
magnitude and returns the evaluated magnitude of the line-to-line voltage. The
formula for this calculation is evaluated as follows. This formula is only valid
under balanced, three-phase system conditions.

Inputs
Name IEC 61131 Type Description

VLN REAL The REAL input representing the line-to-neutral


voltage magnitude.

Return Value
IEC 61131 Type Description

REAL The line-to-line voltage calculated from input line-to-neutral voltage.

Example in Structured Text: (* Result in Vline is 17.3205 *)

Vline := VLN_TO_VLL(10);

Processing
➤ The line-to-line voltage magnitude is calculated using the formula shown
above.

Date Code 20241023 Programming Reference


1112 SELUtils
Functions

MV_VLN_TO_VLL (Function)
This function takes a single MV input representing the line-to-neutral voltage
magnitude and returns the evaluated magnitude of the line-to-line voltage. The
formula for this calculation is evaluated as follows. This formula is only valid
under balanced, three-phase system conditions.

Inputs
Name IEC 61131 Type Description

VLN MV The MV representing the line-to-neutral voltage


magnitude.

Return Value
IEC 61131 Type Description

MV The line-to-line voltage calculated from input line-to-neutral voltage.

Example in Structured Text: (* Input mv_vneutral.instMag is 10 *) (* Resulting


Vline.instMag is 17.3205 *)
Vline := MV_VLN_TO_VLL(mv_vneutral);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The line-to-line voltage magnitude is calculated using the formula shown
above.

CMV_VLN_TO_VLL (Function)
This function takes a single CMV input representing the line-to-neutral voltage
magnitude and angle and returns the evaluated magnitude and angle of the line-
to-line voltage. The formula for this calculation is evaluated as follows. This
formula is only valid under balanced, three-phase system conditions.

Inputs
Name IEC 61131 Type Description

VLN CMV The CMV representing the line-to-neutral voltage


magnitude.

Programming Reference Date Code 20241023


SELUtils 1113
Functions

Return Value
IEC 61131 Type Description

CMV The line-to-line voltage calculated from input line-to-neutral voltage.

Example in Structured Text: (* Input cmv_vneutral.instCVal.mag is 10,


cmv_vneutral.instCVal. ang is 0 *) (* Resulting Vline.instCVal.mag is 17.3205
and Vline.instCVal.ang is 30 *)
Vline := CMV_VLN_TO_VLL(cmv_vneutral);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The line-to-line voltage magnitude is calculated using the formula shown
above.
➤ The line-to-line voltage angle is calculated by adding an additional thirty
degrees.

IP_TO_IL (Function)
This function takes a single REAL input representing the phase-current
magnitude and returns the evaluated magnitude of the line-current. The formula
for this calculation is evaluated as follows. This formula is only valid under
balanced, three-phase system conditions.

Inputs
Name IEC 61131 Type Description

IP REAL The REAL input representing the phase-current


magnitude.

Return Value
IEC 61131 Type Description

REAL The line-current calculated from input phase-current.

Example in Structured Text: (* Result in Iline is 17.3205 *)


Iline := IP_TO_IL(10);

Processing
➤ The line-current magnitude is calculated using the formula shown above.

Date Code 20241023 Programming Reference


1114 SELUtils
Functions

MV_IP_TO_IL (Function)
This function takes a single MV input representing the phase-current magnitude
and returns the evaluated magnitude of the line-current. The formula for this
calculation is evaluated as follows. This formula is only valid under balanced,
three-phase system conditions.

Inputs
Name IEC 61131 Type Description

IP MV The MV representing the phase-current magnitude.

Return Value
IEC 61131 Type Description

MV The line-current calculated from input phase-current.

Example in Structured Text: (* Input mv_iphase.instMag is 10 *) (* Resulting


Iline.inst- Mag is 17.3205 *)

Iline := MV_IP_TO_IL(mv_iphase);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The line-current magnitude is calculated using the formula shown above.

CMV_IP_TO_IL (Function)
This function takes a single CMV input representing the phase-current magnitude
and angle (in degrees) and returns the evaluated magnitude and angle (in
degrees) of the line-current. The formula for this calculation is evaluated
as follows. This formula is only valid under balanced, three-phase system
conditions.

Inputs
Name IEC 61131 Type Description

IP CMV The CMV representing the phase-current magnitude.

Programming Reference Date Code 20241023


SELUtils 1115
Functions

Return Value
IEC 61131 Type Description

CMV The line-current calculated from input phase-current.

Example in Structured Text: (* Input cmv_iphase.instCVal.mag is 10,


cmv_iphase.instCVal. ang is 0 *) (* Resulting Iline.instCVal.mag is 17.3205 and
Iline.instCVal.ang is 30 *)
Vline := CMV_IP_TO_IL(cmv_iphase);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The line-current magnitude is calculated using the formula shown above.
➤ The line-current angle is calculated using the formula shown above.

IL_TO_IP (Function)
This function takes a single REAL input representing the line-current magnitude
and returns the evaluated magnitude of the phase-current. The formula for this
calculation is evaluated as follows. This formula is only valid under balanced,
three-phase system conditions.

Inputs
Name IEC 61131 Type Description

IP REAL The REAL input representing the line-current


magnitude.

Return Value
IEC 61131 Type Description

REAL The phase-current calculated from input line-current.

Example in Structured Text: (* Result in Iphase is 5.7735 *)


Iphase := IL_TO_IP(10);

Processing
➤ The phase-current magnitude is calculated using the formula shown
above.

Date Code 20241023 Programming Reference


1116 SELUtils
Functions

MV_IL_TO_IP (Function)
This function takes a single MV input representing the line-current magnitude
and returns the evaluated magnitude of the phase-current. The formula for this
calculation is evaluated as follows. This formula is only valid under balanced,
three-phase system conditions.

Inputs
Name IEC 61131 Type Description

IL MV The MV representing the line-current magnitude.

Return Value
IEC 61131 Type Description

MV The phase-current calculated from input line-current.

Example in Structured Text: (* Input mv_iline.instMag is 10 *) (* Resulting


Iphase.inst Mag is 5.7735 *)
Iphase := MV_IL_TO_IP(mv_iline);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The phase-current magnitude is calculated using the formula shown
above.

CMV_IL_TO_IP (Function)
This function takes a single CMV input representing the line-current magnitude
and angle (in degrees) and returns the evaluated magnitude and angle (in
degrees) of the phase-current. The formula for this calculation is evaluated
as follows. This formula is only valid under balanced, three-phase system
conditions.

Inputs
Name IEC 61131 Type Description

IP CMV The CMV representing the line-current magnitude.

Programming Reference Date Code 20241023


SELUtils 1117
Functions

Return Value
IEC 61131 Type Description

CMV The phase-current calculated from input line-current.

Example in Structured Text: (* Input cmv_iline.instCVal.mag is 10,


cmv_iline.instCVal.ang is 0 *) (* Resulting Iphase.instCVal.mag is 5.7735 and
Iphase.instCVal.ang is –30 *)

Iphase := CMV_IL_TO_IP(cmv_iline);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality value from the input is loaded into the output.
➤ The time stamp value of the input is loaded into the output.
➤ The phase-current magnitude is calculated using the formula shown
above.

HP_TO_WATTS (Function)
This function takes a single REAL input representing power measured in units of
horsepower and returns the same quantity, measured in Watts. The formula for
this calculation is evaluated as follows.

Inputs
Name IEC 61131 Type Description

Horsepower REAL The REAL input representing a power value


measured in units of horsepower.

Return Value
IEC 61131 Type Description

REAL The power quantity represented in Watts.

Example in Structured Text: (* Result in P is 745700 *)

P := HP_TO_WATTS(1000);

Processing
➤ The power (in units of horsepower) is multiplied by the conversion factor
to evaluate the power in Watts.

Date Code 20241023 Programming Reference


1118 SELUtils
Functions

WATTS_TO_HP (Function)
This function takes a single REAL input representing power measured in Watts
and returns the same quantity, measured in units of horsepower. The formula for
this calculation is evaluated as follows.

Inputs
Name IEC 61131 Type Description

Watts REAL The REAL input representing a power value


measured in Watts.

Return Value
IEC 61131 Type Description

REAL The power quantity represented in units of horsepower.

Example in Structured Text: (* Result in Hp is 1.341 *)

Hp := WATTS_TO_HP(1000);

Processing
➤ The power (in Watts) is divided by the conversion factor to evaluate the
power measured in units of horsepower.

PEAK_TO_RMS (Function)
This function takes a single REAL input representing the peak magnitude of a
phasor (complex, sinusoidally oscillating) quantity and applies the appropriate
calculation to represent the quantity as a root-mean-square (rms) value. The
formula for this calculation is evaluated as follows, where RMS represents the
root-mean-square evaluated output.

Inputs
Name IEC 61131 Type Description

PEAK REAL The REAL input representing the peak magnitude


of the input for which the root-mean-square (rms)
should be evaluated.

Programming Reference Date Code 20241023


SELUtils 1119
Functions

Return Value
IEC 61131 Type Description

REAL The root-mean-square (rms) evaluation of the input PEAK.

Example in Structured Text: (* Result in Rms is 120.0 *)


Rms := PEAK_TO_RMS(169.706);

Processing
➤ The input (PEAK) is divided by the square root of two.

RMS_TO_PEAK (Function)
This function takes a single REAL input representing the root-mean-square (rms)
magnitude of a phasor (complex, sinusoidally oscillating) quantity and applies
the appropriate calculation to represent the quantity as a peak value. The formula
for this calculation is evaluated as follows, where PEAK represents the evaluated
peak output magnitude.

Inputs
Name IEC 61131 Type Description

RMS REAL The REAL input representing the root-mean-square


(rms) magnitude of the input for which the peak
magnitude should be evaluated.

Return Value
IEC 61131 Type Description

REAL The evaluated peak magnitude corresponding to the input RMS.

Example in Structured Text: (* Result in Pk is 169.706 *)


Pk := RMS_TO_PEAK(120.0);

Processing
➤ The input (RMS) is multiplied by the square root of two.

ZeroSequence (Function)
This function takes three CMV inputs representing the three phases of an
electrical system and applies the appropriate calculation to evaluate the zero-
sequence component equivalent of these inputs. The formula for this calculation
is evaluated as shown below where Px represents the phase inputs, x is the phase
index, N0 is the zero-sequence output, and a is the symmetrical components
operator (sometimes denoted as α), equivalent to: 1Ð120°.

Date Code 20241023 Programming Reference


1120 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

PHASE1 CMV The CMV representing the first phase element


(typically denoted as Phase A).

PHASE2 CMV The CMV representing the second phase element


(typically denoted as Phase B).

PHASE3 CMV The CMV representing the third phase element


(typically denoted as Phase C).

Return Value
IEC 61131 Type Description

CMV The CMV representing the zero-sequence symmetrical component.

Example in Structured Text: (* Input P1 is 13800 Ð60°, P2 is 13800 Ð−120°,


and P3 is 13800 Ð70° *) (* Resulting ZeroSeq is 4600 Ð70° *)

ZeroSeq := ZeroSequence(P1, P2, P3);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.
➤ The magnitudes of the three input phase values are added together to find
3 • N0.
➤ The evaluated magnitude representing 3 • N0 is divided by three to find
N0.

PositiveSequence (Function)
This function takes three CMV inputs representing the three phases of an
electrical system and applies the appropriate calculation to evaluate the positive-
sequence component equivalent of these inputs. The formula for this calculation
is evaluated as shown below where Px represents the phase inputs, x is the phase
index, N1 is the positive-sequence output, and a is the symmetrical components
operator (sometimes denoted as α), equivalent to: 1Ð120°.

Programming Reference Date Code 20241023


SELUtils 1121
Functions

Inputs
Name IEC 61131 Type Description

PHASE1 CMV The CMV representing the first phase element


(typically denoted as Phase A).

PHASE2 CMV The CMV representing the second phase element


(typically denoted as Phase B).

PHASE3 CMV The CMV representing the third phase element


(typically denoted as Phase C).

Return Value
IEC 61131 Type Description

CMV The CMV representing the positive-sequence symmetrical


component.

Example in Structured Text: (* Input P1 is 13800 Ð60°, P2 is 13800 Ð−120°,


and P3 is 13800 Ð70° *) (* Resulting PosSeq is 9867.547 Ð2.671° *)

PosSeq := PositiveSequence(P1, P2, P3);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.
➤ The magnitudes of the three input phase values are added together with
the appropriate symmetrical component operator to find 3 • N1.
➤ The evaluated magnitude representing 3 • N1 is divided by three to find
N1.

NegativeSequence (Function)
This function takes three CMV inputs representing the three phases of an
electrical system and applies the appropriate calculation to evaluate the negative-
sequence component equivalent of these inputs. The formula for this calculation
is evaluated as shown in the following equation, where Px represents the phase
inputs, x is the phase index, N2 is the negative-sequence output, and a is the
symmetrical components operator (sometimes denoted as α), equivalent to
1Ð120°.

Date Code 20241023 Programming Reference


1122 SELUtils
Functions

Inputs
Name IEC 61131 Type Description

PHASE1 CMV The CMV representing the first phase element


(typically denoted as Phase A).

PHASE2 CMV The CMV representing the second phase element


(typically denoted as Phase B).

PHASE3 CMV The CMV representing the third phase element


(typically denoted as Phase C).

Return Value
IEC 61131 Type Description

CMV The CMV representing the negative-sequence symmetrical


component.

Example in Structured Text: (* Input P1 is 13800 Ð60°, P2 is 13800 Ð−120°,


and P3 is 13800 Ð70° *) (* Resulting NegSeq is 8480.066 Ð122.29° *)
NegSeq := NegativeSequence(P1, P2, P3);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The quality values from all inputs are merged using the MERGE_q
function.
➤ The newest time stamp of the inputs is used to evaluate the output time
stamp.
➤ The magnitudes of the three input phase values are added together with
the appropriate symmetrical component operator to find 3 • N2.
➤ The evaluated magnitude representing 3 • N2 is divided by three to find
N2.

PHASES_TO_SEQUENCES (Function)
This function takes three CMV inputs representing the three phases of an
electrical system and applies the appropriate calculation to evaluate the sequence
component equivalents of these inputs. The formula for this calculation is
evaluated as shown below where Px represents the phase inputs, x is the
phase index, Ny is the sequence outputs, y is the sequence index, and a is the
symmetrical components operator (sometimes denoted as α), equivalent to:
1Ð120°.

Programming Reference Date Code 20241023


SELUtils 1123
Functions

Inputs
Name IEC 61131 Type Description

PHASE1 CMV The CMV representing the first phase element


(typically denoted as Phase A).

PHASE2 CMV The CMV representing the second phase element


(typically denoted as Phase B).

PHASE3 CMV The CMV representing the third phase element


(typically denoted as Phase C).

Outputs
Name IEC 61131 Type Description

SEQUENCE0 CMV The CMV representing the zero-sequence


symmetrical component.

SEQUENCE1 CMV The CMV representing the positive-sequence


symmetrical component.

SEQUENCE2 CMV The CMV representing the negative-sequence


symmetrical component.

Return Value
IEC 61131 Type Description

BOOL Status indicator of the calculation, returns TRUE if quality


OperatorBlocked attribute is FALSE.

Example in Structured Text: (* The variables P1, P2, and P3 are all of type
CMV, and represent the three phase inputs; the variables ZSeq, PSeq, and NSeq
are also of type CMV, and represent the calculated sequence components. *)

PHASES_TO_SEQUENCES(P1, P2, P3, SEQUENCE0=>ZSeq,


SEQUENCE1=>PSeq, SEQUENCE2=>NSeq);

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ Zero-sequence value is calculated by use of the ZeroSequence function.
➤ Positive-sequence value is calculated by use of the PositiveSequence
function.
➤ Negative-sequence value is calculated by use of the NegativeSequence
function.
➤ The return value is set TRUE to indicate successful calculation.

Date Code 20241023 Programming Reference


1124 SELUtils
Functions

SEQUENCES_TO_PHASES (Function)
This function takes three CMV inputs representing the three symmetrical
component values and applies the appropriate calculation to find the electrical
system phase equivalents of these inputs. The formula for this calculation
is evaluated as shown below where Px represents the phase outputs, x is the
phase index, Ny is the sequence inputs, y is the sequence index, and a is the
symmetrical components operator (sometimes denoted as α), equivalent to:
1Ð120°.

Inputs
Name IEC 61131 Type Description

SEQUENCE0 CMV The CMV representing the zero-sequence


symmetrical component.

SEQUENCE1 CMV The CMV representing the positive-sequence


symmetrical component.

SEQUENCE2 CMV The CMV representing the negative-sequence


symmetrical component.

Outputs
Name IEC 61131 Type Description

PHASE1 CMV The CMV representing the first phase element


(typically denoted as Phase A).

PHASE2 CMV The CMV representing the second phase element


(typically denoted as Phase B).

PHASE3 CMV The CMV representing the third phase element


(typically denoted as Phase C).

Return Value
IEC 61131 Type Description

BOOL Status indicator of the calculation, returns TRUE if quality


OperatorBlocked attribute is FALSE.

Example in Structured Text: (* The variables ZSeq, PSeq, and NSeq are each of
type CMV, and represent the calculated sequence components; the variables P1,
P2, and P3 are also of type CMV, and represent the three phase outputs. *)

SEQUENCES_TO_PHASES(ZSeq, PSeq, NSeq, PHASE1=>P1,


PHASE2=>P2, PHASE3=>P3);

Programming Reference Date Code 20241023


SELUtils 1125
Functions

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ Phase index 1 value is calculated by summing sequence inputs.
➤ Phase index 2 value is calculated by summing sequence inputs with
appropriate multipliers.
➤ Phase index 3 value is calculated by summing sequence inputs with
appropriate multipliers.
➤ The return value is set TRUE to indicate successful calculation.

REF3_vector_t (Function)
This function evaluates the value of three vector values representative of power
system phasors according to a common reference. Based upon this common
reference, the three input vectors will have their angle adjusted to respect the
common reference value.

Inputs
Name IEC 61131 Type Description

Ref vector_t Vector to use as reference.

In1 vector_t First vector in which to modify the angle in


proportion to the reference angle.

In2 vector_t Second vector in which to modify the angle in


proportion to the reference angle.

In3 vector_t Third vector in which to modify the angle in


proportion to the reference angle.

Outputs
Name IEC 61131 Type Description

Ref1 vector_t Reference-adjusted equivalent of the In1 vector.

Ref2 vector_t Reference-adjusted equivalent of the In2 vector.

Ref3 vector_t Reference-adjusted equivalent of the In3 vector.

Processing
➤ In1 value is adjusted according to the reference vector.
➤ In2 value is adjusted according to the reference vector.
➤ In3 value is adjusted according to the reference vector.

Date Code 20241023 Programming Reference


1126 SELUtils
Functions

DecodeEventType (Function)
This function takes an INS and returns a STR describing event type in a
standardized encoding suitable for SCADA communications using DNP3
registers. A list of the possible interpretations is shown in Table 36.2. This list
covers a broad range of event types reported by several SEL relays.

Table 36.2 Relationship Between DNP3 Register Encoding and Event


Descriptions

DNP3 Event Encoded INS STR Event Description

256 'TRIG'

512 'PULSE'

1024 'TRIP'

1025 'A T'

1026 'B T'

1027 'AB T'

1028 'C T'

1029 'CA T'

1030 'BC T'

1031 'ABC T'

1033 'AG T'

1034 'BG T'

1035 'ABG T'

1036 'CG T'

1037 'CAG T'

1038 'BCG T'

2048 'ER'

2049 'A'

2050 'B'

2051 'AB'

2052 'C'

2053 'CA'

2054 'BC'

2055 'ABC'

2057 'AG'

2058 'BG'

2059 'ABG'

2060 'CG'

2061 'CAG'

2062 'BCG'

Programming Reference Date Code 20241023


SELUtils 1127
Functions

Inputs
Name IEC 61131 Type Description

EventType INS The INS for which the event type representation
should be evaluated.

Return Value
IEC 61131 Type Description

STR The STR event type representation of the input INS.

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The INT input is evaluated against the options listed in Table 36.2 and the
appropriate string value is returned.
➤ If the INT is not found to be one of the possible options listed in
Table 36.2, the string 'Indeterminate' is returned.

EncodeEventType (Function)
This function takes a STR and returns an INS encoding for the event type
description in a standardized format, suitable for SCADA communications using
DNP3 registers. A list of the possible interpretations is shown in Table 36.2.
This list covers a broad range of event types reported by several SEL relays.

Inputs
Name IEC 61131 Type Description

EventString STR The STR for which the event type representation
should be evaluated.

Return Value
IEC 61131 Type Description

INS The INS event type representation of the input string value.

Processing
➤ Input quality OperatorBlocked attribute is tested; if TRUE, function
returns without execution.
➤ The string input is evaluated against the options listed in Table 36.2 and
the appropriate INS value is returned.
➤ If the string value is not found to be one of the possible options listed in
Table 36.2, the integer value 9999 is returned in the INS data structure.

Date Code 20241023 Programming Reference


1128 SELUtils
Function Blocks

Function Blocks
This library provides the PID function block and the related CascadeControl
function block.

PID (Proportional-Integral-Derivative) Function Block


Proportional Integral Derivative (PID) control is a typical feedback control
algorithm widely used in industrial control applications. It is used to regulate
the parameters of many industrial processes such as flow, temperature, and
level. PID logic typically uses an analog input to read the present value of the
variable to be controlled (process variable) and uses an analog output to operate
an external control element (actuator), which in turn adjusts the process variable.
The logic compares the process variable with the desired value (set point) and
calculates the difference, which is known as the error. The PID logic uses this
error to calculate how much it needs to adjust the external control element to
bring the process variable to the desired set point. Examples of an external
control element include a motorized flow control valve, a device that regulates
the speed of a motor, or a relay that controls the power delivered to a heating
element.

The PID logic computes the actuator output by summing up three different
control actions:

➤ Proportional action: The control reaction is based on how far the


process variable is away from the set point.
➤ Integral action: The control reaction is based on how long the process
variable has been away from the set point.
➤ Derivative action: The control reaction is based on how fast the error is
changing.

Proportional action alone always leaves the process variable slightly off the set
point, because an error must exist between the process variable and the set point
to maintain a nonzero controller output value. Consequently, the steady-state
error is never zero. Integral action eliminates the steady-state error by integrating
all of the previous errors over time so that the controller output continues to
grow as long as any error is present. Derivative action produces an output based
on the rate-of-change of the error, acting as a brake on the control action. If
the process variable approaches the set point too quickly, the derivative action
counteracts this effect to reduce overshoot to an acceptable level.

Most applications do not require you to use all three control actions.
Proportional-Integral (PI) control is particularly common because Derivative
action reacts quickly any time the process variable changes, even if the change is
only noise.

Programming Reference Date Code 20241023


SELUtils 1129
Function Blocks

Terminology
The following table describes the terminology used in this PID function block
section.

Term Description

Process Variable (PV) The actual value of the variable to be controlled. This value
is detected by a sensor and used as the feedback signal as the
PID control is taking place.

Set Point (SP) The target value such as a specific temperature or fluid level
that the PID control system is supposed to reach.

Error The difference between SP and PV.

Manipulated Variable (MV) The input of the process (i.e., the physical variable that the
controller output is adjusting).

Controller Output (CO) The output of the PID controller, which is equal to the sum of
the proportional, integral, and derivative control actions.

Figure 36.1 shows a PID control system block diagram that includes the
terminology shown in the previous table.

Figure 36.1 Block Diagram of a PID Control System

PID Algorithm
The PID function block in the RTAC implements the ideal (ISA) form of the
PID positional algorithm with dependent gains. In this PID equation form, the
controller gain Kc equally affects all three control actions. The standard time-
domain PID equation with dependent gains is shown in the following equation.

where:

E is the error

Kc is the controller gain

Ti is the integral time

Td is the derivative time

Date Code 20241023 Programming Reference


1130 SELUtils
Function Blocks

The PID algorithm on the RTAC implements different variations of this


equation depending on two input parameters: Source of derivative (Source of
Derivative on page 1133) and control action (Direct/Reverse Control Action
on page 1133). The user selects between direct and reverse control action and
selects the signal input for the derivative term (error or PV). These two settings
affect the terms of the equation, specifically the derivative term. Table 36.3
contains the time-domain PID equations used by the PID function block.

Table 36.3 PID Equations

Source of
Control Action PID Equation
Derivative

Error Direct/Reverse

PV Reverse (E = SP − PV )

Direct (E = PV − SP)

Table 36.4 describes the constants of the PID equation.

Table 36.4 Parameters of the PID Equations

PID Data
Units Description
Term Type

Kc REAL Controller gain


Unitless ( )

Ti REAL Seconds per repeat Integral Time


Integral action may be disabled by setting Ti = 0

Td REAL Seconds Derivative time

Function Block Inputs and Outputs


The information described in the previous sections is leveraged by this function
block to create a PID algorithm and control whose inputs and outputs are
described here.

Inputs

Name IEC 61131 Type Description

PV REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


Analog signal from the output of a process.

SP REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


Desired value of the PV.

Kc REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


Controller gain.

Ti REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


Integral time in seconds. Set to 0 to disable integral
action.

Td REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


Derivative time in seconds.

Programming Reference Date Code 20241023


SELUtils 1131
Function Blocks

Name IEC 61131 Type Description

DoPV BOOL Default = TRUE.


TRUE: Derivative on PV. FALSE: Derivative on
error.

Auto BOOL Default = TRUE.


TRUE: Automatic mode. FALSE: Manual mode.

ManualOut REAL Range: 0 to 100, default: 0.


PID function block output in manual mode.

OutBias REAL Range: –100 to 100, default: 0.


Value, in percentage (%), manually added to the
output after the PID calculation.

FilterTime REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


Derivative filter time. Set to 0 to disable derivative
filter.

MaxEU REAL Range: (3.4E+38) to (+3.4E+38), default: 100.


Maximum engineering units of PV and SP.

MinEU REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


Minimum engineering units of PV and SP.

MaxOUT REAL Range: 0 to 100, default: 100.


Maximum output limit in percentage.

MinOUT REAL Range: 0 to 100, default: 0.


Minimum output limit, in percentage.

TimeBase UINT Default = 1


Execution rate of PID logic (Execution Rate = Task
Cycle Time • Time Base).

DirectAction BOOL Default = FALSE.


TRUE: E = PV SP
FALSE: E = SP PV.

Freeze_I BOOL Default = FALSE.


TRUE: Suspends integral calculation and freezes
integral term.
FALSE: Resumes integral calculation.

SPrate REAL Range: (3.4E+38) to (+3.4E+38), default: 0.


SP ramp rate in EU per PID cycle time (0 to disable
SP ramping).

Reset_I BOOL Default = FALSE.


TRUE: Integral accumulation is reset to zero.
FALSE: Integral accumulates.

Outputs

Name IEC 61131 Type Description

PIDout REAL PID Output. Result of the PID equation (0% to


100%).

Error_p REAL Error value as a percentage or EU range.

SPramp BOOL SP Ramping. TRUE if the function block is


ramping to SP.

Pterm REAL Proportional Term. Kc • Error

Date Code 20241023 Programming Reference


1132 SELUtils
Function Blocks

Name IEC 61131 Type Description

Iterm REAL
Integral Term.

Dterm REAL Derivative Term. Kc • Td • Derivative

Alarms PID_Alarms Tag structure composed by four Boolean alarm


tags. See Alarms on page 1137.

DeltaT REAL Time (ms) elapsed since previous PID execution.

Processing
Manual/Automatic Modes and Bumpless Transfer
The PID function block has two operation modes, automatic and manual. In
automatic mode, the result of the PID equation determines the controller output
value. In manual mode, the operator sets the controller output value directly by
setting the ManualOut input (0–100 percent).

The PID function block provides bumpless transfer to avoid an abrupt change
on the output when switching from manual to automatic. It achieves bumpless
transfer by enabling set-point tracking and output tracking when the controller
is in manual mode. Set-point tracking overwrites the set point with the current
PV. Consequently, when the controller switches to automatic mode, it will begin
control with zero error. Output tracking preloads the integral term with the
output value set by the operator. As a result, when the controller switches to
automatic mode, it will begin control from the last output value entered by the
operator.

The PID function block supports ramping to set point. Upon switching to
automatic mode, the function block ramps the set point of the controller at a
specified rate (SPrate input) until reaching the desired SP entered by the user.
The SPrate input has to be set in engineering units per PID execution time.

PV and SP During Manual Mode, Automatic Mode, and Ramp-to-Set Point

Figure 36.2 illustrates the manual/automatic operation and ramp-to-set point.

Figure 36.2 Manual/Automatic and Ramp-to-Set Point Operation

Programming Reference Date Code 20241023


SELUtils 1133
Function Blocks

As illustrated in Figure 36.2, the PID control starts in Manual mode at t = 0


and remains operating in Manual mode until it is switched to automatic mode
at t = k. In Manual mode (t < k), the PID equation calculates a new value
continuously, but this value does not affect the PID output. Rather, the operator
controls the output and directly adjusts its value, which in turn adjusts the
process variable. In Manual mode, the PID equation continuously calculates
the output value needed to smoothly start automatic control upon switching
to Automatic mode. The PID logic ignores the current value on the SP input
(blue line) and overwrites the set point with the current PV value (green line).
Consequently, in Manual mode, the PID equation uses an SP value equal to PV.
This is set-point tracking, which allows bumpless transfer to Automatic mode.

When the PID controller switches to Automatic mode (t = k), it stops set-
point tracking and ramp-to-set point starts (SPramp output goes to TRUE).
Immediately after switching to Automatic mode, the controller gradually
increases the set-point value. This starts from the last value read while in
Manual mode (Point A in Figure 36.2) and increases to the SP value configured
by the user (Point B in Figure 36.2). PV follows SP according to the PID tuning
settings and the dynamics of the process. The controller ramps the set point by
an amount equal to SPrate (engineering units) every PID execution cycle. When
SP reaches the value configured by the user (Point B), ramp-to-set point ends
(SPramp output goes to FALSE). After ramp-to-set point ends, if the user makes
a set-point change, the PID equation will immediately use this new SP value to
calculate the output value. Ramp-to-set point will not start again until the next
manual-to-automatic transition.

Output Bias
Output bias is an input parameter that you enter. The controller adds this value to
the result of the PID equation, as shown in Table 36.3.

You may use output bias to reset error offset when no integral action is used (P-
only control). You may also use the output bias input for combining the PID
controller with feedforward control to improve the response to disturbances. The
PID controller accepts an output bias value scaled from –100 to +100 percent. If
the output bias is more than 100 percent or less than –100 percent, the controller
will clamp it to 100 or –100 percent, respectively.

Source of Derivative
Using the derivative of the error may cause large transients in the controller
output because of set-point changes. In practice, it is better to use the derivative
of PV instead of using the derivative of the error. The derivative of the error
works well when SP does not change or when it changes smoothly.

The DoPV input allows you to select between derivative of PV (DoPV = TRUE)
or derivative of error (DoPV = FALSE).

Direct/Reverse Control Action


The PID function block supports direct and reverse control action. The
difference between a direct control action and a reverse control action is in the
way the error is calculated, as shown in Table 36.5.

Date Code 20241023 Programming Reference


1134 SELUtils
Function Blocks

Table 36.5 Error Calculation

Direct Control Action Reverse Control Action

(DirectAction = TRUE) DirectAction = FALSE)


Error E = PV − SP E = SP − PV

Reverse control action will be used for controlling direct-acting processes,


whereas direct control action will be used for controlling inverse-acting process.
Direct- and Reverse- Acting Processes describes how to determine whether your
process is direct-acting or reverse-acting.

Direct- and Reverse-Acting Processes

To determine whether your process is direct-acting or reverse-acting, you have


to analyze the relation between the manipulated variable (MV) and the process
variable (PV):

➤ Direct-acting process: Increasing MV yields to an increase in PV.


➤ Inverse-acting process: Increasing MV yields to a decrease in PV.

Figure 36.3 illustrates the difference between direct- and reverse-acting


processes.

Figure 36.3 Direct-Acting and Reverse-Acting Processes

In both cases, we are controlling the level of the liquid in the tank by
manipulating the opening of the valve. Therefore, the manipulated variable is the
opening of the valve and the process variable is the liquid level. In the process
shown on the left side of Figure 36.3, an increase in the valve opening results
in a decrease of the liquid level. Consequently, it is a reverse-acting process and
the PID controller must be configured for direct action. In the process shown
on the right side of Figure 36.3, an increase in the valve opening results in an
increase of the liquid level. Consequently, it is a direct-acting process and the
PID controller must be configured for reverse action. In summary:

➤ If the increase of the manipulated variable results in an increase of the


process variable, then the process is direct-acting and the PID control
shall be configured for reverse action.
➤ If the increase of the manipulated variable results in a decrease of the
process variable, then the process is reverse-acting and the PID control
shall be configured for direct action.

Programming Reference Date Code 20241023


SELUtils 1135
Function Blocks

Derivative Filter
When derivative action is used, even small amounts of noise in PV may cause
large unnecessary PID output movements. The PID function block implements
a first-order filter to reduce the noise reading and smooth the signal feeding the
derivative term (PV or error). The frequency-domain transfer function of the
derivative filter is shown as follows:

The cutoff frequency for the filter is as follows:

where FilterTime is a PID input parameter.

Setting FilterTime to 0 disables the derivative filter.

Output Limiting
The PID function block allows you to set maximum (OutMAX) and minimum
(OutMIN) limits for the output (0–100 percent). The PID function block
clamps the output at these limits, preventing it from exceeding the maximum or
minimum limits. An alarm bit is also set if the calculated output is beyond these
limits.

Anti-Integral Windup
Integral windup occurs when the actuator is at its maximum or minimum limit
but the set point has not been reached. The integral term gradually increases,
increasing the output more than 100 percent (or less than 0 percent), which is
physically impossible for the actuator.

Date Code 20241023 Programming Reference


1136 SELUtils
Function Blocks

Figure 36.4 Integral Windup

The problem with integral windup is that it may take a relatively long time to
correct, because the integral term needs to unwind. The top graph in Figure 36.4
illustrates integral windup. The red line represents the output value that the PID
equation is instructing to send. The blue line represents the output value that is
actually sent. A PID control with no integral antiwindup implementation is not
aware of the PID output limits. Consequently, if the error persists long enough,
the integral term may grow indefinitely, beyond the output limit, driving the
actuator to the maximum limit. At this point, the PID equation no longer has an
impact on the controller output or the actuator. When the error changes to the
opposite sign, the output may take a long time to wind down before getting to
the operational range.

The bottom graph in Figure 36.4 illustrates a PID output with antiwindup
implementation. When the output reaches the limit, the integral calculation is
suppressed and consequently the output will not accumulate beyond this point.
When the error changes to the opposite sign, the output drops immediately to the
operational range.

The PID function block prevents integral windup by switching off integration
and keeping the accumulated integral term constant in either of the following
situations:

➤ PID output is greater than or equal to the maximum output limit


(MaxOUT) and the error is positive.
➤ PID output is less than or equal to the minimum output limit (MinOUT)
and the error is negative.

When the PID output returns to a value in the range between OutMIN and
OutMAX, the integral calculation resumes.

Programming Reference Date Code 20241023


SELUtils 1137
Function Blocks

Freezing Integral Calculation


The Freeze_I input parameter, when TRUE, suspends the integral calculation
and freezes the integral term. When Freeze_I is set back to FALSE, the integral
calculation resumes. This feature may be helpful in case of cascade control to
stop the integral calculation on the primary PID loop when the secondary PID
output hits the limit. See CascadeControl (Function Block) on page 1138 for
more information on cascade control.

Alarms
The PID function block has an alarm output to alert you of an abnormal
condition. The alarm output is a tag structure of Boolean variables; each
Boolean variable within the structure represents a different alarm. The alarms
that are implemented are shown in the following table.

Alarm Description

Output_High_Limit PID output has reached the maximum limit.

Output_Low_Limit PID output has reached the minimum limit.

SP_Out_of_Range Set-point value is out of the engineering units range (MinEU,


MaxEU).

PV_Out_of_Range Process variable value is out of the engineering units range


(MinEU, MaxEU).

PID Timing
The PID function block uses the Task Cycle Time as its time base and is
executed at a rate equal to a multiple of this time base. The TimeBase input
parameter defines the multiplier value for the PID execution rate.

For example, if you configure the RTAC to run every 50 milliseconds (Task
Cycle Time = 50) and the instance of the PID function block is configured with
TimeBase = 10, the PID code is executed every 500 milliseconds. This allows
you to have in your logic multiple instances of the PID function block running at
different rates.

Date Code 20241023 Programming Reference


1138 SELUtils
Function Blocks

PID Block Diagram

Figure 36.5 Block Diagram of the PID Instruction

CascadeControl (Function Block)


The CascadeControl function block is part of the PID library and facilitates the
implementation of a PID cascade system. By adding a CascadeControl function
block to the logic and properly connecting it to the primary and secondary
PID controllers, it will handle antiwindup logic (see Anti-Integral Windup on
page 1135), and switch between the different PID cascade modes (see Cascade
Control on page 1151).

Figure 36.6 CascadeControl Function Block

Programming Reference Date Code 20241023


SELUtils 1139
Function Blocks

In order to use this function block, set up a cascade control system using the
CascadeControl function block as follows:

1. Incorporate two PID function blocks (primary and secondary) and a


CascadeControl function block in your ACSELERATOR RTAC project.
2. Connect the CascadeControl function block inputs and outputs to the
corresponding inputs and outputs of the primary and secondary PID
blocks (refer to the CascadeControl Input Table).
3. Configure the individual PID settings (tuning constants, direct/reverse
action, derivative filter, etc.) for the primary and secondary controller.

Inputs
Name IEC 61131 Type Description

Mode CascadeModes The mode input determines the operating mode of the cascade system. The possible values for
this input are ManualMode, AutoMode, and CascadeMode. When this input is ManualMode,
both primary and secondary controllers are placed in Manual mode. In Manual mode, you
directly determine the output of the secondary controller by writing to the ManValue input
(0–100 percent). When this output is AutoMode, the primary controller is placed in Manual
mode and the secondary controller is placed in Automatic mode. You can directly manipulate
the set point of the secondary controller by writing to the AutoValue input (0–100 percent).
Finally, when this output is CascadeMode, both primary and secondary controllers are placed
in Automatic mode for full cascade operation.

PVsec REAL Connect the PVsec input to the process variable (PV) signal of the secondary controller. Note:
The PV signal of the secondary controller must be in percentage units (0–100 percent).

ManValue REAL The ManValue input determines the output of the secondary controller when the system is
in Manual mode. When the Mode input is ManualMode, the current value of this ManValue
input is sent to the output of the secondary controller. When the Mode input is AutoMode or
CascadeMode, the value of this ManValue input is ignored.

AutoValue REAL The AutoValue input determines the set point of the secondary controller when the system is
in Automatic mode. When the Mode input is AutoMode, the current value of this AutoValue
input is sent to the set point (SP) input of the secondary controller. When the Mode input is
ManualMode or CascadeMode, the value of this AutoValue input is ignored.

ALARMSsec PID_Alarms Connect the ALARMSsec input to the Alarms output of the secondary controller.

Outputs
Name IEC 61131 Type Description

AUTOpri BOOL Connect the AUTOpri output to the Auto input of


the primary PID controller.

AUTOsec BOOL Connect the AUTOsec output to the Auto input of


the secondary PID controller.

MANOUTpri REAL Connect the MANOUTpri output to the ManualOut


input of the primary PID controller.

MANOUTsec REAL Connect the MANOUTsec output to the ManualOut


input of the secondary PID controller.

FIpri BOOL Connect the FIpri output to the Freeze_I input of


the primary controller.

Date Code 20241023 Programming Reference


1140 SELUtils
Function Blocks

Cascade Control System Tuning


Tune a cascade control system by placing the primary controller in Manual
mode and tuning the secondary controller first. Once you have tuned the
secondary controller, start tuning the primary controller. When tuning the
primary controller, the system will be placed in Cascade mode (or Automatic
mode, depending on the tuning recipe). The primary controller will be tuned as
if you are tuning a single control loop system, treating the secondary controller
as just another part of the process.

From the perspective of the primary controller, the secondary controller is


part of the process. Consequently, any tuning modification on the secondary
controller may change the process dynamics of the outer loop, and this, in turn,
will impact the tuning of the primary controller. After the secondary controller is
tuned and tested, no modification will be made on its tuning parameters.

fb_PADM (Function Block)


Synchrophasor-based control and monitoring schemes often leverage calculated
phase angle differences, which can inform operators about system stress and
can be tracked over time to enable island detection, load shedding schemes, and
more.

The fb_PADM function block targets applications that require the calculation of
the angle difference between phasor measurements. It contains two configurable
alarms, which allow for alerts on varying levels of angle differences between the
inputs.

The angle difference is calculated as ÐPhasor1 − ÐPhasor2.

NOTE
For coherent function block output, input measurements must be measured
on a synchronized schedule and time-aligned such that the samples have
matching time stamps when processed by the fb_PADM function block.
Additionally, the fb_PADM implementation assumes that the measured angles
are wrapped between –180 and 180 (inclusive of 180). Both of these conditions
are automatically satisfied when you source all measurements from IEEE
C37.118 clients in the RTAC. Note, however, that phasor measurements from
®
SEL-2240 Axion modules are not automatically time-aligned with IEEE
C37.118 clients in the RTAC. You must implement additional logic to guarantee
time-alignment between IEEE C37.118 clients and Axion synchrophasor
measurements, which may be done with use of the class_TimeAlignment
provided in the ChannelMonitoring library. It is only necessary to time-align
phasor angles from IEEE C37.118 clients if they are being used in conjunction
with Axion measurements by the same fb_PADM. Axion synchrophasor
measurements are wrapped between –180 and 180 degrees.

Figure 36.7 fb_PADM Function Block

Programming Reference Date Code 20241023


SELUtils 1141
Function Blocks

Inputs
Name IEC 61131 Type Description

Enable BOOL Input to enable or disable operation.

Phasor1 CMV First phasor whose angle will be used for angle
difference monitoring.

Phasor2 CMV Second phasor whose angle will be used for angle
difference monitoring.

Threshold1 REAL Threshold angle (in degrees) above which Alarm1


output will assert.

Threshold2 REAL Threshold angle (in degrees) above which Alarm2


output will assert.

PT1 TIME Pickup time which must be elapsed before Alarm1


may assert.

PT2 TIME Pickup time which must be elapsed before Alarm2


may assert.

Outputs
Name IEC 61131 Type Description

Enabled BOOL Indicator that function block is active and


calculated values are valid.

AngleDiff MV Angle difference in degrees bounded between –180


and 180 (inclusive of 180) as a MV.

Alarm1 BOOL Alarm point which will assert if AngleDiff


surpasses Threshold1 for a time greater than that
specified by PT1.

Alarm2 BOOL Alarm point which will assert if AngleDiff


surpasses Threshold2 for a time greater than that
specified by PT2.

Processing
➤ If not enabled, outputs are all set as defaults such that AngleDiff.instMag
equals zero, AngleDiff.t.value is equal to system start time, Enabled is
FALSE, and both alarms are FALSE.
➤ If enabled, the output AngleDiff is loaded with updated attributes from
the input CMVs including the latest time, and the worst-case quality from
both input tags.
➤ The angle difference is calculated as Phasor1.instCVal.ang −
Phasor2.instCVal.ang where the resulting angle difference is wrapped
such that it is bounded by –180 and 180 (inclusive of 180).
➤ The absolute value of the evaluated angle difference is used to compare
against the two input thresholds, and this comparison is used to enable the
pickup timers for each respective alarm with time values specified by PT1
and PT2, respectively.

Date Code 20241023 Programming Reference


1142 SELUtils
Function Blocks

fb_TTLInput (Function Block)


This function block monitors an analog input for Transistor-Transistor-Logic.

Transistor–transistor logic (TTL) is a logic family built from bipolar junction


transistors. Some inter-device connection schemes use TTL logic to transmit
binary statuses between two IEDs with voltages in the range of 0–5 V. Typical
LOW (deasserted) values are between 0–0.8 V and typical HIGH (asserted)
values are between 2–5 V.

This function block accepts an analog signal registering the voltage of the
TTL input and evaluates it as a binary signal (TRUE/FALSE) according to the
minimum asserted and maximum deasserted thresholds.

Inputs
Name IEC 61131 Type Description

Input REAL The analog signal to condition as a TTL input.

MinimumAssertedThreshold REAL (Optional) A minimum voltage threshold to be evaluated as a HIGH signal


(asserted). Default is 2.

MaximumDeassertedThreshold REAL (Optional) A maximum voltage threshold above which values should no
longer be evaluated as a LOW signal (deasserted). Default is 0.8.

Inverted BOOL (Optional) A control to invert the resultant signal. When set, analog HIGH
values will equate to Boolean LOW values, and vice versa. Default is False.

Outputs
Name IEC 61131 Type Description

Result SPS A conditioned value to represent the binary status


of the TTL logic.

Processing
➤ If the input analog surpasses the assertion threshold or falls below the
deassertion threshold, the state of the output value is changed and the
time stamp is captured.
➤ If the Inverted flag is set, the output will be negated and set to its logical
inverse.
➤ If a custom minimum assertion threshold is found to be below the
maximum deassertion threshold, the quality of the output shall be set to
questionable.

fb_UnderComparatorWithHysteresis
This function block implements a comparator with hysteresis that compares the
input signal against a pickup value and the output asserts when the input value
is less than the pickup value. The output deasserts when the input signal returns
higher than the pickup value plus the hysteresis input.

Programming Reference Date Code 20241023


SELUtils 1143
Function Blocks

Inputs
Name IEC 61131 Type Description

InputSignal LREAL The input signal compared against the pickup value.

PickupValue LREAL The pickup value. When the input signal is less than this value, the
comparator output asserts.

Hysteresis LREAL The hysteresis value to reset the output signal.

Outputs
Name IEC 61131 Type Description

ComparatorOperate BOOL Asserts when the InputSignal is less than the PickupValue and remains
asserted until the InputSignal is greater than the PickupValue plus the
Hysteresis.

HystersisActive BOOL Asserts only after the comparator operate has asserted and the input value
is now greater than the PickupValue but not greater than the PickupValue
plus the Hysteresis.

Processing

Date Code 20241023 Programming Reference


1144 SELUtils
Function Blocks

➤ If logic evaluates to Reset, ComparatorOperate = False and


HysteresisActive = False.
➤ If logic evaluates to Operate, ComparatorOperate = True and
HysteresisActive = False.
➢ If Operate stage is active and both the InputSignal > (PickupValue +
Hysteresis) and InputSignal >= PickupValue are both satisfied, the
return to the Reset stage (InputSignal > (PickupValue + Hysteresis))
takes priority.
➤ If logic evaluates to HystersisActive, ComparatorOperate = True and
HysteresisActive = True.

fb_OverComparatorWithHysteresis
This function block implements a comparator with hysteresis that compares the
input signal against a pickup value and the output asserts when the input value is
greater than the pickup value. The output deasserts when the input signal returns
less than the pickup value minus the hysteresis input.

Inputs
Name IEC 61131 Type Description

InputSignal LREAL The input signal compared against the pickup


value.

PickupValue LREAL The pickup value. When the input signal is greater
than this value, the comparator output asserts.

Hysteresis LREAL The hysteresis value to reset the output signal.

Outputs
Name IEC 61131 Type Description

ComparatorOperate BOOL Asserts when the InputSignal is greater than the PickupValue and remains
asserted until the InputSignal is less than the PickupValue minus the
Hysteresis.

HystersisActive BOOL Asserts only after the comparator operate has asserted and the input value
is now less than the PickupValue but is not less than the PickupValue minus
the Hysteresis.

Programming Reference Date Code 20241023


SELUtils 1145
Benchmarks

Processing

➤ If logic evaluates to Reset, ComparatorOperate = False and


HysteresisActive = False.
➤ If logic evaluates to Operate, ComparatorOperate = True and
HysteresisActive = False.
➢ If Operate stage is active and both the InputSignal < (PickupValue -
Hysteresis) and InputSignal <= PickupValue checksare both satisfied,
the return to Reset stage (InputSignal < (PickupValue - Hysteresis))
takes priority.
➤ If logic evaluates to HystersisActive, ComparatorOperate = True and
HysteresisActive = True.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3505
➢ R143-V0 firmware
➤ SEL-3530
➢ R143-V0 firmware

Date Code 20241023 Programming Reference


1146 SELUtils
Benchmarks

➤ SEL-3555
➢ R143-V0 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R143 firmware

Benchmark Test Descriptions


REAL_TO_FORMATTED_STRING Performance Tests
This test runs the function REAL_TO_FORMATTED_STRING 1000 times
with a task cycle of 100 ms and the time to run the function is recorded. The
average, maximum, minimum, and standard deviation are recorded here.

LREAL_TO_FORMATTED_STRING Performance Tests


This test runs the function LREAL_TO_FORMATTED_STRING 1000 times
with a task cycle of 100 ms and the time to run the function is recorded. The
average, maximum, minimum, and standard deviation are recorded here.

TIMESTAMP_TO_STRING Performance Tests


This test runs the function TIMESTAMP_TO_STRING 1000 times with a
task cycle of 100 ms and the time to run the function is recorded. The average,
maximum, minimum, and standard deviation are recorded here.

VALIDITY_TO_STRING Performance Tests


This test runs the function VALIDITY_TO_STRING 1000 times with a task
cycle of 100 ms and the time to run the function is recorded. The average,
maximum, minimum, and standard deviation are recorded here.

Benchmark Results
Platform (time in ns)
Operation Tested Metric
SEL-3505 SEL-3530 SEL-3555

REAL_TO_FORMATTED_STRING Average 2540.4 1374.7 54.2


Maximum 10977.8 5904.3 321.1
Minimum 380.3 251.7 81.
Std Deviation 2722.5 1366.7 55.9

LREAL_TO_FORMATTED_STRING Average 314.6 204.9 16.7


Maximum 4636.9 1909.5 297.4
Minimum 102.1 76.5 3.8
Std Deviation 548.5 272.1 19.6

Programming Reference Date Code 20241023


SELUtils 1147
Examples

Platform (time in ns)


Operation Tested Metric
SEL-3505 SEL-3530 SEL-3555

TIMESTAMP_TO_STRING Average 1057.1 631.8 29.2


Maximum 6555.3 3841.6 399.1
Minimum 245.9 275.3 4.1
Std Deviation 749.7 376.6 36.6

VALIDITY_TO_STRING Average 1057.1 631.8 29.2


Maximum 6555.3 3841.6 399.1
Minimum 245.9 275.3 4.1
Std Deviation 749.7 376.6 36.6

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Using FORMAT_SIGNIFICANT_FIGURES Function (ST)


This example illustrates how the FORMAT_SIGNIFICANT_FIGURES function
can be used to convert a REAL quantity to a STRING formatted according to a
number of significant figures.
Code Snippet 36.1 FORMAT_SIGNIFICANT_FIGURES_Example
PROGRAM FORMAT_SIGNIFICANT_FIGURES_Example
VAR
OriginNum : REAL := 5431.24;
SigFigNum : STRING(255);
END_VAR

// Convert the number according to the number of significant figures


SigFigNum := FORMAT_SIGNIFICANT_FIGURES(OriginNum, Figures := 3);
// Result: SigFigNum is set to '5430'
SigFigNum := FORMAT_SIGNIFICANT_FIGURES(OriginNum, Figures := 5);
// Result: SigFigNum is set to '5431.2'

Using REAL_APPROX_EQUAL Function (ST)


This example illustrates how the REAL_APPROX_EQUAL function can be
used to evaluate the effective equality of two floating-point values.

The value 2242.6 cannot be exactly represented as a 32-bit float (REAL). It will
be represented as either ~2242.60009766 (0x450c299a) or ~2242.59985352
(0x450c2999). In this example, if we performed the mathematical operation
2000 * 1.1213, we would expect to get 2242.6. However, the result would be
stored as one of the above values. When comparing the equality of the result
of this operation to our expected value of 2242.6 assigned to a variable, it will

Date Code 20241023 Programming Reference


1148 SELUtils
Examples

evaluate to false. To account for this, we check whether the first value is one bit
greater or one bit less than the second value. Therefore, the "error" accounted for
in this comparison thus varies with the floating-point value but will always be
±1 bit. This means the error is relative to the magnitude of the value in question.
Code Snippet 36.2 REAL_APPROX_EQUAL_Example
PROGRAM REAL_APPROX_EQUAL_Example
VAR
actual : REAL := 2000 * 1.1213;
expectation : REAL := 2242.6;
result : BOOL;
END_VAR

// Evaluate the effective equality of the two floating point values


result := REAL_APPROX_EQUAL(actual, expectation);
// Result: the return value will be TRUE

Using REAL_TO_FORMATTED_STRING Function (ST)


This example illustrates how the REAL_TO_FORMATTED_STRING function
can be used to convert a REAL quantity to a formatted STRING.
Code Snippet 36.3 REAL_TO_FORMATTED_STRING_Example
PROGRAM REAL_TO_FORMATTED_STRING_Example
VAR
PiAsString : STRING(255);
END_VAR

// Convert math constant Pi to a STRING in standard notation and with 3 decimal places
PiAsString := REAL_TO_FORMATTED_STRING(Math.PI, FALSE, 3);
// Result: PiAsString is set to '3.142'

Using LREAL_TO_FORMATTED_STRING Function (ST)


This example illustrates how the LREAL_TO_FORMATTED_STRING
function can be used to convert an LREAL quantity to a formatted STRING.
Code Snippet 36.4 LREAL_TO_FORMATTED_STRING_Example
PROGRAM LREAL_TO_FORMATTED_STRING_Example
VAR
Pi : LREAL := 3.14159;
PiAsString : STRING(255);
END_VAR

// Convert Pi to a STRING in standard notation and with 3 decimal places


PiAsString := LREAL_TO_FORMATTED_STRING(Pi, FALSE, 3);
// Result: PiAsString is set to '3.142'

Using EncodeEventType Function (ST)


This example illustrates how the EncodeEventType function can be used to
convert a standard event type string from an SEL relay to an integer value that
may be more readily applicable for SCADA communications.

Programming Reference Date Code 20241023


SELUtils 1149
Examples

This example assumes that there exists an SEL-351S relay named


"SEL_351S_1_SEL" with the "NEW_EVENT_EVENT" string tag enabled
in addition to a DNP Shared Server Map with at least one INS analog input
configured as "DNPSharedMap_DNP.Event".
Code Snippet 36.5 Event_String_Encoding_Example
PROGRAM Event_String_Encoding_Example

// Convert the relay's event string to an encoded integer for the DNP shared server map
DNPSharedMap_DNP.Event := EncodeEventType (SEL_351S_1_SEL.NEW_EVENT_EVENT);
// Result: DNPSharedMap_DNP.Event contains an encoded representation of the event type that
// can be decoded by the 'DecodeEventType' function.

Using DecodeEventType Function (ST)


This example illustrates how the DecodeEventType function can be used to
evaluate the event type from an encoding created by the EncodeEventType
function. This is especially useful in extracting the event type description on a
SCADA device where the encoded event will be displayed as a string in some
form of human machine interface (such as the RTAC's HMI).
This example assumes that a DNP3 client exists in the project as
"Substation1_DNP" and contains an INS tag named "EventType".
Code Snippet 36.6 Event_String_Decoding_Example
PROGRAM Event_String_Decoding_Example
VAR
DecodedEvent : STR;
END_VAR

// Interpret the encoded event type for displaying to a user


DecodedEvent := DecodeEventType ( Substation1_DNP.EventType);
// Result: DecodedEvent now contains the string representation of the event reported
// by the relay and encoded using the 'EncodeEventType' function.

Standard Process Control (CFC and ST)


This example illustrates how to configure a PID instruction by using Continuous
Function Chart (CFC) and Structured Text (ST) programming languages,
respectively. The PID instructions are configured under the following
conditions:

➤ The range of the analog sensor that measures the process variable is 100–
1200.
➤ The analog PV sensor is connected to an analog input module.
➤ An analog output channel is used to adjust the final actuator.
➤ RTAC Task Cycle time is 100 ms and the PID instruction has to be
executed every 5 seconds.
➤ You use a switch, connected to digital input channel, to select between
Automatic and Manual modes.
➤ When in Manual mode, you use an RTAC HMI control to enter the PID
output value.
➤ When in Automatic mode, you use an RTAC HMI control to enter the set
point.
➤ Proportional-Integral (PI) control is required (no derivative action).

Date Code 20241023 Programming Reference


1150 SELUtils
Examples

➤ Proportional and integral tuning constants are stored in Global Variables


named P_ gain and I_time, respectively.
➤ A digital output alarm contact closes when the PID output reaches the
maximum or minimum limit.
➤ PID output cannot be greater than 85 percent or less than 10 percent.

PID Configuration in Continuous Function Chart (CFC)


PROGRAM Program1
VAR
TemperatureOven: PID;
END_VAR

Figure 36.8 PID Configuration in CFC

PID Configuration in Structured Text (ST)


Code Snippet 36.7 PIDcontrol
PROGRAM PIDcontrol
VAR
TemperatureOven: PID;
END_VAR

/////////////////// PID CONFIGURATION ///////////////////////


TemperatureOven(
SP := VirtualTagList1.APC_0000.oper.setMag, //7
PV := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag, //2
Kc := P_gain, Ti := I_time, //9
Td := 0, //8
Auto := SEL_24DI_1_ECAT.INPUT_001.stVal, //5
ManualOut := VirtualTagList1.APC_0001.oper.setMag, //6
MaxEU := 1200, MinEU := 100, //1
MaxOUT := 85, MinOUT := 10, //11
TimeBase := 50, //4
PIDout => SEL_8AO_1_ECAT.AO_VALUE_001); //3

// PID ALARMS
IF TemperatureOven.Alarms.Output_High_Limit
OR TemperatureOven.Alarms.Output_Low_Limit
THEN // 10
SEL_16DO_1_ECAT.OUTPUT_001.operSet.ctlVal := TRUE;
SEL_16DO_1_ECAT.OUTPUT_001.operClear.ctlVal := FALSE;
ELSE
SEL_16DO_1_ECAT.OUTPUT_001.operSet.ctlVal := FALSE;
SEL_16DO_1_ECAT.OUTPUT_001.operClear.ctlVal := TRUE;
END_IF

Programming Reference Date Code 20241023


SELUtils 1151
Examples

The input values that are not configured in the logic retain their default values.

Cascade Control
In some applications, two PID controllers are nested together and used in
combination to improve the control performance over the single-loop system.
This is called cascade control and is used to improve the response of the system
to disturbances.

Figure 36.9 shows a typical example of cascade control. The variable to


be controlled (primary variable) is the water temperature leaving the heat
exchanger. The operator sets the desired temperature (set point) on the primary
controller, which determines the desired amount of steam flow to control the
temperature. The output of the primary controller manipulates the set point of
the secondary controller, which maintains the steam flow at the desired level,
correcting any steam flow disruption before the primary variable is impacted.

Figure 36.9 Cascade Control Example

A single PID controller could control the temperature of the water by reading its
temperature (PV) and setting the position of the valve without going through a
secondary PID controller. However, if any disturbance occurs on the steam flow,
the effect of the disturbance has to flow through the water temperature process
and move the temperature away from the set point before it can be corrected by
the single PID controller. Introducing a secondary PID controller to control the
steam flow makes the loop control more stable and faster responding because
a flow control loop reacts much faster than a temperature control loop. Any
disturbance that affects the secondary variable is detected and compensated by
the secondary controller before it affects the primary variable.

Cascade control may be implemented on the RTAC by adding two PID function
block instances into the project (primary and secondary controllers) and
implementing additional logic to prevent integral windup and to switch between
the different cascade modes. The way to implement this additional logic is
described in Anti-Windup Logic on page 1152 and Cascade Control Logic
Using CascadeControl Function Block on page 1153.

Date Code 20241023 Programming Reference


1152 SELUtils
Examples

Anti-Windup Logic
In a single-loop controller, when the output of the PID function block reaches
the limit and the error contributes to increase the output beyond this point, the
integral accumulation is suspended. When the output returns to the operational
range, the integral accumulation resumes. This is called anti-windup and is
described in detail in Anti-Integral Windup on page 1135.

In cascade control, integral windup may occur in the primary controller because
of the interaction between the two controllers, and a different anti-windup
technique is necessary to prevent this problem from happening. Integrator
windup will occur if the output of the secondary controller hits the limit and the
primary controller continues to integrate the error. To prevent this, it is necessary
to implement an external anti-windup logic to automatically freeze the integral
term of the primary controller when the output of the secondary controller
reaches the limit. The PID function block provides alarm output bits to indicate
that the output is saturated, and also provides a Boolean input to freeze the
integral term. Implementing the external anti-windup logic is straightforward if
you use these alarm output bits and Freeze_I input.

The Structured Text code in Code Snippet 36.8 shows a configuration example
of a primary PID controller. The highlighted line shows how to configure
the Freeze_I input to suspend the integral calculation when the output of the
secondary PID controller hits the higher or lower limit.
Code Snippet 36.8 Configuration Example of Primary PID Controller
PROGRAM CascadeLogic
VAR
PrimaryPID : PID;
SecondaryPID : PID;
END_VAR

PrimaryPID (SP := VirtualTagList1.APC_0000.oper.setMag,


PV := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag,
Kc := P_gain, Ti := I_time , Td := 0,
Auto := SEL_24DI_1_ECAT.INPUT_001.stVal,
ManualOut := VirtualTagList1.APC_0001.oper.setMag,
MaxEU := 1200, MinEU := 100, MaxOut := 85,
MinOut := 10, TimeBase := 50,

PIDout => SEL_8AO_1_ECAT.AO_VALUE_ACTUAL_001,

// THIS IS THE IMPORTANT PART


Freeze_I := SecondaryPID.Alarms.Output_High_Limit
OR SecondaryPID.Alarms.Output_Low_Limit);

Implementation of PID Cascade Modes


Most cascade control applications require three different operating modes:
manual, automatic, and cascade. Manual and automatic modes are typically
used during startup and commissioning, whereas cascade is used for normal
operation. These operating modes are explained in Table 36.6.

Programming Reference Date Code 20241023


SELUtils 1153
Examples

Table 36.6 Cascade Operating Modes

Cascade Mode
➤ The operator manipulates the set point of the primary
controller.
➤ Both primary and secondary controllers are in automatic mode.

Automatic Mode
➤ The operator manipulates the set point of the secondary
controller.
➤ Primary controller is in manual mode and secondary controller
is in automatic mode.

Manual Mode
➤ The operator directly manipulates the final control element
(valve).
➤ Both primary and secondary controllers are in manual mode.

When implementing the operating modes, take the following considerations into
account to ensure there is no sudden change in the output to the final actuator.
➤ Cascade Mode
➢ Both controllers (primary and secondary) must be placed in
Automatic mode.
➤ Automatic Mode
➢ The primary controller should be placed in Manual mode.
➢ The secondary controller should be placed in Automatic mode.
➢ The operator directly controls the set point of the secondary controller
by setting a value to the ManualOut input of the primary controller.
➤ Manual Mode
➢ Both controllers (primary and secondary) must be placed in Manual
mode.
➢ The operator directly controls the final actuator by setting a value to
the ManualOut input of the secondary controller.
➢ The output of the primary controller must track the process variable
(PV) of the secondary controller. This will allow a bumpless transfer
to Automatic or Cascade mode.

Cascade Control Logic Using CascadeControl Function Block


Connect the CascadeControl function block to the primary and secondary PID
controllers.

Date Code 20241023 Programming Reference


1154 SELUtils
Examples

NOTE
The secondary PID controller process variable (PV) must be in percentage
units (0–100 percent). This scaling can be done directly in the analog output
module settings, or by using programming logic, as shown in Figure 36.10.

Figure 36.10 Cascade Configuration

Using fb_PADM Function Block


This example illustrates how the fb_PADM function block can be used to
monitor the angle difference between two phasor measurements originating from
two IEEE C37.118 clients (SEL_421_1_C37_118 and SEL_351_1_C37_118,
respectively) each with a single PMU named PMU1. You can log the outputs in
these examples via the SOE (Sequence of Events) logger, assign them to virtual
tags for use on an HMI, and/or use them in additional user-defined logic.

This logic is shown implemented as CFC in Figure 36.11, and as ST in Code


Snippet 36.10. Both examples use identical declarations shown in Code
Snippet 36.9.
Code Snippet 36.9 Angle_Difference_Tracking_Declaration_Example
PROGRAM Angle_Difference_Tracking
VAR
// PADM instance
PADM1 : fb_PADM;

// Static inputs
Warning_Threshold : REAL := 10;
Warning_Pickup_Time : TIME := T#5S;
Alarm_Threshold : REAL := 15;
Alarm_Pickup_Time : TIME := T#10S;

// Outputs
PADM1_OK : BOOL;
PADM1_Angle_Difference : MV;
PADM1_Warning : BOOL;
PADM1_Alarm : BOOL;
END_VAR

Programming Reference Date Code 20241023


SELUtils 1155
Examples

Figure 36.11 Angle_Difference_Tracking_Example_CFC

Code Snippet 36.10 Angle_Difference_Tracking_Example_ST


// Load inputs
PADM1.Enable := (SEL_421_1_PMU1.V1LPM.t.quality.accuracy = T5)
AND (SEL_421_1_PMU1.V1LPM.q.validity = good)
AND (SEL_351_1_PMU1.V1PM.t.quality.accuracy = T5)
AND (SEL_351_1_PMU1.V1PM.q.validity = good);

PADM1.Phasor1 := SEL_421_1_PMU1.V1LPM;
PADM1.Phasor2 := SEL_351_1_PMU1.V1PM;
PADM1.Threshold1 := Warning_Threshold;
PADM1.Threshold2 := Alarm_Threshold;
PADM1.PT1 := Warning_Pickup_Time;
PADM1.PT2 := Alarm_Pickup_Time;

// Run function block


PADM1 ();

// Load outputs
PADM1_OK := PADM1.Enabled;
PADM1_Angle_Difference := PADM1.AngleDiff;
PADM1_Warning := PADM1.Alarm1;
PADM1_Alarm := PADM1.Alarm2;

Using fb_TTLInput Function Block


This example illustrates how the fb_TTLInput function block can be used to
monitor an analog value as the signal for transistor-transistor logic. This allows
low-level analogs to be conditioned as binary inputs, which is useful when
Boolean signals are provided with voltage levels below that of standard Axion
inputs.

This logic is shown implemented as ST in Code Snippet 36.12 and a declaration


shown in Code Snippet 36.11.
Code Snippet 36.11 Analog_TTL_Tracking_Declaration_Example
PROGRAM Analog_TTL_Tracking
VAR
// Transistor-Transistor-Logic Monitor instance
ttl1 : fb_TTLInput;

// Static inputs
Min_Asserted : REAL := 4.5;
Max_Deasserted : REAL := 1;
END_VAR
VAR_OUTPUT
InputAsserted : SPS;
END_VAR

Date Code 20241023 Programming Reference


1156 SELUtils
Examples

Code Snippet 36.12 Analog_TTL_Tracking_Example


// Run function block
ttl1(
Input := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag,
MinimumAssertedThreshold := Min_Asserted,
MaximumDeassertedThreshold := Max_Deasserted,
Inverted := FALSE
);

// Load output
InputAsserted := ttl1.Result;

Programming Reference Date Code 20241023


S E C T I O N 3 7

SVPplus
Introduction
The SVPplus (Synchrophasor Vector Processor Plus) library provides Prony
Analysis of signals, referred to here as modal analysis. The overall goal of this
library is to encapsulate algorithms that describe the dynamics of a substation or
electrical grid.

Modal Analysis (MA)


Similar to Fourier series, modal analysis decomposes a signal into its individual
frequencies or modes. In addition, it also provides the damping rate of
each frequency. Damping information is vital when monitoring wide area
power system stability as it can be used to predict sustained or uncontrolled
oscillations.

Because of the computationally intensive nature of this algorithm, it is very


important to consider benchmarks while using this object. See Benchmarks on
page 1163 for benchmark information.

Sample Timing
The timing requirements of the modal analysis input signal are the responsibility
of the user of the library. The library does not check the times of the samples
given. The interval between each sample must be within acceptable error of the
sample rate given in hertz. For example, if 20 Hz is given, the period between
samples should be 0.05 seconds. The recommended error threshold is 5 percent.

Use Cases
Modal Analysis has been proven significantly useful in several areas of power
system analysis.

Sometimes power system equipment or their controllers can be configured in


such a way that they unintentionally incite growing oscillations. Rapid detection
of these forced oscillations is important to guard against excessive mechanical
fatigue and system instability. Modal analysis can detect these events by noting
the maximum modal amplitudes of a system and triggering an alarm or control
action based on larger than normal and/or increasing magnitude of oscillatory
modal amplitude.

Disturbances in the power system are often identifiable from the decaying
oscillations visible from streaming synchrophasor measurements. These events
provide an opportunity to determine the natural system dynamic modes. The
dynamic modes inform planners of the inherent stability, or lack thereof, of the
power system and help identify areas where additional stabilizing devices could
be installed.

Date Code 20241023 Programming Reference


1158 SVPplus
Introduction

Modal analysis performed on ambient data can identify the frequency of the
natural dynamic modes. A change in the frequency component of these modes
can indicate a system change that may require further investigation.

Operation
The modal analysis function block in this library is responsible for two primary
tasks. The first task is to collect and store samples given to it. The second task is
to analyze these stored values once enough new samples are given and return the
modes of the stored signal.

The samples are stored in a ring buffer. Once a certain percentage of new
samples are given, modal analysis is conducted on the stored array of samples.
Figure 37.1 shows this visually, where blue indicates old samples and red new
samples. If the object has just been initialized and there are no stored samples,
modal analysis is not complete until the entire buffer has been filled. After the
initial filling of the buffer, modal analysis is done once the percentage of new
samples has been reached. For example, if the total number of samples specified
as the initialization variable numSamples is set to 100, and percentUpdate is
set to 10 percent, then the tenth call to GiveSample() will trigger another
calculation. This new modal calculation is performed on the most recent 90
old samples and the 10 new samples, with the oldest 10 samples having been
overwritten in the ring buffer.

Figure 37.1 Ring Buffer Used to Store Samples in Modal Analysis Object

Because modal analysis is very computationally expensive, the analysis is done


over many task cycles. The Run() method of each modal object does part of
the analysis each cycle until it is complete. If a new analysis has been triggered
and the previous is not yet complete, it is ignored until the previous analysis is
finished. Once the current analysis is complete, the ignored trigger causes a new
analysis to begin immediately. The ignored trigger is not a queue, but rather is a
single request to restart once the previous analysis completes.

Modes
Modes are returned from modal analysis, which is the decomposition of
the input signal into a series of modes. These modes consist of sinusoidal
decaying signals that closely match the original signal when summed together.
The equation used to construct each mode from their values is given in
Equation 37.1, where A is the amplitude, is the decay, f is the frequency, and
is the angle phase.

Programming Reference Date Code 20241023


SVPplus 1159
Supported Firmware Versions

Equation 37.1

The quality of the signal is determined by the signal-to-noise ratio (SNR)


returned with a call to GetModes(). Equation 37.2 shows how the SNR is
calculated, where S is the original signal and N is a signal reconstructed from the
modes returned.

Equation 37.2

The SNR is calculated by using the decibel logarithmic unit on the ratio of
the root-mean-square of the original signal over the root-mean-square of the
difference between the original signal and reconstructed signal. If the value is
20, then the amplitude of the signal is 10 times greater than the error; when the
value is 40, the amplitude of the signal is 100 times greater than the error, and so
on.

Damping Ratio
The damping ratio is determined from the decay α and the frequency f (as
seen in Modern Solutions for Protection, Control, and Monitoring of Electric
Power Systems ISBN 978-0-9725026-3-4). Equation 37.3 is used to compute the
damping ratio. A negative damping ratio illustrates an increasing oscillation that
can lead to power system instability.

Equation 37.3

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Versions 3.5.0.3 and earlier can be used on RTAC firmware version R132 and
later.

Global Constants
This section lists values of global constants provided for facilitating work with
the library.

Name IEC 61131 Type Value Description

g_c_Infinity REAL ∞ Positive infinity.

Date Code 20241023 Programming Reference


1160 SVPplus
Structure Definitions

Structure Definitions
This section enumerates structures needed for the user to communicate with this
library.

struct_Mode
This object contains the information for one sinusoidal mode returned from
class_ModalAnalysis.

Name IEC 61131 Type Description

Amplitude REAL Amplitude of this mode.

Frequency REAL Frequency of this mode.

Phase REAL Phase of this mode in radians.

Damping REAL Decay rate of this mode.

DampingRatio REAL Damping ratio of this mode.

Classes
This section enumerates the classes used to access the functionality of this
library.

class_ModalAnalysis (Class)
This class conducts modal analysis on an input signal.

Initialization Inputs
Name IEC 61131 Type Description

numSamples UDINT Total number of samples this modal analysis object


uses.

sampleRate UINT Rate at which samples are taken in hertz.

percentUpdate UDINT(10..100) Percentage of new samples this modal analysis


collects before performing analysis.

stepTime ULINT The amount of time in microseconds the Run()


method will run each time it is called.

numModes UDINT(1..16) Number of modes that are returned from analysis.

For any meaningful analysis of a digital input signal, a minimum number of


sample history must be stored in a buffer. numSamples is the size of this buffer
for modal analysis.

Programming Reference Date Code 20241023


SVPplus 1161
Classes

Outputs
Name IEC 61131 Type Description

IsEnabled BOOL Flag that states if this class instance is


active.

Error POINTER TO STRING(80) If class instance failed initialization, this


points to a string describing what failed.

These outputs give the status of the modal analysis object as a whole. If the
initialization of the class instance was successful, it is flagged and enabled and
ready to take new samples to analyze. If initialization failed, it is flagged as not
enabled and the error string pointer returns a pointer to a string that described
what failed in initialization.

bootstrap_SetFilter (Method)
This initialization routine sets the filter that is used on the raw input provided by
GiveSample(). This routine is optional to call, and if it is not called, no filter is
used and the raw samples are fed directly into modal analysis.

Inputs
Name IEC 61131 Type Description

filter I_Filter Interface pointer to filter that will be used on raw


input.

Return Value
IEC 61131 Type Description

BOOL Returns TRUE if the filter was successfully added to the object.

Processing
This routine takes the interface to the filter and confirms the pointer to it is real.
If the pointer to the filter is zero or the modal analysis object has already been
initialized, it will return FALSE as a failure.

GiveSample (Method)
This method gives a new sample as input to the modal analysis block. The
sample rate integrity of the signal must be verified by the user, as discussed in
Sample Timing on page 1157.

Inputs
Name IEC 61131 Type Description

sample REAL New sample.

Date Code 20241023 Programming Reference


1162 SVPplus
Classes

Processing
This method takes the input sample and stores it within its internal buffer of
samples. If enough new samples have been given or the entire buffer of samples
has been populated for the first time, the method will trigger the calculation of
new modes. This calculation is done over many cycles in the run method.

Reset (Method)
Modal analysis is only effective on a continuous stream of evenly spaced
samples. When a gap in the stream has been detected, modal analysis must be
reset. This causes it to discard all previous samples. Additionally, a sample with
unacceptably low quality is considered a gap in the stream, and therefore, modal
analysis must be reset.

Resetting modal analysis delays the next analysis as additional samples will
need to be gathered. A sample is considered bad if it does not meet the timing
requirements defined in Sample Timing on page 1157 or if the quality of the
sample is unacceptable.

Processing
This method will discard all saved samples and start with an empty buffer that
needs to be refilled for modal analysis to happen.

Run (Method)
This method must run once per cycle for each modal analysis object that exists.
It is responsible for processing modal analysis of the samples. It performs a part
of an analysis, if one is pending, each time it is called.

Return Value
IEC 61131 Type Description

UDINT Percentage of completion for modal analysis task from 0 to 100.

Processing
Once the output complete has reached 100, the analysis is complete and
GetModes can be called.

GetModes (Method)
Call this method to get the most recent modal analysis results. If no analysis has
yet been done, this method will return an array of structures whose values are all
set to zero.

The range of the signal-to-noise ratio can be anywhere from 0 to the maximum
number of UINT. Increasing the number of modes returned will improve this
signal-to-noise ratio.

Programming Reference Date Code 20241023


SVPplus 1163
Benchmarks

Inputs
Name IEC 61131 Type Description

pt_modes POINTER TO struct_Mode Address of array to copy modes to as returned by the ADR() function. This array
must contain numModes structures as specified in the Initialization Inputs of the
class.

Return Value
IEC 61131 Type Description

REAL Signal-to-noise ratio that determines quality of modes returned.

Processing
If no analysis has yet been done, this method will set all structures to zero. If the
number of modes for this object has been initialized with a number n that is less
than the global value g_p_numModes, then all structures past n will be set to
zero.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms:

➤ SEL-3505
➢ R134 firmware
➤ SEL-3530
➢ R134 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V1 firmware

Benchmark Test Descriptions


Because so much of the performance of this library is defined by the user, these
benchmarks attempt to give an overall feel for the cost of performing modal
analysis in terms of number of samples and number of modes requested. All
results are presented as the number of scans taken to perform the analysis where
the ModalAnalysis object is given 5 ms of run time each task cycle.

The following benchmarks are tested:

➤ 4, 8, and 16 modes with 500 samples


➤ 4 modes with 600 samples
➤ 4, 8, and 16 modes with 5000 samples

Date Code 20241023 Programming Reference


1164 SVPplus
Examples

Benchmark Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555

4 Modes 500 Samples 27 16 2

8 Modes 500 Samples 114 64 6

16 Modes 500 Samples 462 253 21

4 Modes 600 Samples 34 17 3

4 Modes 5k Samples 155 93 2

8 Modes 5k Samples 460 276 23

16 Modes 5k Samples 1586 952 80

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Calculating Modes
Objective
The objective of this example is to calculate the modal frequencies and damping
coefficients of a synchrophasor frequency measurement for oscillation stability
analysis at an update rate of once per second. This example will cover the
preconditioning of incoming time stamps and how to call the ModalAnalysis
methods in the appropriate sequence.

Assumptions
This example assumes the following are true:

➤ The RTAC project incorporates both the SVPplus and Analog


Conditioning libraries.
➤ The RTAC is collecting synchrophasor measurements from one
synchrophasor measurement device, referenced here as a C37_118 RTAC
client called PMU1.
➤ The RTAC is performing no tasks other than those referred to in this
example.
➤ The nominal frequency of the power system is 60 Hz.
➤ The synchrophasor message rate is 60 samples per second.
➤ The RTAC Main Task cycle time, under which all programs are being
run, is set to 8 ms.

Programming Reference Date Code 20241023


SVPplus 1165
Examples

➤ The Deadband and Zero Deadband settings for the PMU1.FREQ tag are
set to 0.
➤ There are only four modes of interest in the system. Each is between 0.3
Hz and 10 Hz.
➤ Data samples are filtered with a 10 Hz cutoff low-pass filter before being
processed with MA. The ArmaFilter class from the Analog Conditioning
library is used to implement this filter. This is also demonstrated in the
example.
➤ The global variable list and sample flagging programs shown in Code
Snippet 37.1 and Code Snippet 37.2, respectively, are included in the
project.
Code Snippet 37.1 Global Variable List
VAR_GLOBAL CONSTANT
g_c_NumModes : UINT := 4;
// Using coefficients for a 10 Hz cutoff low pass filter.
g_c_Acoeff : ARRAY[1..g_p_MaxFilterOrder] OF REAL := [-1.96299, 1.40000, -0.34641];
g_c_Bcoeff : ARRAY[0..g_p_MaxFilterOrder] OF REAL :=
[0.011325, 0.033975, 0.033975, 0.011325];
END_VAR

VAR_GLOBAL
g_SampleQuality, g_SampleUpdated, g_SampleTimeValid, g_SampleValid : BOOL;
g_SNR : REAL;
g_ModeResults : ARRAY [1..g_c_NumModes] OF struct_Mode;
g_DampingAlarm : ARRAY [1 .. g_c_NumModes] OF BOOL;
END_VAR

Code Snippet 37.2 prg_SampleFlagging


PROGRAM prg_SampleFlagging
VAR
dTime : DINT; // Current day and time of PMU1_C37_118
us, timeNow, timeLast, timeDiff : LREAL;
END_VAR

// Establish the quality of the sample.


g_SampleQuality := NOT(DINT_TO_BOOL(PMU1_C37_118.FREQ.q.validity)) AND
NOT(PMU1_C37_118.FREQ.t.quality.clockNotSynchronized);
// Calculate the time difference between the current and previous samples.
dTime := DT_TO_DINT(PMU1_C37_118.FREQ.t.value.dateTime);
us := UDINT_TO_LREAL(PMU1_C37_118.FREQ.t.value.uSec) / 1000000;
timeNow := dTime + us;
timeDiff := (timeNow - timeLast)*1000; // Sample time difference in ms
timeLast := timeNow;
// Determine if the sample has updated.
IF (timeDiff > 0) THEN
g_SampleUpdated := TRUE;
ELSE
g_SampleUpdated := FALSE;
END_IF
// Validate the sample time difference against +-2.5 % of a 60 Hz period.
// This check allows us to detect missing samples. This is important because the
// accuracy of the modal analysis result is heavily affected by missing samples.
IF (timeDiff > 17.08 OR timeDiff < 16.25) THEN
g_SampleTimeValid := FALSE;
ELSE
g_SampleTimeValid := TRUE;
END_IF
// Assign overall sample validity.
IF (g_SampleQuality AND g_SampleTimeValid) THEN
g_SampleValid := TRUE;
ELSE
g_SampleValid := FALSE;
END_IF

Date Code 20241023 Programming Reference


1166 SVPplus
Examples

Solution
Having flagged the incoming samples for quality and continuity, the samples can
be filtered and processed with MA as shown in Code Snippet 37.3.
Code Snippet 37.3 prg_ModeCalc
PROGRAM prg_ModeCalc
VAR
modal : SVPplus.class_ModalAnalysis( numSamples := 600, sampleRate
:= 60,
percentUpdate := 10, stepTime := 4000,
numModes := g_c_NumModes);
inputSample : REAL;
filter : class_ArmaFilter(g_c_Acoeff, g_c_Bcoeff, 3, 4);
analysisComplete : R_TRIG;
doneLatch : BOOL;
init : BOOL := TRUE;
END_VAR

// Update input sample.


inputSample := PMU1_C37_118.FREQ.instMag;
// Initialize: Load filter into the MA object.
IF init THEN
modal.bootstrap_SetFilter(filter);
init := FALSE;
END_IF

// Load the sample into MA only if it has updated and is valid.


IF(g_SampleUpdated) THEN
IF(g_SampleValid) THEN
modal.giveSample(inputSample - 60); // Factor out the 60 Hz offset
ELSE
// If the sample is not valid, clear the data buffer
modal.reset();
END_IF;
END_IF;

(* If Run() method is at 100 % completion, populate g_ModeResults and return SNR.


Use an edge trigger to guarantee that getModes() is only called once per analysis. *)
doneLatch := modal.Run() = 100;
analysisComplete(CLK := doneLatch);
IF analysisComplete.Q THEN
g_SNR := modal.getModes(ADR(g_ModeResults));
END_IF

Analyzing Modes
Objective
The objective of this example is to demonstrate how the output of the
ModalAnalysis class can be processed to flag a necessary control action.

Assumptions
This example extends the previous example. Thus, it is assumed that the
getModes() method has been called successfully. It is further assumed that
the program in this example will accesses the global variable list defined in the
previous example.

Programming Reference Date Code 20241023


SVPplus 1167
Examples

Solution
The code below shows a simple example which asserts a per-mode alarm bit
if the given mode meets the user-specified criteria. The signal-to-noise ratio
output of the getModes() method is used to validate the accuracy of the modal
estimation.
Code Snippet 37.4 prg_ModeAnalyze
PROGRAM prg_ModeAnalyze
VAR
dmpThr : REAL; // Define damping ratio threshold here.
ampThr : REAL; // Define oscillation amplitude threshold here.
SNRFail : BOOL;
i : UINT;
END_VAR

IF g_SNR > 5 THEN


SNRFail := FALSE;
FOR i := 1 TO g_c_NumModes DO
IF g_ModeResults[i].DampingRatio < dmpThr
AND g_ModeResults[i].Amplitude > ampThr
AND g_ModeResults[i].Frequency > 0 // Factor out DC modes.
THEN
g_DampingAlarm[i] := TRUE;
ELSE
g_DampingAlarm[i] := FALSE;
END_IF
END_FOR
ELSE
SNRFail := TRUE;
END_IF

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 3 8

SnmpLite
Introduction
This library encapsulates common communications management responsibilities
that industrial control and monitoring equipment are expected to perform
on the communications fabric of a control system using Simplified Network
Management Protocol (SNMP).

The common use for these devices is to annunciate failures within the system.
Therefore, this library only provides basic network interface descriptions
and port states to allow detection and annunciation of device failures. More
advanced diagnostic and system description tools that fully use SNMP
are outside the scope of this library and are not considered to be common
requirements of an automation controller.

Glossary
Abstract Syntax Notation One (ASN.1). A standard that provides rules
and a notation for representing, encoding, transmitting, and decoding data in
telecommunications. SNMP uses this standard to represent the data within a
UDP packet.

Management Information Base (MIB). A hierarchical description of the


structure and data available in a device that supports SNMP.

Object Identifier (OID). A unique identifier for an object or leaf in a


hierarchically defined namespace, where a "." specifies the next object as the
child of the previous. For example, the OID 1.3.6.1.2.1.2.2.1 identifies the
entries in a table of interfaces. In the context of this library, OIDs uniquely
identify information found in communication with the network devices.

SNMP Trap. Unsolicited information SNMP agents send to SNMP managers.


Events that trigger SNMP Traps and the Trap content are configured on the
SNMP agent device and utilize Port 162.

Simplified Network Management Protocol (SNMP). An Internet standard


protocol for managing devices on IP networks. This protocol is generally
supported by network-fabric devices such as Ethernet switches and routers, and
it is often used by other network-centric devices. There are many versions of
SNMP. All SNMP traffic, except SNMP traps, is sent and received on Port 161.

Simple Network Management Protocol Version 2, Community-Based


SNMPv2c). This version of the protocol transmits all data, including the
community strings used to group SNMP agents and managers, in raw form with
no encryption.

User Datagram Protocol (UDP). A connectionless, packet-based protocol used


to stream data between two devices without requiring responses. UDP does not
implement handshaking, packet ordering, or confirmation of packet delivery.

Date Code 20241023 Programming Reference


1170 SnmpLite
Introduction

Special Considerations
Consider the following topics when implementing this library in a project.

Versions of SNMP
This version of the library only supports SNMPv2c, which is an unsecured
implementation that transmits all data on the wire without encryption or security.

Open SNMP Ports


This library does not have the ability to open ports in the RTAC firewall to
communicate with the various devices. When the class_SnmpManager is
instantiated in an ACSELERATOR RTAC® project, the creator of that project is
responsible for creating two access points that allow the class_SnmpManager
object to communicate with the specified devices.

➤ UDP Port 161 Ethernet Listener Access Point must be created for all
normal SNMP traffic.
➤ UDP Port 162 Ethernet Listener Access Point must be created to receive
SNMP traps.

Declaring Objects in Global Variable Lists


This library uses variables in a Global Variable List (GVL) set to Global
Initialization Slot 1 as the registry mechanism for its classes.

Instantiating a class in this library as a global variable and forcing it to be


initialized at Global Initialization Slot 1 or lower will cause undefined behavior.
Declaring classes in a normal global variable list causes no issues because the
default Global Initialization Slot is 50000 (unless explicitly set otherwise).

All SNMP Objects in a Single, Non-Time Critical Task


This library expects that all instantiated objects are in the same task. Care has
been taken in designing this library to evenly distribute processing load, and
the library scales to management of many devices without incurring additional
processing. However, the execution time to parse arbitrarily large and complex
responses from agent devices is, by nature, not deterministic. Therefore,
this library should not be used on the same task with logic that must execute
deterministically.

Put All SNMP Objects in a Single Program


Consider instantiating all of these objects in a single IEC 61131 program to
mitigate the concerns described in Declaring Objects in Global Variable Lists
on page 1170 and All SNMP Objects in a Single, Non-Time Critical Task on
page 1170.

Programming Reference Date Code 20241023


SnmpLite 1171
Supported Firmware Versions

Copying Instantiated Objects


Copying classes from this library causes unwanted behavior. This means the
following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_SnmpObject"
mySnmpObject := otherSnmpObject;

// This is fine
someVariable := mySnmpObject.value;
// As is this
pt_mySnmpObject := ADR(mySnmpObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.

Scope of Instantiated Objects


Classes in this library have memory allocated inside them. As such, they should
only be created in environments of permanent scope (e.g., Programs, Global
Variable Lists, or VAR_STAT sections).

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.
Versions 3.5.0.3 and earlier can be used on RTAC firmware version R133 and
later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

NOTE
See http://tools.ietf.org/html/rfc2863 for more information about the
interface states.

enum_InterfaceStatus
This enumeration provides a textual representation of the statuses possible for
any individual port.

Enumeration Description

NONE Interface specified is out of range for this device.

UP Interface status is up.

DOWN Interface status is down.

Date Code 20241023 Programming Reference


1172 SnmpLite
Structures

Enumeration Description

TESTING Interface is in test configuration.

UNKNOWN Port link status is unknown.

DORMANT The interface is ready to transmit and receive network traffic


but is waiting on some external event.

NOT_PRESENT Interface is not configured in this hardware.

LOWER_LAYER_DOWN The dependent interface is not up, a condition relevant only if


stacked interfaces are employed.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

struct_InterfaceInfo
This structure contains some of the commonly used information available in the
table OID 1.3.6.1.2.1.2.2.1.N.

NOTE
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2)
ifTable(2) . ifEntry(1) . item(N)

Name IEC 61131 Type Description

ifIndex UDINT The index the manufacturer provides from OID 1.3.6.1.2.1.2.2.1.1.N.

ifDescr STRING(255) First 255 characters of description from OID 1.3.6.1.2.1.2.2.1.2.N.

ifType UDINT The integer value of the interface type from OID 1.3.6.1.2.1.2.2.1.3.N.

ifSpeed UDINT The bandwidth this interface report during initialization from OID
1.3.6.1.2.1.2.2.1.5.N.

ifPhysicalAddress STRING(80) Usually the MAC address. Obtained from OID 1.3.6.1.2.1.2.2.1.6.N.

ifOperStatus enum_InterfaceStatus The operational status of this link from OID 1.3.6.1.2.1.2.2.1.8.N. This updates
periodically, or when this library receives a trap.

Classes
class_SnmpManager (Class)
A single class_SnmpManager object is instantiated to manage the UDP traffic
on Port 161 for SNMP get and set requests and responses to these requests. The
same object listens on Port 162, which is the SNMP trap listening port. If two
or more class are instantiated, all but one of the classes will fail to initialize and
display an appropriate error state.
This object issues SNMP requests queued by instantiated SNMP agent classes.
It sends responses to these requests and forwards SNMP traps received from a
given IP address to the SNMP agent class associated with the sending IP. The
agent class is responsible for the processing of the message.

Programming Reference Date Code 20241023


SnmpLite 1173
Classes

The manager issues no more than one SNMP request per call to the Run()
method. This constraint evenly distributes the load per scan and allows support
for an arbitrary number of agents. However, this constraint also means that
the more devices that this manager supervises, the more time it takes to cycle
through the pending requests from all of the agent classes. This result can
be mitigated by configuring traps on the SNMP agent devices because the
manager also processes one trap per call to the Run() method; a trap event will
update the status of the SNMP device immediately and the delay in getting new
information is not affected by the number of devices being monitored. Instead,
only the number of traps received simultaneously affects the latency of updates
to the agent monitoring classes.

Run (Method)
Call this method once every scan on a low-priority task where real-time
performance is not critical.

Processing
The Run() method does the following:

➤ Issues a pending poll:


➢ Get the next registered agent class.
➢ Issue the queued request.
➤ Dequeues a maximum of two SNMP traps from the Port 162 socket and
then sends the traps to the agent class designated to the IP address of the
sender for parsing.
➤ Dequeues a maximum of two SNMP responses from the Port 161 socket
and then send the responses to the agent class designated to the IP address
of the sender for parsing.

class_SnmpAgentMonitor (Class)
When instantiated, this class registers itself with the active class_SnmpManager.
There is no need to call methods on this class or to run it periodically because
the manager class is responsible for refreshing the state of all agent monitors.
This class monitors a generic SNMP agent device that has a list of network
interfaces listed under OID 1.3.6.1.2.1.2.2.11. It also displays the number of
interfaces the SNMP agent provides in response to requesting the Integer32
value at OID 1.3.6.1.2.1.2.12.
The list of interfaces is initially obtained by walking through all of the table
objects. If the number of interfaces returned by walking the interface table is less
than the number of interfaces OID 1.3.6.1.2.1.2.1 advertises, the device will not
enable. If the interface information from all interfaces can be obtained, then the
object enables itself. Subsequently, the agent only requests port statuses via OID
1.3.6.1.2.1.2.2.1.8.N3.
The port information obtained by GetInterfaceInfo() updates only during
initialization, with the exception of ifOperStatus, which continually updates.
1
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) . ifTable(2) . ifEntry(1).
2
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) . ifNumber(1).
3
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) . ifTable(2) . ifEntry(1) . ifOperStatus( 8) . item(N).

Date Code 20241023 Programming Reference


1174 SnmpLite
Classes

In the event that (a) the agent does not receive replies to requests for
ifOperStatus, (b) the quantity of interfaces changes, or (c) the indexing of the
monitored interfaces changes, this block sets ENO to FALSE and attempts to
reinitialize.

This basic SNMP agent monitor discards SNMP traps it receives from the
class_SnmpManager object because the contents of SNMP traps are highly
dependent on the MIB of the particular device sending the traps.

Initialization Inputs
Name IEC 61131 Type Description

ipAddress STRING(15) The IP address of the monitored agent as a string.

communityString STRING(80) A string that designates the community this agent


device has been assigned. This ID is included in
every packet the agent and manager send.

Outputs
Name IEC 61131 Type Description

IpAddress STRING(15) The IP address as a string.

ENO BOOL The class was initialized.

NumInterfaces UDINT The number of interfaces the agent device


has.

MessagesReceived UDINT The total number of responses and traps


received from the manager object since ENO
last became true.

TimeSinceLastMessage TIME The elapsed time since the last message from
this device.

Error STRING(255) The last error encountered will be described


here. It will not be cleared.

GetInterfaceStatus (Method)
This method provides the status of the specified interface.

Inputs
Name IEC 61131 Type Description

interfaceIndex UDINT A numeric identifier of the interface. It must


be greater than 0 and less than or equal to
NumInterfaces.

Return Value
IEC 61131 Type Description

enum_InterfaceStatus The state of the requested interface.

Programming Reference Date Code 20241023


SnmpLite 1175
Classes

Processing
➤ Check that interfaceIndex is within the specified range. Return NONE if
it is not.
➤ Return the state of the specified interface.

GetInterfaceInfo (Method)
This method returns the information obtained from walking OID
1.3.6.1.2.1.2.2.1 before the ENO output was true.

NOTE
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) .
ifTable(2) . ifEntry(1)

Inputs
Name IEC 61131 Type Description

interfaceIndex UDINT A numeric identifier of the interface. It must


be greater than 0 and less than or equal to
NumInterfaces.

Outputs
Name IEC 61131 Type Description

info struct_InterfaceInfo The structure containing the interface information.

Return Value
IEC 61131 Type Description

BOOL TRUE if the object is initialized and the interfaceIndex is in range.

Processing
➤ Check that interfaceIndex is within the specified range. Return FALSE if
it is not, leaving the output in an undefined state.
➤ Copy internal information to the output and return true.

Reinitialize (Method)
Returns the agent to an uninitialized state, resulting in the ENO output being
set to FALSE. From this point, the agent automatically tries to re-initialize,
refreshing all port information in the process.

class_SEL2730MAgent (Class)
This class has all of the functionality of the class_SnmpAgentMonitor. However,
because the number of ports are known in advance, the class also displays the
port statuses as pins.

Date Code 20241023 Programming Reference


1176 SnmpLite
Classes

Because this class contains knowledge of the device, future changes to


SEL-2730M firmware may change interface enumerations in SNMP. All
versions of SEL-2730M firmware that do not impact the assumptions in
SEL-2730M Assumptions on page 1176 will work.

SEL-2730M Assumptions
1. Port F up/down status is not accessible via SNMP get request. Where
all other ports default to NONE and then report the status of SNMP get
requests, this port defaults to UNKNOWN until a trap is received and
then changes to UP or DOWN as appropriate.
2. Ports 1–24 can be accessed through use of a GetNextRequest SNMP
command. The order of the ports is unimportant.
3. The description field of Ports 1–24 always ends with the port number.
The OID order is randomly defined at every boot, so the class uses the
description to associate the OID with the physical port index.

When instantiated, this class registers itself with the active class_SnmpManager.
There is no need to call methods on this class or to run it periodically because
the manager class is responsible for refreshing the state of all agent monitors.

This class monitors a generic SNMP agent device that has a list of network
interfaces listed under OID 1.3.6.1.2.1.2.2.14. It also displays the number of
interfaces the SNMP agent provides in response to requesting the Integer32
value at OID 1.3.6.1.2.1.2.15.

The list of interfaces is initially obtained by walking through all of the table
objects. If the number of interfaces returned by walking the interface table is less
than the number of interfaces OID 1.3.6.1.2.1.2.1 advertises, the device will not
enable. If the interface information from all interfaces can be obtained, then the
object enables itself. Subsequently, the agent only requests port statuses via OID
1.3.6.1.2.1.2.2.1.8.N6.

The port information obtained by GetInterfaceInfo() updates only during


initialization, with the exception of ifOperStatus, which continually updates.

In the event that (a) the agent does not receive replies to requests for
ifOperStatus, (b) the quantity of interfaces changes, or (c) the indexing of the
monitored interfaces changes, this block sets ENO to FALSE and attempts to
reinitialize.

Traps from SEL-2730M devices have a known structure, so traps sent to this
agent monitor from the class_SnmpManager are parsed. The textual message
contained in a trap that is displayed in the LastMessage output. If the trap
indicates a port status change, the state of the indicated port updates accordingly.

Whether by traps or periodic queries, the output pin statuses update


automatically without the implementer having to call any methods or the body
of the class.

4
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) . ifTable(2) . ifEntry(1).
5
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) . ifNumber(1).
6
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) . ifTable(2) . ifEntry(1) . ifOperStatus(8) . item(N).

Programming Reference Date Code 20241023


SnmpLite 1177
Classes

Initialization Inputs
Name IEC 61131 Type Description

ipAddress STRING(15) The IP address of the monitored agent as a string.

communityString STRING(80) A string that designates the community this agent


device has been assigned. This ID is included in
every packet the agent and manager send.

Outputs
Name IEC 61131 Type Description

IpAddress STRING(15) The IP address as a string.

ENO BOOL The class was initialized.

NumInterfaces UDINT The number of interfaces the agent


device has.

MessagesReceived UDINT The total number of responses and


traps received from the manager object
since ENO last became true.

TimeSinceLastMessage TIME The elapsed time since the last message


from this device.

Error STRING(255) The last error encountered will be


described here. It will not be cleared.

LastMessage STRING(255) The first 255 characters of the last


string message from this device.

PortStatus ARRAY[0..24] OF The state of all ports. Index 0 is ETHF,


enum_InterfaceStatus Index 1 is Port 1, Index 24 is Port 24.

GetPortInfo (Method)
This method returns the information obtained from walking OID
1.3.6.1.2.1.2.2.1 before the ENO output was true. The index provided is the port
number for the SEL-2730M instead of an arbitrary order.

NOTE
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) .
ifTable(2) . ifEntry(1).

Inputs
Name IEC 61131 Type Description

portNumber UDINT(0..24) The port index on the switch. portNumber 0 is for


ETHF, 1 is for Port 1, and 24 is for Port 24.

Outputs
Name IEC 61131 Type Description

info struct_InterfaceInfo The structure containing the interface information.

Date Code 20241023 Programming Reference


1178 SnmpLite
Classes

Return Value
IEC 61131 Type Description

BOOL TRUE if the object is initialized and the requested port number is in
range.

GetInterfaceStatus (Method)
This method provides the status of the specified interface.

Inputs
Name IEC 61131 Type Description

interfaceIndex UDINT A numeric identifier of the interface. It must


be greater than 0 and less than or equal to
NumInterfaces.

Return Value
IEC 61131 Type Description

enum_InterfaceStatus The state of the requested interface.

Processing
➤ Check that interfaceIndex is within the specified range. Return NONE if
it is not.
➤ Return the state of the specified interface.

GetInterfaceInfo (Method)
This method returns the information obtained from walking OID
1.3.6.1.2.1.2.2.1 before the ENO output was true.

NOTE
iso(1) . org(3) . dod(6) . internet(1) . mgmt(2) . mib-2(1) . interfaces(2) .
ifTable(2) . ifEntry(1)

Inputs
Name IEC 61131 Type Description

interfaceIndex UDINT A numeric identifier of the interface. It must


be greater than 0 and less than or equal to
NumInterfaces.

Outputs
Name IEC 61131 Type Description

info struct_InterfaceInfo The structure containing the interface information.

Programming Reference Date Code 20241023


SnmpLite 1179
Benchmarks

Return Value
IEC 61131 Type Description

BOOL TRUE if the object is initialized and the interfaceIndex is in range.

Processing
➤ Check that interfaceIndex is within the specified range. Return FALSE if
it is not, leaving the output in an undefined state.
➤ Copy internal information to the output and return true.

Reinitialize (Method)
Returns the agent to an uninitialized state, resulting in the ENO output being
set to FALSE. From this point, the agent automatically tries to re-initialize,
refreshing all port information in the process.

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R134-V0 firmware
➤ SEL-3530-4
➢ R133-V0 firmware
➤ SEL-3505
➢ R133-V0 firmware

Benchmark Test Descriptions


class_SnmpManager.Run()
The posted time is the average execution time of 100 method calls when no traps
are being received.

class_SnmpAgentMonitor.GetInterfaceStatus()
The posted time is the average execution time of 100 method calls.

class_SnmpAgentMonitor.GetInterfaceInfo()
The posted time is the average execution time of 100 method calls.

Date Code 20241023 Programming Reference


1180 SnmpLite
Examples

class_SnmpAgentMonitor.Reinitialize()
The posted time is the average execution time of 100 method calls.

class_SEL2730MAgent.GetPortInfo()
The posted time is the average execution time of 100 method calls.

class_SEL2730MAgent.GetInterfaceStatus()
The posted time is the average execution time of 100 method calls.

class_SEL2730MAgent.GetInterfaceInfo()
The posted time is the average execution time of 100 method calls.

class_SEL2730MAgent.Reinitialize()
The posted time is the average execution time of 100 method calls.

Benchmark Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530-4 SEL-3555

class_SnmpManager.Run() 644 409 22

class_SnmpAgentMonitor.GetInterfaceStatus() 49 11 1

class_SnmpAgentMonitor.GetInterfaceInfo() 92 4 1

class_SnmpAgentMonitor.Reinitialize() 12 65 1

class_SEL2730MAgent.GetPortInfo() 47 8 1

class_SEL2730MAgent.GetInterfaceStatus() 37 8 1

class_SEL2730MAgent.GetInterfaceInfo() 18 6 1

class_SEL2730MAgent.Reinitialize() 21 19 1

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Programming Reference Date Code 20241023


SnmpLite 1181
Examples

Monitoring Port Status of Three SEL-2730M Switches


Objective
A user has an SEL-RTAC that he wants to use to monitor link status of Ports
5–24 on three switches. He wants an alarm if one of those ports is inactive or if
an additional port has a device plugged in.

Assumptions
➤ The RTAC being programmed can access three SEL-2730M devices
configured on the network. These SEL-2730M devices have the following
IP addresses:
➢ 10.203.50.1
➢ 10.203.50.101
➢ 10.203.50.201
➤ The user has configured these switches to communicate with the RTAC
via SNMP. This means the following:
➢ The user has added a v2c profile to the switch with the community
string "Switches" and at least Read permissions.
➢ The user has added the RTAC to the switch as a trap server using the
desired profile.
➤ The RTAC, configured as the SNMP manager, has an IP address
10.203.50.2.
➤ The Main task of the RTAC is not used for real-time critical purposes,
making it appropriate to instantiate the SNMP manager object on the
Main task.
➤ The RTAC has two access points configured to allow UDP traffic as
follows:
➢ UDP incoming on Port 161 for normal SNMP
➢ UDP incoming on Port 162 for SNMP traps

Solution
On the Main task, the user can create a program as shown in Code Snippet 38.1.
Code Snippet 38.1 prg_SnmpManagerWith3Agents
PROGRAM prg_SnmpManagerWith3Agents
VAR CONSTANT
c_NumSwitches : UDINT := 3;
END_VAR
VAR
SnmpManager : class_SnmpManager;
Switch1 : class_SEL2730MAgent( iPAddress := '10.203.50.1',
communityString := 'Switches');
Switch2 : class_SEL2730MAgent( iPAddress := '10.203.85.101',
communityString := 'Switches');
Switch3 : class_SEL2730MAgent( iPAddress := '10.203.85.201',
communityString := 'Switches');
Alarm : BOOL;
SwitchPointers : ARRAY[1..c_NumSwitches] OF POINTER TO
class_SEL2730MAgent := [ ADR(Switch1),
ADR(Switch2), ADR(Switch3)];
END_VAR
VAR_TEMP

Date Code 20241023 Programming Reference


1182 SnmpLite
Examples

i, j : UDINT; // Iterators used.


END_VAR

// Run the SnmpManager, which is responsible for doing all the required work.
SnmpManager.Run();

// Initialize to success, so any unexpected result can flag failure.


Alarm := FALSE;
FOR i := 1 TO c_NumSwitches DO
// Check that statuses match expected.
IF SwitchPointers[i]^.PortStatus[0] = SnmpLite.UP THEN
// Alarm if something is plugged into the front port.
// Note that ETHF status cannot be polled, so it will remain in
// UNKNOWN state until a trap is received.
Alarm := TRUE;
END_IF
FOR i := 1 TO c_NumSwitches DO
FOR j := 1 TO 4 DO
IF SwitchPointers[i]^.PortStatus[j] <> SnmpLite.DOWN THEN
// Alarm if something plugged into the gigabit ports.
Alarm := TRUE;
END_IF
END_FOR
FOR j := 5 TO 24 DO
IF SwitchPointers[i]^.PortStatus[j] <> SnmpLite.UP THEN
// Alarm if something unplugged from ports 5–24.
Alarm := TRUE;
END_IF
END_FOR
END_FOR

Programming Reference Date Code 20241023


S E C T I O N 3 9

SyslogCollector
Introduction
This library allows the RTAC to receive syslog messages from other devices.
Once the RTAC receives a syslog message, the contents of the message are
available to the IEC 61131 logic engine. Logic can be performed on the syslog
messages to accomplish the following:
➤ Store syslog messages into the SOE log of the RTAC.
➤ Create a custom syslog file with the FileIO library.
➤ Map syslog data into protocol servers.
➤ Display syslog messages on RTAC HMI screens.
➤ Generate an email or text message.
➤ Generate syslog messages based on received syslog messages with
modified content.
The syslog message is presented to the logic engine as a string data type.
Anything that can be done with a string in the logic engine can be done with the
received syslog message.
This library offers the ability to filter received syslog messages based on its
origin IP address. It also allows for automatically logging the received syslog
messages into the RTAC SOE.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

struct_syslogMessageFormat
Name IEC 61131 Type Description

ReceivedIPAddress String(15) IP address from which the syslog message


was received.

FacilityLevel enum_facility The facility level of the syslog message.

SeverityLevel enum_severity The severity level of the syslog message.

SyslogMessage STRING(2000) The content of syslog message.

Date Code 20241023 Programming Reference


1184 SyslogCollector
Enumerations

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

enum_severity
This enumeration lists the different severity levels allowed in syslog.

Enumeration Value Description

Emergency 0 System is unusable

Alert 1 Action must be taken immediately

Critical 2 Critical conditions

Error 3 Error conditions

Warning 4 Warning conditions

Notice 5 Normal but significant conditions

Informational 6 Informational messages

Debug 7 Debug-level messages

None 8 No severity selected

enum_facility
This enumeration lists the different facility levels allowed in syslog.

Enumeration Value Description

kern 0 Kernel messages

user 1 User-level messages

mail 2 Mail system

daemon 3 System daemons

auth 4 Security/authorization messages

syslog 5 Messages generated internally by syslogd

lpr 6 Line printer subsystem

news 7 Network news subsystem

uucp 8 UUCP subsystem

clock 9 Clock daemon

authpriv 10 Security/authorization messages

ftp 11 FTP daemon

NTP 12 NTP subsystem

logAudit 13 Log audit

logAlert 14 Log alert

cron 15 Scheduling daemon

Programming Reference Date Code 20241023


SyslogCollector 1185
Function Blocks

Enumeration Value Description

local0 16 Local use 0

local1 17 Local use 1

local2 18 Local use 2

local3 19 Local use 3

local4 20 Local use 4

local5 21 Local use 5

local6 22 Local use 6

local7 23 Local use 7

None 24 No facility selected

Function Blocks
fb_syslogCollector (Function Block)
This function block makes syslog messages that were received on one of the IP
addresses of the RTAC available to the IEC 61131 logic engine.

Inputs
Name IEC 61131 Type Description

LocalIPAddress STRING(15) Specify an RTAC IP address on which to listen. Default is 0.0.0.0, which listens on
all interfaces.

LocalPortNumber UINT Defaults to 514, which is the standard syslog port.

LogReceivedSyslog BOOL If TRUE, received syslog data will be entered into the RTAC SOE log.

FilterOnSeverity enum_Severity If set to a value other than NONE, the RTAC will only log syslog messages that
have a severity of NONE or higher. Default value is NONE.

UseSeverityInSyslogMessage enum_Severity If set to a value other than NONE, received syslog messages will use this severity
when logged. If set to NONE, logged syslog messages will use the severity
received in message. Default value is NONE.

IPAddressFilterList STRING(1600) Enter a comma-separated list of IP addresses for the RTAC to process syslog
messages from. If left empty, the RTAC processes all received syslog messages.

Outputs
Name IEC 61131 Type Description

RecSyslogMessage ARRAY[1..50] OF Received syslog messages.


struct_SyslogMessageFormat

InvalidInputPin STRING Lists an incorrectly configured input pin.

Date Code 20241023 Programming Reference


1186 SyslogCollector
Examples

Processing
➤ This function block will log received syslog messages in the RTAC SOE
if the LogReceivedSyslog input is set to TRUE. If the syslog message
is longer than 255 characters, the logged message will be truncated and
MessageTruncated will be appended to the end of the SOE message.
➤ This function block filters received syslog messages based upon
the originating IP address. These addresses can be entered into the
IPAddressFilterList input. If this value is left empty or set to 0.0.0.0
(which is the default setting), the function block will process all received
syslog messages.
➤ This function block will process as many as 50 received syslog messages
per processing cycle. If the RTAC receives more than 50 syslog messages
in a single processing cycle, the excess messages will be buffered and
processed in a subsequent processing interval. The function block
displays processed messages for a single processor cycle.
➤ By default, Port 514 is used to listen for syslog messages. This can be
changed by configuring the LocalPortNumber input to a desired port to
listen for syslog messages.
➤ This function block only processes UDP-based syslog messages. No TCP
syslog messages are processed with this function block.
➤ This function block must be used in conjunction with an Ethernet
listening UDP incoming access point that matches the LocalPortNumber
input. Unless the input pin is configured to a nondefault value, this port
must be 514 on the Ethernet listening UDP incoming access point.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Receiving Syslog Messages


Objective
A user would like to collect all syslog messages from other devices in their
substation network.

Assumptions
A UPD incoming access point needs to be included in the project
configuration. The Local Port Number setting input of the port must match the
LocalPortNumber setting on the syslog function block, as shown in Figure 39.1
and Code Snippet 39.1.

Programming Reference Date Code 20241023


SyslogCollector 1187
Examples

Figure 39.1 UDP Incoming Access Point

Solution
The syslog function block can be used as shown in Code Snippet 39.1. This
example shows the function block processing all received syslog messages on
a specified interface (by entering the IP address used on that interface). This
example also shows the function block storing all received messages with their
received severity levels into the SOE log of the RTAC.
Code Snippet 39.1 prg_SyslogCollector
PROGRAM prg_SyslogRec
VAR
_syslogCollector : fb_SyslogCollector;
END_VAR

_syslogCollector(LocalIPAddress := '192.168.1.2',
LocalPortNumber := 514,
LogReceivedSyslog := TRUE,
FilterOnSeverity := SyslogCollector.enum_severity.None,
UseSeverityInSyslogMessage := SyslogCollector.enum_severity.None,
IPAddressFilterList := '');

Figure 39.2 shows the same program but in a CFC program.

Figure 39.2 prg_SyslogCollector in CFC Form

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 4 0

TrendRecorder
Introduction
This library provides flexible and scalable analog trend recording capability to
the RTAC. It can provide ACSELERATOR TEAM® SEL-5045 Software Load Data
Profile (LDP) records, which are viewable via SEL-5705 Synchrowave Reports.
By using intuitive function blocks, users can configure as many as 32 different
recorders, each capable of recording 16 analog values. Two types of recorders
are available: an interval recorder and a monitor recorder. The interval recorder
uses a recording interval setting and records all 16 analog values each interval.
The monitor recorder has a record time and a trigger input. Recording occurs
when the rising edge of the trigger is observed and the time provided by the
record time input is associated with the record (instead of the internal time
source of the RTAC). Each recorder records the value of each analog at the time
the record occurs (also known as an end-of-Interval recorder).
This document provides detailed information about the purpose and
functionality of each function block (along with its inputs and outputs). It also
provides a configuration example.

Special Considerations
Record Storage Space
The TrendRecorder library uses files stored on the RTAC file system to record
data. The amount of data that can be retained is dependent on the available hard
drive space as well as the recording interval configured for each recorder.

Recommended Library Class Usage


Copying classes from this library causes unwanted behavior. This means the
following:
1. The assignment operator ":=" must not be used on any class from this
library; consider assigning pointers to the objects instead.

// This is bad and in most cases will provide a compiler error such as:
// "C0328: Assignment not allowed for type class_ProfileRecorderObject"
myProfileRecorderObject := otherProfileRecorderObject;

// This is fine
someVariable := myProfileRecorderObject.value;
// As is this
pt_myProfileRecorderObject := ADR(myProfileRecorderObject);

2. Classes from this library must never be VAR_INPUT or VAR_OUTPUT


members in function blocks, functions, or methods. Place them in the
VAR_IN_OUT section or use pointers instead.

Date Code 20241023 Programming Reference


1190 TrendRecorder
Supported Firmware Versions

Classes in this library have memory allocated inside them. As such, they should
only be created in environments of permanent scope (e.g., Programs, Global
Variable Lists, or VAR_STAT sections).

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R143 or later.
To enable TrendRecorder library support, the device number of your RTAC
must include the feature in its model option table (MOT). You cannot download
projects including this library to RTACs that do not support the library. Use the
SEL website MOT configuration (https://www.selinc.com/onlinemot/) to ensure
that a particular part number has TrendRecorder support enabled.
Version 3.5.3.0 must be used on RTAC firmware version R150 and later.
Versions 3.5.0.3 and earlier can be used on RTAC firmware version R136-V2
and later.

Usage
The purpose of this library is to provide analog trend recording capability to
the RTAC in a way that requires as little configuration as possible. All settings
required for recorder setup are completed with only three function blocks
(see Function Blocks on page 1192 for more detail). This section provides
information about the intended usage of the TrendRecorder library as well as
some details about operations that occur in the background.

Theory of Operation
The TrendRecorder library is designed to interface with TEAM. TEAM collects
the recorded data in LDP format and saves it into the ACSELERATOR Database.
The collected data is then available for other software solutions, such as
Synchrowave Reports.
It is important to note that the TrendRecorder library can record analog values
from any capable source—it is not limited only to typical load profile or even
electrical) values. As long as the analog is of type REAL, it can be recorded.
The core of the TrendRecorder library user interface consists of two profile
recorder function blocks: ProfileIntervalRecorder and ProfileTriggerRecorder.
Contained within these two function blocks is everything the RTAC needs
to collect and record analog data. Simply instantiate one or more of them in
a Continuous Function Chart (CFC) program, connect each recorder to the
ProfileManager function block, create a Telnet Access Point, and start collecting
recorded data. Each recorder records 16 analogs, and as many as 32 recorder
function blocks can be instantiated (512 total analogs can be recorded in a single
RTAC).
Each ProfileIntervalRecorder records data at an interval specified by its
RecordingInterval setting. If possible, the recorder will align the recording
interval with the current time. For example, if an interval of 5 seconds is
specified, the recorder will record data at 0, 5, 10, 15, 20 seconds, and so on.

Programming Reference Date Code 20241023


TrendRecorder 1191
Usage

If 1800 seconds is specified (equal to 30 minutes), the recorder will record


data at the top of the hour and the bottom of the hour (at 0 and 30 minutes
of the hour). A full list of auto-aligned intervals is available in Inputs in
ProfileIntervalRecorder (Function Block) on page 1192.

Each ProfileTriggerRecorder records data when the rising edge of an external


trigger is observed, at a frequency as high as once per second. It is capable of
accepting an external time stamp to associate with the data record. This allows
the RTAC to save data with the same time stamp provided by a remote IED with
the data over a protocol that supports time-stamped data (such as Distributed
Network Protocol (DNP)).

The ProfileManager function block is responsible for providing the Telnet


command line interface that TEAM uses to collect recorded data. It is also
responsible for compiling and transmitting records via a binary data format to
TEAM via YMODEM.

NOTE
TEAM collects trend record data from the RTAC via Telnet. An Access Point
configured for Telnet Port 23 must exist within the RTAC project to facilitate
this communication.

Date Code 20241023 Programming Reference


1192 TrendRecorder
Function Blocks

Figure 40.1 Example Recorder Usage

Function Blocks
This library provides three function blocks for use in setting up trend recorders:
ProfileIntervalRecorder, ProfileTriggerRecorder, and ProfileManager. You only
need these function blocks to configure fully functional profile recording in the
RTAC.

ProfileIntervalRecorder (Function Block)


This function block records 16 analogs of type REAL at a specified interval
from 1 to 7200 seconds. Any unused channels record a zero at each recording
interval.

Programming Reference Date Code 20241023


TrendRecorder 1193
Function Blocks

Inputs
Name IEC 61131 Type Description

ConnectToProfileManager This pin must be connected to the ProfileManager. This connection is required for
the recorder to save data and for the manager to retrieve data when TEAM requests
it.

RecorderNumber UINT The recorder number (1–32) to assign to the recorder. Any recorder with a recorder
number outside of this range will not record data. Any recorders that duplicate a
recorder number will not record data.

RecordingInterval UINT The interval (1–7200, in seconds) at which to record data. If no RecordingInterval
is provided, the recorder will default to a setting of 60 seconds. Any interval value
less than one will be forced to a setting of one. Any interval value greater than 7200
will be forced to a setting of 7200.

Channel[n]_Data REAL The analog inputs to be recorded, where n is the channel number from 01–16. Zeros
are recorded for all disconnected channel data inputs.

Channel[n]_Name STRING(15) The names of analogs to be recorded, where n is the channel number from 01–16.
Channel names longer than 15 characters will be truncated to the first 15 characters.
If no value is assigned, the channel name will be set to Chan [n] Rec [x], where n
is the channel number and x is the recorder number.

Outputs
Name IEC 61131 Type Description

SettingsError BOOL This output asserts if the recorder has a settings


error. If this output is asserted, the recorder will not
function.

ProfileTriggerRecorder (Function Block)


This function block records 16 analogs of type REAL any time the rising edge
of the record trigger input is observed, at a frequency as high as once per second.
Any unused channels will record a zero at each recording interval.

Inputs
Name IEC 61131 Type Description

ConnectToProfileManager This pin must be connected to the ProfileManager. This connection is required for
the recorder to save data and for the manager to retrieve data when TEAM requests
it.

RecorderNumber UINT The recorder number (1–32) to assign to the recorder. Any recorder with a recorder
number outside of this range will not record data. Any recorders that duplicate a
recorder number will not record data.

RecordTrigger UINT The recording trigger. Asserting this trigger at a rate as high as once per second will
result in data being recorded.

RecordTime DT The record time that will be used when recording data. If this input is not providing
a valid time or is left disconnected, the internal time of the RTAC will be used
instead.

Date Code 20241023 Programming Reference


1194 TrendRecorder
Function Blocks

Name IEC 61131 Type Description

Channel[n]_Data REAL The analog inputs to be recorded, where n is the channel number from 01–16. Zeros
are recorded for all disconnected channel data inputs.

Channel[n]_Name STRING(15) The names of analogs to be recorded, where n is the channel number from 01–16.
Channel names longer than 15 characters will be truncated to the first 15 characters.
If no value is assigned, the channel name will be set to Chan [n] Rec [x], where n
is the channel number and x is the recorder number.

Outputs
Name IEC 61131 Type Description

SettingsError BOOL This output asserts if the recorder has a settings error. If this output is asserted, the recorder
will not function.

RecordingBlocked BOOL This output asserts immediately following an assertion of the RecordTrigger input and
remains asserted for one second. When asserted, no recording occurs, and any assertion of the
RecordTrigger input is ignored.

ProfileManager (Function Block)


This function block is used to provide files to TEAM. It also helps manage
RTAC storage space for all configured recorders. It has three inputs—DeviceID,
TerminalID, and FID—which are used by Synchrowave Reports to label reports
generated using data collected from the RTAC. Do not create more than one
instance of ProfileManager, as doing so results in undesired behavior. All
configured recorders must be connected to it via their ConnectToProfileManager
pins.

Inputs
Name IEC 61131 Type Description

DeviceID STRING(22) The RTAC device description. Inputs greater than


22 characters are truncated to 22 characters.

TerminalID STRING(22) A description of the function or location of the


RTAC. Inputs greater than 22 characters are
truncated to 22 characters.

FID STRING The Firmware ID of the RTAC. SystemTags.FID


must be connected to this input. If this input is not
connected, no recording occurs.

Outputs
Name IEC 61131 Type Description

ConnectToRecorders The connection point for the ConnectToProfileManager pins on each configured
recorder. Each recorder must be connected to this pin in order to function.

DataStorageWarning BOOL This output asserts when not enough storage space is available to meet the
requirements of the current recorder configurations. When this output asserts
recorders will run out of storage space within 30 days. To resolve this issue
either free up hard drive space on the RTAC or reduce the number of configured
recorders.

Programming Reference Date Code 20241023


TrendRecorder 1195
Recorder Operation

Name IEC 61131 Type Description

DataStorageError BOOL This output asserts when no storage space is available, indicating no new data are
being saved.

SettingsError BOOL This output asserts if the recorder has a settings error. If asserted, none of the
recorders will function.

Telnet Communications
The ProfileManager function block uses Telnet to provide trend data to external
clients such as TEAM. To be able to communicate via Telnet on the RTAC, an
Access Point with Network Connection Type of Telnet and Local Port Number
of 23 must be added to the RTAC project.

Recorder Operation
Recording Interval Functionality
The ProfileIntervalRecorder attempts to time-align the recording interval with
the top of minute, top of hour, or top of day. This makes for cleaner chart
generation and data visualization. The following table describes how each
interval setting is adjusted.

Interval Setting (seconds) Time Alignment Behavior

1 Top of second

2 Top of second AND current second MOD 2 = 0

3 Top of second AND current second MOD 3 = 0

4 Top of second AND current second MOD 4 = 0

5 Top of second AND current second MOD 5 = 0

6 Top of second AND current second MOD 6 = 0

10 Top of second AND current second MOD 10 = 0

15 Top of second AND current second MOD 15 = 0

20 Top of second AND current second MOD 20 = 0

30 Top of second AND current second MOD 30 = 0

60 Top of minute

120 Top of minute AND current minute MOD 2 = 0

180 Top of minute AND current minute MOD 3 = 0

240 Top of minute AND current minute MOD 4 = 0

300 Top of minute AND current minute MOD 5 = 0

360 Top of minute AND current minute MOD 6 = 0

600 Top of minute AND current minute MOD 10 = 0

900 Top of minute AND current minute MOD 15 = 0

1800 Top of minute AND current minute MOD 30 = 0

3600 Top of hour

Date Code 20241023 Programming Reference


1196 TrendRecorder
Recorder Operation

Interval Setting (seconds) Time Alignment Behavior

7200 Top of hour AND current hour MOD 2 = 0

All others Start recording immediately (no time alignment)

Effect of Task Cycle Time on TrendRecorder Functionality


Like all user logic executing on an RTAC, the Trend Recorder library executes at
a speed defined by the Cycle Time setting of the task it is running on. It is highly
recommended that configured recorders be run on a task with a cycle time as
fast as possible (i.e., 100 milliseconds or less).

NOTE
The slower the Task Cycle setting, the longer it will take for the RTAC to
communicate with TEAM. The collection interval configured in TEAM should be
adjusted to account for this.

ProfileTriggerRecorder RecordTime Input Requirements


The ProfileTriggerRecorder function block can associate record data with an
external time stamp provided via the RecordTime input. This input is of type DT
and in order to be valid must be greater than midnight on January 1, 2000.

Settings Changes
When the settings of a recorder are changed, all of the saved data for that
recorder is removed from the RTAC. A loss of data in other recorders could also
occur because of storage reallotment caused by the addition of a new recorder.

Changes to settings elsewhere in the RTAC (i.e., not recorder settings) will not
result in deleted data. The only data loss that may occur would be caused by a
missed recording interval during the sending of the new settings to the RTAC.

The Trend Recorder function blocks require 60 seconds to initialize after startup,
regardless of settings change.

Do not remove or modify the files stored in the LDP folder on the RTAC. These
files contain settings and record data. Tampering with or removing these files
may result in recorder data loss or deletion.

Loss of Data Because of File System Use


Because of the flexibility of the RTAC, its file system usage is dependent on
the specifics of the application. If the file system is used for more than just the
TrendRecorder library (such as for file storage, FTP operations, or file retrieval),
it is possible that not enough file space will be available to store TrendRecorder
data. If this occurs, recorders will not be able to record new data. Use the
following equation to calculate the required file space:

Programming Reference Date Code 20241023


TrendRecorder 1197
Recorder Operation

where:

➤ 86400 = Number of seconds in a day


➤ 73 = Size of one record
➤ 30 = Max number of days of recording (same as number of days)

Trend Recorder Data Files


Each recorder saves data to the RTAC hard drive in a binary file. A new file is
created at the top of each day, for as many as 30 days of record data. These files
are viewable from the RTAC web interface but are saved in a binary format and
are not human-readable. Do not delete these files—doing so will cause recorder
data loss.

The TrendRecorder library limits its file system space to 1 GB in the SEL-3505,
SEL-3505-3, SEL-2241, SEL-3530, and SEL-3530-4 and 6 GB of space for
all other RTAC platforms. Each recorder is given an equal share of that space
and will use as much of that space as is required based on its recording interval
setting or record trigger frequency. For the platforms using 1 GB of file system
space, once a recorder has reached its allotted share of storage space, it will
delete the oldest file until its consumed storage space is within the prescribed
limit.

The following equation can be used to calculate the number of days for which
data will be retained before the oldest files are deleted. This equation only
applies to the SEL-3505, SEL-3505-3, SEL-2241, SEL-3530, and SEL-3530-4.
All other RTAC platforms are allocated enough space to contain the maximum
number of recorders at the highest frequency.

where:

➤ 1073741824 = 1 GB in bytes
➤ 86400 = Number of seconds in a day
➤ 73 = Size of one record

The platforms using 6 GB of file system space are able to handle the maximum
number of recorders at the highest recording frequency with a retention of
the maximum 30 days and will not delete any files (given the system has the
required 6 GB free in the file system).

SOE Logging
Trend Recorder logs settings errors and storage space errors to the RTAC SOE
log.

Date Code 20241023 Programming Reference


1198 TrendRecorder
Benchmarks

Benchmarks
Benchmark Platforms
The benchmarking tests recorded for this library are performed on the following
platforms.

➤ SEL-3505
➢ R136-V0
➤ SEL-3530
➢ R136-V0
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R136-V0

Benchmark Test Descriptions


All tests were run on a 100-millisecond task cycle time with ProfileRecorders
running at the default interval of 60 seconds.

The posted times include the minimum, mean, maximum, and standard deviation
of execution time in microseconds over 5000 samples.

Benchmark Results
NOTE
The benchmarks were not found to be different in any statistically significant
way from those for the previous release, so the numbers have not been
updated.

Platform (time in µs)


Operation Tested Metric
SEL-3505 SEL-3530 SEL-3555

ProfileManager Min 23 18 1

Mean 571 233 27

Max 154315 1546 627

σ 2875 152 34

1 ProfileIntervalRecorder Min 26 19 1

Mean 978 556 26

Max 2572 1120 80

σ 285 176 8

ProfileManager Min 25 18 1

Mean 854 311 37

Max 186153 1567 568

σ 5422 214 42

Programming Reference Date Code 20241023


TrendRecorder 1199
Benchmarks

Platform (time in µs)


Operation Tested Metric
SEL-3505 SEL-3530 SEL-3555

4 ProfileIntervalRecorders Min 84 60 1

Mean 3633 2103 63

Max 5462 3263 129

σ 834 641 14

ProfileManager Min 27 18 1

Mean 359 316 38

Max 312459 2318 578

σ 4416 274 42

12 ProfileIntervalRecorders Min 252 164 4

Mean 10320 5642 179

Max 16134 7944 328

σ 3972 1668 51

ProfileManager Min 24 19 1

Mean 233 278 34

Max 88357 9557 717

σ 1259 259 43

1 ProfileTriggerRecorder Min 25 19 1

Mean 1026 565 23

Max 2779 1100 60

σ 263 131 6

ProfileManager Min 25 19 1

Mean 778 191 43

Max 142039 13522 780

σ 3505 259 46

4 ProfileTriggerRecorders Min 87 60 2

Mean 3979 2182 66

Max 5852 3450 151

σ 876 473 13

ProfileManager Min 27 18 1

Mean 216 265 11

Max 90038 14945 92

σ 1284 310 5

12 ProfileTriggerRecorders Min 236 236 4

Mean 11434 6230 190

Max 14799 8152 330

σ 2496 1201 37

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 4 1

Web_Client_SL
Introduction
The Web_Client_SL library provides mechanisms to act as an HTTP client and
make appropriate requests.

Implementation Note
This library is provided as a member of the CODESYS® IIoT package as a
special offering available in the SEL RTAC. The functionality provided by this
resource is generally intended to operate in generic CODESYS® environments.
As such, some limitations may be encountered when implementing these
resources in the SEL RTAC. Any POUs or POU inputs that may be subject to
these limitations are marked accordingly in this document.

Special Considerations
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R151 or later.

Global Constants
This section lists the global constants provided for interacting with the web
client.

Name Data Type Value and Description

gc_wsLF WSTRING(2) "$R$N"

gc_sLF STRING(2) '$R$N'

gc_wsDoubleLF WSTRING(4) "$R$N$R$N"

gc_sDoubleLF STRING(4) '$R$N$R$N'

gc_wsContentLength WSTRING(15) "Content-Length:"

gc_sContentLength STRING(15) 'Content-Length:'

gc_sContentLengthLower STRING(15) 'content-length:'

gc_wsChunked WSTRING(26) "Transfer-Encoding: chunked"

gc_sChunked STRING(26) 'Transfer-Encoding: chunked'

Date Code 20241023 Programming Reference


1202 Web_Client_SL
Global Constants

Name Data Type Value and Description

gc_wsHex WSTRING(3) "16#"

gc_sHex STRING(3) '16#'

gc_sChunkEnd STRING(5) '0$R$N$R$N'

gc_wsClosed WSTRING(18) "Connection: close"

gc_sAuthorization STRING(20) 'Authorization:'

gc_sOAuth STRING(20) 'OAuth '

gc_sOauth_consumer_key STRING(20) 'oauth_consumer_key'

gc_sOauth_nonce STRING(20) 'oauth_nonce'

gc_sOauth_signature STRING(25) 'oauth_signature'

gc_sOauth_signature_method STRING(25) 'oauth_signature_method'

gc_sOauth_timestamp STRING(20) 'oauth_timestamp'

gc_sOauth_token STRING(20) 'oauth_token'

gc_sOauth_version STRING(20) 'oauth_version'

gc_sEquals STRING(1) '='

gc_sApos STRING(1) '"'

gc_sAnd STRING(1) '&'

gc_sQM STRING(1) '?'

gc_sBlank STRING(1) ''

gc_sComma STRING(1) ','

gc_wsBlank WSTRING(1) ""

gc_wsEquals WSTRING(1) "="

gc_wsApos WSTRING(1) "$"

gc_wsQM WSTRING(1) "?"

gc_wsComma WSTRING(1) ","

gc_wsColon WSTRING(1) ":"

gc_wsSquareClosedBracket WSTRING(1) "]"

gc_wsCurvedClosedBracket WSTRING(1) "}"

gc_awsURLEncodingStrings ARRAY [0..255] OF WSTRING(3) ["%00", "%01", .. "%FE", "%FF"]

gc_asURLEncodingStrings ARRAY [0..255] OF STRING(3) ['%00', '%01', .. '%FE', '%FF']

gc_wsAuthHeader WSTRING(21) "Authorization: Basic"

gc_wsDP WSTRING(1) ":"

gc_wsGrantTypeClient WSTRING(30) "grant_type=client_credentials"

gc_wsGrantTypePassword WSTRING(30) "grant_type=password"

gc_wsGrantTypeRefreshToken WSTRING(30) "grant_type=refresh_token"

gc_wsClientId WSTRING(20) "client_id="

gc_wsClientSecret WSTRING(20) "client_secret="

Programming Reference Date Code 20241023


Web_Client_SL 1203
Global Parameters

Name Data Type Value and Description

gc_wsScope WSTRING(20) "scope="

gc_wsRedirectURI WSTRING(20) "redirect_uri="

gc_wsAnd WSTRING(1) "&"

gc_wsResponseTypeCode WSTRING(20) "response_type=code"

gc_wsResponseTypeToken WSTRING(20) "response_type=token"

gc_wsUsername WSTRING(10) "username="

gc_wsPassword WSTRING(10) "password="

gc_wsRefreshToken WSTRING(20) "refresh_token="

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

g_udiMaxRequestSize UDINT 16000 Maximum size of the HTTP request in bytes.

g_udiMaxResponseSize UDINT 16000 Maximum size of the HTTP response in bytes.

g_udiMaxHeaderSize UDINT 4000 Maximum size of the HTTP header in bytes.

g_udiMaxOAuth2TokenSize UDINT 2048 Maximum size of the OAuth2 access and refresh token.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
Enumerations defined in this, the Web Client SL library, provide control of the
various HTTP request mechanisms.

CONTENT_TYPE
Enumeration Description

APPLICATION_FORM HTML-Form

APPLICATION_JSON JSON data

NONE Do not set the "content type" in the HTTP header.

REQUEST_TYPE
Enumeration Description

GET Use HTTP "GET" verb.

POST Use HTTP "POST" verb (needs input pwsPostValue).

Date Code 20241023 Programming Reference


1204 Web_Client_SL
Structures

Enumeration Description

DELETE Use HTTP "DELETE" verb.

PUT Use HTTP "PUT" verb (needs input pwsPostValue).

HEAD Use HTTP "HEAD" verb.

PATCH Use HTTP "PATCH" verb.

ERROR
Enumeration Description

NO_ERROR No error.

TIME_OUT Time out.

UNEXPECTED_ERROR Unexpected error.

TCP_INIT_ERROR Unable to initialize the TCP socket.

TCP_READ_ERROR Error while reading response.

TCP_WRITE_ERROR Error while sending the request.

MISSING_POST_VALUE Current request type needs a post value.

RESULT_PARSE_ERROR Error while parsing the response.

MAXIMUM_SIZE_EXCEEDED Maximum size of buffer exceeded.

CONVERT_ERROR Converting error (UTF-8 to UTF-16 or UTF-16 to UTF-8).

POST_VALUE_IS_NULL Post value is null.

UNSUPPORTED_OAUTH2_CREDENTIAL_INTERFACE Supported interfaces: IOAuth2ClientCredentials and


IOAuth2ResourceOwnerCredentials.

OAUTH2_AUTHENTICATION_SERVER_ERROR Error while sending request to authentication server.

OAUTH2_REQUEST_ERROR Error while sending request to resource server.

OAUTH2_REFRESH_ACCESS_TOKEN_ERROR Error while refreshing access token.

INVALID_LICENSE RTAC firmware does not adequately provide IIoT information.

RESOLVE_HOSTNAME_FAILED The hostname cannot be resolved.

NOT_FOUND Value or key not found.

MAXIMUM_TOKEN_SIZE_EXCEEDED Maximum size of access token or refresh token exceeded.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Structures defined in this, the Web Client SL library, are positioned to be


provide functional access for the various web requests being made.

Programming Reference Date Code 20241023


Web_Client_SL 1205
Functions

KeyValue
Name IEC 61131 Type Description

sKey STRING(255) Key of key-value pair.

sValue STRING(255) Value of key-value pair.

HttpResult
Name IEC 61131 Type Description

iStatus INT HTTP status

wsHeader WSTRING(g_udiMaxHeaderSize) HTTP header as WSTRING

wsContent WSTRING(g_udiMaxResponseSize) result of the request as WSTRING

sHeader STRING(g_udiMaxHeaderSize) HTTP header as STRING

sContent STRING(g_udiMaxResponseSize) result of the request as STRING

diContentLength DINT length of wsContent

NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.

URL
Name IEC 61131 Type Description

sProtocol STRING(5) Protocol (e.g., HTTP). Note: only HTTP is supported.

sDomain STRING(255) The domain (e.g., "selinc.com").

uiPort UINT Port of the server.

sPath STRING(1024) The path (e.g., "/1.1/statuses/update.json").

Functions
This library provides functions to perform various operations in relation to URL
encoding/decoding and byte-encoding conversions.

ConvertUTF16toUTF8 (Function)
This function converts a WSTRING (UTF16) to a STRING (UTF8).

Inputs
Name IEC 61131 Type Description

sourceStart POINTER TO Pointer to WSTRING.


WORD

targetStart POINTER TO BYTE Pointer to STRING.

Date Code 20241023 Programming Reference


1206 Web_Client_SL
Functions

Name IEC 61131 Type Description

dwTargetBufferSize DWORD Size of STRING.

bStrictConversion BOOL Require strict conversion technique.

Return Value
IEC 61131 Type Description

UDINT Number of WORD characters converted.

ConvertUTF8toUTF16 (Function)
This function converts a STRING (UTF8) to a WSTRING (UTF16).

Inputs
Name IEC 61131 Type Description

sourceStart POINTER TO BYTE Pointer to STRING.

targetStart POINTER TO Pointer to WSTRING.


WORD

dwTargetBufferSize DWORD Size of WSTRING.

bStrictConversion BOOL Require strict conversion technique.

Return Value
IEC 61131 Type Description

UDINT Number of BYTE characters converted.

BASE64_DECODE (Function)
This function decodes a Base-64 string.

Inputs
Name IEC 61131 Type Description

diSizeIn DINT Size of "in".

in POINTER TO BYTE Input: Pointer to the source STRING.

out POINTER TO BYTE Output: Pointer to destination STRING.

Outputs
Name IEC 61131 Type Description

diSizeOut DINT Number of BYTE characters decoded.

Programming Reference Date Code 20241023


Web_Client_SL 1207
Functions

BASE64_ENCODE (Function)
This function encodes a Base-64 string.

Inputs
Name IEC 61131 Type Description

diSizeIn DINT Size of "in".

in POINTER TO BYTE Input: Pointer to the source STRING.

out POINTER TO BYTE Output: Pointer to destination STRING.

Outputs
Name IEC 61131 Type Description

diSizeOut DINT Number of BYTE characters encoded.

FindJSONValue (Function)
Finds the corresponding value of a key in a JSON WSTRING. Objects and
arrays are NOT supported.

Inputs
Name IEC 61131 Type Description

pwsIn POINTER TO Pointer to the source JSON WSTRING.


WORD

udiSizeIn DINT Size of "pwsIn".

pwsKey POINTER TO Pointer to key WSTRING.


WORD

diSearchStartPos DINT Start position of the search.

Inputs/Outputs
Name IEC 61131 Type Description

wsValue WSTRING(255) Identified value corresponding to key.

Return Value
IEC 61131 Type Description

DINT Index of the value in the JSON STRING.

FindJSONValue2 (Function)
Finds the corresponding value of a key in a JSON WSTRING. Objects and
arrays are NOT supported.

Date Code 20241023 Programming Reference


1208 Web_Client_SL
Functions

Inputs
Name IEC 61131 Type Description

pwsIn POINTER TO Pointer to the source JSON WSTRING.


WORD

udiSizeIn UDINT Size of "pwsIn".

pwsKey POINTER TO Pointer to key WSTRING.


WORD

diSearchStartPos DINT Start position of the search.

pwsValue POINTER TO Pointer to the result value.


WSTRING

udiValueSize UDINT Size of "pwsValue".

Outputs
Name IEC 61131 Type Description

eError ERROR Error generated during search.

Return Value
IEC 61131 Type Description

DINT Index of the value in the JSON STRING.

URL_ENCODE_STRING (Function)
Encodes a STRING into a format appropriate for URLs.

Inputs
Name IEC 61131 Type Description

pbIn POINTER TO BYTE Pointer to the source STRING.

Return Value
IEC 61131 Type Description

STRING(Param.g_udiMaxRequestSize) Index of the value in the JSON STRING.

URL_ENCODE_STRING2 (Function)
Encodes a STRING into a format appropriate for URLs.

Programming Reference Date Code 20241023


Web_Client_SL 1209
Interfaces

Inputs
Name IEC 61131 Type Description

pbIn POINTER TO BYTE Pointer to the source STRING.

pbOut POINTER TO BYTE Pointer to the destination URL-encoded


STRING.

udiSizeOut UDINT Maximum size of the destination buffer.

URL_ENCODE_WSTRING (Function)
Encodes a WSTRING into a format appropriate for URLs.

Inputs
Name IEC 61131 Type Description

pbIn POINTER TO BYTE Pointer to the source WSTRING.

Return Value
IEC 61131 Type Description

WSTRING(Param.g_udiMaxRequestSize) Index of the value in the JSON WSTRING.

URL_ENCODE_WSTRING2 (Function)
Encodes a WSTRING into a format appropriate for URLs.

Inputs
Name IEC 61131 Type Description

pbIn POINTER TO BYTE Pointer to the source WSTRING.

pbOut POINTER TO BYTE Pointer to the destination URL-encoded


WSTRING.

udiSizeOut UDINT Maximum size of the destination buffer.

Interfaces
This library provides the following interfaces.

Date Code 20241023 Programming Reference


1210 Web_Client_SL
Function Blocks

IOAuth2Credentials
Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

ClientId WSTRING(255) R/W Client ID as a WSTRING.

ClientSecret WSTRING(255) R/W Client secret as a WSTRING.

Scope WSTRING(255) R/W Client scope as a WSTRING.

IOAuth2ClientCredentials
This interface extends IOAuth2Credentials.

IOAuth2ClientCredentials
This interface extends IOAuth2Credentials and provisions additional interface
properties.

Properties
Properties are internal values made visible through Get and Set accessors.
Access is defined as R (read), W (write), or R/W (read/write).

Name IEC 61131 Type Access Description

Password WSTRING(255) R/W Resource owner password.

Username WSTRING(255) R/W Username of the resource owner.

Function Blocks
The Web Client SL library provides various function blocks to interact with the
respective web client functionalities.

OAuth2ClientCredentials (Function Block)


Function block for the OAuth2 request type (flow): client_credentials.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
OAuth2ClientCredentials.

Programming Reference Date Code 20241023


Web_Client_SL 1211
Function Blocks

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ IOAuth2ClientCredentials

Inputs

Name IEC 61131 Type Description

wsClientId WSTRING(255) Client ID as a WSTRING.

wsClientSecret WSTRING(255) Client secret as a WSTRING.

wsScope WSTRING(255) Client scope as a WSTRING.

OAuth2ResourceOwnerCredentials (Function Block)


Function block for the OAuth2 request type (flow): password.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
OAuth2ResourceOwnerCredentials.

Implemented Interfaces
An interface defines a required set of functionality as methods and properties.
As an implementer of any interface all methods and properties declared in that
interface must exist as members of this class. This allows multiple generally
unrelated classes to be used interchangeably for a specific feature set.

➤ IOAuth2ResourceOwnerCredentials

Inputs

Name IEC 61131 Type Description

wsClientId WSTRING(255) Client ID. Leave blank if not used.

wsClientSecret WSTRING(255) Client Secret. Leave blank if not used.

wsPassword WSTRING(255) Resource owner password.

wsUsername WSTRING(255) Username of the resource owner.

wsScope WSTRING(255) Scope. Leave blank if not used.

WebClient (Function Block)


Function block to establish a simple web client over HTTP.

Date Code 20241023 Programming Reference


1212 Web_Client_SL
Function Blocks

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with WebClient.

NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.

Inputs

Name IEC 61131 Type Description

xExecute BOOL Rising edge: Send request.

udiTimeOut UDINT Timeout in microseconds.

sURL STRING(1024) URL of the web server (resource server).

eRequestType REQUEST_TYPE Type of the request: POST or GET.

eContentType CONTENT_TYPE HTTP Content-Type of the request.

pwsAdditionalHeader POINTER TO WSTRING Additional HTTP header.

pwsPostValue POINTER TO WSTRING Post parameter.

xCloseConnection BOOL Close the connection after each request.

hCert RTS_IEC_HANDLE Handle to a certificate (optional).

itfTLSContext NBS.ITLSContext Encapsulates all the data necessary to handle encrypted TCP
connections.

itfAsyncProperty NBS.IAsyncProperty Runs the connect process in its own background task; for usage, see
library Net Base Services.

Outputs

Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

HTTPResult HttpResult The result of the request.

BasicAuthWebClient (Function Block)


Function block to establish a simple web client over HTTP using BasicAuth.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
BasicAuthWebClient.

Programming Reference Date Code 20241023


Web_Client_SL 1213
Function Blocks

NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.

Inputs

Name IEC 61131 Type Description

wsLogin WSTRING(255) Login username.

wsPassword WSTRING(255) Login password.

xExecute BOOL Rising edge: Send request.

udiTimeOut UDINT Timeout in microseconds.

sURL STRING(1024) URL of the web server (resource server).

eRequestType REQUEST_TYPE Type of the request: POST or GET.

eContentType CONTENT_TYPE HTTP Content-Type of the request.

pwsAdditionalHeader POINTER TO WSTRING Additional HTTP header.

pwsPostValue POINTER TO WSTRING Post parameter.

xCloseConnection BOOL Close the connection after each request.

hCert RTS_IEC_HANDLE Handle to a certificate (optional).

itfTLSContext NBS.ITLSContext Encapsulates all the data necessary to handle encrypted TCP
connections.

itfAsyncProperty NBS.IAsyncProperty Runs the connect process in its own background task; for usage, see
library Net Base Services.

Outputs

Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

HTTPResult HttpResult The result of the request.

OAuth1WebClient (Function Block)


Function block to a send an OAuth1 authenticated request.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
OAuth1WebClient.

Date Code 20241023 Programming Reference


1214 Web_Client_SL
Classes

NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Sends request.

udiTimeOut UDINT Timeout in microseconds.

sURL STRING(1024) URL of the web server (resource server).

eRequestType REQUEST_TYPE Type of the request: POST or GET.

eContentType CONTENT_TYPE HTTP Content-Type of the request.

pwsAdditionalHeader POINTER TO WSTRING Additional HTTP header.

pwsPostValue POINTER TO WSTRING Post parameter.

xCloseConnection BOOL Close the connection after each request.

sOAuthConsumerKey STRING(255) OAuth1: Consumer key.

sOAuthToken STRING(255) OAuth1: Token.

sConsumerSecret STRING(255) OAuth1: Consumer secret.

sOAuthTokenSecret STRING(255) OAuth1: Token secret.

itfTLSContext NBS.ITLSContext Encapsulates all the data necessary to handle encrypted TCP
connections.

itfAsyncProperty NBS.IAsyncProperty Runs the connect process its own background task; for usage, see
library Net Base Services.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

HTTPResult HttpResult The result of the request.

Classes
The Web Client SL library provides the following classes in order to facilitate
OAuth2 connections.

OAuth2WebClient (Class)
Function block to send a request via two-legged OAuth2 authentication.
Supported request types (flows): client_credentials and password.

Programming Reference Date Code 20241023


Web_Client_SL 1215
Classes

NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.

Class Inputs and Outputs


The following tables describe the inputs and outputs associated with
OAuth2WebClient.

Inputs

Name IEC 61131 Type Description

xExecute BOOL Rising edge: Sends request.

udiTimeOut UDINT Timeout in microseconds.

sURL STRING(1024) URL of the web server (resource server).

eRequestType REQUEST_TYPE Type of the request: POST or GET.

eContentType CONTENT_TYPE HTTP Content-Type of the request.

pwsAdditionalHeader POINTER TO WSTRING Additional HTTP header.

pwsPostValue POINTER TO WSTRING Post parameter.

sAuthorizationServerURL STRING(1024) URL of authorization server.

pwsAdditionalAuthenticationHeader POINTER TO WSTRING Additional Auth HTTP header.

xCloseConnection BOOL Close the connection after each request.

itfTLSContext NBS.ITLSContext Encapsulates all the data necessary to handle


encrypted TCP connections.

itfAsyncProperty NBS.IAsyncProperty Runs the connect process in its own background


task; for usage, see library Net Base Services.

Outputs

Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

HTTPResult HttpResult The result of the request.

ResetToken (Method)
Resets the access and refresh token. This method does not require any inputs and
provides no return type. ResetToken should be called when the token should be
refreshed.

Date Code 20241023 Programming Reference


1216 Web_Client_SL
Examples

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Make a GET Request (ST)


The goal of this example is to make a GET request to a specific server using
HTTP. The test should access a simple httpbin.org service to echo requests to
verify their behavior. For the purposes of testing, this service may be accessed
over a WAN-connected network, or it may be hosted locally, preventing the need
to address firewall considerations.

Assumptions
The following assumptions are made:

1. The RTAC is configured to use DNS, either by static configuration or by


use of DNS configuration over DHCP.
2. An httpbin service is accessible by the URL http://httpbin.org.

Solution
Code Snippet 41.1 prg_MakeAGETRequest
PROGRAM prg_MakeAGETRequest
VAR CONSTANT
c_HostURL : STRING := 'http://httpbin.org';
END_VAR
VAR
// Function block to perform HTTP requests.
client : WEB_CLIENT.WebClient;

// Explicitly defined content/request types


requestType : WEB_CLIENT.REQUEST_TYPE := WEB_CLIENT.REQUEST_TYPE.GET;
contentType : WEB_CLIENT.CONTENT_TYPE := WEB_CLIENT.CONTENT_TYPE.NONE;

// Placeholder variable for the resultant data


result : WEB_CLIENT.HttpResult;

runNow : BOOL; // force this variable to watch program run!


END_VAR

// Run the web client


client(
xExecute := runNow,
sURL := c_HostURL,
eRequestType := requestType,
eContentType := contentType,
httpResult => result
);

Programming Reference Date Code 20241023


Web_Client_SL 1217
Examples

Examine HTTP Status Code (ST)


The goal of this example is to make a GET request to a specific server using
HTTP and verify the HTTP status code provided in response. The test should
access a simple httpbin.org service to echo requests to verify their behavior. For
the purposes of testing, this service may be accessed over a WAN-connected
network, or it may be hosted locally, preventing the need to address firewall
considerations.

Assumptions
The following assumptions are made:
1. The RTAC is configured to use DNS, either by static configuration or by
use of DNS configuration over DHCP.
2. An httpbin service is accessible by the URL http://httpbin.org.
3. The httpbin service will respond with a status code equivalent to that
requested with the endpoint /status/{code}; e.g., a request to http://
httpbin.org/status/200 will provide a status code of 200.

Solution
Code Snippet 41.2 prg_ExamineHttpStatusCode
PROGRAM prg_ExamineHttpStatusCode
VAR CONSTANT
c_HostURL : STRING := 'http://httpbin.org';
c_StatusEndpoint : STRING := '/status/';
END_VAR
VAR
// Function block to perform HTTP requests.
client : WEB_CLIENT.WebClient;

// Explicitly defined content/request types


requestType : WEB_CLIENT.REQUEST_TYPE := WEB_CLIENT.REQUEST_TYPE.GET;
contentType : WEB_CLIENT.CONTENT_TYPE := WEB_CLIENT.CONTENT_TYPE.NONE;

fullyQualifiedURL : STRING(255);

// Placeholder variable for the resultant data


result : WEB_CLIENT.HttpResult;

// The specific status code that should be provided.


status : INT := 200; // 200 (the default) is "Success"

runNow : BOOL; // force this variable to watch program run!


END_VAR

// Construct the fully qualified URL from:


// - the hostname
// - the endpoint
// - the desired status response code
fullyQualifiedURL := CONCAT(
c_HostURL,
CONCAT(
c_StatusEndpoint,
TO_STRING(status)
)
);
// fullyQualifiedURL := http://httpbin.org/status/200

// Run the web client


client(

Date Code 20241023 Programming Reference


1218 Web_Client_SL
Examples

xExecute := runNow,
sURL := fullyQualifiedURL,
eRequestType := requestType,
eContentType := contentType,
httpResult => result
);

Echo Data From POST (ST)


The goal of this example is to make a POST request to a specific server using
HTTP and verify the HTTP response echoes the same POST data.

Assumptions
The following assumptions are made:

1. The RTAC is configured to use DNS, either by static configuration or by


use of DNS configuration over DHCP.
2. An httpbin service is accessible by the URL http://httpbin.org.
3. The httpbin service will respond with echoed data POSTed to the
endpoint /anything.

Solution
Code Snippet 41.3 prg_EchoDataFromPOST
PROGRAM prg_EchoDataFromPOST
VAR CONSTANT
c_HostURL : STRING := 'http://httpbin.org';
c_EchoEndpoint : STRING := '/anything';
END_VAR
VAR
// Function block to perform HTTP requests.
client : WEB_CLIENT.WebClient;

// Explicitly defined content/request types


requestType : WEB_CLIENT.REQUEST_TYPE := WEB_CLIENT.REQUEST_TYPE.POST;
contentType : WEB_CLIENT.CONTENT_TYPE := WEB_CLIENT.CONTENT_TYPE.APPLICATION_JSON;

fullyQualifiedURL : STRING(255);

// Placeholder variable for the resultant data


result : WEB_CLIENT.HttpResult;

// String of JSON data.


postData : WSTRING(255) := "{
$"integer$" : 123,
$"boolean$" : FALSE,
$"string$" : $"Hello, World!$"
}";

runNow : BOOL; // force this variable to watch program run!


END_VAR

// Construct the fully qualified URL from:


// - the hostname
// - the endpoint
fullyQualifiedURL := CONCAT(c_HostURL, c_StatusEndpoint);

// fullyQualifiedURL := http://httpbin.org/anything

// Run the web client

Programming Reference Date Code 20241023


Web_Client_SL 1219
Examples

client(
xExecute := runNow,
sURL := fullyQualifiedURL,
eRequestType := requestType,
eContentType := contentType,
pwsPostValue := ADR(postData),
httpResult => result
);

Make an Encrypted Request over HTTPS (ST)


The goal of this example is to make a GET request to a specific server using
HTTPS by using TLS to encrypt the connection per best practices for modern
web interactions. The test should access a simple httpbin.org service to echo
requests to verify their behavior. For the purposes of testing, this service may
be accessed over a WAN-connected network, or it may be hosted locally,
preventing the need to address firewall considerations.

Assumptions
This example assumes the following:

1. The RTAC is configured to use DNS, either by static configuration or by


use of DNS configuration over DHCP.
2. An httpbin service is accessible via the URL https://httpbin.org.
3. The public key for the certificate authority responsible for signing the
httpbin application's certificate is loaded in the RTAC's certificate store.

Solution
Code Snippet 41.4 prg_MakeEncryptedGETRequest
PROGRAM prg_MakeEncryptedGETRequest
VAR CONSTANT
c_HostURL : STRING := 'https://httpbin.org';
END_VAR
VAR
// Function block to perform HTTP requests.
client : WEB_CLIENT.WebClient;

// Explicitly defined content/request types


requestType : WEB_CLIENT.REQUEST_TYPE := WEB_CLIENT.REQUEST_TYPE.GET;
contentType : WEB_CLIENT.CONTENT_TYPE := WEB_CLIENT.CONTENT_TYPE.NONE;

// Placeholder variable for the resultant data


result : WEB_CLIENT.HttpResult;

// TLS Configuration for the HTTP Client


tlsContext : NBS.TLSContext := (
ePurpose := NBS.PURPOSE.CLIENT_SIDE,
udiVerificationMode := 1
);

runNow : BOOL; // force this variable to watch program run!


END_VAR

// Run the web client


client(
xExecute := runNow,
sURL := c_HostURL,
eRequestType := requestType,

Date Code 20241023 Programming Reference


1220 Web_Client_SL
Examples

eContentType := contentType,
xUseTLS := TRUE,
itfTLSContext := tlsContext,
httpResult => result
);

Programming Reference Date Code 20241023


S E C T I O N 4 2

Web_Socket_Client_SL
Introduction
The Web_Socket_Client_SL library provides mechanisms to act as an HTTP
client and make appropriate requests.

Implementation Note
This library is provided as a member of the CODESYS® IIoT package as a
special offering available in the SEL RTAC. The functionality provided by this
resource is generally intended to operate in generic CODESYS® environments.
As such, some limitations may be encountered when implementing these
resources in the SEL RTAC. Any POUs or POU inputs that may be subject to
these limitations are marked accordingly in this document.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R151 or later.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
Enumerations defined in this, the Web Socket Client SL library, provide control
of the various HTTP request mechanisms.

ERROR
Enumeration Description

NO_ERROR No error.

TIME_OUT Time out.

INVALID_LICENSE RTAC firmware does not adequately provide IIoT information.

URI_PARSE_ERROR Error while parsing the URI.

RESOLVE_HOSTNAME_FAILED Cannot resolve hostname.

CONNECTION_REFUSED Connection refused by server.

TLS_CONTEXT_ERROR Error while creating the TLS context.

TCP_INIT_ERROR Error TCP Init error.

SEND_OPENING_HANDSHAKE_ERROR Error while sending handshake.

Date Code 20241023 Programming Reference


1222 Web_Socket_Client_SL
Structures

Enumeration Description

RECEIVE_OPENING_HANDSHAKE_ERROR Error while receiving handshake.

TCP_ERROR TCP error while client is connected to server.

FRAME_PARSE_ERROR Error while parsing the frame.

PONG_ERROR Error while sending the pong request.

PING_ERROR Error while sending the ping request.

PING_TIMEOUT Ping timeout, no pong request from server received.

PAYLOAD_POINTER_IS_NULL The payload pointer is null, although the payload size is greater than 0.

CAN_NOT_ALLOCATE_BUFFERS Error while allocating buffers.

CONNECTION_CLOSED_BY_SERVER The connection has been closed by the server.

MAX_PAYLOAD_SIZE_EXCEEDED The maximum size of the payload data was exceeded.

RECEIVED_MASKED_SERVER_FRAME Received an unexpected, masked server frame.

PROXY_CONNECTION_REFUSED Connection refused by proxy.

SEND_PROXY_CONNECT_ERROR Error while sending connection handshake to proxy.

RECEIVE_PROXY_CONNECT_ERROR Error while receiving connection handshake from proxy.

UPGRADE_CONNECTION_NOT_SUPPORTED Upgrade connection not supported.

PENDING The current action is in pending state.

FRAME_TYPE
Enumeration Description

TEXT The payload contains a text message.

BINARY The payload contains a binary message.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
Structures defined in this, the Web Socket Client SL library, are positioned to be
provide functional access for the various web requests being made.

KeyValue
Name IEC 61131 Type Description

sProxyServer STRING(255) Hostname or IP address of the proxy server. Leave


blank if no proxy server is used.

uiProxyPort UINT Port of the proxy server.

sProxyUser STRING Name of the proxy user. Leave blank if no


authentication is required.

sProxyPassword STRING Password of the proxy user.

Programming Reference Date Code 20241023


Web_Socket_Client_SL 1223
Interfaces

Interfaces
This library provides the following interface.

IWebSocketClient
Interface of the WebSocket client.

Read (Method)
Read incoming messages.

Inputs
Name IEC 61131 Type Description

pData __XWORD Pointer to the payload data.

udiSize UDINT Maximum size of the payload.

Outputs
Name IEC 61131 Type Description

udiCount UDINT Size of the received data.

xReceived BOOL TRUE if data received.

eFrameType FRAME_TYPE Type of the payload.

xIsFinalFragment BOOL FALSE if the payload is incomplete and is sent via


multiple packets.

TRUE if the payload is complete or if the payload


was incomplete and this packet is the last packet of
a message.

Return Value
IEC 61131 Type Description

NBS.ERROR Generated error.

Write (Method)
Send messages to a WebSocket server.

Inputs
Name IEC 61131 Type Description

pData __XWORD Pointer to the payload data.

udiSize UDINT Maximum size of the payload.

eFrameType FRAME_TYPE Type of the payload data.

Date Code 20241023 Programming Reference


1224 Web_Socket_Client_SL
Function Blocks

NOTE
It can take more than one cycle to send a message if the payload is greater
than the maximum buffer size.

Outputs

Name IEC 61131 Type Description

udiCount UDINT Number of sent bytes.

Return Value

IEC 61131 Type Description

NBS.ERROR Generated error.

Function Blocks
The Web Socket Client SL library provides various function block to interact
with the respective web client functionalities.

WebSocketRead (Function Block)


Function block to read incoming messages using the Common Behavior Model
(e.g., for CFC applications).

NOTE
This function block OR the Write method of the WebSocketClient MUST
be called in each cycle because the method also handles other requests
in background (ping, pong, etc.). Set xEnable to TRUE if xActive of the
WebSocketClient is TRUE.

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
WebSocketRead.

Inputs

Name IEC 61131 Type Description

xEnable BOOL TRUE: Activates the defined operation.

FALSE: Aborts/resets the defined operation.

itfWebSocketClient IWebSocketclient Reference to the WebSocketClient.

pData __XWORD Pointer to the payload data.

udiSize UDINT Maximum size of the payload.

Programming Reference Date Code 20241023


Web_Socket_Client_SL 1225
Function Blocks

Outputs
Name IEC 61131 Type Description

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

xReady BOOL TRUE: TRUE if data received.

udiCount UDINT Size of the received data.

eFrameType FRAME_TYPE Type of the payload.

xIsFinalFragment BOOL FALSE if the payload is incomplete and is


sent via multiple packets.

TRUE if the payload is complete or if the


payload was incomplete and this packet is the
last packet of a message.

WebSocketWrite (Function Block)


Function block to send messages to WebSocket server using the Common
Behavior Model (e.g., for CFC applications).

Function Block Inputs and Outputs


The following tables describe the inputs and outputs associated with
WebSocketWrite.

Inputs
Name IEC 61131 Type Description

xEnable BOOL TRUE: Activates the defined operation.

FALSE: Aborts/resets the defined operation.

udiTimeOut UDINT Max. operating time for executing [µs], 0: No


operating time limit.

itfWebSocketClient IWebSocketclient Reference to the WebSocketClient.

pData __XWORD Pointer to the payload data.

udiSize UDINT Size of the payload.

eFrameType FRAME_TYPE Type of the payload data.

NOTE
It can take more than one cycle to send a message if the payload is greater
than the maximum buffer size.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

Date Code 20241023 Programming Reference


1226 Web_Socket_Client_SL
Classes

Name IEC 61131 Type Description

xError BOOL TRUE: Error condition reached.

udiCount UDINT Size of the received data.

Classes
The Web Socket Client SL library provides the following class in order to
facilitate web socket connections.

WebSocketClient (Class)
Function block to establish a connection to a WebSocket server.

Class Inputs and Outputs


The following tables describe the inputs and outputs associated with
WebSocketClient.

Inputs

Name IEC 61131 Type Description

xEnable BOOL TRUE: Activates the defined operation.


FALSE: Aborts/resets the defined operation.

itfTLSContext NBS.ITLSContext User-defined TLS context for encrypted TCP connections (only for wss-URIs). If the
TLS context is 0 then a default TLS context will be created for wss-URIs.

itfAsyncProperty NBS.IAsyncProperty Runs the connect process in a background task. Use this property if the connection setup
takes longer than one task cycle (e.g., TLS connections).

udiTimeOut UDINT Defines the time (µs) after which the connection setup aborts with xError.

sProtocol STRING Sec-WebSocket-Protocol. The underlaying subprotocols like "mqtt". Default: "chat".

sExtensions STRING Sec-WebSocket-Extensions. Note: The extension data must be added manually to the
payload data. Default: "", no extension.

tPingInterval TIME Ping interval, T#0s: no ping.

httpProxySettings HttpProxySettings Optional HTTP proxy settings.

udiBufferSize UDINT The maximum size of the send and receive buffer. Changes during an online change have
no effect on the buffer size.

Inputs/Outputs

Name IEC 61131 Type Description

sUri STRING(1024) The URI of the server, e.g., "ws://localhost:8080" ws-URI =


"ws:" "//" host [ ":" port ] path [ "?" query ] wss-URI = "wss:"
"//" host [ ":" port ] path [ "?" query ].

Programming Reference Date Code 20241023


Web_Socket_Client_SL 1227
Classes

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

udiCount UDINT Size of the received data.

xActive BOOL TRUE if a connection is established.

eError ERROR Output error.

sSupportedProtocols STRING Supported protocols (server side).

sSupportedExtensions STRING Supported extensions (server side).

Read (Method)
Read incoming messages. If a message was received, then the message is copied
to pData and xReceived is set to TRUE. udiCount corresponds to the size of the
received data.

NOTE
This method MUST be called in each cycle because the method also handles
other requests in background (ping, pong, etc.). The method can be called
directly OR via the function block WebSocketRead.

Inputs
Name IEC 61131 Type Description

pData __XWORD Pointer to the payload data.

udiSize UDINT Maximum size of the payload.

Outputs
Name IEC 61131 Type Description

udiCount UDINT Size of the received data.

xReceived BOOL TRUE if data received.

eFrameType FRAME_TYPE Type of the payload.

xIsFinalFragment BOOL FALSE if the payload is incomplete and is sent via


multiple packets.

TRUE if the payload is complete or if the payload


was incomplete and this packet is the last packet of
a message.

Return Value
IEC 61131 Type Description

NBS.ERROR Resultant status.

Date Code 20241023 Programming Reference


1228 Web_Socket_Client_SL
Examples

Write (Method)
Sends messages to a WebSocket server. This method sends the payload pData
with the size udiSize to the server.

Inputs

Name IEC 61131 Type Description

pData __XWORD Pointer to the payload data.

udiSize UDINT Size of the payload.

eFrameType FRAME_TYPE Type of the payload data.

NOTE
It can take more than one cycle to send a message if the payload is greater
than the maximum buffer size.

Outputs

Name IEC 61131 Type Description

udiCount UDINT Number of sent bytes.

Return Value

IEC 61131 Type Description

NBS.ERROR Resultant status.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Establish a Web Socket Connection (ST)


The goal of this example is to connect to a Web Socket server. The test should
access a simple echo-server service to echo web-socket messages to verify the
behavior. For the purposes of testing, this service may be accessed over a WAN-
connected network, or it may be hosted locally, preventing the need to address
firewall considerations.

Programming Reference Date Code 20241023


Web_Socket_Client_SL 1229
Examples

Assumptions
The following assumptions are made:

1. The RTAC is configured to use DNS, either by static configuration or by


use of DNS configuration over DHCP.
2. An echo-server service is accessible by the URL http://
echo.websocket.events/.

Solution
Code Snippet 42.1 prg_MakeAWebSocketEcho
PROGRAM prg_MakeAWebSocketEcho
VAR CONSTANT
hostURL : STRING := 'http://echo.websocket.events/';
END_VAR
VAR
// Function block to establish WS connection.
client : WEB_SOCKET.WebSocketClient;
// Results
result_write, result_read : WEB_SOCKET.NBS.ERROR;

// WS Interval
sendInterval : SELUtils.TI := (PT:=T#2S);

// Payload data
payload : STRING(1024);
response : STRING(1024);
END_VAR

// Run the web socket client


client(
xEnable := TRUE,
sURI := hostURL,
tPingInterval := T#1S
);

sendInterval();

IF sendInterval .Q THEN
// Write to the websocket
result_write := client.Write (
pData := ADR ( payload ),
udiSize := TO_UDINT (LEN( payload ))
);
END_IF

// Receive data from websocket


result_read := client.Read(
pData := ADR ( response ),
udiSize := SIZEOF ( response )
);

Date Code 20241023 Programming Reference


This page intentionally left blank
S E C T I O N 4 3

XML_Utility_SL
Introduction
The XML_Utility_SL library provides mechanisms to generate and parse
XML (Extensible Markup Language) data structures from any structure whose
characters are accessible by byte-wise operations (example structures include
Dynamic Vectors, STRINGs, and arrays of BYTEs). The library can read and
write UTF-8 and UTF-16 coded well-formed XML files.

Supported XML elements are as follows:

1. Standard element <xxx>aaa</xxx> and <xxx />


2. Attributes yyy="zzz"
3. Comments <!– Comment –>
4. CDATA elements

Each element of the file is stored in a structure of the type XMLElement. A


complete XML file or parts of it will be stored in an array of structures.

Parameters
Reading data is buffered. The size of the buffer must greater than the size of
the largest XML element. The size of the buffer and the maximum WSTRING
size of the structure XMLElement can be changed in the parameter list (param)
of the library manager. The size of the data array can be declared individually
outside the function blocks.

Implementation Note
This library is provided as a member of the CODESYS® IIoT package as a
special offering available in the SEL RTAC. The functionality provided by this
resource is generally intended to operate in generic CODESYS® environments.
As such, some limitations may be encountered when implementing these
resources in the SEL RTAC. Any POUs or POU inputs that may be subject to
these limitations are marked accordingly in this document.

Supported Firmware Versions


You can use this library on any device configured using ACSELERATOR RTAC®
SEL-5033 Software with firmware version R151 or later.

Date Code 20241023 Programming Reference


1232 XML_Utility_SL
Global Parameters

Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.

Name IEC 61131 Type Value Description

gc_udiBufferSize UDINT 4096 Buffer size: Maximum size of a single XML element inclusive attributes
and value.

gc_udiMaxValueSize UDINT 255 Maximum size of names, values, attributes, and attribute names.

gc_MaxStructureDepth UINT 100 Maximum structure depth of the XML file.

Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.

Enumerations defined in this, the XML Utility SL library, provide control of the
various JSON parser/serializer mechanisms.

ERROR
Enumeration Description

NO_ERROR No error.

TIME_OUT Time out.

FILE_OPEN_ERROR Could not open file.

INVALID_HANDLE Open file returned invalid handle.

READ_ERROR Could not read file.

WRITE_ERROR Could not write file.

SET_POS_FAILED Invalid file position.

NOT_FOUND Element not found.

START_TAG_NOT_FOUND Start tag of the element not found.

NEXT_START_TAG_NOT_FOUND Next start element not found.

ELEMENT_EXCEEDS_BUFFERSIZE Element size exceeds buffer size. Increment


the value of gc_udiBufferSize.

COMMENT_EXCEEDS_BUFFERSIZE Comment size exceeds buffer size. Increment


the value of gc_udiBufferSize.

BLANK_NOT_FOUND Missing blank between attributes.

MAX_ELEMENT_SIZE_EXCEEDED Maximum array size of XMLElements


exceeded.

DATA_ARRAY_POINTER_IS_NULL Data pointer is null.

EMPTY_DATASET Empty dataset.

Programming Reference Date Code 20241023


XML_Utility_SL 1233
Structures

Enumeration Description

MAX_VALUE_SIZE_EXCEEDED Maximum value size exceeded. Increment the


value of gc_udiMaxValueSize.

INVALID_LICENSE RTAC firmware does not adequately provide


IIoT information.

Encoding
Enumeration Description

UTF8 UTF-8 encoding.

UTF16 UTF-16 encoding.

ElementType
Enumeration Description

Element Marks an element.

CDATAElement Marks an element with CDATA.

Attribute Marks an attribute of an element.

Comment Marks a comment.

NotSet Marks an empty element.

READ_MODE
Enumeration Description

ONE_ELEMENT Reads only the specified element.

CHILDREN_ONLY Reads all child elements of the specified element.

RECURSIVE Reads all underlying elements of the specified element.

Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.

Structures defined in this, the XML Utility SL library, are positioned to be


provide functional access to JSON data.

XMLElement
Name IEC 61131 Type Description

diParentIndex DINT The index of the parent XMLElement.

wsName WSTRING(gc_udiMaxValueSize) The name of the XML element.

Date Code 20241023 Programming Reference


1234 XML_Utility_SL
Function Blocks

Name IEC 61131 Type Description

wsValue WSTRING(gc_udiMaxValueSize) The value of the XML element.

udiPosition UDINT Position of the start tag in XML file.

elementType ElementType Type of the element (Element, Attribute, Comment, etc.).

Function Blocks
The XML Utility SL library provides various function blocks to construct and
parse data into respective structures.

XMLFindElement (Function Block)


Finds an XML element by name and attribute. To read from data array set
sFileName = "" and paDataArray to data pointer.

Inputs
Name IEC 61131 Type Description

sFileName STRING(255) Path to an XML file. This functionality is not presently supported on the
RTAC.

wsElement WSTRING(gc_udiMaxValueSize) The element to find. If blank, the root element will be returned.

attribute XMLElement Attributes of the XML element to find.

readMode READ_MODE Read mode.

paElements POINTER TO XMLElement Pointer to the result set.

udiMaxElements UDINT Maximum size of paElements.

udiStartPosition UDINT Start position in bytes.

xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.

paDataArray POINTER TO BYTE Pointer to XML data array.

udiDataArraySize UDINT Size of paDataArray.

Outputs
Name IEC 61131 Type Description

eError ERROR Output error.

udiCountElements UDINT Number of elements in paElements.

udiNextReadPos UDINT Position in file (in bytes) of the next XML


element, 0 if last element.

eEncoding Encoding Encoding of the XML file.

Programming Reference Date Code 20241023


XML_Utility_SL 1235
Function Blocks

XMLFindElementAsync (Function Block)


Finds an XML element by name and attribute asynchronously, i.e., distributed
on several cycles. This function block should be used to find elements in large
XML files. To read from data array set sFileName = "" and paDataArray to data
pointer.

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Action starts.

Falling edge: Resets outputs.

If a falling edge occurs before the function block has completed its action.
The outputs operate in the usual manner and are only reset if either the action
is completed or in the event of an error. In this case, the corresponding output
values (xDone, xError) are present at the outputs for exactly one cycle.

sFileName STRING(255) Path to an XML file. This functionality is not presently supported on the
RTAC.

wsElement WSTRING(gc_udiMaxValueSize) The element to find. If blank, the root element will be returned.

attribute XMLElement Attributes of the XML element to find.

readMode READ_MODE Read mode.

paElements POINTER TO XMLElement Pointer to the result set.

udiMaxElements UDINT Maximum size of paElements.

udiStartPosition UDINT Start position in bytes.

xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.

paDataArray POINTER TO BYTE Pointer to XML data array.

udiDataArraySize UDINT Size of paDataArray.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

eLastError ERROR The last error.

udiCountElements UDINT Number of elements in paElements.

udiNextReadPos UDINT Position in file (in bytes) of the next XML element;
0 if last element.

eEncoding Encoding Encoding of the XML file.

Date Code 20241023 Programming Reference


1236 XML_Utility_SL
Function Blocks

XMLFindElementByStringAsync (Function Block)


Finds an XML element by name and attribute asynchronously, i.e., distributed
on several cycles. This function block should be used to find elements in large
XML files. To read from data array set sFileName = "" and paDataArray to data
pointer.

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Action starts.

Falling edge: Resets outputs.

If a falling edge occurs before the function block has completed its action.
The outputs operate in the usual manner and are only reset if either the action
is completed or in the event of an error. In this case, the corresponding output
values (xDone, xError) are present at the outputs for exactly one cycle.

sFileName STRING(255) Path to an XML file. This functionality is not presently supported on the
RTAC.

wsElement WSTRING(gc_udiMaxValueSize) The element to find. If blank, the root element will be returned.

attributeName WSTRING(gc_udiMaxValueSize) Name of the attribute, BLANK if not required.

attributeValue WSTRING(gc_udiMaxValueSize) Value of the attribute.

readMode READ_MODE Read mode.

paElements POINTER TO XMLElement Pointer to the result set.

udiMaxElements UDINT Maximum size of paElements.

udiStartPosition UDINT Start position in bytes.

xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.

paDataArray POINTER TO BYTE Pointer to XML data array.

udiDataArraySize UDINT Size of paDataArray.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

eLastError ERROR The last error.

udiCountElements UDINT Number of elements in paElements.

udiNextReadPos UDINT Position in file (in bytes) of the next XML element,
0 if last element.

eEncoding Encoding Encoding of the XML file.

Programming Reference Date Code 20241023


XML_Utility_SL 1237
Function Blocks

XMLGetElement (Function Block)


Reads an XML element from file. Use the function block
XMLGetElementAsync for large XML files to get the values asynchronously. To
read from data array set sFileName = "" and paDataArray to data pointer.

Inputs
Name IEC 61131 Type Description

sFileName STRING(255) Path to an XML file. This functionality is


not presently supported on the RTAC.

udiStartPosition UDINT Start position in bytes. Use


XMLElement.udiPosition.

readMode READ_MODE Read mode.

paElements POINTER TO Pointer to the result set.


XMLElement

udiMaxElements UDINT Maximum size of paElements.

xTruncateValues BOOL TRUE: All values that exceed the maximum


value size will be truncated.

paDataArray POINTER TO BYTE Pointer to XML data array.

udiDataArraySize UDINT Size of paDataArray.

Outputs
Name IEC 61131 Type Description

eError ERROR Output error.

udiCountElements UDINT Number of elements in paElements.

udiNextReadPos UDINT Position in file (in bytes) of the next XML element,
0 if last element.

eEncoding Encoding Encoding of the XML file.

XMLGetElementAsync (Function Block)


Reads an XML element from file asynchronously, i.e., distributed on several
cycles. This function block should be used to get elements of large XML files.
To read from data array set sFileName = "" and paDataArray to data pointer.

Date Code 20241023 Programming Reference


1238 XML_Utility_SL
Function Blocks

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Action starts.

Falling edge: Resets outputs.

If a falling edge occurs before the function block has completed its action.
The outputs operate in the usual manner and are only reset if either the action
is completed or in the event of an error. In this case, the corresponding output
values (xDone, xError) are present at the outputs for exactly one cycle.

sFileName STRING(255) Path to an XML file. This functionality is not presently supported on the
RTAC.

udiStartPosition UDINT Start position in bytes. Use XMLElement.udiPosition.

readMode READ_MODE Read mode.

paElements POINTER TO XMLElement Pointer to the result set.

udiMaxElements UDINT Maximum size of paElements.

xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.

paDataArray POINTER TO BYTE Pointer to XML data array.

udiDataArraySize UDINT Size of paDataArray.

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

eLastError ERROR The last error.

udiCountElements UDINT Number of elements in paElements.

udiNextReadPos UDINT Position in file (in bytes) of the next XML element,
0 if last element.

eEncoding Encoding Encoding of the XML file.

XMLWrite (Function Block)


Writes XML data to a buffer. Use the function block XMLWriteAsync for
large XML files to write the values asynchronously. To write to data array set
sFileName = "" and paDataArray to data pointer.

Programming Reference Date Code 20241023


XML_Utility_SL 1239
Function Blocks

Inputs
Name IEC 61131 Type Description

sFileName STRING(255) Path to an XML file. This functionality is


not presently supported on the RTAC.

paElements POINTER TO Pointer to the result set.


XMLElement

udiCountElements UDINT Number elements in paElements.

eEncoding Encoding Encoding of the XML data.

paDataArray POINTER TO BYTE Pointer to XML data array.

udiDataArraySize UDINT Size of paDataArray.

xAddDeclaration BOOL Adds XML declaration with encoding info


like "<?XML version=1.0 encoding=..",
default: TRUE.

Outputs
Name IEC 61131 Type Description

eError ERROR Output error.

XMLWriteAsync (Function Block)


Writes an XML file asynchronously, i.e., distributed on several cycles. This
function block should be used to write large XML files. To write to data array
set sFileName = "" and paDataArray to data pointer.

Inputs
Name IEC 61131 Type Description

xExecute BOOL Rising edge: Action starts.

Falling edge: Resets outputs.

If a falling edge occurs before the function block has completed its action.
The outputs operate in the usual manner and are only reset if either the action
is completed or in the event of an error. In this case, the corresponding output
values (xDone, xError) are present at the outputs for exactly one cycle.

sFileName STRING(255) Path to an XML file. This functionality is not presently supported on the
RTAC.

paElements POINTER TO XMLElement Pointer to the result set.

udiCountElements UDINT Number elements in paElements.

eEncoding Encoding Encoding of the XML data.

paDataArray POINTER TO BYTE Pointer to XML data array.

udiDataArraySize UDINT Size of paDataArray.

xAddDeclaration BOOL Adds XML declaration with encoding info like "<?XML version=1.0
encoding=..", default: TRUE.

Date Code 20241023 Programming Reference


1240 XML_Utility_SL
Examples

Outputs
Name IEC 61131 Type Description

xDone BOOL TRUE: Ready condition reached.

xBusy BOOL TRUE: Operation is running.

xError BOOL TRUE: Error condition reached.

eError ERROR Output error.

eLastError ERROR The last error.

Examples
These examples demonstrate the capabilities of this library. Do not mistake them
as suggestions or recommendations from SEL.

Implement the best practices of your organization when using these libraries. As
the user of this library, you are responsible for ensuring correct implementation
and verifying that the project using these libraries performs as expected.

Parse XML Into Array of XMLElements (ST)


Objective
You want to parse an XML structure from a string into an array of respective
XML elements.

Assumptions
This example assumes that an XML data structure defined globally as a variable
by the user is to be parsed. The data is to be defined as follows, and its length (in
number of characters) is also defined as a global variable.

<?xml version="1.0" encoding="utf-8"?>


<Elements>
<!-- This is a simple xml example -->
<Element attribute1="1">
This is the value of Element 1
</Element>
<Element attribute1="2">
This is the value of Element 2
</Element>
<Element attribute1="3" attribute2="33789" attribute3="99.98">
This is the value of Element 2
</Element>
<Element attribute1="4">
<Subelement id="1">
Value of Subelement 1
</Subelement>
<Subelement id="2">
Value of Subelement 2
</Subelement>
<Subelement id="3">
Value of Subelement 3
<!--3. level -->
<Child attribute1="1">
Element4/Subelement3/Child1

Programming Reference Date Code 20241023


XML_Utility_SL 1241
Examples

</Child>
<Child attribute1="2">
Element4/Subelement3/Child2
</Child>
<Child attribute1="3">
Element4/Subelement3/Child3
</Child>
</Subelement>
</Element>
<!--CDATA and escaping -->
<Text id="1">
<![CDATA[This is a CDATA section.]]>
</Text>
<Text id="2">
Lesser than: &lt; Greater than: &gt; And: &amp; Apostroph: &apos; Quote: &quot;
</Text>
</Elements>

Solution
Code Snippet 43.1 prg_ParseArrayintoElements
PROGRAM prg_ParseArrayintoElements
VAR
// Parser object which will interpret serialized XML
parser : XML.XMLFindElement;
// Storage object which will manage all XML elements
elements : ARRAY[1..100] OF XML.XMLElement;

runOnce : BOOL := TRUE;


END_VAR

// Run the parser


IF runOnce THEN
parser(
paElements := ADR(elements[1]),
udiMaxElements := 100,
// the string is a global variable
paDataArray := ADR(g_DataByteString),
// the length of the string is defined globally
udiDataArraySize := g_DataByteStringLength
);

runOnce := FALSE;
END_IF

Date Code 20241023 Programming Reference


This page intentionally left blank
A P P E N D I X A

Release Notes
The following tables list the versions, revision descriptions, and corresponding
Programming Reference Manual date codes for ACSELERATOR RTAC
Extensions, and IEC 61131-3 Libraries.

Libraries
IEC 61131 libraries are pre-packed logic that are authored by SEL for IEC
61131 applications like data recording, email, and generation control. Below are
release notes for the various different library solutions which are available for
selection in ACSELERATOR RTAC.

Starting with revisions published after March 1, 2022, changes that address
security vulnerabilities are marked with "[Cybersecurity]". Other improvements
to cybersecurity functionality that should be evaluated for potential
cybersecurity importance are marked with "[Cybersecurity Enhancement]".

AnalogConditioning
Version Summary of Revisions Date Code

3.5.2.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC type "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.1.1 ➤ Added class_ArmaFilter_LREAL. 20150722

3.5.1.0 ➤ Changed I_LimitedSplpf to inherit from I_Filter. 20141107


➤ Modified class_LimitedSplpfStepToDefault to implement updated I_LimitedSplpf.
➤ Modified class_LimitedSplpfRampToDefault to implement updated I_LimitedSplpf.
➤ Added advanced ARMA filter.
➤ Added dummy class_PassThroughFilter.

3.5.0.1 ➤ Initial release. 20140701

ChannelMonitoring
Version Summary of Revisions Date Code

3.5.3.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.3.0 are not supported for project versions R148 and later.

3.5.2.0 ➤ Added class_TimeAlignment. 20200826

3.5.1.2 ➤ Modified behavior of fb_ChannelIntegral EN input to allow integration pausing. 20191024


➤ Made ExcursionThreshold dynamically settable for fb_ChannelAlert and
fb_MultiChannelAlert.
➤ Added LatchAlarm input to fb_ChannelAlert and fb_MultiChannelAlert.
➤ Addressed an issue that could cause an unexpected Integral result after a manual reset to
fb_ChannelIntegral while the PeriodicProcessing input is true.

Date Code 20241023 Programming Reference


1244 Release Notes
Libraries

Version Summary of Revisions Date Code

3.5.1.1 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.
➤ Added fb_ChannelDerivative.
➤ Added fb_ChannelIntegral.
➤ Added fb_IndicatorTimeDelta.

3.5.0.0 ➤ Initial release. 20151223

ConditionMonitoring
Version Summary of Revisions Date Code

3.5.3.1 ➤ Addressed an issue in class_CmReportWriter where detail file content was misaligned 20241023
relative to column labels. This occurred when multiple bootstrapped sources presented
unequal numbers of detail columns.

3.5.3.0 ➤ Added class_87LCommMonitor411L. 20240711


➤ Replaced class_CmReportWriter.SummaryTrigger with
class_CmReportWriter.pt_SummaryTrigger.

3.5.2.3 ➤ Added Boolean properties to the I_CM interface to allow for implementing classes to directly 20231114
trigger the generation of new files through class_CmReportWriter.
➤ Addressed an issue where a class_StreamingCTPTMonitor active channel alert state does not
deassert if the reference is driven below the minimum magnitude.
➤ Limited the minimum value of the MinimumMagnitude input of
class_CtPtMonitor.Initialize() to 1.
➤ Resolved an issue in a class_CmReportWriter dependency that could cause a logic engine
restart.

3.5.2.2 ➤ Addressed an issue that causes an "Invalid use of restricted SEL library" compile error on 20221216
ACSELERATOR RTAC versions 1.35.151.6000 and later.

3.5.2.1 ➤ Added AlertEdge Boolean to struct_CTPTGroupStatus. Pulses for one task cycle on the 20221104
rising edge of any monitored channel Alert.stVal.
➤ Normalized class_StreamingCTPTMonitor input/output naming convention to favor Alert
over Alarm.
➤ Replaced MonitorGroup with NodeGroup within struct_CTPTStatusOutput.
➤ Addressed an issue where struct_CTPTGroupStatus.StatusDescription does not
clear a warning message if a warning condition is cleared while in an alert state.
➤ Addressed an issue in class_StreamingCTPTMonitor where phase angle wrapping is not
accounted for when MonitorMode = DEFINED_REFERENCE.
➤ Addressed an issue in class_StreamingCTPTMonitor where a deassertion of Initialize.EN is
not logged to the SOE/Summary file.
➤ Addressed an issue in class_StreamingCTPTMonitor where the MonitorGroup column of the
SOE/Summary file can show an inaccurate list of CtPt IDs.
➤ Addressed an issue in class_StreamingCTPTMonitor where
struct_CTPTStatusOutput.ReferenceMeasurement for InputTypeIsAngle = TRUE
loses decimal resolution for angles in quadrants two and three of the unit circle.

3.5.2.0 ➤ Added support to class_StreamingCTPTMonitor for topology processing, angle monitoring, 20220909
and chatter tracking.

3.5.1.2 ➤ Addressed issue in the CtPt Monitor Extension that could prevent the project from going 20211216
online with an RTAC in certain configurations.
➤ Addressed an issue in class_IedReportConverter where calls to Bootstrap_ReportRegexRule
with ContentType of SEQUENCE and Instances of one result in a corrupt label string.
➤ Addressed an issue in class_IedReportConverter where the last line of sequence data may not
be written to the output file.
➤ Allows compatibility with project versions R150 and later.

Programming Reference Date Code 20241023


Release Notes 1245
Libraries

Version Summary of Revisions Date Code

3.5.1.1 ➤ Added additional phase options and outputs to the CtPt monitor class and extension. 20210504
➤ Removed monitored channel magnitude comparison to MinimumMagnitude from
class_StreamingCTPTMonitor as a qualification for monitor enabling.

3.5.1.0 ➤ Added CtPt Monitor Extension. 20210212

3.5.0.0 ➤ Initial release. 20200826

CrossTaskData
Version Summary of Revisions Date Code

3.5.1.2 ➤ Addressed an issue that will cause compile warnings relating to type UDINT possibly not 20231114
converting to POINTER TO BYTE.

3.5.1.1 ➤ Addressed an issue that will cause logic engine restart when using duplicate writer mutex 20220526
IDs.
➤ Must be used with R150 firmware or later.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.3 ➤ Copy operations between tasks have been optimized to be more efficient for large cross task 20160708
data sets.

3.5.0.2 ➤ Corrected catching of SysMem internal errors. 20140828

3.5.0.1 ➤ Initial release. 20140701

DescriptiveData
Version Summary of Revisions Date Code

3.5.2.2 ➤ Added SerializeRow method to class_CsvManager as well as PercentSerialized and 20220909


PercentParsed outputs.
➤ Converted the duration-vs-content size relationship for class_CsvManager CSV parse
operations from exponential to linear.
➤ Resolved an issue in class_CsvManager where parsing files larger than 10 MB asserts the
class output error.

3.5.2.1 ➤ Added AddKeyValuePairSELString and GetSELString methods to class_JsonManager to 20220331


allow SELString values to be assigned to and retrieved from values stored in key-value pairs.

3.5.2.0 ➤ Added ExtractCell and OverwriteCell methods to class_CsvManager. 20211216


➤ Resolved an issue in class_CsvManager where calling the Serialize method could cause a
logic engine restart.
➤ Resolved an issue in class_JsonManager where serializing empty key or value strings would
cause logic engine restart.
➤ Allows compatibility with project versions R150 and later.

3.5.1.0 ➤ Added class_CsvManager. 20210826


➤ Added the SerializeJson() method to class_JsonManager to allow serializing JSON structure
contents to a byte array.
➤ Added the GetNextValue() method to class_JsonManager to automate the process of
retrieving the next item in a list or map.
➤ Added the GoToIndex() method to class_JsonManager to allow navigation to a specified
JSON element.
➤ Added theAddKeyValuePair() method to class_JsonManager to allow the addition of user-
specified key-value pairs to a blank JSON structure.

3.5.0.0 ➤ Initial release. 20200826

Date Code 20241023 Programming Reference


1246 Release Notes
Libraries

Dictionaries
Version Summary of Revisions Date Code

3.5.2.0 ➤ Added functions fun_NewBinaryTreeDictionary and fun_DeleteBinaryTreeDictionary. 20231114

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.1 ➤ Initial release. 20140811

DynamicDisturbanceRecorder
Version Summary of Revisions Date Code

3.5.4.5 ➤ Increased maximum size of triggered records from 10 MB to 50 MB. 20240711

3.5.4.4 ➤ Enhanced class_SoeHarvesterCsv to create CSV files that contain locally generated RTAC 20240325
SOE records.
➤ Resolved an issue introduced in 3.5.4.0 where class_SoeHarvesterCsv causes a logic engine
restart.

3.5.4.3 ➤ Resolved an issue where generated COMTRADE files could contain invalid data when 20230310
configured for TIME_CHANGE mode with MaxFileSize set such that records are generated
frequently.
➤ Resolved an issue introduced in 3.5.4.2 where class_ComtradeFloat32 causes a logic engine
restart.
➤ Resolved an issue introduced in 3.5.3.0 where preparing zipped COMTRADE records may
exceed configured task cycle time constraints.
➤ Resolved an issue where FilePostfix was not recorded when using TRIGGER_EVENT as the
DataLogType for class_TimeAlignedCsv.

3.5.4.2 ➤ Restored COMTRADE file generation performance to pre-3.5.3.0 levels. See description of 20220909
class_ComtradeFloat32 for expected performance.
➤ Added runtime license check verification after project download.

3.5.4.1 ➤ Resolved an issue introduced in 3.5.4.0 where the DynamicDisturbanceRecorder configured 20220526
with a record type of SOE Harvester CSV eventually fails to generate CSV files and prevents
further file system writes from other libraries attempting to create files.

3.5.4.0 ➤ Resolved an issue introduced in 3.5.3.0 where class_SoeHarvesterCsv is unable to detect new 20220331
SOE records when a previously tracked record is removed from the RTAC SOE Log.
➤ Modified class_SoeHarvesterCsv to remove the fixed internal 10-second SOE query interval
and added the QueryRecords input to allow external triggering.
➤ Allows compatibility with project versions R150 and later.

3.5.3.1 ➤ Resolved an issue introduced in 3.5.3.0 where generation of COMTRADE files is 20210826
significantly slower than previous versions.

3.5.3.0 ➤ Added SOE Harvesting functionality via class_SoeHarvesterCsv. 20210504


➤ Resolved an issue where COMTRADE .dat files could contain out of order samples.
➤ Must be used with R148 firmware or later.

3.5.2.3 ➤ Resolved an issue where no data is recorded when only data types without associated time 20210212
stamps are configured.
➤ Resolved an issue where CMV magnitude and angle channel names, as written in the
COMTRADE .cfg file, were out of compliance with IEEE-C37.111-2013.
➤ Resolved an issue where digital channels in the COMTRADE .cfg file were not assigned an
IEEE-C37.111-2013 compliant normal state indicator.
➤ Increased phase description string length to a maximum of two characters for COMTRADE
recordings and provided selectable phase presets as per IEEE C37.111-2013.

3.5.2.2 ➤ Resolved an issue where COMTRADE files could be deleted prematurely. 20191122

Programming Reference Date Code 20241023


Release Notes 1247
Libraries

Version Summary of Revisions Date Code

3.5.2.1 ➤ Resolved an issue where Boolean data types could not be recorded in a COMTRADE file. 20190726
➤ Optimized the COMTRADE class so that files greater than 10 MB can be created.
➤ Must be used with R144 firmware or later.

3.5.2.0 ➤ Adds support for simple data types. 20190218


➤ Increases maximum triggered COMTRADE file size from 1 MB to 10 MB.
➤ Extends COMTRADE pre- and post-trigger sample counts to 18,000.
➤ Updates class_ComtradeFloat32 and class_TimeAlignedCsv to allow the LoggingInterval
setting to change during runtime.
➤ COMTRADE files are now compressed to reduce file size.
➤ Must be used with R144 firmware or later.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.0 ➤ Initial release of class_ComtradeFloat32. 20170601


➤ Initial release of class_SoeClass.
➤ Initial release of class_TimeAlignedCsv.

DynamicVectors
Version Summary of Revisions Date Code

3.5.3.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.3.0 are not supported for project versions R148 and later.

3.5.2.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.1.0 ➤ Added typed vectors for REAL, LREAL, LWORD, and POINTER. 20150511

3.5.0.2 ➤ Initial release. 20140811

Email
Version Summary of Revisions Date Code

3.5.2.0 ➤ Allows compatibility with project versions R150 and later. 20220331

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.6 ➤ Full SMTP client/server handshaking implemented. 20150722


➤ Added fb_SimpleEmailClient2 and class_EmailClient2. These items extend the basic objects,
providing destination and source port initialization parameters.
➤ Attachment functionality added for multiple files and raw data.
➤ Very large emails, over 10 KB in size, send correctly.

3.5.0.3 ➤ Added correct HELO syntax when using local ip "0.0.0.0". 20141212
➤ Allow up to 10 seconds to connect with a mail server instead of a single scan.

3.5.0.2 ➤ Improved sending of long emails. 20141110

3.5.0.1 ➤ Initial release. 20141010

Date Code 20241023 Programming Reference


1248 Release Notes
Libraries

EmailPlus
Version Summary of Revisions Date Code

3.5.3.1 ➤ Resolved an issue where the use of extended ASCII characters in the email body would 20240325
prevent successful transmission of the email.
➤ Resolved an issue where Monitored Events mode generates emails with the Event Timestamp
in UTC rather than the original local time offset.

3.5.3.0 ➤ Added Monitored Events functionality to class_EmailClient. 20231114


➤ Expanded the list of available special characters in the file name of email attachments.
➤ Increased the maximum configurable Startup Delay to 30 minutes.
➤ Resolved an issue where the AppendToBodyFrom... method calls would produce emails
where only the body contents specified on the first call was part of the email body and the
contents on subsequent calls were added as attachments.
➤ Improved email address input validation.
➤ Requires project versions of R151 and later.

3.5.2.0 ➤ Added Monitored Alarms functionality to class_EmailClient. Previous functionality is now 20220909
referred to as Triggered Report configuration.
➤ Added MaintenanceMode input.

3.5.1.0 ➤ Allows compatibility with project versions R150 and later. 20220331

3.5.0.2 ➤ Updated extension for compatibility with ACSELERATOR RTAC versions newer than 20200826
1.30.146.3437.

3.5.0.1 ➤ Initial release. 20200220

FTPSync
Version Summary of Revisions Date Code

3.5.2.3 ➤ Added "." (dot), "-" (dash), and "@" (at) as supported characters for the FTP username. 20241023
➤ Addressed an issue where COMTRADE events were not synchronized in RTAC firmware
versions R152-V1 and later if the RTAC system time was not synchronized with the device
originating the event.

3.5.2.2 ➤ Extension-only change. 20231114

3.5.2.1 ➤ Documentation-only change. 20220909

3.5.2.0 ➤ Allows compatibility with project versions R150 and later. 20220331
➤ Added visibility of licensing error to RuntimeErrors.

3.5.1.4 ➤ Added a setting for defining the file transfer timeout period. 20210826
➤ Added the ability to disable periodic synchronization.

3.5.1.3 ➤ Added public key authentication example (documentation-only change). 20200826

3.5.1.2 ➤ Added the ability to specify the TCP port used during connection to the FTP or SFTP server. 20200403
➤ Added the ability to sync Recording Group events and any other events in the file system not
previously accessible by the library.
➤ Must be used with R146-V0 firmware or later.

3.5.0.1 ➤ Resolved an issue that may cause a logic engine restart. 20200214

3.5.0.0 ➤ Initial release. 20190830

Programming Reference Date Code 20241023


Release Notes 1249
Libraries

FallingConductorProtection
Version Summary of Revisions Date Code

3.5.0.5 ➤ Resolved issue where a falling conductor trip could be erroneously issued if a faulty sensor 20240325
condition was present and the IEEE C37.118 data stream of the associated switch was
interrupted.
➤ Modified faulty sensor conditions to no longer latch in until receipt of a target reset.
➤ Modified faulty sensor switch comparison qualification (e.g., identical 52A status tags) to
require all criteria to match between a pair of switches before evaluating for faulty sensor
detection.
➤ Enhanced faulty sensor detection to support a configurable dropout period, defined by a new
advanced setting FaultySensorDropoutTime.
➤ Enhanced breaker status transit detection to support a configurable period where this
detection is inhibited following a transition of the breaker status indication to bad quality.
This time period is defined by a new advanced setting BreakerStatusBadQualityBlockTime.

3.5.0.4 ➤ Added new FUSE_SOURCE switch type. 20220909


➤ Enhanced dI0/dt spike alarming and blown fuse detection to use the configurable breaker
status transition time period during which detection is suppressed.
➤ Enhanced blocking fault and faulty sensor detection to evaluate switch availability before
performing logic checks for these conditions.
➤ Modified faulty sensor detection to only apply with switches configured as type
BREAKER_SWITCH.
➤ Modified blown fuse detection logic to only process when the associated 52A contact status
with the FUSE_TAP switch is closed. This status should be associated with the closest
upstream BREAKER_SWITCH or SUBSTATION_BREAKER 52A status.
➤ Modified blown fuse detection logic to no longer flag a parent zone as having a possible
blown fuse.

3.5.0.3 ➤ Enhanced switch availability status to support a configurable pickup and dropout time. 20220526
➤ Enhanced Faulty Sensor detection to support a configurable pickup time as well as a
configurable breaker status transition time period during which detection is suppressed.
➤ Modified per-switch RoundTripTime value calculation to handle condition where switch is no
longer communicating.
➤ Modified dI0/dt spike alarming to only apply with switches configured as type
SUBSTATION_BREAKER.
➤ Modified V0-Angle and V2-Angle method calculations to remove ABS value condition.
This was previously applied against the angle values before they were subtracted from one
another.
➤ Modified per-switch FCDetectionFlag logic to only latch in the flag if a trip is issued to the
switch that detects a falling conductor method.

3.5.0.2 ➤ Added new Substation Breaker switch type. 20220331


➤ Added tracking of the availability status of switches providing zone reference voltages. If this
switch becomes unavailable, other switches in the zone using those voltages are prevented
from executing falling conductor method detection.
➤ Added AlgorithmsEnabled status to struct_SwitchStatus structure to provide per-switch
indication of the enabled status of falling conductor method calculations.
➤ Added new blocking condition for external disturbances that are determined to be out of the
zone of protection of falling conductor protection.

3.5.0.1 ➤ Initial release. 20211216

Date Code 20241023 Programming Reference


1250 Release Notes
Libraries

FaultLocation
Version Summary of Revisions Date Code

3.5.2.0 ➤ Added optional inputs to class_SingleEndedFault and the LocateFault method to produce fault 20231114
locations based on a narrow window of the event record. These inputs decrease the time to locate
a fault when working with large event files.
➤ Added class_FaultLocationManager.
➤ Addressed an issue where class_SingleEndedFault logs internal status to the SOE as an error.
These status messages now appear only on the ErrorDescription output.
➤ Added optional inputs to the LocateFault and RequestSingleEndedFaultLocation methods to
allow processing fault locations on COMTRADE records whose channels use primary scaling.

3.5.1.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.1.0 are not supported for project versions R148 and later.

3.5.0.1 ➤ Removed licensing requirement. 20200826

3.5.0.0 ➤ Initial release. 20200702

FileIO
Version Summary of Revisions Date Code

3.5.7.5 ➤ Added NewestFileTime output to class_DirectoryListing GetList method. 20241023

3.5.7.4 ➤ Added new input to class_FileWriter that allows for overriding the maximum buffer size 20240711
imposed by param_FileIo.g_p_FileIo_MaxBufferSize for file writes.
➤ Added new input to class_DirectoryManager that allows for overriding the maximum buffer
size imposed by param_FileIo.g_p_FileIo_MaxBufferSize for file writes.

3.5.7.3 ➤ Added new inputs to class_ComtradeParser and class_FileReader2 that allow for configuring 20231114
the number of bytes to read per RTAC task cycle.
➤ Added new inputs to class_ComtradeParser and class_FileReader2 that allow for overriding
the maximum file size limit imposed by param_FileIo.g_p_FileIo_MaxBufferSize for file
read operations.
➤ Added class_EventListing2 and struct_EventDetails2 that facilitate the same functionality
as class_EventListing with the added element of the file name and path exposed in
struct_EventDetails2.
➤ Resolved an issue in class_PersistentData that could cause a logic engine restart.
➤ Must be used with project versions R151 and later.

3.5.7.2 ➤ Added runtime license check verification after project download. 20220909
➤ Added inputs to class_ComtradeParser and class_FileReader2 ReadEventFromDB methods
to allow for reading a window of data from the database (.dat) files.

3.5.7.1 ➤ Added new class_PersistentData to store logic engine variable values on the RTAC file 20220331
system and automatically restore them upon system restart.

3.5.7.0 ➤ Added GetAnalogChannelNumber, GetDigitalChannelNumber ConvertComtradeTStoUTC, 20211216


and GetEventFromFS methods to class_ComtradeParser.
➤ Added NumSamples element to struct_ComtradeInfo.
➤ Addressed an issue in class_ComtradeParser where data samples cannot be retrieved from
events whose .cfg file defines nrates = 0 and samp = 0.
➤ Allows compatibility with project versions R150 and later.

3.5.6.2 ➤ Addressed an issue in class_ComtradeParser where calls to GetDigitalSample() could fail for 20210826
events with more digital channels than analog channels.
➤ Addressed an issue in class_DirectoryListing where it would continuously consume memory
when used with firmware versions R144 through R147.

Programming Reference Date Code 20241023


Release Notes 1251
Libraries

Version Summary of Revisions Date Code

3.5.6.1 ➤ Added GetBoolVector method to class_ComtradeParser. 20210504


➤ Added GetEventFromDBDirect method to class_ComtradeParser.
➤ Addressed an issue in class_ComtradeParser where an event with a number of digital
channels that are equally divisible by 16 leads to invalid results returned from the various get-
vector and get-sample methods.

3.5.6.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.6.0 are not supported on project versions R148 and later.
➤ Resolved an issue where calls to fun_SoeAscending fail while the ReturnAlarmSoeOnly
input is True.

3.5.5.0 ➤ Added new class_ComtradeParser to read COMTRADE .dat and .cfg event data into the 20190401
RTAC's logic engine.

3.5.4.1 ➤ Added facility to filter a directory listing to only return files newer than or equal to the date 20190201
and time specified.
➤ Added new class_BasicDirectoryManager, which rotates the contents of a given directory
based on maximum size constraints.
➤ Must be used with R144-V1 firmware or later.

3.5.3.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.
➤ Increased default g_p_FileIo_MaxBufferSize size from 1 MB to 10 MB.

3.5.2.2 ➤ Added note recommending not using FileIO with RTAC firmware versions R136-V0 and 20161221
R136-V1.
➤ Added class_TimeBasedDirectoryManager to provide directory management capabilities for
the user to keep files for a set number of days rather than a maximum number of files.
➤ Fixed an issue in class_DirectoryManger and class_LogDirectoryManager in which a system
performing large quantities of FileIO tasks could result in early deletion of managed files.
➤ Added class_TimeBasedDirectoryManager to provide directory management capabilities for
the user to keep files for a set number of days rather than a maximum number of files.
➤ Fixed an issue in class_DirectoryManger and class_LogDirectoryManager in which a system
performing large quantities of FileIO tasks could result in early deletion of managed files.
➤ Rebranded the FileIo library to uppercase the "o" and be: "FileIO" (literature change only, no
changes made to actual library name or namespaces).

3.5.2.0 ➤ Added class_DirectoryManager to provide directory management capabilities without the file 20160610
content helps and constraints found in class_LogDirectoryManager.
➤ Added ability to write to directory manager files from vectors, byte arrays, and SELStrings in
addition to the strings previously possible.
➤ Added functions to facilitate accessing SOEs monotonically in order of SOE creation.
➤ Added function to query for available file system free space.
➤ Modified file deletion algorithm for the directory manager classes to recover space faster in
the case that the directory size is exceeded.
➤ Modified class_LogDirectoryManager to remove metadata for deleted files from the .unsent
file both when FTP is configured and when it is not.
➤ Modified library to ensure that calling the StartNewLog() method on
class_LogDirectoryManger multiple times during startup always appends the time-stamped
file close message.
➤ Modified BytesLeft in class_FileWriter to show all pending work, where before it did not
include bytes to be written to a new file name.
➤ Modified class_LogDirectoryManager to prevent a condition where dates before the year
2000 cause constant writing and rotating of files.
➤ Modified class_Filewriter property Filename to no longer require file content before allowing
Filename to be modified again.
➤ Removed deprecated features from class_FileReader because of loss of file system support.
Use of these features now results in compilation errors.
➤ Removed deprecated class_EventReportListing because of loss of file system support. Use of
this class now results in compilation errors.

Date Code 20241023 Programming Reference


1252 Release Notes
Libraries

Version Summary of Revisions Date Code

3.5.1.0 ➤ Added class_FileReader2 that replaces deprecated dependency with new sel_file features for 20150930
accessing events.
➤ Added functions and documentation to wrapping underlying firmware API.
➤ Removed documentation of underlying firmware API.
➤ Added ability to read from the SOE database into the logic engine.

3.5.0.10 ➤ Made class_LogDirectoryManager able to delete files more quickly, facilitating a faster file 20150717
creation rate and larger number of files.
➤ Fixed issue in class_FileWriter where changing Filename in quick succession caused the
class to get stuck writing to a single file.

3.5.0.9 ➤ Fixed issue where an invalid Filename followed immediately by a valid Filename locked out 20150213
class_FileWriter.

3.5.0.7 ➤ Added the Filename property to class_FileWriter. 20141205


➤ Added a new class_LogDirectoryManager.

3.5.0.4 ➤ Internal parts of the library are now hidden. 20141008


➤ Tested with sel_file V1.0.1.0 -released with R133 firmware (see RTAC firmware release
notes for more details).

3.5.0.3 ➤ Initial release. 20140812

GridConnect
Version Summary of Revisions Date Code

3.5.7.4 ➤ Added real and reactive power clamp functionality for storage assets. 20241023
➤ Added setting EnableVarForAllGroups to fb_masterPlantController to allow for assets that
are not producing real power to participate in reactive power objectives.
➤ Modified storage assets to participate in reactive power objectives while charging.
➤ Modified storage assets to not participate in meeting PSetpoint objectives while
StorageChargeSetpoint is greater than 0 even if the storage asset has completed charging.
➤ Increased fb_masterPlantController input MaxFileSize to 10 MB. The default value is now 5
MB.
➤ Changed the default value of fb_masterPlantController input EnableDdrRecording to TRUE.
➤ Resolved an issue where an asset entering reactive power clamp could cause setpoints of non-
clamped assets to increase.
➤ Resolved an issue where changing an asset's PRating or QRating would not maintain the
previous setpoint until the next evaluation period.

3.5.7.3 ➤ Added setting FRegulationBaseSetpoint to select which frequency regulation curve (PlantP or 20240711
PSetpoint) to respond from when a frequency regulation event occurs.
➤ Modified power clamp detection to assert after the asset response has been outside of the
asset setpoint for the duration of PLimitDelay.
➤ Modified downramp discharge from BESS to stop if a setpoint change occurs during the
downramp.

3.5.7.2 ➤ Extension update only. 20240418

Programming Reference Date Code 20241023


Release Notes 1253
Libraries

Version Summary of Revisions Date Code

3.5.7.1 ➤ Added additional data columns to the DDR Recording file. 20240325
➤ Enhanced power clamp detection and closed-loop control anti-windup to account for when
assets respond to set points with more than 1 percent error.
➤ Enhanced fb_PVInverterSim to limit the reactive power output based upon irradiance
limitations.
➤ Added input settings AssetPError and AssetQError to fb_PvInverter, fb_StorageInverter, and
fb_ReciprocatingGenerator to inform assets how to set power clamp set points when assets
have an error in their response to set points.
➤ Added input setting EnforcePccPFLimitsForAllModes to fb_masterPlantController to enforce
power factor lead and lag limits in all reactive power modes.
➤ Added input setting ResetPIControllersForSetpointChanges to fb_masterPlantController to
reset the PI controller to the current plant output for real and reactive power when TRUE.
➤ Resolved an issue introduced in 3.5.7.0 where after a storage asset completed charging, the
energy allocated to charging that asset was not redistributed to other charging storage assets.

3.5.7.0 ➤ Added support to fb_PvInverter and fb_StorageInverter for groups of generation assets. 20231114
➤ Added new function blocks fb_Load and fb_ReciprocatingGenerator.
➤ Added support for islanding operation.

3.5.6.5 ➤ Resolved an issue that prevented storage assets from participating in reactive power 20241023
objectives when only storage assets were present.

3.5.6.4 ➤ Resolved an issue where set points did not update when some inverters are in power clamp 20240325
mode after the PLimitMode was changed to Simple from Advanced.
➤ Resolved an issue where set points could become zero in low irradiance conditions.
➤ Added input setting EnforcePccPFLimitsForAllModes to fb_masterPlantController to enforce
power factor lead and lag limits in all reactive power modes.
➤ Added input setting ResetPIControllersForSetpointChanges to fb_masterPlantController to
reset the PI controller to current plant output for real and reactive power when TRUE.

3.5.6.3 ➤ Resolved an issue where inverter setpoints could become negative in PCCMetering mode if 20231114
PlantP was greater than 0 when all inverter setpoints were 0.
➤ Resolved an issue where MaxPExportSetpoint was not range checked by PlantPRating.

3.5.6.2 ➤ Resolved an issue introduced in 3.5.6.1 in Advanced PLimitMode that allows PlantP to 20231114
exceed PSetpoint + PDeadband when all inverters are in power clamp mode and irradiance
increases slower than PowerClampMarginPercent between evaluation periods.

3.5.6.1 ➤ Modified Advanced PLimitMode to slowly return inverters to a proportional set point across 20221216
all inverters while staying within Pdeadband of PSetpoint after an inverter leaves power
clamp mode.

Date Code 20241023 Programming Reference


1254 Release Notes
Libraries

Version Summary of Revisions Date Code

3.5.6.0 ➤ Note: Updating to version 3.5.6.0 will require re-tuning for configurations that operate 20220909
in Advanced PLimitMode.
➤ Added function blocks fb_PCCSim, fb_PVInverterSim, fb_BESSSim, and fb_CapSim to
support simulated configurations of GridConnect systems on an RTAC.
➤ Added support to fb_masterPlantController for charging storage assets during solar
smoothing while PV increases.
➤ Added support to fb_masterPlantController for anti-windup in reactive closed-loop control
modes including Var Control, Voltage Control, and Voltage Compensation.
➤ Added input pin AutomaticChargingSource to fb_masterPlantController to select a power
source for automatic charging algorithm.
➤ Added input pin OptionalLowerVDeadband to fb_masterPlantController to allow for unique
upper and lower deadbands for voltage control.
➤ Added support for frequency regulation in PCC Metering mode.
➤ Added simulator function blocks for testing and exploration of GridConnect.
➤ Resolved an issue in fb_masterPlantController that resulted from a PSetpoint change
occurring in Advanced mode while PDeadband was larger than PLimitRampRate. The
process value was driven in the opposite direction of PSetpoint until the target ramp value
was driven outside the range of PDeadband from PlantP.
➤ Resolved an issue in fb_masterPlantController in Advanced mode where overshoot correction
was delayed.
➤ Resolved an issue in fb_masterPlantController when automatic charging was active and
transitioned to solar smoothing. After transitioning to solar smoothing, PlantP would start at a
value greater than what it was prior to the transition.

3.5.5.0 ➤ Added support for constant power mode. 20211216


➤ Added additional diagnostic POU pins to fb_masterPlantController.
➤ Modified solar smoothing to have configurable downramp rate and timing inputs.
➤ Added input pin to fb_masterPlantController to reset all PI controllers.
➤ fb_StorageInverter and fb_PvInverter immediately update PLimitSetMag and QSetMag when
PRating or QRating change.

3.5.4.3 ➤ Modified real power Advanced Mode to reset integral and match output to current PlantP 20211216
when a setpoint change occurs.
➤ Improved setpoint executions by one evaluation period.

3.5.4.1 ➤ Modified real power ramp logic to start at current power level rather than the previous set 20210504
point.
➤ Modified power clamp logic detection percentage to be configurable.
➤ Modified capacitor operation percentage to be configurable.
➤ Resolved an issue where power factor control did not stop when plant power was below
PlantLowPowerCutoff.
➤ Modified capacitor close and open times to be configurable.

3.5.4.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.4.0 are not supported for project versions R148 and later.

3.5.3.2 ➤ Resolved an issue where real power deadband was not scaled correctly in PCC Metering 20210212
Mode.

3.5.3.1 ➤ Resolved an issue where a Ramp Rate of 0 did not work in PCC Metering Mode. 20201029
➤ Resolved an issue where Ramp Rate may not reflect the configured value in Simple Mode.
➤ Improved PI response in Advanced Mode.

3.5.3.0 ➤ Added support for 5MW License. 20200826


➤ Added support for PCC Metering Mode.
➤ Added support for automatic charging logic for storage inverters.

3.5.2.8 ➤ Added support for Real Power Control Modes for storage-only systems. 20200626
➤ Added support for charging logic for storage inverters.
➤ Enhanced QuickStop to zero set point outputs regardless of operation mode.
➤ Resolved an issue introduced in 3.5.1.2 where GridConnect could not be disabled.

3.5.1.2 ➤ Updated internal licensing check. 20200214


➤ Must be used with R144 firmware or later.

Programming Reference Date Code 20241023


Release Notes 1255
Libraries

Version Summary of Revisions Date Code

3.5.1.1 ➤ Enhanced set point outputs, making them smoother after QuickStop is released. 20191122

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Updated internal calculations to better handle cases where inverter ratings are inadvertently
set to zero.
➤ Must be used with R143 firmware or later.

3.5.0.2 ➤ Renamed library components to conform to library extensions naming conventions. 20180427
➤ Add quick stop feature.
➤ Add control mode: VAR control.
➤ Add control mode: PF Compensation.
➤ Add control mode: Voltage Compensation.
➤ Updated control mode: Voltage control now employs direct VAR control of the inverters.
➤ Add frequency regulation for plant response.
➤ Add frequency regulation for storage system response.
➤ Add support for energy storage system.
➤ Add downramp control (real power support for storage systems).

0.1.5.2 ➤ Fixed VAR Control mode. 20150708


➤ Added an additional deadband detection exclusively for VAR mode, because inverter control
is only enabled if an out-of-deadband is signaled.
➤ Corrected the initialized values in the instruction manual.
➤ Added separate tuning parameters for VAR control mode.

0.1.5.1 ➤ Added ability to control multiple capacitors. 20150605


➤ Added VAR control mode to types of POI control.

1.4.3 ➤ Added SEL-3555 and SEL-3532 to the MOT Checker. 20141231

1.4.2 ➤ Changed library dependencies to use the newest version always. 20140812

1.4.1 ➤ Added PL_MODE to GC_MSPC for user selection of one of three power limit modes. 20140122
➢ "NoLimit" means all power limit outputs are set to 100%.
➢ "Simple" means the power Limit set point is converted to a percentage of the P ratings
of the available inverters. The same percent output limit is sent to each inverter. This
simplification does not address any non-uniform cloud cover issues.
➢ "Advanced" means use the PI controller based limiter (requires inverter data updates <5
seconds).

1.3.1 ➤ Added INV_PL_DELAY input pin to GC_MSPC. 20131104


➤ Delay time between inverter not responding to power set point and application of the adaptive
power limit.

1.2.2 ➤ Changed MSPC.V input default value to 1.0. 20130919


➤ Changed MSPC.V_SP input default value to 1.0.
➤ Changed MSPC.V_DB input default value to 0.02.

1.2.1 ➤ Add POI QUALITY and ENABLE pins. 20130722


➤ Added ENABLED output pin to GC_MSPC.

1.1.8 ➤ Enhanced power limit control. Added per inverter power limit antiwindup logic. 20130529

1.1.7 ➤ Modified set point bias logic during voltage or powerfactor excursions beyond critical limits. 20130506
➤ Decoupled PF control deadband and lag/lead alarm generation from voltage limits.

1.1.6 ➤ Decrease power limit ramp rate output deadband to 0.01%/Sec. 20130412
➤ Corrected predictive aggregate inverter response logic.
➤ Limit power limit control output between 0 and 100% in open loop and closed loop mode.

1.1.5 ➤ GC_INV–Corrected trigger logic to allow PF_TRIG output to reset between control intervals. 20130206

1.1.4 ➤ GC_MSPC–Corrected closed loop cycle time pulse generation. 20130206

Date Code 20241023 Programming Reference


1256 Release Notes
Libraries

Version Summary of Revisions Date Code

1.1.3 ➤ GC_MSPC Function Block Bug Fixes: 20130201


➢ Corrected Retry pulse generation.
➢ Corrected Closed loop cycle time pulse generation.
➢ Corrected Version output pin.

1.1.2 ➤ Added RTAC MOT support. 20121126

1.1.1 ➤ Initial release. 20120906

IPAliasRedundancy
Version Summary of Revisions Date Code

3.5.3.3 ➤ Addressed an issue where a gratuitous ARP was not being transmitted when the IP alias was 20241023
activated.

3.5.3.2 ➤ Added support to re-add the IP Alias to the configured interface if the interface is added or 20240711
removed from a bonded, bridged, or PTP configuration.

3.5.3.1 ➤ Resolved an issue where CIDR notation was allowed on the RemoteRtacPort input 20231114
pin, preventing RTAC-to-RTAC communication from occurring on Ethernet or serial
communication channels.

3.5.3.0 ➤ Allows compatibility with project versions R150 and later. 20220331

3.5.2.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.2.0 are not supported for project versions R148 and later.

3.5.1.1 ➤ Resolved an issue that could cause a logic engine restart if communications were not 20200626
processed for five seconds or more.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.3 ➤ Initial release. 20180427

JSON_Utilities_SL
Version Summary of Revisions Date Code

1.0.4.0 ➤ Initial release. 20221104

MQTT_Client_SL
Version Summary of Revisions Date Code

1.1.0.0 ➤ Initial release. 20221104

Programming Reference Date Code 20241023


Release Notes 1257
Libraries

MathComplex
Version Summary of Revisions Date Code

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.2 ➤ Corrected bug in struct_ComplexRect_TO_vector_t() that returned a value of NaN due 20150925
to rounding errors.
➤ Defined the range of the angle returned by struct_ComplexRect_TO_vector_t() to be [–
180, 180] degrees. Previous to this release, this was undefined but returning [0, 360].

3.5.0.1 ➤ Fixed negative return values in fun_ComplexAbs(). This also corrected issues in 20150722
fun_ComplexCmp() and fun_ComplexLn().

3.5.0.0 ➤ Initial release. 20150511

MathMatrix
Version Summary of Revisions Date Code

3.5.2.1 ➤ Addressed an issue that causes an 'Invalid use of restricted SEL library' compile error on 20221216
ACSELERATOR RTAC versions 1.35.151.6000 and later.

3.5.2.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.2.0 are not supported for project versions R148 and later.

3.5.1.1 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.1 ➤ Initial release. 20150722

PacketEncoding
Version Summary of Revisions Date Code

3.5.2.0 ➤ Allows compatibility with project versions R150 and later. 20220331

3.5.1.0 ➤ Allows new versions of ACSELERATOR to compile projects for previous firmware versions 20180921
without SEL IEC types "Cannot convert" messages.
➤ Replaced the deprecated "POINTER_TO_ANY" type with POINTER_TO_BYTE".
➤ Must be used with R143 firmware or later.

3.5.0.4 ➤ Added base64-MIME encoding and decoding functionality. 20150722

3.5.0.3 ➤ Initial release. 20141010

Date Code 20241023 Programming Reference


1258 Release Notes
Libraries

PowerMetering
Version Summary of Revisions Date Code

3.5.2.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.1.0 ➤ Added fb_KYZ. 20160415


➤ Added fb_KY.
➤ Resolved an issue that could cause the fb_Demand block to discard the initialValue after the
first five minutes, resulting in the Demand calculation being reset.
➤ Updated examples using retain values for clarity.

3.5.0.5 ➤ Initial release. 20140714

PowerSystemAutomation
Version Summary of Revisions Date Code

3.5.1.2 ➤ Added input pin PositiveSlipRequired to fb_SynchronismCheck, which provides an option 20240711
for negative or positive slip to be used to close in a breaker.
➤ Resolved an issue in fb_SynchronismCheck where MinimumSlipFreq did not allow an input
value of 0.

3.5.1.1 ➤ Resolved an issue where local controls are processed in fb_DisconnectSwitchControl, 20220909
fb_BreakerOpenControl, and fb_BreakerCloseControl when the LocalMode input is false.

3.5.1.0 ➤ Added function blocks for disconnect switch and circuit breaker control. 20210826

3.5.0.0 ➤ Initial release. 20201029

PowerSystemModel
Version Summary of Revisions Date Code

3.5.2.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.2.0 are not supported for project versions R148 and later.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.0 ➤ Initial release. 20150924

PowerSystemProtection
Version Summary of Revisions Date Code

3.5.2.1 ➤ Extension update only. 20240711

3.5.2.0 ➤ Added the OverFrequency function block. 20240325


➤ Added the UnderFrequency function block.
➤ Added the FrequencyElement function block.
➤ Added the AlphaVoltageSupervision function block.

3.5.1.1 ➤ Removed licensing check, making PowerSystemProtection a free-to-use library. 20191018

Programming Reference Date Code 20241023


Release Notes 1259
Libraries

Version Summary of Revisions Date Code

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180619
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.0 ➤ Initial release of time-overcurrent function block. 20170517


➤ Initial release of instantaneous-overcurrent function block.
➤ Initial release of loss-of-potential function block.
➤ Initial release of overvoltage function block.
➤ Initial release of undervoltage function block.
➤ Initial release of bus-line voltage check function block.
➤ Initial release of conductor thermal overload function block.

Queue
Version Summary of Revisions Date Code

3.5.3.1 ➤ Added the Resize2 method that is identical to Resize but additionally updates the Size 20230310
property.

3.5.3.0 ➤ Added support to dynamically generate queues at runtime. 20210504

3.5.2.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.2.0 are not supported for project versions R148 and later.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Replaced the deprecated POINTER_TO_ANY type with POINTER_TO_BYTE.
➤ Must be used with R143 firmware or later.

3.5.0.0 ➤ Initial release. 20150511

Quicksort
Version Summary of Revisions Date Code

3.5.1.1 ➤ Addressed an issue that causes an 'Invalid use of restricted SEL library' compile error on 20221216
ACSELERATOR RTAC versions 1.35.151.6000 and later.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Replaced the deprecated POINTER_TO_ANY type with POINTER_TO_BYTE.
➤ Must be used with R143 firmware or later.

3.5.0.0 ➤ Initial release. 20140812

RecordingTriggers
Version Summary of Revisions Date Code

3.5.2.1 ➤ Addressed an issue introduced in version 3.5.2.0 where if a High Threshold trigger is 20240325
configured for Rising-Edge mode and the condition exists for exactly one processing interval,
the trigger output could latch in.

3.5.2.0 ➤ Added an optional pickup time input to all recording trigger function blocks. 20231114
➤ Added an optional dropout time input to the fb_DigitalTrigger function block.
➤ Added an optional minimum active trigger threshold to the fb_LowThreshold function block.
➤ Added data structure struct_RecordingTriggerOutputInfo.

3.5.1.2 ➤ Documentation-only change. 20220909

Date Code 20241023 Programming Reference


1260 Release Notes
Libraries

Version Summary of Revisions Date Code

3.5.1.1 ➤ Addressed an issue that causes a compile warning when entering more than 100 triggers. 20200702

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.2 ➤ Initial release of high-threshold function block. 20170908


➤ Initial release of low-threshold function block.
➤ Initial release of rate-of-change function block.
➤ Initial release of digital trigger function block.

ReportGenerator
Version Summary of Revisions Date Code

3.5.0.7 ➤ Extension update only. 20240325

3.5.0.6 ➤ Extension update only. 20231114

3.5.0.5 ➤ Documentation-only change. 20220909

3.5.0.4 ➤ Resolved an issue that prevents going online while using the ReportGenerator extension and 20211216
FileIo library in the same project.
➤ Allows compatibility with project versions R150 and later.

3.5.0.3 ➤ Updated extension for compatibility with ACSELERATOR RTAC versions newer than 20200702
1.30.146.3437.

3.5.0.2 ➤ Resolved an issue that may cause a logic engine restart. 20200214

3.5.0.1 ➤ Updated class_ReportGenerator for compatibility with SEL Server FILE SHOW command. 20191024
➤ Addressed an issue with the Report Generator extension that may cause a logic engine restart
when referencing REAL or LREAL variables with the value NaN, +inf, or -inf.
➤ Addressed an issue with the Report Generator extension that may keep timeStamp_t data
types from being rendered in the report.

3.5.0.0 ➤ Initial release. 20190830

SELEthernetController
Version Summary of Revisions Date Code

3.5.2.0 ➤ Allows compatibility with project versions R150 and later. 20220526

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.6 ➤ Allow the class to recover instead of closing the socket when attempting to send large 20160501
amounts of data all at once.

3.5.0.5 ➤ Added queues as input and output mechanisms for socket data. 20150511
➤ Allow TCP client ports to connect to a server without binding to a specific local port.

3.5.0.3 ➤ Made TCP sockets not throw error when outgoing data buffer is full. 20141107

3.5.0.2 ➤ Initial release. 20141010

Programming Reference Date Code 20241023


Release Notes 1261
Libraries

SELRand
Version Summary of Revisions Date Code

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.0 ➤ Initial release. 20140811

SELServerSimulators
Version Summary of Revisions Date Code

3.5.3.1 ➤ Resolved an issue that caused a compile error when using class_TelnetServer or 20220909
class_SessionManager in R150 projects.
➤ SELServerSimulators support is deprecated for firmware revisions R151 and later.

3.5.3.0 ➤ Allows compatibility with project versions R150 and later. 20220331

3.5.2.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.2.0 are not supported for project versions R148 and later.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.1 ➤ Initial release. 20150511

SELString
Version Summary of Revisions Date Code

3.5.3.1 ➤ Resolved an issue in class_SELString LeftJustify and RightJustify methods where use of the 20220909
same padding length as the SELString caused a logic engine restart.

3.5.3.0 ➤ Resolved an issue in the class_SELString FindString method where evaluating an IEC 61131 20220331
string of the same length as the SELString would return an incorrect result.
➤ Added support to append from an array of bytes.
➤ Added functions fun_ByteIsAlpha, fun_ByteIsNumeric, fun_ByteIsAlphanumeric.
➤ Added functions fun_LowercaseByte and fun_UppercaseByte.
➤ Added class_SELString methods Count, StartsWith, EndsWith, LeftJustify, RightJustify,
Strip, LeftStrip, RightStrip.
➤ Added support to copy class_SELString contents to another class_SELString.
➤ Added support to convert raw byte content to and from ASCII-encoded hexadecimal strings.
➤ Added property to access a pointer to the first byte in a class_SELString.
➤ Allows compatibility with project versions R150 and later.

3.5.2.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.2.0 are not supported for project versions R148 and later.
➤ Added support for simultaneous use in both main and automation tasks.
➤ Modified class_SELString and class_SELStringList to have maximum size determined by
available system memory.
➤ Modified class_SELStringList.Join method to accept class_SELString as an argument and
return pointer to STRING to indicate any errors encountered.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

Date Code 20241023 Programming Reference


1262 Release Notes
Libraries

Version Summary of Revisions Date Code

3.5.0.3 ➤ Added FromByteArray and ToByteArray methods. 20140811


➤ Added AppendString and PrependString methods.
➤ Added FindString method.
➤ Protected classes against assignment.

3.5.0.1 ➤ Initial release. 20140701

SELUtils
Version Summary of Revisions Date Code

3.5.6.0 ➤ Added enumerations to represent enumerated states of an SEL-2488 Satellite-Synchronized 20241023


Network Clock polled over SNMP.
➤ Added BYTES_TO_IPv4_STRING and BYTES_TO_MAC_ADDRESS_STRING to support
converting byte strings to ASCII representations.
➤ Added FORMAT_SIGNIFICANT_FIGURES function to evaluate floating point numbers
according to a specified number of significant figures.
➤ Added fb_TTLInput function block to evaluate analog values to interpret Boolean
representations.
➤ Modified PID and CascadeControl function blocks to reduce the number of visible variables.

3.5.5.1 ➤ Modified fun_CheckLicense to support R200 firmware. 20241023

3.5.5.0 ➤ Added the OverComparatorWithHystersis function block. 20240325


➤ Added the UnderComparatorWithHystersis function block.
➤ Added fun_GenerateUUID4 to generate a UUID.
➤ Added functions to convert between hexadecimal string and an LWORD
(HEX_STRING_TO_LWORD and LWORD_TO_HEX_STRING).

3.5.4.3 ➤ Modified all library enumerations to require fully qualified access. 20231114
➤ Added support of TO_STRING data type conversions for all library enumerations.
➤ Addressed an issue in TRANSLATE_INS where the returned INS.stVal is fixed at
Range_Min_Out.
➤ Addressed an issue in ADD_CMV and SUB_CMV where a resultant angle of 90 degrees is
incorrectly displayed as –90.
➤ Addressed an issue in ComposePF where the power factor sign is inverted for angles with an
absolute difference in excess of 180 degrees.

3.5.4.2 ➤ Added default values for offset, ceiling, and floor inputs of SCALE_MV, SCALE_CMV, 20221104
and SCALE_INS making these parameters optional. Note, R150+ is required to use default
values.
➤ Added additional global constants for data type maximum and minimum value.
➤ Updated description of global constant FLOAT_MIN.
➤ Added function SCALE_BCR to scale BCR values.
➤ Added function block Logger_ACD to log ACD data types to RTAC's sequence of event log.
➤ Added function block Logger_ACT to log ACT data types to RTAC's sequence of event log.
➤ Added function REAL_APPROX_EQUAL to check if two REAL or two LREAL values are
effectively equal (± 1 bit) accounting for floating point precision limitations.

3.5.4.1 ➤ Added functions to convert between hexadecimal digits and a DWORD 20220909
(HEX_STRING_TO_DWORD and DWORD_TO_HEX_STRING).

3.5.4.0 ➤ Added functions to get and set individual bits within BYTE, WORD, DWORD, and LWORD 20220331
datatypes.
➤ Added functions to convert between hexadecimal digits and a WORD
or BYTE(HEX_STRING_TO_BYTE, HEX_STRING_TO_WORD,
BYTE_TO_HEXSTRING).
➤ Added function to validate hexadecimal digits in a STRING and BYTE
(fun_isValidHEXString, fun_isValidHEXChar).
➤ Resolved an issue with angle calculation in ComposePF, ComposeWatts, and ComposeVAR.

Programming Reference Date Code 20241023


Release Notes 1263
Libraries

Version Summary of Revisions Date Code

3.5.3.2 ➤ Added functions to convert CMV, MV, SPS, INS, and BCR to formatted STRING. 20211216
➤ Added functions to convert hex STRING characters to the numeric representation of BYTE,
and WORD.
➤ Added function to obtain the Power Factor from W, VA, and VAR.

3.5.3.1 ➤ Added string checksum evaluation function (fun_Checksum). 20210504


➤ Added functions to convert numeric representation of BYTE and WORD to STRING of hex
characters.

3.5.3.0 ➤ Added phasor angle difference monitor (fb_PADM). 20210212


➤ Added string padding function.
➤ Added filename validation function and supporting structure.

3.5.2.0 ➤ Added power calculation functions. 20201029


➤ Added functions to add or subtract time to a dateTime_t structure.
➤ Added functions for converting dateTime_t to ULINT and ULINT to dateTime_t.

3.5.1.4 ➤ Added functions for converting a variety of data types. 20200826


➤ Added structures to support regular expression usage in logic engine.

3.5.1.3 ➤ Added functions for converting a variety of data types. 20200403

3.5.1.2 ➤ Modified behavior to make empty strVal passed to Logger_STR clear the associated alarm. 20200214
➤ Resolved an issue that may cause a logic engine restart.

3.5.1.1 ➤ Added validation functions for IP addresses, REALs, and LREALs. 20191024
➤ Must be used with R145-V0 firmware or later.

3.5.1.0 ➤ Added functions for converting REAL, LREAL, timestamp_t, and quality_t to STRING. 20180917

3.5.0.1 ➤ Initial release. 20180703

SVPplus
Version Summary of Revisions Date Code

3.5.2.4 ➤ Addressed an issue that causes an 'Invalid use of restricted SEL library' compile error on 20221216
ACSELERATOR RTAC versions 1.35.151.6000 and later.

3.5.2.3 ➤ Added runtime license check verification after project download. 20220909

3.5.2.2 ➤ Addressed an issue where the class_ModalAnalysis percent-of-completion, indicated by the 20220331
return of the Run() method, could remain at 64 when the execution time of the Run() method
nears the stepTime initialization input value.

3.5.2.1 ➤ Literature update only. Removed recommendation for SNR of 80. 20211216

3.5.2.0 ➤ Allows compatibility with project versions R148 and later. 20210212
➤ Versions prior to 3.5.2.0 are not supported for project versions R148 and later.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.3 ➤ Improved precision of entire algorithm. 20150718


➤ Improved performance for large matrices.
➤ Hid internal variables of all function blocks.

3.5.0.0 ➤ Initial release. 20141101

Date Code 20241023 Programming Reference


1264 Release Notes
Libraries

SnmpLite
Version Summary of Revisions Date Code

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 through R149 firmware. SNMPLite support is deprecated for
firmware revisions R150 and later.

3.5.0.6 ➤ Improved management of Ethernet socket failure. 20150511

3.5.0.5 ➤ Removed limitation that number and SNMP ID of ports cannot change. 20150213

3.5.0.4 ➤ Initial release. 20141010

SyslogCollector
Version Summary of Revisions Date Code

3.5.1.0 ➤ Allows compatibility with project versions R150 and later. 20221104

3.5.0.0 ➤ Initial release. 20180928

TrendRecorder
Version Summary of Revisions Date Code

3.5.4.1 ➤ Updated for compatibility with the SEL Data Management and Automation (DMA) 20240711
Blueframe application suite.

3.5.4.0 ➤ Increased the maximum number of recorders from 12 to 32. 20231114


➤ Increased the storage limit from 1 GB to 6 GB on SEL-3350 and SEL-3555 firmware
platforms.

3.5.3.1 ➤ Added runtime license check verification after project download. 20220909

3.5.3.0 ➤ Allows compatibility with project versions R150 and later. 20220526

3.5.2.0 ➤ Resolved an issue in the Profile Manager where inputs no longer accepted direct string 20210826
assignments in projects using R148 or later firmware.

3.5.1.0 ➤ Allows new versions of ACSELERATOR RTAC to compile projects for previous firmware 20180921
versions without SEL IEC types "Cannot convert" messages.
➤ Must be used with R143 firmware or later.

3.5.0.3 ➤ Resolved an issue where, under certain conditions, recorded data were not provided to 20170412
ACSELERATOR TEAM software.
➤ Removed library version 3.5.0.2 from the installer.

3.5.0.2 ➤ Initial release. 20161216

Web_Client_SL
Version Summary of Revisions Date Code

1.1.2.0 ➤ Initial release. 20221104

Programming Reference Date Code 20241023


Release Notes 1265
Extensions

Web_Socket_Client_SL
Version Summary of Revisions Date Code

1.1.0.0 ➤ Initial release. 20221104

XML_Utility_SL
Version Summary of Revisions Date Code

1.0.4.0 ➤ Initial release. 20221104

Extensions
Extensions are pre-packaged solutions (e.g., data recording and email) that
offer settings form-based configuration of IEC 61131-3 logic in ACSELERATOR
RTAC. Below are release notes for various different extensions which are
available via ACSELERATOR RTAC.

Some extensions work closely with features of ACSELERATOR RTAC, or specific


versions of an associated library, as such, these minimum versions are also
documented in the "Version" column of the table below.

Starting with revisions published after March 1, 2022, changes that address
security vulnerabilities are marked with "[Cybersecurity]". Other improvements
to cybersecurity functionality that should be evaluated for potential
cybersecurity importance are marked with "[Cybersecurity Enhancement]".

87L Comm Monitor


Version Summary of Revisions Date Code

1.35.0.1 ➤ Library update only. 20241023


Associated Library
(ConditionMonitoring): 3.5.3.1
ACSELERATOR RTAC: 1.36.152.8000

1.35.0.0 ➤ Initial release. 20240711


Associated Library
(ConditionMonitoring): 3.5.3.0
ACSELERATOR RTAC: 1.36.152.8000

CDC Type II Server


Version Summary of Revisions Date Code

1.33.0.1 ➤ Documentation-only change. 20220909


ACSELERATOR RTAC: 1.34.150.15000

1.33.0.0 ➤ Added support for R150 firmware. 20220526


ACSELERATOR RTAC: 1.34.150.15000

1.22.0.0 ➤ Initial release. 20170109


ACSELERATOR RTAC: 1.20.10548.2239

Date Code 20241023 Programming Reference


1266 Release Notes
Extensions

CDC Type II Client


Version Summary of Revisions Date Code

1.33.0.1 ➤ Documentation-only change. 20220909


ACSELERATOR RTAC: 1.34.150.15000

1.33.0.0 ➤ Added support for R150 firmware. 20220526


ACSELERATOR RTAC: 1.34.150.15000

1.27.0.0 ➤ Initial release. 20181217


ACSELERATOR RTAC: 1.28.144.16774

CommProc Converter
Version Summary of Revisions Date Code

1.34.0.0 ➤ Initial release. 20241023


ACSELERATOR RTAC: 1.36.152.8000

CtPt Monitor
Version Summary of Revisions Date Code

1.33.0.5 ➤ Library update only. 20241023


Associated Library: 3.5.3.1
ACSELERATOR RTAC: 1.34.150.18000

1.33.0.4 ➤ Library update only. 20240711


Associated Library: 3.5.3.0
ACSELERATOR RTAC: 1.34.150.18000

1.33.0.3 ➤ Increased the minimum range of the Minimum Signal Magnitude 20231114
Associated Library: 3.5.2.3 setting on the Group Settings page to 1.
ACSELERATOR RTAC: 1.34.150.18000 ➤ Addressed an issue where the Maximum File Retention setting of the
Reports Setting page is not applied to the associated directory manager
function.

1.33.0.2 ➤ Library update only. 20221216


Associated Library: 3.5.2.2
ACSELERATOR RTAC: 1.34.150.18000

1.33.0.1 ➤ Allows disabling summary logging by setting the Summary Logging 20221104
Associated Library: 3.5.2.1 Interval of the Report Settings tab to zero.
ACSELERATOR RTAC: 1.34.150.18000 ➤ Addressed an issue where CMV channels are not validated for group
inclusion when Angle Monitoring is enabled.

1.33.0.0 ➤ Added CtPt Monitor support for topology processing, angle 20220909
Associated Library: 3.5.2.0 monitoring, chatter tracking, report generation, RTAC SOE integration,
ACSELERATOR RTAC: 1.34.150.18000 and SCADA tag mapping.

1.31.0.2 ➤ Allows compatibility with project versions R150 and later. 20211216
Associated Library: 3.5.1.2 ➤ Addressed issue that could prevent the project from going online with
ACSELERATOR RTAC: 1.32.148.7000 an RTAC in certain configurations.

1.31.0.1 ➤ Added additional phase options. 20210504


Associated Library: 3.5.1.1
ACSELERATOR RTAC: 1.32.148.7000

1.31.0.0 ➤ Initial release. 20210212


Associated Library: 3.5.1.0
ACSELERATOR RTAC: 1.32.148.7000

Programming Reference Date Code 20241023


Release Notes 1267
Extensions

Digital Fault Recorder


Version Summary of Revisions Date Code

1.36.0.0 ➤ Added a Generic Asset Type. 20241023


ACSELERATOR RTAC: 1.37.153.8500 ➤ Added configuration of user-defined Custom Digital and Analog
Channels to allow DFR triggering and recording from external tags.
➤ Added configuration for Analog Input Extended Range Modules for
DFR triggering and recording.
➤ Added setting to enable generation of SOE Log CSV files.
➤ Added setting for Synchrophasor Server PDC ID and PMU Data Rate.
➤ Added a calculated IN neutral current value for Transmission Line and
Generic assets.
➤ Enhanced Local Monitoring to calculate disk space usage statistics.
➤ Modified asset trigger configuration column names to specify units.
➤ Resolved an issue where a Build DFR operation would fail due to the
presence of invalid settings combinations.
➤ Resolved an issue where assets and EtherCAT modules could be
assigned invalid names.

1.35.0.0 ➤ Initial release. 20231114


ACSELERATOR RTAC: 1.36.152.8000

DMA Link
Version Summary of Revisions Date Code

1.35.0.0 ➤ Initial release. 20240711


ACSELERATOR RTAC: 1.36.152.8000

Dynamic Disturbance Recorder


Version Summary of Revisions Date Code

1.33.0.2 ➤ Library update only. 20240711


Associated Library: 3.5.4.5
ACSELERATOR RTAC: 1.34.150.15000

1.33.0.1 ➤ Library update only. 20240325


Associated Library: 3.5.4.4
ACSELERATOR RTAC: 1.34.150.15000

1.33.0.0 ➤ Reduced maximum file size from 500 MB to 100 MB. 20230310
Associated Library: 3.5.4.3
ACSELERATOR RTAC: 1.34.150.15000

1.31.0.4 ➤ Library update only. 20220909


Associated Library: 3.5.4.2
ACSELERATOR RTAC: 1.34.150.15000

1.31.0.3 ➤ Updated SOE CSV Harvester. 20220526


Associated Library: 3.5.4.1
ACSELERATOR RTAC: 1.34.150.15000

1.31.0.2 ➤ Allows compatibility with project versions R150 and later. 20220331
Associated Library: 3.5.4.0
ACSELERATOR RTAC: 1.34.150.15000

1.31.0.1 ➤ Library update only. 20210826


Associated Library: 3.5.3.1
ACSELERATOR RTAC: 1.32.148.7000

Date Code 20241023 Programming Reference


1268 Release Notes
Extensions

Version Summary of Revisions Date Code

1.31.0.0 ➤ Added SOE CSV Harvesting. 20210504


Associated Library: 3.5.3.0
ACSELERATOR RTAC: 1.32.148.7000

1.27.0.3 ➤ Enforce phase assignment for monitored data. 20210212


Associated Library: 3.5.2.3
ACSELERATOR RTAC: 1.28.144.18296

1.27.0.2 ➤ Library update only. 20191122


Associated Library: 3.5.2.2
ACSELERATOR RTAC: 1.28.144.18296

1.27.0.1 ➤ Accept BOOL tag type for COMTRADE records. 20190726


Associated Library: 3.5.2.1
ACSELERATOR RTAC: 1.28.144.18296

1.27.0.0 ➤ Added Enable Recorder setting. 20190218


Associated Library: 3.5.2.0
ACSELERATOR RTAC: 1.28.144.18296

1.26.0.0 ➤ Allows compatibility with project versions R143 and later. 20180921
Associated Library: 3.5.1.0
ACSELERATOR RTAC: 1.26.143.16172

1.21.0.0 ➤ Initial release. 20170601


Associated Library: 3.5.0.0
ACSELERATOR RTAC: 1.22.139.11052

Email Plus
Version Summary of Revisions Date Code

1.34.1.0 ➤ Added support for 61131 STRING and STR variables as the email 20240325
Associated Library: 3.5.3.1 subject for Triggered Reports mode.
ACSELERATOR RTAC: 1.36.152.8000 ➤ Added support for assigning body content from dynamic byte
array structures such as DynamicVectors.class_ByteVector and
Queue.class_ByteDeque.
➤ Added POU output pins to count the number of successful email
transmissions, the number of email transmission failures, and a BOOL
to indicate email send completion for a single cycle.
➤ Altered encoding standard from UTF-8 to CP437 to comply with
library requirements of ASCII characters.
➤ Resolved an issue where Monitored Events mode could not detect CEV
event records from SEL-387 series IEDs.

1.34.0.0 ➤ Added Monitored Events functionality. 20231114


Associated Library: 3.5.3.0 ➤ Increased email body editor size from 65,535 to 1,048,576 characters.
ACSELERATOR RTAC: 1.36.152.8000

1.33.0.1 ➤ Added Monitored Alarms functionality. 20220909


Associated Library: 3.5.2.0 ➤ Added setting for Maintenance Mode.
ACSELERATOR RTAC: 1.34.150.15000

1.33.0.0 ➤ Allows compatibility with project versions R150 and later. 20220331
Associated Library: 3.5.1.0
ACSELERATOR RTAC: 1.34.150.15000

Programming Reference Date Code 20241023


Release Notes 1269
Extensions

Version Summary of Revisions Date Code

1.29.0.1 ➤ Updated extension for compatibility with ACSELERATOR RTAC 20200826


Associated Library: 3.5.0.2 versions newer than 1.30.146.3437.
ACSELERATOR RTAC: 1.30.146.3437

1.29.0.0 ➤ Initial release. 20200220


Associated Library: 3.5.0.1
ACSELERATOR RTAC: 1.30.146.3437

FTP Sync
Version Summary of Revisions Date Code

1.36.0.0 ➤ Added "." (dot), "-" (dash), and "@" (at) as supported characters for the 20241023
Associated Library: 3.5.2.3 FTP username.
ACSELERATOR RTAC: 1.37.153.8500 ➤ Resolved an issue introduced in 1.35.0.0 where CEV event monitoring
would fail on an SEL Protocol device that contained "_SEL" in the
middle of the device name.

1.35.0.0 ➤ Added additional settings pages to enhance workflow for defining 20231114
Associated Library: 3.5.2.2 monitored directories and event sources.
ACSELERATOR RTAC: 1.36.152.8000

1.29.0.4 ➤ Documentation-only change. 20220909


Associated Library: 3.5.2.1
ACSELERATOR RTAC: 1.34.150.15000

1.29.0.3 ➤ Allows compatibility with project versions R150 and later. 20220331
Associated Library: 3.5.2.0
ACSELERATOR RTAC: 1.34.150.15000

1.29.0.2 ➤ Added setting for Sync Timeout. 20210826


Associated Library: 3.5.1.4 ➤ Allow Sync Interval of 0.
ACSELERATOR RTAC: 1.30.146.3437

1.29.0.1 ➤ Documentation-only change. 20200826


Associated Library: 3.5.1.3
ACSELERATOR RTAC: 1.30.146.3437

1.29.0.0 ➤ Added settings for FTP Server Port and Monitored Events by Path. 20200403
Associated Library: 3.5.1.2
ACSELERATOR RTAC: 1.30.146.3437

1.28.0.1 ➤ Library update only. 20200214


Associated Library: 3.5.0.1
ACSELERATOR RTAC: 1.29.145.20391

1.28.0.0 ➤ Initial release. 20190830


Associated Library: 3.5.0.0
ACSELERATOR RTAC: 1.29.145.20391

Falling Conductor Protection


Version Summary of Revisions Date Code

1.28.0.4 ➤ Added Faulty Sensor Dropout Time and Breaker Status Bad Quality 20240325
Associated Library: 3.5.0.5 Block Time advanced settings.
ACSELERATOR RTAC: 1.29.145.20386

1.28.0.3 ➤ Added Fuse Source switch type. 20220909


Associated Library: 3.5.0.4
ACSELERATOR RTAC: 1.29.145.20386

Date Code 20241023 Programming Reference


1270 Release Notes
Extensions

Version Summary of Revisions Date Code

1.28.0.2 ➤ Added advanced settings for Availability Pickup/Dropout, Faulty 20220526


Associated Library: 3.5.0.3 Sensor Pickup, and Breaker Status Transit Time.
ACSELERATOR RTAC: 1.29.145.20386

1.28.0.1 ➤ Added Substation Breaker switch type. 20220331


Associated Library: 3.5.0.2
ACSELERATOR RTAC: 1.29.145.20386

1.28.0.0 ➤ Initial release. 20211216


Associated Library: 3.5.0.1
ACSELERATOR RTAC: 1.29.145.20386

Grid Connect
Version Summary of Revisions Date Code

1.35.0.2 ➤ Resolved an issue where Multidrop Serial clients would not be allowed 20241023
Associated Library: 3.5.7.4 to share a common serial port.
ACSELERATOR RTAC: 1.36.152.9500 ➤ Resolved an issue where ControlMode on PCC Settings could not be
set to NoControlMode.
➤ Resolved an issue where upgrading from extension version 1.35.0.0 to
1.35.0.1 could prevent a project from being opened.

1.35.0.1 ➤ Removed IncludeCommand and ExcludeCommand from Reciprocating 20240711


Associated Library: 3.5.7.3 Generator function input mapping.
ACSELERATOR RTAC: 1.36.152.9500 ➤ Corrected data mapping for OperationModeFeedback, OperationMode,
MinStateOfCharge, MaxStateOfCharge, and MaxChargingPower for
BESS inverters.
➤ Added support for new settings in library 3.5.7.3.
➤ Resolved an issue where an error was generated when multiple holding
or input registers had the same start address when the tag type was SPS
or MDBC.

1.35.0.0 ➤ Initial release. 20240418


Associated Library: 3.5.7.2
ACSELERATOR RTAC: 1.36.152.9500

Indirect Tagging
Version Summary of Revisions Date Code

1.33.0.0 ➤ Added support for mapping of structured client tag names containing 20220909
ACSELERATOR RTAC: 1.34.150.15000 multiple periods, such as those present on MMS clients. These tags
will be mapped to similarly named virtual tag list tags containing
underscores in place of the periods.

1.28.0.1 ➤ Added per-client option to only map the .status sub-attribute of Modbus 20210504
ACSELERATOR RTAC: 1.32.148.7000 Holding Register tags of type APC/INC/MDBC to corresponding tags
of type MV/INS/SPS located in the Shared Tag Map.

1.28.0.0 ➤ Initial release. 20210212


ACSELERATOR RTAC: 1.32.148.7000

Programming Reference Date Code 20241023


Release Notes 1271
Extensions

MMS File Transfer


Version Summary of Revisions Date Code

1.35.0.0 ➤ Initial release. 20240325


Associated Library: 3.5.7.1
ACSELERATOR RTAC: 1.36.152.8000

Protection Elements
Version Summary of Revisions Date Code

1.35.0.1 ➤ Increased the maximum allowed frequency elements in each substation 20240711
Associated Library: Power System asset to 16 elements.
Protection 3.5.2.1
ACSELERATOR RTAC: 1.36.152.nnnn

1.35.0.0 ➤ Initial release. 20240325


Associated Library: Power System
Protection 3.5.2.0
ACSELERATOR RTAC: 1.36.152.8000

Recording Triggers
Version Summary of Revisions Date Code

1.26.1.1 ➤ Updated the extension for compatibility with the 3.5.2.1 library update. 20240325
Associated Library: 3.5.2.1
ACSELERATOR RTAC: 1.26.143.16172

1.26.1.0 ➤ Added an optional pickup time setting for each trigger. 20231114
Associated Library: 3.5.2.0 ➤ Added the Low Trigger Minimum Active Setpoint setting.
ACSELERATOR RTAC: 1.26.143.16172 ➤ Added an optional dropout time setting for digital triggers.
➤ Added POU pins for the number of enabled recording triggers and the
individual trigger output array.

1.26.0.2 ➤ Documentation-only change. 20220909


Associated Library: 3.5.1.2
ACSELERATOR RTAC: 1.26.143.16172

1.26.0.1 ➤ Addressed warnings when more than 100 triggers are configured. 20200702
Associated Library: 3.5.1.1
ACSELERATOR RTAC: 1.26.143.16172

1.26.0.0 ➤ Updated extension for compatibility with ACSELERATOR RTAC 20180921


Associated Library: 3.5.1.0 versions newer than 1.26.143.16172.
ACSELERATOR RTAC: 1.26.143.16172

1.20.0.0 ➤ Initial release. 20170908


Associated Library: 3.5.0.2
ACSELERATOR RTAC: 1.23.140.12272

Date Code 20241023 Programming Reference


1272 Release Notes
Extensions

Report Generator
Version Summary of Revisions Date Code

1.28.0.7 ➤ Added support for array access of variables for variable interpretation. 20240325
Associated Library: 3.5.0.7 ➤ Added support for MV, INS, CMV, SPS, and BCR types for variable
ACSELERATOR RTAC: 1.35.151.6000 interpretation.
➤ Added support to allow escape characters such as \t, \n, and \r.
➤ Improved settings validation by removing the ability to set conflicting
options in configuration.

1.28.0.6 ➤ Increased report text editor size from 65,535 to 1,048,576 characters. 20231114
Associated Library: 3.5.0.6
ACSELERATOR RTAC: 1.35.151.6000

1.28.0.5 ➤ Resolved an issue where the DataStorageWarning output did not assert 20220909
Associated Library: 3.5.0.5 when warning conditions existed.
ACSELERATOR RTAC: 1.34.150.15000

1.28.0.4 ➤ Allows compatibility with project versions R150 and later. 20211216
Associated Library: 3.5.0.4 ➤ Resolved an issue that prevented going online while using the
ACSELERATOR RTAC: 1.34.150.15000 ReportGenerator extension and FileIO library in the same project.

1.28.0.3 ➤ Updated extension for compatibility with ACSELERATOR RTAC 20200702


Associated Library: 3.5.0.3 versions newer than 1.30.146.3437.
ACSELERATOR RTAC: 1.30.146.3437

1.28.0.2 ➤ Library update only. 20200214


Associated Library: 3.5.0.2
ACSELERATOR RTAC: 1.29.145.20391

1.28.0.1 ➤ Resolved an issue that prevented timeStamp_t data types from being 20191024
Associated Library: 3.5.0.1 rendered in the report.
ACSELERATOR RTAC: 1.29.145.20391

1.28.0.0 ➤ Initial release. 20190830


Associated Library: 3.5.0.0
ACSELERATOR RTAC: 1.29.145.20391

Simple Tag Mapper


Version Summary of Revisions Date Code

1.36.0.0 ➤ Added support for CSV file map imports. 20241023


ACSELERATOR RTAC: 1.37.153.8500 ➤ Added support for integration of DNP and Modbus shared map settings
(point number, variation, etc.) on the generated map tabs.
➤ Added support for live data and logging-only modes to allow live data
and SOE logging functionality without any tag mapping features.
➤ Added support for the FUNCTION operator to allow use of a custom
IEC 61131 function to populate server tags.
➤ Addressed an issue where multiple instances of Simple Tag Mapper
could not be inserted into a project.

1.33.0.1 ➤ Added Control Mode setting to allow customized mapping of 20221104


ACSELERATOR RTAC: 1.35.151.6000 command tags with either Auto, Verbose or None as options.
➤ Added logging of setpoint actions for .oper elements within APC and
INC tag types.
➤ Addressed an issue introduced in R150 projects where Live Data
statements and KY/KYZ operator functions could no longer be used.

1.33.0.0 ➤ Documentation-only change. 20220909


ACSELERATOR RTAC: 1.34.150.15000

1.28.0.0 ➤ Initial release. 20210504


ACSELERATOR RTAC: 1.32.148.7000

Programming Reference Date Code 20241023


A P P E N D I X B

Developer Mode
Introduction
Developer Mode can be enabled by going to the following location: SEL >
Options > Advanced.

Figure B.1 Enable Developer Mode

Once the check box is selected and the RTAC software has been restarted,
projects R135 and later will support developer mode.

"Developer Mode" is an option that can be turned on in ACSELERATOR RTAC to


allow users to develop their own libraries directly in the ACSELERATOR RTAC
software. Libraries allow for code to be easily shared between projects and
potentially allows for code to be secured in a compiled library.

To start creating your own libraries, you need to create RTAC projects
specifically intended to be converted to a library format. Do this by starting a
new SEL RTAC Project and checking the Create As Library option.

Date Code 20241023 Programming Reference


1274 Developer Mode
Library Manager

Figure B.2 Create Project as Library

With this new project created and opened, you can now begin adding POU's to
the POUs tab which is minimized to the left-hand side of ACSELERATOR RTAC
by default. Code added in the POUs tab can be accessed by user logic in the
project tab. Protocol connections or RTAC firmware features cannot be added
into the POUs tab.

Figure B.3 POUs Tab

Library Manager
The library manager is a tool which can be added to the POUs tab. This tool
allows code from other libraries to be referenced in the POUs tab. These
libraries may be from SEL or from users. Add a library manager by right-
clicking on the baseline object from the POUs tree and select Add Object >
Library Manager from the context menu.

Programming Reference Date Code 20241023


Developer Mode 1275
Library Manager

Figure B.4 Adding Library Manager

Library Placeholders
Library Manager objects in ACSELERATOR RTAC can use explicit library
references that point directly to a library of a specific version. That is to say
that if you reference a library such as SEL IEC Types, you will be specifying a
library exactly as the particular version (e.g., 3.5.2.0) and when that dependency
library (SEL IEC Types) is upgraded to a newer version, the dependent library
(your new library) will still reference the original dependency reference (3.5.2.0)
and will require a new library build to reference the newer library. This poses a
long-term issue in terms of library dependencies, and it can cause a variety of
issues.

The simple resolution of this problem is the application of Library Placeholders.


Instead of referencing a library directly by its version, a developer can reference
a library by placeholder, and allow ACSELERATOR RTAC software to resolve
the dependency in real time and select the best (most applicable) library version
at compile time. This is the recommended practice for library development.
Especially for libraries released by SEL.

Inserting Placeholders
Start by selecting the Add library option, and from the popup window, select
Advanced to open the advanced library reference view.

Date Code 20241023 Programming Reference


1276 Developer Mode
Library Manager

Figure B.5 Navigating to Placeholder Page

From the advanced view, select the Placeholder tab, and find the library you are
interested in adding a placeholder for. In this example SEL IEC Types is selected
from the Miscellaneous section. All RTAC related from SEL will appear in the
Miscellaneous section. It is recommended to also include the Standard library
from the Common section. The library gives access to many common data types
and timers that are often utilized.

Programming Reference Date Code 20241023


Developer Mode 1277
Library Manager

Figure B.6 Selecting Placeholder Library

Finally, type a Placeholder name with the exact same name as the Library name,
and select OK to add the library placeholder to the Library Manager.

Date Code 20241023 Programming Reference


1278 Developer Mode
Library Manager

Figure B.7 Adding Placeholder Name

You should now see the placeholder library reference listed among the other
library references that you have added to the Library Manager.

Figure B.8 Completed Library With Placeholder Reference

Referencing Libraries Added in Library Manager


Often when creating libraries, you will need to reference external libraries
(already added on your Library Manager as shown earlier), for that you
will have to reference the Library by its Namespace. After adding the
SEL_IEC_Types library to your Library Manager, you can now use the various
data types in your library with the namespace you used for your placeholder as
shown below.

Programming Reference Date Code 20241023


Developer Mode 1279
Exporting a User-Created Library

Syntax: <library namespace>.<content name>

Example: SEL_IEC_TYPES.TON

Example: SEL_IEC_TYPES.SPS

Figure B.9 Library Reference Example

Exporting a User-Created Library


Libraries are created via the POUs tab. Once the desired logic has been written,
it can be exported as a compiled library to be installed and included in other
RTAC software installations and project configurations.

Prior to saving the POUs as a .compiled-library, the following items in the


project information must be present.

➤ Summary tab:
➢ Company must be filled out
➢ Title must be filled out
➢ Version must be filled out

Figure B.10 Summary Tab for Project Information


➤ Properties tab:

Step 1. Set Key to Public.


Step 2. Set Type to Boolean.
Step 3. Set Value to True.
Step 4. Click Add.
This will allow logic in the library to be accessed by other logic in the
RTAC project.

Date Code 20241023 Programming Reference


1280 Developer Mode
Classes and Methods

Figure B.11 Properties Tab for Project Information

Once project information is filled out properly, click POU > Save POUs
as .compiled-library.

Figure B.12 Save POUs as .compiled-library

Classes and Methods


Classes
Some object oriented concepts are available in the POUs tab. This includes the
class concept. All classes in the POUs tab are created as a function block. Then
additional items can be added to the function block to include other traditional
object oriented concepts.

To start creating the class, add a Function Block by right-clicking and selecting
Add Object > POU.

Programming Reference Date Code 20241023


Developer Mode 1281
Classes and Methods

Figure B.13 Select a POU to Add a Class

Figure B.14 Select Function Block and Name

Extending Function Blocks


The extension of a function block is based on the concept of inheritance in
object-oriented programming. An inherited function block thereby extends a
basic function block and in doing so is given the properties of the basic function
block in addition to its own properties.

Date Code 20241023 Programming Reference


1282 Developer Mode
Classes and Methods

The extension of a function block means:

➤ The inherited function block contains all data and methods that are
defined by the basic function block. You can use an instance of the basic
function block in every context in which ACSELERATOR RTAC expects a
function block of the type of the basic function block.
➤ The inherited function block is permitted to overwrite the methods
that you have defined in the basic function block. This means that the
inherited function block can define a method with the same name, the
same inputs, and the same output as is defined by the basic function
block.
➤ The inherited function block is not permitted to have any function block
variables with the same name as used for the base function block. The
compiler reports this as an error.
➤ You can directly address the variables and methods of the basic function
block within the scope of the inherited function block by using the
SUPER pointer.

In the example below a function block is created with the basic functionality
common to all relays in a project.

Figure B.15 Base Function Block Example

After adding a second function block, this can extend the previously added
function block. This function block can be extended to have additional
functionality that is common only to a new subset of relays, for instance,
overcurrent relays. This is done by using the keyword EXTENDS.

Figure B.16 Extended Function Block Example

Programming Reference Date Code 20241023


Developer Mode 1283
Classes and Methods

This derived function block has all the variables that the base class has plus
any other variable defined in itself. The derived function block can also access
the base class functionality with the special pointer SUPER. When SUPER^()
is called it will execute the code in the main function block of the extended
function block. It important to note that a derived function block can also
be extended so this process could be repeated further to create new objects
(function blocks) that have all the variables and functionalities of its base class.

Methods
Methods are an extension of the IEC 61131-3 standard and a tool for object-
oriented programming that is used for data encapsulation. A method contains
a sequence of instructions, but unlike a function it is not an independent POU
and it must be assigned to a function block or program. A method has access
to the data in the function block it belongs to, as well as to the variables in
any function block it is derived from. All variables defined in methods are
reinitialized on every call, similar to a Function.

➤ All data of a method are temporary data and are valid only during the
execution of a method. This means that the RTAC engine re-initializes all
variables local variables in the method each time the method is called.
➤ Like functions, methods can have additional outputs. You must assign
these additional outputs in the method call.
➤ Methods have access to the variables in the parent function block, this
includes inputs, outputs, and local variables of the parent function block.
➤ Use the THIS pointer to point to the function blocks own instance.
➤ You cannot access VAR_TEMP variables of the function block from a
method.

Adding a Method to a Function Block or Program


A Method can be added to any Function Block or Program that is created in the
POUs tab. To add a Method, right-click the Function Block or Program > Add
Object > Method.

Date Code 20241023 Programming Reference


1284 Developer Mode
Access Modifiers

Figure B.17 Adding a Method to Function Block or Program

Figure B.18 Configuring a Method to Function Block or Program

Access Modifiers
Many POU objects can be declared with the access specifiers of PUBLIC,
PRIVATE, or INTERNAL. These specifiers indicate to the library what
namespace(s) should be granted access to see, leverage, and use these objects.
In many cases, if your library should utilize structures, class methods,
enumerations, or other select POU types that should not be viewable after the
library is exported to a compiled library, these objects should use either the
PRIVATE or INTERNAL specifier to designate such privacy.

Programming Reference Date Code 20241023


Developer Mode 1285
Attribute Pragmas

PUBLIC Specifier
PUBLIC access specifier (or no specifier) will inform the logic engine that
the logic can be instantiated, leveraged, and used outside its own Library
(namespace).

INTERNAL Specifier
Function Blocks, methods, structures, and enumerations with INTERNAL
access specifier can only be accessed within its library (i.e., the same
namespace). INTERNAL specifier is commonly used in conjunction with the
Hidden Attribute (see Attribute Pragmas) to filter what objects will be accessible
from users of the library.

Figure B.19 Internal Access Modifier Example

PRIVATE Specifier (Methods Only)


Methods with PRIVATE access specifier can only be accessed by its Function
Block or Program. No other Program or Function Block can access this Method.

Attribute Pragmas
Hide
This pragma prevents variables from being displayed when using an instantiated
instance of the code. For example, they are not visible in the input assistant or in
the declaration section in online mode.

Figure B.20 Hide Attribute Definition

Date Code 20241023 Programming Reference


1286 Developer Mode
Attribute Pragmas

When attribute 'hide' is added in the line above a variable declaration, that
variable will not be shown with the others during development or online mode.
In the example above OutA will not be shown during development or Online
Mode.

Figure B.21 Hide Attribute Usage During Logic Engine Runtime:


Implementation Section

Figure B.22 Hide Attribute Usage During Logic Engine Runtime: Declaration
Section

If attribute 'hide' is added in the line before the POU declaration, then the entire
POU is hidden.

Figure B.23 Hide Attribute for Entire POU

Programming Reference Date Code 20241023


Developer Mode 1287
Attribute Pragmas

Even if the variables are hidden, they can still be accessed by using the correct
variable and POU name. If the pragma hide is used in compiled libraries for
variables and signatures, these variables and signatures are also not displayed in
the library manager.

hide_all_locals
This pragma prevents all local variables of a POU from being visible in
the display of the List components function, in the input assistant or in the
declaration part in online mode.

Figure B.24 Hide All Locals Attribute for Entire POU

When attribute 'hide_all_locals' is added in the first of the POU declaration area,
all local variables (VAREND_VAR) will not be shown during online mode. In
the example above LocalA and LocalB will not be shown during Online Mode.

Figure B.25 Hide All Locals Attribute During Runtime

Date Code 20241023 Programming Reference


This page intentionally left blank
SCHWEITZER ENGINEERING LABORATORIES, INC.
2350 NE Hopkins Court • Pullman, WA 99163-5603 U.S.A.
Phone: +1.509.332.1890 • Fax: +1.509.332.7990
selinc.com • [email protected]

You might also like