ProgrammingReference_20241023
ProgrammingReference_20241023
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/.
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
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
Examples................................................................................................................................ 345
Examples................................................................................................................................ 735
Retain Variables....................................................................................................................... 744
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
values are another type of argument you can use. There are two types of
values: bound and unbound.
For example:
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:
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
0 success
1 failure
2 bad syntax
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
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>
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" 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.
Options
-a, --alias <alias>
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"
connect
This command is the same as Go Online in ACSELERATOR RTAC.
Synopsis
AcRtacCmd connect [options] <ipaddress> <username>
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>
Options
-a, --alias <alias>
In addition to going online with the given RTAC, also send the specified
project from option -n or current open project.
Sends complete project.
Update the Retain Password Vault with the given password parameters.
-b, --databaseport <databaseport>
Advanced Options
The following are additional settings that can be in a project:
-v, --advanced <key>
Name Description
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: 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"
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>
<version>
<type>
The type of RTAC. Valid RTAC types are shown in Table 1.3.
Table 1.3 Convert RTAC Types
Type Description
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.
Options
-a, --alias <alias>
The new name for the converted project. If no name is provided, a new
name will be generated automatically.
-d, --delete
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: 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>
Options
-a, --alias <alias>
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
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.
Options
-a, --alias <alias>
Examples
Feature: Disable the password on a project.
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.
Options
-a, --alias <alias>
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: 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
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>
Options
-a, --alias <alias>
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.
Examples
Feature: Importing and Exporting projects as .exp file
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>
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.
Examples
Feature: Export a project to a .compiled-library file
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.
➤ 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>
Options
-a, --alias <alias>
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: Import a new project named Xmlexample for a 3530 using version
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
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>
Options
-a, --alias <alias>
<name>
Examples
Feature: Importing and Exporting projects as .exp file
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>
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 type of RTAC. Valid RTAC types are shown in Table 1.4.
Table 1.4 importxml RTAC Types
Type Description
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.
<version>
Options
-a, --alias <alias>
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
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"
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>
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 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
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>
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.
login
Log into the ACSELERATOR RTAC database.
Synopsis
AcRtacCmd login [options] <username>
Values
<username>
Options
-a, --alias <alias>
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.
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
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>
Options
-a, --alias <alias>
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'
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"
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>
Options
-a, --alias <alias>
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>
Advanced Options
The following are additional settings that can be in a project:
-v, --advanced <key>
Name Description
Name Description
Examples
Feature: Reading project settings from a RTAC.
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>
Options
-a, --alias <alias>
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.
rtacinfo
Displays information associated with an RTAC.
Synopsis
AcRtacCmd rtacinfo [-a <alias> | -i <pid>] [-p
<password>] [-b <databaseport>] <ipaddress> <username>
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>
Options
-a, --alias <alias>
Examples
Feature: Display information associated with an RTAC.
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>
Options
-a, --alias <alias>
Examples
Feature: Set the password on a project.
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>
Startup Switches
-s, --switch <startup switch>
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
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
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>
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
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
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>
Options
-a, --alias <alias>
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.
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>
<username>
<file>
Options
-a, --alias <alias>
Examples
Feature: Upgrade firmware on an RTAC
Assumptions
The following must be true for this example to work:
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.
Expected Result
The project definition should now exist in the following folder:
C:\TestConvertExpToXml\MyProject\.
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)/).
.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)
The .xml files in the .rext file will be parsed, and the content of the first tag:
<RTACModule><CustomApplicationDefinition><Name>
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:
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.
Usage
From within the RTAC subdirectory ./SEL/AcSELerator/RTAC, the installer
can be provided a folder that contains various types of packages. For example:
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.
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.
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.
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.
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.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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).
OutOfBoundsAlarm (Method)
Provides the out-of-bounds state of the ConditionValue() input.
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:
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
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.
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:
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
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.
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.
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.
Return Value
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.
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 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
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
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
initialValue REAL Range: lowLimit ≤ initialValue ≤ highLimit. Sets the initial value to
be used by the filter at startup.
Return Value
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.
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.
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
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
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.
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
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.
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
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.
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:
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.
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);
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
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.2 An Excursion Defined by the Indicator Equaling a TRUE Value for
the Excursion Time Generates an Alert
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);
Versions 3.5.0.0 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_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.
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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
ChatterCount UDINT Number of deviations allowed within a time period defined by the
ExcursionTime
LatchAlarm BOOL Defaults to true. If true, Alert will stay asserted until Reset is
asserted.
Outputs
Name IEC 61131 Type Description
ChannelStatus enum_ChannelAlert Enumeration describing the channels that generated the status 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.
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
ChatterCount UDINT Number of deviations allowed within a time period defined by the
ExcursionTime
LatchAlarm BOOL Defaults to true. If true, Alert will stay asserted until Reset is
asserted
Outputs
Name IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
ChatterCount UDINT Number of deviations allowed within a time period defined by the
ExcursionTime
Outputs
Name IEC 61131 Type Description
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.
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
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.
Outputs
Name IEC 61131 Type Description
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.
➤ 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
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.
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.
Outputs
Name IEC 61131 Type Description
QualityAlert BOOL Asserts when channel quality is bad or integral output accuracy is
suspect
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.
Equation 4.1
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
Outputs
Name IEC 61131 Type Description
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.
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.
Figure 4.5 depicts a relative time alignment scenario where samples with
matching time stamps arrive within the wait window.
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.
➤ 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.
➤ 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.
Inputs
Name IEC 61131 Type Description
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
BootstrapChannelSet_MV (Method)
This method adds an input/output set of MV channels for monitoring and
updating respectively.
Inputs/Outputs
Return Value
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
Return Value
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
➤ 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.
➤ 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.
GetDataSet (Method)
This method updates the output channels with the oldest available set of time-
aligned data.
Outputs
Return Value
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.
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
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_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 Alert
The cost of a call to fb_ChannelDerivative while Status = EXCURSION and
Alert.stVal = TRUE.
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).
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.
For each bracket, and each evaluated class method, two additional operating
conditions are considered, as described below.
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_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 Alert 6 8 1
fb_IndicatorTimeDelta No Deviation 9 12 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.
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
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 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
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;
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:
PROGRAM prg_KWH_Track
VAR
Enable : BOOL;
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
// 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;
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
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
// 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.
Solution
This solution applies a single instance of class_TimeAlignment to time align the
three channels. This example assumes the following:
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
// 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
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).
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
enum_GenericDataClass
This enumeration specifies a class of data and is intended for use by
class_CmReportWriter.
Enumeration Description
enum_PhaseID
This enumeration allows for the specification of a particular electrical phase.
Enumeration Description
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
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
Enumeration Description
e_END_OF_SER_TAGS
e_24HR_LOST_PACKETS_INS 24-hour lost packet count 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_END_OF_ENUM
Structures
struct_CTPTGroupStatus
This structure contains status information relevant to all monitored assets of a
given 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.
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.
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.
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.
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.
NodeGroup STRING(255) List of node indexes associated with the assets' monitor group.
struct_DetailColLabel
This structure specifies a label and data class for a given column in a Detail CSV
file.
DataClass enum_GenericDataClass Indication of how this data column should be interpreted by a receiving algorithm.
struct_GenericDataPoint
This structure specifies a single value and associated data class.
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.
This interface enables the CSV formatting for and transfer of three categories of
content.
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).
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
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
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
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
assetID STRING(255) An identifier for the asset that the SOE content
pertains to.
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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.
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.
COM87LResetPeriod UDINT The COM 87L statistics reset period in hours. Set to zero for
triggered-only resets.
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_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.
Outputs
Name IEC 61131 Type Description
Alert87L BOOL Pulses for one cycle if any monitored data point
enters an alert state.
Bootstrap_MonitoredDataPoint (Method)
Bootstrap a logic engine tag and associated metadata for a data channel that
sources 87L communications status from an IED.
Inputs
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
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
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().
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.
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_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".
.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.
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.2 CT Monitoring Group With Applied Scaling for Transformer Low-Side
CTs
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.
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.
Outputs
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).
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
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.
NOTE
When initialization input InputTypeIsAngle = TRUE, the .instCVal.ang
is used for monitoring. Otherwise, .instCVal.mag is used.
Inputs/Outputs
StatusOutput struct_CTPTStatusOutput The target structure to be updated with monitored status information for the given CT
or PT.
Inputs
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
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
StatusOutput struct_CTPTStatusOutput The target structure to be updated with monitored status information for the given CT
or PT.
Inputs
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
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
StatusOutput struct_CTPTStatusOutput The target structure to be updated with monitored status information for the given CT
or PT.
Inputs
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
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.
Inputs/Outputs
Channel CMV The CT or PT data channel to be used as a reference for the specified phase.
Inputs
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
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.
NOTE
The .instMag portion of the MV is used for monitoring.
Inputs/Outputs
Channel MV The CT or PT data channel to be used as a reference for the specified phase.
Inputs
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
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
Channel INS The CT or PT data channel to be used as a reference for the specified phase.
Inputs
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
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).
Inputs
Inputs/Outputs
Status SPS Status element for the given breaker/switch. .stVal Interpreted as TRUE = closed.
Return Value
Processing
➤ Returns FALSE if called after a successful call to Initialize().
➤ Returns FALSE if either node ID is outside of the specified range.
Initialize (Method)
This method registers the global inputs for the class.
Inputs/Outputs
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
AlertPickupTime TIME Maximum time a sustained deviation beyond AlertThreshold is allowed. After
the initial deviation, momentary normalization is disregarded.
Return Value
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
➤ 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.
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.
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.
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.
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.
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).
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:
Inputs
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.
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.
MaxSoeFileSize UDINT Maximum SOE file size in bytes before a new file is created.
MaxDetailFileSize UDINT Maximum Detail file size in bytes before a new file is created.
MaxRowsOfDetailHistory UDINT Maximum Number of Detail file rows cached in RAM for historical analysis. Set to
zero to disable.
Outputs
Name IEC 61131 Type Description
Date,Time,TimeCode,StationID,DeviceID,CompanyName,
OutputFilePostfix,Type.csv
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
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
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.
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.
Outputs
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.
Bootstrap_ReportRegExRule (Method)
Call this method to specify a regular expression and associated metadata
necessary to parse content from the original IED report.
Inputs
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
Type = SUMMARY
Return Value
IEC 61131 Type Description
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
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
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.
Date,Time,TimeCode,outputFilePostfix
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.
➤ Bootstrap_ReportRegExRule
➢ Type: enum_ReportContentType.SUMMARY
➢ Label: "Max Current (A)"
➢ RegEx: "(?:MaxCurrent[\\x20-\\x2E\\x41-\\x7E]{1,})([0-9]{1,4})"
➢ Instances: 1
➤ 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
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.
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;
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);
RunOnce := FALSE;
END_IF
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();
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
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);
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);
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);
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
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
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',
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);
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);
Assumptions
This example assumes the following:
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);
////////// ////////// ////////// ////////// ////////// /////
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);
////////// ////////// ////////// ////////// ////////// /////
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);
////////// ////////// ////////// ////////// ////////// /////
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);
Assumptions
This example assumes the following:
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');
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
ReportConverter.Run();
Assumptions
This example assumes the following:
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';
'[\\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
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();
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 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.
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.
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.
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]).
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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
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
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.
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
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.
Benchmark Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555
fb_CrossTaskWrite10 13 8 1
fb_CrossTaskRead10 17 9 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.
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
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
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);
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
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
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);
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);
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
enum_JsonType
Enumeration Description
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.
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
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
struct_JsonElement
Name IEC 61131 Type Description
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.
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
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 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).
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.
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.
Inputs
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
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.
➤ 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
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
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.
Return Value
IEC 61131 Type Description
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.
Return Value
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
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.
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.
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 }
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.
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
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.
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
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.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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.
GoToIndex (Method)
Call this method to navigate to a specified element in the JSON structure and
load it to the current scope.
Inputs
Return Value
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
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.
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.
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
Return Value
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.
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.
Inputs
Inputs/Outputs
Return Value
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
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.
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.
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).
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.
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.
InitReadWriteMode (Method)
This method initializes the CSV manager in read/write mode and initiates a CSV
parse operation.
Inputs/Outputs
Return Value
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.
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
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
pt_Labels POINTER TO STRING(255) A pointer to a contiguous memory space containing a collection of column labels.
Return Value
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
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.
Inputs
Name IEC 61131 Type Description
pt_sourceData POINTER TO STRING(255) A pointer to a contiguous memory space containing the row content.
Outputs
Name IEC 61131 Type Description
pt_serializedRow POINTER TO BYTE Pointer to the first byte of serialized row data.
Return Value
IEC 61131 Type Description
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
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
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
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
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.
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
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
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
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
Return Value
IEC 61131 Type Description
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
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
Return Value
IEC 61131 Type Description
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
Return Value
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.
Inputs
newValue STRING(255) The content with which the cell will be overwritten.
Return Value
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.
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.
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 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"}}';
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 ]
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
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 }
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
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;
FileWriter : fileio.class_FileWriter('/RTAC_statistics.json');
TempString : STRING(255);
TempSELString : class_SELString;
END_VAR
END_IF
FileWriter.Run();
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);
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);
//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
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
//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;
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
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
//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
//Recycle tempRow
tempRow.Recycle();
//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
IF writer.BytesLeft = 0 THEN
complete := TRUE;
END_IF
END_CASE
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);
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 :=
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;
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
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
//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;
Assumptions
This example assumes the following:
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;
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;
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
//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;
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.
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().
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);
Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.
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
Return Value
IEC 61131 Type Description
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.
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).
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).
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).
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).
GetData (Method)
This method provides the data associated with the provided key.
Inputs
Name IEC 61131 Type Description
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
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.
Delete (Method)
This method removes the key-value pair from the binary tree.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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:
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.
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Size (Property)
This method provides the number of nodes within the tree.
Return Value
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
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.
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.
GetData 14 2 1
Insert 796 59 47
Delete 799 53 42
Begin 3 1 1
Next 2 1 1
NextKey 4 1 1
NextValue 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.
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
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
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';
ELSE
CurrentJob := 'Idle';
END_CASE
IF Working THEN
CurrentData := MyBinaryLookupTree.GetData(CurrentJob, data =>
pt_CurrentData);
fun_DoWork(pt_currentData);
END_IF
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
END_FOR
initialized := TRUE;
END_IF
(* 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
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:
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:
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
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.
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.
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);
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.
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.
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.
Inputs
Name IEC 61131 Type Description
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.
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
ActiveFileName STRING(255) Name of the file that logs are being written to.
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.
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Return Value
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Return Value
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.
Inputs
Inputs/Outputs
Return Value
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.
➤ 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.
Inputs
Name IEC 61131 Type Description
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.
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
ActiveFileName STRING(255) Name of the file that logs are being written to.
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.
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
Inputs/Outputs
Return Value
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
Inputs/Outputs
Return Value
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Return Value
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Return Value
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Return Value
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
➤ 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.
Inputs
Name IEC 61131 Type Description
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.
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.
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
ActiveFileName STRING(255) Name of the file that logs are being written to.
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.
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
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.
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
Return Value
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
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
Return Value
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
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
Return Value
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
COMTRADE object. This method will only add the INS point to be monitored
if called before calling the function block itself.
Inputs
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
Return Value
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
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
Return Value
IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
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
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.
Inputs/Outputs
Return Value
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 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
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.
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.
Inputs
Name IEC 61131 Type Description
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.
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.
Outputs
Name IEC 61131 Type Description
ActiveFileName STRING(255) Name of the file that logs are being written to.
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.
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
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.
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.
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.
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
Benchmark Results
Platform (time in µs)
Operation Tested Metric
SEL-3505 SEL-3530 SEL-3555
class_SoeCsv
class_Float32COMTRADE
class_TimeAlignedCSVManager
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.
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
INIT := TRUE;
END_IF
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
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
15/03/2017,11:51:37.674722
float32
1000
-7,-7
F,3
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
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.
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);
Versions 3.5.1.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.
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
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
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
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
Return Value
IEC 61131 Type Description
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).
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.
Append (Method)
This method appends an array of elements to the end of the vector.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Recycle (Method)
This method removes all elements from the vector without modifying the
memory allocated to the vector.
Return Value
IEC 61131 Type Description
Processing
All elements are removed from the vector.
Resize (Method)
This method resizes the vector so it can contain the number of elements
specified without requiring any additional memory allocations.
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
Processing
This method resizes the vector so it can contain the number of elements
specified without requiring any additional memory allocations.
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
Initialization Inputs
elementSize UDINT The number of bytes required for each element this
vector will hold. If zero, then default to one.
GetCopyOfElement (Method)
This method copies the element at the zero-based index specified from the
vector to the destination pointer.
Inputs
index UDINT The index of the element to copy from the vector.
Return Value
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
Return Value
BOOL TRUE if the last element is successfully copied and removed from the
vector. FALSE if an error occurs.
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
Return Value
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
Return Value
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
Outputs
element BYTE The element at the specified index. If the return value
is FALSE, this value is undefined.
Return Value
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
element BYTE A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.
Return Value
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
Return Value
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
Return Value
IEC 61131 Type Description
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
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.
Return Value
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
Return Value
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
Return Value
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
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.
Push (Method)
This method appends a copy of the provided element to the end of the vector.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
GetAt (Method)
Provides a copy of the element at the specified, zero-based index.
Inputs
Name IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Outputs
element REAL The element at the specified index. If the return value
is FALSE, this value is undefined.
Return Value
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
element REAL A copy of the former last element in the vector. If the
return value is FALSE, this value is undefined.
Return Value
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
Return Value
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
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
element LREAL 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 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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
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
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
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
element POINTER TO BYTE The element to copy to the end of the vector.
Return Value
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
Return Value
IEC 61131 Type Description
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
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.
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
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
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
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.
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
// 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
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
// 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
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.
// 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();
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 fine
someVariable := myEmailClientObject.value;
// As is this
pt_myEmailClientObject := ADR(myEmailClientObject);
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
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.
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
SentMsg STRING(255) The first 255 characters of the last message the
function block sent to the SMTP server.
Processing
The fb_SimpleEmailClient function block body does the following:
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.
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.
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).
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.
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
Inputs/Outputs
Return Value
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.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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.
Return Value
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
Return Value
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.
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
Return Value
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
Return Value
BOOL TRUE if the body content of the email was successfully populated.
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
Return Value
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.
Inputs
Name IEC 61131 Type Description
pt_data POINTER TO BYTE The bytes 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 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
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.
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
Return Value
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
Return Value
BOOL TRUE if the subject content of the email was successfully populated.
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
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.
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
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.
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.Send()
The posted time is the average execution time of 100 method calls. The class is
not busy when the method is called.
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.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.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.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.
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.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.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.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.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.
Benchmark Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555
class_EmailClient.AddRecipient() 120 72 13
class_EmailClient.ClearRecipients() 5 2 1
class_EmailClient.SetSender() 98 58 14
class_EmailClient.SetSubjectBytes() 49 31 9
class_EmailClient.SetSubjectString() 66 42 11
class_EmailClient.SetSubjectVector() 17 9 4
class_EmailClient2.AddRecipient() 118 72 12
class_EmailClient2.ClearRecipients() 5 2 1
class_EmailClient2.SetSender() 95 59 14
class_EmailClient2.SetSubjectBytes() 48 31 8
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.
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.
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);
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.
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';
FileBuffer : class_ByteVector;
LogFileReader : class_FileReader;
END_VAR
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.
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
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
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:
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
pt_myEmailPlusObject := ADR(myEmailPlusObject);
➤ 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 ≡
➤ 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.
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
enum_EmailerType
Configuration mode of this class_EmailClient instance. Used with the
EmailerType input in the Initialize() method.
Enumeration Description
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.
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
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
enum_RecipientType
The type of email recipient. Used with AddRecipient() method.
Enumeration Description
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.
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
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.
Outputs
Name IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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
Inputs
Return Value
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.
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
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
Return Value
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
Return Value
BOOL TRUE if the body content of the email was successfully populated.
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).
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
Processing
The Bootstrap_EventSource() method does the following:
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
Return Value
IEC 61131 Type Description
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
pt_Variable POINTER TO BYTE Pointer to the variable representing the monitored alarm.
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.
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.
Return Value
IEC 61131 Type Description
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.
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
Processing
The ClearRecipients() method does the following:
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
Return Value
Processing
The Initialize() method does the following:
Run (Method)
This method must be called every task cycle. It performs the sending of emails.
Processing
The Run() method does the following:
➢ 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).
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
Return Value
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.
Inputs
Name IEC 61131 Type Description
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.
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.
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();
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();
Assumptions
This example assumes the following:
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
);
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,
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();
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);
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
struct_SyncStatus
This structure contains the sync status for a single monitored IED or directory.
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
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
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.
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.
RunTimeErrors STR Lists any runtime errors the FTP client encounters.
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.
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
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
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
Return Value
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.
Inputs
Return Value
GetSyncStatus (Method)
This method returns the sync status for a given directory or IED.
Inputs
Return Value
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.
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();
Assumptions
This example assumes the following:
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 —–".
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.
The text should all be on a single line and look similar to this (shown with line
wrapping enabled):
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();
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.
Global Constants
The library applies the following global constants which are useful in providing
common constants and references.
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.
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
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.
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.
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.
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)
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)
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%)
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)
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).
struct_ProtTypeEnable
The struct_ProtTypeEnable structure is used to identify the enabled detection
methods for an individual zone.
struct_SwitchStatus
The struct_SwitchStatus structure represents all of the input and calculated
quantities that are respectively evaluated for each switch.
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.
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.
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".
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
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.
➤ 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
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.
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.
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.
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.
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.
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.
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.
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.
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.
Figure 14.11 Zero- and Negative-Sequence Voltage Magnitude (|V0| and |V2|)
Method Logic for Determining Falling Conductor Criteria
Equation 14.1
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
Inputs
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.
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.
Outputs
Trip BOOL Indicator that a Trip signal has been sent to one or more switches
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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
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
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.
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
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.
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)
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.
➤ 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.
➢ 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)
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;
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] );
LD_VB1GGIO3_Ind020 := FCPInstance.RoundTripTimeOutput;
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);
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
enum_FaultType
This enumeration defines the fault type.
Enumeration Description
enum_PhaseRotation
This enumeration defines the phase rotation.
Enumeration Description
enum_WiringConfig
This enumeration defines the potential transformer wiring configuration.
Enumeration Description
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
struct_FaultDetails
This structure is used to represent the fault distance and type determined by a
calculation.
struct_FaultEventDetails
This structure is used by the RequestSingleEndedFaultLocation() method as an
output for calculation results.
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:
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.
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
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.
Inputs
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
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)
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.
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.
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.
Outputs
Name IEC 61131 Type Description
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
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.
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).
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
Processing
➤ The inputs will be cached in a structure and stored in a work request
queue.
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.
Assumptions
This example assumes the following:
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
Assumptions
This example assumes the following:
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
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);
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.
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.
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
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
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
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
FILE_NOT_FOUND The requested file was not found in the file system.
INVALID_FH The file handle provided was not for an open file.
FS_OUT_OF_SPACE The file system did not have enough space to perform the action.
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.
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
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.
FS_OUT_OF_SPACE The file system did not have enough space to perform the action.
OPERATION_TIMEOUT The FTP attempt took longer than the provided time-out.
enum_FileType
Enumeration Description
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
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.
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.
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.
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.
DeviceName STRING(255) The name of the device that logged this event
on the RTAC.
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.
DeviceName STRING(255) The name of the device that logged this event
on the RTAC.
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.
struct_ComtradeInfo
Name IEC 61131 Type Description
struct_AnalogChannelInfo
Name IEC 61131 Type Description
struct_DigitalChannnelInfo
Name IEC 61131 Type Description
struct_SamplingInfo
Name IEC 61131 Type Description
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
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
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.
fun_FtpEventUpload
Use this function to upload event files from the database to an FTP server.
Inputs
Name IEC 61131 Type Description
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
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.
Inputs
Name IEC 61131 Type Description
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
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
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
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.
Inputs/Outputs
Name IEC 61131 Type Description
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
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
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_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
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
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.
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.
Inputs/Outputs
Name IEC 61131 Type Description
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.
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.
Inputs/Outputs
Name IEC 61131 Type Description
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.
Outputs
Name IEC 61131 Type Description
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
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
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 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
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
NewestFileTime timeStamp_t The most recent update time, in UTC, among the listed files.
Return Value
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.
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
NewListReady BOOL Once a list has been built, this output is set to
TRUE.
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
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.
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
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
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.
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).
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.
Outputs
Name IEC 61131 Type Description
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
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
Return Value
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
Return Value
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
Return Value
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.
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.
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.
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
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.
Inputs
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
Return Value
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.
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
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
Return Value
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
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
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.
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.
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
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.
Return Value
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.
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.
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
Error BOOL TRUE if the class cannot write the contents of its
buffer to file.
MaxFileSize UDINT The size, in bytes, at which this class rotates its
automatically generated files.
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
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
Inputs
Name IEC 61131 Type Description
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
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.
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
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
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
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
pt_data POINTER TO BYTE The address of the bytes to use as the footer
block, as returned by the ADR() function.
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
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
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
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
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
Return Value
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
Return Value
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
Inputs/Outputs
Return Value
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
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
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
Inputs/Outputs
Return Value
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.
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.
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.
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.
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
Error BOOL TRUE if the class cannot write the contents of its
buffer to file.
MaxFileSize UDINT The size, in bytes, at which this class rotates its
automatically generated files.
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.
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
pt_data POINTER TO BYTE The address of the bytes to use as the header
block, as returned by the ADR() function.
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
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
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.
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
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
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
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
Return Value
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
Return Value
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
Return Value
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
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
Inputs/Outputs
Name IEC 61131 Type Description
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
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
Return Value
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
Inputs/Outputs
Return Value
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.
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.
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 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.
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.
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
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
Error BOOL TRUE if the class cannot write the contents of its
buffer to file.
MaxFileSize UDINT The size, in bytes, at which this class rotates its
automatically generated files.
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
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
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.
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
Return Value
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
Return Value
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
Return Value
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.
Inputs/Outputs
Name IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
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
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
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
Inputs/Outputs
Name IEC 61131 Type Description
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.
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.
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.
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.
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.
➤ IEEE C37.111-1999
➤ IEEE C37.111-2013
➤ BINARY
➤ FLOAT32
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
CfgBytes UDINT The number of bytes read from the .cfg file.
DatBytes UDINT The number of bytes read from the .dat file.
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.
Inputs
Return Value
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
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
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
Return Value
IEC 61131 Type Description
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
Return Value
Processing
If Error and InProgress are FALSE:
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
ChannelNumber UDINT The digital channel number for which the method
collects information.
Outputs
Return Value
Processing
If Error and InProgress are FALSE:
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
Return Value
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
Return Value
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
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
If Error and InProgress are FALSE:
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.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
If Error and InProgress are FALSE:
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
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).
Return Value
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.
GetDigitalSample (Method)
Call this method to get a single sample of a digital channel and output the
sample as a BOOL value.
Inputs
Outputs
Return Value
Processing
If Error and InProgress are FALSE:
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
Outputs
Name IEC 61131 Type Description
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:
Run (Method)
Call this method on every scan. It supervises all asynchronous operations.
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.
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.
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
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
Processing
If Error and Initialized are FALSE:
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.
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
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.
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().
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.
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.
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.
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.
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.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.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.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.AppendToString 13 6 1
class_FileReader2.Run 4 2 1
class_FileReader2.Run (Idle) 3 1 1
class_LogDirectoryManager.WriteLogEntryString 143 71 5
class_LogDirectoryManager.EventLogFromBytes 145 91 4
class_LogDirectoryManager.EventLogFromVector 149 68 3
class_DirectoryManager.WriteLogEntryBytes 92 27 1
class_DirectoryManager.WriteLogEntryVector 41 15 1
class_DirectoryManager.WriteLogEntryString 46 30 2
class_DirectoryManager.EventLogFromVector 220 85 4
class_DirectoryManager.EventLogFromString 158 80 4
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.EventLogFromVector 236 84 3
class_TimeBasedDirectoryManager.EventLogFromString 165 82 4
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
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.
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;
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
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.
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.
Assumptions
The file "/FileToRead.txt" exists in the root of the RTAC File Manager.
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.
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.
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.
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);
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();
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';
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;
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';
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;
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
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
(* 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
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();
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);
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
LogManager.Run();
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);
IF FirstScan THEN
LogManager.SetFtpServerForArchiving( ftpServer := ServerIP,
remotePath := RemotePath,
username := FtpUser,
password := FtpPassword,
timeout := 5,
schedule := ON_UPDATE);
FirstScan := FALSE;
END_IF
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;
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
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
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.
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;
Timestamp : timestamp_t;
Now : DT;
Last : 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;
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
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
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();
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
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.
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.
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
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.
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);
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.
Parameter Description
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).
The controller automatically adjusts the power limit reference signal of the
inverters to limit the cumulative power output of the plant.
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.
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:
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
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.
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.
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:
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.
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:
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:
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.
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
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.
➤ 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.
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.
➤ 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.
➤ VSetpoint
➤ VDeadband
➤ VKp
➤ VKi
➤ dV_dQ
➤ QRampSetpoint
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.
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.
➤ PFCompensationSetpoint
➤ PFCompensationCutoff
➤ PFCompensationGradient
➤ 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.
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
➤ 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.
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.
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:
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
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
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:
Equation 17.5
The simple power limit mode does not address any non-uniform cloud cover
issues or the presence of local load.
➤ PSetpoint
➤ PLimitRampSetpoint
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.
➤ PSetpoint
➤ PDeadband
➤ PKp
➤ PKi
➤ PLimitRampSetpoint
➤ PLimitDelay
➤ PowerClampMarginPercent
The following settings are used to manage the Constant PCC Power mode:
➤ PSetpoint
➤ PDeadband
➤ PKp
➤ PKi
➤ PLimitRampSetpoint
➤ PLimitDelay
➤ PowerClampMarginPercent
➤ AdditionalStorageDischargeSetPoint
➤ ConstantPowerPickupTime
➤ ConstantPowerDropOutTime
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.
The following settings are used to manage PCC Metering Power mode:
➤ PLimitRampSetpoint
➤ StorageChargeSetpoint
➤ AdditionalStorageDischargeSetPoint
➤ InitialSmoothingSetpoint
➤ MaxPImportSetpoint
➤ MaxPExportSetpoint
➤ PDeadband
➤ SmoothingStrategy
➤ SolarSmoothingRampRate
➤ SolarSmoothingRampTime
➤ SolarChargingRampRate
➤ SolarChargingRampTime
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.
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.
➤ 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.
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.
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.
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.
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.
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.
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
➢ 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.
Parameter Description
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 =
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.
enum_ChargingSource
This enumeration is used to manage the source of power for charging storage
assets.
enum_PLimitMode
This enumeration is used to set and indicate the real power control mode of the
Master Plant Controller.
enum_FrequencyRegulationMode
This enumeration is used to set and indicate the frequency regulation mode of
the Master Plant Controller.
enum_SolarSmoothingStrategy
This enumeration is used to manage solar smoothing strategies.
enum_StorageOperation
This enumeration manages and describes how storage assets are being utilized
by GridConnect.
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.
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.
enum_IslandOperationState
Enumeration Value Description
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.
IslandShutDownGeneration 7 Island shutdown initiated. Shuts down all generation asset and opens all loads if
possible.
enum_PvPenetrationMode
The mode in which PV output will be restricted in islanded operations.
enum_fileConfig
The mode in generated log files will be rotated automatically.
Function Blocks
The library contains the function blocks required to build a GridConnect control
system.
Inputs
Name IEC 61131 Type Description
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)
QSetpoint REAL PCC reactive power control set point. Units are kVAR.
Default is 0.
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.
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.
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.
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.
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.
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.
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.
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.
PlantPRating REAL PCC power output rating. Units are kW. Default is
50000.
PlantQRating REAL PCC reactive power rating. Units are kVAR. Default is
50000.
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.
InverterModeChangeControlDelay TIME Time to delay sending set points after an inverter mode
change. Default is T#10S.
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.
IslandVoltageDeviationTimeout TIME The time to wait after a voltage excursion has occurred
during islanded operation before turning off all
generation. Default is T#0S.
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
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).
PControlLoopIntegral REAL The integral factor of error built up over time from
a set-point change.
QControlLoopIntegral REAL The integral factor of error built up over time from
a set-point change.
PFControlLoopIntegral REAL The integral factor of error built up over time from
a set-point change.
ActiveFileName STRING(255) Name of the file that logs are being written to.
Inputs
Name IEC 61131 Type Description
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.
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.
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.
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.
QuickStop BOOL Asserts to send stop signal to asset. This output can assert when
required even if the master controller is not enabled.
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.
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.
Inputs
Name IEC 61131 Type Description
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.
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.
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.
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.
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.
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.
QuickStop BOOL Asserts to send stop signal to asset. This output can assert when required
even if the master controller is not enabled.
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.
InsufficientCharge BOOL This storage asset has insufficient SOC to discharge power. This is set
when SOC is less than or equal to MinStateOfCharge.
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.
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.
Inputs
Name IEC 61131 Type Description
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.
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.
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.
OperationModeSetpoint enum_gridOperationMode The expected operation mode of how the asset takes setpoints. Default is
GridForming.
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.
Inputs
Name IEC 61131 Type Description
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.
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.
Outputs
Name IEC 61131 Type Description
IncludedInMasterControl BOOL Asset is included in master control. Will assert when asset is included and not
excluded.
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.
Inputs
Name IEC 61131 Type Description
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.
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.
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
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.
PCCSim will accumulate the total combination of all "behind the meter assets"
and then apply the PCC parameters of restrictions or adjustments.
➤ PV Inverters
➤ Battery(ies)
➤ Capacitor
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
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.
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.
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.
Outputs
Name IEC 61131 Type Description
PlantV REAL Voltage at PCC that accounts for VAR flow at PCC. Units are kV.
PlantFrequency REAL Frequency (in hertz) at PCC; reflects the nominal frequency input.
Inverter should output the given input unless it violates the following:
Inputs
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.
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.
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
POutput REAL Real power output of the asset. Units are kW.
QOutput REAL Reactive power output of the asset. Units are kVAR.
A positive set point for Setpoint causes battery discharge, and a negative set
point causes the battery to consume power and store charge.
Inverter should output the given input unless it violates the following:
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.
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.
InitialSOC REAL Initial SOC of battery on first scan or reset. Units are in percent.
MinSOC REAL Minimum SOC above which battery may deliver energy. Units are in percent.
Outputs
POutput REAL Real power output of the asset. Units are in kW.
QOutput REAL Reactive power output of the asset. Units are in kVAR.
Generator should output the given input unless it violates the following:
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.
Inputs
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.
SetpointDelayTime TIME The time it takes for the asset to update its output
once it has received a new set point.
InitialFuelLevel REAL Initial fuel level on first scan or reset. Units are in
percent. Range is 0 to 100.
Outputs
POutput REAL Real power output of the asset. Units are in kW.
QOutput REAL Reactive power output of the asset. Units are in kVAR.
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.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Inputs
Name IEC 61131 Type Description
ConnectToPCCSim POINTER TO fb_PCCSim Connection to the Point of Common Coupling Simulator object.
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.
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
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.
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
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
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;
// 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
// 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
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;
// 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 :=
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 :=
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;
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;
Glossary
A list of terms related to power system management.
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 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:
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.
➤ 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.
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 fine
someVariable := myIpAliasRedundancyObject.value;
// As is this
pt_myIpAliasRedundancyObject :=
ADR(myIpAliasRedundancyObject);
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.
Inputs
Name IEC 61131 Type Description
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.
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.
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.
CommunicationDataResetCounter WORD Lists the number of times internal data has been reset due to delayed
responses or corrupted received data.
Inputs
Name IEC 61131 Type Description
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.
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.
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.
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.
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.
Port1Control(
ControlledInterface := Eth_02,
ControlledIPAlias := '10.55.55.55/24',
Backup := FALSE,
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.
RTAC Project 2
The user creates an Ethernet listening access point as shown in Figure 18.3.
Port1Control(
ControlledInterface := Eth_02,
ControlledIPAlias := '10.55.55.55/24',
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.2 presents the same logic as Code Snippet 18.2 shown in CFC rather
than an ST program.
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.
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.
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
);
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.
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.
Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.
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.
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.
ERROR
Enumeration Description
NO_ERROR No error.
Encoding
Enumeration Description
JSONType
Enumeration Description
Enumeration Description
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
JSONElement
Name IEC 61131 Type Description
Unions
Unions provide a means to interchange datatypes sharing the same memory
space to facilitate accessing data commonalities in a functional manner.
JSONElement
Name IEC 61131 Type Description
Functions
JSONElementToString (Function)
Converts a JSON element to WSTRING.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Interfaces
This library provides the following interfaces.
IJSONData
Interface for JSONData.
Clear (Method)
Clears the underlying data array.
Return Value
FindAllElementsByKey (Method)
Find all elements by key.
Inputs
Outputs
Return Value
FindFirstElementByKey (Method)
Find the first element in the data array by key.
Inputs
Outputs
jsonElement JSONElement The first element in the array with the requested
key.
Return Value
FindFirstValueByKey (Method)
Find the first value of the requested key.
Inputs
Outputs
Name IEC 61131 Type Description
jsonElement JSONElement The first element in the array with the requested
key.
Return Value
IEC 61131 Type Description
GetChildren (Method)
Get all children of an element.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
GetElementByIndex (Method)
Get an element by index.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
SetArray (Method)
Method to set an object.
Inputs
Return Value
SetBool (Method)
Method to set BOOL values.
Inputs
Return Value
SetKey (Method)
Method to set a key.
Inputs
Return Value
SetLReal (Method)
Method to set LREAL values.
Inputs
Return Value
SetLRealRounded (Method)
Method to set rounded LREAL values. Rounding mode: Round halfway from
zero.
Inputs
Return Value
IEC 61131 Type Description
SetLint (Method)
Method to set LINT values.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetNull (Method)
Method to set NULL values.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetObject (Method)
Method to set an object.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetString (Method)
Method to set WSTRING values.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Function Blocks
The JSON Utilities SL library provides various function block to construct and
parse data into respective structures.
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
Inputs
Name IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
Inputs
Name IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Inputs
Name IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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.
Outputs
Name IEC 61131 Type Description
SetKey (Method)
Method to set key in a JSON data.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetKeyWithArray (Method)
Method to set key with an array in a JSON data.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetKeyWithObject (Method)
Method to set key and object in a JSON data.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetKeyWithValue (Method)
Method to set key and value in a JSON data.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetKeyWithValueNull (Method)
Method to set key and null value in a JSON data.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetObject (Method)
Method to set an object value in a JSON data.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
SetKeyWithValue (Method)
Method to set value in a JSON data.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
JSONDataFactory (Class)
Factory with a heap based extendable memory pool.
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
Return Value
IEC 61131 Type Description
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.
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;
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.
Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.
g_udiMaxQueuedPackets UDINT 1000 The maximal count of queued packets that are
possible to store.
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
COMMUNICATION_MODE
Enumeration Description
FILTER_MODE
Enumeration Description
FILTER_OFF Turns the filter off and receives ALL subscribed telegrams.
MQTT_ERROR
Enumeration Description
NO_ERROR No error.
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.
ADD_MQTT_PACKET_COLLECTION_ERROR Collection Error while trying to add an MQTT packet 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.
CAN_NOT_ADD_ELEMENT_TO_QUEUE Cannot add the element to queue (maybe the maximum size has been
exceeded).
MQTT_QOS
Enumeration Description
QoS0 Send Message 1x, if disconnected from server then send can fail.
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).
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
ConvertUTF8toUTF16 (Function)
This function converts a STRING (UTF8) to a WSTRING (UTF16).
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
Inputs
xWillRetain BOOL TRUE: Saves the "Last Will" message on server. If Client subscribes later,
then it receives the last stack message from server.
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.
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.
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
Outputs
Name IEC 61131 Type Description
SetWebSocketOptions (Method)
Method to set additional websocket options if eCommunicationMode =
COMMUNICATION_ MODE.WEB_SOCKET.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Function Blocks
The MQTT Client SL library provides function blocks designed to be
implemented to provide unique subscription and publisher functionality.
Inputs
Name IEC 61131 Type Description
xReDelivery BOOL TRUE: When packet got already send and now
should got resend.
FALSE: First time.
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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.
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.
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
);
// 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 ))
);
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.
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.
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.
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
fun_ComplexCmp (Function)
This function compares two complex values based on magnitude.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
This function calculates the absolute value of both provided inputs and then
provides its return based on which one is larger.
fun_ComplexConjugate (Function)
This function returns the conjugate of the provided complex number.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Processing
This function performs the equivalent of providing a result
formatted as a single complex number.
fun_ComplexExp (Function)
Compute enum.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
Performs the calculation .
fun_ComplexLn (Function)
Compute the natural logarithm of num.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
fun_ComplexScale (Function)
This function multiplies a complex number by a scalar.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
fun_ComplexSubtract (Function)
This function returns the difference of two complex numbers.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
fun_ComplexZero (Function)
This function zeros the provided struct_ComplexRect.
Inputs/Outputs
Name IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
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.
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.
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
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);
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 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.
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
pt_myMathMatrixObject := ADR(myMathMatrixObject);
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
enum_MatrixState
Enumeration Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Processing
This function sets the return value to TRUE if all conditions for performing the
addition are met as follows:
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
toColumn UINT The column index of the column being copied to.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
This function sets the return value to TRUE if all conditions for performing the
copy are met as follows:
fun_MatrixDeterminant (Function)
This function calculates the determinant of a square matrix. The entire operation
will complete before the function returns.
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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.
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
Outputs
Name IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
Processing
This function sets the return value to TRUE if all conditions for performing the
calculation are met as follows:
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.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
This function verifies that the subtraction can be performed:
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
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.
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
toRow UINT The second addend and the location of the result.
Return Value
IEC 61131 Type Description
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.
Inputs
Return Value
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
Return Value
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.
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
Return Value
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
Return Value
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
Return Value
IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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.
Inputs/Outputs
Return Value
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
Return Value
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
Return Value
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
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
Return Value
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.
RowSwap (Method)
This method exchanges the position of two rows in a given matrix.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
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.
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
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
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
Inputs/Outputs
Return Value
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
Return Value
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.
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
Return Value
IEC 61131 Type Description
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.
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
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
Return Value
IEC 61131 Type Description
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.
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
Outputs
Return Value
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
LockMatrices (Method)
This method primes the class to perform the Gaussian elimination. It must be
called before each calculation to be performed.
Inputs/Outputs
Return Value
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
Outputs
Return Value
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.
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
Outputs
Return Value
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.
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
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
Return Value
IEC 61131 Type Description
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.
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
Outputs
Return Value
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.
Inputs/Outputs
Outputs
Return Value
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.
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
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
Return Value
IEC 61131 Type Description
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.
The operation will perform the next steps sub-operations of the complete
multiplication algorithm.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Processing
1. Validates that LockMatrices() has been successfully called.
2. Multiplies matrix1 by matrix2.
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
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
The operation will perform work for the next duration microseconds toward the
complete subtraction algorithm.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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
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
Inputs/Outputs
Return Value
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
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.
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_MatrixAdd - 2x2 17 7 1
fun_MatrixAdd - 8x8 66 46 4
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_MatrixGaussianElim - 2x2 76 39 2
fun_MatrixInvert - 2x2 74 48 3
fun_MatrixMultiply - 2x2 26 15 2
fun_MatrixSubtract - 2x2 13 6 1
fun_MatrixSubtract - 8x8 90 41 4
fun_MatrixTranspose - 2x2 8 4 1
fun_MatrixTranspose - 8x8 29 12 1
fun_Matrix_ATA - 2x2 26 15 1
fun_NewMatrix - 8x8 87 39 5
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.
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;
Row : UINT;
Col : UINT;
END_VAR
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;
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
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
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;
(* 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
// 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 *)
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);
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.
enum_Asn1ClassType
Enumeration Value Description
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
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
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
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
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.
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
Return Value
IEC 61131 Type Description
Processing
The fun_DecodeAsn1_Boolean() function does the following:
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."
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The fun_DecodeAsn1_Integer() function does the following:
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."
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The fun_DecodeAsn1_Enumerated() function does the following:
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.
Inputs
Name IEC 61131 Type Description
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
Processing
The fun_DecodeAsn1_Object_Identifier() function does the following:
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
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The fun_SerializeAsn1_Boolean() function does the following:
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The fun_SerializeAsn1_Integer() function does the following:
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_Enumerated
Place the integer value provided as the next entry in an ASN.1 BER message.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The fun_SerializeAsn1_Enumerated() function does the following:
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The fun_SerializeAsn1_Real() function does the following:
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
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
Return Value
IEC 61131 Type Description
Processing
The fun_SerializeAsn1_Object_Identifier() function does the
following:
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.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The fun_SerializeAsn1_Bit_String() function does the following:
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
Return Value
IEC 61131 Type Description
Processing
The fun_BeginAsn1Constructed_Bit_String() function:
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
Return Value
IEC 61131 Type Description
Processing
The fun_AppendAsn1_Eoc() function does the following:
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.
Inputs/Outputs
Name IEC 61131 Type Description
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:
This function encodes a raw byte vector in base64-MIME. The output encoded
will be approximately 133% the size of source.
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
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.
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
Outputs
Return Value
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
Return Value
Pop (Method)
This method provides a copy of the last item in the vector and removes that
element from the vector.
Outputs
Return Value
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
Return Value
IEC 61131 Type Description
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
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.
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.
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
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.
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*)
// Iterator counts.
ListPosition : UDINT;
ObjectCount : UDINT;
// 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
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;
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
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;
// Counting variable.
i : UDINT;
END_VAR
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.
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);
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
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.
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.
initialTime timestamp_t Time stamp value to use for initialization if settingsChange is FALSE.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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.
initialTime timestamp_t Time stamp value to use for initialization if settingsChange is FALSE.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
EventTime timestamp_t The date and time that Minimum 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, 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
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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
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
Outputs
Name IEC 61131 Type Description
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
Inputs
Name IEC 61131 Type Description
Y SPS Terminal Y.
Z SPS Terminal Z.
Outputs
Name IEC 61131 Type Description
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
Inputs
Name IEC 61131 Type Description
Y SPS Terminal Y.
Outputs
Name IEC 61131 Type Description
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
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
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.
PROGRAM prg_Maximum_Retain_Example
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
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.
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;
PROGRAM prg_Minimum_Example_Retain
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
MinThreshold : REAL := 50000;
RETAIN_VERSION := VERSION;
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;
PROGRAM prg_Energy_Example_Retain
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
Threshold : REAL;
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.
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;
PROGRAM prg_Demand_Example_Retain
VAR
En : BOOL;
Value : REAL;
Reset : BOOL;
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
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;
//The KYZ blocks ignore their initial values because settingsChange is true.
KYZ_12bit : fb_KYZ( settingsChange := TRUE, initialCV := DNP_Counter1,
initialROV := 0, maxValue := 4095);
END_VAR
PROGRAM prg_KYZ_Retain_Example
VAR
//Block inputs
DI_Y_Terminal : SPS;
DI_Z_Terminal : SPS;
Enable : BOOL;
Reset : BOOL;
KY
Objective
A user has one input connected to the Y 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.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;
PROGRAM prg_KY_Retain_Example
VAR
//Terminal for Y pulses
DI_Y_Terminal : SPS;
//Enabling and Rest Conditions
Enable : BOOL;
Reset : BOOL;
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
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.
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);
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
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).
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.
➤ 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
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.
VoltageDiffMax REAL Maximum absolute value of the difference between synchronizing and reference
voltage magnitudes.
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.
Outputs
Name IEC 61131 Type Description
SynchCheckLogicEnabled BOOL The synchronism-check logic is enabled. For more details, refer to Processing
on page 749.
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.
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.
Equation 25.1
➤ AdvancedAngle:
Equation 25.2
➤ VSynchAdv:
➢ VSynchAdv.MAG = VSynchCompensated.MAG
➢ VSynchAdv.ANG = VSynchCompensated.ANG + AdvancedAngle
Equation 25.3
Inputs
Name IEC 61131 Type Description
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.
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).
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
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.
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.
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
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
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.
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
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.
Processing
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
CloseSignalLocal BOOL Close command signal issued locally (e.g., via the SEL Touchscreen).
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.
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
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
Timer Symbols
The timer symbols used in the logic diagrams follow the conventions shown
below:
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.
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
Assumptions
This example assumes the following:
➤ 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.
➤ 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.
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
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
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.
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.
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.
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.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.
Figure 26.6 All Objects Defined for One Side of the Substation
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.
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
enum_ValueSource
Enumeration Description
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
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.
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.
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.
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
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.
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:
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.
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.
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
Return Value
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.
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
Inputs/Outputs
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
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.
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.
Inputs/Outputs
Return Value
Processing
This method is intended to be called before processing to associate a data
location with the switch. It performs the following actions:
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
Return Value
Processing
This method is intended to be called before processing to associate a data
location with the switch. It performs the following actions:
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
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.
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.
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.
Inputs/Outputs
Return Value
Processing
This method is intended to be called before processing to associate a data
location with the breaker. It performs the following actions:
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
Return Value
Processing
This method is intended to be called before processing to associate a data
location with the breaker. It performs the following actions:
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
Outputs
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
Outputs
Name IEC 61131 Type Description
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.
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
Outputs
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
Outputs
pt_TerminalA POINTER TO class_Terminal The first terminal of this line, used to attach
it inside the model.
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
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
Return Value
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
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
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.
This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.
Inputs
Return Value
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_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
Return Value
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
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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
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.
This type of bootstrap method must be called after tying terminals and before
calling any bootstrap_Add methods.
Inputs
Name IEC 61131 Type Description
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
Return Value
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
Return Value
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
Return Value
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.
Inputs
Return Value
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_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
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
Outputs
Name IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
class_TapChanger
Instantiate one instance of this class for each class_PowerTransformerEnd
requiring a dynamic transformer ratio.
Inputs
Name IEC 61131 Type Description
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.
Outputs
Name IEC 61131 Type Description
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
ratioModifier INS The variable that will report the step position of the
tap changer.
Return Value
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
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.
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
Return Value
IEC 61131 Type Description
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
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
Return Value
Processing
This method is intended to be called before processing to associate equipment
with this container. It performs the following actions:
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.
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
Outputs
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
enable BOOL The variable that will report the state of the manual
override of this measurement.
Return Value
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
enable BOOL The variable that will report the state of the manual
override of this measurement.
Return Value
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
enable BOOL The variable that will report the state of the manual
override of this measurement.
Return Value
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.
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
Outputs
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
enable BOOL The variable that will report the state of the manual
override of this measurement.
Return Value
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.
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.
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_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
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
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
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
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
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
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
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
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.
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 Results
Platform (time in µs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555
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.
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)),
(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
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();
:= ['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),
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]),
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
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
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
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();
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,
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
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)),
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();
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),
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],
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
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.
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
Enumeration Description
DLUB Dead-Line, Undefined-Bus (bus voltage is above dead threshold, but not
above live threshold)
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
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
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.
Outputs
Name IEC 61131 Type Description
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.
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
where:
Inputs
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
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.
Processing
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.
Table 27.1 IEC Equations Associated With Predefined Inverse-Time Overcurrent Function Blocks
Curve Function Block Name Operating Time (sec) Reset Time (sec)
Table 27.2 U.S. Equations Associated With Predefined Inverse-Time Overcurrent Function Blocks
Curve Function Block Name Operating Time (sec) Reset Time (sec)
U2–Inverse fb_InverseTimeCurveU2
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
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.
Outputs
Name IEC 61131 Type Description
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.
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.
Inputs
Name IEC 61131 Type Description
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
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
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.
Processing
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Processing
The OverVoltage and ENO outputs are computed based on the input states
according to the following logic diagram:
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Processing
The UnderVoltage and ENO outputs are computed based on the input states
according to the following logic diagram:
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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).
Inputs
Name IEC 61131 Type Description
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.
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
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.
Processing
This section describes the formulas used by this function block to calculate the
outputs.
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Δ.
Equation 27.3
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
Equation 27.9
Equation 27.10
Equation 27.11
Equation 27.12
Equation 27.13
where:
TCalculatedk ≡ CalculatedTemp
TMaxConductor ≡ MaxConductorTemp
TReference ≡ ReferenceAmbientTemp
TAmbient ≡ AmbientTemp
I ≡ MeasuredCurrent
In ≡ RatedCurrent
On each execution of the function block, a new estimated line temperature - TΔk
is calculated using Equation 27.13.
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
Inputs
Name IEC 61131 Type Description
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.
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
PickupTimeout BOOL The overfrequency pickup delay based on the PickupDelay and DropoutDelay inputs.
Processing
Inputs
Name IEC 61131 Type Description
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.
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
PickupTimeout BOOL The underfrequency pickup delay based on the PickupDelay and DropoutDelay inputs.
Processing
Inputs
Name IEC 61131 Type Description
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.
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
PickupTimeout BOOL The frequency protection element delayed based on the PickupDelay and DropoutDelay
inputs.
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.
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.
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.
Inputs
Name IEC 61131 Type Description
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
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
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.
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:
➣ Otherwise,
Equation 27.16
The voltage supervision threshold input can be calculated using the desired
undervoltage set point.
Equation 27.17
Equation 27.18
Equation 27.19
Next, the rms magnitude Valpha can be derived from the following equation.
Equation 27.20
Equation 27.21
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
➤ 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.)
➤ fb_BusLineVoltageCheck
➤ fb_OverVoltage
➤ fb_UnderVoltage
Benchmark Results
Platform (time in µs)
Operation Tested SEL-3530
SEL-3555
SEL-2241
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.
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;
// 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);
O50PT := AProtection.PickupTimeout OR
BProtection.PickupTimeout OR
CProtection.PickupTimeout;
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
Cphase.PickupTimeOut;
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
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
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();
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
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
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
Assumptions
This example assumes the following:
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;
ReasonForBadQuality : STRING;
END_VAR
// 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);
Assumptions
This example assumes the following:.
Solution
Code Snippet 27.6 prg_UnderFrequencyProtectionScheme
PROGRAM prg_UnderFrequencyProtectionScheme
VAR
SlowUnderFreqElement: fb_FrequencyElement;
FastUnderFreqElement : fb_FrequencyElement;
END_VAR
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.
All queues in this library assume that all elements within the queue are the same
size.
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).
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);
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.
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
Enumeration Description
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
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
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
Return Value
IEC 61131 Type Description
Interfaces
This library provides the following interface.
I_Queue (Interface)
This interface is implemented by any class that provides a queue 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).
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
EraseFront (Method)
This method deletes the specified number of elements from the front of the
queue.
Inputs
Return Value
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.
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
Return Value
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
Return Value
UDINT The number of elements successfully copied and removed from the
queue. Zero if the queue was not modified.
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.
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
Processing
All elements are removed from the queue.
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.
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
Inputs
Return Value
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
pt_source POINTER TO BYTE A pointer to the source from which the elements
are copied.
Return Value
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.
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
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.
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
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
FrontByte (Method)
This method provides the element at the front of the deque without modifying
the deque.
Outputs
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
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
Return Value
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.
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
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.
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
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
FrontDword (Method)
This method provides the element at the front of the deque without modifying
the deque.
Outputs
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
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
Return Value
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.
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
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.
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
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
FrontLword (Method)
This method provides the element at the front of the deque without modifying
the deque.
Outputs
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
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
Return Value
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.
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
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.
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
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
FrontLreal (Method)
This method provides the element at the front of the deque without modifying
the deque.
Outputs
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
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
Return Value
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.
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
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.
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
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
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
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.
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.
Return Value
IEC 61131 Type Description
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.
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.
Return Value
IEC 61131 Type Description
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
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.
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
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
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
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.
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
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
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.
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
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).
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.
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
Return Value
IEC 61131 Type Description
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
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.
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
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.
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
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.
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
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.
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.
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
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
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
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
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
PopFront - Byte 1 5 8
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
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
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
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 Up - LReal 3 34 84
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.
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.
4. Five values are popped off of the front of the deque and into an array.
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.
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
Objective
This example comprises the following steps:
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.
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
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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_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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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).
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
Return Value
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.
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
➤ 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.
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
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.
Solution
Code Snippet 29.1 prg_SortInt
PROGRAM prg_SortInt
VAR
intArray : ARRAY [1..5] OF INT;
END_VAR
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.
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
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.
struct_RecordingTriggerOutputInfo
Name IEC 61131 Type Description
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
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).
Outputs
Name IEC 61131 Type Description
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.
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
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).
Outputs
Name IEC 61131 Type Description
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.
➤ 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.
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
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
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):
➤ 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
Inputs
Name IEC 61131 Type Description
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
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
➤ fb_HighThreshold
➤ fb_LowThreshold
➤ fb_RateOfChange
➤ fb_DigitalTriggers
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.
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);
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)
HighTrigger_level(InSignal := SEL_16AI_1_ECAT.INPUT_VALUE_001.instMag);
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);
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 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);
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;
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:
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);
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.
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);
Enumerations
Enumerations make code more readable by allowing a specific number to have a
readable textual equivalent.
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
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
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
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 (\
\, /./, /../).
FileType enum_FileType TXT, HTML, or CSV. Defines the file name extension. Does not affect formatting
of report content.
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
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
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
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.
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.
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.
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);
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
Aliases
This section lists aliases that this library defines.
SESSION_HANDLE
Alias IEC 61131 Type
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.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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).
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
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
Processing
The Open() method does the following:
Close (Method)
Unconfigure the class_UdpSocket to disable communication.
Processing
The Close() method does the following:
SendData (Method)
Send a block of data to the socket.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
Inputs/Outputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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).
bootstrap_SetLocalIP (Method)
Perform a one-time setting of the local IP address and port this socket will use.
Inputs
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.
Return Value
IEC 61131 Type Description
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
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
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.
Inputs
Processing
The Close() method does the following:
SendData (Method)
Send a block of data to the socket.
Inputs
Return Value
Processing
The SendData() method does the following:
SendQueuedData (Method)
Send a block of data to the socket from the front of a queue.
Inputs/Outputs
Return Value
Processing
The SendQueuedData() method does the following:
ReceiveData (Method)
Appends a block of data from the socket to data.
Inputs
Inputs/Outputs
Return Value
Processing
The ReceiveData() method does the following:
ReceiveToQueue (Method)
Pushes a block of data from the socket to the back of queue.
Inputs
Inputs/Outputs
Return Value
Processing
The ReceiveToQueue() method does the following:
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
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).
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.
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
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
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.
Return Value
IEC 61131 Type Description
Processing
The Open() method does the following:
Close (Method)
Unconfigure the class_TcpServer to disable communication.
Inputs
Name IEC 61131 Type Description
Processing
The Close() method does the following:
AcceptNextSession (Method)
Accept the next new inbound data session. This does not change the active
session.
Return Value
IEC 61131 Type Description
Processing
The AcceptNextSession() method does the following:
SetSession (Method)
Select the session from which the class reads data from and replies to.
Inputs
Return Value
Processing
The SetSession() method does the following:
GetSessionInfo (Method)
Get the IP address and port number related to a session handle.
Inputs
Outputs
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
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
Return Value
IEC 61131 Type Description
Processing
The SendData() method does the following:
➤ Does nothing if no valid session has been selected.
➤ Validates access to the pointer provided.
SendQueuedData (Method)
Send a block of data to the socket from the front of a queue.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The SendQueuedData() method does the following:
ReceiveData (Method)
Receive a block of data from the active session.
Inputs
Name IEC 61131 Type Description
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The ReceiveData() method does the following:
ReceiveToQueue (Method)
Pushes a block of data from the socket to the back of queue.
Inputs
Inputs/Outputs
Return Value
Processing
The ReceiveToQueue() method does the following:
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
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.
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.
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
class_UdpSocket.Close 13 65 117
class_UdpSocket.ReceiveFrom 12 90 200
class_TcpClient.SetIP 1 1 1
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.AcceptNextSession 20 97 130
class_TcpServer.SetSession 2 4 6
class_TcpServer.GetSessionInfo 2 5 14
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.
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;
// Initialization variables.
SocketInitialized : BOOL := FALSE;
LocalIP : SELEthernetController.INADDR;
DestIP : SELEthernetController.INADDR;
END_VAR
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.
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;
Assumptions
For this use case, we assume that the server doubles any data that are sent to it.
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;
// IP address variables.
LocalIP : SELEthernetController.INADDR;
DestIP : SELEthernetController.INADDR;
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;
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
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.
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;
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
EXIT;
END_IF
END_IF
END_FOR
TcpServer.SendQueuedData(Sessions[i].SendDeque);
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.
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
Processing
At the first call of this function, it randomly seeds itself. It will continually
return pseudorandom values with each use.
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
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
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.
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.
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
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
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
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);
Supported Devices
This library contains simulators for the following devices:
➤ SEL-351
Version 3.5.0.1 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_PointType
This enumeration defines all possible point types for a relay.
Enumeration Description
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
struct_SEL351_Analog
This structure defines the analog points available on an SEL-351. For example,
this structure might contain the following:
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.
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).
Close (Method)
Closes the session to the client.
Inputs
ReadData (Method)
Read data from the client.
Inputs
pt_destination POINTER TO BYTE Pointer to where the incoming data are written.
Return Value
WriteData (Method)
Write data to the client.
Inputs
Name IEC 61131 Type Description
pt_source POINTER TO BYTE Pointer from where the outgoing data are read.
Return Value
IEC 61131 Type Description
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).
AddSessionProvider (Method)
Adds an I_SessionProvider to this session manager.
Inputs
Name IEC 61131 Type Description
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.
Return Value
IEC 61131 Type Description
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
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).
I_SELServerAnalogPoint
This interface defines common methods unique to analog points. This interface
extends 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).
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.
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
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).
Initialize (Method)
This method initializes the point.
Inputs
Name IEC 61131 Type Description
class_SELServerFloat32
This class defines an analog point represented as a 32-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).
Initialize (Method)
This method initializes the point.
Inputs
Name IEC 61131 Type Description
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).
Initialize (Method)
This method initializes the point.
Inputs
Name IEC 61131 Type Description
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).
Initialize (Method)
This method initializes the point.
Inputs
Name IEC 61131 Type Description
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.
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).
Initialize (Method)
This method initializes the point.
Inputs
class_SEL351ServerSimulator
This class implements a server simulating an SEL-351 relay with firmware
version R515. The following ASCII commands are supported:
Some commands have optional parameters that may not be supported by the
simulator.
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).
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
Outputs
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
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.
Inputs
Return Value
DeleteEvent (Method)
This method deletes an event from the simulator that was created with
CreateEvent().
Inputs
recNum UINT The record number for the event as provided by the
CHI command.
Return Value
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
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:
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();
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
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);
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
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
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
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);
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.
g_p_MaxIec61131StringSize UDINT 255 The largest size IEC 61131 string that this library can
convert from/to.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Processing
The fun_ByteIsNumeric function performs the following action:
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
Return Value
IEC 61131 Type Description
Processing
The fun_ByteIsAlphaNumeric function performs the following action:
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
Return Value
IEC 61131 Type Description
Processing
The fun_LowercaseByte function performs the following action:
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
Return Value
IEC 61131 Type Description
Processing
The fun_UppercaseByte function performs the following action:
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).
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
Return Value
IEC 61131 Type Description
Processing
The FromString method performs the following actions:
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
Return Value
IEC 61131 Type Description
Processing
The FromByteArray method performs the following actions:
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
Return Value
Processing
The CopyTo method performs the following actions:
ToString (Method)
This method outputs an IEC 61131 string representation of the data being stored
within the SELString.
Return Value
Processing
The ToString method performs the following actions:
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
Return Value
Processing
The ToByteArray method performs the following actions:
Replace (Method)
This method replaces every occurrence of the string before with the string after.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The Replace method performs the following actions:
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
Return Value
IEC 61131 Type Description
Processing
The Split method performs the following actions:
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.
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
Return Value
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
numBytes UDINT The number of bytes to copy from the byte array.
Return Value
Processing
The AppendByteArray method performs the following actions:
AppendString (Method)
This method appends the characters of the input, str, onto the end of this
class_SELString.
Inputs/Outputs
Return Value
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Processing
The Insert method performs the following actions:
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
Inputs/Outputs
Return Value
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:
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
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
Processing
The Clear method performs the following actions:
Item (Method)
This method returns the character at the requested index.
Inputs
Return Value
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:
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
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.
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.
Inputs/Outputs
Return Value
Processing
The ToAsciiHex method performs the following actions:
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
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
Processing
The FromAsciiHex method performs the following actions:
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
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
Processing
The StartsWith method performs the following actions:
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.
Inputs
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
Processing
The EndsWith method performs the following actions:
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.
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
Return Value
Processing
The LeftJustify method performs the following actions:
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
Return Value
IEC 61131 Type Description
Processing
The RightJustify method performs the following actions:
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
Return Value
IEC 61131 Type Description
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).
Append (Method)
This method adds the requested string to the end of the list.
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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
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
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().
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
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
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
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
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.
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.
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.
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.
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 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().
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 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 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.
FromString Replace 9 89
FromString Depopulate 16 79
ToString 8 75
FromByteArray Replace 7 75
FromByteArray Depopulate 16 77
ToByteArray 7 65
Trim No Whitespace 11 87
Size 1 1
Append 1 4
AppendString 49 272
Prepend 1 4
PrependString 45 276
Insert Middle 1 6
Find Max 8 71
Clear 16 77
Item Middle 1 4
Begin 1 1
End 1 1
Position Middle 1 4
Next 1 1
Previous 1 1
Append
This test calls Append() on a class_SELStringList of g_p_StringSize
class_SELStrings.
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.
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 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.
Append 1 4
Insert Middle 2 14
RemoveLast 17 80
Size 1 1
Item Middle 1 4
Begin 1 1
End 1 1
Position Middle 1 4
Next 1 1
Previous 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.
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
ToString
Code Snippet 35.2 SELString ToString Example
PROGRAM prg_ToStringExample
VAR
normalString : STRING := 'This is a normal string';
selString : class_SELString;
END_VAR
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
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
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;
firstString : STRING;
secondString : STRING;
END_VAR
Trim
Code Snippet 35.6 SELString Trim Example
PROGRAM prg_TrimExample
VAR
selString : class_SELString;
END_VAR
Size
Code Snippet 35.7 SELString Size Example
PROGRAM prg_SizeExample
VAR
selString : class_SELString;
size : UDINT;
END_VAR
Append
Code Snippet 35.8 SELString Append Example
PROGRAM prg_AppendExample
VAR
firstString : class_SELString;
secondString : class_SELString;
END_VAR
Prepend
Code Snippet 35.9 SELString Prepend Example
PROGRAM prg_PrependExample
VAR
firstString : class_SELString;
secondString : class_SELString;
END_VAR
Insert
Code Snippet 35.10 SELString Insert Example
PROGRAM prg_InsertExample
VAR
firstString : class_SELString;
secondString : class_SELString;
END_VAR
Find
Code Snippet 35.11 SELString Find Example
PROGRAM prg_FindExample
VAR
firstString : class_SELString;
secondString : class_SELString;
index : DINT;
END_VAR
Clear
Code Snippet 35.12 SELString Clear Example
PROGRAM prg_ClearExample
VAR
selString : class_SELString;
END_VAR
Item
Code Snippet 35.13 SELString Item Example
PROGRAM prg_ItemExample
VAR
selString : class_SELString;
character : BYTE;
END_VAR
CopyTo
Code Snippet 35.15 SELString CopyTo Example
PROGRAM prg_CopyTo
VAR
selString : class_SELString;
copiedSELString : class_SELString;
END_VAR
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
FromAsciiHex
Code Snippet 35.18 SELString FromAsciiHex Example
PROGRAM prg_FromAsciiHex
VAR
stringInHEX : STRING := '41';
hexSELString1 : class_SELString;
asciiSELString1 : class_SELString;
hexSELString2 : class_SELString;
asciiSELString2 : class_SELString;
stringInAscii1 : STRING;
stringInAscii2 : STRING;
END_VAR
Strip
Code Snippet 35.19 SELString Strip Example
PROGRAM prg_StripExample
VAR
selString : class_SELString;
END_VAR
LeftStrip
Code Snippet 35.20 SELString LeftStrip Example
PROGRAM prg_LeftStripExample
VAR
selString : class_SELString;
END_VAR
RightStrip
Code Snippet 35.21 SELString RightStrip Example
PROGRAM prg_RightStripExample
VAR
selString : class_SELString;
END_VAR
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;
selStringList : class_SELStringList;
listSize : UDINT;
END_VAR
Append
Code Snippet 35.25 SELStringList Append Example
PROGRAM prg_AppendExample
VAR
selString : class_SELString;
selStringList : class_SELStringList;
END_VAR
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
RemoveLast
Code Snippet 35.27 SELStringList RemoveLast Example
PROGRAM prg_RemoveLastExample
VAR
selString1 : class_SELString;
selString2 : class_SELString;
selStringList : class_SELStringList;
END_VAR
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
Item
Code Snippet 35.29 SELStringList Item Example
PROGRAM prg_ItemExample
VAR
selStringList : class_SELStringList;
firstString : class_SELString;
middleString : class_SELString;
lastString : class_SELString;
middleString : class_SELString;
lastString : class_SELString;
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
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.
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.
READING_SETTINGS 2 SEL Axion module settings are being read over the EtherCAT network.
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
enum_RegExOutputTypes
Enumeration Description
enum_SEL2488AntStatus
This enumeration defines states for the antenna status of an SEL-2488 Satellite-
Synchronized Network Clock polled over SNMP.
OK 1 OK status.
enum_SEL2488DSTStatus
This enumeration defines states for the daylight-saving time function of an
SEL-2488 polled over SNMP.
enum_SEL2488IPAddrType
This enumeration defines states for the IP address type of an Ethernet port on an
SEL-2488 polled over SNMP.
enum_SEL2488MediaType
This enumeration defines states for the Ethernet port media of an SEL-2488
polled over SNMP.
enum_SEL2488PortStatus
This enumeration defines states for the Ethernet port status of an SEL-2488
polled over SNMP.
enum_SEL2488PTPState
This enumeration defines states for the PTP state of an SEL-2488 polled over
SNMP.
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
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
PI REAL 3.14159265358979323846
Numeric value for mathematical
constant Pi
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.
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Processing
➤ Compares each element of the string using fun_IsValidHexChar.
➤ Returns TRUE if all characters in STRING are valid hexadecimal digits;
otherwise, returns FALSE.
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
Return Value
IEC 61131 Type Description
aReal := 50.123;
anLreal := 5012.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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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.
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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
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
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
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
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
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
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
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.
➤ 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
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
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
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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:
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
REAL The REAL variable whose angle has been wrapped between 0
and 360 degrees.
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:
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
REAL The REAL variable whose angle has been wrapped between –
180 and 180 degrees.
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
STRING(4) The hex string representing the output sum of all input bytes.
InString := '"FID=SEL-351-7-R405-V0-Z010006-D20120203",';
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
SetVal BOOL The value with which to overwrite the InPattern bit
at BitIndex.
Return Value
IEC 61131 Type Description
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).
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
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
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
Return Value
IEC 61131 Type Description
VarByte := HEX_STRING_TO_BYTE('9C');
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
Return Value
IEC 61131 Type Description
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
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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'.
➤ 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).
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
REAL The apparent power calculated from input current and voltage.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
CMV The apparent power magnitude and angle calculated from input
current and voltage.
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.
Return Value
IEC 61131 Type Description
REAL The power factor calculated from input voltage and current angles.
Pf := ComposePF(60, 0, 10);
Processing
➤ The power factor is calculated using the formula shown above.
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
Return Value
IEC 61131 Type Description
MV The power factor calculated from input voltage and current angles.
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.
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
Return Value
IEC 61131 Type Description
REAL The reactive power calculated from input voltage and current.
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
REAL The real power calculated from input voltage, current, and power
factor.
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
Return Value
IEC 61131 Type Description
MV The real power calculated from input voltage, current, and power
factor.
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
Return Value
IEC 61131 Type Description
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.
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
Return Value
IEC 61131 Type Description
REAL The apparent power calculated from input real and reactive power
magnitudes.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
REAL The reactive (imaginary) power magnitude calculated from input real
and apparent power magnitudes.
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
REAL The real (active) power magnitude calculated from input real and
apparent power magnitudes.
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
Return Value
IEC 61131 Type Description
MV The real (active) power magnitude calculated from input real and
apparent power magnitudes.
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
MV The power factor calculated from the relation between real power and
apparent power.
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
Return Value
IEC 61131 Type Description
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.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Vline := VLN_TO_VLL(10);
Processing
➤ The line-to-line voltage magnitude is calculated using the formula shown
above.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Processing
➤ The line-current magnitude is calculated using the formula shown above.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
Processing
➤ The phase-current magnitude is calculated using the formula shown
above.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
P := HP_TO_WATTS(1000);
Processing
➤ The power (in units of horsepower) is multiplied by the conversion factor
to evaluate the power in Watts.
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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°.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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°.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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°.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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°.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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. *)
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.
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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. *)
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
Outputs
Name IEC 61131 Type Description
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.
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.
256 'TRIG'
512 'PULSE'
1024 'TRIP'
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'
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
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.
Function Blocks
This library provides the PID function block and the related CascadeControl
function block.
The PID logic computes the actuator output by summing up three different
control actions:
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.
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.
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.
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
Source of
Control Action PID Equation
Derivative
Error Direct/Reverse
PV Reverse (E = SP − PV )
Direct (E = PV − SP)
PID Data
Units Description
Term Type
Inputs
Outputs
Iterm REAL
Integral Term.
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.
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).
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:
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:
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.
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:
When the PID output returns to a value in the range between OutMIN and
OutMAX, the integral calculation resumes.
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
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.
In order to use this function block, set up a cascade control system using the
CascadeControl function block as follows:
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
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.
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.
Inputs
Name IEC 61131 Type Description
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.
Outputs
Name IEC 61131 Type Description
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.
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
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
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.
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.
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
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
PickupValue LREAL The pickup value. When the input signal is greater
than this value, the comparator output asserts.
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.
Processing
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
➤ SEL-3555
➢ R143-V0 firmware
➤ SEL-3555
➢ Dual-core Intel i7-3555LE processor
➢ 4 GB ECC RAM
➢ R143 firmware
Benchmark Results
Platform (time in ns)
Operation Tested Metric
SEL-3505 SEL-3530 SEL-3555
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.
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
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
// 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'
// 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.
➤ 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).
// 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
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.
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.
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
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.
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.
// 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
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;
// Load outputs
PADM1_OK := PADM1.Enabled;
PADM1_Angle_Difference := PADM1.AngleDiff;
PADM1_Warning := PADM1.Alarm1;
PADM1_Alarm := PADM1.Alarm2;
// Static inputs
Min_Asserted : REAL := 4.5;
Max_Deasserted : REAL := 1;
END_VAR
VAR_OUTPUT
InputAsserted : SPS;
END_VAR
// Load output
InputAsserted := ttl1.Result;
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.
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.
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.
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
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.
Equation 37.1
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
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.
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.
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
Outputs
Name IEC 61131 Type Description
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
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
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
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.
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
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 Results
Platform (time in μs)
Operation Tested
SEL-3505 SEL-3530 SEL-3555
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 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
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
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.
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
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.
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.
➤ 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.
// 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);
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
Enumeration Description
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)
ifIndex UDINT The index the manufacturer provides from OID 1.3.6.1.2.1.2.2.1.1.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.
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:
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).
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
Outputs
Name IEC 61131 Type Description
TimeSinceLastMessage TIME The elapsed time since the last message from
this device.
GetInterfaceStatus (Method)
This method provides the status of the specified interface.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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.
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.
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.
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).
Initialization Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
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
Return Value
IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
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
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.
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_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.
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
// Run the SnmpManager, which is responsible for doing all the required work.
SnmpManager.Run();
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.
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
struct_syslogMessageFormat
Name IEC 61131 Type Description
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.
enum_facility
This enumeration lists the different facility levels allowed in syslog.
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.
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
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.
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.
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 := '');
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.
// 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);
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).
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.
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.
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.
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
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.
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.
Inputs
Name IEC 61131 Type Description
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.
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.
1 Top of second
60 Top of minute
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.
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.
where:
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.
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
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.
ProfileManager Min 23 18 1
σ 2875 152 34
1 ProfileIntervalRecorder Min 26 19 1
σ 285 176 8
ProfileManager Min 25 18 1
σ 5422 214 42
4 ProfileIntervalRecorders Min 84 60 1
σ 834 641 14
ProfileManager Min 27 18 1
σ 4416 274 42
σ 3972 1668 51
ProfileManager Min 24 19 1
σ 1259 259 43
1 ProfileTriggerRecorder Min 25 19 1
σ 263 131 6
ProfileManager Min 25 19 1
σ 3505 259 46
4 ProfileTriggerRecorders Min 87 60 2
σ 876 473 13
ProfileManager Min 27 18 1
σ 1284 310 5
σ 2496 1201 37
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.
Global Constants
This section lists the global constants provided for interacting with the web
client.
Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.
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
REQUEST_TYPE
Enumeration Description
Enumeration Description
ERROR
Enumeration Description
NO_ERROR No error.
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
KeyValue
Name IEC 61131 Type Description
HttpResult
Name IEC 61131 Type Description
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
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
Return Value
IEC 61131 Type Description
ConvertUTF8toUTF16 (Function)
This function converts a STRING (UTF8) to a WSTRING (UTF16).
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
BASE64_DECODE (Function)
This function decodes a Base-64 string.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
BASE64_ENCODE (Function)
This function encodes a Base-64 string.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
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
Inputs/Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
FindJSONValue2 (Function)
Finds the corresponding value of a key in a JSON WSTRING. Objects and
arrays are NOT supported.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
URL_ENCODE_STRING (Function)
Encodes a STRING into a format appropriate for URLs.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
URL_ENCODE_STRING2 (Function)
Encodes a STRING into a format appropriate for URLs.
Inputs
Name IEC 61131 Type Description
URL_ENCODE_WSTRING (Function)
Encodes a WSTRING into a format appropriate for URLs.
Inputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
URL_ENCODE_WSTRING2 (Function)
Encodes a WSTRING into a format appropriate for URLs.
Inputs
Name IEC 61131 Type Description
Interfaces
This library provides the following interfaces.
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).
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).
Function Blocks
The Web Client SL library provides various function blocks to interact with the
respective web client functionalities.
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
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
NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.
Inputs
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
NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.
Inputs
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
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
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
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.
NOTE
HTTPS connections are supported in the web client in RTAC firmware versions
R153 and later. Prior versions only support HTTP connections.
Inputs
Outputs
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.
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.
Assumptions
The following assumptions are made:
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;
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;
fullyQualifiedURL : STRING(255);
xExecute := runNow,
sURL := fullyQualifiedURL,
eRequestType := requestType,
eContentType := contentType,
httpResult => result
);
Assumptions
The following assumptions are made:
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;
fullyQualifiedURL : STRING(255);
// fullyQualifiedURL := http://httpbin.org/anything
client(
xExecute := runNow,
sURL := fullyQualifiedURL,
eRequestType := requestType,
eContentType := contentType,
pwsPostValue := ADR(postData),
httpResult => result
);
Assumptions
This example assumes the following:
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;
eContentType := contentType,
xUseTLS := TRUE,
itfTLSContext := tlsContext,
httpResult => result
);
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.
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.
Enumeration Description
PAYLOAD_POINTER_IS_NULL The payload pointer is null, although the payload size is greater than 0.
FRAME_TYPE
Enumeration Description
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
Interfaces
This library provides the following interface.
IWebSocketClient
Interface of the WebSocket client.
Read (Method)
Read incoming messages.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Write (Method)
Send messages to a WebSocket server.
Inputs
Name IEC 61131 Type Description
NOTE
It can take more than one cycle to send a message if the payload is greater
than the maximum buffer size.
Outputs
Return Value
Function Blocks
The Web Socket Client SL library provides various function block to interact
with the respective web client functionalities.
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.
Inputs
Outputs
Name IEC 61131 Type Description
Inputs
Name IEC 61131 Type Description
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
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.
Inputs
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.
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
Outputs
Name IEC 61131 Type Description
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
Outputs
Name IEC 61131 Type Description
Return Value
IEC 61131 Type Description
Write (Method)
Sends messages to a WebSocket server. This method sends the payload pData
with the size udiSize to the server.
Inputs
NOTE
It can take more than one cycle to send a message if the payload is greater
than the maximum buffer size.
Outputs
Return Value
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.
Assumptions
The following assumptions are made:
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
sendInterval();
IF sendInterval .Q THEN
// Write to the websocket
result_write := client.Write (
pData := ADR ( payload ),
udiSize := TO_UDINT (LEN( payload ))
);
END_IF
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.
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.
Global Parameters
The library applies the following values as maximums; they can be modified
when the library is included in a project.
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.
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.
Enumeration Description
Encoding
Enumeration Description
ElementType
Enumeration Description
READ_MODE
Enumeration Description
Structures
Structures provide a means to group together several memory locations
(variables), making them easier to manage.
XMLElement
Name IEC 61131 Type Description
Function Blocks
The XML Utility SL library provides various function blocks to construct and
parse data into respective structures.
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.
xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.
Outputs
Name IEC 61131 Type Description
Inputs
Name IEC 61131 Type Description
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.
xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.
Outputs
Name IEC 61131 Type Description
udiNextReadPos UDINT Position in file (in bytes) of the next XML element;
0 if last element.
Inputs
Name IEC 61131 Type Description
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.
xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.
Outputs
Name IEC 61131 Type Description
udiNextReadPos UDINT Position in file (in bytes) of the next XML element,
0 if last element.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
udiNextReadPos UDINT Position in file (in bytes) of the next XML element,
0 if last element.
Inputs
Name IEC 61131 Type Description
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.
xTruncateValues BOOL TRUE: All values that exceed the maximum value size will be truncated.
Outputs
Name IEC 61131 Type Description
udiNextReadPos UDINT Position in file (in bytes) of the next XML element,
0 if last element.
Inputs
Name IEC 61131 Type Description
Outputs
Name IEC 61131 Type Description
Inputs
Name IEC 61131 Type Description
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.
xAddDeclaration BOOL Adds XML declaration with encoding info like "<?XML version=1.0
encoding=..", default: TRUE.
Outputs
Name IEC 61131 Type Description
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.
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.
</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: < Greater than: > And: & Apostroph: ' Quote: "
</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 := FALSE;
END_IF
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.
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.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.
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.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.
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.
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.
DescriptiveData
Version Summary of Revisions Date Code
Dictionaries
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.
DynamicDisturbanceRecorder
Version Summary of Revisions Date Code
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.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
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.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.
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
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.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.
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.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.
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.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.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
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.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.
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.
FileIO
Version Summary of Revisions Date Code
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.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.
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.
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.
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.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.
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.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.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.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).
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.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
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.
JSON_Utilities_SL
Version Summary of Revisions Date Code
MQTT_Client_SL
Version Summary of Revisions Date Code
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().
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.
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.
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.
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
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.
PowerSystemProtection
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.
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.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.
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.
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.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.
ReportGenerator
Version Summary of Revisions Date Code
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.
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
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.
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.
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.
SELUtils
Version Summary of Revisions Date Code
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.
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.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
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.
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.5 ➤ Removed limitation that number and SNMP ID of ports cannot change. 20150213
SyslogCollector
Version Summary of Revisions Date Code
3.5.1.0 ➤ Allows compatibility with project versions R150 and later. 20221104
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.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.
Web_Client_SL
Version Summary of Revisions Date Code
Web_Socket_Client_SL
Version Summary of Revisions Date Code
XML_Utility_SL
Version Summary of Revisions Date Code
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.
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]".
CommProc Converter
Version Summary of Revisions Date Code
CtPt Monitor
Version Summary of Revisions Date Code
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.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.
DMA Link
Version Summary of Revisions Date Code
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.2 ➤ Allows compatibility with project versions R150 and later. 20220331
Associated Library: 3.5.4.0
ACSELERATOR RTAC: 1.34.150.15000
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
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.33.0.0 ➤ Allows compatibility with project versions R150 and later. 20220331
Associated Library: 3.5.1.0
ACSELERATOR RTAC: 1.34.150.15000
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.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.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.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
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.
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.
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
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.1 ➤ Addressed warnings when more than 100 triggers are configured. 20200702
Associated Library: 3.5.1.1
ACSELERATOR RTAC: 1.26.143.16172
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.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
Developer Mode
Introduction
Developer Mode can be enabled by going to the following location: SEL >
Options > Advanced.
Once the check box is selected and the RTAC software has been restarted,
projects R135 and later will support developer mode.
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.
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.
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.
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.
Inserting Placeholders
Start by selecting the Add library option, and from the popup window, select
Advanced to open the advanced library reference view.
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.
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.
You should now see the placeholder library reference listed among the other
library references that you have added to the Library Manager.
Example: SEL_IEC_TYPES.TON
Example: SEL_IEC_TYPES.SPS
➤ Summary tab:
➢ Company must be filled out
➢ Title must be filled out
➢ Version must be filled out
Once project information is filled out properly, click POU > Save POUs
as .compiled-library.
To start creating the class, add a Function Block by right-clicking and selecting
Add Object > POU.
➤ 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.
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.
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.
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.
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.
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.
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.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.
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.
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.