[solved] Air pollution data from luftdaten.info

Tags: #<Tag:0x00007f5c8760ce68>

(openhabiger) #1


I’m new to OpenHAB and doing my first steps.
When drilling through a lot of information I found some sources for air quality (Air Quality Binding).
The data seems to come from govermental measurement stations.
Here in Germany there is a project called Luftdaten on luftdaten.info.
It is based on small DIY measurements of pollution (PM10, PM2.5, often also temperature and humidity).
All data is available through an api http://api.luftdaten.info
Does a binding exist to this project ?
How can I access this api to get and display relevant data ?

(Rich Koshak) #2

The API appears to be HTTP REST based so you should be able to make it work with the HTTP binding and/or sendHTTP* actions.

(Hakan Tandogan) #3

Actually, last I checked, you could only upload data through the API. For downloads, there was no nice endpoint.

I am aware of some sites that regulary mirror the full data dump and process them in their own databases, but still no nice query API there :frowning:

(openhabiger) #4

Thanks for your help.

You can simply download data:
Try for example sensor 3361 and it will return somethings like

[{“id”:219436974,“sampling_rate”:null,“timestamp”:“2017-07-24 20:31:15”,“location”:{“id”:1694,“latitude”:“48.126”,“longitude”:“11.552”,“country”:“DE”},“sensor”:{“id”:3361,“pin”:“1”,“sensor_type”:{“id”:14,“name”:“SDS011”,“manufacturer”:“Nova Fitness”}},“sensordatavalues”:[{“id”:509387502,“value”:“1.20”,“value_type”:“P1”},{“id”:509387503,“value”:“1.10”,“value_type”:“P2”}]},{“id”:219439993,“sampling_rate”:null,“timestamp”:“2017-07-24 20:33:41”,“location”:{“id”:1694,“latitude”:“48.126”,“longitude”:“11.552”,“country”:“DE”},“sensor”:{“id”:3361,“pin”:“1”,“sensor_type”:{“id”:14,“name”:“SDS011”,“manufacturer”:“Nova Fitness”}},“sensordatavalues”:[{“id”:509393905,“value”:“0.80”,“value_type”:“P1”},{“id”:509393906,“value”:“0.80”,“value_type”:“P2”}]}]

So no need to download the full data. There are also options to get defined periods but that’s out of my scope. The last value(s) would be good enough.

My question is how to get the relevant data from that json stuff


This are the values for PM10 and PM2.5 (see particulates in wikipedia

(Jürgen Baginski) #5

Using a rule you could get the values like:

val String Station_ID="3361"
// Using  JSONPath
rule "Reading AirPollution"
when Time cron "0 * * * * ?" //every Minute, Change as needed!
var String URL= "http://api.luftdaten.info/v1/sensor/" + Station_ID + "/"
var String json = sendHttpGetRequest(URL)
logInfo("Reading AirPollution"," P1 first Reading: {}",transform("JSONPATH", "$[0].sensordatavalues[0].value", json))
logInfo("Reading AirPollution"," P2 first Reading: {}",transform("JSONPATH", "$[0].sensordatavalues[1].value", json))
logInfo("Reading AirPollution"," P1 second Reading: {}",transform("JSONPATH", "$[1].sensordatavalues[0].value", json))
logInfo("Reading AirPollution"," P2 second Reading: {}",transform("JSONPATH", "$[1].sensordatavalues[1].value", json))

JSONPath Transformation installed
All JSON Returns have 2 readings and each reading gives P1 and P2
Results are given in the LogInfo, to get them into items is up to you
Code is written without checking (No System available!)

[Edit:] As stated by @rlkoshak, this could also easily be done using the HTTP-Binding. If more people see the need to have that in a dedicated binding, I could build it (this winter :wink: )

(Viktor Schopf) #6


yes it seems to be accessible with JSON and HTTP:

You should be able to access the values of a specific sensor by, as the FAQ say:


(openhabiger) #7

Thanks for all replies.
I did install the HTTP binding. But I’m struggeling with configuration and use.

What did I try:
Using the Paper UI I tried to add anew thing based on the HTTP binding. All I get is an empty screen with no chance to insert anything.
I tried to configure a new thing using the config file /etc/openhab2/services/http.cfg
There I added two lines

But I can’t find a thing in the configuration interface of the paper UI.
What do I do in the wrong way ?

(Rich Koshak) #8

HTTP binding is a 1.x version binding. You will need to create Items with a binding configuration as documented in the binding’s readme. I don’t think you can create Items for 1.x bindings in PaperUI.

1.x bindings do not support Things and if it did, you would create the Thing in a .things file in the things folder. The services/http.cfg is, as documented for the binding, a place to configure a way for the binding to make one request to the HTTP service the result of which can be used to populate multiple different Items.


(openhabiger) #9

Thanks for that solution proposal. I tried it and it is working fine.
But here is my next question.
With that rule I just create an entry in the logfile giving me the value.
How can I get value in a thing or item (I still confused how to distinguish them)?

I also tried to write a script which captures the api-result in a file and cat that file in a thing using a json transformation

JSONPATH( “$[0].sensordatavalues[0].value”, json)

But this approach just fires an error

[ERROR] [hab.binding.exec.handler.ExecHandler] - An exception occurred while transforming ‘[{“id”:240651585,“sampling_rate”:null,“timestamp”:“2017-08-05 09:39:26”,“location”:{“id”:16,“latitude”:“xxxxx”,“longitude”:“xxxx”,“country”:“DE”},“sensor”:{“id”:3361,“pin”:“7”,“sensor_type”:{“id”:9,“name”:“DHT22”,“manufacturer”:“various”}},“sensordatavalues”:[{“id”:554239711,“value”:“24.70”,“value_type”:“temperature”},{“id”:554239712,“value”:“61.30”,“value_type”:“humidity”}]},{“id”:240655278,“sampling_rate”:null,“timestamp”:“2017-08-05 09:42:10”,“location”:{“id”:1693,“latitude”:“xxx”,“longitude”:“xxx”,“country”:“DE”},“sensor”:{“id”:3361,“pin”:“7”,“sensor_type”:{“id”:9,“name”:“DHT22”,“manufacturer”:“various”}},“sensordatavalues”:[{“id”:554247472,“value”:“24.90”,“value_type”:“temperature”},{“id”:554247473,“value”:“61.30”,“value_type”:“humidity”}]}]’ with ‘JSONPATH( “$[0].sensordatavalues[0].value”, json)’ : ‘An error occurred while transforming JSON expression.’

(openhabiger) #10

After searching for documentation and lot of try&error I found a solution which returns me the desired data.
I added an item

String StrTest1 “Sensor 3361: [%s]”

Then I extened the rule by an postUpdate. I extracted this idea from How to display the min & max value of an item.

import org.openhab.core.library.types.*
import org.openhab.model.script.actions.*

val String Station_ID=“3361”
// Using JSONPath

// Set the name of the rule
rule “Reading AirPollution”

// When cron job execution
when Time cron “0 */2 * * * ?” //every 5 Minutes at Second 0
var String URL= “http://api.luftdaten.info/v1/sensor/” + Station_ID + "/"
var String json = sendHttpGetRequest(URL)
var String P10
var String P2
var String Unit = " (Unit)"
var String returnvalue = “Wert Rückgabe”

// logInfo(“Reading AirPollution”," P1 first Reading: {}",transform(“JSONPATH”, “$[0].sensordatavalues[0].value”, json))
// logInfo(“Reading AirPollution”," P2 first Reading: {}",transform(“JSONPATH”, “$[0].sensordatavalues[1].value”, json))
// logInfo(“Reading AirPollution”," timestamp: {}",transform(“JSONPATH”, “$[0].sensordatavalues[1].timestamp”, json))
// logInfo(“Reading AirPollution”," P1 second Reading: {}",transform(“JSONPATH”, “$[1].sensordatavalues[0].value”, json))
// logInfo(“Reading AirPollution”," P2 second Reading: {}",transform(“JSONPATH”, “$[1].sensordatavalues[1].value”, json))

P10=transform(“JSONPATH”, “$[0].sensordatavalues[0].value”, json)
P2=transform(“JSONPATH”, “$[0].sensordatavalues[1].value”, json)

// calculate the return value (string)
returnvalue = "P10: " + P10 + Unit + “” + " - P2,5: " + P2 + Unit

// Update the item for that value
postUpdate(StrTest1 , returnvalue)
logInfo(“Reading AirPollution”," return value: {}", returnvalue)

Not sure whether this is a good and/or nice solution.

(Jürgen Baginski) #11

My posted solution was for the reply with a single sensor. If there are more sensors, you have to separate the needed one Can’t help atm because I’m on the road, sorry.
You have found a solution, that is good. You do handle the returns as strings, if you would convert them to numbers you could start persisting them for a chart display.

(openhabiger) #12

Yes, I’m aware of that. My idea was to start with a string to avoid any trouble when converting to a number. And I was quite happy when I the string was finally displayed in a panel.
Persistance is a topic that I will start later on as it is not easy to understand the world of OH2: the documentation is quite sparse for a newbie like me and partly outdated (for OH1 only).

(E. Gerland) #13

Hi @openhabiger:

Have you been able to set everything using numbers?

Could you please share your items, rules and other requires stuff?
Any accelaration for my progress is greatly appreciated.
Thanks in advance.

(E. Gerland) #14

Never mind.
I almost did it. :slight_smile:

The only issue I have is that the values of the sensor are stored the “german way” with a ","instead of a “.” as the decimal point.

How can I replace the “,” with a “.” before converting the string into a number?

(openhabiger) #15

I defined a number item PM10, PM2 and an additional string StrTest1 and a rule is assigning the value to the number

import org.openhab.core.library.types.*
import org.openhab.model.script.actions.*

val String Station_ID="3361"
// Using  JSONPath

// Set the name of the rule
rule "Reading AirPollution"

// When cron job execution
when Time cron "0 */2 * * * ?" //every 5 Minutes at Second 0
var String URL= "http://api.luftdaten.info/v1/sensor/" + Station_ID + "/"
var String json = sendHttpGetRequest(URL)
var String P10
var String P2
var String Unit = " (Unit)"
var String returnvalue = "Wert Rückgabe"

P10=transform("JSONPATH", "$[0].sensordatavalues[0].value", json)
P2=transform("JSONPATH", "$[0].sensordatavalues[1].value", json)

// calculate the return value (string)
returnvalue =  "P10: " + P10 + Unit + "" + " - P2,5: " + P2 + Unit

// Update the item for that value
postUpdate(PM10 , P10)
postUpdate(PM25 , P2)
postUpdate(StrTest1 , returnvalue)
logInfo("Reading AirPollution"," return value: {}", returnvalue)


I just checked my data.
It also displays with a dot.
I fear that OH2 is using the “international” representation with the dot.
Maybe somebody more experienced can answer that question how to adapt this to the German representation.

(Rich Koshak) #16

If you are in a rule you can use String methods to replace the , with .

You can do the same with a JS transform, but you can’t use to transforms at the same time so you will need to extract the value from the JSON and then replace the , with .

(E. Gerland) #17

Hi @openhabiger, @rlkoshak,

thanks a lot for your help. I have it up an running :slight_smile:
I investigated a little more and found out that the persistence (in the beginning playing around with formats) stored PM10 as a string (VARCHAR) and PM2 as a number (DOUBLE) item in my sql DB.
Both have been shown in the logs with “.” - so there was no obvious difference.
I just recognized the “,” used in Germany was shown depending on the sql DB tool to display the data (this was the case with heidiSQL).
Accessing the DB with the iphone APP QueryDB, everything is shown with “.”

However, the problem I had, was that it took me a while until I recognized the different format in my SQL DB (I was not able to show the data of the string in charts of course).

The issue was, once initialized (by persistence) as string in my DB, the values have not been converted to number even after changing to the parseFloat format in my rule.
I first needed to delete the whole item entry in my DB to overcome this issue.
Now both are stored as DOUBLE and can be used for charts.

Again, thanks for your help.

(E. Gerland) #18

Unfortunately there was obviously a change in JSONPATH in OH 2.2 stable (?)

I get:
Error executing the transformation 'JSONPATH': Invalid path '$[0].sensordatavalues[1]

Anyone who solved this already?

After a reboot the issue was solved.
In general my first impression about 2.2. is that it’s more sensitive to updates (rules / items etc) while running.