Airly2MQTT

Simple flow to get air quality measurements into MQTT broker. Includes current PM2.5 and PM10 values with limits percentage and extened CAQI air quality index. Based on data provided by Airly.eu public API. Please see map for available air quality stations.

Attention: before importing this flow please add node-red-contrib-credentials module to your Node-RED pallete first!

Update: Airly has lately limited it's free public API to 100 calls per day. That's 1 call every ~15 minutes but we also do nearest station API call every hour. So I changed the interval to 20 minutes now and the flow fits the current limit perfectly (96 calls per day in total).

Airly2MQTT-v3-desc

[{"id":"270210d8.03352","type":"http request","z":"1c429eb9.f7ea21","name":"Get measurements","method":"GET","ret":"obj","paytoqs":false,"url":"https://airapi.airly.eu/v2/measurements/installation?installationId={{installationId}}","tls":"","proxy":"","authType":"","x":610,"y":460,"wires":[["7fe14370.ea286c","569b13fc.2d5bcc","d56f9845.8f0038","57962394.99249c","4b01a992.9fc618","cd5469a3.ba8788"]]},{"id":"7fe14370.ea286c","type":"function","z":"1c429eb9.f7ea21","name":"AIRLY CAQI value","func":"return { payload: msg.payload.current.indexes[0].value };","outputs":1,"noerr":0,"x":890,"y":580,"wires":[["eab61933.a596b8"]]},{"id":"a1c7aa6.f3ee558","type":"http request","z":"1c429eb9.f7ea21","name":"Get nearest station","method":"GET","ret":"obj","paytoqs":false,"url":"https://airapi.airly.eu/v2/installations/nearest?lat={{lat}}&lng={{lng}}&maxDistanceKM={{maxDistanceKM}}","tls":"","proxy":"","authType":"","x":330,"y":600,"wires":[["9da00eaa.4cfe","871ebf1b.9b3f"]]},{"id":"a146c7a9.d64238","type":"function","z":"1c429eb9.f7ea21","name":"Set params","func":"msg.lat = flow.get(\"latitude\");\nmsg.lng = flow.get(\"longitude\");\nmsg.maxDistanceKM = flow.get(\"maxDistanceKM\");\nmsg.headers = {};\nmsg.headers['Accept'] = 'application/json';\nmsg.headers['apikey'] = flow.get(\"apikey\");\nreturn msg;","outputs":1,"noerr":0,"x":190,"y":540,"wires":[["a1c7aa6.f3ee558"]]},{"id":"569b13fc.2d5bcc","type":"function","z":"1c429eb9.f7ea21","name":"AIRLY CAQI level","func":"return { payload: msg.payload.current.indexes[0].level };","outputs":1,"noerr":0,"x":890,"y":640,"wires":[["e0398db0.f1d2a"]]},{"id":"d56f9845.8f0038","type":"function","z":"1c429eb9.f7ea21","name":"PM2.5 value","func":"return { payload: msg.payload.current.values[1].value };","outputs":1,"noerr":0,"x":870,"y":300,"wires":[["bb4e6243.5d7be"]]},{"id":"4b01a992.9fc618","type":"function","z":"1c429eb9.f7ea21","name":"PM10 value","func":"return { payload: msg.payload.current.values[2].value };","outputs":1,"noerr":0,"x":870,"y":420,"wires":[["a1988859.7637a8"]]},{"id":"57962394.99249c","type":"function","z":"1c429eb9.f7ea21","name":"PM2.5 limit-percent","func":"return { payload: msg.payload.current.standards[0].percent };","outputs":1,"noerr":0,"x":890,"y":360,"wires":[["365d4481.588b3c"]]},{"id":"cd5469a3.ba8788","type":"function","z":"1c429eb9.f7ea21","name":"PM10 limit-percent","func":"return { payload: msg.payload.current.standards[1].percent };","outputs":1,"noerr":0,"x":890,"y":480,"wires":[["d2e68e8a.732ca"]]},{"id":"bb4e6243.5d7be","type":"mqtt out","z":"1c429eb9.f7ea21","name":"node-red/Airly/PM25/value","topic":"node-red/Airly/PM25/value","qos":"0","retain":"true","broker":"a1b0e25b.130ed","x":1180,"y":300,"wires":[]},{"id":"365d4481.588b3c","type":"mqtt out","z":"1c429eb9.f7ea21","name":"node-red/Airly/PM25/limit-percent","topic":"node-red/Airly/PM25/limit-percent","qos":"0","retain":"true","broker":"a1b0e25b.130ed","x":1160,"y":360,"wires":[]},{"id":"a1988859.7637a8","type":"mqtt out","z":"1c429eb9.f7ea21","name":"node-red/Airly/PM10/value","topic":"node-red/Airly/PM10/value","qos":"0","retain":"true","broker":"a1b0e25b.130ed","x":1180,"y":420,"wires":[]},{"id":"d2e68e8a.732ca","type":"mqtt out","z":"1c429eb9.f7ea21","name":"node-red/Airly/PM10/limit-percent","topic":"node-red/Airly/PM10/limit-percent","qos":"0","retain":"true","broker":"a1b0e25b.130ed","x":1160,"y":480,"wires":[]},{"id":"eab61933.a596b8","type":"mqtt out","z":"1c429eb9.f7ea21","name":"node-red/Airly/CAQI/value","topic":"node-red/Airly/CAQI/value","qos":"0","retain":"true","broker":"a1b0e25b.130ed","x":1190,"y":580,"wires":[]},{"id":"e0398db0.f1d2a","type":"mqtt out","z":"1c429eb9.f7ea21","name":"node-red/Airly/CAQI/level","topic":"node-red/Airly/CAQI/level","qos":"0","retain":"true","broker":"a1b0e25b.130ed","x":1190,"y":640,"wires":[]},{"id":"871ebf1b.9b3f","type":"change","z":"1c429eb9.f7ea21","name":"Remember station","rules":[{"t":"set","p":"installationId","pt":"flow","to":"msg.payload[0].id","tot":"msg"}],"action":"","property":"","from":"","to":"","reg":false,"x":570,"y":600,"wires":[["73460a46.373094"]]},{"id":"5285b86b.f2ed28","type":"switch","z":"1c429eb9.f7ea21","name":"Station selected?","property":"installationId","propertyType":"flow","rules":[{"t":"regex","v":"\\d","vt":"str","case":false},{"t":"else"}],"checkall":"false","repair":false,"outputs":2,"x":210,"y":440,"wires":[["73460a46.373094"],["a146c7a9.d64238"]],"outputLabels":["Yes","No"]},{"id":"632fa76e.0665d8","type":"inject","z":"1c429eb9.f7ea21","name":"Pool every 20m","topic":"","payload":"","payloadType":"date","repeat":"1200","crontab":"","once":true,"onceDelay":0.1,"x":210,"y":320,"wires":[["566326a.93050d8","5285b86b.f2ed28","83c3ace3.ba29d"]]},{"id":"566326a.93050d8","type":"credentials","z":"1c429eb9.f7ea21","name":"Airly API key","props":[{"value":"apikey","type":"flow"}],"x":550,"y":200,"wires":[[]]},{"id":"cc331755.292fc8","type":"change","z":"1c429eb9.f7ea21","name":"Forget station","rules":[{"t":"delete","p":"installationId","pt":"flow"}],"action":"","property":"","from":"","to":"","reg":false,"x":560,"y":680,"wires":[[]]},{"id":"9da00eaa.4cfe","type":"delay","z":"1c429eb9.f7ea21","name":"After 1h","pauseType":"delay","timeout":"1","timeoutUnits":"hours","rate":"1","nbRateUnits":"1","rateUnits":"second","randomFirst":"1","randomLast":"5","randomUnits":"seconds","drop":false,"x":360,"y":680,"wires":[["cc331755.292fc8"]]},{"id":"73460a46.373094","type":"function","z":"1c429eb9.f7ea21","name":"Set params","func":"msg.installationId = flow.get(\"installationId\");\nmsg.headers = {};\nmsg.headers['Accept'] = 'application/json';\nmsg.headers['apikey'] = flow.get(\"apikey\");\nreturn msg;","outputs":1,"noerr":0,"x":470,"y":400,"wires":[["270210d8.03352"]]},{"id":"d3caa67a.85e148","type":"comment","z":"1c429eb9.f7ea21","name":"<-- Put your GPS location here","info":"","x":770,"y":160,"wires":[]},{"id":"ebfbb643.43c538","type":"comment","z":"1c429eb9.f7ea21","name":"<-- Put your Airly API key here (package -contrib-credentials required)","info":"","x":890,"y":200,"wires":[]},{"id":"83c3ace3.ba29d","type":"change","z":"1c429eb9.f7ea21","name":"Configuration","rules":[{"t":"set","p":"latitude","pt":"flow","to":"52.180000","tot":"str"},{"t":"set","p":"longitude","pt":"flow","to":"21.02000","tot":"str"},{"t":"set","p":"maxDistanceKM","pt":"flow","to":"25","tot":"str"}],"action":"","property":"","from":"","to":"","reg":false,"x":550,"y":160,"wires":[[]],"icon":"node-red/cog.png"},{"id":"a1b0e25b.130ed","type":"mqtt-broker","z":"","name":"MQTT broker","broker":"192.168.1.2","port":"1883","clientid":"","usetls":false,"compatmode":true,"keepalive":"60","cleansession":true,"birthTopic":"","birthQos":"0","birthPayload":"","closeTopic":"","closeQos":"0","closePayload":"","willTopic":"","willQos":"0","willPayload":""}]

Flow Info

Created 8 months, 2 weeks ago
Updated 2 weeks, 6 days ago
Rating: 5 2

Owner

Node Types

Core
  • change (x3)
  • comment (x2)
  • delay (x1)
  • function (x8)
  • http request (x2)
  • inject (x1)
  • mqtt out (x6)
  • mqtt-broker (x1)
  • switch (x1)
Other

Tags

  • airly
  • mqtt
  • air
  • quality
  • pm25
  • pm10
  • pm2.5
Copy this flow JSON to your clipboard and then import into Node-RED using the Import From > Clipboard (Ctrl-I) menu option