Datacenter User Guide

Version 2.0 | Published November 02, 2023 ©

Manipulating Dataset Entries via Scripting

Introduction

Scripting can be used to process the incoming data before it is sent to the output, allowing flexible data manipulation. For example, data can be normalized to an expected format / units, and new entries can be computed from incoming data.

These are the following topics:

Applying a Script

Scripts can be applied to a dataset via the Processing parameters panel:
images/download/thumbnails/120745851/image-2023-9-8_12-35-18.png

  • To apply a script, open the corresponding dropdown menu and select the script to apply.

    images/download/thumbnails/120745851/image-2023-9-8_12-36-42.png
  • Scripts are applied immediately on the dataset output. When applied successfully, the icon next to the script name turns green.

    images/download/thumbnails/120745851/image-2023-9-8_12-39-38.png
  • Conversely, scripts that are not applied successfully show a red icon next their name. You can hover over the icon to reveal the error message.

    images/download/thumbnails/120745851/image-2023-9-8_12-40-56.png
  • By clicking the magnifier glass icon images/download/thumbnails/120745851/image-2023-9-8_12-41-19.png you can inspect the content of the loaded script.

    images/download/attachments/120745851/image-2023-9-8_12-44-23.png

Adding a New Script

Datacenter, constantly monitors all the scripts located in C:\ProgramData\vizrt\Datacenter\scripts, and therefore, the new scripts added to that folder are immediately visible in the Datacenter script list.

Another option to add a new script is to enable the Allow uploading scripts toggle in the General/Communication section of the Admin page.

images/download/attachments/120745851/image-2023-9-8_13-59-21.png

Doing so, enables an upload button next to the scripts list in the main page, which can be use to load new scripts.

images/download/thumbnails/120745851/image-2023-9-8_14-0-5.png

Script Uploading

Warning: Datacenter does not vet uploaded scripts, therefore, allowing the upload of arbitrary scripts to Datacenter can pose a security threat. We strongly recommend to enable scripts uploading, only when strictly necessary and for the time required.

Development

Scripts are Javascript programs located in C:\ProgramData\vizrt\Datacenter\scripts, and they must be named as *.js (sub-directories are supported).

Scripts are constantly monitored by Datacenter, and are reloaded every time there is a change.

To start developing a script, simply open a Visual Studio Code (or any other text editor) in C:\ProgramData\vizrt\Datacenter\scripts, create a script and see your changes applied as soon as the file is saved.

Warning: Because of the file watcher, when saving a script with VS Code, the file might suddenly become empty. Therefore, simply Undo (CTRL + Z) the last action and save the file again.

Process

All scripts must export a function named process, which is then called whenever data is received from a provider.

When multiple inputs are configured (for example multiple endpoints for a REST provider), the input variable holds the incoming data in multiple members named data, data_1, data_2.

Example

Here is an example of a script with the following inputs:

Input
raw_endpoint_data_1 = { // in the script, this is readable from input.data
"key11": 1,
"key12": 2
}
 
raw_endpoint_data_2 = { // in the script, this is readable from input.data_1
"key21": 3,
"key22": 4
}
Script
export function process(input) {
var obj1 = JSON.parse(input.data);
var obj2 = JSON.parse(input.data_1);
return {
a: obj1.key11,
b: obj2.key21,
c: obj1.key12 + obj2.key22
}
}

The output data is then three keys (a, 1), (b, 3) and (c, 6).

Arguments

To allow more flexible scripts, arguments can be added to the code and is shown in the UI.

It is possible to add numbers, strings, enums and date arguments that are then passed to the script during execution.

A function named getProcessArguments must be exported from the script and must return the arguments created with helper functions (see example). This function takes an optional parameter of the current provider input, allowing to create arguments dependent on the currently received values.

Argument Declaration Helper Functions

The following helpers can be used to declare scripts arguments:

function argumentEnum(name, defaultIndex, values, description="") { /*... */ }
function argumentString(name, defaultValue, description="") { /*... */ }
function argumentInt(name, defaultValue, min = Number.MIN_VALUE, max = Number.MAX_VALUE, description="") { /*... */ }
function argumentFloat(name, defaultValue, min = Number.MIN_VALUE, max = Number.MAX_VALUE, description="") { /*... */ }
function argumentDate(name, defaultValue, description="") { /*... */ }

The enum values can be of type string, or an object of type {label: string, data: string}. On the second case, the label is displayed to the user and the script receives the data.

Example

Example with hard-coded arguments
export function getProcessArguments() {
return [
argumentEnum("enumArg", 0, ["option1", "option2"], "An enum argument"),
argumentEnum("enumWithValuesArg", 1, [ {"label": "option3", "data": "value3"}, {"label": "option4", "data": "value4"}], "Another enum argument"),
argumentString("stringArg", "default value", "A string argument"),
argumentInt("intArg", 2, 0, 5, "An int argument"),
argumentFloat("floatArg", 3.1, 1.2, 5.6, "A float argument"),
argumentDate("dateArg", "2023-07-01", "A date argument"),
];
}
 
export function process(input, args) {
var result = {}
result["receivedInput"] = input.data;
result["receivedEnumArg"] = args.enumArg;
result["receivedEnumWithValuesArg"] = args.enumWithValuesArg;
result["receivedStringArg"] = args.stringArg;
result["receivedIntArg"] = args.intArg;
result["receivedFloatArg"] = args.floatArg;
result["receivedDateArg"] = args.dateArg;
 
return result;
}
Example with arguments generated from input
/** Function called by the Viz Datacenter scripting stage. The script's input arguments are defined with this function.
* @param {object} input The input object
* @returns {object[]} An Array of arguments
*/
export function getProcessArguments (input) {
const events = getEvents(input)
const options = getEventOptions(events)
 
return [argumentEnum('Event', 0, options, 'The event to select')]
}
 
/** Retrieves the list of events from the input object
* @param {object} input The input object
* @returns {object[]} A list of all the events
*/
function getEvents (input) {
let events = []
if (input.data) {
const obj = parseInputObject(input)
for (const event of obj.liveData.event) {
events.push(event)
}
}
return events
}

Assuming some kind of input and if the user does not modify the default arguments, the dataset would contain the following values:

receivedInput { "inputData": "something" }
receivedEnumArg option1
receivedEnumWithValuesArg value4
receivedStringArg default value
receivedIntArg 2
receivedFloatArg 3.1
receivedDateArg 2023-07-01

Imports

In order to allow code reuse, it is possible for a script to import another file. Those imported files must be named *.import.js, so they are not shown as scripts in the Datacenter UI.

The imports are relative to the scripts root directory C:\ProgramData\vizrt\Datacenter\scripts, not the current script directory.

Example

utils/helpers.import.js
export function doNothing(input) {
return input;
}
provider/script.js
import { doNothing } from "utils/helpers.import.js"
 
export function process(input) {
return doNothing(input);
}

Debugging

To debug a script add the following launch configuration to VS Code:

Launch configuration
{
"launch": {
"configurations": [
{
"name": "ClearScript",
"type": "node",
"request": "attach",
"address": "localhost",
"port": 9757
}
],
"compounds": []
}
}

Then add the following line to the script to debug:

//SCRIPT_DEBUG_PORT=9757

In VS code, execute Run and debug with the ClearScript configuration. The debugger attaches to the running script and breakpoints can be set in the Loaded scripts section.

Info: Because of some internal limitations, the debug port is not immediately freed after modifying a script. Therefore, it is necessary to adapt the debug port in the script and launch configuration when modifying and saving the debugged script.