This forum uses cookies
This forum makes use of cookies to store your login information if you are registered, and your last visit if you are not. Cookies are small text documents stored on your computer; the cookies set by this forum can only be used on this website and pose no security risk. Cookies on this forum also track the specific topics you have read and when you last read them. Please confirm that you accept these cookies being set.

Weather Info from API
#21
Hello,
i nedd to know how may mm of rain done. I modify the script:
require('json')
https = require('ssl.https')
escape = require('socket.url').escape

key = 'xxxxxxxxxxxx'
location = 'Mandello del Lario'
latitude = 45.921373
longitude = 9.314482
args = 'lat=' .. latitude .. '&lon=' .. longitude

url = 'https://api.apixu.com/v1/forecast.json?key=%s&q=%s&days=2'
url = string.format(url, key, escape(arg))

res = https.request(url)

data = json.pdecode(res)
if type(data) ~= 'table' then
alert('Informazioni meteo non pervenute')
return
end

if data.error then
log('error', data.error)
return
end

current = data.current
today = data.forecast.forecastday[ 1 ].day
tomorrow = data.forecast.forecastday[ 2 ].day

-- log(current, today, tomorrow)

-- temperature in C
grp.write('32/2/1', current.temp_c)

-- total precipitation in millimeters
grp.write('32/2/8', today.totalprecip_mm)

But don't function. Can someone help me please.
Reply
#22
Hello, fabiorusco!

I have added one more object to my script for api.met.no (it is free, no need for special key, you can monitor weather for tomorrow and after tomorrow).

Here are changes what I have added
Code:
local status_precipitation_amount_6h = grp.create({ datatype = dt.float16, address = '33/1/28', name = 'precipitation_amount_6h',}) -- mm for next 6 hours

local precipitation_amount_6h = -1 -- participation amount in mm next 6 hours

    -- for weather now
    if entry.time == timestamp_current_hour then -- get data only for one hour (current hour)
      current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        temperature_YR = current_data.air_temperature or -273          -- temperature in Celsius degree
        air_pressure_YR = current_data.air_pressure_at_sea_level or -1  -- air pressure in hPa
        humidity_YR = current_data.relative_humidity or -1              -- air humidity in %
        wind_direction_YR = current_data.wind_from_direction or -1      -- wind direction in degrees [0;360)
        wind_speed_YR = current_data.wind_speed or -1                  -- wind speed in m/s
        uv_index_YR = current_data.ultraviolet_index_clear_sky or -1    -- uv index
        feelslike_temp_YR = calc_feelslike(temperature_YR, wind_speed_YR, humidity_YR) -- feels like temperature in Celsius degree
      end
     
      next_6h = entry.data.next_6_hours.details
      if type(next_6h) == 'table' then
        precipitation_amount_6h = next_6h.precipitation_amount or -1 -- precipitation amount in mm, next 6 hours
      end
    end



    grp.write(status_precipitation_amount_6h, precipitation_amount_6h) -- precipitation mm for next 6 hours

And here the whole script:
Code:
local status_temp = grp.create({ datatype = dt.float16, address = '33/1/1', name = 'current_temp',})
local status_pressure = grp.create({ datatype = dt.uint16, address = '33/1/2', name = 'current_press',})
local status_humidity = grp.create({ datatype = dt.scale, address = '33/1/3', name = 'current_humid',})
local status_wind_direction = grp.create({ datatype = dt.float16, address = '33/1/4', name = 'current_wind_dir',})
local status_wind_speed = grp.create({ datatype = dt.float16, address = '33/1/5', name = 'current_wind_sp',})
local status_uv_index = grp.create({ datatype = dt.uint8, address = '33/1/6', name = 'current_uv_index',})
local status_feelslike_temp = grp.create({ datatype = dt.float16, address = '33/1/7', name = 'current_feels_temp',})

local status_rain_today = grp.create({ datatype = dt.bool, address = '33/1/8', name = 'rain_today',})
local status_snow_today = grp.create({ datatype = dt.bool, address = '33/1/9', name = 'snow_today',})

local status_min_temp_today = grp.create({ datatype = dt.float16, address = '33/1/10', name = 'today_temp_min',})
local status_max_temp_today = grp.create({ datatype = dt.float16, address = '33/1/11', name = 'today_temp_max',})
local status_min_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/12', name = 'today_press_min',})
local status_max_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/13', name = 'today_press_max',})
local status_min_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/14', name = 'today_wind_min',})
local status_max_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/15', name = 'today_wind_max',})
local status_min_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/16', name = 'today_uv_min',})
local status_max_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/17', name = 'today_uv_max',})

local status_rain_tomor = grp.create({ datatype = dt.bool, address = '33/1/18', name = 'rain_tomor',})
local status_snow_tomor = grp.create({ datatype = dt.bool, address = '33/1/19', name = 'snow_tomor',})

local status_min_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/20', name = 'tomor_temp_min',})
local status_max_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/21', name = 'tomor_temp_max',})
local status_min_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/22', name = 'tomor_press_min',})
local status_max_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/23', name = 'tomor_press_max',})
local status_min_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/24', name = 'tomor_wind_min',})
local status_max_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/25', name = 'tomor_wind_max',})
local status_min_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/26', name = 'tomor_uv_min',})
local status_max_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/27', name = 'tomor_uv_max',})

local status_precipitation_amount_6h = grp.create({ datatype = dt.float16, address = '33/1/28', name = 'precipitation_amount_6h',}) -- mm for next 6 hours

local rain_tod_YR = false        -- is rainy or not (for today)
local snow_tod_YR = false        -- is snowy or not (for today)
local rain_tom_YR = false        -- is rainy or not (for tomorrow)
local snow_tom_YR = false        -- is snowy or not (for tomorrow)

-- current temperature, air pressure, humidity, wind direction and speed
local temperature_YR = -273    -- temperature in degree Celsius
local air_pressure_YR = -1    -- air pressure in hPa
local humidity_YR = -1        -- air humidity in %
local wind_direction_YR = -1  -- wind direction in degrees [0; 360)
local wind_speed_YR = -1      -- wind speed in m/s
local uv_index_YR = -1        -- UV index
local feelslike_temp_YR = -273 -- feels like temperature in degree Celsius
local precipitation_amount_6h = -1 -- participation amount in mm next 6 hours


function init_min_max_table() -- initialize table for minimum, maximum temperature, pressure, windspeed
  local min_max = {}
  min_max.min_t = 8000 -- minimum temperature for today
  min_max.max_t = -273 -- maximum temperature for today
  min_max.min_p = 8000 -- minimum pressure for today
  min_max.max_p = -1  -- maximum pressure for today
  min_max.min_w = 8000 -- minimum wind speed for today
  min_max.max_w = -1  -- maximum wind speed for today
  min_max.min_uv = 8000 -- minimum UV index
  min_max.max_uv = -1  -- maximum UV index
 
  return min_max
end


function set_timestamp(day) -- if day = 0 today; if day = 1 tomorrow, if day = 2 day after tomorrow
  local date = os.date('*t')
  date.day = date.day + day
  local time = os.time(date)
  return os.date('%Y-%m-%d', time), date.hour -- timestamp and current hour
end


-- minimum maximum values of temperature, pressure and windspeed
function min_max_temp_press_wind(dat_tab, min_max_tab)
  min_max_tab.min_t = math.min(min_max_tab.min_t, dat_tab.air_temperature or 8000)
  min_max_tab.max_t = math.max(min_max_tab.max_t, dat_tab.air_temperature or -273)
  min_max_tab.min_p = math.min(min_max_tab.min_p, dat_tab.air_pressure_at_sea_level or 8000)
  min_max_tab.max_p = math.max(min_max_tab.max_p, dat_tab.air_pressure_at_sea_level or -1)
  min_max_tab.min_w = math.min(min_max_tab.min_w, dat_tab.wind_speed or 8000)
  min_max_tab.max_w = math.max(min_max_tab.max_w, dat_tab.wind_speed or -1)
  min_max_tab.min_uv = math.min(min_max_tab.min_uv, dat_tab.ultraviolet_index_clear_sky or 8000)
  min_max_tab.max_uv = math.max(min_max_tab.max_uv, dat_tab.ultraviolet_index_clear_sky or -1)
 
  return min_max_tab
end


function check_for_rain(next1h)
  local is_rainy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('rain') then
    is_rainy = true
  end
 
  return is_rainy
end


function check_for_snow(next1h)
  local is_snowy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('snow') then
    is_snowy = true
  end

  return is_snowy
end


function calc_heat_index(temperature, humidity)
  if temperature < 26.7 then
    log('for heat_index calculation temperature should be higher than +26.7 Celsius degree')
    return -273
  end
 
  if humidity < 0 or humidity > 100 then
    log('humidity should be in a range from 0 ... 100%')
    return -273
  end
 
  local T = temperature
  local H = humidity
  local c_1 = -8.785
  local c_2 = 1.611
  local c_3 = 2.339
  local c_4 = -0.146
  local c_5 = -0.0123
  local c_6 = -0.0164
  local c_7 = 0.00221
  local c_8 = 0.000725
  local c_9 = -0.00000358
  local heat_index = c_1+c_2*T+c_3*H+c_4*T*H+c_5*T*T+c_6*H*H+c_7*T*T*H+c_8*T*H*H+c_9*T*T*H*H
 
return heat_index
end


function calc_wind_chill(temperature, wind_speed)
  if temperature > 10 then
    log('temperature should be less than +10.0 Celsius degree')
  return -273
  end
   
  if wind_speed < 0 or wind_speed > 49.2 then
  log('wind speed should be in a range 0 ... 49.2 m/s')
    return -273
  end
 
  local T_air = temperature -- air temperature Celsius degree
 
  local a = 0.62 -- coef
  local b = 0.51 -- coef
  local T_1 = 13.1 -- Celsius degree
  local T_2 = 14.6 -- Celsius degree
 
  local M_0 = 1.3333 -- m/s
  local M = wind_speed -- m/s
 
  local T_wind_chill
 
  if M > M_0 then
    T_wind_chill = (a*T_air + T_1) + (b*T_air - T_2)*(M/M_0)^0.16
  else
    T_wind_chill = T_air
  end
 
  return T_wind_chill
end


function calc_feelslike(temperature, wind_speed, humidity)
  local T_feelslike
 
  if temperature <= 10.0 then -- if less than 10.0 Celsius degree (or equal) then wind chill
    T_feelslike = calc_wind_chill(temperature, wind_speed)
  elseif temperature >= 26.7 then -- if more than 26.7 Celsius degree (or equal) then heat index
    T_feelslike = calc_heat_index(temperature, humidity)
  else -- other cases just return temperature
    T_feelslike = temperature
  end

  return T_feelslike
end


local min_max_today = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction
local min_max_tomor = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction

--local latitude = 51.5072 --  'London'
--local longitude = 0.1276 --  'London'
local latitude = 45.921373 --  'Mandello del Lario'
local longitude = 9.314482 --  'Mandello del Lario'

https = require('ssl.https')
json = require('json')
ltn12 = require('ltn12')

args = 'lat=' .. latitude .. '&lon=' .. longitude

url = 'https://api.met.no/weatherapi/locationforecast/2.0/complete?' .. args

mac = 0
io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)
  mac = mac * 256 + tonumber(v, 16)
end)

response = {}

res, code = https.request({
  url = url,
  protocol = 'tlsv12',
  headers = {
    ['user-agent'] = 'LM ' .. mac
  },
  sink = ltn12.sink.table(response)
})


if res and code == 200 then
  data = json.pdecode(table.concat(response))
else
  log('request error', res, code)
end


if type(data) == 'table' then
  timestamp, hour = set_timestamp(0) -- current day
 
  if hour < 10 then
    timestamp_current_hour = timestamp .. 'T0' .. hour .. ':00:00Z' -- time stamp for current hour
  else
    timestamp_current_hour = timestamp .. 'T' .. hour .. ':00:00Z'  -- time stamp for current hour
  end
 
  --log('timestamp = ' .. timestamp)
 
  timestamp_next = set_timestamp(1) -- timestamp for tomorrow
  --log('timestamp_next = ' .. timestamp_next)
 
  --timestamp_after_next = set_timestamp(2) -- timestamp for day after tomorrow
  --log('timestamp_after_next = ' .. timestamp_after_next)
 
  --timestamp_after_after = set_timestamp(3) -- timestamp for day after day after tomorrow
  --log('timestamp_after_after = ' .. timestamp_after_after)
 
  for i, entry in ipairs(data.properties.timeseries) do 
   
    -- for weather now
    if entry.time == timestamp_current_hour then -- get data only for one hour (current hour)
      current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        temperature_YR = current_data.air_temperature or -273          -- temperature in Celsius degree
        air_pressure_YR = current_data.air_pressure_at_sea_level or -1  -- air pressure in hPa
        humidity_YR = current_data.relative_humidity or -1              -- air humidity in %
        wind_direction_YR = current_data.wind_from_direction or -1      -- wind direction in degrees [0;360)
        wind_speed_YR = current_data.wind_speed or -1                  -- wind speed in m/s
        uv_index_YR = current_data.ultraviolet_index_clear_sky or -1    -- uv index
        feelslike_temp_YR = calc_feelslike(temperature_YR, wind_speed_YR, humidity_YR) -- feels like temperature in Celsius degree
      end
     
      next_6h = entry.data.next_6_hours.details
      if type(next_6h) == 'table' then
        precipitation_amount_6h = next_6h.precipitation_amount or -1 -- precipitation amount in mm, next 6 hours
      end
    end
   
    if entry.time:sub(1, #timestamp) == timestamp then -- checks remaining hours + 3 previous hours of current day
    current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        min_max_today = min_max_temp_press_wind(current_data, min_max_today)
      end
     
      if rain_tod_YR == false then -- if detected rain does not check for rain
        rain_tod_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tod_YR == false then -- if detected snow does not check for snow
        snow_tod_YR = check_for_snow(entry.data.next_1_hours)
      end
    end
   
    if entry.time:sub(1, #timestamp_next) == timestamp_next then -- checks 24 hours of next day
      tomor_data = entry.data.instant.details
      if type(tomor_data) == 'table' then
        min_max_tomor = min_max_temp_press_wind(tomor_data, min_max_tomor)
      end
     
      if rain_tom_YR == false then -- if detected rain does not check for rain
        rain_tom_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tom_YR == false then -- if detected snow does not check for snow
        snow_tom_YR = check_for_snow(entry.data.next_1_hours)
      end
    end
 
  end

 
  -- data for current hour
  grp.write(status_temp, temperature_YR)
  grp.write(status_pressure, air_pressure_YR)
  grp.write(status_humidity, humidity_YR)
  grp.write(status_wind_direction, wind_direction_YR)
  grp.write(status_wind_speed, wind_speed_YR)
  grp.write(status_uv_index, uv_index_YR)
  grp.write(status_feelslike_temp, feelslike_temp_YR)
  grp.write(status_precipitation_amount_6h, precipitation_amount_6h) -- precipitation mm for next 6 hours
 
  -- data for today: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_today, rain_tod_YR)
  grp.write(status_snow_today, snow_tod_YR)
 
  grp.write(status_min_temp_today, min_max_today.min_t)
  grp.write(status_max_temp_today, min_max_today.max_t)
  grp.write(status_min_pressure_today, min_max_today.min_p)
  grp.write(status_max_pressure_today, min_max_today.max_p)
  grp.write(status_min_wind_speed_today, min_max_today.min_w)
  grp.write(status_max_wind_speed_today, min_max_today.max_w)
  grp.write(status_min_uv_today, min_max_today.min_uv)
  grp.write(status_max_uv_today, min_max_today.max_uv)
 
 
  -- data for tomorrow: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_tomor, rain_tom_YR)
  grp.write(status_snow_tomor, snow_tom_YR)
 
  grp.write(status_min_temp_tomor, min_max_tomor.min_t)
  grp.write(status_max_temp_tomor, min_max_tomor.max_t)
  grp.write(status_min_pressure_tomor, min_max_tomor.min_p)
  grp.write(status_max_pressure_tomor, min_max_tomor.max_p)
  grp.write(status_min_wind_speed_tomor, min_max_tomor.min_w)
  grp.write(status_max_wind_speed_tomor, min_max_tomor.max_w)
  grp.write(status_min_uv_tomor, min_max_tomor.min_uv)
  grp.write(status_max_uv_tomor, min_max_tomor.max_uv)
 
end

Attached Files
.lua   my_script_v15.lua (Size: 14.15 KB / Downloads: 8)
Reply
#23
(31.10.2022, 13:48)RomansP Wrote: Hello, fabiorusco!

I have added one more object to my script for api.met.no (it is free, no need for special key, you can monitor weather for tomorrow and after tomorrow).

Here are changes what I have added
Code:
local status_precipitation_amount_6h = grp.create({ datatype = dt.float16, address = '33/1/28', name = 'precipitation_amount_6h',}) -- mm for next 6 hours

local precipitation_amount_6h = -1 -- participation amount in mm next 6 hours

    -- for weather now
    if entry.time == timestamp_current_hour then -- get data only for one hour (current hour)
      current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        temperature_YR = current_data.air_temperature or -273          -- temperature in Celsius degree
        air_pressure_YR = current_data.air_pressure_at_sea_level or -1  -- air pressure in hPa
        humidity_YR = current_data.relative_humidity or -1              -- air humidity in %
        wind_direction_YR = current_data.wind_from_direction or -1      -- wind direction in degrees [0;360)
        wind_speed_YR = current_data.wind_speed or -1                  -- wind speed in m/s
        uv_index_YR = current_data.ultraviolet_index_clear_sky or -1    -- uv index
        feelslike_temp_YR = calc_feelslike(temperature_YR, wind_speed_YR, humidity_YR) -- feels like temperature in Celsius degree
      end
     
      next_6h = entry.data.next_6_hours.details
      if type(next_6h) == 'table' then
        precipitation_amount_6h = next_6h.precipitation_amount or -1 -- precipitation amount in mm, next 6 hours
      end
    end



    grp.write(status_precipitation_amount_6h, precipitation_amount_6h) -- precipitation mm for next 6 hours

And here the whole script:
Code:
local status_temp = grp.create({ datatype = dt.float16, address = '33/1/1', name = 'current_temp',})
local status_pressure = grp.create({ datatype = dt.uint16, address = '33/1/2', name = 'current_press',})
local status_humidity = grp.create({ datatype = dt.scale, address = '33/1/3', name = 'current_humid',})
local status_wind_direction = grp.create({ datatype = dt.float16, address = '33/1/4', name = 'current_wind_dir',})
local status_wind_speed = grp.create({ datatype = dt.float16, address = '33/1/5', name = 'current_wind_sp',})
local status_uv_index = grp.create({ datatype = dt.uint8, address = '33/1/6', name = 'current_uv_index',})
local status_feelslike_temp = grp.create({ datatype = dt.float16, address = '33/1/7', name = 'current_feels_temp',})

local status_rain_today = grp.create({ datatype = dt.bool, address = '33/1/8', name = 'rain_today',})
local status_snow_today = grp.create({ datatype = dt.bool, address = '33/1/9', name = 'snow_today',})

local status_min_temp_today = grp.create({ datatype = dt.float16, address = '33/1/10', name = 'today_temp_min',})
local status_max_temp_today = grp.create({ datatype = dt.float16, address = '33/1/11', name = 'today_temp_max',})
local status_min_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/12', name = 'today_press_min',})
local status_max_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/13', name = 'today_press_max',})
local status_min_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/14', name = 'today_wind_min',})
local status_max_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/15', name = 'today_wind_max',})
local status_min_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/16', name = 'today_uv_min',})
local status_max_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/17', name = 'today_uv_max',})

local status_rain_tomor = grp.create({ datatype = dt.bool, address = '33/1/18', name = 'rain_tomor',})
local status_snow_tomor = grp.create({ datatype = dt.bool, address = '33/1/19', name = 'snow_tomor',})

local status_min_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/20', name = 'tomor_temp_min',})
local status_max_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/21', name = 'tomor_temp_max',})
local status_min_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/22', name = 'tomor_press_min',})
local status_max_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/23', name = 'tomor_press_max',})
local status_min_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/24', name = 'tomor_wind_min',})
local status_max_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/25', name = 'tomor_wind_max',})
local status_min_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/26', name = 'tomor_uv_min',})
local status_max_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/27', name = 'tomor_uv_max',})

local status_precipitation_amount_6h = grp.create({ datatype = dt.float16, address = '33/1/28', name = 'precipitation_amount_6h',}) -- mm for next 6 hours

local rain_tod_YR = false        -- is rainy or not (for today)
local snow_tod_YR = false        -- is snowy or not (for today)
local rain_tom_YR = false        -- is rainy or not (for tomorrow)
local snow_tom_YR = false        -- is snowy or not (for tomorrow)

-- current temperature, air pressure, humidity, wind direction and speed
local temperature_YR = -273    -- temperature in degree Celsius
local air_pressure_YR = -1    -- air pressure in hPa
local humidity_YR = -1        -- air humidity in %
local wind_direction_YR = -1  -- wind direction in degrees [0; 360)
local wind_speed_YR = -1      -- wind speed in m/s
local uv_index_YR = -1        -- UV index
local feelslike_temp_YR = -273 -- feels like temperature in degree Celsius
local precipitation_amount_6h = -1 -- participation amount in mm next 6 hours


function init_min_max_table() -- initialize table for minimum, maximum temperature, pressure, windspeed
  local min_max = {}
  min_max.min_t = 8000 -- minimum temperature for today
  min_max.max_t = -273 -- maximum temperature for today
  min_max.min_p = 8000 -- minimum pressure for today
  min_max.max_p = -1  -- maximum pressure for today
  min_max.min_w = 8000 -- minimum wind speed for today
  min_max.max_w = -1  -- maximum wind speed for today
  min_max.min_uv = 8000 -- minimum UV index
  min_max.max_uv = -1  -- maximum UV index
 
  return min_max
end


function set_timestamp(day) -- if day = 0 today; if day = 1 tomorrow, if day = 2 day after tomorrow
  local date = os.date('*t')
  date.day = date.day + day
  local time = os.time(date)
  return os.date('%Y-%m-%d', time), date.hour -- timestamp and current hour
end


-- minimum maximum values of temperature, pressure and windspeed
function min_max_temp_press_wind(dat_tab, min_max_tab)
  min_max_tab.min_t = math.min(min_max_tab.min_t, dat_tab.air_temperature or 8000)
  min_max_tab.max_t = math.max(min_max_tab.max_t, dat_tab.air_temperature or -273)
  min_max_tab.min_p = math.min(min_max_tab.min_p, dat_tab.air_pressure_at_sea_level or 8000)
  min_max_tab.max_p = math.max(min_max_tab.max_p, dat_tab.air_pressure_at_sea_level or -1)
  min_max_tab.min_w = math.min(min_max_tab.min_w, dat_tab.wind_speed or 8000)
  min_max_tab.max_w = math.max(min_max_tab.max_w, dat_tab.wind_speed or -1)
  min_max_tab.min_uv = math.min(min_max_tab.min_uv, dat_tab.ultraviolet_index_clear_sky or 8000)
  min_max_tab.max_uv = math.max(min_max_tab.max_uv, dat_tab.ultraviolet_index_clear_sky or -1)
 
  return min_max_tab
end


function check_for_rain(next1h)
  local is_rainy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('rain') then
    is_rainy = true
  end
 
  return is_rainy
end


function check_for_snow(next1h)
  local is_snowy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('snow') then
    is_snowy = true
  end

  return is_snowy
end


function calc_heat_index(temperature, humidity)
  if temperature < 26.7 then
    log('for heat_index calculation temperature should be higher than +26.7 Celsius degree')
    return -273
  end
 
  if humidity < 0 or humidity > 100 then
    log('humidity should be in a range from 0 ... 100%')
    return -273
  end
 
  local T = temperature
  local H = humidity
  local c_1 = -8.785
  local c_2 = 1.611
  local c_3 = 2.339
  local c_4 = -0.146
  local c_5 = -0.0123
  local c_6 = -0.0164
  local c_7 = 0.00221
  local c_8 = 0.000725
  local c_9 = -0.00000358
  local heat_index = c_1+c_2*T+c_3*H+c_4*T*H+c_5*T*T+c_6*H*H+c_7*T*T*H+c_8*T*H*H+c_9*T*T*H*H
 
return heat_index
end


function calc_wind_chill(temperature, wind_speed)
  if temperature > 10 then
    log('temperature should be less than +10.0 Celsius degree')
  return -273
  end
   
  if wind_speed < 0 or wind_speed > 49.2 then
  log('wind speed should be in a range 0 ... 49.2 m/s')
    return -273
  end
 
  local T_air = temperature -- air temperature Celsius degree
 
  local a = 0.62 -- coef
  local b = 0.51 -- coef
  local T_1 = 13.1 -- Celsius degree
  local T_2 = 14.6 -- Celsius degree
 
  local M_0 = 1.3333 -- m/s
  local M = wind_speed -- m/s
 
  local T_wind_chill
 
  if M > M_0 then
    T_wind_chill = (a*T_air + T_1) + (b*T_air - T_2)*(M/M_0)^0.16
  else
    T_wind_chill = T_air
  end
 
  return T_wind_chill
end


function calc_feelslike(temperature, wind_speed, humidity)
  local T_feelslike
 
  if temperature <= 10.0 then -- if less than 10.0 Celsius degree (or equal) then wind chill
    T_feelslike = calc_wind_chill(temperature, wind_speed)
  elseif temperature >= 26.7 then -- if more than 26.7 Celsius degree (or equal) then heat index
    T_feelslike = calc_heat_index(temperature, humidity)
  else -- other cases just return temperature
    T_feelslike = temperature
  end

  return T_feelslike
end


local min_max_today = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction
local min_max_tomor = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction

--local latitude = 51.5072 --  'London'
--local longitude = 0.1276 --  'London'
local latitude = 45.921373 --  'Mandello del Lario'
local longitude = 9.314482 --  'Mandello del Lario'

https = require('ssl.https')
json = require('json')
ltn12 = require('ltn12')

args = 'lat=' .. latitude .. '&lon=' .. longitude

url = 'https://api.met.no/weatherapi/locationforecast/2.0/complete?' .. args

mac = 0
io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)
  mac = mac * 256 + tonumber(v, 16)
end)

response = {}

res, code = https.request({
  url = url,
  protocol = 'tlsv12',
  headers = {
    ['user-agent'] = 'LM ' .. mac
  },
  sink = ltn12.sink.table(response)
})


if res and code == 200 then
  data = json.pdecode(table.concat(response))
else
  log('request error', res, code)
end


if type(data) == 'table' then
  timestamp, hour = set_timestamp(0) -- current day
 
  if hour < 10 then
    timestamp_current_hour = timestamp .. 'T0' .. hour .. ':00:00Z' -- time stamp for current hour
  else
    timestamp_current_hour = timestamp .. 'T' .. hour .. ':00:00Z'  -- time stamp for current hour
  end
 
  --log('timestamp = ' .. timestamp)
 
  timestamp_next = set_timestamp(1) -- timestamp for tomorrow
  --log('timestamp_next = ' .. timestamp_next)
 
  --timestamp_after_next = set_timestamp(2) -- timestamp for day after tomorrow
  --log('timestamp_after_next = ' .. timestamp_after_next)
 
  --timestamp_after_after = set_timestamp(3) -- timestamp for day after day after tomorrow
  --log('timestamp_after_after = ' .. timestamp_after_after)
 
  for i, entry in ipairs(data.properties.timeseries) do 
   
    -- for weather now
    if entry.time == timestamp_current_hour then -- get data only for one hour (current hour)
      current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        temperature_YR = current_data.air_temperature or -273          -- temperature in Celsius degree
        air_pressure_YR = current_data.air_pressure_at_sea_level or -1  -- air pressure in hPa
        humidity_YR = current_data.relative_humidity or -1              -- air humidity in %
        wind_direction_YR = current_data.wind_from_direction or -1      -- wind direction in degrees [0;360)
        wind_speed_YR = current_data.wind_speed or -1                  -- wind speed in m/s
        uv_index_YR = current_data.ultraviolet_index_clear_sky or -1    -- uv index
        feelslike_temp_YR = calc_feelslike(temperature_YR, wind_speed_YR, humidity_YR) -- feels like temperature in Celsius degree
      end
     
      next_6h = entry.data.next_6_hours.details
      if type(next_6h) == 'table' then
        precipitation_amount_6h = next_6h.precipitation_amount or -1 -- precipitation amount in mm, next 6 hours
      end
    end
   
    if entry.time:sub(1, #timestamp) == timestamp then -- checks remaining hours + 3 previous hours of current day
    current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        min_max_today = min_max_temp_press_wind(current_data, min_max_today)
      end
     
      if rain_tod_YR == false then -- if detected rain does not check for rain
        rain_tod_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tod_YR == false then -- if detected snow does not check for snow
        snow_tod_YR = check_for_snow(entry.data.next_1_hours)
      end
    end
   
    if entry.time:sub(1, #timestamp_next) == timestamp_next then -- checks 24 hours of next day
      tomor_data = entry.data.instant.details
      if type(tomor_data) == 'table' then
        min_max_tomor = min_max_temp_press_wind(tomor_data, min_max_tomor)
      end
     
      if rain_tom_YR == false then -- if detected rain does not check for rain
        rain_tom_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tom_YR == false then -- if detected snow does not check for snow
        snow_tom_YR = check_for_snow(entry.data.next_1_hours)
      end
    end
 
  end

 
  -- data for current hour
  grp.write(status_temp, temperature_YR)
  grp.write(status_pressure, air_pressure_YR)
  grp.write(status_humidity, humidity_YR)
  grp.write(status_wind_direction, wind_direction_YR)
  grp.write(status_wind_speed, wind_speed_YR)
  grp.write(status_uv_index, uv_index_YR)
  grp.write(status_feelslike_temp, feelslike_temp_YR)
  grp.write(status_precipitation_amount_6h, precipitation_amount_6h) -- precipitation mm for next 6 hours
 
  -- data for today: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_today, rain_tod_YR)
  grp.write(status_snow_today, snow_tod_YR)
 
  grp.write(status_min_temp_today, min_max_today.min_t)
  grp.write(status_max_temp_today, min_max_today.max_t)
  grp.write(status_min_pressure_today, min_max_today.min_p)
  grp.write(status_max_pressure_today, min_max_today.max_p)
  grp.write(status_min_wind_speed_today, min_max_today.min_w)
  grp.write(status_max_wind_speed_today, min_max_today.max_w)
  grp.write(status_min_uv_today, min_max_today.min_uv)
  grp.write(status_max_uv_today, min_max_today.max_uv)
 
 
  -- data for tomorrow: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_tomor, rain_tom_YR)
  grp.write(status_snow_tomor, snow_tom_YR)
 
  grp.write(status_min_temp_tomor, min_max_tomor.min_t)
  grp.write(status_max_temp_tomor, min_max_tomor.max_t)
  grp.write(status_min_pressure_tomor, min_max_tomor.min_p)
  grp.write(status_max_pressure_tomor, min_max_tomor.max_p)
  grp.write(status_min_wind_speed_tomor, min_max_tomor.min_w)
  grp.write(status_max_wind_speed_tomor, min_max_tomor.max_w)
  grp.write(status_min_uv_tomor, min_max_tomor.min_uv)
  grp.write(status_max_uv_tomor, min_max_tomor.max_uv)
 
end

Thank you,
good help for me.

Best regards
Fabio
Reply
#24
(03.11.2022, 06:51)fabiorusco Wrote:
(31.10.2022, 13:48)RomansP Wrote: Hello, fabiorusco!

I have added one more object to my script for api.met.no (it is free, no need for special key, you can monitor weather for tomorrow and after tomorrow).

Here are changes what I have added
Code:
local status_precipitation_amount_6h = grp.create({ datatype = dt.float16, address = '33/1/28', name = 'precipitation_amount_6h',}) -- mm for next 6 hours

local precipitation_amount_6h = -1 -- participation amount in mm next 6 hours

    -- for weather now
    if entry.time == timestamp_current_hour then -- get data only for one hour (current hour)
      current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        temperature_YR = current_data.air_temperature or -273          -- temperature in Celsius degree
        air_pressure_YR = current_data.air_pressure_at_sea_level or -1  -- air pressure in hPa
        humidity_YR = current_data.relative_humidity or -1              -- air humidity in %
        wind_direction_YR = current_data.wind_from_direction or -1      -- wind direction in degrees [0;360)
        wind_speed_YR = current_data.wind_speed or -1                  -- wind speed in m/s
        uv_index_YR = current_data.ultraviolet_index_clear_sky or -1    -- uv index
        feelslike_temp_YR = calc_feelslike(temperature_YR, wind_speed_YR, humidity_YR) -- feels like temperature in Celsius degree
      end
     
      next_6h = entry.data.next_6_hours.details
      if type(next_6h) == 'table' then
        precipitation_amount_6h = next_6h.precipitation_amount or -1 -- precipitation amount in mm, next 6 hours
      end
    end



    grp.write(status_precipitation_amount_6h, precipitation_amount_6h) -- precipitation mm for next 6 hours

And here the whole script:
Code:
local status_temp = grp.create({ datatype = dt.float16, address = '33/1/1', name = 'current_temp',})
local status_pressure = grp.create({ datatype = dt.uint16, address = '33/1/2', name = 'current_press',})
local status_humidity = grp.create({ datatype = dt.scale, address = '33/1/3', name = 'current_humid',})
local status_wind_direction = grp.create({ datatype = dt.float16, address = '33/1/4', name = 'current_wind_dir',})
local status_wind_speed = grp.create({ datatype = dt.float16, address = '33/1/5', name = 'current_wind_sp',})
local status_uv_index = grp.create({ datatype = dt.uint8, address = '33/1/6', name = 'current_uv_index',})
local status_feelslike_temp = grp.create({ datatype = dt.float16, address = '33/1/7', name = 'current_feels_temp',})

local status_rain_today = grp.create({ datatype = dt.bool, address = '33/1/8', name = 'rain_today',})
local status_snow_today = grp.create({ datatype = dt.bool, address = '33/1/9', name = 'snow_today',})

local status_min_temp_today = grp.create({ datatype = dt.float16, address = '33/1/10', name = 'today_temp_min',})
local status_max_temp_today = grp.create({ datatype = dt.float16, address = '33/1/11', name = 'today_temp_max',})
local status_min_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/12', name = 'today_press_min',})
local status_max_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/13', name = 'today_press_max',})
local status_min_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/14', name = 'today_wind_min',})
local status_max_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/15', name = 'today_wind_max',})
local status_min_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/16', name = 'today_uv_min',})
local status_max_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/17', name = 'today_uv_max',})

local status_rain_tomor = grp.create({ datatype = dt.bool, address = '33/1/18', name = 'rain_tomor',})
local status_snow_tomor = grp.create({ datatype = dt.bool, address = '33/1/19', name = 'snow_tomor',})

local status_min_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/20', name = 'tomor_temp_min',})
local status_max_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/21', name = 'tomor_temp_max',})
local status_min_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/22', name = 'tomor_press_min',})
local status_max_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/23', name = 'tomor_press_max',})
local status_min_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/24', name = 'tomor_wind_min',})
local status_max_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/25', name = 'tomor_wind_max',})
local status_min_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/26', name = 'tomor_uv_min',})
local status_max_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/27', name = 'tomor_uv_max',})

local status_precipitation_amount_6h = grp.create({ datatype = dt.float16, address = '33/1/28', name = 'precipitation_amount_6h',}) -- mm for next 6 hours

local rain_tod_YR = false        -- is rainy or not (for today)
local snow_tod_YR = false        -- is snowy or not (for today)
local rain_tom_YR = false        -- is rainy or not (for tomorrow)
local snow_tom_YR = false        -- is snowy or not (for tomorrow)

-- current temperature, air pressure, humidity, wind direction and speed
local temperature_YR = -273    -- temperature in degree Celsius
local air_pressure_YR = -1    -- air pressure in hPa
local humidity_YR = -1        -- air humidity in %
local wind_direction_YR = -1  -- wind direction in degrees [0; 360)
local wind_speed_YR = -1      -- wind speed in m/s
local uv_index_YR = -1        -- UV index
local feelslike_temp_YR = -273 -- feels like temperature in degree Celsius
local precipitation_amount_6h = -1 -- participation amount in mm next 6 hours


function init_min_max_table() -- initialize table for minimum, maximum temperature, pressure, windspeed
  local min_max = {}
  min_max.min_t = 8000 -- minimum temperature for today
  min_max.max_t = -273 -- maximum temperature for today
  min_max.min_p = 8000 -- minimum pressure for today
  min_max.max_p = -1  -- maximum pressure for today
  min_max.min_w = 8000 -- minimum wind speed for today
  min_max.max_w = -1  -- maximum wind speed for today
  min_max.min_uv = 8000 -- minimum UV index
  min_max.max_uv = -1  -- maximum UV index
 
  return min_max
end


function set_timestamp(day) -- if day = 0 today; if day = 1 tomorrow, if day = 2 day after tomorrow
  local date = os.date('*t')
  date.day = date.day + day
  local time = os.time(date)
  return os.date('%Y-%m-%d', time), date.hour -- timestamp and current hour
end


-- minimum maximum values of temperature, pressure and windspeed
function min_max_temp_press_wind(dat_tab, min_max_tab)
  min_max_tab.min_t = math.min(min_max_tab.min_t, dat_tab.air_temperature or 8000)
  min_max_tab.max_t = math.max(min_max_tab.max_t, dat_tab.air_temperature or -273)
  min_max_tab.min_p = math.min(min_max_tab.min_p, dat_tab.air_pressure_at_sea_level or 8000)
  min_max_tab.max_p = math.max(min_max_tab.max_p, dat_tab.air_pressure_at_sea_level or -1)
  min_max_tab.min_w = math.min(min_max_tab.min_w, dat_tab.wind_speed or 8000)
  min_max_tab.max_w = math.max(min_max_tab.max_w, dat_tab.wind_speed or -1)
  min_max_tab.min_uv = math.min(min_max_tab.min_uv, dat_tab.ultraviolet_index_clear_sky or 8000)
  min_max_tab.max_uv = math.max(min_max_tab.max_uv, dat_tab.ultraviolet_index_clear_sky or -1)
 
  return min_max_tab
end


function check_for_rain(next1h)
  local is_rainy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('rain') then
    is_rainy = true
  end
 
  return is_rainy
end


function check_for_snow(next1h)
  local is_snowy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('snow') then
    is_snowy = true
  end

  return is_snowy
end


function calc_heat_index(temperature, humidity)
  if temperature < 26.7 then
    log('for heat_index calculation temperature should be higher than +26.7 Celsius degree')
    return -273
  end
 
  if humidity < 0 or humidity > 100 then
    log('humidity should be in a range from 0 ... 100%')
    return -273
  end
 
  local T = temperature
  local H = humidity
  local c_1 = -8.785
  local c_2 = 1.611
  local c_3 = 2.339
  local c_4 = -0.146
  local c_5 = -0.0123
  local c_6 = -0.0164
  local c_7 = 0.00221
  local c_8 = 0.000725
  local c_9 = -0.00000358
  local heat_index = c_1+c_2*T+c_3*H+c_4*T*H+c_5*T*T+c_6*H*H+c_7*T*T*H+c_8*T*H*H+c_9*T*T*H*H
 
return heat_index
end


function calc_wind_chill(temperature, wind_speed)
  if temperature > 10 then
    log('temperature should be less than +10.0 Celsius degree')
  return -273
  end
   
  if wind_speed < 0 or wind_speed > 49.2 then
  log('wind speed should be in a range 0 ... 49.2 m/s')
    return -273
  end
 
  local T_air = temperature -- air temperature Celsius degree
 
  local a = 0.62 -- coef
  local b = 0.51 -- coef
  local T_1 = 13.1 -- Celsius degree
  local T_2 = 14.6 -- Celsius degree
 
  local M_0 = 1.3333 -- m/s
  local M = wind_speed -- m/s
 
  local T_wind_chill
 
  if M > M_0 then
    T_wind_chill = (a*T_air + T_1) + (b*T_air - T_2)*(M/M_0)^0.16
  else
    T_wind_chill = T_air
  end
 
  return T_wind_chill
end


function calc_feelslike(temperature, wind_speed, humidity)
  local T_feelslike
 
  if temperature <= 10.0 then -- if less than 10.0 Celsius degree (or equal) then wind chill
    T_feelslike = calc_wind_chill(temperature, wind_speed)
  elseif temperature >= 26.7 then -- if more than 26.7 Celsius degree (or equal) then heat index
    T_feelslike = calc_heat_index(temperature, humidity)
  else -- other cases just return temperature
    T_feelslike = temperature
  end

  return T_feelslike
end


local min_max_today = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction
local min_max_tomor = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction

--local latitude = 51.5072 --  'London'
--local longitude = 0.1276 --  'London'
local latitude = 45.921373 --  'Mandello del Lario'
local longitude = 9.314482 --  'Mandello del Lario'

https = require('ssl.https')
json = require('json')
ltn12 = require('ltn12')

args = 'lat=' .. latitude .. '&lon=' .. longitude

url = 'https://api.met.no/weatherapi/locationforecast/2.0/complete?' .. args

mac = 0
io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)
  mac = mac * 256 + tonumber(v, 16)
end)

response = {}

res, code = https.request({
  url = url,
  protocol = 'tlsv12',
  headers = {
    ['user-agent'] = 'LM ' .. mac
  },
  sink = ltn12.sink.table(response)
})


if res and code == 200 then
  data = json.pdecode(table.concat(response))
else
  log('request error', res, code)
end


if type(data) == 'table' then
  timestamp, hour = set_timestamp(0) -- current day
 
  if hour < 10 then
    timestamp_current_hour = timestamp .. 'T0' .. hour .. ':00:00Z' -- time stamp for current hour
  else
    timestamp_current_hour = timestamp .. 'T' .. hour .. ':00:00Z'  -- time stamp for current hour
  end
 
  --log('timestamp = ' .. timestamp)
 
  timestamp_next = set_timestamp(1) -- timestamp for tomorrow
  --log('timestamp_next = ' .. timestamp_next)
 
  --timestamp_after_next = set_timestamp(2) -- timestamp for day after tomorrow
  --log('timestamp_after_next = ' .. timestamp_after_next)
 
  --timestamp_after_after = set_timestamp(3) -- timestamp for day after day after tomorrow
  --log('timestamp_after_after = ' .. timestamp_after_after)
 
  for i, entry in ipairs(data.properties.timeseries) do 
   
    -- for weather now
    if entry.time == timestamp_current_hour then -- get data only for one hour (current hour)
      current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        temperature_YR = current_data.air_temperature or -273          -- temperature in Celsius degree
        air_pressure_YR = current_data.air_pressure_at_sea_level or -1  -- air pressure in hPa
        humidity_YR = current_data.relative_humidity or -1              -- air humidity in %
        wind_direction_YR = current_data.wind_from_direction or -1      -- wind direction in degrees [0;360)
        wind_speed_YR = current_data.wind_speed or -1                  -- wind speed in m/s
        uv_index_YR = current_data.ultraviolet_index_clear_sky or -1    -- uv index
        feelslike_temp_YR = calc_feelslike(temperature_YR, wind_speed_YR, humidity_YR) -- feels like temperature in Celsius degree
      end
     
      next_6h = entry.data.next_6_hours.details
      if type(next_6h) == 'table' then
        precipitation_amount_6h = next_6h.precipitation_amount or -1 -- precipitation amount in mm, next 6 hours
      end
    end
   
    if entry.time:sub(1, #timestamp) == timestamp then -- checks remaining hours + 3 previous hours of current day
    current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        min_max_today = min_max_temp_press_wind(current_data, min_max_today)
      end
     
      if rain_tod_YR == false then -- if detected rain does not check for rain
        rain_tod_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tod_YR == false then -- if detected snow does not check for snow
        snow_tod_YR = check_for_snow(entry.data.next_1_hours)
      end
    end
   
    if entry.time:sub(1, #timestamp_next) == timestamp_next then -- checks 24 hours of next day
      tomor_data = entry.data.instant.details
      if type(tomor_data) == 'table' then
        min_max_tomor = min_max_temp_press_wind(tomor_data, min_max_tomor)
      end
     
      if rain_tom_YR == false then -- if detected rain does not check for rain
        rain_tom_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tom_YR == false then -- if detected snow does not check for snow
        snow_tom_YR = check_for_snow(entry.data.next_1_hours)
      end
    end
 
  end

 
  -- data for current hour
  grp.write(status_temp, temperature_YR)
  grp.write(status_pressure, air_pressure_YR)
  grp.write(status_humidity, humidity_YR)
  grp.write(status_wind_direction, wind_direction_YR)
  grp.write(status_wind_speed, wind_speed_YR)
  grp.write(status_uv_index, uv_index_YR)
  grp.write(status_feelslike_temp, feelslike_temp_YR)
  grp.write(status_precipitation_amount_6h, precipitation_amount_6h) -- precipitation mm for next 6 hours
 
  -- data for today: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_today, rain_tod_YR)
  grp.write(status_snow_today, snow_tod_YR)
 
  grp.write(status_min_temp_today, min_max_today.min_t)
  grp.write(status_max_temp_today, min_max_today.max_t)
  grp.write(status_min_pressure_today, min_max_today.min_p)
  grp.write(status_max_pressure_today, min_max_today.max_p)
  grp.write(status_min_wind_speed_today, min_max_today.min_w)
  grp.write(status_max_wind_speed_today, min_max_today.max_w)
  grp.write(status_min_uv_today, min_max_today.min_uv)
  grp.write(status_max_uv_today, min_max_today.max_uv)
 
 
  -- data for tomorrow: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_tomor, rain_tom_YR)
  grp.write(status_snow_tomor, snow_tom_YR)
 
  grp.write(status_min_temp_tomor, min_max_tomor.min_t)
  grp.write(status_max_temp_tomor, min_max_tomor.max_t)
  grp.write(status_min_pressure_tomor, min_max_tomor.min_p)
  grp.write(status_max_pressure_tomor, min_max_tomor.max_p)
  grp.write(status_min_wind_speed_tomor, min_max_tomor.min_w)
  grp.write(status_max_wind_speed_tomor, min_max_tomor.max_w)
  grp.write(status_min_uv_tomor, min_max_tomor.min_uv)
  grp.write(status_max_uv_tomor, min_max_tomor.max_uv)
 
end

Thank you,
good help for me.

Best regards
Fabio

Hello,
how it's possible to know the total precipitation of today?
Is it good also for Italy ? (the service is located in scandinavian zone)
Reply
#25
Hello.

I have added calculation of precipitation amount of current day (gives you precipitation amount of remaining day + 3 previous hours of current day).
It is also suitable for Italy (have checked with Rome coordinates).

Code:
local status_temp = grp.create({ datatype = dt.float16, address = '33/1/1', name = 'current_temp',})
local status_pressure = grp.create({ datatype = dt.uint16, address = '33/1/2', name = 'current_press',})
local status_humidity = grp.create({ datatype = dt.scale, address = '33/1/3', name = 'current_humid',})
local status_wind_direction = grp.create({ datatype = dt.float16, address = '33/1/4', name = 'current_wind_dir',})
local status_wind_speed = grp.create({ datatype = dt.float16, address = '33/1/5', name = 'current_wind_sp',})
local status_uv_index = grp.create({ datatype = dt.uint8, address = '33/1/6', name = 'current_uv_index',})
local status_feelslike_temp = grp.create({ datatype = dt.float16, address = '33/1/7', name = 'current_feels_temp',})

local status_rain_today = grp.create({ datatype = dt.bool, address = '33/1/8', name = 'rain_today',})
local status_snow_today = grp.create({ datatype = dt.bool, address = '33/1/9', name = 'snow_today',})

local status_min_temp_today = grp.create({ datatype = dt.float16, address = '33/1/10', name = 'today_temp_min',})
local status_max_temp_today = grp.create({ datatype = dt.float16, address = '33/1/11', name = 'today_temp_max',})
local status_min_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/12', name = 'today_press_min',})
local status_max_pressure_today = grp.create({ datatype = dt.uint16, address = '33/1/13', name = 'today_press_max',})
local status_min_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/14', name = 'today_wind_min',})
local status_max_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/15', name = 'today_wind_max',})
local status_min_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/16', name = 'today_uv_min',})
local status_max_uv_today = grp.create({ datatype = dt.uint8, address = '33/1/17', name = 'today_uv_max',})

local status_rain_tomor = grp.create({ datatype = dt.bool, address = '33/1/18', name = 'rain_tomor',})
local status_snow_tomor = grp.create({ datatype = dt.bool, address = '33/1/19', name = 'snow_tomor',})

local status_min_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/20', name = 'tomor_temp_min',})
local status_max_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/21', name = 'tomor_temp_max',})
local status_min_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/22', name = 'tomor_press_min',})
local status_max_pressure_tomor = grp.create({ datatype = dt.uint16, address = '33/1/23', name = 'tomor_press_max',})
local status_min_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/24', name = 'tomor_wind_min',})
local status_max_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/25', name = 'tomor_wind_max',})
local status_min_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/26', name = 'tomor_uv_min',})
local status_max_uv_tomor = grp.create({ datatype = dt.uint8, address = '33/1/27', name = 'tomor_uv_max',})

local status_precipitation_amount_6h = grp.create({ datatype = dt.float16, address = '33/1/28', name = 'precipitation_amount_6h',}) -- mm for next 6 hours
local status_precipitation_amount_today = grp.create({ datatype = dt.float16, address = '33/1/29', name = 'precipitation_amount_today',}) -- mm for current day + 3 previous hours

local rain_tod_YR = false        -- is rainy or not (for today)
local snow_tod_YR = false        -- is snowy or not (for today)
local rain_tom_YR = false        -- is rainy or not (for tomorrow)
local snow_tom_YR = false        -- is snowy or not (for tomorrow)

-- current temperature, air pressure, humidity, wind direction and speed
local temperature_YR = -273    -- temperature in degree Celsius
local air_pressure_YR = -1    -- air pressure in hPa
local humidity_YR = -1        -- air humidity in %
local wind_direction_YR = -1  -- wind direction in degrees [0; 360)
local wind_speed_YR = -1      -- wind speed in m/s
local uv_index_YR = -1        -- UV index
local feelslike_temp_YR = -273 -- feels like temperature in degree Celsius
local precipitation_amount_6h = -1 -- participation amount in mm next 6 hours
local precipitation_amount_today = 0 -- participation amount in mm for current day + 3 previous hours

function init_min_max_table() -- initialize table for minimum, maximum temperature, pressure, windspeed
  local min_max = {}
  min_max.min_t = 8000 -- minimum temperature for today
  min_max.max_t = -273 -- maximum temperature for today
  min_max.min_p = 8000 -- minimum pressure for today
  min_max.max_p = -1  -- maximum pressure for today
  min_max.min_w = 8000 -- minimum wind speed for today
  min_max.max_w = -1  -- maximum wind speed for today
  min_max.min_uv = 8000 -- minimum UV index
  min_max.max_uv = -1  -- maximum UV index
 
  return min_max
end


function set_timestamp(day) -- if day = 0 today; if day = 1 tomorrow, if day = 2 day after tomorrow
  local date = os.date('*t')
  date.day = date.day + day
  local time = os.time(date)
  return os.date('%Y-%m-%d', time), date.hour -- timestamp and current hour
end


-- minimum maximum values of temperature, pressure and windspeed
function min_max_temp_press_wind(dat_tab, min_max_tab)
  min_max_tab.min_t = math.min(min_max_tab.min_t, dat_tab.air_temperature or 8000)
  min_max_tab.max_t = math.max(min_max_tab.max_t, dat_tab.air_temperature or -273)
  min_max_tab.min_p = math.min(min_max_tab.min_p, dat_tab.air_pressure_at_sea_level or 8000)
  min_max_tab.max_p = math.max(min_max_tab.max_p, dat_tab.air_pressure_at_sea_level or -1)
  min_max_tab.min_w = math.min(min_max_tab.min_w, dat_tab.wind_speed or 8000)
  min_max_tab.max_w = math.max(min_max_tab.max_w, dat_tab.wind_speed or -1)
  min_max_tab.min_uv = math.min(min_max_tab.min_uv, dat_tab.ultraviolet_index_clear_sky or 8000)
  min_max_tab.max_uv = math.max(min_max_tab.max_uv, dat_tab.ultraviolet_index_clear_sky or -1)
 
  return min_max_tab
end


function check_for_rain(next1h)
  local is_rainy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('rain') then
    is_rainy = true
  end
 
  return is_rainy
end


function check_for_snow(next1h)
  local is_snowy = false
  local code = ''
 
  if type(next1h) == 'table' and type(next1h.summary) == 'table' then
    code = next1h.summary.symbol_code or ''
  end
 
  if code:find('snow') then
    is_snowy = true
  end

  return is_snowy
end


function calc_heat_index(temperature, humidity)
  if temperature < 26.7 then
    log('for heat_index calculation temperature should be higher than +26.7 Celsius degree')
    return -273
  end
 
  if humidity < 0 or humidity > 100 then
    log('humidity should be in a range from 0 ... 100%')
    return -273
  end
 
  local T = temperature
  local H = humidity
  local c_1 = -8.785
  local c_2 = 1.611
  local c_3 = 2.339
  local c_4 = -0.146
  local c_5 = -0.0123
  local c_6 = -0.0164
  local c_7 = 0.00221
  local c_8 = 0.000725
  local c_9 = -0.00000358
  local heat_index = c_1+c_2*T+c_3*H+c_4*T*H+c_5*T*T+c_6*H*H+c_7*T*T*H+c_8*T*H*H+c_9*T*T*H*H
 
return heat_index
end


function calc_wind_chill(temperature, wind_speed)
  if temperature > 10 then
    log('temperature should be less than +10.0 Celsius degree')
  return -273
  end
   
  if wind_speed < 0 or wind_speed > 49.2 then
  log('wind speed should be in a range 0 ... 49.2 m/s')
    return -273
  end
 
  local T_air = temperature -- air temperature Celsius degree
 
  local a = 0.62 -- coef
  local b = 0.51 -- coef
  local T_1 = 13.1 -- Celsius degree
  local T_2 = 14.6 -- Celsius degree
 
  local M_0 = 1.3333 -- m/s
  local M = wind_speed -- m/s
 
  local T_wind_chill
 
  if M > M_0 then
    T_wind_chill = (a*T_air + T_1) + (b*T_air - T_2)*(M/M_0)^0.16
  else
    T_wind_chill = T_air
  end
 
  return T_wind_chill
end


function calc_feelslike(temperature, wind_speed, humidity)
  local T_feelslike
 
  if temperature <= 10.0 then -- if less than 10.0 Celsius degree (or equal) then wind chill
    T_feelslike = calc_wind_chill(temperature, wind_speed)
  elseif temperature >= 26.7 then -- if more than 26.7 Celsius degree (or equal) then heat index
    T_feelslike = calc_heat_index(temperature, humidity)
  else -- other cases just return temperature
    T_feelslike = temperature
  end

  return T_feelslike
end


local min_max_today = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction
local min_max_tomor = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction

--local latitude = 51.5072 --  'London'
--local longitude = 0.1276 --  'London'
local latitude = 45.921373 --  'Mandello del Lario'
local longitude = 9.314482 --  'Mandello del Lario'

https = require('ssl.https')
json = require('json')
ltn12 = require('ltn12')

args = 'lat=' .. latitude .. '&lon=' .. longitude

url = 'https://api.met.no/weatherapi/locationforecast/2.0/complete?' .. args

mac = 0
io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)
  mac = mac * 256 + tonumber(v, 16)
end)

response = {}

res, code = https.request({
  url = url,
  protocol = 'tlsv12',
  headers = {
    ['user-agent'] = 'LM ' .. mac
  },
  sink = ltn12.sink.table(response)
})


if res and code == 200 then
  data = json.pdecode(table.concat(response))
else
  log('request error', res, code)
end


if type(data) == 'table' then
  timestamp, hour = set_timestamp(0) -- current day
 
  if hour < 10 then
    timestamp_current_hour = timestamp .. 'T0' .. hour .. ':00:00Z' -- time stamp for current hour
  else
    timestamp_current_hour = timestamp .. 'T' .. hour .. ':00:00Z'  -- time stamp for current hour
  end
 
  --log('timestamp = ' .. timestamp)
 
  timestamp_next = set_timestamp(1) -- timestamp for tomorrow
  --log('timestamp_next = ' .. timestamp_next)
 
  --timestamp_after_next = set_timestamp(2) -- timestamp for day after tomorrow
  --log('timestamp_after_next = ' .. timestamp_after_next)
 
  --timestamp_after_after = set_timestamp(3) -- timestamp for day after day after tomorrow
  --log('timestamp_after_after = ' .. timestamp_after_after)
 
  for i, entry in ipairs(data.properties.timeseries) do 
   
    -- for weather now
    if entry.time == timestamp_current_hour then -- get data only for one hour (current hour)
      current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        temperature_YR = current_data.air_temperature or -273          -- temperature in Celsius degree
        air_pressure_YR = current_data.air_pressure_at_sea_level or -1  -- air pressure in hPa
        humidity_YR = current_data.relative_humidity or -1              -- air humidity in %
        wind_direction_YR = current_data.wind_from_direction or -1      -- wind direction in degrees [0;360)
        wind_speed_YR = current_data.wind_speed or -1                  -- wind speed in m/s
        uv_index_YR = current_data.ultraviolet_index_clear_sky or -1    -- uv index
        feelslike_temp_YR = calc_feelslike(temperature_YR, wind_speed_YR, humidity_YR) -- feels like temperature in Celsius degree
      end
     
      next_6h = entry.data.next_6_hours.details
      if type(next_6h) == 'table' then
        precipitation_amount_6h = next_6h.precipitation_amount or -1 -- precipitation amount in mm, next 6 hours
      end
    end
   
   
    if entry.time:sub(1, #timestamp) == timestamp then -- checks remaining hours + 3 previous hours of current day
    current_data = entry.data.instant.details
      if type(current_data) == 'table' then
        min_max_today = min_max_temp_press_wind(current_data, min_max_today)
      end
     
      if rain_tod_YR == false then -- if detected rain does not check for rain
        rain_tod_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tod_YR == false then -- if detected snow does not check for snow
        snow_tod_YR = check_for_snow(entry.data.next_1_hours)
      end
     
      precipitation_amount_today = precipitation_amount_today + (entry.data.next_1_hours.details.precipitation_amount or 0)
    end
   
    if entry.time:sub(1, #timestamp_next) == timestamp_next then -- checks 24 hours of next day
      tomor_data = entry.data.instant.details
      if type(tomor_data) == 'table' then
        min_max_tomor = min_max_temp_press_wind(tomor_data, min_max_tomor)
      end
     
      if rain_tom_YR == false then -- if detected rain does not check for rain
        rain_tom_YR = check_for_rain(entry.data.next_1_hours)
      end
     
      if snow_tom_YR == false then -- if detected snow does not check for snow
        snow_tom_YR = check_for_snow(entry.data.next_1_hours)
      end
    end
 
  end

 
  -- data for current hour
  grp.write(status_temp, temperature_YR)
  grp.write(status_pressure, air_pressure_YR)
  grp.write(status_humidity, humidity_YR)
  grp.write(status_wind_direction, wind_direction_YR)
  grp.write(status_wind_speed, wind_speed_YR)
  grp.write(status_uv_index, uv_index_YR)
  grp.write(status_feelslike_temp, feelslike_temp_YR)
  grp.write(status_precipitation_amount_6h, precipitation_amount_6h) -- precipitation mm for next 6 hours
  grp.write(status_precipitation_amount_today, precipitation_amount_today) -- precipitation mm for today (remaining day + 3 previous hours)
 
  -- data for today: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_today, rain_tod_YR)
  grp.write(status_snow_today, snow_tod_YR)
 
  grp.write(status_min_temp_today, min_max_today.min_t)
  grp.write(status_max_temp_today, min_max_today.max_t)
  grp.write(status_min_pressure_today, min_max_today.min_p)
  grp.write(status_max_pressure_today, min_max_today.max_p)
  grp.write(status_min_wind_speed_today, min_max_today.min_w)
  grp.write(status_max_wind_speed_today, min_max_today.max_w)
  grp.write(status_min_uv_today, min_max_today.min_uv)
  grp.write(status_max_uv_today, min_max_today.max_uv)
 
 
  -- data for tomorrow: rain, snow; min and max for temperature, pressure, wind
  grp.write(status_rain_tomor, rain_tom_YR)
  grp.write(status_snow_tomor, snow_tom_YR)
 
  grp.write(status_min_temp_tomor, min_max_tomor.min_t)
  grp.write(status_max_temp_tomor, min_max_tomor.max_t)
  grp.write(status_min_pressure_tomor, min_max_tomor.min_p)
  grp.write(status_max_pressure_tomor, min_max_tomor.max_p)
  grp.write(status_min_wind_speed_tomor, min_max_tomor.min_w)
  grp.write(status_max_wind_speed_tomor, min_max_tomor.max_w)
  grp.write(status_min_uv_tomor, min_max_tomor.min_uv)
  grp.write(status_max_uv_tomor, min_max_tomor.max_uv)
 
end

Attached Files
.lua   my_script_v16.lua (Size: 14.7 KB / Downloads: 27)
Reply
#26
Thank you.
Reply
#27
Hello. 
I have tried the latest version on my spacelynk with vr 2.8.0
I am getting this error in the log:
* arg: 1
  * string: request error
* arg: 2
  * nil
* arg: 3
  * string: Try again

Could someone point me in the right direction? 
I think it something here that's not right:

https = require('ssl.https')
json = require('json')
ltn12 = require('ltn12')

args = 'lat=' .. latitude .. '&lon=' .. longitude

url = 'https://api.met.no/weatherapi/locationforecast/2.0/complete?' .. args

mac = 0
io.readfile('/sys/class/net/eth0/address'):gsub('%x%x', function(v)
  mac = mac * 256 + tonumber(v, 16)
end)


This is the only changes I have done:
--local latitude = 69.6489 --  'Tromso'
--local longitude = 18.95508 --  'Tromso'
local latitude = 69.6489 --  'Tromso'
local longitude = 18.95508 --  'Tromso'
Reply
#28
Check that you have correct gateway and DNS settings in System config > Network > Interfaces.
Reply
#29
is working for me, thanks
Reply


Forum Jump: