diff options
-rw-r--r-- | secrets.lua | 13 | ||||
-rw-r--r-- | weather-widget/README.md | 2 | ||||
-rw-r--r-- | weather-widget/weather.lua | 127 |
3 files changed, 92 insertions, 50 deletions
diff --git a/secrets.lua b/secrets.lua index e110fe5..381f04d 100644 --- a/secrets.lua +++ b/secrets.lua @@ -5,6 +5,15 @@ -- @copyright 2019 Pavel Makhov -------------------------------------------- +local function getenv_bool(var_name, default_val) + val = os.getenv(var_name) + if val ~= nil then + return val:lower() == 'true' + else + return default_val + end +end + local secrets = { -- Yandex.Translate API key - https://tech.yandex.com/translate/ translate_widget_api_key = os.getenv('AWW_TRANSLATE_API_KEY') or 'API_KEY', @@ -12,7 +21,9 @@ local secrets = { -- OpenWeatherMap API key - https://openweathermap.org/appid weather_widget_api_key = os.getenv('AWW_WEATHER_API_KEY') or 'c3d7320b359da4e48c2d682a04076576', weather_widget_city = os.getenv('AWW_WEATHER_CITY') or 'Montreal,ca', - weather_widget_units = os.getenv('AWW_WEATHER_UNITS') or 'metric' -- for celsius, or 'imperial' for fahrenheit + weather_widget_units = os.getenv('AWW_WEATHER_UNITS') or 'metric', -- for celsius, or 'imperial' for fahrenheit + weather_both_temp_units_widget = getenv_bool('AWW_WEATHER_BOTH_UNITS_WIDGET', false), -- on widget, if true shows "22 C (72 F)", instead of only "22 C" + weather_both_temp_units_popup = getenv_bool('AWW_WEATHER_BOTH_UNITS_POPUP', true) -- in the popup, if true shows "22.3 C (72.2 F)" instead of only "22.3 C" } return secrets diff --git a/weather-widget/README.md b/weather-widget/README.md index a7e67e5..6464fcc 100644 --- a/weather-widget/README.md +++ b/weather-widget/README.md @@ -14,6 +14,8 @@ It is possible to customize widget by providing a table with all or some of the | `city` | `Montreal,ca` | City name and country code, [more info](https://openweathermap.org/current) | | `api_key` | none| API key, required | | `units` | `metric` | `metric` for celsius, `imperial` for fahrenheit | +| `both_units_widget` | `false` | show temperature in both units (15°C (59°F)) or in one (15°C) | +| `both_units_popup` | `false` | same as above but for popup | ### Example: diff --git a/weather-widget/weather.lua b/weather-widget/weather.lua index 0899b8f..b0aa070 100644 --- a/weather-widget/weather.lua +++ b/weather-widget/weather.lua @@ -14,8 +14,6 @@ local naughty = require("naughty") local wibox = require("wibox") local gears = require("gears") -local secrets = require("awesome-wm-widgets.secrets") - local path_to_icons = "/usr/share/icons/Arc/status/symbolic/" local weather_widget = {} @@ -28,6 +26,8 @@ local function worker(args) local city = args.city or 'Montreal,ca' local api_key = args.api_key or naughty.notify{preset = naughty.config.presets.critical, text = 'OpenweatherMap API key is not set'} local units = args.units or 'metric' + local both_units_widget = args.both_units_widget or false + local both_units_popup = args.both_units_popup or false local weather_api_url = ( 'https://api.openweathermap.org/data/2.5/weather' @@ -109,63 +109,92 @@ local function worker(args) return directions[math.floor((degrees % 360) / 22.5) + 1] end -local weather_timer = gears.timer({ timeout = 60 }) -local resp - -weather_timer:connect_signal("timeout", function () - local resp_json = {} - local res, status = http.request{ - url=weather_api_url, - sink=ltn12.sink.table(resp_json), - -- ref: - -- http://w3.impa.br/~diego/software/luasocket/old/luasocket-2.0/http.html - create=function() - -- ref: https://stackoverflow.com/a/6021774/595220 - local req_sock = socket.tcp() - -- 't' — overall timeout - req_sock:settimeout(0.2, 't') - -- 'b' — block timeout - req_sock:settimeout(0.001, 'b') - return req_sock + -- Convert degrees Celsius to Fahrenheit + local function celsius_to_fahrenheit(c) + return c*9/5+32 + end + + -- Convert degrees Fahrenheit to Celsius + local function fahrenheit_to_celsius(f) + return (f-32)*5/9 + end + + local weather_timer = gears.timer({ timeout = 60 }) + local resp + + local function gen_temperature_str(temp, fmt_str, show_other_units) + local temp_str = string.format(fmt_str, temp) + local s = temp_str .. '°' .. (units == 'metric' and 'C' or 'F') + + if (show_other_units) then + local temp_conv, units_conv + if (units == 'metric') then + temp_conv = celsius_to_fahrenheit(temp) + units_conv = 'F' + else + temp_conv = fahrenheit_to_celsius(temp) + units_conv = 'C' + end + + local temp_conv_str = string.format(fmt_str, temp_conv) + s = s .. ' ' .. '('.. temp_conv_str .. '°' .. units_conv .. ')' end - } - if (resp_json ~= nil) then - resp_json = table.concat(resp_json) + return s end - if (status ~= 200 and resp_json ~= nil and resp_json ~= '') then - local err_resp = json.decode(resp_json) - naughty.notify{ - title = 'Weather Widget Error', - text = err_resp.message, - preset = naughty.config.presets.critical, + weather_timer:connect_signal("timeout", function () + local resp_json = {} + local res, status = http.request{ + url=weather_api_url, + sink=ltn12.sink.table(resp_json), + -- ref: + -- http://w3.impa.br/~diego/software/luasocket/old/luasocket-2.0/http.html + create=function() + -- ref: https://stackoverflow.com/a/6021774/595220 + local req_sock = socket.tcp() + -- 't' — overall timeout + req_sock:settimeout(0.2, 't') + -- 'b' — block timeout + req_sock:settimeout(0.001, 'b') + return req_sock + end } - elseif (resp_json ~= nil and resp_json ~= '') then - resp = json.decode(resp_json) - icon_widget.image = path_to_icons .. icon_map[resp.weather[1].icon] - temp_widget:set_text(string.gsub(resp.main.temp, "%.%d+", "") - .. '°' - .. (secrets.weather_widget_units == 'metric' and 'C' or 'F')) - end -end) -weather_timer:start() -weather_timer:emit_signal("timeout") + if (resp_json ~= nil) then + resp_json = table.concat(resp_json) + end + + if (status ~= 200 and resp_json ~= nil and resp_json ~= '') then + local err_resp = json.decode(resp_json) + naughty.notify{ + title = 'Weather Widget Error', + text = err_resp.message, + preset = naughty.config.presets.critical, + } + elseif (resp_json ~= nil and resp_json ~= '') then + resp = json.decode(resp_json) + icon_widget.image = path_to_icons .. icon_map[resp.weather[1].icon] + temp_widget:set_text(gen_temperature_str(resp.main.temp, '%.0f', both_units_widget)) + end + end) + weather_timer:start() + weather_timer:emit_signal("timeout") --- Notification with weather information. Popups when mouse hovers over the icon local notification weather_widget:connect_signal("mouse::enter", function() - notification = naughty.notify { + notification = naughty.notify{ icon = path_to_icons .. icon_map[resp.weather[1].icon], - icon_size = 20, - text = '<big>' .. resp.weather[1].main .. ' (' .. resp.weather[1].description .. ')</big><br>' .. - '<b>Humidity:</b> ' .. resp.main.humidity .. '%<br>' .. - '<b>Temperature:</b> ' .. resp.main.temp .. '°' - .. (secrets.weather_widget_units == 'metric' and 'C' or 'F') .. '<br>' .. - '<b>Pressure:</b> ' .. resp.main.pressure .. 'hPa<br>' .. - '<b>Clouds:</b> ' .. resp.clouds.all .. '%<br>' .. - '<b>Wind:</b> ' .. resp.wind.speed .. 'm/s (' .. to_direction(resp.wind.deg) .. ')', + icon_size=20, + text = + '<big>' .. resp.weather[1].main .. ' (' .. resp.weather[1].description .. ')</big><br>' .. + '<b>Humidity:</b> ' .. resp.main.humidity .. '%<br>' .. + '<b>Temperature:</b> ' .. gen_temperature_str(resp.main.temp, '%.1f', + both_units_popup) .. '<br>' .. + '<b>Pressure:</b> ' .. resp.main.pressure .. 'hPa<br>' .. + '<b>Clouds:</b> ' .. resp.clouds.all .. '%<br>' .. + '<b>Wind:</b> ' .. resp.wind.speed .. 'm/s (' .. to_direction(resp.wind.deg) .. ')', timeout = 5, hover_timeout = 10, - width = 200 + width = (both_units_popup == true and 210 or 200) } end) |