We have moved at community.getvera.com

Author Topic: need help with parsing JSON data from HTTP and store variables to virtual device  (Read 2424 times)

Offline ustredna

  • Newbie
  • *
  • Posts: 5
  • Karma: +0/-0
Hi friend,
i'm new in VERA. Vera is very good controller for me, but i need help how can i parse online JSON data from my heating machine cloud.

json data>

http://www.stokercloud.dk/dev/getjsondriftdata.php?mac=hampl


i need read this some JSON data and store into variable as temperature, status, ...
and i need automatically refresh this data each 5 minutes
how can i write easy lua script? is possible run this script automatically each 5 minutes in scenes scheduler?

how make this?


many tnx for your help.
Best regards
Peter

 

Offline akbooer

  • Beta Testers
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +291/-70
  • "Less is more"
i need read this some JSON data and store into variable as temperature, status, ...
and i need automatically refresh this data each 5 minutes

This is very easy if you use  a JSON decoder.  Fortunately, Vera comes with one these days called dkjson.  For example:
Code: [Select]
local json = require "dkjson"

local j = [[
{"501":"34.1 °C flow","502":"0 % Power","503":"24 °C Shaft","504":"0 kW Power","505":"18.2 kg Hopper","506":"0 Lx Light",
"507":"Error no pellets ","508":"16/01-2018 12:22:30","521":"0 °C Return","522":"0 liter/hour Flow","524":"0 °C External temperature",
"525":"54 °C Temperature DHW","526":"15.7 % Actual oxygen","527":"0 % Target oxygen","528":"850 Gram auger/6 min","530":"10.115 kg Today",
"531":"0 kg/m2 Today","532":"0 °C Smoke temp.","533":"65 °C Target boiler temp.","534":"56 °C Target DHW temp.","542":" ","584":"Nitra ",
"585":"86 % humidity","586":"1005 hPa pressure","587":"6.2 m/s wind speed","588":"http://openweathermap.org/img/w/13d.png ",
"589":"-2 °C air temperature","591":"130 null","592":"0.0 °C T5","alarm":"1"}
]]

local data = json.decode(j)

results in the following Lua data structure:
Code: [Select]
{
  ["501"] = "34.1 °C flow",
  ["502"] = "0 % Power",
  ["503"] = "24 °C Shaft",
  ["504"] = "0 kW Power",
  ["505"] = "18.2 kg Hopper",
  ["506"] = "0 Lx Light",
  ["507"] = "Error no pellets ",
  ["508"] = "16/01-2018 12:22:30",
  ["521"] = "0 °C Return",
  ["522"] = "0 liter/hour Flow",
  ["524"] = "0 °C External temperature",
  ["525"] = "54 °C Temperature DHW",
  ["526"] = "15.7 % Actual oxygen",
  ["527"] = "0 % Target oxygen",
  ["528"] = "850 Gram auger/6 min",
  ["530"] = "10.115 kg Today",
  ["531"] = "0 kg/m2 Today",
  ["532"] = "0 °C Smoke temp.",
  ["533"] = "65 °C Target boiler temp.",
  ["534"] = "56 °C Target DHW temp.",
  ["542"] = " ",
  ["584"] = "Nitra ",
  ["585"] = "86 % humidity",
  ["586"] = "1005 hPa pressure",
  ["587"] = "6.2 m/s wind speed",
  ["588"] = "http://openweathermap.org/img/w/13d.png ",
  ["589"] = "-2 °C air temperature",
  ["591"] = "130 null",
  ["592"] = "0.0 °C T5",
  alarm = "1"
}


Quote
how can i write easy lua script? is possible run this script automatically each 5 minutes in scenes scheduler?

The easiest way to do this is simply to put your Lua code into a scene and schedule that scene to run every 5 minutes.
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline ustredna

  • Newbie
  • *
  • Posts: 5
  • Karma: +0/-0
ok,tnx

and how can i readJSON online direct from HTTP link?

Can you write me a simple LUA script with write procedure into device variable sample... i use Multistring Plugin for showing data

Offline akbooer

  • Beta Testers
  • Master Member
  • *****
  • Posts: 6387
  • Karma: +291/-70
  • "Less is more"
The Luup function luup.inet.wget() to make and receive HTTP requests is documented here

http://wiki.micasaverde.com/index.php/Luup_Lua_extensions#function:_wget
3x Vera Lite-UI5/Edge-UI7, 25x Fibaro, 23x TKB, 9x MiniMote, 2x NorthQ Power, 2x Netatmo, 1x Foscam FI9831P, 9x Philips Hue,
Razberry, MySensors Arduino, HomeWave, AltUI, AltHue, DataYours, Grafana, openLuup, ZWay, ZeroBrane Studio.

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
There's a plugin called SiteSensor that will do this for you. You can configure it to query a remote API for a JSON response, and tell it what response fields go into variables that you can access from scenes and Lua scripting.
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline ustredna

  • Newbie
  • *
  • Posts: 5
  • Karma: +0/-0
Hi,
this plugin is super, but i need show this variables as device variables in device list and show this readed variable in imperihome panel on wall tablet.
imperihome don't see this device variables.

any reason for me?
tnx friends.


Peter

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
I don't use Imperihome, so I can't speak to that. In order for the device variables to be populated, you need to specify the reference equations in the configuration. You then should be able to see your individual values on the Vera side by going into the settings/control page for the SiteSensor device, where they appear next to the bracketed numbers (i.e. [1] through [8]). You should see your parsed values there. You can also confirm this by going into the Advanced tab, then Variables, and looking at Value1 through Value8. In either case, if you don't have the expected values, you have an incomplete or incorrect configuration.
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline chris66

  • Sr. Member
  • ****
  • Posts: 318
  • Karma: +9/-8
@rigpapa, great plugin! Just trying to use it with openweathermap, got the last query succeeded, that's a good performance for me  :)
But now two points,
1. I selected Server response is handled as: Text is this right?
Because I got this as result on the web page: (here's an extract)
...
09:00:00"},{"dt":1529496000,"main":{"temp":296.314,"temp_min":296.314,"temp_max":296.314,"pressure":842.84,"sea_level":1032.69,"grnd_level":842.84,"humidity":29,"temp_kf":0},"weather":[{"id":800,"main":"Clear","description":"clear sky","icon":"01d"}],"clouds":{"all":0},"wind":{"speed":0.72,"deg":322},"rain":{},"sys":{"pod":"d"},"dt_txt":"2018-06-20 12:00:00"},{"dt":1529506800,"main":{"temp":294.398,"temp_min":294.398,"temp_max":294.398,"pressure":842.32,"sea_level":1031.73,"grnd_level":842.32,"humidity":36,"temp_kf":0},"weather":[{"id":500,"main":"Rain","description":"light rain","icon":"10d"}],"clouds":{"all":44},"wind":{"speed":0.61,"deg":324.502},"rain":{"3h":0.13},"sys":{"pod":"d"},"dt_txt":"2018-06-20
...
2.  What is the correct syntax to read for example, let's say the "pressure" and "Main" variable? I put "pressure" on the Value Expressions, but I do not understand this part, so nothing appears next to the [1]...

I see your example, but not able to adapt it: { "errCode": 0, "type": { "name": "Normal", "class": "apiobject" } }

In fact I just want to use these variables the same way I use them with the WeatherUnderground plugin. To compare...

Thanks for your time.
 
« Last Edit: June 19, 2018, 12:14:24 pm by chris66 »

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
You need to select JSON response type. That will give you access to the expression fields to extract data from the JSON response. I can't help you with the expressions as posted because you only posted a fragment. Post the whole thing (or email it to me, on my profile) and I'll give you some guidance.
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline chris66

  • Sr. Member
  • ****
  • Posts: 318
  • Karma: +9/-8
Sorry, I have just modified my post in the same time!

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
OK. Got your email.

First, before we really start digging deep, you're doing a forecast request, rather than a current conditions request. Is that intended? If not, your request URL should look more like this:

http://api.openweathermap.org/data/2.5/weather?id=xxxxxxxx&APPID=yyyyyy

And from your second email, you always need to have the protocol ("http://" or "https://") at the front of the request URL.
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline chris66

  • Sr. Member
  • ****
  • Posts: 318
  • Karma: +9/-8
Ok, I use both, Current condition for the outside blind control, because this is critical to me when there is thunderstorm or high wind to put it up. And I use forecast for Heat Pump management, winter time. For example when day+1 forecast is Sunny at 6:00AM the next morning Heat Pump will stay Off, Sun is enough to warm the house.
But if you agree, we are in summer time, so lets start with Current conditions.

Ok did the changes and now I have the correct answer:
08:53:28: SiteSensor: Response HTTP status 200, body="{\"coord\":{\"lon\":7.38,\"lat\":46.26},\"weather\":[{\"id\":800,\"main\":\"Clear\",\"description\":\"clear sky\",\"icon\":\"01d\"}],\"base\":\"stations\",\"main\":{\"temp\":293.15,\"pressure\":1023,\"humidity\":60,\"temp_min\":293.15,\"temp_max\":293.15},\"visibility\":10000,\"wind\":{\"speed\":2.6,\"deg\":90},\"clouds\":{\"all\":0},\"dt\":1529475600,\"sys\":{\"type\":1,\"id\":6005,\"message\":0.003,\"country\":\"CH\",\"sunrise\":1529465903,\"sunset\":1529522751},\"id\":ID,\"name\":\"CityName\",\"cod\":200}"

So now what is the syntax to get for example "main" as [1] -> "Clear" ? If I can get this, I will understand!
« Last Edit: June 20, 2018, 02:59:47 am by chris66 »

Offline rigpapa

  • Beta Testers
  • Hero Member
  • *****
  • Posts: 1121
  • Karma: +187/-3
OK. You've actually chosen a slightly more difficult example for two reasons: (1) "main" is used in two places in the response, so it adds a little potential confusion; and (2) the one you want to use is contained in array of one element, which complicates the reference syntax a little.

Let's start with a simpler example and build on it. I'll use "temp", which is the current temperature. You navigate through the subkeys in the response using the key "response" as the root. So, "temp" is found underneath "main", so we refer to it as response.main.temp. As OpenWeatherMap.org returns it, the temperature is in degrees Kelvin, so we need to convert to Celsius by simply subtracting 273.15, so now response.main.temp - 273.15, or Fahrenheit with response.main.temp*9/5-459.97. You can add the "round" function to clean that up a bit: round(response.main.temp*9/5-459.97,1) rounds the value to one decimal place (second argument to round is number of decimals).

The humidity and pressure keys can also be found under the "main" subkey, so they are response.main.humidity and response.main.pressure.

Now, let's get back to your example--digging out the word "Clear". That is also under a subkey called "main", but it's a subkey of "weather", and you may notice that "weather" is an array. So we need to refer to main through weather as an array element. That can be either response.weather[1].main or last(response.weather).main. The former chooses the first element in the array, and the latter chooses the last, but since it's an array of one element, the effect is the same, so you can use either.

I've put this entire recipe up in the web site documentation at https://www.toggledbits.com/sitesensor, and the full expression syntax and function library for SiteSensor are documented with LuaXP here: https://www.toggledbits.com/luaxp

When looking at the forecast response, it returns an array for different times of day upcoming. You will need to sort out which one you want to use, but I believe they are returned in ascending time order, so the first would be the soonest. Give it a try and see how you do, and if it gives you trouble, post in the SiteSensor plugin support thread and we'll get it sorted.
Author of Reactor, DelayLight, SiteSensor, Rachio, Deus Ex Machina II, Intesis WMP Gateway, Auto Virtual Thermostat and VirtualSensor plugins. Vera Plus w/100+ Z-wave devices. Vera3, Lite. Hassio, Slapdash.

Offline chris66

  • Sr. Member
  • ****
  • Posts: 318
  • Karma: +9/-8
WOW, great! I just followed your example, everything is working great, just one error with humidity:
15:45:23: SiteSensor: Response HTTP status 200, body="{\"coord\":{\"lon\":7.38,\"lat\":46.26},\"weather\":[{\"id\":701,\"main\":\"Mist\",\"description\":\"mist\",\"icon\":\"50d\"}],\"base\":\"stations\",\"main\":{\"temp\":294.73,\"pressure\":1018,\"humidity\":37,\"temp_min\":279.15,\"temp_max\":303.15},\"visibility\":10000,\"wind\":{\"speed\":6.7,\"deg\":260},\"clouds\":{\"all\":20},\"dt\":1529499300,\"sys\":{\"type\":1,\"id\":6005,\"message\":0.0049,\"country\":\"CH\",\"sunrise\":1529465906,\"sunset\":1529522754},\"id\":2660503,\"name\":\"Grimisuat\",\"cod\":200}"
15:45:23: SiteSensor: Eval #1: "last(response.weather).main"=("string")"Mist"
15:45:23: SiteSensor: Eval #2: "response.name"=("string")"Grimisuat"
15:45:23: SiteSensor: Eval #3: "round(response.main.temp * 9 / 5 - 459.97,1)"=("number")70.5
15:45:23: SiteSensor: Failed to execute `"response.humidity"', { location=18, __source="luaxp", message="Subreference not found: humidity", type="evaluation" }
15:45:23: SiteSensor: Eval #4: "response.humidity"=("nil")nil
15:45:23: SiteSensor: Eval #5: "round(response.main.pressure * 0.029529988,2)"=("number")30.06
15:45:23: SiteSensor: Eval trip expression: "response.cod == 200"=("boolean")true
15:45:23: SiteSensor: Next activity in 7200 seconds

Offline chris66

  • Sr. Member
  • ****
  • Posts: 318
  • Karma: +9/-8
Was even able to add:
16:13:23: SiteSensor: Eval #6: "response.wind.speed"=("number")6.7
16:13:23: SiteSensor: Eval #7: "response.wind.deg"=("number")260

And to convert from m/s to km/h: round(response.wind.speed * 18 /5)

So everybody should be able to play with this now,  ;) thanks again for this great plugin!
« Last Edit: June 20, 2018, 10:21:33 am by chris66 »