Warning: You’re entering an advanced section for engineers and developers. Topics described below are not a needed for most PackOS users. They require some programming skills, but can help you better tune PackOS to your needs |
You can think of the pre-processing functions as tools that you can use to perform computations on signals that PackOS receive before they are processed and assigned to specific machines.
Example use cases include:
hex-to-decimal conversion
bit selection
value multiplication
signal aggregation
line flow change
changeover end
Each function is a C# script. It’s a strongly typed language requiring you to handle type conversions, but also making sure there are no syntactic errors by compiling the script before persisting.
Head to https://docs.microsoft.com/en-us/dotnet/csharp/tour-of-csharp/tutorials/ for a tutorial
In addition to variables and services provided by the platform (more about that below), all operations on Double, Int, String or DateTime variables are available to you.
In order to configure pre-processing functions in PackOS, you will need to:
1. Go to Settings by clicking on the Settings button in the left sidebar.
2.Click on the Pre-Processing Functions in the section Advanced located at the bottom of the page.
Each function is triggered when one of the defined tags is observed. Each tag is a pair of Source URI and Device ID.
Source URI usually specifies OPC UA tag available in the OPC Server. If another type of data source is used – it’s the corresponding tag assigned to that node in LogiX Gate.
Device ID further specifies which data source (LogiX Gate’s input) for the Source URI is used, mostly needed when there are multiple OPC Servers publishing the same tags.
In the future, you’ll be able to set a time trigger on the function |
The following variables are available and can be used in the script. There are nested objects containing multiple simple types, and services which can be used to query more data.
TriggerValue [string?]
-- value from the message which triggered the function
Trigger [object]
– details about the trigger
NodeId [string?]
-- Source URI from the message which triggered the function
ApplicationUri [string?]
-- Device ID from the message which triggered the function
Value [object]
-- details about the trigger value
Value [string?]
-- same as TriggerValue variable above
SourceTimestamp [DateTime]
-- timestamp of the message
StatusCode [object?]
-- details of the connection error
Symbol [string]
-- Name of the issue
Code [long]
– OPC error code
TagValue [service]
-- access to current values of all received tags
string GetValue(string sourceUri, string? deviceId)
– getting raw string value of a tag (it does not necessarily need to be one of the trigger tags)
T? GetValue<T>(string sourceUri, string? deviceId)
– value of a tag converted to the desired type (or a default value of that type if conversion invalid)
DateTime? GetUpdate(string sourceUri, string? deviceId)
– timestamp of the last update of this tag
Element [service]
-- access to current element state
WorkLog? WorkLog(string elementName)
– current state of the element
IsForced [bool]
-- true/false if the current state is forced
WorkStateName [string]
-- code name of the current state (e.g. holdup)
StartDate [DateTime]
-- timestamp when the state bug
RootStateName [string?]
-- code name of the root state (e.g. holdup)
RootStartDate [DateTime?]
– timestamp of the root state
Store [service]
-- memory space for custom variables
bool TryGet(string key, out string value)
– getting value of the key
void Set(string key, string value)
– setting value of the key
In service methods, specifying deviceId
is optional. If not provided, the first matching Source URI value will be returned.elementName
is either directly a name of the line, or a path to a machine in the format:
LineName/ MachineName (e.g. Line1/Filler)
Pre-processing function returns a list of commands, all implementing IPreProcessingCommand
type. There are numerous command types available, each function can return a mix of them. New commands will be added in the future to cover more scenarios.
Tag(string value, string sourceUri, string? deviceId = "")
- returns a new value with new SourceUri and DeviceId which then can be mapped to one of the signals in machine or line definition.
SetFlow(string lineName, string flowName)
- changes active flow on the selected line
EndForcedState(string elementName)
- forces state recalculation from rules on the provided element, ending the forced state
The simplest valid function can return just an empty list:
return new IPreProcessingCommand[0]; |
2. Calculate a sum of 3 tags “a”, “b”, “c” and return it as tag “sum”
// 1. Use tag dictionary to get latest values for each of the tags double a = TagValue.GetValue<double>(“a”); double b = TagValue.GetValue<double>(“b”); double c = TagValue.GetValue<double>(“c”); // 2. Calculate the sum double sum = a + b + c; // 3. Return the calculated variable as a command return new [] { new Tag(sum, “sum”) }; |