simple-awesome/simple/widgets/system_resources.lua

245 lines
6.1 KiB
Lua

local awful = require("awful")
local beautiful = require("beautiful")
local gears = require("gears")
local naughty = require("naughty")
local wibox = require("wibox")
local config = require("config").widgets.system_resources
local inspect = require("simple/debug/inspect")
local bar = {
{
{
max_value = 1,
value = 0,
widget = wibox.widget.progressbar,
color = beautiful.system_resources_widget_bar_color,
background_color = beautiful.system_resources_widget_bar_bg,
shape = beautiful.system_resources_widget_bar_shape,
border_color = beautiful.system_resources_widget_border_color,
border_width = beautiful.system_resources_widget_border_width,
},
forced_width = beautiful.system_resources_widget_bar_width,
direction = "east",
layout = wibox.container.rotate,
},
margins = beautiful.system_resources_widget_bar_margin,
widget = wibox.container.margin,
}
local bars = wibox.widget {
bar,
bar,
bar,
layout = wibox.layout.flex.horizontal
}
function fileExists(name)
local f = io.open(name, "r")
if f ~= nil then
io.close(f)
return true
end
return false
end
function readCommand(command)
local handle = io.popen(command, "r")
local r = handle:read("*a")
handle:close()
return r
end
function readFile(file)
local handle = io.open(file, "r")
local r = handle:read("*a")
handle:close()
return r
end
local cpuBar = bars:get_children()[1]:get_children()[1]:get_children()[1]
function getCpuData()
local raw = readCommand("cat /proc/stat | head -n 1")
local data = {raw:match((raw:gsub("[^ ]* ", "([^ ]*) ")))}
return {
user = data[3],
nice = data[4],
system = data[5],
idle = data[6],
iowait = data[7],
irq = data[8],
softirq = data[9],
steal = data[10],
}
end
local lastCpuTime = -1
local lastCpuIdle = -1
gears.timer {
timeout = config.bars.refresh_interval,
call_now = true,
autostart = true,
callback = function()
local data = getCpuData()
local currentCpuTime = data.user + data.nice + data.system + data.idle + data.iowait + data.irq + data.softirq + data.steal
local currentCpuIdle = data.idle + data.iowait
if(lastCpuTime >= 0) then
cpuBar.value = 1 - (currentCpuIdle - lastCpuIdle) / (currentCpuTime - lastCpuTime)
end
lastCpuTime = currentCpuTime
lastCpuIdle = currentCpuIdle
end
}
local memoryBar = bars:get_children()[2]:get_children()[1]:get_children()[1]
function getTotalMemory()
return readCommand("cat /proc/meminfo | grep MemTotal | awk '{print $2}'")
end
function getAvailableMemory()
return readCommand("cat /proc/meminfo | grep MemAvailable | awk '{print $2}'")
end
function getFreeMemory()
return readCommand("cat /proc/meminfo | grep MemFree | awk '{print $2}'")
end
gears.timer {
timeout = config.bars.refresh_interval,
call_now = true,
autostart = true,
callback = function()
memoryBar.value = 1 - getAvailableMemory() / getTotalMemory()
end
}
local swapBar = bars:get_children()[3]:get_children()[1]:get_children()[1]
function getTotalSwap()
return readCommand("cat /proc/meminfo | grep SwapTotal | awk '{print $2}'")
end
function getFreeSwap()
return readCommand("cat /proc/meminfo | grep SwapFree | awk '{print $2}'")
end
gears.timer {
timeout = config.bars.refresh_interval,
call_now = true,
autostart = true,
callback = function()
swapBar.value = 1 - getFreeSwap() / getTotalSwap()
end
}
---
--- Batteries
---
rawBatteries = {}
function refreshRawBatteries()
rawBatteries = readCommand("ls -A1 /sys/class/power_supply")
end
function getBatteryLevel(battery)
local charge = 0
local capacity = 0
if fileExists(battery .. "/energy_now") then
charge = charge + readFile(battery .. "/energy_now")
capacity = capacity + readFile(battery .. "/energy_full")
elseif fileExists(battery .. "/charge_now") then
charge = charge + readFile(battery .. "/charge_now")
capacity = capacity + readFile(battery .. "/charge_full")
elseif fileExists(battery .. "/capacity_level") then
return readFile(battery .. "/capacity_level")
else
return "Unsupported"
end
return string.format("%." .. config.battery.precision .. "f", (charge / capacity) * 100) .. "%"
end
function isCharging(battery)
return readFile(battery .. "/status") == "Charging\n"
end
local batteryContainer = wibox.widget {
layout = wibox.layout.fixed.horizontal
}
local timers = {}
function refreshBatteries()
-- refresh raw batteries and check for change
local oldBatteries = rawBatteries
refreshRawBatteries()
if rawBatteries == oldBatteries then
return
end
-- clear timers
for i,v in ipairs(timers) do
v:stop()
end
timers = {};
-- clear layout
batteryContainer:set_children({})
for battery in rawBatteries:gmatch("([^\n]+)") do
local path = "/sys/class/power_supply/" .. battery
if readFile(path .. "/type"):match("Battery") then
-- widget
local widget = wibox.widget {
{
markup = "-- %",
align = "center",
valign = "center",
widget = wibox.widget.textbox,
},
margins = beautiful.system_resources_widget_battery_margin,
widget = wibox.container.margin,
}
-- tooltip
local name = readFile(path .. "/model_name")
local tooltip = awful.tooltip {
text = name
}
tooltip:add_to_object(widget)
-- update battery level
local batteryText = widget:get_children()[1]
local timer = gears.timer {
timeout = config.battery.refresh_interval,
call_now = true,
autostart = true,
callback = function()
batteryText.markup = (isCharging(path) and "+" or "") .. getBatteryLevel(path)
end
}
table.insert(timers, timer)
batteryContainer:add(widget)
end
end
end
gears.timer {
timeout = config.battery.list_refresh_interval,
call_now = true,
autostart = true,
callback = function()
refreshBatteries()
end
}
return {
bars = bars,
battery = batteryContainer,
}