local awful = require('awful') local beautiful = require('beautiful') local naughty = require('naughty') local wibox = require('wibox') local gears = require('gears') local dpi = beautiful.xresources.apply_dpi local config_dir = gears.filesystem.get_configuration_dir() local widget_icon_dir = config_dir .. 'widget/weather/icons/' local clickable_container = require('widget.clickable-container') local secrets = require('configuration.secrets') local key = secrets.weather.key local city_id = secrets.weather.city_id local units = secrets.weather.units local update_interval = 1200 local weather_icon_widget = wibox.widget { { id = 'icon', image = widget_icon_dir .. 'weather-error.svg', resize = true, forced_height = dpi(45), forced_width = dpi(45), widget = wibox.widget.imagebox, }, layout = wibox.layout.fixed.horizontal } local sunrise_icon_widget = wibox.widget { { id = 'sunrise_icon', image = widget_icon_dir .. 'sunrise.svg', resize = true, forced_height = dpi(18), forced_width = dpi(18), widget = wibox.widget.imagebox, }, layout = wibox.layout.fixed.horizontal } local sunset_icon_widget = wibox.widget { { id = 'sunset_icon', image = widget_icon_dir .. 'sunset.svg', resize = true, forced_height = dpi(18), forced_width = dpi(18), widget = wibox.widget.imagebox, }, layout = wibox.layout.fixed.horizontal } local refresh_icon_widget = wibox.widget { { id = 'refresh_icon', image = widget_icon_dir .. 'refresh.svg', resize = true, forced_height = dpi(18), forced_width = dpi(18), widget = wibox.widget.imagebox, }, layout = wibox.layout.fixed.horizontal } local refresh_button = clickable_container(refresh_icon_widget) refresh_button:buttons( gears.table.join( awful.button( {}, 1, nil, function() awesome.emit_signal('widget::weather_fetch') end ) ) ) local refresh_widget = wibox.widget { refresh_button, bg = beautiful.transparent, shape = gears.shape.circle, widget = wibox.container.background } local weather_desc_temp = wibox.widget { { id = 'description', markup = 'dust and clouds, -1000°C', font = 'SF Pro Text Bold 12', align = 'left', valign = 'center', widget = wibox.widget.textbox }, id = 'scroll_container', max_size = 345, speed = 75, expand = true, direction = 'h', step_function = wibox.container.scroll .step_functions.waiting_nonlinear_back_and_forth, fps = 30, layout = wibox.container.scroll.horizontal, } local weather_location = wibox.widget { { id = 'location', markup = 'Earth, Milky Way', font = 'SF Pro Text Regular 12', align = 'left', valign = 'center', widget = wibox.widget.textbox }, id = 'scroll_container', max_size = 345, speed = 75, expand = true, direction = 'h', step_function = wibox.container.scroll .step_functions.waiting_nonlinear_back_and_forth, fps = 30, layout = wibox.container.scroll.horizontal, } local weather_sunrise = wibox.widget { markup = "00:00", font = 'SF Pro Text Regular 10', align = 'center', valign = 'center', widget = wibox.widget.textbox } local weather_sunset = wibox.widget { markup = "00:00", font = 'SF Pro Text Regular 10', align = 'center', valign = 'center', widget = wibox.widget.textbox } local weather_data_time = wibox.widget { markup = "00:00", font = 'SF Pro Text Regular 10', align = 'center', valign = 'center', widget = wibox.widget.textbox } local weather_report = wibox.widget { { { layout = wibox.layout.fixed.horizontal, spacing = dpi(10), { layout = wibox.layout.align.vertical, expand = 'none', nil, weather_icon_widget, nil }, { layout = wibox.layout.align.vertical, expand = 'none', nil, { layout = wibox.layout.fixed.vertical, spacing = dpi(3), weather_location, weather_desc_temp, { layout = wibox.layout.fixed.horizontal, spacing = dpi(7), { layout = wibox.layout.fixed.horizontal, spacing = dpi(3), sunrise_icon_widget, weather_sunrise }, { layout = wibox.layout.fixed.horizontal, spacing = dpi(3), sunset_icon_widget, weather_sunset }, { layout = wibox.layout.fixed.horizontal, spacing = dpi(3), refresh_widget, weather_data_time } } }, nil } }, margins = dpi(10), widget = wibox.container.margin }, forced_height = dpi(92), bg = beautiful.groups_bg, shape = function(cr, width, height) gears.shape.partially_rounded_rect(cr, width, height, true, true, true, true, beautiful.groups_radius) end, widget = wibox.container.background } if units == "metric" then weather_temperature_symbol = "°C" elseif units == "imperial" then weather_temperature_symbol = "°F" end -- Weather script using your API KEY local weather_details_script = [[ KEY="]]..key..[[" CITY="]]..city_id..[[" UNITS="]]..units..[[" weather=$(curl -sf "http://api.openweathermap.org/data/2.5/weather?APPID="${KEY}"&id="${CITY}"&units="${UNITS}"") if [ ! -z "$weather" ]; then weather_icon="icon=$(printf "$weather" | jq -r ".weather[].icon" | head -1)" weather_location="location=$(printf "$weather" | jq -r ".name")" weather_country="country=$(printf "$weather" | jq -r ".sys.country")" weather_sunrise="sunrise=$(printf "$weather" | jq -r ".sys.sunrise" | xargs -0 -L1 -I '$' echo '@$' | xargs date +"%H:%M" -d)" weather_sunset="sunset=$(printf "$weather" | jq -r ".sys.sunset" | xargs -0 -L1 -I '$' echo '@$' | xargs date +"%H:%M" -d)" weather_data_time="update=$(printf "$weather" | jq -r ".dt" | xargs -0 -L1 -I '$' echo '@$' | xargs date +"%H:%M" -d)" weather_temp="temperature=$(printf "$weather" | jq ".main.temp" | cut -d "." -f 1)" weather_description="details=$(printf "$weather" | jq -r ".weather[].description" | head -1)" DATA="${weather_icon}\n${weather_location}\n${weather_country}\n${weather_sunrise}\n${weather_sunset}\n${weather_data_time}\n${weather_temp}\n${weather_description}\n" printf "${DATA}" else printf "icon=..." fi ]] awesome.connect_signal( 'widget::weather_fetch', function() awful.spawn.easy_async_with_shell( weather_details_script, function(stdout) local weather_data_tbl = {} for data in stdout:gmatch("[^\n]+") do local key = data:match("(.*)=") local value = data:match("=(.*)") weather_data_tbl[key] = value end local icon_code = weather_data_tbl['icon'] if icon_code == '...' then awesome.emit_signal("widget::weather_update", icon_code, 'dust and clouds, -1000°C', 'Earth, Milky Way', '00:00', '00:00', '00:00' ) else local location = weather_data_tbl['location'] local country = weather_data_tbl['country'] local sunrise = weather_data_tbl['sunrise'] local sunset = weather_data_tbl['sunset'] local update_time = weather_data_tbl['update'] local temperature = weather_data_tbl['temperature'] local details = weather_data_tbl['details'] local description = details:sub(1, 1):upper() .. details:sub(2) local weather_description = description .. ', ' .. temperature .. weather_temperature_symbol local weather_location = location .. ', ' .. country awesome.emit_signal("widget::weather_update", icon_code, weather_description, weather_location, sunrise, sunset, update_time ) end collectgarbage('collect') end ) end) local update_widget_timer = gears.timer { timeout = update_interval, autostart = true, call_now = true, single_shot = false, callback = function() awesome.emit_signal('widget::weather_fetch') end } awesome.connect_signal( 'system::wifi_connected', function() gears.timer.start_new( 5, function() awesome.emit_signal('widget::weather_fetch') end ) end ) awesome.connect_signal( "widget::weather_update", function(code, desc, location, sunrise, sunset, data_receive) local widget_icon_name = 'weather-error' local icon_tbl = { ['01d'] = 'sun_icon.svg', ['01n'] = 'moon_icon.svg', ['02d'] = 'dfew_clouds.svg', ['02n'] = 'nfew_clouds.svg', ['03d'] = 'dscattered_clouds.svg', ['03n'] = 'nscattered_clouds.svg', ['04d'] = 'dbroken_clouds.svg', ['04n'] = 'nbroken_clouds.svg', ['09d'] = 'dshower_rain.svg', ['09n'] = 'nshower_rain.svg', ['10d'] = 'd_rain.svg', ['10n'] = 'n_rain.svg', ['11d'] = 'dthunderstorm.svg', ['11n'] = 'nthunderstorm.svg', ['13d'] = 'snow.svg', ['13n'] = 'snow.svg', ['50d'] = 'dmist.svg', ['50n'] = 'nmist.svg', ['...'] = 'weather-error.svg' } widget_icon_name = icon_tbl[code] weather_icon_widget.icon:set_image(widget_icon_dir .. widget_icon_name) weather_icon_widget.icon:emit_signal('widget::redraw_needed') weather_desc_temp.description:set_markup(desc) weather_location.location:set_markup(location) weather_sunrise:set_markup(sunrise) weather_sunset:set_markup(sunset) weather_data_time:set_markup(data_receive) end ) return weather_report