Logic Machine Forum
openweather ONE call API - Printable Version

+- Logic Machine Forum (https://forum.logicmachine.net)
+-- Forum: LogicMachine eco-system (https://forum.logicmachine.net/forumdisplay.php?fid=1)
+--- Forum: Scripting (https://forum.logicmachine.net/forumdisplay.php?fid=8)
+--- Thread: openweather ONE call API (/showthread.php?tid=3623)

Pages: 1 2


openweather ONE call API - pioneersteffen - 17.10.2021

Hi @all,

I looking around to get a weather service including for free forecasts and found out that there is a new option using openweather ONE call API:

https://openweathermap.org/api/one-call-api

Is somebody having experience with it and can help me with a working script to start with?

Many thanks for your help!

Best Regards 
Steffen


RE: openweather ONE call API - admin - 18.10.2021

See this: https://forum.logicmachine.net/showthread.php?tid=3491


RE: openweather ONE call API - JRP - 19.10.2021

Hello there
you can also look here
https://forum.logicmachine.net/showthread.php?tid=2731&pid=21340#pid21340
Greetings


RE: openweather ONE call API - pioneersteffen - 19.10.2021

Many thanks for your help. I will try this the next days and give you a feedback if it works.


RE: openweather ONE call API - pioneersteffen - 20.10.2021

Hi @all,

due to the great hints of you guys I got the first script running for the current temperature and humidity value.

Now I want to get also the current weather description and the daily forecast for temperature min and max.

Unfortunately this values are not working. In the script log I see the following message: 

Code:
User script:39: attempt to index field 'temp' (a nil value)
stack traceback:

Here is my actual script:

Code:
require('json')
http = require('socket.http')

appid = 'XXX'
lat = 'XXX'
lon ='XXX'
lang = 'en'
units = 'metric'

url = 'http://api.openweathermap.org/data/2.5/onecall?lat=%s&lon=%s&units=%s&lang=%s&appid=%s'
url = string.format(url, lat, lon, units, lang, appid)

res, code, headers, status = http.request(url)
log (code, status, headers)
data = json.pdecode(res)

--Fault messages:
if not data then
  alert('Error converting data')
  return
end

if not res then
  alert('Error collecting data')
  return
end

current = data.current
daily = data.daily


-- current temperature
grp.write('41/1/1', current.temp)
-- current Weather condition
grp.write('41/1/2', current.weather.description)
--current Humidity
grp.write('41/1/3', current.humidity)
--daily forecast Temperature min
grp.write('41/1/4', daily.temp.min)
--daily forecast Temperature max
grp.write('41/1/5', daily.temp.max)


Do you have an idea what might be wrong?

Many thanks for your help!

Best Regards
Steffen


RE: openweather ONE call API - admin - 21.10.2021

Try replacing line 29 with this:
Code:
daily = data.daily[1]



RE: openweather ONE call API - pioneersteffen - 21.10.2021

Many thanks for the help!

Now the daily temperature predictions are working! Unfortunately the daily.weather group e.g. daily.weather.description is not getting a result. I played around with the datatypes (250 byte string, 14 byte string) with no effect.

Any idea what I can do?


RE: openweather ONE call API - admin - 22.10.2021

Use daily.weather[1].description


RE: openweather ONE call API - pioneersteffen - 22.10.2021

Many thanks for the help, it works fine now!

Here is the finished script for other users to continue with it:

Code:
require('json')
http = require('socket.http')

appid = 'XXX'
lat = 'XXX'
lon ='XXX'
lang = 'de'
units = 'metric'

url = 'http://api.openweathermap.org/data/2.5/onecall?lat=%s&lon=%s&units=%s&lang=%s&appid=%s'
url = string.format(url, lat, lon, units, lang, appid)

res, code, headers, status = http.request(url)
log (code, status, headers)
data = json.pdecode(res)

--Fault messages:
if not data then
  alert('Error converting data')
  return
end

if not res then
  alert('Error collecting data')
  return
end

current = data.current
daily = data.daily[1]


-- current temperature
grp.write('41/1/1', current.temp)
--current Humidity
grp.write('41/1/3', current.humidity)
--current wind speed
grp.write('41/1/6', current.wind_speed)
--daily forecast Temperature min
grp.write('41/1/4', daily.temp.min)
--daily forecast Temperature max
grp.write('41/1/5', daily.temp.max)
-- daily Weather condition
grp.write('41/1/2', daily.weather[1].description)

One last rookie question. I want to combine current.temp + current.humidity + current.wind_speed to one string and send this via a 14 byte ASCII group adress.

How would this look like?

Many thanks for your help!

Found the solution on my own, here is a line to combine the values:

wetterprognose = daily.temp.min.."/"..daily.temp.max


RE: openweather ONE call API - pioneersteffen - 22.10.2021

I trying to integrate the alerts as well. Unfortuantely I getting the following error:

Code:
Openweathermap 22.10.2021 19:39:38
User script:52: attempt to index global 'alerts' (a nil value)
stack traceback:
User script:52: in main chunk

Do you have an idea what might be wrong?

Here is the complete code:

Code:
require('json')
http = require('socket.http')

appid = 'xxx'
lat = 'xxx'
lon ='xxx'
lang = 'de'
units = 'metric'

url = 'http://api.openweathermap.org/data/2.5/onecall?lat=%s&lon=%s&units=%s&lang=%s&appid=%s'
url = string.format(url, lat, lon, units, lang, appid)

res, code, headers, status = http.request(url)
log (code, status, headers)
data = json.pdecode(res)

--Fault messages:
if not data then
  alert('Error converting data')
  return
end

if not res then
  alert('Error collecting data')
  return
end

current = data.current
daily = data.daily[1]
alerts = data.alerts


-- current temperature
grp.write('41/1/1', current.temp)
--current Humidity
grp.write('41/1/3', current.humidity)
--current wind speed
grp.write('41/1/6', current.wind_speed)
--daily forecast Temperature min
grp.write('41/1/4', daily.temp.min)
--daily forecast Temperature max
grp.write('41/1/5', daily.temp.max)
-- daily Weather condition
grp.write('41/1/2', daily.weather[1].description)
--daily forecast wind gust
grp.write('41/1/7', daily.wind_gust)
--daily forecast max UV Index
grp.write('41/1/8', daily.uvi)
--daily forecast max UV Index
grp.write('41/1/9', daily.rain)
--alerts
grp.write('41/1/10', alerts.event)

wetterprognose = math.ceil(daily.temp.min).."/"..math.ceil(daily.temp.max).."/"..daily.rain.."/"..math.ceil(daily.wind_gust).."/"..math.ceil(daily.uvi)

--sending daily weather forecast to MDT Taster
grp.write('41/2/1', wetterprognose)

Many thanks for your help!

Best Regards
Steffen


RE: openweather ONE call API - pioneersteffen - 23.10.2021

Additional to post #10 I got a the same problem with the "rain" value today. Yesterday it worked fine due to rain = 4.31. Today there is no rain predicted. The failure is calling:

Code:
User script:54: attempt to concatenate field 'rain' (a nil value)
stack traceback:
User script:54: in main chunk

Can you help me with an idea for a solution please?

Many thanks!


RE: openweather ONE call API - admin - 25.10.2021

Replace daily.rain with (daily.rain or 0)

Alerts might not be available so an extra check is needed:
Code:
if type(alerts) == 'table' and type(alerts[1]) == 'table' then
  alert_event = alerts[1].event
end
grp.write('41/1/10', alert_event or '')



RE: openweather ONE call API - pioneersteffen - 28.10.2021

Many thanks for the help! It is working now.

Here my complete script for all other users to continue with it:

Code:
require('json')
http = require('socket.http')

appid = 'xxxx'
lat = 'xxx'
lon ='xxx'
lang = 'de'
units = 'metric'

url = 'http://api.openweathermap.org/data/2.5/onecall?lat=%s&lon=%s&units=%s&lang=%s&appid=%s'
url = string.format(url, lat, lon, units, lang, appid)

res, code, headers, status = http.request(url)
log (code, status, headers)
data = json.pdecode(res)

--Fault messages:
if not data then
  alert('Error converting data')
  return
end

if not res then
  alert('Error collecting data')
  return
end

current = data.current
daily = data.daily[1]
alerts = data.alerts


-- current temperature
grp.write('41/1/1', current.temp)
--current Humidity
grp.write('41/1/3', current.humidity)
--current wind speed
grp.write('41/1/6', current.wind_speed)
--daily forecast Temperature min
grp.write('41/1/4', daily.temp.min)
--daily forecast Temperature max
grp.write('41/1/5', daily.temp.max)
-- daily Weather condition
grp.write('41/1/2', daily.weather[1].description)
--daily forecast wind gust
grp.write('41/1/7', daily.wind_gust)
--daily forecast max UV Index
grp.write('41/1/8', daily.uvi)
--daily forecast max UV Index
grp.write('41/1/9', (daily.rain or 0))
--alerts
if type(alerts) == 'table' and type(alerts[1]) == 'table' then
   alert_event = alerts[1].event
end
grp.write('41/1/10', alert_event or '')


wetterprognose = math.ceil(daily.temp.min).."-"..math.ceil(daily.temp.max).."/"..(daily.rain or 0).."/"..math.ceil(daily.wind_gust).."/"..math.ceil(daily.uvi)

--sending daily weather forecast to MDT Taster
grp.write('7/2/3', wetterprognose)



RE: openweather ONE call API - Erwin van der Zwart - 28.10.2021

I would change all grp.write into grp.checkupdate, this avoids all objects being updated each run when values are not changed and you have a lot of unneeded KNX telegrams on your TP bus (i assume most are for visu only), for the values you realy need on the bus you should use grp.checkwrite


RE: openweather ONE call API - AlexLV - 30.10.2021

Hi Erwin,

Sorry, not directly to this topic, but linked with weather data.

how better organize checking that weather data are updating (correctly)? I will install weather station first time, before I usually used different weather services. Of course I saw simply way once per hour check as example wind speed, and if data not changing - than do alert. But weather station sends data constantly and 1 hour checking period will be long? I just thing how correctly configure weather station to send data and not to overload KNX line.. Send data only if changed or cyclically every 10 minutes send them again? Script I found for data check:


I would add a check to be sure that the values from the online service are received as expected, we do the same with a signal from a local weather station (alive signal).

Make a resident / scheduled script at like this:
lastupdate = grp.find('1/1/1').updatetime
difference = os.time() - lastupdate
if difference > then 3600 then -- 1 hour not changed
alert('No new value received from online weather service')
-- or mail / push / sms etcetera
end

What is recommendation for local weather station?

BR, Alexander


RE: openweather ONE call API - Erwin van der Zwart - 31.10.2021

Not sure what KNX weather station you have, but our KNX weather station has this alarming in the application and there is no scripting required.. have you checked the ETS application already for possible settings? From this alarm object you can simply trigger your email script or trigger the alert manager.


RE: openweather ONE call API - AlexLV - 31.10.2021

Thank you Erwin, will check again possibility of my weather station.

BR,

Alexander


RE: openweather ONE call API - pioneersteffen - 15.01.2024

Hi @all,

I want to get the snow fall forecast for the next 24h unfortunately I struggling to address the table position right.

What would be the right address for the snow value?

Code:
table:
[1]
  * table:
   ["feels_like"]
    * number: -4.82
   ["dew_point"]
    * number: 0.53
   ["snow"]
    * table:
     ["1h"]
      * number: 0.1
   ["pop"]
    * number: 0.34
   ["humidity"]
    * number: 95
   ["weather"]
    * table:
     [1]
      * table:
       ["main"]
        * string: Snow
       ["description"]
        * string: Mäßiger Schnee
       ["icon"]
        * string: 13d
       ["id"]
        * number: 600
   ["uvi"]
    * number: 0
   ["wind_gust"]
    * number: 13.94
   ["wind_deg"]
    * number: 266
   ["pressure"]
    * number: 993
   ["wind_speed"]
    * number: 8.29
   ["temp"]
    * number: 1.24
   ["visibility"]
    * number: 10000
   ["clouds"]
    * number: 98
   ["dt"]
    * number: 1705305600
[2]
  * table:
   ["feels_like"]
    * number: -4.51
   ["dew_point"]
    * number: 0.5
   ["snow"]
    * table:
     ["1h"]
      * number: 0.13
   ["pop"]
    * number: 0.49
   ["humidity"]
    * number: 94
   ["weather"]
    * table:
     [1]
      * table:
       ["main"]
        * string: Snow
       ["description"]
        * string: Mäßiger Schnee
       ["icon"]
        * string: 13d
       ["id"]
        * number: 600
   ["uvi"]
    * number: 0.2
   ["wind_gust"]
    * number: 13.92
   ["wind_deg"]
    * number: 264
   ["pressure"]
    * number: 992
   ["wind_speed"]
    * number: 7.88
   ["temp"]
    * number: 1.36
   ["visibility"]
    * number: 277
   ["clouds"]
    * number: 100
   ["dt"]
    * number: 1705309200


I‘ve tried the following:

Code:
data.hourly[i].snow.1h

But getting the failure: 

Code:
Lua syntax error at line 79: malformed number near '.1h'

Many thanks for your help!

Best Regards 
Steffen


RE: openweather ONE call API - admin - 15.01.2024

Use this:
Code:
data.hourly[i].snow['1h']



RE: openweather ONE call API - pioneersteffen - 15.01.2024

(15.01.2024, 09:14)admin Wrote: Use this:
Code:
data.hourly[i].snow['1h']

Many thanks! This idea work, but I have a problem in the case of The value doesn’t exist because there is no snow forecasted = nil.

I tried this one:

Code:
repeat
    i=i+1
        if data.hourly[i].snow['1h'] == nil
        then
        data.hourly[i].snow['1h'] = 0
        end
    log(data.hourly[i].snow['1h'])
    snowsum = data.hourly[i].snow['1h'] + snowsum
until
    i>24

but it doesn’t work. 

Code:
User script:83: attempt to index field 'snow' (a nil value)
stack traceback:

Do you have an idea please? 

Many thanks!