2019-09-14 05:33:40 +02:00
|
|
|
-- weather widget type fetching from from US NOAA
|
|
|
|
-- Copyright (C) 2010 Adrian C. <anrxc@sysphere.org>
|
|
|
|
-- Copyright (C) 2017 mutlusun <mutlusun@github.com>
|
|
|
|
-- Copyright (C) 2019 Arthur Axel 'fREW' Schmidt <git@frew.co>
|
|
|
|
-- Copyright (C) 2019 Nguyễn Gia Phong <vn.mcsinyx@gmail.com>
|
|
|
|
--
|
|
|
|
-- This file is part of Vicious.
|
|
|
|
--
|
|
|
|
-- Vicious is free software: you can redistribute it and/or modify
|
|
|
|
-- it under the terms of the GNU General Public License as
|
|
|
|
-- published by the Free Software Foundation, either version 2 of the
|
|
|
|
-- License, or (at your option) any later version.
|
|
|
|
--
|
|
|
|
-- Vicious is distributed in the hope that it will be useful,
|
|
|
|
-- but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
-- MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
-- GNU General Public License for more details.
|
|
|
|
--
|
|
|
|
-- You should have received a copy of the GNU General Public License
|
|
|
|
-- along with Vicious. If not, see <https://www.gnu.org/licenses/>.
|
2009-07-29 18:46:43 +02:00
|
|
|
|
|
|
|
-- {{{ Grab environment
|
2010-03-06 03:20:43 +01:00
|
|
|
local tonumber = tonumber
|
|
|
|
local math = { ceil = math.ceil }
|
Surface {when} in local time for weather widget
Here's how I use this:
local weather_widget = function(
code,
url,
name
)
local actual_widget = wibox.widget.textbox()
local actual_tooltip = awful.tooltip({ objects = { actual_widget } });
actual_widget:buttons(awful.util.table.join(
awful.button({}, 1, function () awful.spawn("firefox '" .. url .. os.time() .. "'") end)
))
vicious.register(actual_widget, vicious.widgets.weather,
function (widget, args)
actual_tooltip:set_text(
"City: " .. args["{city}"] ..
"\nWind: " .. args["{windmph}"] .. "mph " ..
"\nSky: " .. args["{sky}"] ..
"\nHumidity: " .. args["{humid}"] ..
"\nMeasured at: " .. os.date("%F %T", args["{when}"]))
return name .. " " .. args["{tempf}"] .. "°F"
end, 60 * 10, code)
return actual_widget
end
2019-05-20 05:36:45 +02:00
|
|
|
local os = { date = os.date, difftime = os.difftime, time = os.time }
|
2019-09-14 05:33:40 +02:00
|
|
|
local string = { format = string.format }
|
2019-02-12 14:43:45 +01:00
|
|
|
|
2019-05-13 07:30:35 +02:00
|
|
|
local spawn = require"vicious.spawn"
|
2019-05-13 09:51:02 +02:00
|
|
|
local helpers = require"vicious.helpers"
|
2009-07-29 18:46:43 +02:00
|
|
|
-- }}}
|
|
|
|
|
|
|
|
-- Weather: provides weather information for a requested station
|
2012-06-15 18:07:05 +02:00
|
|
|
-- vicious.widgets.weather
|
2017-01-25 17:57:16 +01:00
|
|
|
local weather_all = {}
|
2009-07-29 18:46:43 +02:00
|
|
|
|
Surface {when} in local time for weather widget
Here's how I use this:
local weather_widget = function(
code,
url,
name
)
local actual_widget = wibox.widget.textbox()
local actual_tooltip = awful.tooltip({ objects = { actual_widget } });
actual_widget:buttons(awful.util.table.join(
awful.button({}, 1, function () awful.spawn("firefox '" .. url .. os.time() .. "'") end)
))
vicious.register(actual_widget, vicious.widgets.weather,
function (widget, args)
actual_tooltip:set_text(
"City: " .. args["{city}"] ..
"\nWind: " .. args["{windmph}"] .. "mph " ..
"\nSky: " .. args["{sky}"] ..
"\nHumidity: " .. args["{humid}"] ..
"\nMeasured at: " .. os.date("%F %T", args["{when}"]))
return name .. " " .. args["{tempf}"] .. "°F"
end, 60 * 10, code)
return actual_widget
end
2019-05-20 05:36:45 +02:00
|
|
|
-- copied from http://lua-users.org/wiki/TimeZone
|
|
|
|
local function get_timezone_offset()
|
|
|
|
local ts = os.time()
|
|
|
|
local utcdate = os.date("!*t", ts)
|
|
|
|
local localdate = os.date("*t", ts)
|
|
|
|
localdate.isdst = false -- this is the trick
|
|
|
|
return os.difftime(os.time(localdate), os.time(utcdate))
|
|
|
|
end
|
|
|
|
|
2009-07-29 18:46:43 +02:00
|
|
|
-- {{{ Weather widget type
|
2019-05-13 09:51:02 +02:00
|
|
|
local function parse(stdout, stderr, exitreason, exitcode)
|
2019-02-12 14:43:45 +01:00
|
|
|
-- Initialize function tables
|
|
|
|
local _weather = {
|
|
|
|
["{city}"] = "N/A",
|
Surface {when} in local time for weather widget
Here's how I use this:
local weather_widget = function(
code,
url,
name
)
local actual_widget = wibox.widget.textbox()
local actual_tooltip = awful.tooltip({ objects = { actual_widget } });
actual_widget:buttons(awful.util.table.join(
awful.button({}, 1, function () awful.spawn("firefox '" .. url .. os.time() .. "'") end)
))
vicious.register(actual_widget, vicious.widgets.weather,
function (widget, args)
actual_tooltip:set_text(
"City: " .. args["{city}"] ..
"\nWind: " .. args["{windmph}"] .. "mph " ..
"\nSky: " .. args["{sky}"] ..
"\nHumidity: " .. args["{humid}"] ..
"\nMeasured at: " .. os.date("%F %T", args["{when}"]))
return name .. " " .. args["{tempf}"] .. "°F"
end, 60 * 10, code)
return actual_widget
end
2019-05-20 05:36:45 +02:00
|
|
|
["{when}"] = "N/A",
|
2019-02-12 14:43:45 +01:00
|
|
|
["{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"
|
|
|
|
}
|
2010-03-06 03:20:43 +01:00
|
|
|
|
2009-07-29 18:46:43 +02:00
|
|
|
-- Check if there was a timeout or a problem with the station
|
2019-05-13 09:51:02 +02:00
|
|
|
if stdout == '' then return _weather end
|
2009-08-05 21:58:04 +02:00
|
|
|
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{city}"] = -- City and/or area
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"^(.+)%,.*%([%u]+%)"
|
|
|
|
or _weather["{city}"]
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{wind}"] = -- Wind direction and degrees if available
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Wind:[%s][%a]+[%s][%a]+[%s](.+)[%s]at.+$"
|
|
|
|
or _weather["{wind}"]
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{windmph}"] = -- Wind speed in MPH if available
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Wind:[%s].+[%s]at[%s]([%d]+)[%s]MPH"
|
|
|
|
or _weather["{windmph}"]
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{sky}"] = -- Sky conditions if available
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Sky[%s]conditions:[%s](.-)[%c]"
|
|
|
|
or _weather["{sky}"]
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{weather}"] = -- Weather conditions if available
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Weather:[%s](.-)[%c]"
|
|
|
|
or _weather["{weather}"]
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{tempf}"] = -- Temperature in fahrenheit
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Temperature:[%s]([%-]?[%d%.]+).*[%c]"
|
|
|
|
or _weather["{tempf}"]
|
2013-12-15 02:48:00 +01:00
|
|
|
_weather["{dewf}"] = -- Dew Point in fahrenheit
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Dew[%s]Point:[%s]([%-]?[%d%.]+).*[%c]"
|
|
|
|
or _weather["{dewf}"]
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{humid}"] = -- Relative humidity in percent
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Relative[%s]Humidity:[%s]([%d]+)%%"
|
|
|
|
or _weather["{humid}"]
|
2012-06-15 18:07:05 +02:00
|
|
|
_weather["{press}"] = -- Pressure in hPa
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"Pressure[%s].+%((.+)[%s]hPa%)"
|
|
|
|
or _weather["{press}"]
|
2009-10-04 00:54:27 +02:00
|
|
|
|
Surface {when} in local time for weather widget
Here's how I use this:
local weather_widget = function(
code,
url,
name
)
local actual_widget = wibox.widget.textbox()
local actual_tooltip = awful.tooltip({ objects = { actual_widget } });
actual_widget:buttons(awful.util.table.join(
awful.button({}, 1, function () awful.spawn("firefox '" .. url .. os.time() .. "'") end)
))
vicious.register(actual_widget, vicious.widgets.weather,
function (widget, args)
actual_tooltip:set_text(
"City: " .. args["{city}"] ..
"\nWind: " .. args["{windmph}"] .. "mph " ..
"\nSky: " .. args["{sky}"] ..
"\nHumidity: " .. args["{humid}"] ..
"\nMeasured at: " .. os.date("%F %T", args["{when}"]))
return name .. " " .. args["{tempf}"] .. "°F"
end, 60 * 10, code)
return actual_widget
end
2019-05-20 05:36:45 +02:00
|
|
|
local year, month, day, hour, min =
|
2019-09-14 05:33:40 +02:00
|
|
|
stdout:match"(%d%d%d%d).(%d%d).(%d%d) (%d%d)(%d%d) UTC"
|
Surface {when} in local time for weather widget
Here's how I use this:
local weather_widget = function(
code,
url,
name
)
local actual_widget = wibox.widget.textbox()
local actual_tooltip = awful.tooltip({ objects = { actual_widget } });
actual_widget:buttons(awful.util.table.join(
awful.button({}, 1, function () awful.spawn("firefox '" .. url .. os.time() .. "'") end)
))
vicious.register(actual_widget, vicious.widgets.weather,
function (widget, args)
actual_tooltip:set_text(
"City: " .. args["{city}"] ..
"\nWind: " .. args["{windmph}"] .. "mph " ..
"\nSky: " .. args["{sky}"] ..
"\nHumidity: " .. args["{humid}"] ..
"\nMeasured at: " .. os.date("%F %T", args["{when}"]))
return name .. " " .. args["{tempf}"] .. "°F"
end, 60 * 10, code)
return actual_widget
end
2019-05-20 05:36:45 +02:00
|
|
|
if year ~= nil then
|
2019-09-14 05:33:40 +02:00
|
|
|
local utctable = { year = year, month = month, day = day,
|
|
|
|
hour = hour, min = min }
|
|
|
|
_weather["{when}"] = os.time(utctable) + get_timezone_offset()
|
Surface {when} in local time for weather widget
Here's how I use this:
local weather_widget = function(
code,
url,
name
)
local actual_widget = wibox.widget.textbox()
local actual_tooltip = awful.tooltip({ objects = { actual_widget } });
actual_widget:buttons(awful.util.table.join(
awful.button({}, 1, function () awful.spawn("firefox '" .. url .. os.time() .. "'") end)
))
vicious.register(actual_widget, vicious.widgets.weather,
function (widget, args)
actual_tooltip:set_text(
"City: " .. args["{city}"] ..
"\nWind: " .. args["{windmph}"] .. "mph " ..
"\nSky: " .. args["{sky}"] ..
"\nHumidity: " .. args["{humid}"] ..
"\nMeasured at: " .. os.date("%F %T", args["{when}"]))
return name .. " " .. args["{tempf}"] .. "°F"
end, 60 * 10, code)
return actual_widget
end
2019-05-20 05:36:45 +02:00
|
|
|
end
|
|
|
|
|
2010-03-06 03:20:43 +01:00
|
|
|
-- Wind speed in km/h if MPH was available
|
2012-06-15 18:07:05 +02:00
|
|
|
if _weather["{windmph}"] ~= "N/A" then
|
2019-09-14 05:33:40 +02:00
|
|
|
_weather["{windmph}"] = tonumber(_weather["{windmph}"])
|
|
|
|
_weather["{windkmh}"] = math.ceil(_weather["{windmph}"] * 1.6)
|
2010-03-06 03:43:38 +01:00
|
|
|
end -- Temperature in °C if °F was available
|
2012-06-15 18:07:05 +02:00
|
|
|
if _weather["{tempf}"] ~= "N/A" then
|
2019-09-14 05:33:40 +02:00
|
|
|
_weather["{tempf}"] = tonumber(_weather["{tempf}"])
|
|
|
|
_weather["{tempc}"] = math.ceil((_weather["{tempf}"] - 32) * 5/9)
|
2013-12-15 02:48:00 +01:00
|
|
|
end -- Dew Point in °C if °F was available
|
|
|
|
if _weather["{dewf}"] ~= "N/A" then
|
2019-09-14 05:33:40 +02:00
|
|
|
_weather["{dewf}"] = tonumber(_weather["{dewf}"])
|
|
|
|
_weather["{dewc}"] = math.ceil((_weather["{dewf}"] - 32) * 5/9)
|
2010-03-06 03:43:38 +01:00
|
|
|
end -- Capitalize some stats so they don't look so out of place
|
2012-06-15 18:07:05 +02:00
|
|
|
if _weather["{sky}"] ~= "N/A" then
|
2019-09-14 05:33:40 +02:00
|
|
|
_weather["{sky}"] = helpers.capitalize(_weather["{sky}"])
|
2010-03-06 03:43:38 +01:00
|
|
|
end
|
2012-06-15 18:07:05 +02:00
|
|
|
if _weather["{weather}"] ~= "N/A" then
|
2019-09-14 05:33:40 +02:00
|
|
|
_weather["{weather}"] = helpers.capitalize(_weather["{weather}"])
|
2009-07-29 18:46:43 +02:00
|
|
|
end
|
|
|
|
|
2012-06-15 18:07:05 +02:00
|
|
|
return _weather
|
2009-07-29 18:46:43 +02:00
|
|
|
end
|
2019-02-12 14:43:45 +01:00
|
|
|
|
|
|
|
function weather_all.async(format, warg, callback)
|
2019-05-13 07:30:35 +02:00
|
|
|
if not warg then return callback{} end
|
2019-02-12 14:43:45 +01:00
|
|
|
|
|
|
|
-- Get weather forceast by the station ICAO code, from:
|
|
|
|
-- * US National Oceanic and Atmospheric Administration
|
2019-09-14 05:33:40 +02:00
|
|
|
local url = string.format(
|
|
|
|
"https://tgftp.nws.noaa.gov/data/observations/metar/decoded/%s.TXT",
|
|
|
|
warg)
|
2019-05-13 09:51:02 +02:00
|
|
|
spawn.easy_async("curl -fs " .. url,
|
|
|
|
function (...) callback(parse(...)) end)
|
2019-02-12 14:43:45 +01:00
|
|
|
end
|
2009-07-29 18:46:43 +02:00
|
|
|
-- }}}
|
2009-08-01 23:11:41 +02:00
|
|
|
|
2019-05-15 11:05:16 +02:00
|
|
|
return helpers.setasyncall(weather_all)
|