------------------------------------------------- -- Battery Widget for Awesome Window Manager -- Shows the battery status using the ACPI tool -- More details could be found here: -- https://github.com/streetturtle/awesome-wm-widgets/tree/master/battery-widget -- @author Pavel Makhov -- @copyright 2017 Pavel Makhov ------------------------------------------------- local awful = require('awful') local naughty = require('naughty') local watch = require('awful.widget.watch') local wibox = require('wibox') local clickable_container = require('widget.material.clickable-container') local gears = require('gears') local dpi = require('beautiful').xresources.apply_dpi -- acpi sample outputs -- Battery 0: Discharging, 75%, 01:51:38 remaining -- Battery 0: Charging, 53%, 00:57:43 until charged local HOME = os.getenv('HOME') local PATH_TO_ICONS = HOME .. '/.config/awesome/widget/battery/icons/' local widget = wibox.widget { { id = 'icon', widget = wibox.widget.imagebox, resize = true }, layout = wibox.layout.fixed.horizontal, opacity = 0.8 } local widget_button = clickable_container(wibox.container.margin(widget, dpi(0), dpi(8), dpi(8), dpi(8))) widget_button:buttons( gears.table.join( awful.button( {}, 1, nil, function() awful.spawn('xfce4-power-manager-settings') end ) ) ) -- Alternative to naughty.notify - tooltip. You can compare both and choose the preferred one local battery_popup = awful.tooltip( { objects = {widget_button}, mode = 'outside', align = 'left', preferred_positions = {'right', 'left', 'top', 'bottom'} } ) -- To use colors from beautiful theme put -- following lines in rc.lua before require("battery"): --beautiful.tooltip_fg = beautiful.fg_normal --beautiful.tooltip_bg = beautiful.bg_normal local function show_battery_warning() naughty.notify { icon = PATH_TO_ICONS .. 'battery-alert.svg', icon_size = dpi(48), text = 'Huston, we have a problem', title = 'Battery is dying', timeout = 5, hover_timeout = 0.5, position = 'bottom_left', bg = '#d32f2f', fg = '#EEE9EF', width = 248 } end local last_battery_check = os.time() watch( 'acpi -i', 1, function(_, stdout) local batteryIconName = 'battery' local battery_info = {} local capacities = {} for s in stdout:gmatch('[^\r\n]+') do local status, charge_str, time = string.match(s, '.+: (%a+), (%d?%d?%d)%%,?.*') if status ~= nil then table.insert(battery_info, {status = status, charge = tonumber(charge_str)}) else local cap_str = string.match(s, '.+:.+last full capacity (%d+)') table.insert(capacities, tonumber(cap_str)) end end local capacity = 0 for _, cap in ipairs(capacities) do capacity = capacity + cap end local charge = 0 local status for i, batt in ipairs(battery_info) do if batt.charge >= charge then status = batt.status -- use most charged battery status -- this is arbitrary, and maybe another metric should be used end charge = charge + batt.charge * capacities[i] end charge = charge / capacity if (charge >= 0 and charge < 15) then if status ~= 'Charging' and os.difftime(os.time(), last_battery_check) > 300 then -- if 5 minutes have elapsed since the last warning last_battery_check = _G.time() show_battery_warning() end end if status == 'Charging' or status == 'Full' then batteryIconName = batteryIconName .. '-charging' end local roundedCharge = math.floor(charge / 10) * 10 if (roundedCharge == 0) then batteryIconName = batteryIconName .. '-outline' elseif (roundedCharge ~= 100) then batteryIconName = batteryIconName .. '-' .. roundedCharge end widget.icon:set_image(PATH_TO_ICONS .. batteryIconName .. '.svg') -- Update popup text battery_popup.text = string.gsub(stdout, '\n$', '') collectgarbage('collect') end, widget ) return widget_button