[SOLVED] Luftdaten.info data extraction

Hello,

I just put together the air quality sensor from luftdaten.info. So now I want to display PM2.2, PM10, Temp and Humidity on my side map. The sensor gives me following back:

{“software_version”: “NRZ-2017-099”, “age”:“145”, “sensordatavalues”:[{“value_type”:“SDS_P1”,“value”:“9.17”},{“value_type”:“SDS_P2”,“value”:“7.17”},{“value_type”:“temperature”,“value”:“21.30”},{“value_type”:“humidity”,“value”:“48.70”},{“value_type”:“samples”,“value”:“598123”},{“value_type”:“min_micro”,“value”:“237”},{“value_type”:“max_micro”,“value”:“802637”},{“value_type”:“signal”,“value”:"-74"}]}

I have the http and json transformation add-on installed and also created items and I used a rule I found in the forum https://community.openhab.org/t/create-json-item-in-oh2/33279 . The rule from Scott Rushworth.

Can one of you guys give me a hint how I have to modify the rule that it extracts the right date. The link of cause I have already change to my local sensor IP 192.168.xxx.xx/data.json

To make it clear no one should write code for me, just point me in the right direction!

Thank you in advance

Dirk

Post your code and I’ll tell you where the corrections are needed with a hint of what they should be. Just a hint!

Hi,

yes, sorry for that. here is my item definition:

Number    PM_ten    "PM10 [%.1f µg/m³]"    <PM10>    
Number    PM_two    "Outside Humidity [%.1f µg/m³]"    <PM25>   
Number    Outside_Temperature    "Außentemperatur Balkon[%.1f °C]"    <temperature>
Number    Outside_Humidity       "Luftfeuchtigkeit Balkon [%.1f %%]"  <humidity>

and the corresponding rule:

rule "Outside Airquality"
when
    Time cron "0 */2 * ? * *"
then
    var String rawMessage = executeCommandLine("/bin/sh@@-c@@/usr/bin/curl -s -X GET http://192.168.178.61/data.json",60000)
    if (rawMessage != null && rawMessage.contains("sensordatavalues")) {
        rawMessage = rawMessage.substring(1,rawMessage.length - 1).replace("},\n","},,")
        val String[] rawMessageArray = rawMessage.split(",,")
        rawMessageArray.forEach[item|
            val String transformedMessage = transform("JSONPATH", "$.value_type", item + "}")
            switch (transform("JSONPATH", "$.value", item + "}")) {
                case "SDS_P1" : PM_ten.sendCommand(transformedMessage)
                case "SDS_P2" : PM_two.sendCommand(transformedMessage)
                case "temperature" : Outside_Temperature.sendCommand(transformedMessage)
                case "humidity" : Outside_Humidity.sendCommand(transformedMessage)
            }
        ]
    }
end

Cheers
Dirk

Can you also publish the full json, please?

I get this back from my sensor:

{“software_version”: “NRZ-2017-099”, “age”:“86”, “sensordatavalues”:[{“value_type”:“SDS_P1”,“value”:“8.17”},{“value_type”:“SDS_P2”,“value”:“5.80”},{“value_type”:“temperature”,“value”:“23.70”},{“value_type”:“humidity”,“value”:“43.90”},{“value_type”:“samples”,“value”:“598208”},{“value_type”:“min_micro”,“value”:“238”},{“value_type”:“max_micro”,“value”:“797593”},{“value_type”:“signal”,“value”:"-70"}]}

assuming that your posted json looks like this before the replacements in your rule i would go with something like this (code is untested)

rule "Outside Airquality"
when
    Time cron "0 */2 * ? * *"
then
    var String json = executeCommandLine("/bin/sh@@-c@@/usr/bin/curl -s -X GET http://192.168.178.61/data.json",60000)
    if (json != null && json.contains("sensordatavalues")) {
      var String items = "PM_ten,PM_two,Outside_Temperatur,Outside_Humidity"
      var item_buffer = items.split(",")
      var counter = -1
      while ((counter=counter+1) < 4) {
        var value = transform("JSONPATH", "$.sensordatavalues["+counter+"].value", json)
        var item_to = item_buffer.get(counter)
        sendCommand(item_to,value)
      }
    }  
end

edit: corrected small code bug

1 Like

There is no date in this json

@vzorglub it is, the problem is that he didn’t used code fence so the forum replaced the "

@mueslee
I saw, I hate it when that happens. I didn’t mean no data. I meant no date.
@dirk_sh is looking for a date…

Sorry stupid me, I need the data. The auto correction made date out of it…

stupid me, i read “data” all the time :rofl:
but since Dirk was looking for the data of it, it was a lucky accident
@dirk_sh have a look at my suggestion above

Thank you for your work!

Openhab gives me two issues:

file: 'file:///Volumes/openHAB-conf/rules/airqual.rules'
severity: 'Fehler'
message: 'The method or field rawMessage is undefined'
at: '6,9'
source: ''
code: 'org.eclipse.xtext.diagnostics.Diagnostic.Linking'

and

file: 'file:///Volumes/openHAB-conf/rules/airqual.rules'
severity: 'Fehler'
message: 'Type mismatch: cannot convert from double to String'
at: '13,29'
source: ''
code: 'org.eclipse.xtext.xbase.validation.IssueCodes.incompatible_types'

in the rule it is highlighted with ** **:

rule "Outside Airquality"
when
    Time cron "0 */2 * ? * *"
then
    var String json = executeCommandLine("/bin/sh@@-c@@/usr/bin/curl -s -X GET http://192.168.178.61/data.json",60000)
    if (**rawMessage** != null && json.contains("sensordatavalues")) {
      var String items = "PM_ten,PM_two,Outside_Temperatur,Outside_Humidity"
      var item_buffer = items.split(",")
      var counter = -1
      while ((counter=counter+1) < 4) {
        var value = Double.parseDouble(transform("JSONPATH", "$.sensordatavalues["+counter+"].value", json))
        var item_to = item_buffer.get(counter)
        sendCommand(item_to,**value**)
      }
    }  
end

The first one, no clue. The second one I do not understand with my very limited knowledge, because the item is defined as a number.

rule "Outside Airquality"
when
    Time cron "0 */2 * ? * *"
then
    var String json = executeCommandLine("/bin/sh@@-c@@/usr/bin/curl -s -X GET http://192.168.178.61/data.json",60000)
    if (json != null && json.contains("sensordatavalues")) {
      var String items = "PM_ten,PM_two,Outside_Temperatur,Outside_Humidity"
      var item_buffer = items.split(",")
      var counter = -1
      while ((counter=counter+1) < 4) {
        var value = Double.parseDouble(transform("JSONPATH", "$.sensordatavalues["+counter+"].value", json)) as Number
        var item_to = item_buffer.get(counter)
        sendCommand(item_to,**value**)
      }
    }  
end

as @vzorglub wrote the rawMessage need to replace with json (copy&paste error)
and for the second problem remove the Double.parseDouble(

I am deeply impressed by you guys!

It works perfectly!!!

I owe you a beer or two, so if you are one day in the Munich area drop me a line.

Cheers
Dirk

you are welcome!
could you please mark this thread as solved? i have edit my original code to remove the two bugs

Bit late to the show but here’s my solution for a luftdaten.info integration:

Rule

rule "Luftdaten einlesen"
when
	Time cron "0 * * * * ?"
then
	val json = sendHttpGetRequest("http://192.168.X.Y/data.json")
	val PM10 = transform("JSONPATH", "$.sensordatavalues[0].value", json)
	val PM25 = transform("JSONPATH", "$.sensordatavalues[1].value", json)
	val Temp = transform("JSONPATH", "$.sensordatavalues[2].value", json)
	val Feuchte = transform("JSONPATH", "$.sensordatavalues[3].value", json)
	postUpdate(Luftdaten_PM25, PM25)
	postUpdate(Luftdaten_PM10, PM10)
	postUpdate(Luftdaten_Temp, Temp)
	postUpdate(Luftdaten_Feuchte, Feuchte)
end

Items

Number Luftdaten_PM25 "PM 2,5 [%.2f µg/m³]"
Number Luftdaten_PM10 "PM 10 [%.2f µg/m³]"
Number Luftdaten_Temp "Temperatur [%.1f °C]"
Number Luftdaten_Feuchte "Rel. Luftfeuchte [%.0f %%]"

Sitemap

sitemap default label="Loremipsum" {
	Frame label="Feinstaubmesser" {
		Text item=Luftdaten_PM25
		Text item=Luftdaten_PM10
		Text item=Luftdaten_Temp
		Text item=Luftdaten_Feuchte
	}
}

Hi

I tried bjoern’s solution on Openhab 2.4M4, and get errors like this:

Cannot convert '{"software_version": "NRZ-2018-111", "age":"66", "sensordatavalues":[{"value_type":"SDS_P1","value":"24.43"},{"value_type":"SDS_P2","value":"14.30"},{"value_type":"temperature","value":"5.50"},{"value_type":"humidity","value":"99.90"},{"value_type":"samples","value":"591945"},{"value_type":"min_micro","value":"239"},{"value_type":"max_micro","value":"873059"},{"value_type":"signal","value":"-67"}]}' to a state type which item 'Luftdaten_Feuchte' accepts: [DecimalType, QuantityType, UnDefType].

I have not installed any JSON TRansform Addin, as I could not find any on the Add-In Page. Would that be needed to be done manually?

Thanks
Nils

yes, you need to install the transformation add on. it is called “jsonpath”, that’s the keyword to look for. I can confirm bjoern’s solution works when the right add-on is installed