EN

Creating a handler

To create a new handler, go to the Handlers tab. Add handler by clicking on the plus sign.
Fill in the following fields:
  • name - name of the handler;
  • description - detailed description of the handler, to be filled in if necessary; description - detailed description of the handler if necessary;
  • default parameters - behavior of the handler when receiving a packet of data packet that does not contain the required input arguments:
    • take last sent value - the values of missing parameters in the packet will be substituted by the last received value for these parameters. parameters missing in the packet will be substituted by the last received value for these parameters. parameters. For example, in the handler you calculate the effective temperature on the basis of two input values: temperature and humidity. two input values: temperature and humidity, but they come not in one package, but in different in one packet, but in different ones, sequentially. Then when you receive only temperature, the handler itself will take the last received humidity value for calculation, and vice versa.
    • replace with "null " - "null" will be substituted for the values of parameters missing in the package. will be substituted with "null". For example, in the handler you calculate the average value of velocity on the basis of of the last ten values. However, you do not get the speed in every packet. If you choose the "take the last value sent" mode, then when you receive a packet without speed, the handler will take the last value. packet without speed, the handler will take the last speed value and calculate for it. and calculate for it. You will get an incorrect output value. If you choose the "replace with "null" mode, then you can handle this situation and not perform the calculation: if you receive a packet with no speed, the handler will take the last speed value and perform the calculation for it. and not perform the calculation:
      if (speed === null) {
        return {};
      }
Click the Create button. A ready template will open in front of you with a small code for calculating the sum of two input values. code to calculate the sum of two input values. Use it as a as an example of how the handler can be implemented.
  1. Save: Save the changes to the handler. If the handler was previously handler was previously run on objects, it will continue to work already in the updated version
  2. test: Open the test window, where you can enter input parameters and check the resulting output values. parameters and check the resulting output values
  3. Download .js: Export the handler to a JSON file.
  4. This part of the comment specifies an additional description of the handler
  5. This part of the comment specifies the login of the handler author
  6. This part of the comment specifies input parameters in the following format format
 * @param {<data_type>} <name> <description>
Example:
 * @param {string} rawData input data in base64 format
  1. The names of input parameters in parentheses are specified in the following format
function process(parameter_1, parameter_2, ..., parameter_n)
Example:
function process(rawData)
  1. Handler code that works with input parameters according to the given algorithm
  2. The names of output parameters are specified in curly brackets after the word return in the following format
return {parameter_1, parameter_2, ..., parameter_n};
Example:
return { time, hypotenuse };
💡
Hint: There can be multiple input and output parameters.

Built-in libraries and modules

Handlers support the ECMAScript standard up to ES2019. They also contain all standard JavaScript objects:
Look at the example of using some built-in standard libraries. You can work with them without connecting any additional modules.
While designing data processing and creating a handler, you may have may need to connect and use auxiliary functions. In addition to the standard libraries, a ric object has been added to the data processing architectural layer ric object, which includes additional methods, has been added to the data processing architectural layer:
  • event generation;
  • Base64 decoding;
  • organization of local storage.

Event generation

The following handler code allows you to generate event when the specified criterion is triggered for the sum of two input parameters. specified criterion for the sum of two input parameters.
/**
 * @param {number} a sample param 1
 * @param {number} b sample param 2
 */
 
function process(a, b) {
  const sum = a + b;
  if (sum > 25) {
    ric.events.gen("model-event-01", { sum });
  }
  return { sum };
}

Base64 decoding

The following handler code allows you to get the { lat, lon } parameters from the eight-byte buffer. ric.base64.decode takes a Base64 string and returns the JavaScript DataView (opens in a new tab).
/**
 * Parse { lat, lon } params from binary
 *
 * ```
 * +----------+----------+
 * | lat      | lon      |
 * +----------+----------+
 * | 32bit be | 32bit be |
 * | ieee 754 | ieee 754 |
 * +----------+----------+
 * ```
 *
 * @param {string} payload base64 encoded bytes
 */
function process(payload) {
  const buf = ric.base64.decode(payload);
 
  return {
    lat: buf.getFloat32(0),
    lon: buf.getFloat32(4),
  };
}
 
// test Ql8Z6EIWn/M=

Local Storage

If you need to work with device parameters that came from the device in the in past packages, you can save them to local storage and then use them. The following handler code allows you to store the last ten parameters received and return their number, sum, and average.
/**
 * Calc average of last 10 a's
 * @param {number} a sample param
 */
 
function process(a = 0) {
  /* init local store with default values (if empty)
     and reduce it with fresh values */
  const { counter, last10 } = ric.localStore.forObject
    .initWith({
      counter: 0,
      last10: [a],
    })
    .reduce((prev) => ({
      counter: prev.counter + 1,
      last10: [...prev.last10, a].slice(-10),
    }));
 
  /* calc sum and avg of last 10 values */
  const sum = last10.reduce((acc, val) => acc + val, 0);
  const avg = sum / last10.length;
 
  return {
    counter,
    sum,
    avg,
  };
}
💡
When developing large and complex code, take advantage of the additional You can open the list of additional features by right-clicking in the code area of the handler. in the code area of the handler. For example, there is a function of code auto-formatting.

Third-party libraries and modules

In addition to using already built-in handler features, you can connect third-party libraries by reference. The library itself must be written in in JavaScript and conform to the specification ESM (EcmaScript modules) (opens in a new tab).
Limitations on pluggable libraries:
  • maximum library size is 65 Kbytes;
  • code must use only standard JavaScript objects (opens in a new tab). If the library uses any extended APIs (e.g. Buffer from Node.js), or their built-in modules (e.g., fs, path), or browser APIs (fetch, WebSocket) (fetch, WebSocket), it will not work.
If the constraints are violated, the handler will not be saved.
You can use services to import already existing libraries from npm:

Import Javascript module

As an example, let's take a simple one from GitHub Javascript module (opens in a new tab), which counts the sum of two numbers
export function sum(a, b) {
  return a + b;
}
💡
Hint: You can use not only the GitHub repository, but also any You can use not only the GitHub repository, but also any other Internet addresses where the content of the module you want to import is available. of the module to be imported.
The following handler code allows you to sum two numbers by using an imported function from the module.
import { sum } from "https://raw.githubusercontent.com/rightech/ric-examples/master/handlers/lib/example.js";
 
function process(a, b) {
  const res = sum(a, b);
  return { sum: res };
}
💡
Important: Note that when importing modules from the GitHub repository. you must use their "raw" version, because otherwise the GitHub server will HTML page for viewing, but not the content of the file itself. To click the Raw button in the GitHub interface to get the desired link address.
💡
Tip: If you are confused that the word process becomes faint when third-party libraries are attached, add the word export before the word function. libraries, add the word export before the word function.

Import library from npm

As an example, let's take the package gps (opens in a new tab) service Skypack (opens in a new tab).
The following handler code allows you to parse the string received in NMEA format, and extract coordinates from it.
import GPS from "https://cdn.skypack.dev/gps@0.6.1";
 
function process(nmea) {
  const gps = new GPS();
 
  let lat = 0;
  let lon = 0;
 
  gps.on("data", (parsed) => {
    lat = parsed.lat;
    lon = parsed.lon;
  });
 
  gps.update(nmea);
 
  return { lat, lon };
}
💡
Tip: The library code is loaded and imported at the moment of saving the handler, so it is desirable to specify its working version right away. so it is advisable to specify its working version at once to avoid problems related to updating the imported package. to avoid problems related to updating the imported package.