Data Analytics NodeJS Guide¶
Overview¶
The Data Analytics functionality can be implemented as a Node.js script using the Node.js ZIOTC (Zebra IOT Connector) module resident on the reader.
The Node.js ZIOTC module is meant to abstract the underlying connections between the IoT Connector components (i.e. Radio Control and Reader Gateway) and allow the script filter, analyze, and act on the data itself.
The minimal flow of the script would be:
Define callback functions
New Message Callback: Operates on the incoming data. This function will be called whenever there is a new message to be filtered.
const onNewMessageCallback = (msg) => { ... };
For more details see New Message Callback
Passthru: Callback when the a new passthru message has been received from the reader gateway.
const onPassthruCallback = (msg) => { ... };
For more details see DA Passthru
OK: Callback when the module ends
const onOKCallback = (msg) => { ... };
error: Callback when the module encounters and error
const onNewErrorCallback = (msg) => { ... };
Open the ZIOTC module.
This will establish connections between the script and the other IoT Connector components.
const ziotc = require('./ziotc.node');
Set Data Source.
This will set the data source for incoming messages. The data source is set to CONNECT_FOR_RADIO_DATA by default. Refer to NodeJS API reference Guide for further details.
ziotc.SetDataSource("CONNECT_FOR_RADIO_DATA");
Register callbacks and Run ZIOTC
This will cause register the callback previously defined callback functions and run the module.
ziotc.Run(onErrorCallback, onOkCallback, onNewMessageCallback, onPassthruCallback);
New Message Callback¶
The user-defined new message callback function is the core of the script. The callback definition contains a single parameter: the message as a json object.
The function can then process the message. For example, the following callback function, sends out a data message if the beginning of the tag’s ID begins with a prefix.
var prefix = "00"; const onNewMessageCallback = (msg) => { if ( msg["type"] == 0 ) { tag_id_hex = JSON.parse(msg["msg"])["data"]["idHex"] if (tag_id_hex.startsWith(prefix)) { msg["type"]=3; ziotc.SendNextMsg(msg); } } };
Input Message types¶
The new message callback will be called each time a new message arrives from the Radio Control. The message will be a json object. It contains a “type” field and a “msg” field. When type is 0, msg field contains a string that can be parsed into a json object. The format is identical to the format of tag messages coming directly from the Radio Control.
Output Message types¶
Messages can be sent to the Reader Gateway and off the reader by calling:
ziotc.SendNextMsg(msg);
The format for sending message matches the incoming messages. The currently available value for outgoing messages are:
ZIOTC_MSG_TYPE_DATA = 3 ZIOTC_MSG_TYPE_CTRL = 4 ZIOTC_MSG_TYPE_GPO = 5
The ZIOTC_MSG_TYPE_DATA type will send the message to the Reader Gateway to output on the Data Interface. The ZIOTC_MSG_TYPE_CTRL type will send the message to the Reader Gateway to output on the Management Event Interface. The ZIOTC_MSG_TYPE_GPO type will send the message to the GPIO-LED module.
Data Analytics Passthru¶
In addition to processing data from the Radio Control and passing new, or filtered, data through to the Reader Gateway, messages can be passed through the Reader Gateway directly to the Data Analytics script. These messages can be sent to the Reader Gateway via the Management Command/Response interface.
In order to process the passed through messages, a pass through callback must be defined and registered with the ZIOTC object. The pass through callback takes in a single parameter - the passed through message. The function MUST issue a sendResponse with a message. This functionality enables a mechanism to configure the Data Analytics Script. The following code snippet continues the example above and allows for a single command “prefix” to be sent to the script. If only “prefix” is sent, the script returns the current value the script is using to filter tags. If prefix is followed by another string, it will update the “prefix” to the new value.
const onPassthruCallback = (msg) =>{ try { if (msg.startsWith("prefix")) { parts = msg.split(" ") if (parts.length >= 2) { prefix = parts[1] } ziotc.SendResponse("prefix set to " + prefix); } else { ziotc.SendResponse("unrecognized command"); } catch(err) { console.log(err.message); } };
Management and Control of Reader¶
DA apps can manage and control the reader using the REST interface described here. Reader bundles the nodejs http
module which can be used to call local rest apis.
const http = require('http');
const options = {
hostname: '127.0.0.1',
port: 80,
path: '/cloud/status',
method: 'GET',
};
const req = http.request(options, (res) => {
let data = '';
res.on('data', (chunk) => {
data += chunk;
});
res.on('end', () => {
console.log('Request successful!');
console.log('Response data:', data);
});
});
req.on('error', (error) => {
console.error('Request failed. Error:', error.message);
});
req.end();
Full NodeJS script¶
Below is the full script based on the code snippets above. It contains a command line parser. The only accepts a single command, “exit”.
const ziotc = require('ziotc.node'); const onErrorCallback = (msg) => { console.log(msg); }; const onOkCallback = () => { console.log("done"); }; var prefix = "00"; const onNewMessageCallback = (msg) => { if ( msg["type"] == 0 ) { tag_id_hex = JSON.parse(msg["msg"])["data"]["idHex"] if (tag_id_hex.startsWith(prefix)) { msg["type"]=3; ziotc.SendNextMsg(msg); } } }; const onPassthruCallback = (msg) =>{ try { if (msg.startsWith("prefix")) { parts = msg.split(" ") if (parts.length >= 2) { prefix = parts[1] } ziotc.SendResponse("prefix set to " + prefix); } else ziotc.SendResponse("unrecognized command"); } catch(err) { console.log(err.message); } }; ziotc.SetDataSource("CONNECT_FOR_RADIO_DATA"); ziotc.Run(onErrorCallback, onOkCallback, onNewMessageCallback, onPassthruCallback); console.log("started DA simple application") function stopZIOTC() { console.log(`stopping...`); ziotc.Stop(); } setTimeout(stopZIOTC, 60000); // run for 1 minute