Language Reference

Built-In Functions

let value = JSON.parse(str);

Parse JSON string and return parsed value.

let str = JSON.stringify(value);

Get string representation of the mJS value.

let proto = {foo: 1}; let o = Object.create(proto);

Create an object with the provided prototype.

'some_string'.slice(start, end);

Return a substring between two indices. Example: ‘abcdef’.slice(1,3) === ‘bc’;

'abc'.at(0);

Return numeric byte value at given string index. Example: ‘abc’.at(0) === 0x61;

'abc'.indexOf(substr[, fromIndex]);

Return index of first occurence of substr within the string or -1 if not found. ‘abc’.indexOf(‘bc’) === 1;

chr(n);

Return 1-byte string whose ASCII code is the integer n. If n is not numeric or outside of 0-255 range, null is returned. Example: chr(0x61) === ‘a’;

let a = [1,2,3,4,5]; a.splice(start, deleteCount, ...);

Change the contents of an array by removing existing elements and/or adding new elements. Example: let a = [1,2,3,4,5]; a.splice(1, 2, 100, 101, 102); a === [1,100,101,102,4,5];

let s = mkstr(ptrVar, length);

Create a string backed by a C memory chunk. A string s starts at memory location ptrVar, and is length bytes long.

let s = mkstr(ptrVar, offset, length, copy = false);

Like mkstr(ptrVar, length), but string s starts at memory location ptrVar + offset, and the caller can specify whether the string needs to be copied to the internal mjs buffer. By default it’s not copied.

System

Required library: load('api_sys.js');

void * Sys.malloc(int size)

Allocate a memory region. Memory allocated this way must be explicitly released with free().

Sys.free(void *memory_pointer)

Free memory previously allocated with malloc.

Sys.total_ram()

Return total available RAM in bytes.

Sys.free_ram()

Return free available RAM in bytes.

Sys.reboot(ms)

Reboot the system after ms milliseconds.

Sys.uptime()

Return number of seconds since last reboot.

Sys.usleep(microseconds)

Delay execution the given number of microseconds.

Config

Set and get values from the device’s config.

Required library: load('api_config.js');

Cfg.get(path)
Get a value from the device’s configuration.
path: the JSON path (using dot notation) of the setting to get.
Examples:
Cfg.get('device.id');          // returns a string
Cfg.get('accel.interval');     // returns an integer
Cfg.get('ambient.available');  // returns a boolean
Cfg.set(obj)
Set part of the device’s configuration.
obj: the JSON object to set.
Examples:
Cfg.set({input2: {digital: {alert: {enable: false}}}});

Warning

Incorrect use of the Cfg.set() function may lead to corruption of critical parameters, and result in bricking of the device. Use with caution.

Timers

Timers and time related functions.

Required library: load('api_timers.js');

Timer.set(milliseconds, flags, handler, userdata)
Setup timer with milliseconds timeout and handler as a callback. flags can be either 0 or Timer.REPEAT. In the latter case, the call will be repeated indefinitely (but can be cancelled with Timer.del()), otherwise it’s a one-off. Returns a numeric timer ID.

Example:

Timer.set(1000, Timer.REPEAT, function() {
  // This will repeat every second
  let s = "HELLO";
  SQ.serial_write(1, s, s.length);
}, null);

Warning

Be conscious of accidentally setting repeating timers from a function that itself is repeating (for instance from SQ.set_data_handler), as you will quickly run out of memory.

Timer.del(id)
Cancel a previously installed timer with given id.
let id = Timer.set( ... );  // Set timer, store the id
...
Timer.del(id);    // Cancel the previously set timer
id = 0;           // Explicitly clear the stored id (Important!)
Timer.now()
Return current time as double value, UNIX epoch (seconds since 1970).
Timer.fmt(fmt, time)
Formats the time time according to the strftime-like format specification fmt. The strftime reference can be found here.

Example:

let now = Timer.now();
let s = Timer.fmt("ISO8601 Time is: %FT%TZ", now);
dispatch(1, s); // Example output: "ISO8601 Time is: 2021-04-13T10:17:32Z"

Math

General mathematical functions.

Required library: load('api_math.js');

Math.ceil(x)
Rounds x upward, returning the smallest integral value that is not less than x.
Math.floor(x)
Rounds x downward, returning the largest integral value that is not greater than x.
Math.round(x)
Returns the integral value that is nearest to x, with halfway cases rounded away from zero.
Math.max(x, y)
Returns the larger of its arguments: either x or y. If one of the arguments is NaN, the other is returned.
Math.min(x, y)
Returns the smaller of its arguments: either x or y. If one of the arguments is NaN, the other is returned.
Math.abs(x)
Returns the absolute value of x.
Math.sqrt(x)
Returns the square root of x.
Math.exp(x)
Returns the base-e exponential function of x, which is e raised to the power x.
Math.log(x)
Returns the natural logarithm of x.
Math.pow(base, exponent)
Returns base raised to the power exponent
Math.sin(x)
Returns the sine of an angle of x radians.
Math.cos(x)
Returns the cosine of an angle of x radians.
Math.random()
Returns a pseudo-random number from 0.0 to 1.0

Senquip

Functions for interacting with data collection and the device’s peripherals.

Required library: load('senquip.js');

Constants:
  • SQ.INFO: 10

  • SQ.ALERT: 20

  • SQ.WARNING: 30

  • SQ.ALARM: 40

SQ.set_data_handler(function, userdata)
Registers a callback function that allows creation of new data parameters collected by the device.
function: A callback function, invoked when a measurement cycle is completed. The completed JSON data structure is passed to the callback function.
userdata: Some user data that is passed to the callback function. Set null if unused.
SQ.dispatch_double(index, value, precision)
Add new value to the device’s data message. If called multiple times for the same index value, only the first call will be written to the outgoing data message.
index: The index of the data parameter, starting from 1.
value: The numerical value of the data to be added.
precision: The number of decimal places to send in the data message. The value must be between 0 and 8 (inclusive). 0 means no decimal places.
SQ.dispatch_string(index, string, length)
Add a new string to the device’s data message. If called multiple times for the same index value, only the first call will be written to the outgoing data message.
index: The index of the data parameter, starting from 1.
string: The string to be added.
length: The number of characters in the string. Maximum 50.
SQ.dispatch_event(index, severity, message)
Add an event (alert, warning, alarm) to the device’s data message.
index: The index on the data parameter, starting from 1.
severity: The severity of the event. Should be one of SQ.INFO, SQ.ALERT, SQ.WARNING or SQ.ALARM
message: The event message string. Maximum 30 characters.
SQ.dispatch(index, value, len)
Helper function to dispatch either a number or string. If the len parameter is omitted, a default is used. The function consists of the following mJS code:
function dispatch(index, value, len) {
  if (typeof value === 'string') {
    if (typeof len === 'undefined') { len = value.length; }
    this.dispatch_string(index, value, len);
  }
  else if (typeof value === 'number') {
    if (typeof len === 'undefined') { len = 1; }
    this.dispatch_double(index, value, len);
  }
}
SQ.set_trigger_handler(function, userdata)
Registers a callback function that is called when a trigger button is activated from the Senquip Portal.
function: A callback function, invoked when a trigger button event occurs. The trigger parameter index number is passed into the callback function. For example: 5 is passed in for tp5.
userdata: Some user data that is passed to the callback function. Set null if unused.
SQ.set_output(channel, state, time_s)
Set the device’s output channel to the given state, for the given time.
channel: Output channel index. (1 for Output 1)
state: The new state of the output. (0 = OFF, 1 = ON)
time_s: The time to stay in the new state. Use 0 for a permanent state change. (5 = 5 seconds)
SQ.parse(string, start, length, base)
Convert a string to a number using the base given.
strings: The string to parse.
start: The starting character index. (0 = the first character in the string).
length: The number of characters in the string to parse from the start position.
base: The numerical base used when parsing the string. (10 = Decimal, 16 = Hexadecimal). A special case applies when when base is (-16): the byte order will be reversed.
Returns the parsed number, or 0 on error.
SQ.atob(string)
Decodes and returns the base 64 encoded input string.
string: A base 64 encoded string. The maximum input string length is 256 characters.
Returns the decoded string.
SQ.split(string, separator)
Takes an input string an splits it into parts using the seperator character.
string: The string to split
separator: The seperator character.
Returns the split up array of strings.
Example: SQ.split('1,2,,4', ',') returns ['1', '2', undefined, '4']
SQ.crc(data, length, algorithm_id)
Calculates a CRC on the specified input data and returns the CRC as an integer. The length parameter is optional, but should be specified if data contains a null character. The algorithm_id is optional, by default the Modbus CRC16 is calculated.
data: The input string.
length: (Optional) Number of bytes of the input data to use in the calculaion. Default: data.length
algorithm_id: (Optional) An integer to specify the algorithm. Default: 1 (Modbus CRC16)
Returns the CRC as an integer.
Example: SQ.crc('Hello') returns 62327

Serial

Functions for reading/writing serial data over the RS232/RS485 interface. All settings for the serial port are inherited from the device’s main configuration, and the Serial 1 Interval setting must be non-zero.

Required library: load('api_serial.js');

SERIAL.write(channel, string, length)
Write serial data out to the device’s RS232/RS485 port. This call can be used in all modes (Capture, Modbus and Scripted), however if the serial port is in use the string data will be queued until the port is available.
channel: Serial channel index. (1 = Serial 1)
string: The string to write.
length: The number of characters in the string. Maximum length is 256 bytes.
SERIAL.read(channel)
Read serial data from the device’s input buffer. This function is only guaranteed to work correctly when the Serial port is configured as ‘Scripting’ mode.
channel: Serial channel index. (1 = Serial 1)
SERIAL.read_avail(channel)
Return number of bytes received and waiting in the input buffer.
channel: Serial channel index. (1 = Serial 1)
SERIAL.set_handler(channel, function, userdata)
Registers a callback function that is called when there is a new data in the input buffer or when space becomes available on the output buffer.
channel: Serial channel index. (1 = Serial 1)
function: The callback function which receives the following arguments: (channel, userdata).
userdata: Some user data that is passed to the callback function. Set null if unused.

Example:

let data = "";
SERIAL.set_handler(1, function(channel) {
  // Keep adding to data string as characters arrive
  data = data + SERIAL.read(channel);
  // Process data string here
  // ...
  // Clear data string when completed
  data = "";
}, null);

Endpoint

Functions for sending data to custom endpoints.

Required library: load('api_endpoint.js');

MQTT.pub(topic, message)
Publish the given message on the topic for the MQTT Endpoint connection.
topic: The MQTT topic to publish on.
message: The message string to publish.
Example: MQTT.pub('data/topic', 'Message to publish')
HTTP.post(body, headers)
Publish the body and extra headers in a HTTP POST request to the url specified in the HTTP Endpoint settings.
body: The data string to put in the message body.
headers: (Optional) A string of extra HTTP Headers. Each header must end with \r\n.
Example: HTTP.post('Hello World!')

Warning

At this stage custom HTTP POST requests from the script are not retried or buffered if they fail. This will be addressed in a future release.

UDP.send(data, length)
Send the data in a UDP message to the url specified in the UDP Endpoint settings.
data: The data string to put in the message.
length: (Optional) Number of bytes of data to send. Default: data.length
Example: UDP.send('Hello World!')