API
  • 20 Apr 2024
  • 43 Minutes to read
  • PDF

API

  • PDF

Article Summary

Each script has access to the following features that are not part of the Javascript standard. Instead, these are added by N3uron. Most of them are accessed via a special $ object. However, some (like the sprintf function) can be used directly:

sprintf(format: string, ...params: any[])

Sprintf is a function that can be used to create a new string from a format string that can contain placeholders (for example %s and %d) and a list of values that will replace the placeholders in the format string in order to generate the new string. The following are valid placeholders for different data types:

  • Integer: %d or %i
  • String: %s
  • Binary: %b
  • Boolean: %t
  • JSON: %j
  • ASCII character from numeric value: %c
  • Scientific notation: %e
  • Floating point: %f
  • Fixed point: %g
  • Octal: %o
  • Unsigned integer: %u
  • Hexadecimal lowercase: %x
  • Hexadecimal uppercase: %XF
  • Node buffer: %r$.pF

If the integer and unsigned integer format type receive a decimal number, the decimal part will be truncated.

Most of these placeholders can also accept modifiers that will affect how the string will be formatted. For example, %02f will force a floating point number to always use 2 decimals. More information about the sprintf function can be found at NPM sprintf-js

An example of various format strings with different placeholders can be seen in the next code snippet:

// Numbers are: 10 and 15
sprintf("Numbers are: %d and %i", 10, 15.7);

// String is: Hello world!
sprintf("String is: %s", "Hello world!");

// The binary representation of 5 is: 101
sprintf("The binary representation of 5 is: %b", 5);

// The ASCII character with decimal value 48 is 0
sprintf("The ASCII character with decimal value 48 is %c", 48);

// 1000 in scientific notation is: 1e3
sprintf("1000 in scientific notation is: %e", 1000);

// 1234 in scientific notation and 2 decimals is: 1.23e3
sprintf("1234 in scientific notation and 2 decimals is: %.2e", 1234);

// 12.34 in floating point notation is: 12.34
sprintf("12.34 in floating point notation is: %f", 12.34);

// 12.3456 in fixed point notation is: 12.3
sprintf("12.3456 in fixed point notation is: %.3g", 12.3456);

// 12 in octal is: 14
sprintf("12 in octal is: %o", 12);

// -10 in unsigned integer format is: 4294967286
sprintf("-10 in unsigned integer format is: %u", -10);

// 10 in hexadecimal is: 1e
sprintf("30 in hexadecimal is: %x", 30);

// 30 in uppercase hexadecimal is: 1E
sprintf("30 in uppercase hexadecimal is: %X", 30);

// The buffer is: <48 65 6c 6c 6f 20 77 6f 72 6c 64 21>;
const buf = Buffer.from("Hello world!");
sprintf("The buffer is: %r", buf);

$.global

The $.global object is a key-value store that can be used to share data between all the scripts, even if they are in different tasks. It has two functions:

  • get(property: string) => any: This function is used to retrieve a value from the global store.
  • set(property: string, value: any) => void: This function is used to store a value with a given key in the global store. Only values that can be serialized using the structured clone algorithm can be stored in the global store. This includes numbers, strings, booleans, objects (without any associated functions), maps and sets. If a value can't be serialized, an error is thrown. Some common variables that can not be serialized are class instances and functions. 

$.taskLocal

The $.taskLocal object is a key-key store shared between all scripts within the same task, but not between scripts in different tasks. It has two functions:

  • get(property: string) => any: This function is used to retrieve a value from the global store.
  • set(property: string, value: any) => void: This function is used to store a value with a given key in the global store. Only values that can be serialized using the structured clone algorithm can be stored in the global store. This includes numbers, strings, booleans, objects (without any associated functions), maps and sets. If a value can't be serialized, an error is thrown. Some common variables that can not be serialized are class instances and functions. 

$.local

The $.local is a persistent object within a specific script. This can be used to store states between script executions. Unlike $.global and $.taskLocal, since this is an object, it can store any value that can be stored in an object (including functions or class instances). These values do not persist between module restarts.

$.lib

$.lib is a function used to import libraries declared in the Libraries configuration into a Script. This is done by invoking the $.lib(name: string) => any function with the same name that was given when declaring the library in the configuration section.

$.paths

The $.paths object contains different paths for N3uron, irrespective of where N3uron is installed or the operating system in use. The $.paths object has two nested objects, one labelled global and one labelled local. The first one contains paths relevant to the N3uron installation, while the latter contains paths related to the currentScripting instance. For example, if N3uron is installed in the default windows installation folder and the current Scripting instance named as “Scripting”, the $.paths object has the following contents:

{
  "base": "C:/Program Files/N3uron",
  "global": {
    "bin": "C:/Program Files/N3uron/bin",
    "config": "C:/Program Files/N3uron/config",
    "log": "C:/Program Files/N3uron/log",
    "data": "C:/Program Files/N3uron/data",
    "licenses": "C:/Program Files/N3uron/licenses"
  },
  "local": {
    "bin": "C:/Program Files/N3uron/bin/modules/Scripting",
    "config": "C:/Program Files/N3uron/config/Scripting",
    "log": "C:/Program Files/N3uron/log/Scripting",
    "data": "C:/Program Files/N3uron/data/Scripting"
  }
}

$.exit(error?: null|Error, returnValue?: any)

Deprecated
This method is deprecated in N3uron V1.21.7.

The $.exit() function is used to indicate that the current script execution has finished. This function must be called when the script has been fully executed (that includes both synchronous and asynchronous executions) and after it is called, no further code should be executed. As such, it is recommended to follow a call to $.exit() with the return; statement to stop the script from executing any more code.

This function takes two optional parameters. If the function is called without parameters, it is assumed that it finished without errors and a return value:

  • error: If set, the error will be automatically logged to the log. If there are no errors and the script has a return value, the error argument must be set to null.
  • returnValue: When set, this will be the return value of the script. This is mostly used by external actions in order to return values to other modules. The return value can have any type, although other modules may impose a specific format for the return value in order to function properly.

$.event

The $.event object contains information about the trigger that launched the current script. This object will vary depending on which type of action launched the script, as seen in the following list:

  • Start-up
    • $.event.startTime: Contains the time when the module was started, in UNIX epoch with milliseconds.
  • Shutdown
    • $.event.stopTime: Contains the time when the module was stopped, in UNIX epoch with milliseconds.
  • Periodic
    • $.event.time: Contains the time when the periodic action was triggered, in UNIX epoch with milliseconds.
    • $.event.initial: Boolean flag that indicates if the current execution is the initial one (when Run on startup is true) or a normal periodic execution.
    • $.event.blockTs: Contains the start time of the current execution rounded to the nearest interval (only applies to interval and cron period types). For example, if the interval is 60 seconds, or the cron job runs every minute, the blockTs will be rounded to XX:01:00, XX:02:00, even if the script executes slightly later due to timer delays.
  • Tag change
    • $.event.tag: Contains the full path of the tag that changed, as a string.
    • $.event.oldValue: Contains the old tag event before the change. It's an object with value (whose type depends on the tag type), quality (as a number), and ts (as a number in UNIX Epoch milliseconds).
    • $.event.newValue: Contains the new tag event that triggered the script. It's an object with value (whose type depends on the tag type), quality (as a number), and ts (as a number in UNIX Epoch milliseconds).
    • $.event.changes: Contains an object indicating which properties have changed in the new tag event compared to the old tag event. It has three boolean properties, a value, quality, and timestamp. which are set to true if the property has changed, or false if it hasn't changed.
  • Condition 
    • $.event.tag: Contains the full path of the tag that triggered the condition, as a string. 
    • $.event.value: Contains the event that triggered the condition, or the current value if the condition type is whileTrue or whileFalse. It's an object with value (whose type depends on the tag type), quality (as a number), and ts (as a number in UNIX Epoch milliseconds). 
    • $.event.time: Contains the time when the periodic tag condition action was triggered, in UNIX epoch with milliseconds. This only applies if the condition type is whileTrue or whileFalse.
    • $.event.initial: Boolean flag that indicates if the current execution is the initial one (when the condition first triggers), or a normal periodic execution. This only applies if the condition type is whileTrue or whileFalse.
    • $.event.blockTs: Contains the start time of the current execution rounded to the nearest interval (only applies to interval and cron period types). For example, if the interval is 60 seconds, or the cron job runs every minute, the blockTs will be rounded to XX:01:00, XX:02:00, even if the script executes slightly later due to timer delays. This only applies if the condition type is whileTrue or whileFalse.
  • External action 
    • External actions contain their arguments as keys to the $.event object. For example, if an external action receives value1=23 and value2=60as arguments, the event object will contain $.event.value1 and $.event.value2.

The following code block contains examples of all the different $.event objects:

// Startup at 2022-04-25 10:00:00
$.event.startTime = 1650880800000;

// Shutdown at 2022-04-25 10:30:00
$.event.stopTime = 1650882600000;

// Periodic trigger at 2022-04-25 10:00:23  with 60s interval
$.event.time = 1650880823000;
$.event.initial = false;
$.event.blockTs = 1650880800000;

//Tag /Plant1/ActivePower changes from 1000 to 1020
$.event.tag = "/Plant1/ActivePower";
$.event.oldValue = { value: 1000, quality: 192, ts: 1650880772000 };
$.event.newValue = { value: 1020, quality: 192, ts: 1650880810000 };
$.event.changes = { value: true, quality: false, ts: true };

// Tag /Plant1/Alarm changes from 0 to 1, triggering a condition
$.event.tag = "/Plant1/Alarm";
$.event.value = { value: 1, quality: 192, ts: 1650880810000 };

// External action with val1=123 and val2=300 arguments
$.event.val1 = 123;
$.event.val2 = 300;

$.config

The $.config object contains static information about the action that triggered the script. This object contains the following keys:

  • $.config.type: An enumeration that identifies the action that triggered this script. The values for this enumeration are the following:
    • Startup: 0
    • Shutdown: 1
    • Periodic: 2
    • Tag condition: 3
    • Tag change: 4
    • External: 5
  • $.config.actionOptions: An object that contains the configuration of the action that triggered this script, which depends on the type of action (and is non-existent for Startup, Shutdown, and External, since these actions don't have any specific configuration).

$.parameters

The $.parameters object is used to retrieve configuration parameters for the current script. The structure of this object is the same as the one in the configuration. For example, if there is a parameter named "Basepath", its value can be retrieved by using $.parameters.Basepath. These parameters are read-only and will throw an error when attempting to modify them (this includes functions that modify them as a side effect, such as the .push() method of an array).

$.logger

The $.logger object is used to log messages to disk and can be used for both debugging and informative purposes. The log file can be found in N3uron/log/ScriptingInstance/. It is shared by both the internal module code and any messages written by users, which can be easily distinguished by the “User” string appended to them. The logger has the following five logging functions:

  • $.logger.error(msg: string, ...params: any[])
  • $.logger.warn(msg: string, ...params: any[])
  • $.logger.info(msg: string, ...params: any[])
  • $.logger.debug(msg: string, ...params: any[])
  • $.logger.trace(msg: string, ...params: any[])

Each logging function takes at least one argument containing the string that is going to be logged. This string can also be a format string with a placeholder, in which case, the rest of the arguments will be used to resolve these placeholders. This is the same behaviour as sprintf.

$.api

The $.api object is used to interface with N3uron and provides access to several N3uron functionalities, such as tags, links, N3uron node stats, etc. Each of these functions is hosted in a different namespace, depending on which part of N3uron they affect. For example, functions that affect tags are hosted in the tag namespace, functions that provide the status of a host machine are present in the system namespace, and so on:

Most of the functions in $.api execute asynchronously and return a promise that is fulfilled when the asynchronous request finishes. This can also be used with the await keyword function straight to the top level, without needing to wrap it into an async function. These functions can also reject promises in case of an error, in which case, the rejection reason is a string with information about the error.

The different subspaces and their functions are as follows:

$.api.authentication

$.api.authentication.getRoles

Function prototype: $.api.authentication.getRoles(options: {}): Promise<string[]>

This function retrieves the user roles available on the target node.

Example:

const roles = await $.api.authentication.getRoles({});

for (const roleName of roles) {
  $.logger.info("Found role '%s'", roleName);
}

$.api.authentication.get

Function prototype: get(user: string, password: string): Promise<{id: string, name: string, roles: string[]}>

This function performs authentication for a specific user and returns its internal ID and the roles the user belongs to.

Example:

const { id, name, roles } = await $.api.authentication.get("admin", "n3uron");

$.logger.info("ID: %s, Name: %s, Roles => %s", id, name, JSON.stringify(roles));

$.api.system

$.api.system.status 

Function prototype: $.api.system.status(options: {}): Promise<StatusResult>

This function queries the status of the host system and returns an object with information about the current hardware, hostname, uptime, etc. 

Example: 

const statusResult = await $.api.system.status({});

$.logger.info(JSON.stringify(statusResult));

The status result is an object with the following structure:

type StatusResult = {
    n3: {
        errors: ReadonlyArray<string>,
        node: string,
        pid: number,
        tags: {
            local: number,
            remote: number,
            total: number
        },
        up: number,
        versions: [exeVersion: string, bootstrapVersion: string]
    }, sys: {
        cpu: [model: string, frequency: number, coreCount: number],
        hostname: string,
        standby: boolean,
        ts: number,
        up: number,
        usage: {
            cpu: [used: number, total: number],
            disk: [used: number, total: number],
            ram: [used: number, total: number]
        }
    }
}

$.api.system.errorCount

Function prototype: $.api.system.errorCount(options: {}): Promise<number>

This function queries the number of errors in the current node. If there are no errors, 0 is returned, otherwise, it returns the number of errors (this can be caused by invalid tag configuration, invalid link configuration, etc...).

Example:

const errCount = await $.api.system.errorCount({});

$.logger.info("The current node has %d errors", errCount);


$.api.system.getStandby

Function prototype: $.api.system.getStandby(options: {}): Promise<boolean>

This function queries the standby status of the current node. If the node does not use redundancy, or if it's the standby node, the function returns false. Otherwise, it returns true.

Example:

const isStandby = await $.api.system.getStandby({});
if (isStandby) {
  $.logger.info("Node is in standby mode");
} else {
  $.logger.info("Node is NOT in standby mode");
}


$.api.system.getNetworkAdapters

Function prototype: $.api.system.getNetworkAdapters(options: {}) Promise<NetworkInterface[]>

This function retrieves the network interfaces available in the host system.

Example:

const adapters = await $.api.system.getNetworkAdapters({});

$.logger.info(JSON.stringify(adapters));

The NetworkInterface is an object with the following structure: 

type NetworkInterface = {
    all: boolean;
    name: string;
    address: string;
    mask: string;
    mac: string;
    internal: boolean;
}

$.api.system.restartService

Function prototype: $.api.system.restartService(options: {})

This function restarts the N3uron service.

Example:

$.api.system.restartService({});


$.api.license

$.api.license.getUid

Function prototype: $.api.license.getUid(): Promise<UidObject>

This function retrieves the UID of the N3uron installation.

Example:

const { host, uid } = await $.api.license.getUid();

$.logger.info("Host: %s, UID: %s", host, uid);

It returns a UidObject containing the host and UID.

type UidObject = {
    host: string,
    uid: string
}

$.api.license.get

Function prototype: $.api.license.get(): Promise<ReadonlyArray<LicenseFile>>

This function retrieves the list of licenses installed in the target node.

Example:

const licenses = await $.api.license.get();

for (const lic of licenses) {
  $.logger.info(JSON.stringify(lic));
}

 It returns a ReadonlyArray<LicenseFile> with the following definition:

type LicenseFile = {
    path: string,
    name: string,
    error: string,
    id: string,
    host: string,
    uid: string,
    nonce: number,
    unlicensed: boolean,
    licenses: ReadonlyArray<License>,
}

type License = {
    version: string,
    error: string,
    host: string,
    uid: string,
    expires: string,
    type: "production",
    modules: ReadonlyArray<ModuleLicense>,
    supportExpires: number,
    nonce: number,
    id: string
}

type ModuleLicense = {
    type: string,
    tagAccess: "remote" | "local",
    count: number,
    used: number
}

$.api.license.read

Function prototype: $.api.license.read(name: string): Promise<string>

This function returns the content of a license.

  • name: The name of the license.

Example:

const license = await $.api.license.read("node001-20240213.105718.n3l")

$.logger.info(license);

$.api.license.add

Function prototype: $.api.license.add(data: string, options:{}): void;

This function adds a new license to the target node. Receives the content of the license file.

  • data: The full content of the license file.

Example:

$.api.license.add(`{"version":"1","created":"2024-02-13T10:57:00.104Z", ....}`, {});

$.api.license.remove

Function prototype: $.api.license.remove(name: string, options:{}): void;

This function removes a license from the target node.

  • name: The name of the license.

Example:

const license = "node001-20240213.105718.n3l";

try {
  await $.api.license.remove(license, {});
  $.logger.info("License '%s' removed", license);
} catch (error) {
  $.logger.error("Failed to remove license: %v", error);
}

$.api.license.unlicense

Function prototype: $.api.license.unlicense(name: string, options:{}): Promise<string>

This function unlicenses the node and returns the unlicense file encoded as Base64.

  • name: The name of the license.

Example:

try {
  const unlic = await $.api.license.unlicense(
    "node001-20240213.105718.n3l",
    {}
  );
  $.logger.info("Unlicense file ==> %s", unlic);
} catch (error) {
  $.logger.error("Failed to unlicense: %v", error);
}

$.api.link

$.api.link.get 

Function prototype: $.api.link.get(options:{}): Promise<LinkStatus>

This function retrieves information about the status of the links in the current node. 

Example:

const linkStatus = await $.api.link.get();

$.logger.info(JSON.stringify(linkStatus));

The return value is a promise that resolves an object with the following structure: 

type LinkStatus = {
    nodeInfo: {
        name: string
    },
    links: {
        [linkName: string]: {
            local: {
                subscription: null | string,
                tagCount: number, view: {
                    name: string,
                    ro: boolean,
                    ae: boolean,
                    ack: boolean
                },
                sf: {
                    enabled: boolean,
                    paused: boolean
                }
            },
            name: string,
            online: boolean,
            remote: null | {
                endpoint: string,
                subscription: null | string,
                tagCount: number,
                view: {
                    name: string,
                    ro: boolean,
                    ae: boolean,
                    ack: boolean
                },
                sf: {
                    enabled: boolean,
                    paused: boolean
                }
            },
            type: "in" | "out"
        }
    }
}

$.api.link.sfPause

Function prototype: $.api.link.sfPause(link: string, paused: boolean): void

This function pauses the store and forward mechanisms for a specific link. When paused, no more events from S&F will be sent over that link until it is unpaused. This can be used if the receiver gets saturated with events from a link. By pausing the link, it can process the events it received before unpausing it to receive more events. It takes two arguments: 

  • link: This is the name of the link that will be paused.
  • paused: When true, it pauses the link. When false, it unpauses the link.

Example:

$.api.link.sfPause("central01", true);

$.api.certificate

$.api.certificate.get

Function prototype: $.api.certificate.get(options: {moduleName: string, type: string}): Promise<Array<Certificates>>

This function is used to retrieve certificates with a specific type from a module. It takes a single argument: 

  • options: Options used to select which certificates to retrieve.
    • moduleName: Name of the module whose certificates will be retrieved. Can be set to "bootstrap" to retrieve bootstrap link certificates
    • type: Select which type of certificate will be retrieved. For bootstrap, it can be "outbound" or "inbound", while other modules can define their own types. The types of certificates for other modules can be found in their documentation.

Example:

const certificates = await $.api.certificate.get({
  moduleName: "bootstrap",
  type: "outbound",
});

for (const cert of certificates) {
  $.logger.info(JSON.stringify(cert));
}

The return value is a promise that resolves to an array of the following objects:

type Certificate = {
    c: string,
    dn: string,
    from: number,
    id: string,
    o: string,
    sn: string,
    to: number,
    type: string,
    status: string
}

$.api.certificate.set

Function prototype: $.api.certificate.set(options: {moduleName: string, type: string, id: string, action: string}): Promise<void>

This function is used to execute an action against a certificate. It takes a single argument: 

  • options: Options used to select the target certificate and action that will be applied.
    • moduleName: Name of the module whose certificates will be modified. Can be set to "bootstrap" to execute actions on bootstrap link certificates.
    • type: Select the type of certificate that will be affected by the action. For bootstrap, it can be "outbound" or "inbound", while other modules can define their own types. The types of certificates for other modules can be found in their documentation.
    • id: Select which certificate will be affected by the action. The id can be retrieved by a call to $.api.certificate.get.
    • action: Select which action will be executed. The available actions depend on the module and the state of the target certificate (for example, a certificate that is already trusted can't be trusted again). The actions available to bootstrap link certificates are "clear", "reject", and "trust".

Example:

await $.api.certificate.set({
  moduleName: "bootstrap",
  type: "outbound",
  id: "pending/CENTRAL01__N3uron__LinkManager[F07A91C73030507C4ABCB3689C46257A6E9406A5]",
  action: "trust",
});

$.api.certificate.export

Function prototype: $.api.certificate.export(options: {moduleName: string, type: string, id: string, action: string} ): Promise<string>

This function is used to export a certificate. It takes a single argument: 

  • options: Options used to select the target certificate that will be exported.
    • moduleName: Name of the module whose certificate will be exported. Can be set to "bootstrap" to export bootstrap link certificates.
    • type: Select the type of certificate that will be exported. For bootstrap, it can be "outbound" or "inbound", while other modules can define their own types. The types of certificates for other modules can be found in their documentation.
    • id: Select which certificate will be exported. The id can be retrieved by a call to $.api.certificate.get.

Example:

const cert = await $.api.certificate.export({
  moduleName: "bootstrap",
  type: "outbound",
  id: "own/NODE01__N3uron__LinkOut",
});

$.logger.debug(cert);

The return value is a promise that resolves to a base64 string of the certificate's contents.

$.api.certificate.remove

Function prototype: $.api.certificate.remove(options: {moduleName: string, type: string, id: string, action: string} ): Promise<void>

This function is used to remove a certificate. It takes a single argument: 

  • options: Options used to select the target certificate that will be removed.
    • moduleName: Name of the module whose certificate will be removed. Can be set to "bootstrap" to remove bootstrap link certificates.
    • type: Select the type of certificate that will be removed. For bootstrap, it can be "outbound" or "inbound", while other modules can define their own types. The types of certificates for other modules can be found in their documentation.
    • id: Select which certificate will be removed. The id can be retrieved by a call to $.api.certificate.get.

Example:

await $.api.certificate.remove({
  moduleName: "bootstrap",
  type: "outbound",
  id: "pending/CENTRAL__N3uron__LinkManager[F07A91C73030507C4ABCB3689C46257A6E9406A5]",
  action: "remove",
});

$.api.module

$.api.module.details 

Function prototype: $.api.module.details(): Promise<ModuleDetails>

 This function is used to retrieve details about the current node (such as uptime, RAM usage, etc.) as well as details of the created modules (such as running status, license status, etc.). 

Example: 

const details = await $.api.module.details();

$.logger.info(JSON.stringify(details));

It returns a promise that resolves to the following object:

type ModuleDetails = {
    memoryUsage: {
        arrayBuffer: string,
        external: string,
        heapTotal: string,
        heapUsed: string,
        rss: string
    },
    modules: {
        [moduleName: string]: {
            api: null | {
                online: boolean,
                info: {
                    category: Array<"source" | "publisher">,
                    fileversion: string,
                    name: string,
                    releaseType: string,
                    requisites: {
                        exeVersion: undefined | {
                            min: string,
                            max: string
                        },
                        bootstrapVersion: undefined | {
                            min: string,
                            max: string
                        }
                    }
                    type: string,
                    version: string
                }, stats: {
                    tx: {
                        ok: number,
                        error: number
                    },
                    rx: {
                        ok: number,
                        error: number
                    }
                }
            },
            config: {
                required: boolean,
                type: string,
                start: {
                    enabled: boolean,
                    delay: number
                },
                monitor: {
                    enabled: boolean,
                    delay: number
                }
            },
            lastStart: null | string,
            lastStop: null | string,
            license: {
                acquired: boolean,
                mode: "production" | "demo",
                period: number,
                tagAccess: "local" | "remote"
            },
            mode: null,
            pid: null | number,
            running: boolean
        }
    },
    pid: number,
    running: boolean,
    ts: string,
    uptime: string
}

$.api.module.getConfig

Function prototype: $.api.module.getConfig<T>(moduleName: string): Promise<TagSourceConfiguration<T>>

This function is used to retrieve the configuration of the source tags belonging to a specific module. It returns a promise that resolves to an object containing the configuration of the source tags for the given module. It takes the following arguments: 

  • moduleName: Name of the module whose source tag configuration will be retrieved.

Example: 

const tagConfig = await $.api.module.getConfig("ModbusClient");

$.logger.info(JSON.stringify(tagConfig));

The following snippet is an example of the source tag configuration for a ModbusClient module:

type TagSourceConfiguration<ModbusClient> = {
    [
    tagPath: string]: {
        type: "number" | "boolean" | "string",
        link: null | string,
        data: {
            value: number | string | boolean | null,
            quality: number,
            ts: number
        },
        source: {
            device: string,
            address: string,
            type: string,
            rate: number
        }
    }
}


$.api.module.getConfigData

Function prototype: $.api.module.getConfigData(moduleName: null|string, configName: string): Promise<ConfigData>

This function is used to retrieve a specific configuration from a module. It returns a promise that resolves to the configuration of that module. The configuration is the raw unprocessed configuration. It is the same as if reading the respective configuration.n3c file. It takes two arguments: 

  • moduleName: Name of the instance whose configuration will be retrieved. If set to null, it will retrieve a configuration from bootstrap (such as tags or links).
  • configName: Name of the configuration that will be retrieved. This can be found by using $.api.module.getConfigList.

Example: 

const configData = await $.api.module.getConfigData("Historian", "logger");

$.logger.debug(JSON.stringify(configData));

$.api.module.getConfigList

Function prototype: $.api.module.getConfigList(moduleType: string): Promise<ConfigList>

This function is used to retrieve the different configurations available to a module (such as the default configuration, the logger configuration, etc...). It takes one argument: 

  • moduleType: Type of module whose configuration will be retrieved. This is independent of the module's instance name since it doesn't refer to a specific instance (for example, ModbusClient can have an MC or Modbus instances, but the type is ModbusClient).

Example: 

const configList = await $.api.module.getConfigList("Historian");

$.logger.info(JSON.stringify(configList));

The return value is a promise that resolves to the list of configurations available to the specified module type. The structure of this object can be seen in the next type definition:

type ConfigList = {
    [
    configName: string]: {
        text: string,
        icon: string
    }
}

$.api.module.getConfigPresent

Function prototype: $.api.module.getConfigPresent(moduleName: string): Promise<ConfigPresent>

This function is used to retrieve which configuration files are present (such as the default configuration, the logger configuration, etc...). It takes one argument: 

  • moduleName: Name of the instance whose configuration will be checked.

Example: 

const configPresent = await $.api.module.getConfigPresent("OpcUaClient");

$.logger.info(JSON.stringify(configPresent));

The return value is a promise that resolves to an object containing information about which configurations are present. The structure of this object can be seen in the next type definition:

type ConfigPresent = {  [configName: string]: boolean}

$.api.module.getInstalled

Function prototype: $.api.module.getInstalled(options: {}): Promise<string[]>

This function is used to retrieve a list of the modules installed in the current node. It takes no arguments and returns a promise that resolves to an array of strings containing the name of the installed modules.

Example: 

const modules = await $.api.module.getInstalled({});

for (const module of modules) {
   $.logger.info(module);
}


$.api.module.setConfigData

Function prototype: $.api.module.setConfigData(moduleName: null|string, configName: string, configData, options: {}): Promise<void>

 This function is used to update the configuration of a module. It takes four arguments: 

  • moduleName: Name of the instance whose configuration will be updated. If null, it affects configurations of bootstrap (such as tags or links).
  • configName: Name of the configuration that will be updated. The various configuration names for a module can be retrieved with $.api.module.getConfigList.
  • configData: New configuration that will be saved to disk for the specified module. The configuration must be in a valid format, that is, it needs to follow the same format as $.api.module.getConfig (in general, the easiest way to ensure the format is correct is to retrieve the configuration and modify it).
  • options
    • restart: Restarts module after saving new configuration (optional parameter)
    • deleteData: Only applicable to the module configuration file. List of deleted module instances for cleaning their data. Can be a single instance, a comma-separated list, or a JSON array (optional parameter).

Example:

const config =
  '{"version":{"main":1,"editor":2},"result":["Object",{"bufferLimit":["Number",500000],"maxDays":["Number",60],"db":["Object",{"run":["Boolean",false],"protocol":["String","mongodb"],"host":["String","db-mongo.internal"],"port":["Number",27017],"database":["String","n3-history"],"parameters":["String",""],"auth":["Object",{"enabled":["Boolean",false],"username":["String",""],"password":["SecuredString",""]}],"tls":["Object",{"enabled":["Boolean",false],"ca":["String",""],"rejectUnauthorized":["Boolean",true]}]}]}],"editor":{"extends":{"module":null},"modified":1711467825068,"comment":"","UID":0}}';

try {
  await $.api.module.setConfigData("Historian", "default", config, {
    restart: true,
  });
} catch (error) {
  $.logger.error(error);
}

$.api.backup

$.api.backup.create 

Function prototype: $.api.backup.create(name: string, metadata: {user: string, description: string}): Promise<void> 

This function creates a new backup of the current node configuration. The newly created backup will be saved to N3uron/data/bootstrap/backup. It takes two arguments:

  • name: Name of the backup that will be created.
  • metadata.user: User that created the backup. This can be any string and doesn't have to be an existing user.
  • metadata.description: Description of the backup.

Example: 

  await $.api.backup.create("20240623-backup", {
    user: "scripting",
    description: "Automatic backup created with Scripting.",
  });

$.api.backup.delete

Function prototype: $.api.backup.delete(name: string}): Promise<void> 

This function deletes a backup from the current node. It takes one argument:

  • name: Name of the backup that will be deleted.

Example: 

const backupName = "20240317-backup";

try {
  await $.api.backup.delete(backupName);
  $.logger.info("Backup deleted => %s", backupName);
} catch (error) {
  $.logger.error("Failed to delete backup %s: %v", backupName, error);
}

$.api.backup.export

Function prototype: $.api.backup.export(name: string): Promise<string> 

This function exports a backup from the current node. The return value is a promise that resolves to a base64 string of the backup files's binary content (in .zip format). It takes one argument:

  • name: Name of the backup that will be exported.

Example: 

const fs = require("fs");

const backupName = "20240317-backup";
const content = await $.api.backup.export(backupName);
const decodedContent = Buffer.from(content, "base64");

try {
  fs.writeFileSync(
    "/var/n3uron/backups/" + backupName + ".zip",
    decodedContent
  );
  $.logger.info("Backup exported => %s", backupName);
} catch (error) {
  $.logger.error("Failed to export backup to disk: %v", error);
}

$.api.backup.get

Function prototype$.api.backup.get(): Promise<Backups> 

This function retrieves the list of backups present in the current node. The return value is a promise that resolves to the following object:

type Backups = {
    [name: string]: {
        description: string,
        user: string,
        node: string,
        ts: string,
        version: {
            [modName: string]: string
        }
    }
}

Example: 

const backups = await $.api.backup.get();

$.logger.info("Found %d backups", Object.keys(backups).length);

$.api.backup.import

Function prototype$.api.backup.import(name: string, data: string): Promise<void>

This function imports a backup to the current node. It takes two arguments:

  • name: Sets the name of the backup after it is imported.
  • data: Base64 encoded data of a backup, either obtained through $.api.backup.export, or by encoding a valid .zip backup file into base64.

Example:

const fs = require("fs");
const path = "/var/n3uron/backups/20240404.1651.zip";

try {
  const backupFile = fs.readFileSync(path);
  const encodedData = Buffer.from(backupFile).toString("base64");
  $.api.backup.import("test", encodedData);

  $.logger.info("Backup imported => %s", path);
} catch (error) {
  $.logger.error("Failed to import backup: %v", error);
}

$.api.backup.load

Function prototype$.api.backup.load(name: string, options: {rollback: boolean}): Promise<void> 

This function applies the configuration of a backup to the current node. It takes two arguments:

  • name: Select which backup will be loaded.
  • options.rollback: When true, if the backup loading fails, the configuration will be rolled back to the previous configuration. Otherwise, the backup loading process proceeds, ignoring any errors that might result in invalid configuration for some modules.

Example:

try {
  await $.api.backup.load("20240404.1651", { rollback: true });
} catch (error) {
  $.logger.error(error);
}

$.api.backup.rename

Function prototype$.api.backup.rename(from: string, to: string): Promise<void> 

This function renames the specified backup. It takes two arguments:

  • from: The original name of the backup that will be renamed.
  • to: The final name of the backup after being renamed.

Example:

await $.api.backup.rename("20240404.1651", "monthly-04");

$.api.redundancy

$.api.redundancy.status

Function prototype: $.api.redundancy.status(options: {}): Promise<RedundancyStatus>

This function is used to retrieve the status of the redundancy mode.

Example: 

const status = await $.api.redundancy.status({});

$.logger.info(JSON.stringify(status));


$.api.redundancy.sync

Function prototype: $.api.redundancy.sync(paths: string[], absolute: bool): void

This function is used to synchronize files between the primary and backup nodes when using redundancy. As such, it doesn't do anything if redundancy is not enabled. It takes two arguments:

  • paths: An array of paths that will be synchronized between the redundant nodes.
  • absolute: This flag selects how the paths will be synchronized between the nodes. If it's false, the paths will be relative to the N3uron base folder (for example, when synchronizing files in N3uron/data between two N3uron instances installed in different paths). If it's true, the absolute path will be used so that files will be in the same location in both nodes.

Example:

try {
  await $.api.redundancy.sync(["data/ExampleModule"], false);
} catch (error) {
  $.logger.error(error);
}

$.api.redundancy.unsync

Function prototype$.api.redundancy.unsync(paths: string[], absolute: bool): void

This function is used to stop the synchronization of files between the primary and backup nodes when using redundancy. As such, it doesn't do anything if redundancy is not enabled. When executing $.api.redundancy.unsync, it will carry out one last synchronization of the paths to synchronize their current state before stopping any further synchronization. It takes two arguments:

  • paths: An array of paths that will be synchronized between the redundant nodes.
  • absolute: This flag selects how the paths will be synchronized between nodes. If it's false, the paths will be relative to the N3uron base folder (for example, when synchronizing files in N3uron/data between two N3uron instances installed in different paths). If it's true, the absolute path will be used, so the files will be in the same location in both nodes.

Example:

try {
  await $.api.redundancy.unsync(["data/ExampleModule"], false);
} catch (error) {
  $.logger.error(error);
}

$.api.tag

$.api.tag.browse

Function prototype$.api.tag.browse(path: string, options:{hideTags?: boolean, hideGroups?: boolean, recurrent?: boolean, flat?: boolean}): Promise<BrowseResultObject|Array<string>> 

This function lists the tags and groups present in a given path, and optionally, in all of the sublevels of that path. It takes two arguments: 

  • path: Select which tag group to browse. To browse the root path, this argument should be ‘/’. The path must end with a trailing /.  
  • options.hideTags: If true, tags are excluded from the result.
  • options.hideGroups: If true, groups are excluded from the result.
  • options.recurrent: If true, the result will also include tags and groups in the sub-levels of the given path.
  • options.flat: If true, returns an array with the full paths of all the tags at the given paths (and in sub-levels if recurrent is set). This option only returns tags. It does not return groups and as such, it cannot be used to list the groups in a given path.

Example:

const result = await $.api.tag.browse("/", {
  hideTags: false,
  hideGroups: false,
  recurrent: true,
  flat: false,
});

$.logger.info(JSON.stringify(result));

The return value of this function is a promise that can resolve to either an array of strings (if options.flat is set) or the following object:

type BrowseResultObject = {
    tags: Array<string>,
    groups: {
        [name: string]: BrowseResultObject
    }
}


$.api.tag.read

Function prototype: $.api.tag.read(path: string, {recurrent: boolean, filter: string}): Promise<TagData|GroupReadResult>

This function reads the value of a tag, or several tags, present in the given path. It takes two arguments:

  • path: Selects the tag or group that will be read. If the path is a group, it must end in *.  
  • options.recurrent: If true, the tag values in the sub-levels of the given group will also be read. This only applies when the path is a group.
  • options.filter: When present, only tags that match the filter will be read. This is a string that will be converted to a regular expression with the "ignore case" flag set.

Example:

const tag = await $.api.tag.read("/SITE_01/Temperature", {
  recurrent: false,
});

$.logger.info(JSON.stringify(tag));

The return value of this function is a promise that resolves to one of the following objects, depending on the arguments:

  • If the path refers to a tag, it resolves to TagData.  
  • If the path refers to a group, it resolves to GroupReadResult.
type TagData = {
    data: {
        value: null | number | string | boolean,
        quality: number,
        ts: number
    },
    status: {
        value: 0 | 1,
        ts: number
    }
}

type GroupReadResult = {
    groups: {
        [name: string]: GroupReadResult
    },
    tags: {
        [name: string]: TagData
    }
}

$.api.tag.details

Function prototype: $.api.tag.details<T>(path: string, {recurrent: boolean, filter: string}): Promise<TagDetails<T>|GroupDetailsResult<T>>

This function retrieves details about a tag or tags present in a tag group. It takes two arguments: 

  • path: Select the tag or group that will be queried for details. If the path is a group, it must end in *.
  • options.recurrent: If true, the details of the tags in the sub-levels of the given group will also be retrieved. This only applies when the path is a group.
  • options.filter: When present, only tags that match the filter will be queried. This is a string that will be converted to a regular expression with the "ignore case" flag set.

Example: 

const details = await $.api.tag.details("/*", {
  recurrent: true,
  filter: "Turbine",
});

$.logger.info(JSON.stringify(details));

The return value of this function is a promise that resolves to one of the following objects, depending on the arguments:

  • If the path refers to a tag, it resolves to TagDetails<T>.  
  • If the path refers to a group, it resolves to GroupDetailsResult<T>.
type TagDetails<T> = {  fullPath: string,  remote: null|string,  status: {    value: 0|1,    ts: number  },  data: {    value: null|number|string|boolean,    quality: number,    ts: number  },  config: {    clientAccess: "R"|"RW",    deadband: "string",    default: string,    description: string,    engUnits: string,    format: null|string,    persistency: 0|1|2,    security: {},    simulation: {      enabled: boolean     },    type: "number|string|boolean",    views: Array<string>,    extensions: {      ae: {        alarms: {          [name: string]: {            enabled: boolean,            description: string,            limit: number,            priority: 1|2|3|4,            mode: "ge"|"gt"|"le"|"lt"|"eq"|"ne"          }        }      },      history: {        enabled: boolean,        module: string,        config: {          deadband: string,          defaultMethod: "first"|"last"|"min"|"max"|"avg",          interpolation: "linear"|"step",          mode: "change",          rangeY: [min: number, max: number],          rate: [min: number, max: number]        }      },      scaling: {        enabled: boolean,        raw: [min: number, max: number],        eu: [min: number, max: number],        clamp: [min: boolean, max: boolean]      },      source: {        enabled: boolean,        module: string,        type: string,        config: TagConfiguration<T>      }    }  }}type GroupDetailsResult<T> = {  groups: {    [name: string]: GroupDetailsResult<T>  },  tags: {    [name: string]: TagDetails<T>  }}


$.api.tag.history

Function prototype: $.api.tag.history(tag: string, start: number, end: number, options: {mode: "raw"|"aggregated"|"filter"|"delta", method?: null|"first"|"last"|"min"|"max"|"avg", interval?: number, deadband?: number}): TagHistory

This function is used to query historical data from a tag. It takes four arguments:

  • tag: Select the tag that will be queried for historical data.
  • start: Select the start date of the query. This is a date in UNIX Epoch format with milliseconds.
  • end: Select the end date of the query. This is a date in UNIX Epoch format with milliseconds.
  • options.mode: Selects how the data is retrieved. More information about the different ways of retrieving data can be found at N3uron Historian.
  • options.method: Selects the aggregation method that is used when retrieving the data (only applies when the mode is "aggregated"). If set to null, it uses the method defined in the tag configuration. More information about the different aggregation methods can be found at N3uron Historian.
  • options.interval: Selects the aggregation interval, displayed in milliseconds (only applies when the mode is "aggregated").
  • options.deadband: Selects the deadband used when retrieving the data (only applies when the mode is "delta" or "filter").
  • options.invalidAsNull: Converts non-good quality values to null when using raw mode (optional parameter, by default it is enabled).
  • options.limit: Maximum number of samples to return when using raw mode (optional parameter)

Example:

const history = await $.api.tag.history("/PLANT_01/ACTIVE_POWER", 1642214400000, Date.now(), {
  mode: "raw",
});

$.logger.info(JSON.stringify(history));

The return value of the function is a promise that resolves to the following object:

type TagHistory = {  request: {    tag: string,    start: number,    end: number,    options: {      remoteNode?: true|string|string[],      mode: "aggregated"|"raw"|"filter"|"delta",      method?: "first"|"last"|"min"|"max"|"avg",      interval?: number,      deadband?: number    },    data: Array<[ts: number, value: null|number|string|boolean]>  }}

TagHistory.request is a copy of the arguments that were passed when executing the historical request. 

$.api.tag.write

Function prototype: $.api.tag.write(tag: string, value: null|number|string|boolean, options: {}): Promise<void>

This function is used to write a value to a tag. It takes three arguments:

  • tag: Select the tag that will be written.
  • value: Select the value that will be written to the tag. The type must match the tag type, otherwise, the write may fail or the written value might not be correct.
  • options: Empty options object.

Example:

await $.api.tag.write('/SITE02/Speed', 200, {});

$.api.tag.getViews

Function prototype: $.api.tag.getViews(options: {}): Promise<Array<string>>

This function retrieves the views available in the current node. It takes one argument:  

  • options: Empty options object.

The return value of this function is a promise that resolves to an array of strings containing the views available in the current node.

Example: 

const views = await $.api.tag.getViews({});

$.logger.info("Found %d views.", views.length);


$.api.tag.update

Function prototype: $.api.tag.update(tag: string, value: null|number|string|boolean, quality?: number, ts?: number, force?: boolean): void

This function is used to generate an update event on a Scripting source tag using its tag path (it cannot be used to update tags whose source is not Scripting). It takes five arguments:  

  • tag: Sets the path of the tag that will be updated. If the path is invalid or the tag is not a Scripting source tag, a warning will be logged and the tag will not be updated.
  • value: Sets the value of the tag update event. The type depends on the type of the tag and if the types do not match, it is implicitly converted, if possible. This is not recommended, since implicit conversion is not always valid ("hello world" can't be converted to a number) and can result in invalid values.
  • quality: Sets the quality of the tag update event. This value is optional and if not provided, the tag will be automatically updated with good quality (192). N3uron uses an enum for the different qualities that can be found at $.qualityCodes. However, any number in the 0-255 range is valid.
  • ts: Sets the timestamp of the tag update event. The format is a number in UNIX Epoch with milliseconds. This value is optional and if not provided, the event timestamp will be set to the current time.  
  • force: If set, the function will always generate a new tag event, even if the value or quality does not change. Otherwise, a tag event willonly be generated if the value or quality changes.

Example:

$.api.tag.update("/SITE02/ComputedByScripting", 5682, 48);

$.api.tag.updateAlias

Function prototype: $.api.tag.updateAlias(alias: string, value: null|number|string|boolean, quality?: number, ts?: number, force?: boolean): void

This function is used to generate an update event on one or various Scripting source tags using its tag alias (since multiple tags can have the same alias, it can be used to update multiple tags at once with the same value). It takes five arguments:  

  • alias: Selects the alias that will be used to generate tag events. All of the tags with matching aliases will be updated. If the alias is non-existent, a warning will be logged and the tag will not be updated.
  • value: Sets the value of the tag update event. The type depends on the tag type and if the types do not match, it is implicitly converted, if possible. This is not recommended, since implicit conversion is not always valid ("hello world" can't be converted to a number) and can result in invalid values.
  • quality: Sets the quality of the tag update event. This value is optional and if not provided, the tag will be automatically updated with good quality (192). N3uron uses an enum for the different qualities that can be found at $.qualityCodes. However, any number in the 0-255 range is valid.
  • ts: Sets the timestamp of the tag update event. The format is a number in UNIX Epoch with milliseconds. This value is optional and if not provided, the event timestamp will be set to the current time.  
  • force: If set, the function will always generate a new tag event, even if the value or quality does not change. Otherwise, a tag event willonly be generated if the value or quality changes.

Example:

$.api.tag.updateAlias("Speed", 82, 192););

$.api.tag.browseSource

Function prototype: $.api.tag.browseSource(path: string, {recurrent: boolean}): Promise<Array<string>> 

This function returns all the Scripting source tags present in the given path. It takes two arguments:  

  • path: Selects the path that will be browsed. This path must start and end with a “/”. Otherwise, the browse will fail.
  • options.recurrent: When set, it will return tags from the given group, as well as any sub-levels that are present. Otherwise, only tags present in the given group will be returned.

This function returns a promise that resolves to an array of tag paths for all the tags that were browsed.

Example: 

const tags = await $.api.tag.browseSource("/", { recurrent: true });

for (const tag of tags) {
  $.logger.info(tag);
}

$.api.tag.browseAlias

Function prototype: $.api.tag.browseAlias (): Promise<TagAliasList>

This function is used to retrieve all of the tag aliases and the tags that they refer to that are present in the tag models' Scripting source tags. It takes no arguments and returns a promise that resolves to the following object:

type TagAliasList = {  [alias: string]: Array<string>}

Example: 

const aliases = await $.api.tag.browseAlias();

$.logger.info(JSON.stringify(aliases));

$.api.tag.subscribe

Function prototype: $.api.tag.subscribe(tags: Array<string>, handler: (tag: string, data: {value: number|string|boolean|null, quality: number, ts: number}, initial: boolean) => void): symbol

This function is used to subscribe to tag events from a list of tags. It takes three arguments:

  • tags: Selects tags that are part of the subscription. If only one tag is needed, an array of one element must be used.
  • handler: Sets the callback that will be called whenever the given tags emit an update event. The callback will be called with the following arguments:
    • tag: Path of the tag that generated the update event.
    • data.value: Contains the tag value of the event.
    • data.quality: Contains the tag quality of the event.
    • data.ts: Contains the tag timestamp of the event, displayed as a number in UNIX Epoch format with milliseconds.
    • initial: If true, it indicates that the event was received in response to a new subscription (such as when the tag model changes). Otherwise, it's a normal event.

This function returns a symbol, which can then be used to cancel the subscription by calling $.api.tag.unsubscribe using the returned symbol.

Example: 

const sub = await $.api.tag.subscribe(["/SITE_02/Wind_Speed"], onTagEvent);

function onTagEvent(tag, data) {
  $.logger.info(JSON.stringify(data));
}

$.api.tag.unsubscribe

Function prototype: $.api.tag.unsubscribe(subscription: symbol): void

This function is used to cancel a previous subscription. It takes one argument:

  • subscription: Select which subscription will be canceled based on the provided symbol. This symbol must have been created by $.api.tag.subscribe.

Example: 

$.api.tag.unsubscribe(sub);

$.api.alarm

$.api.alarm.get

Function prototype: $.api.alarm.get(path: string, options: {recurrent: boolean, filter: {path: string, status: Array<number>, priority: number}}): Promise<Array<TagAlarmData>>

This function is used to retrieve the tag alarms present in a given path. It takes two arguments:

  • path: Sets the path that will be browsed for alarms. This must refer to a tag group.
  • options.recurrent: When set, alarms for the given group, as well as any sub-groups, will be retrieved. Otherwise, only alarms present in the given sub-group will be returned.
  • options.filter.path: Sets a regular expression that will be used to filter alarms based on their full path. If the regular expression matches, the alarm will be shown in the result.
  • options.filter.status: Select which alarms will be shown in the result based on their status. This can be set to null to retrieve all alarms independently of status, or it can be an array of numbers selecting which alarms to retrieve based on the following criteria: This is an array containing one or more of the following status codes:
    • 0: Cleared and acked 
    • 1: Active and acked
    • 2: Cleared and unacked
    • 3: Active and unacked
  • options.filter.priority: Select the minimum alarm priority that will be shown in the result. A value of null or 0 will retrieve all alarms. Otherwise, one of the following priority codes can be used:
    • 0: Low priority
    • 1: Medium priority
    • 2: High priority
    • 3: Critical priority

Example:

const alarms = await $.api.alarm.get("/", {
  recurrent: true,
  filter: {},
  priority: 2,
});

$.logger.info(JSON.stringify(alarms));

The return value of this function is a promise that resolves to an array of the following object:

type TagAlarmInfo = {  path: string,  description: string,  priority: number,  remote: Nullable<string>,  online: 0|1,  status: 0|1,  ts: number,  value: tag.TagEvent,  format: Nullable<string>,  ackInfo: null | {    msg: string,    user: string,    options: {},    node: string,    module: string  }}

$.api.alarm.count

Function prototype: $.api.alarm.count(path: string, options: {recurrent: boolean, filter: {path: string, status: Array<number>, priority: number}}): Promise<number>

This function is used to retrieve the number of alarms present at a given path that match a filter (such as number of active and unacked alarms). It takes two arguments:

  • path: Sets the path that will be browsed for alarms. This must refer to a tag group.
  • options.recurrent: When set, alarms for the given group, as well as any sub-groups, will be retrieved. Otherwise, only alarms present in the given sub-group will be returned.
  • options.filter.path: Sets a regular expression that will be used to filter alarms based on their full path. If the regular expression matches, the alarm will be shown in the result.
  • options.filter.status: Selects which alarms will be shown in the result based on their status. This can be set to null to retrieve all alarms independently of status, or it can be an array of numbers selecting which alarms to retrieve based on the following criteria: This is an array containing one or more of the following status codes:
    • 0: Cleared and acked 
    • 1: Active and acked
    • 2: Cleared and unacked
    • 3: Active and unacked
  • options.filter.priority: Selects the minimum alarm priority that will be shown in the result. A value of null or 0 will retrieve all alarms. Otherwise, one of the following priority codes can be used:
    • 0: Low priority
    • 1: Medium priority
    • 2: High priority
    • 3: Critical priority

The return value of this function is a promise that resolves to the number of alarms that match the filter.

const count = await $.api.alarm.count("/", {
  recurrent: true,
  filter: {},
  priority: 0,
});

$.logger.warn("Found %d active alarms", count);

$.api.alarm.history

Function prototype: $.api.alarm.history(path: string, start: number, end: number, options: {recurrent: boolean, filter: {path: string, status: Array<number>, priority: number}}): Promise<TagAlarmHistory>

This function is used to query historical alarm data. It takes four arguments:

  • path: Sets the path that will be browsed for alarms. This must refer to a tag group.
  • start: Selects the start date of the query. This is a date in UNIX Epoch format with milliseconds.
  • end: Selects the end date of the query. This is a date in UNIX Epoch format with milliseconds.
  • options.recurrent: When set, alarms for the given group, as well as any sub-groups, will be retrieved. Otherwise, only alarms present in the given sub-group will be returned.
  • options.filter.path: Sets a regular expression that will be used to filter alarms based on their full path. If the regular expression matches, the alarm will be shown in the result.
  • options.filter.status: Selects which alarms will be shown in the result based on their status. This can be set to null to retrieve all alarms independently of status, or it can be an array of numbers selecting which alarms to retrieve based on the following criteria: This is an array containing one or more of the following status codes:
    • 0: Cleared and acked 
    • 1: Active and acked
    • 2: Cleared and unacked
    • 3: Active and unacked
  • options.filter.priority: Selects the minimum alarm priority that will be shown in the result. A value of null or 0 will retrieve all alarms. Otherwise, one of the following priority codes can be used:
    • 0: Low priority
    • 1: Medium priority
    • 2: High priority
    • 3: Critical priority

Example:

const history = await $.api.alarm.history(
  "/FAKE001",
  1712422694,
  1712522694,
  {
    recurrent: true,
    filter: { priority: 3 },
  }
);

$.logger.info(JSON.stringify(history));

The return value of this function is a promise that resolves to the following object (where request is a copy of the historical request): 

type TagAlarmData = {  path: string,  description: string,  priority: number,  remote: Nullable<string>,  online: 0|1,  status: 0|1,  ts: number,  value: tag.TagEvent,  format: Nullable<string>,  ackInfo: null | {    msg: string,    user: string,    options: {},    node: string,    module: string  }};type TagAlarmHistory = {  request: {    path: string,    start: number,    end: number,    options: {      recurrent?: boolean,        filter: {          path?: string,          status?: Nullable<Array<number>>,          priority?: Nullable<number>        }    }  },  data: Array<TagAlarmData>};

$.api.alarm.ack

Function prototype: $.api.alarm.ack(paths: string|Array<string>, msg: string, user: string, options: {}): Promise<void>

This function is used to acknowledge one or multiple alarms with a message and the user that executed the acknowledgement. It takes three arguments:

  • paths: Selects which alarm will be acknowledged. It can be either a single alarm, or a list of alarms. The path must be a path to the specific alarm that will be acknowledged, not a path for the tag that declares the alarm (alarm paths are formed of TAG_PATH.ALARM_NAME). For example, if the tag /C01/TemperatureAlarm has a “HiHi" alarm, the path of the alarm would be /C01/TemperatureAlarm.HiHi
  • msg: Sets the acknowledgment message for the specified alarm.
  • (String) user: User who acknowledged the alarm.
  • (Function) callback (err): This callback will be called once the acknowledgement request finishes. It has the following arguments:
    • (String) err: Error message if the operation fails, or null if it succeeds.

Example: 

await $.api.alarm.ack("/Site01/Temperature.TestAlarm", "Example message", "user", {});

$.qualityCodes

This enumeration provides different OPC quality codes that can be used to compare against the quality value of a tag. The different qualities, along with their values are:

$.qualityCodes = {  BAD_NON_SPECIFIC: 0x00, //0  BAD_CONFIG_ERR0R: 0x04, //4  BAD_NOT_CONNECTED: 0x08, //8  BAD_DEVICE_FAILURE: 0x0C, //12  BAD_SENSOR_FAILURE: 0x10, //16  BAD_LAST_KNOWN_VALUE: 0x14, //20  BAD_COMM_FAILURE: 0x18, //24  BAD_OUT_OF_SERVICE: 0x1C, //28  BAD_UNINITIALIZED: 0x20, //32   UNCERTAIN_NON_SPECIFIC: 0x40, //64  UNCERTAIN_LAST_USABLE_VALUE: 0x44, //68  UNCERTAIN_SENSOR_NOT_ACCURATE: 0x50, //80  UNCERTAIN_EU_UNITS_EXCEEDED: 0x54, //84  UNCERTAIN_SUB_NORMAL: 0x58, //88  GOOD_NON_SPECIFIC: 0xC0, //192  GOOD_LOCAL_OVERRIDE: 0xD8 //216}

cron library

cron is an internal N3uron library used for both validation of cron syntax, as well as parsing and retrieving the next (or several future) time(s) when the expression must execute. When retrieving this library, an object will be returned with two keys; one which acts as cron expression validation and the other as a scheduler.

const cron = $.lib("cron");//cron has the following format:type cron =  {  validate: function(string),  schedule: typeof cron-schedule}

validate(expression: string): Result<void, string[]>

The validate function is used to validate a cron expression. This function is a simplified version of cron-validate, where it only takes a single string argument (no options required). The return type is the same as cron-validate since it returns a Result-type. An example of the validate function can be seen in the below code snippet:

const cron = $.lib("cron");const expression = "* * * * *";const result = cron.validate(expression);if(result.isError()){  $.logger.warn("Invalid cron expression");  for(const errMsg of result.getError()){    $.logger.warn(errMsg);  }}

Schedule

The schedule key contains the default export for the cron-schedule library. As such, any code that is valid with that library is equivalent to using cron.schedule. The next code snippet shows an example of how to get the next value assigned a cron expression:

const cron = $.lib("cron");const expression = "0,15,30,45 * * * *";const schedule = cron.schedule.parseCronExpression(expression);const nextDate = schedule.getNextDate();$.logger.debug(nextDate);

xlsxwriter library

xlsxwriter is an internal N3uron library that can be used for basic data ingestion to Microsoft Excel XLSX files. The library exports the following functions and classes:

Workbook

The workbook class represents an XLSX workbook, which is composed of one or several sheets. This class can't be directly constructed. Instead, a new Workbook is created using the static asynchronous Open method. Workbooks have the following methods:

static Open(path: string): Promise<Workbook>

This static method is used to open a new XLSX workbook at a given path.

getSheet(id: string|index): Promise<Worksheet>

This method is used to retrieve a worksheet from the current workbook. In order to select which worksheet will be retrieved, a worksheet id must be provided. This can be either a number, in which case it's the index of the worksheet, or a string corresponding to the name of the worksheet.

setCalculateFlag(): Promise<void>

This method sets the "calculate on open" flag on the workbook. When set, the next time the workbook is opened in Microsoft Excel, all of the cells of the workbook are recalculated. If not set, the cells will keep their current cached values. If a cell is affected by a modification using this library (whether it's directly affected or one of its dependencies is affected), this flag must be set, otherwise, the modification won't be propagated.

save(path: string): Promise<void>

This method saves the workbook to the given path. 

 Worksheet

The worksheet class represents a worksheet in the current workbook. This class can't be directly constructed. Instead, an instance of it is created by the getSheet method of the workbook. It has the following methods:

writeData(data: any[][], startRow: number, startColumn: number): Promise<Worksheet>

This method writes new data to the worksheet, overwriting any existing data. It takes the following arguments:

  • data: Data that will be written to the worksheet as an array of rows, where each row is also an array.
  • startRowSelects which column will be written as the first row of the data. The data will write rows, starting from startRow up to the length of each row in data.
  • startColumn: Selects which column will be written as the first column of the data. The data will write columns starting from startColumn until it has written all the columns in data.

appendData(data: any[][], startRow: number, startColumn: number): Promise<Worksheet>

This method appends new data to the worksheet, keeping any existing data if the cells already contain data. It takes the same arguments as writeData.



Was this article helpful?