Node-RED for OM2M: node-red-contrib-ide-iot

IDE-OM2M: a framework for developing IoT applications using the OM2M platform

(https://www.npmjs.com/package/node-red-contrib-ide-iot)

This page gives examples and tutorial to use the Node-RED nodes for OM2M. Those nodes have been developped in a cooperation betweeen LAAS-CNRS (France) and National Chiao Tung University (Taiwan). 

NCTU team:

LAAS-CNRS Team:

Node-RED is a programming tool for wiring hardware devices, APIs and online services in new and interesting way. It provides a browser-based editor that makes it easy to wire together flows using a wide range of nodes, available in the palette that can be deployed to its runtime in a single-click.

Contents:

A) installation

B) Node-RED

C) Integration of node-red-contrib-ide-iot

D) Nodes

PlatformNamedSensorLabeledSensorSemanticSensor, DataExtractor, NotificationHandler, SimpleCondition, NamedActuator, LabeledActuator, SementicActuator

E) Use Case 1

F) Use Case 2

Nodes: Application, Container, ContentInstance, NotificationHandler

A) Installation

Before installing Node-RED, you must have a working installation of Node.js. We recommend you to use the version LTS 8.x of Node.js available at this address: https://nodejs.org/en/download/

Once the installation of Node.js has finished, we will proceed with the installation of Node-RED. The easiest way is to use the node package manager ‘npm’ that comes with Node.js as follows:

npm install -g --unsafe-perm node-red

PS: To use it as a global module, add the command node-red to your system path. After the installation of Node-RED, you can run it using the command:

node-red

Now, you can access to the Node-RED editor by pointing your browser at the address: http://localhost:1880 .

B) Node-RED

Node-RED provides a feed editor that consists of basically three panels:

  1. Node Panel: Contains a list of nodes that will be used by the user to create their streams. Each node belongs to a specific category according to the functionality it offers.
  2. Flow Panel: This is the main workspace of the user, where he can create his streams by dragging and dropping nodes from the Node Panel.
  3. Information and Debug Panel: It consists of two tabs:
  • An info tab: which has for role the display the information relating to a given node (for example: its type, its properties, the functionalities it provides, etc.).
  • A debug tab: which allows the users to view the results and outputs of deployed flows and errors encountered during execution.

To create an application streams, the user slips the desired node from the node palette and places it into the workspace. Once he has done with all the required nodes, he has to connect them with arcs to constitute the application.

C) Integration of node-red-contrib-ide-iot in Node-RED

1. Get and download the module node-red-contrib-ide-iot, then integrate it in Node-RED by using the npm link command. This allows you to link it into a local node-red install. In the directory containing the node’s package.json file, and run:

sudo npm link

In your node-red user directory, typically ~/.node-red, run the following command:

npm link node-red-contrib-ide-iot

This will create the appropriate symbolic links between the two directories, so Node-RED will discover the node at start-time. Any changes in the node’s file can be picked up by simplyrestarting Node-RED.

2. As node-red-contrib-ide-iot is published in npm, we can directly use the following command to integrate it into Node-RED:

npm install node-red-contrib-ide-iot

We show the role and the functioning of the different nodes constituting IDE-OM2M via the manipulation of the simple examples:
To reproduce these examples, select the JSON given for each, right-mouse Copy and then Import from... clipboard in Node-RED and ctrl-V the content into the text box. Click OK and the three- node flow will appear under the cursor to be parked on the worksheet.

D) Nodes

Platform

To enter the parameters (URL, login, password) describing the OM2M platform solicited in a global way. If earlier configurations have been specified, the user can select one of them directly.

NamedSensor:

To retrieve the measurements produced by a sensor or the the device state using the exact name of the resource representing that sensor.

Example: retrieve the last data instance of LAMP_0 lamp by creating a flow as mentioned below:


[{"id":"c6f9ff80.c11b6","type":"inject","z":"5a51e562.22665c","name":"","topic":"","payload":"", "payloadType":"date","repeat":"","crontab":"","once":false,"x":135,"y":238,"wires":[["9ddf51cb. e9c7b"]]},{"id":"9ddf51cb.e9c7b","type":"NamedSensor","z":"5a51e562.22665c","name":"","pla tform":"cc607602.827248","sensor":"7bc59deb.e65404","container":"DATA","cntInstance":"/la ","x":309.5,"y":217,"wires":[["dfcc05aa.e2ad58"]]},{"id":"dfcc05aa.e2ad58","type":"debug","z":" 5a51e562.22665c","name":"","active":true,"console":"false","complete":"false","x":460,"y":260," wires":[]},{"id":"cc607602.827248","type":"xN_CSE","z":"","platform":"OM2M_1","URLBase":"ht tp://127.0.0.1:8080/~/mn-cse/mn- name","user":"admin","password":"admin"},{"id":"7bc59deb.e65404","type":"AE","z":"","appId" :"LAMP_0"}]

  • Platform: Select the OM2M platform that you want to use 
  • SensorName: the requested sensor name.
  • ContentInstance: to choose the instance of data to recover (Latest or Oldest)
  • Name: to name its node in the graphical interface to avoid any ambiguity when using multiple NamedSensor nodes.

The nodes Inject and Debug are already existing nodes in Node-RED, the first node is used to launch our use case and the other to display the result returned by our stream.
After connecting all the nodes of our flow, it will be deployed thanks to the Deploy button. Data instance returned :

LabeledSensor: To recover the data produced by a sensor using a dynamic list of labels (keywords).

Example: retrieve the last data instance of the lamp described by the keywords: Type/actuator Category/luminosity Location/home by creating a flow as mentioned below:

[{"id":"75678cda.8398c4","type":"inject","z":"5a51e562.22665c","name":"","topic":"","payload" :"","payloadType":"date","repeat":"","crontab":"","once":false,"x":120,"y":140,"wires":[["deaf85 28.a8e828"]]},{"id":"deaf8528.a8e828","type":"LabeledSensor","z":"5a51e562.22665c","platfo rm":"cc607602.827248","name":"","width":0,"options":[{"label":"Type","value":"actuator"},{"la bel":"Category","value":"Luminosity"},{"label":"Location","value":"home"}],"cntInstance":"/DA TA/la","x":260,"y":80,"wires":[["81eeb611.0eeb18"]]},{"id":"81eeb611.0eeb18","type":"debug" ,"z":"5a51e562.22665c","name":"","active":true,"console":"false","complete":"false","x":410,"y": 140,"wires":[]},{"id":"cc607602.827248","type":"xN_CSE","z":"","platform":"OM2M_1","URLBas e":"http://127.0.0.1:8080/~/mn-cse/mn-name","user":"admin","password":"admin"}]

  • Platform: in our case, we use the same platform used previously, so we only have to select the name OM2M_1 that we chose to give to our platform.
  • ContentInstance: to choose the instance of data to recover (Latest or Oldest)
  • LabeledName: to introduce the list of labels describing the device to use. The user can delete a given label via add new labels using using add button.

Data instance returned:

SemanticSensor: retrieve a data instance produced by a sensor using semantics via an SPARQL query request.
Example: retrieve the last data instance produced by a Phidget presence sensor. This node only work with Semantic LAAS-CNRS version of OM2M.

[{"id":"6f143573.3401cc","type":"SemanticSensor","z":"5a51e562.22665c","name":"","platfor m":"cc607602.827248","sparql":"SELECT * WHERE { ?resource \n <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>\n <http://purl.oclc.org/NET/ssnx/ssn#philips_Presence_Sensor>. }","cntInstance":"/DATA/la"," x":300,"y":800,"wires":[["99ae1c4f.b906e"]]},{"id":"ee2f64b4.80e548","type":"inject","z":"5a5 1e562.22665c","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":""," once":false,"x":200,"y":880,"wires":[["6f143573.3401cc"]]},{"id":"99ae1c4f.b906e","type":"deb ug","z":"5a51e562.22665c","name":"","active":true,"console":"false","complete":"false","x":419, y":867,"wires":[]},{"id":"cc607602.827248","type":"xN_CSE","z":"","platform":"OM2M_1","URL Base":"http://127.0.0.1:8080/~/mn-cse/mn-name","user":"admin","password":"admin"}]

Result :

DataExtractor: After receiving a data instance returned by a sensor node (NamedSensor, LabeledSensor, SemanticSensor or NotificationsHandler), the user can retrieve the value of a useful value of this instance using this node.

Example: extract the state of the lamp LAMP_0 from the data instance returned by LabeledSensor.

[{"id":"75678cda.8398c4","type":"inject","z":"5a51e562.22665c","name":"","topic":"","payload" :"","payloadType":"date","repeat":"","crontab":"","once":false,"x":120,"y":140,"wires":[["deaf85 28.a8e828"]]},{"id":"deaf8528.a8e828","type":"LabeledSensor","z":"5a51e562.22665c","platfo rm":"cc607602.827248","name":"","width":0,"options":[{"label":"Type","value":"actuator"},{"la bel":"Category","value":"Luminosity"},{"label":"Location","value":"home"}],"cntInstance":"/DA TA/la","x":240,"y":80,"wires":[["89f3b4af.41ea58"]]},{"id":"89f3b4af.41ea58","type":"DataExtr actor","z":"5a51e562.22665c","name":"","viewtype":"state","viewunid1":"","viewunid2":"","x":3 80,"y":140,"wires":[["81eeb611.0eeb18"]]},{"id":"81eeb611.0eeb18","type":"debug","z":"5a51 e562.22665c","name":"","active":true,"console":"false","complete":"false","x":530,"y":80,"wires" :[]},{"id":"cc607602.827248","type":"xN_CSE","z":"","platform":"OM2M_1","URLBase":"http://1 27.0.0.1:8080/~/mn-cse/mn-name","user":"admin","password":"admin"}]


The user can choose one of the properties:

  • State: state of a given device;
  • Data: measure retrieved;
  • Other: to be indicated by the user;
  • JPath: in the case of a complicated data instance, the user can use the JPath option to introducethe property path via JSONPath.

Result : the lamp is off.

NotificationsHandler: This node acts as an HTTP server to receive notifications regarding the different resources to which the user has subscribed once a new data instance is created.

Example: receive notifications whenever the LAMP_0 lamp status changes. A SUBSCRIPTION resource must be created under the DATA container of LAMP_0.

The flow created in Node-RED:

[{"id":"a0686126.c5094","type":"NotificationsHandler","z":"5a51e562.22665c","host":"127.0.0 .1","port":"1400","context":"/monitor","name":"","x":150,"y":620,"wires":[["91eb702b.3b122"] ]},{"id":"91eb702b.3b122","type":"debug","z":"5a51e562.22665c","name":"","active":true,"cons ole":"false","complete":"false","x":350,"y":580,"wires":[]}]

And to launch its server, the user clicks the right node button as follows:

After launching the server, create the SUBSCRIPTION resource with the following parameters:

Field

value

URL

Method

POST

Header

X-M2M-Origin: admin:admin Content-Type: application/xml;ty=23

Body

<m2m:sub xmlns:m2m="http://www.onem2m.org/xml/protocols" rn="SUBSCRIPTION">

<nu>http://localhost:1400/monitor</nu>

<nct>2</nct> </m2m:sub>

After the subscription, the lamp LAMP_0 is switched on to receive a notification

The received notification:

SimpleConditionThis node aims to test the validity of a simple condition.

Example: test if the lamp LAMP_O is On.

[{"id":"75678cda.8398c4","type":"inject","z":"5a51e562.22665c","name":"","topic":"","payload" :"","payloadType":"date","repeat":"","crontab":"","once":false,"x":120,"y":140,"wires":[["deaf85 28.a8e828"]]},{"id":"deaf8528.a8e828","type":"LabeledSensor","z":"5a51e562.22665c","platfo rm":"cc607602.827248","name":"","width":0,"options":[{"label":"Type","value":"actuator"},{"la bel":"Category","value":"Luminosity"},{"label":"Location","value":"home"}],"cntInstance":"/DA TA/la","x":240,"y":80,"wires":[["89f3b4af.41ea58"]]},{"id":"89f3b4af.41ea58","type":"DataExtr actor","z":"5a51e562.22665c","name":"","viewtype":"state","viewunid1":"","viewunid2":"","x":3 80,"y":140,"wires":[["acb2a5a6.3f5fe8"]]},{"id":"acb2a5a6.3f5fe8","type":"SimpleCondition","z ":"5a51e562.22665c","operator":"=","value_c":"true","inputType":"msg","input":"payload","na me":"","x":460,"y":80,"wires":[["81eeb611.0eeb18"]]},{"id":"81eeb611.0eeb18","type":"debug" ,"z":"5a51e562.22665c","name":"","active":true,"console":"false","complete":"false","x":590,"y": 140,"wires":[]},{"id":"cc607602.827248","type":"xN_CSE","z":"","platform":"OM2M_1","URLBas e":"http://127.0.0.1:8080/~/mn-cse/mn-name","user":"admin","password":"admin"}]

Result:

NamedActuator: It’s used to send a simple command to an actuator using the exact name ofthe resource that describes it and to act on the state of a device or change the properties of the user's environment.
Example : turn off the lamp LAMP_0

[{"id":"a435609.78aafa","type":"inject","z":"5a51e562.22665c","name":"","topic":"","payload":" ","payloadType":"date","repeat":"","crontab":"","once":false,"x":200,"y":320,"wires":[["a06fa9c9 .31db98"]]},{"id":"a06fa9c9.31db98","type":"NamedActuator","z":"5a51e562.22665c","platfor m":"cc607602.827248","name":"","actuator":"7bc59deb.e65404","command":"op=setOff&lam pid=LAMP_0","x":420,"y":320,"wires":[]},{"id":"cc607602.827248","type":"xN_CSE","z":"","platf orm":"OM2M_1","URLBase":"http://127.0.0.1:8080/~/mn-cse/mn- name","user":"admin","password":"admin"},{"id":"7bc59deb.e65404","type":"AE","z":"","appId" :"LAMP_0"}]

  • Platform: edit the parameters of the OM2M platform to use or directly select an already existing OM2M_1 as previously configured.
  • ActuatorName: the name of the solicited actuator.
  • Command: the command to send to the actuator.
  • Name: to name its node in the GUI to avoid ambiguity when using multiple NamedActuator nodes.

Result: LAMP_0 is Off

LabeledActuatorIt’s used to send a simple command to an actuator using a dynamic list oflabels that describes it. You have to enter the list of labels and the command to send.

SemanticActuator: use to control a sensor described by a simple SPARQL query. This node only work with Semantic LAAS-CNRS version of OM2M.

E) Use case 1

1: allows to light the lamp LAMP_1 and to send a mail if a presence is detected and the lamp LAMP_0 is extinguished. This shows that IDE-OM2M nodes can work with other existing nodes in Node-RED.

[{"id":"c82097f.499ae68","type":"inject","z":"470c6ba.c6c0794","name":"","topic":"","payload": "","payloadType":"date","repeat":"","crontab":"","once":false,"x":80,"y":220,"wires":[["fc5a9a.ad 034568","68c69eb8.0245c"]]},{"id":"fc5a9a.ad034568","type":"SemanticSensor","z":"470c6ba. c6c0794","name":"","platform":"cc607602.827248","sparql":"SELECT * WHERE { ?resource \n <http://www.w3.org/1999/02/22-rdf-syntax-ns#type>\n <http://purl.oclc.org/NET/ssnx/ssn#philips_Presence_Sensor>. }","cntInstance":"/DATA/la"," x":180,"y":140,"wires":[["c2716f67.bf397"]]},{"id":"c2716f67.bf397","type":"DataExtractor","z ":"470c6ba.c6c0794","name":"","viewtype":"state","viewunid1":"","viewunid2":"","x":300,"y":2 20,"wires":[["ec417a4c.146ce8"]]},{"id":"ec417a4c.146ce8","type":"SimpleCondition","z":"470 c6ba.c6c0794","operator":"=","value_c":"true","inputType":"msg","input":"payload","name":""," x":400,"y":140,"wires":[["5a0b4e0c.33c53"]]},{"id":"68c69eb8.0245c","type":"LabeledSensor", "z":"470c6ba.c6c0794","platform":"cc607602.827248","name":"","width":0,"options":[{"label": "Category","value":"luminosity"},{"label":"Location","value":"home"}],"cntInstance":"/DATA/la" ,"x":180,"y":320,"wires":[["383eaadc.09ded6"]]},{"id":"383eaadc.09ded6","type":"DataExtract or","z":"470c6ba.c6c0794","name":"","viewtype":"data","viewunid1":"","viewunid2":"","x":300," y":260,"wires":[["102da5f 7.0a01ca"]]},{"id":"102da5f 7.0a01ca","type":"SimpleCondition","z":" 470c6ba.c6c0794","operator":"<","value_c":"200","inputType":"msg","input":"payload","name": "","x":417.5,"y":315,"wires":[["5a0b4e0c.33c53"]]},{"id":"5a0b4e0c.33c53","type":"BooleanLog ic","z":"470c6ba.c6c0794","name":"","operation":"AND","inputCount":2,"topic":"result","x":546, "y":240,"wires":[["a745c3f1.f6ed7"]]},{"id":"a745c3f1.f6ed7","type":"switch","z":"470c6ba.c6c 0794","name":"","property":"payload","propertyType":"msg","rules":[{"t":"true"},{"t":"false"}]," checkall":"true","outputs":2,"x":610.5,"y":181,"wires":[["1400f3c0.8972ac","d0cff 790.3e7098" ],["80b1215.d90c4e"]]},{"id":"1400f3c0.8972ac","type":"NamedActuator","z":"470c6ba.c6c07 94","platform":"cc607602.827248","name":"","actuator":"6ca959a7.2f0028","command":"op=s etOn&lampid=LAMP_1","x":759.5,"y":129,"wires":[]},{"id":"80b1215.d90c4e","type":"NamedAc tuator","z":"470c6ba.c6c0794","platform":"cc607602.827248","name":"","actuator":"6ca959a7 .2f0028","command":"op=setOff&lampid=LAMP_1","x":780,"y":280,"wires":[]},{"id":"e31da54 3.ad2578","type":"e-mail","z":"470c6ba.c6c0794","server":"smtp.gmail.com","port":"587","secure":false,"name":"kh adirkarima15@gmail.com","dname":"","x":734,"y":44,"wires":[]},{"id":"d0cff 790.3e7098","type ":"function","z":"470c6ba.c6c0794","name":"","func":"msg.payload=\"Une présence est détectée dans votre maison\";\nmsg.topic=\"Presence_Sensor\"\n\nreturn msg;","outputs":1,"noerr":0,"x":507.5,"y":45,"wires":[["e31da543.ad2578"]]},{"id":"cc607602. 827248","type":"xN_CSE","z":"","platform":"OM2M_1","URLBase":"http://127.0.0.1:8080/~/in -cse/in- name","user":"admin","password":"admin"},{"id":"6ca959a7.2f0028","type":"AE","z":"","appId": "LAMP_1"}]

Results:


The received mail:

F) Use case 2

Create a simple AE by using Application, Container, ContentInstance, Subscription, and NotificationHandler nodes.

Application:

Creates an Application resource. You can specify the following attributes:

  • Platform: Destination CSE.
  • Application: AE Id (application name).
  • Point of Access: PoA URL.
  • Announce: whether this resource is announced to other CSE or not.
  • Labels: labels to describe this application.

Container:

Creates a Container resource to store content instances. You can specify the following attributes:

  • Platform: Destination CSE.
  • Application: AE Id (application name).
  • Container: Name of the container (choose among DESCRIPTOR, DATA, or input your own container’s name).

ContentInstance: 

Creates a ContentInstance resource to store application’s data. You can specify the following attributes:

  • Platform: Destination CSE.
  • Application: AE Id (application name).
  • Container: Name of the container.
  • Labels: The data you want to store. You must describe three fields: Type (str, int, bool, etc.), Name (the name of the attribute), Value (the value of the attribute).

Subscription: 

Creates a Subscription source. You can specify the following attributes:

  • Platform: Destination CSE.
  • Application: AE Id (application name).
  • Container: Name of the container you want to subscribe to.
  • Path: URL of the webservice that will handle the notification of this subscription.

NotificationHandler: 

Creates a HTTP werbservice able to manage platform notifications. You can specify the following attributes:

  • Host: Host IP address.
  • Port: Host Port number.
  • Context: context path of the webservice.

Notification received: