BlocNotes

Notepad of a tinker, maker, hacker or whatever you call it :)

Node-Red - Grab pollution data from local services

I am currently evaluating some solutions to build my home automation system. As a part of this system I want to monitor air quality, but, I do not have any sensor yet, so I use a public service and parse its data with Node-Red.

I built the following flow which get the data from a Air Rhone-Alpes, a local service. After grabbing the web page, it extracts the pollution level, parse it, publish it to my MQTT broker.
I added a filter to avoid any update if there is no change in the pollution level value. Another flow subscribed to the MQTT topic and send ioPush-App notifications depending on the pollution level.

Flow_Polution

The flow may be useful to somebody else in order to understand how to parse an HTML page, but mainly people from Rhône-Alpes area, France will use it :)

So copy the following flow, and insert it in your NodeRed page (Import->Clipboard->Paste). It can be tested by clicking on the "Start flow" button.

[{"id":"b82a5ab2.47d5a8","type":"mqtt-broker","broker":"localhost","port":"1883","clientid":"Node-Red"},{"id":"9f2c1b12.60d3e8","type":"inject","z":"d99ce1.ff26632","name":"Start flow","topic":"","payload":"","payloadType":"date","repeat":"3600","crontab":"","once":true,"x":138.99993896484375,"y":102.55555311838782,"wires":[["e9f3befe.160c4"]]},{"id":"e9f3befe.160c4","type":"http request","z":"d99ce1.ff26632","name":"","method":"GET","ret":"txt","url":"http://www.air-rhonealpes.fr/indice/atmo","x":218.99993896484375,"y":159.55555311838782,"wires":[["30106e06.cfef92"]]},{"id":"30106e06.cfef92","type":"switch","z":"d99ce1.ff26632","name":"Check HTTP status","property":"statusCode","rules":[{"t":"eq","v":200,"v2":0},{"t":"neq","v":200,"v2":0}],"checkall":"true","outputs":2,"x":319.49993896484375,"y":208.8888966242472,"wires":[["473dec33.b8c214"],["4c47b272.b3b84c"]]},{"id":"473dec33.b8c214","type":"function","z":"d99ce1.ff26632","name":"Extract data","func":"var msg = { payload:msg.payload.split(\"<tr class=\\\"odd\\\">\")[3].split(\"span\")[3].substr(24, 1) };\n\nreturn msg;","outputs":"1","noerr":0,"x":526.4999771118164,"y":176.66666507720947,"wires":[["4dfde937.b20218"]]},{"id":"576fcefb.a8903","type":"mqtt out","z":"d99ce1.ff26632","name":"","topic":"/raw/Outside/AirQuality","qos":"0","retain":"false","broker":"b82a5ab2.47d5a8","x":975.4999771118164,"y":176.66666507720947,"wires":[]},{"id":"4c47b272.b3b84c","type":"function","z":"d99ce1.ff26632","name":"Add error message","func":"msg.payload = \"Erreur - Impossible de récupérer la polution de Grenoble @\" + msg.url\nreturn msg;","outputs":1,"noerr":0,"x":549.4999771118164,"y":236.66666507720947,"wires":[["76bea7bc.894158"]]},{"id":"1319a2fc.ece65d","type":"comment","z":"d99ce1.ff26632","name":"Get the data from http://www.air-rhonealpes.fr","info":"1. Every hour, get the RSS feed from \"Air rhone alpes\"\n2. Parse it to find last report URL\n3. Get the report and extract the data","x":190.5,"y":40,"wires":[]},{"id":"4dfde937.b20218","type":"rbe","z":"d99ce1.ff26632","name":"Block unless value change","func":"rbe","gap":"","x":731.5,"y":180,"wires":[["576fcefb.a8903"]]}]