Skip to content

Custom Code#

codeexecutionsvg

This task allows custom code to be executed in the system, similar to what happens with DEE Actions, creating an abstraction layer of code that can be used to aggregate several commands that can be more complex to create through the regular workflow editor.

customcode_01

Inputs#

Name Data Type Description
<custom list> <custom> Object with the inputs for the action
Activate any Executes the action in MES

Outputs#

Name Data Type Description
<custom list> <custom> Outputs of the action
Success Boolean If there was no problem emits a true
Error Error Error that occurred during the processing of this task

Settings#

On the General Tab, you have the usual settings and the following settings:

Name Data Type Default Description
ExpirationTime Integer 10000 Time window (in milliseconds) for code execution

customcode_02

On the Inputs Tab, there are the following settings:

Name Data Type Default Description
Name String An input name
Friendly Name String Name to be displayed
Type Long
Decimal
DateTime
Boolean
String
Integer
ReferenceType
...
The type of the input
Collection Type None
Array
Map
Default Value - Default Value

customcode_03

On the Outputs Tab, there are the following settings:

Name Data Type Default Description
Name String An output name
Friendly Name String Name to be displayed
Type Long
Decimal
DateTime
Boolean
String
Integer
ReferenceType
...
The type of the output
Collection Type None
Array
Map
Default Value - Default Value

customcode_04

On the Code Tab, there is a editor with syntax highlighting and intelligent code completion that allows the user to edit the code that should be run in this Task. This is the main focus point of the Task and should be used with care since it permits access to the MES itself through API calls, as well as storing values in a database table and perform logging of important values.

customcode_05

Here is an example of a direct MES interaction, where this Task calls a business method that removes all filled positions from a Container by the use of the EmptyContainer method:

import { Framework } from 'framework';

export default class {
    /** Allows accessing external functions */
    public framework: Framework;
    constructor(framework: Framework) {
        this.framework = framework;
    }
    /*
        * Entry point of the class (IMPORTANT: don't change the signature of this method)
        * Should return an object containing the values for each output to emit
        * If necessary, use the parameter "outputs" to emit data while running the code.
    */
    public async main(inputs: any, outputs: any): Promise<any> {
        // Add code here
        this.framework.logger.warning(inputs.xx);
        const input = new this.framework.LBOS.Cmf.Navigo.BusinessOrchestration.ContainerManagement.InputObjects.EmptyContainerInput();
        input.Container = new this.framework.LBOS.Cmf.Navigo.BusinessObjects.Container();
        input.Container.Name = "Container001";
        input.IgnoreLastServiceId = true;
        const output = await this.framework.system.call(input);
        this.framework.logger.error(JSON.stringify(output));
        // emit output during execution: outputs.output1.emit("something");
        // return example: return { output1: inputs.input1, output2: "Hello World" };
    }
}

Behavior#

This task executes the (TypeScript) code created by the user in the Code section of the Task settings. This code is executed with the received inputs and emits all the outputs defined in the code. Although similar to what happens in the execution of DEE Actions in MES, in this particular situation the user can have full control over the inputs and outputs of the block, with added configuration options for both scalar and reference types.

A main class must be defined and the name MUST be the following:

export class CustomCode

Within the code, the execution layer MUST define the following properties:

public api: Api = null;
public customApi: CustomApi = null;

Afterwards, those properties can be used in a method that MUST have the following signature:

public async main(inputs: any, outputs: any): Promise<any>

Inside the main method the user can create code to access multiple namespaces. Here is a list of the available API namespaces and the methods and classes that can be used:

Datastore#

Object Type Description
retrieve method retrieves value from the data store
store method stores value to the data store

Driver#

Object Type Description
automationControllerDriverDefinition property access to the driver definition of the current Automation Controller
connect method connects to the driver
disconnect method disconnects from the driver
executeCommand method executes a command
getProperties method gets property values from the driver
notifyRaw method sends notification to the driver
sendRaw method sends message to the driver
setProperties method sets property values in the driver

Logger#

Object Type Description
debug method logs debug message
error method logs error message
info method logs information message
warning method logs warning message

MessageBus#

Object Type Description
publish method sends message to the MessageBus
sendRequest method sends message to the MessageBus and waits for reply

System#

Object Type Description
call method calls an available API in the MES system

Utils#

Object Type Description
convertValueToType method runs a type conversion on a given input
sleep method places the system on pause for a predefined time

Remarks#

This Task should be used with care since a user may unwittingly introduce extra complexity in a workflow where a more simple way to perform specific tasks can be achieved by using simpler, more straightforward Tasks. Due to possible breaking changes (method signature changes, parameter renaming, among others), this Task should be used sparingly and when no other form of automation workflow is possible.

Info

As a quick tip for faster and easier development, pressing the combination of the Ctrl and S keys when editing the code inside the task will save the existing buffer.