JSONata ~> (transform) question

I'm trying to keep 'last_seen' values (milliseconds) about several devices in a global hash called 'last_seen' using MAC addresses as keys. e.g.:

{
    "11-22-33-44-55-66": {"last_seen": 0,"reported": false},
    "AABBCCDDEEFF": {"last_seen": 0,"reported": false}
}

Query works fine,

$lookup($globalContext('last_seen'),payload)

but how do I update values?

Tried a 'change' node with this

$globalContext('last_seen')~>|payload|{"last_seen": $millis()}|

but it doesn't work. What am I missing?

Must it be JSONata?

It is easily achieved in a function...

var mac_to_update = msg.payload;  //or where ever it comes from 
if(!mac_to_update) return msg;  //nothing to update!
var last_seen = global.get('last_seen') || {};  //get or create the global object
if(!last_seen[mac_to_update]) last_seen[mac_to_update] = {};  //handle empty/new mac
last_seen[mac_to_update].last_seen = Date.now();  //set last_seen 
global.set('last_seen',last_seen);  //store back in global
return msg;//return to next node

Thanks for your code!

I'd very much like it to be JSONata, yes - it's kinda made for this sort of thing. I'm just having a hard time wrapping my head around ~>

Hi,

Here an example of how it can be done:

last_seen ~> | $lookup($,$$.new_value.MAC) | { "last_seen" : $millis(),
                                               "reported"  : $$.new_value.reported} |

So the input of this JSONata expression consists of:

  • new_value : specifying the MAC address that needs to be updated + new reported value.
  • last_seen : is the json string that must be updated.

The input I have used as example:

{
  "new_value": {
    "MAC": "AABBCCDDEEFF",
    "reported": true
  },
  "last_seen": {
    "11-22-33-44-55-66": {
      "last_seen": 0,
      "reported": false
    },
    "AABBCCDDEEFF": {
      "last_seen": 0,
      "reported": false
    }
  }
}

If this doesn't exactly do what you want then please share an example of the input and the expected output for that input.

1 Like

Or it can be done with the $merge function
e.g.

[{"id":"2cd1fcf0.4fe704","type":"inject","z":"8d22ae29.7df6d","name":"","props":[{"p":"payload"},{"p":"last_seen","v":"","vt":"date"}],"repeat":"","crontab":"","once":false,"onceDelay":0.1,"topic":"","payload":"11-22-33-44-55-66","payloadType":"str","x":190,"y":2520,"wires":[["212634ed.7da8fc"]]},{"id":"212634ed.7da8fc","type":"change","z":"8d22ae29.7df6d","name":"","rules":[{"t":"set","p":"last_seen","pt":"global","to":"$merge([$globalContext(\"last_seen\"),{payload:{\"last_seen\":$millis(),\"reported\":true}}])","tot":"jsonata"}],"action":"","property":"","from":"","to":"","reg":false,"x":450,"y":2500,"wires":[["d6dae2d8.e5527"]]},{"id":"d6dae2d8.e5527","type":"debug","z":"8d22ae29.7df6d","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"true","targetType":"full","statusVal":"","statusType":"auto","x":650,"y":2500,"wires":[]}]
1 Like

If you are having a hard time then whoever inherits the code (or yourself in a couple of years) will probably also have a hard time. That might be considered an argument for doing it in a more easy to understand way (such as a function node).

1 Like

True, but I'm building an MVP, so whoever has to deal with it can just ask me :wink:

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.