08.06.2022, 08:52
Hi, here is new yr weather script.
Code:
-- Please comment objects which you are not using, comment also grp.write() at the bottom of script
--latitude = 60.3894 -- Bergen
--longitude = 5.33 -- Bergen
latitude = 56.9496 -- Riga
longitude = 24.1052 -- Riga
--latitude = 51.5072 -- London
--longitude = 0.1276 -- London
--[[
status_temp = '32/1/13' -- group address of temperature, should be float
status_pressure = '32/1/14' -- air pressure, should be float
status_humidity = '32/1/15' -- relative humidity, should be float
status_wind_direction = '32/1/16' -- wind direction, should be float
status_wind_speed = '32/1/17' -- wind speed, should be float
status_uv_index = '32/2/4' -- UV index, should be float
status_feelslike_temp = '32/2/3' -- feels like temperature, should be float
status_rain_today = '32/1/11' -- today's rain object, should be boolean
status_snow_today = '32/1/12' -- today's snow object, should be boolean
status_min_temp_today = '32/1/20' -- today's minimum air temperature, float
status_max_temp_today = '32/1/21' -- today's maximum air temperature, float
status_min_pressure_today = '32/1/22' -- minimum air pressure, float
status_max_pressure_today = '32/1/23' -- maximum air pressure, float
status_min_wind_speed_today = '32/1/24' -- minimum wind speed, float
status_max_wind_speed_today = '32/1/25' -- maximum wind speed, float
status_min_uv_today = '32/2/5' -- minimum UV today, float
status_max_uv_today = '32/2/6' -- maximum UV today, float
status_rain_tomor = '32/1/9' -- tomorrow's rain object
status_snow_tomor = '32/1/10' -- tomorrow's snow object
status_min_temp_tomor = '32/1/26'
status_max_temp_tomor = '32/1/27'
status_min_pressure_tomor = '32/1/28'
status_max_pressure_tomor = '32/1/29'
status_min_wind_speed_tomor = '32/1/30'
status_max_wind_speed_tomor = '32/1/31'
status_min_uv_tomor = '32/2/7'
status_max_uv_tomor = '32/2/8'
--]]
--[[]]
status_temp = grp.create({ datatype = dt.float16, address = '33/1/1', name = 'current_temp',})
status_pressure = grp.create({ datatype = dt.float16, address = '33/1/2', name = 'current_press',})
status_humidity = grp.create({ datatype = dt.float16, address = '33/1/3', name = 'current_humid',})
status_wind_direction = grp.create({ datatype = dt.float16, address = '33/1/4', name = 'current_wind_dir',})
status_wind_speed = grp.create({ datatype = dt.float16, address = '33/1/5', name = 'current_wind_sp',})
status_uv_index = grp.create({ datatype = dt.float16, address = '33/1/6', name = 'current_uv_index',})
status_feelslike_temp = grp.create({ datatype = dt.float16, address = '33/1/7', name = 'current_feels_temp',})
status_rain_today = grp.create({ datatype = dt.bool, address = '33/1/8', name = 'rain_today',})
status_snow_today = grp.create({ datatype = dt.bool, address = '33/1/9', name = 'snow_today',})
status_min_temp_today = grp.create({ datatype = dt.float16, address = '33/1/10', name = 'today_temp_min',})
status_max_temp_today = grp.create({ datatype = dt.float16, address = '33/1/11', name = 'today_temp_max',})
status_min_pressure_today = grp.create({ datatype = dt.float16, address = '33/1/12', name = 'today_press_min',})
status_max_pressure_today = grp.create({ datatype = dt.float16, address = '33/1/13', name = 'today_press_max',})
status_min_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/14', name = 'today_wind_min',})
status_max_wind_speed_today = grp.create({ datatype = dt.float16, address = '33/1/15', name = 'today_press_max',})
status_min_uv_today = grp.create({ datatype = dt.float16, address = '33/1/16', name = 'today_uv_min',})
status_max_uv_today = grp.create({ datatype = dt.float16, address = '33/1/17', name = 'today_uv_max',})
status_rain_tomor = grp.create({ datatype = dt.bool, address = '33/1/18', name = 'rain_tomor',})
status_snow_tomor = grp.create({ datatype = dt.bool, address = '33/1/19', name = 'snow_tomor',})
status_min_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/20', name = 'tomor_temp_min',})
status_max_temp_tomor = grp.create({ datatype = dt.float16, address = '33/1/21', name = 'tomor_temp_max',})
status_min_pressure_tomor = grp.create({ datatype = dt.float16, address = '33/1/22', name = 'tomor_press_min',})
status_max_pressure_tomor = grp.create({ datatype = dt.float16, address = '33/1/23', name = 'tomor_press_max',})
status_min_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/24', name = 'tomor_wind_min',})
status_max_wind_speed_tomor = grp.create({ datatype = dt.float16, address = '33/1/25', name = 'tomor_wind_max',})
status_min_uv_tomor = grp.create({ datatype = dt.float16, address = '33/1/26', name = 'tomor_uv_min',})
status_max_uv_tomor = grp.create({ datatype = dt.float16, address = '33/1/27', name = 'tomor_uv_max',})
--]]
rain_tod_YR = false -- is rainy or not (for today)
snow_tod_YR = false -- is snowy or not (for today)
rain_tom_YR = false -- is rainy or not (for tomorrow)
snow_tom_YR = false -- is snowy or not (for tomorrow)
-- current temperature, air pressure, humidity, wind direction and speed
temperature_YR = -273 -- temperature in degree Celsius
air_pressure_YR = -1 -- air pressure in hPa
humidity_YR = -1 -- air humidity in %
wind_direction_YR = -1 -- wind direction in degrees [0; 360)
wind_speed_YR = -1 -- wind speed in m/s
uv_index_YR = -1 -- UV index
feelslike_temp_YR = -273 -- feels like temperature in degree Celsius
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
min_max_today = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction
min_max_tomor = init_min_max_table() -- table for minimum maximum temperature, air pressure, wind direction
json = require('json')
http = require('socket.http')
args = 'lat=' .. latitude .. '&lon=' .. longitude
--url = 'https://api.met.no/weatherapi/locationforecast/2.0/compact?' .. args
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)
http.USERAGENT = 'LM ' .. mac
res, err = http.request(url)
data = json.pdecode(res)
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
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)
-- 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