Edge Action Runner Reference

This topic provides detailed information about the Action Runner scripting language that you can use to implement logic in Edge Actions that run on Octave edge devices at the edge.

JavaScript Environment

The Action Runner runs the appropriate Actions when their configured triggers are received from the Data Hub.

ECMAScript 5

The environment that executes your code is in strict mode, a restricted subset of JavaScript 5.1. For more information, read the documentation.

With this version you should avoid declaring global variables (use var x = 1; instead of just simply x = 1;). For more information about strict mode, read the Mozilla Developer Network article.

We do not support most features of ECMAScript 6 and we also disallow the use of eval. If you are not familiar with JavaScript, get started in a few minutes with the following resources:

Format

Structure

The Action is a standard ECMAScript 5.1 function, with arity-1:

function ( payload ) {
}

Valid input payload consists of any valid JSON element:

  • JSON Boolean
  • JSON Number
  • JSON String
  • JSON Object
  • JSON Array

Output

Each Action should return a value. If no value is returned, no further work needs to be done. If a value is returned, Action Runner validates it to match the following JSON format:

result = {
     key1 : [ value1, value2, … , valueN],
     key2 : [ … ],
     …
     keyN : [ … ]
}

Each value must be in an array of key/value pairs.

The “keys” specify the target to deliver the payloads. Each key is a URI, comprised of a scheme (), a separator (://), and a path () - i.e. ://. The available key types are:

NameFormat (<destination>://<path>)
Datahub Resourcedh://<resource_value_path>
Virtual Resourcevr://<virtual_resource_name>
Cloud (Immediate)cl://
Cloud (Store and Forward)st://

The “values” are the data to output. Each “value” can be any JSON type (boolean, number, string, object, array).

📘

Note

Events sent from an Edge Action cannot be sent to a named Stream in the Cloud, they will be stored in the :/default Stream of the device.

Each <destination>://<path> entry must be unique.

Errors and Failures

  • If an Action fails validation at compilation (load) time, it cannot be loaded. If it is the sole Action to specify that topic, Octave remove the callback handler for that topic.
  • If an Action fails while executing, an error should be logged, and a value should be written to the Data Hub.
  • If a single output “key” or “value” fails validation, Octave proceeds with the other keys and values and continue to process those which are valid.

Octave Functions

The following JavaScript functions are provided within the environment.

📘

Note

It's recommended that the functions listed below in firmware 3.1.0+ be used where possible.

Functions Available in Firmware 3.1.0+:

Functions Available in all Firmware Versions:

  • Datahub.read(): Performs a read operation on the Data Hub (e.g., to read the value of a resource).
  • Datahub.query(): Performs a query operation which reads the min, max, mean, or standard deviation of a value on the Data Hub.

Resource.readValue()

Reads and returns the current value of a Resource.

This function is available in firmware 3.1.0+.

Parameters

ParameterTypeRequiredDescription
pathStringYesThe path is checked to be a valid Resource in the Data Hub and may one of two types:

Regular Resources:
- Actual Resources; must begin with a /.
- These paths can be either absolute or relative. Absolute paths must begin with /app and are used without modification.
- Relative paths are assumed to be with respect to /app and have /app prepended to them internally before use (e.g. The relative path argument: /myapp/mysensor/period is converted to the full path: /app/myapp/mysensor/period).

Virtual Resources: Resources created via the /virtual/config Resource. These are read using Datahub.read() and are written using the vr:// output tag in the return object. Each Virtual Resource behaves in a similar way to that of a global variable, and is accessible from all actions which belong to a particular device. These Resources are not visible between devices.
- Variable names which do not contain any slashes / (i.e. no sub-directories).
- When read, the terminating node /value is appended to the path.

Returns

The current value of the Resource.

Example

Request

var result = Resource.readValue('/redSensor/light/value');

Response

988

Resource.read()

Reads the current value of a Resource.

This function is available in firmware 3.1.0+.

Parameters

ParameterTypeRequiredDescription
pathStringYes Regular Resources:
- Actual resources; must begin with a /.
- These paths can be either absolute or relative. Absolute paths must begin with /app and are used without modification.
- Relative paths are assumed to be with respect to /app and have /app prepended to them internally before use (e.g. The relative path argument: /myapp/mysensor/period is converted to the full path: /app/myapp/mysensor/period).

Virtual Resources: Xreated from via the /virtual/config Resource. These are read using Datahub.read() and are written using the vr:// output tag in the return object. Each Virtual Resource behaves in a similar way to that of a global variable, and is accessible from all actions which belong to a particular device. These Resources are not visible between devices.
- Variable names which do not contain any slashes / (i.e. no sub-directories).
- When read, the terminating node /value is appended to the path.

Returns

FieldTypeDescription
value variableThe current value of the Resource.
timestamp IntegerThe time, in seconds, when the Resource was set to its current value.

Example

Request

var result = Resource.read('/redSensor/light/value');

Response

{
    "value": 1291,
    "timestamp": 1606159021.780723
}

Observation.getMax()

Returns the maximum value in an Observation's buffer.

This function is available in firmware 3.1.0+.

Parameters

ParameterTypeRequiredDescription
obs_nameStringYesThe name of the Observation from which to get the maximum value from the buffer.
windows_time_size IntegerNoThe time window, in seconds, is the time from which to begin analyzing the data.

Returns

The resulting data will be a scalar, or null if the buffer is empty.

Example

Request

var result = Observation.getMin('light', 10);

Response

780

Observation.getMin()

Returns the minimum value in an Observation's buffer.

This function is available in firmware 3.1.0+.

Parameters

ParameterTypeRequiredDescription
obs_name StringYesThe name of the Observation from which to get the minimum value from the buffer.
windows_time_size IntegerNoThe time window, in seconds, is the time from which to begin analyzing the data.

Returns

The resulting data will be a scalar, or null of the buffer is empty.

Example

Request

var result = Observation.getMax('light', 10);

Response

900

Observation.getMean()

Returns the mean value in an Observation's buffer.

This function is available in firmware 3.1.0+.

Parameters

ParameterTypeRequiredDescription
obs_name StringYesThe name of the Observation from which to get the mean value from the buffer.
windows_time_size IntegerNoThe time window, in seconds, is the time from which to begin analyzing the data.

Returns

The resulting data will be a scalar, or null of the buffer is empty.

Example

Request

var result = Observation.getMean('light', 10);

Response

890

Observation.getBuffer()

Extracts the raw buffer from an Observation.

This function is available in firmware 3.1.0+.

Parameters

ParameterTypeRequiredDescription
obs_name StringYesThe name of the Observation from which to get the values from the buffer.
windows_time_size IntegerNoThe time window, in seconds, is the time from which to begin analyzing the data.

Returns

An array of value/timestamp pairs:

FieldTypeDescription
vVariableThe current value for this buffered item.
tIntegerThe time window, in seconds, is the time from which to begin analyzing the data for the current buffered item.

Example

Request

var result = Observation.getBuffer('light');

Response

[
  {"v" : 254, "t" : 1234567890},
  {"v" : 259, "t" : 1233563449}
]

Datahub.read()

Performs a read operation on the Data Hub (e.g. to read the value of a Resource).

Parameters

ParameterTypeRequiredDescription
pathStringYesThe path is checked to be a valid resource in the Data Hub and may one of two types:

Regular Resources:
- Actual Resources; must begin with a /.
- These paths can be either absolute or relative. Absolute paths must begin with /app and are used without modification.
- Relative paths are assumed to be with respect to /app and have /app prepended to them internally before use (e.g. The relative path argument: /myapp/mysensor/period is converted to the full path: /app/myapp/mysensor/period).

Virtual Resources: Created via the /virtual/config Resource. These are read using Datahub.read() and are written using the vr:// output tag in the return object. Each Virtual Resource behaves in a similar way to that of a global variable, and is accessible from all actions which belong to a particular device. These Resources are not visible between devices.
- Variable names which do not contain any slashes / (i.e. no sub-directories).
- When read, the terminating node /value is appended to the path.
timeoutIntegerNoThe timeout parameter has been deprecated and is always 0. Immediately upon being called, the read function will attempt to read from the Resource.

The value read will be returned or NULL will be returned if the read failed.

Returns

The resulting data will be in JSON format, with two field names:

FieldTypeDescription
valueVariableThe current value of the Resource.
timestampIntegerThe time, in seconds, when the Resource was set to its current value.

Example 1

Request

For regular Resources, <data name> is the terminating node of the path provided. For example:

var result = Datahub.read('/io/ADC0/period', 0)

Response

{
    "period" : 300,
    timestamp : 1292947293
}

Example 2

Request

For user-defined Resources, the terminating node of the path is always "value". For example:

var result = Datahub.read("/redSensor/light/value",0);

Response

{
    "value" : 254,
    timestamp : 1234567890
}

Datahub.query()

Performs a query operation which reads the min, max, mean, or standard deviation of a value on the Data Hub.

Parameters

ParameterTypeRequiredDescription
pathStringYesThe path is validated to be a valid path in the Data Hub and may be either absolute or relative. Absolute paths must begin with /obs. Relative paths are assumed to be with respect to /obs and must begin with a /.
queryTypeStringYesThe query type is a (case-insensitive) string matching one of: min, max, mean, or stddev.
timeWindowSIntegerNoThe time window, in seconds, is the time from which to begin analyzing the data.

Returns

The resulting data will be a scalar.

Example

Request

var queryResult = Datahub.query('my_observation', 'mean', 10000)

Response

32

Manipulating Binary Data

Often times it necessary to manipulate data such as that read from Modbus (e.g., to change endianness). This is can be done in an Edge Action or, less commonly, in a Cloud Action, using JavaScript's support for bitwise operators.

For more information about bitwise operator support in JavaScript, see: Bitwise Operators.