Pre-Processing Functions ✔️

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

Introduction

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

Syntax

 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.

Configuration

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.

When you click on Save, the script is compiled and validated. If no errors are shown, it means that that you did not use any forbidden variables or make any typos.

Click on the blue play button to test your function using any trigger input value.

 

Specifying trigger tags

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

Available variables

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)

Function result

 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

  • ResetBuffers(string lineName) - resets all tracked line buffers (see: [In Progress: Differential waste calculation])

Example functions:

  1. The simplest valid function can return just an empty list:

1  return new IPreProcessingCommand[0];


2. Calculate a sum of 3 tags “a”, “b”, “c” and return it as tag “sum”

1 2 3 4 5 6 7 8 9 10 11 12 13 // 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”) };