Hello there!
In the last couple of days in Poland we’ve seen a drastic increase of AQI.
This is why I thought I will share my openHAB2 setup of air quality measurement
Just a quick update - you no longer need all of it - you can use the AirQuality binding
Prerequisites
We will utilize an API of aqicn.org so first thing you need to do is
Setting up your openHAB
- Create 3 items (see airquality.items file)
-
Number AirQualityIndex "AQI"
- store AQI value
-
String AirQuality
- This will display human-friendly SCALE transformation output
-
Switch AirQualityRerun
- simple switch for fetching new data
- Create a
airquality.rules
file containing a simple rule for retrieving data from API and sending them accordingly to your items.
Remember to change your geo coordinates and API token:
var String coordinates = "37.14360;-115.482399"
var String token = "YOURTOKEN"
- Add some nice SCALE Transformation (here’s Polish version as well)
And you’re done!
The API has much more details inside, that you can measure as well (like CO, PM2.5 levels etc).
Here’s example response from the API:
{
"status": "ok",
"data": {
"idx": 3402,
"aqi": 190,
"time": {
"v": 1483988400,
"s": "2017-01-09 19:00:00",
"tz": "+01:00"
},
"city": {
"name": "Aleja Krasi\u0144skiego, Krak\u00f3w, Ma\u0142opolska",
"url": "http:\/\/aqicn.org\/city\/poland\/malopolska\/krakow\/aleja-krasinskiego\/",
"geo": ["50.057678", "19.926189"]
},
"attributions": [{
"name": "Regional Inspectorate for Environmental Protection in Krakow (WIO\u015a - Wojew\u00f3dzki Inspektorat Ochrony \u015arodowiska w Krakowie)",
"url": "http:\/\/monitoring.krakow.pios.gov.pl\/"
}, {
"name": "World Air Quality Index Project",
"url": "http:\/\/waqi.info\/"
}],
"iaqi": {
"pm25": {
"v": 190
},
"pm10": {
"v": 137
},
"no2": {
"v": 45
},
"co": {
"v": 19
},
"t": {
"v": -9
},
"p": {
"v": 1024
},
"h": {
"v": 72
}
}
}
}
3 Likes
Quick question - would you be interested in having a dedicated openHAB2 binding for measuring Air Quality Index?
There would be one Thing containing mulitple channels, like aqi
, pm25,
, pm10
and so on.
I was thinking about it and am willing to do it if there’s enough interest
Cheers,
Kuba
2 Likes
Hey @kubawolanin,
I didn’t know about “AQI” but I really like it. Will add it to my system later this week
A binding would be great! Looking forward to it!
Just a quick update - you no longer need all of it - you can use the AirQuality binding
2 Likes
Created a custom HabPanel widget if anyone is interested (color coding matches AQI website):
<div ng-if="itemValue('Aqi_Level')<50">
<div class="template-container" style="top:0;bottom:0;left:0;right:0;position:absolute;background-color:#009966">
<div class="template-contents">
<div class="row"><span style="color: white">{{itemValue('Aqi_Description')}}</span></div>
<div class="row">
<div class="col-xs-12"><span style="color: white; font-size: 20pt">{{itemValue('Aqi_Level')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">PM<sub>25</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Pm25')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">O<sub>3</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_O3')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">NO<sub>2</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_No2')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">CO:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Co')}}</span></div>
</div>
</div>
</div>
</div>
<div ng-if="itemValue('Aqi_Level')>=50 && itemValue('Aqi_Level')<100">
<div class="template-container" style="top:0;bottom:0;left:0;right:0;position:absolute;background-color:#ffde33">
<div class="template-contents">
<div class="row"><span style="color: black">{{itemValue('Aqi_Description')}}</span></div>
<div class="row">
<div class="col-xs-12"><span style="color: black; font-size: 20pt">{{itemValue('Aqi_Level')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">PM<sub>25</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_Pm25')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">O<sub>3</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_O3')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">NO<sub>2</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_No2')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">CO:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_Co')}}</span></div>
</div>
</div>
</div>
</div>
<div ng-if="itemValue('Aqi_Level')>=100 && itemValue('Aqi_Level')<150">
<div class="template-container" style="top:0;bottom:0;left:0;right:0;position:absolute;background-color:#ff9933">
<div class="template-contents">
<div class="row"><span style="color: black">{{itemValue('Aqi_Description')}}</span></div>
<div class="row">
<div class="col-xs-12"><span style="color: black; font-size: 20pt">{{itemValue('Aqi_Level')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">PM<sub>25</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_Pm25')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">O<sub>3</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_O3')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">NO<sub>2</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_No2')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: black">CO:</span></div>
<div class="col-xs-6" align="left"><span style="color: black">{{itemValue('Aqi_Co')}}</span></div>
</div>
</div>
</div>
</div>
<div ng-if="itemValue('Aqi_Level')>=150 && itemValue('Aqi_Level')<200">
<div class="template-container" style="top:0;bottom:0;left:0;right:0;position:absolute;background-color:#cc0033">
<div class="template-contents">
<div class="row"><span style="color: white">{{itemValue('Aqi_Description')}}</span></div>
<div class="row">
<div class="col-xs-12"><span style="color: white; font-size: 20pt">{{itemValue('Aqi_Level')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">PM<sub>25</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Pm25')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">O<sub>3</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_O3')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">NO<sub>2</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_No2')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">CO:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Co')}}</span></div>
</div>
</div>
</div>
</div>
<div ng-if="itemValue('Aqi_Level')>=200 && itemValue('Aqi_Level')<300">
<div class="template-container" style="top:0;bottom:0;left:0;right:0;position:absolute;background-color:#660099">
<div class="template-contents">
<div class="row"><span style="color: white">{{itemValue('Aqi_Description')}}</span></div>
<div class="row">
<div class="col-xs-12"><span style="color: white; font-size: 20pt">{{itemValue('Aqi_Level')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">PM<sub>25</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Pm25')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">O<sub>3</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_O3')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">NO<sub>2</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_No2')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">CO:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Co')}}</span></div>
</div>
</div>
</div>
</div>
<div ng-if="itemValue('Aqi_Level')>=300">
<div class="template-container" style="top:0;bottom:0;left:0;right:0;position:absolute;background-color:#7e0023">
<div class="template-contents">
<div class="row"><span style="color: white">{{itemValue('Aqi_Description')}}</span></div>
<div class="row">
<div class="col-xs-12"><span style="color: white; font-size: 20pt">{{itemValue('Aqi_Level')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">PM<sub>25</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Pm25')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">O<sub>3</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_O3')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">NO<sub>2</sub>:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_No2')}}</span></div>
</div>
<div class="row">
<div class="col-xs-6" align="right"><span style="color: white">CO:</span></div>
<div class="col-xs-6" align="left"><span style="color: white">{{itemValue('Aqi_Co')}}</span></div>
</div>
</div>
</div>
</div>