@@ -17,17 +17,18 @@ local type = type
1717local tonumber = tonumber
1818
1919-- OpenWeatherMap
20- -- current weather and X-days forecast
20+ -- current weather and 5d/3h forecast
2121-- lain.widget.weather
2222
2323local function factory (args )
2424 args = args or {}
2525
26- local weather = { widget = args .widget or wibox .widget .textbox () }
26+ -- weather.now will hold the 'current' and 'forecast' state
27+ local weather = { widget = args .widget or wibox .widget .textbox (), now = {} }
2728 local APPID = args .APPID -- mandatory api key
2829 local timeout = args .timeout or 900 -- 15 min
29- local current_call = args .current_call or " curl -s ' https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&APPID=%s&units=%s&lang=%s' "
30- local forecast_call = args .forecast_call or " curl -s ' https://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&APPID=%s&cnt=%s&units=%s&lang=%s' "
30+ local current_uri = args .current_uri or " https://api.openweathermap.org/data/2.5/weather?lat=%s&lon=%s&APPID=%s&units=%s&lang=%s"
31+ local forecast_uri = args .forecast_uri or " https://api.openweathermap.org/data/2.5/forecast?lat=%s&lon=%s&APPID=%s&cnt=%s&units=%s&lang=%s"
3132 local lat = args .lat or 0 -- placeholder
3233 local lon = args .lon or 0 -- placeholder
3334 local units = args .units or " metric"
@@ -37,15 +38,15 @@ local function factory(args)
3738 local notification_preset = args .notification_preset or {}
3839 local notification_text_fun = args .notification_text_fun or
3940 function (wn )
40- local day = os.date (" %a %d" , wn [" dt" ])
41+ local day = os.date (" %a %d %H:%M " , wn [" dt" ])
4142 local temp = math.floor (wn [" main" ][" temp" ])
4243 local desc = wn [" weather" ][1 ][" description" ]
43- return string.format (" <b>%s</b>: %s, %d " , day , desc , temp )
44+ return string.format (" <b>%s</b>: %s, %d° " , day , desc , temp )
4445 end
4546 local weather_na_markup = args .weather_na_markup or " N/A "
4647 local followtag = args .followtag or false
4748 local showpopup = args .showpopup or " on"
48- local settings = args .settings or function () end
49+ local settings = args .settings or function (_ , _ ) end
4950
5051 weather .widget :set_markup (weather_na_markup )
5152 weather .icon_path = icons_path .. " na.png"
@@ -88,18 +89,17 @@ local function factory(args)
8889 end
8990
9091 function weather .forecast_update ()
91- local cmd = string.format (forecast_call , lat , lon , APPID , cnt , units , lang )
92+ local uri = string.format (forecast_uri , lat , lon , APPID , cnt , units , lang )
93+ helpers .uri (uri , function (f )
94+ local forecast , _ , err = json .decode (f , 1 , nil )
9295
93- helpers .async (cmd , function (f )
94- local err
95- weather_now , _ , err = json .decode (f , 1 , nil )
96-
97- if not err and type (weather_now ) == " table" and tonumber (weather_now [" cod" ]) == 200 then
96+ if not err and type (weather .forecast ) == " table" and tonumber (forecast [" cod" ]) == 200 then
97+ weather .now .forecast = forecast
9898 weather .notification_text = " "
99- for i = 1 , weather_now [" cnt" ], math.floor (weather_now [" cnt" ] / cnt ) do
99+ for i = 1 , forecast [" cnt" ], math.floor (forecast [" cnt" ] / cnt ) do
100100 weather .notification_text = weather .notification_text ..
101- notification_text_fun (weather_now [" list" ][i ])
102- if i < weather_now [" cnt" ] then
101+ notification_text_fun (forecast [" list" ][i ])
102+ if i < forecast [" cnt" ] then
103103 weather .notification_text = weather .notification_text .. " \n "
104104 end
105105 end
@@ -108,17 +108,18 @@ local function factory(args)
108108 end
109109
110110 function weather .update ()
111- local cmd = string.format (current_call , lat , lon , APPID , units , lang )
112-
113- helpers .async (cmd , function (f )
114- local err
115- weather_now , _ , err = json .decode (f , 1 , nil )
116-
117- if not err and type (weather_now ) == " table" and tonumber (weather_now [" cod" ]) == 200 then
118- local sunrise = tonumber (weather_now [" sys" ][" sunrise" ])
119- local sunset = tonumber (weather_now [" sys" ][" sunset" ])
120- local icon = weather_now [" weather" ][1 ][" icon" ]
111+ local uri = string.format (current_uri , lat , lon , APPID , units , lang )
112+ helpers .uri (uri , function (f )
113+ local current , _ , err = json .decode (f , 1 , nil )
114+
115+ if not err and type (current ) == " table" and tonumber (current [" cod" ]) == 200 then
116+ weather .now .current = current
117+ local sunrise = tonumber (current [" sys" ][" sunrise" ])
118+ local sunset = tonumber (current [" sys" ][" sunset" ])
119+ local icon = current [" weather" ][1 ][" icon" ]
121120 local loc_now = os.time ()
121+ local city = current [" name" ]
122+ local temp = current [" main" ][" temp" ]
122123
123124 if sunrise <= loc_now and loc_now <= sunset then
124125 icon = string.gsub (icon , " n" , " d" )
@@ -127,8 +128,8 @@ local function factory(args)
127128 end
128129
129130 weather .icon_path = icons_path .. icon .. " .png"
130- widget = weather .widget
131- settings ()
131+ weather .widget : set_markup ( string.format ( " %s %d° " , city , temp ))
132+ settings (weather . widget , weather . now )
132133 else
133134 weather .icon_path = icons_path .. " na.png"
134135 weather .widget :set_markup (weather_na_markup )
@@ -138,6 +139,7 @@ local function factory(args)
138139 end )
139140 end
140141
142+
141143 if showpopup == " on" then weather .attach (weather .widget ) end
142144
143145 weather .timer = helpers .newtimer (" weather-" .. lat .. " :" .. lon , timeout , weather .update , false , true )
0 commit comments