2017-12-01 00:21:33 -06:00
|
|
|
---------------------------------------------------
|
|
|
|
-- Licensed under the GNU General Public License v2
|
|
|
|
-- * (c) 2010, Adrian C. <anrxc@sysphere.org>
|
|
|
|
---------------------------------------------------
|
|
|
|
|
|
|
|
-- {{{ Grab environment
|
|
|
|
local tonumber = tonumber
|
|
|
|
local io = { popen = io.popen }
|
|
|
|
local setmetatable = setmetatable
|
|
|
|
local math = { ceil = math.ceil }
|
|
|
|
local string = { match = string.match }
|
|
|
|
local helpers = require("vicious.helpers")
|
|
|
|
-- }}}
|
|
|
|
|
|
|
|
|
|
|
|
-- Weather: provides weather information for a requested station
|
|
|
|
-- vicious.widgets.weather
|
|
|
|
local weather = {}
|
|
|
|
|
|
|
|
|
|
|
|
-- Initialize function tables
|
|
|
|
local _weather = {
|
2018-05-18 22:36:34 -05:00
|
|
|
["{city}"] = "N/A",
|
|
|
|
["{wind}"] = "N/A",
|
|
|
|
["{windmph}"] = "N/A",
|
|
|
|
["{windkmh}"] = "N/A",
|
|
|
|
["{sky}"] = "N/A",
|
|
|
|
["{weather}"] = "N/A",
|
|
|
|
["{tempf}"] = "N/A",
|
|
|
|
["{tempc}"] = "N/A",
|
|
|
|
["{dewf}"] = "N/A",
|
|
|
|
["{dewc}"] = "N/A",
|
|
|
|
["{humid}"] = "N/A",
|
|
|
|
["{press}"] = "N/A"
|
2017-12-01 00:21:33 -06:00
|
|
|
}
|
|
|
|
|
|
|
|
-- {{{ Weather widget type
|
|
|
|
local function worker(format, warg)
|
2018-05-18 22:36:34 -05:00
|
|
|
if not warg then return end
|
2017-12-01 00:21:33 -06:00
|
|
|
|
2018-05-18 22:36:34 -05:00
|
|
|
-- Get weather forceast by the station ICAO code, from:
|
|
|
|
-- * US National Oceanic and Atmospheric Administration
|
|
|
|
local url = "http://weather.noaa.gov/pub/data/observations/metar/decoded/"..warg
|
|
|
|
local f = io.popen("curl --connect-timeout 1 -fsm 3 "..helpers.shellquote(url)..".TXT")
|
|
|
|
local ws = f:read("*all")
|
|
|
|
f:close()
|
2017-12-01 00:21:33 -06:00
|
|
|
|
2018-05-18 22:36:34 -05:00
|
|
|
-- Check if there was a timeout or a problem with the station
|
|
|
|
if ws == nil then return _weather end
|
2017-12-01 00:21:33 -06:00
|
|
|
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{city}"] = -- City and/or area
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "^(.+)%,.*%([%u]+%)") or _weather["{city}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{wind}"] = -- Wind direction and degrees if available
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Wind:[%s][%a]+[%s][%a]+[%s](.+)[%s]at.+$") or _weather["{wind}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{windmph}"] = -- Wind speed in MPH if available
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Wind:[%s].+[%s]at[%s]([%d]+)[%s]MPH") or _weather["{windmph}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{sky}"] = -- Sky conditions if available
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Sky[%s]conditions:[%s](.-)[%c]") or _weather["{sky}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{weather}"] = -- Weather conditions if available
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Weather:[%s](.-)[%c]") or _weather["{weather}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{tempf}"] = -- Temperature in fahrenheit
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Temperature:[%s]([%-]?[%d%.]+).*[%c]") or _weather["{tempf}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{dewf}"] = -- Dew Point in fahrenheit
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Dew[%s]Point:[%s]([%-]?[%d%.]+).*[%c]") or _weather["{dewf}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{humid}"] = -- Relative humidity in percent
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Relative[%s]Humidity:[%s]([%d]+)%%") or _weather["{humid}"]
|
2018-05-18 22:36:34 -05:00
|
|
|
_weather["{press}"] = -- Pressure in hPa
|
2017-12-17 12:06:39 -06:00
|
|
|
string.match(ws, "Pressure[%s].+%((.+)[%s]hPa%)") or _weather["{press}"]
|
2017-12-01 00:21:33 -06:00
|
|
|
|
2018-05-18 22:36:34 -05:00
|
|
|
-- Wind speed in km/h if MPH was available
|
|
|
|
if _weather["{windmph}"] ~= "N/A" then
|
|
|
|
_weather["{windmph}"] = tonumber(_weather["{windmph}"])
|
|
|
|
_weather["{windkmh}"] = math.ceil(_weather["{windmph}"] * 1.6)
|
|
|
|
end -- Temperature in °C if °F was available
|
|
|
|
if _weather["{tempf}"] ~= "N/A" then
|
|
|
|
_weather["{tempf}"] = tonumber(_weather["{tempf}"])
|
|
|
|
_weather["{tempc}"] = math.ceil((_weather["{tempf}"] - 32) * 5/9)
|
|
|
|
end -- Dew Point in °C if °F was available
|
|
|
|
if _weather["{dewf}"] ~= "N/A" then
|
|
|
|
_weather["{dewf}"] = tonumber(_weather["{dewf}"])
|
|
|
|
_weather["{dewc}"] = math.ceil((_weather["{dewf}"] - 32) * 5/9)
|
|
|
|
end -- Capitalize some stats so they don't look so out of place
|
|
|
|
if _weather["{sky}"] ~= "N/A" then
|
|
|
|
_weather["{sky}"] = helpers.capitalize(_weather["{sky}"])
|
|
|
|
end
|
|
|
|
if _weather["{weather}"] ~= "N/A" then
|
|
|
|
_weather["{weather}"] = helpers.capitalize(_weather["{weather}"])
|
|
|
|
end
|
2017-12-01 00:21:33 -06:00
|
|
|
|
2018-05-18 22:36:34 -05:00
|
|
|
return _weather
|
2017-12-01 00:21:33 -06:00
|
|
|
end
|
|
|
|
-- }}}
|
|
|
|
|
|
|
|
return setmetatable(weather, { __call = function(_, ...) return worker(...) end })
|