function to format data for chart to plot series of timestamp,value

The topic of interest in the "function slice and aggregate...." It solves the problem of plotting {timestamp, value} points, not just adding a new value.

It originates from polling a public api that exposes recorded IoT data. The data received contains the latest value for the inquired sensors, however since the data is timestamped, these should be respected in the plotting.

Notice: The context stores the obtained dataset and adds points if the timestamp is not previously seen. Some memory is wasted maintaining a lookup array that is not used for anything.

[{"id":"7ecac352.dfff0c","type":"debug","z":"238cfcaf.6e0304","name":"","active":false,"console":"false","complete":"false","x":1119,"y":568.72998046875,"wires":[]},{"id":"46031e77.b3a134","type":"function","z":"238cfcaf.6e0304","name":"slice & aggregate to get plots of {timestamp,value)","func":"//solves the problem of plotting value @ timestamp data\n\nnode.log('in slicer function' + msg);\n\n//prototype safety skip if not needed\nif(msg.payload.ok !== true){\n    node.error('Missing OK property in incoming data');\n    context.set('cache',null); //wipes cache object\n    return;\n}\nelse{\n    var res = [];\n    var bNewData = false;\n    for(var ptr=0;ptr<msg.payload.data.length;ptr++){\n        var d = msg.payload.data[ptr];\n\n        var datapoints = context.get('cache'); //datapoints allready used\n        if(!datapoints)//initial const\n            datapoints = {};\n        \n        if(datapoints.hasOwnProperty(d.varId)===false)\n          {\n              var _data = {};\n              datapoints[d.varId] = _data;\n              _data.key = d.varId;\n              _data.values = []; //data for the chart contained here\n              _data.ts = []; //lookup for checking allready processed timestamps\n          }\n          \n        _data = datapoints[d.varId];\n        \n        var ts = Date.parse(d.tsLastChecked)*1; //ts is short for timestamp :-)\n        \n        \n        if(_data.ts.indexOf(ts)!==-1){\n            //do nada, got it earlier\n        }\n        else{\n            _data.ts.push(ts);\n            _data.values.push([ts, d.val])\n            bNewData = true; //trigger save to context\n        }\n    }\n    \n    if(bNewData)\n        context.set('cache', datapoints); \n    \n    //build output (chart top output shows what the target should look like)\n    var output = [];\n    for(var p in datapoints){\n        if(datapoints.hasOwnProperty(p) === true){\n            var values = datapoints[p].values;\n            output.push({key:p,values:values});\n        }\n    }\n    \n    var newMsg = {payload: output};\n    return newMsg;\n}\n","outputs":1,"noerr":0,"x":560,"y":553,"wires":[["9813358f.42ced8","2b5b5e.f6cea0a2"]]},{"id":"9813358f.42ced8","type":"ui_chart","z":"238cfcaf.6e0304","name":"Temps slice and aggregate","group":"ddff4c51.b23e","order":0,"width":"4","height":"4","label":"Temps","chartType":"line","legend":"false","xformat":"%H:%M:%S","interpolate":"linear","nodata":"","ymin":"","ymax":"","removeOlder":1,"removeOlderUnit":"3600","x":913,"y":486.0699462890625,"wires":[["7ecac352.dfff0c"],[]]},{"id":"2b5b5e.f6cea0a2","type":"debug","z":"238cfcaf.6e0304","name":"sl & ag output","active":true,"console":"false","complete":"payload","x":1131,"y":649.72998046875,"wires":[]},{"id":"d04b8b7a.0b8c5","type":"inject","z":"238cfcaf.6e0304","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"x":229,"y":551.3599853515625,"wires":[["46031e77.b3a134"]]},{"id":"ddff4c51.b23e","type":"ui_group","z":"238cfcaf.6e0304","name":"G2","tab":"21594c22.837164","order":3,"disp":true,"width":"6"},{"id":"21594c22.837164","type":"ui_tab","z":"238cfcaf.6e0304","name":"Kaplenivej 20","icon":"dashboard","order":"1"}]
Laro88

Flow Info

created 8 months, 2 weeks ago

Node Types

Core
  • debug (x2)
  • function (x1)
  • inject (x1)
Other
  • ui_chart (x1)
  • ui_group (x1)
  • ui_tab (x1)

Tags

  • chart
  • timeseries
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option