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 gets the data from Air Rhone-Alpes, a local service. After grabbing the web page, it extracts the pollution level, parses it, publishes 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.
The flow may be useful to somebody else to understand how to parse an HTML page, but mainly people from the Rhône-Alpes area, France will use it :)
So copy the following flow, and insert it in your Node-RED 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"]]
}
]
Share this post
Twitter
Google+
Facebook
Reddit
LinkedIn
StumbleUpon
Pinterest
Email