Monday, March 12, 2018

JSONata - Application Notes - Part 3

Use case:

There is a global variable (object) called "accessories" like this:

{
"at_home": {
"name": "at_home",
"service": "Switch"
},
"heating_control": {
"name": "heating_control",
"service": "Switch"
},
"heating": {
"name": "heating",
"service": "Switch"
},
"alarm": {
"name": "alarm",
"service": "Switch"
},
"office_lamp": {
"name": "office_lamp",
"service": "Lightbulb",
"Brightness": "default",
"Hue": "default",
"Saturation": "default"
}
}


and there is a msg.payload that change over time but has a structure like this:

{
    "name": "at_home",
    "characteristic": "On",
    "value": true
}



Problem:  take the value of msg.payload.name and check against the object "accessories" to verify if accessories has a key with the value from msg.payload.name (in this case "at_home").




Proposed Solution:

This solution uses a change node with 3 rules inside.
The first rule is to setup the global object accessories.
The second rule appends to msg.payload.accessories the global object. 
The last rule check is a JSONata expression to test if payload.name is included in the keys from the object accessories.

Third rule:

payload.name in $keys(payload.accessories)

This rule will set the property msg.result as true or false depending if payload.name is one of the keys in the message accessories.

The rule takes advantage of the JSONata operator "in".


Source: http://docs.jsonata.org/operators.html

Operator in

The array inclusion operator returns Boolean true if the value of the LHS is included in the array of values on the RHS. Otherwise it returns false.



Source: http://docs.jsonata.org/object-functions.html

$keys(object)

Returns an array containing the keys in the object. If the argument is an array of objects, then the array returned contains a de-duplicated list of all the keys in all of the objects


Therefore, the  $keys() JSONata function applied on the object accessories will result in the following array:

[
  "at_home",
  "heating_control",
  "heating",
  "alarm",
  "office_lamp"
]

Flow:






Detail of Change node configuration:






Node-RED debug output:





Flow:

```
[{"id":"1979788e.62a6d7","type":"inject","z":"8c924cf8.04b8a","name":"at_home on","topic":"setValue","payload":"{\"name\":\"at_home\",\"characteristic\":\"On\",\"value\":true}","payloadType":"json","repeat":"","crontab":"","once":false,"x":130,"y":160,"wires":[["964735e5.750e08"]]},{"id":"df6bf2f3.f4c42","type":"inject","z":"8c924cf8.04b8a","name":"foobar","topic":"setValue","payload":"{\"name\":\"foobar\",\"characteristic\":\"On\",\"value\":false}","payloadType":"json","repeat":"","crontab":"","once":false,"x":130,"y":240,"wires":[["964735e5.750e08"]]},{"id":"964735e5.750e08","type":"change","z":"8c924cf8.04b8a","name":"","rules":[{"t":"set","p":"accessories","pt":"global","to":"{\"at_home\":{\"name\":\"at_home\",\"service\":\"Switch\"},\"heating_control\":{\"name\":\"heating_control\",\"service\":\"Switch\"},\"heating\":{\"name\":\"heating\",\"service\":\"Switch\"},\"alarm\":{\"name\":\"alarm\",\"service\":\"Switch\"},\"office_lamp\":{\"name\":\"office_lamp\",\"service\":\"Lightbulb\",\"Brightness\":\"default\",\"Hue\":\"default\",\"Saturation\":\"default\"}}","tot":"json"},{"t":"set","p":"payload.accessories","pt":"msg","to":"accessories","tot":"global"},{"t":"set","p":"result","pt":"msg","to":"payload.name in $keys(payload.accessories)","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":360,"y":220,"wires":[["d654b364.59d04"]]},{"id":"d654b364.59d04","type":"debug","z":"8c924cf8.04b8a","name":"","active":true,"console":"false","complete":"true","x":590,"y":220,"wires":[]}]

```