Up until now I've been using an HS3 plugin to poll PurpleAir sensors but I decided to re-implement this in Node-RED instead of paying to upgrade to the HS4 version of the plugin. I also like the fact that I can see and control exactly what's going on with the response processing and that nothing is "hidden" behind a plugin curtain.
The flow uses a recurring inject node to trigger polling every 10 minutes. The polling is done with an HTTP Request node. The trigger is delayed 2 seconds between the request nodes just to keep PurpleAir from getting upset with too many requests in a short period of time. This delay also allows the results to be processed by the same change node and finally routed to the HS Device nodes with a switch node.

With the exception of the change node, the other nodes are basic and straightforward. The request nodes should be set to return a parsed JSON object in msg.payload. Note that the sensors I'm showing here are sensors I randomly picked out in the framing community of Modesto, CA.
The change node moves msg.payload to msg.save, which is generally a good idea so that nothing in the JSON payload affects follow-on nodes that unexpectedly may interpret the msg. It then sets up the new message for the HS Device node and also sets msg.sensor_id to ID of the PurpleAir sensor.

The switch node routes the msg to the appropriate HS Device node based on msg.sensor_id that was set by the change node.
The flow uses a recurring inject node to trigger polling every 10 minutes. The polling is done with an HTTP Request node. The trigger is delayed 2 seconds between the request nodes just to keep PurpleAir from getting upset with too many requests in a short period of time. This delay also allows the results to be processed by the same change node and finally routed to the HS Device nodes with a switch node.
With the exception of the change node, the other nodes are basic and straightforward. The request nodes should be set to return a parsed JSON object in msg.payload. Note that the sensors I'm showing here are sensors I randomly picked out in the framing community of Modesto, CA.
The change node moves msg.payload to msg.save, which is generally a good idea so that nothing in the JSON payload affects follow-on nodes that unexpectedly may interpret the msg. It then sets up the new message for the HS Device node and also sets msg.sensor_id to ID of the PurpleAir sensor.
The switch node routes the msg to the appropriate HS Device node based on msg.sensor_id that was set by the change node.
Code:
[ { "id": "76915431a1cecbc2", "type": "tab", "label": "PurpleAir", "disabled": false, "info": "", "env": [] }, { "id": "157fe75fbc04079e", "type": "http request", "z": "76915431a1cecbc2", "name": "Poll 73501", "method": "GET", "ret": "obj", "paytoqs": "ignore", "url": "https://www.purpleair.com/json?show=73501", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 510, "y": 180, "wires": [ [ "62d6719dee1a7ad8" ] ] }, { "id": "02a654e63f671d92", "type": "inject", "z": "76915431a1cecbc2", "name": "Polling Trigger", "props": [ { "p": "payload" }, { "p": "topic", "vt": "str" } ], "repeat": "600", "crontab": "", "once": true, "onceDelay": "5", "topic": "", "payload": "", "payloadType": "date", "x": 120, "y": 180, "wires": [ [ "157fe75fbc04079e", "25a17ec1df5b53cd" ] ] }, { "id": "acfee28bda839a3d", "type": "http request", "z": "76915431a1cecbc2", "name": "Poll 13489", "method": "GET", "ret": "obj", "paytoqs": "ignore", "url": "https://www.purpleair.com/json?show=13489", "tls": "", "persist": false, "proxy": "", "authType": "", "senderr": false, "x": 510, "y": 220, "wires": [ [ "62d6719dee1a7ad8" ] ] }, { "id": "498c17d0e80b2513", "type": "hs-device", "z": "76915431a1cecbc2", "name": "Aurora", "device": "55", "server": "cca8073e1d5285f1", "feature": "56", "reportonstartup": false, "x": 1110, "y": 180, "wires": [ [] ] }, { "id": "c2603bb730b922f8", "type": "debug", "z": "76915431a1cecbc2", "name": "", "active": false, "tosidebar": true, "console": false, "tostatus": false, "complete": "true", "targetType": "full", "statusVal": "", "statusType": "auto", "x": 930, "y": 140, "wires": [] }, { "id": "62d6719dee1a7ad8", "type": "change", "z": "76915431a1cecbc2", "name": "", "rules": [ { "t": "move", "p": "payload", "pt": "msg", "to": "save", "tot": "msg" }, { "t": "set", "p": "topic", "pt": "msg", "to": "update", "tot": "str" }, { "t": "set", "p": "payload.value", "pt": "msg", "to": "save.results[0].PM2_5Value", "tot": "msg" }, { "t": "set", "p": "payload.status", "pt": "msg", "to": "save.results[0].PM2_5Value", "tot": "msg" }, { "t": "set", "p": "sensor_id", "pt": "msg", "to": "save.results[0].ID", "tot": "msg" } ], "action": "", "property": "", "from": "", "to": "", "reg": false, "x": 740, "y": 200, "wires": [ [ "80b0b6e2904278a6", "c2603bb730b922f8" ] ] }, { "id": "41d3c92200d53d66", "type": "hs-device", "z": "76915431a1cecbc2", "name": "AMTS Modesto", "device": "55", "server": "cca8073e1d5285f1", "feature": "58", "reportonstartup": false, "x": 1140, "y": 240, "wires": [ [] ] }, { "id": "25a17ec1df5b53cd", "type": "delay", "z": "76915431a1cecbc2", "name": "2 Secs", "pauseType": "delay", "timeout": "2", "timeoutUnits": "seconds", "rate": "1", "nbRateUnits": "1", "rateUnits": "second", "randomFirst": "1", "randomLast": "5", "randomUnits": "seconds", "drop": false, "allowrate": false, "outputs": 1, "x": 330, "y": 220, "wires": [ [ "acfee28bda839a3d" ] ] }, { "id": "80b0b6e2904278a6", "type": "switch", "z": "76915431a1cecbc2", "name": "", "property": "sensor_id", "propertyType": "msg", "rules": [ { "t": "eq", "v": "73501", "vt": "str" }, { "t": "eq", "v": "13489", "vt": "str" } ], "checkall": "true", "repair": false, "outputs": 2, "x": 930, "y": 200, "wires": [ [ "498c17d0e80b2513" ], [ "41d3c92200d53d66" ] ] }, { "id": "cca8073e1d5285f1", "type": "hs-server", "name": "HS4Pi", "host": "172.29.1.17", "port": "80" } ]
Comment