Make helpers.sysctl_async cross-platform & let bat_openbsd use it (#93)
This commit is contained in:
parent
ee970d0c68
commit
1277889978
25
helpers.lua
25
helpers.lua
|
@ -31,6 +31,7 @@
|
|||
-- along with Vicious. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-- {{{ Grab environment
|
||||
local ipairs = ipairs
|
||||
local pairs = pairs
|
||||
local rawget = rawget
|
||||
local require = require
|
||||
|
@ -274,9 +275,29 @@ function helpers.sysctl_async(path_table, parse)
|
|||
|
||||
spawn.with_line_callback("sysctl " .. path, {
|
||||
stdout = function (line)
|
||||
if not string.find(line, "sysctl: unknown oid") then
|
||||
local key, value = string.match(line, "(.+): (.+)")
|
||||
local separators = {
|
||||
freebsd = ": ",
|
||||
linux = " = ",
|
||||
openbsd = "="
|
||||
}
|
||||
local pattern = ("(.+)%s(.+)"):format(separators[helpers.getos()])
|
||||
local key, value = string.match(line, pattern)
|
||||
ret[key] = value
|
||||
end,
|
||||
stderr = function (line)
|
||||
local messages = {
|
||||
openbsd = { "level name .+ in (.+) is invalid" },
|
||||
linux = { "cannot stat /proc/sys/(.+):",
|
||||
"permission denied on key '(.+)'" },
|
||||
freebsd = { "unknown oid '(.+)'" }
|
||||
}
|
||||
|
||||
for _, error_message in ipairs(messages[helpers.getos()]) do
|
||||
local key = line:match(error_message)
|
||||
if key then
|
||||
key = key:gsub("/", ".")
|
||||
ret[key] = "N/A"
|
||||
end
|
||||
end
|
||||
end,
|
||||
output_done = function () parse(ret) end
|
||||
|
|
|
@ -18,68 +18,77 @@
|
|||
-- along with Vicious. If not, see <https://www.gnu.org/licenses/>.
|
||||
|
||||
-- {{{ Grab environment
|
||||
local pairs = pairs
|
||||
local tonumber = tonumber
|
||||
local math = { floor = math.floor, modf = math.modf }
|
||||
local table = {
|
||||
insert = table.insert
|
||||
}
|
||||
|
||||
local helpers = require"vicious.helpers"
|
||||
local spawn = require"vicious.spawn"
|
||||
local math = {
|
||||
floor = math.floor,
|
||||
modf = math.modf
|
||||
}
|
||||
|
||||
local helpers = require("vicious.helpers")
|
||||
-- }}}
|
||||
|
||||
local STATES = { [0] = "↯", -- not charging
|
||||
local bat_openbsd = {}
|
||||
function bat_openbsd.async(format, warg, callback)
|
||||
local battery_id = warg or "bat0"
|
||||
|
||||
local fields = {
|
||||
charging_rate = ("hw.sensors.acpi%s.power0"):format(battery_id),
|
||||
last_full_capacity = ("hw.sensors.acpi%s.watthour0"):format(battery_id),
|
||||
remaining_capacity = ("hw.sensors.acpi%s.watthour3"):format(battery_id),
|
||||
design_capacity = ("hw.sensors.acpi%s.watthour4"):format(battery_id),
|
||||
state = ("hw.sensors.acpi%s.raw0"):format(battery_id)
|
||||
}
|
||||
|
||||
local sysctl_args = {}
|
||||
for _, v in pairs(fields) do table.insert(sysctl_args, v) end
|
||||
|
||||
local battery = {}
|
||||
helpers.sysctl_async(sysctl_args, function (ret)
|
||||
for k, v in pairs(fields) do
|
||||
-- discard the description that comes after the values
|
||||
battery[k] = tonumber(ret[v]:match("(.-) "))
|
||||
end
|
||||
|
||||
local states = {
|
||||
[0] = "↯", -- not charging
|
||||
[1] = "-", -- discharging
|
||||
[2] = "!", -- critical
|
||||
[3] = "+", -- charging
|
||||
[4] = "N/A", -- unknown status
|
||||
[255] = "N/A" } -- unimplemented by the driver
|
||||
[255] = "N/A" -- unimplemented by the driver
|
||||
}
|
||||
local state = states[battery.state]
|
||||
|
||||
return helpers.setasyncall{
|
||||
async = function (format, warg, callback)
|
||||
local filter = "hw.sensors.acpi" .. (warg or "bat0")
|
||||
local pattern = filter .. ".(%S+)=(%S+)"
|
||||
local bat_info = {}
|
||||
local charge = tonumber(battery.remaining_capacity
|
||||
/ battery.last_full_capacity * 100)
|
||||
|
||||
spawn.with_line_callback_with_shell(
|
||||
("sysctl -a | grep '^%s'"):format(filter),
|
||||
{ stdout = function (line)
|
||||
for key, value in line:gmatch(pattern) do
|
||||
bat_info[key] = value
|
||||
end
|
||||
end,
|
||||
output_done = function ()
|
||||
-- current state
|
||||
local state = STATES[tonumber(bat_info.raw0)]
|
||||
|
||||
-- battery capacity in percent
|
||||
local percent = tonumber(
|
||||
bat_info.watthour3 / bat_info.watthour0 * 100)
|
||||
|
||||
local time
|
||||
if tonumber(bat_info.power0) < 1 then
|
||||
time = "∞"
|
||||
local remaining_time
|
||||
if battery.charging_rate < 1 then
|
||||
remaining_time = "∞"
|
||||
else
|
||||
local raw_time = bat_info.watthour3 / bat_info.power0
|
||||
local raw_time = battery.remaining_capacity / battery.rate
|
||||
local hours, hour_fraction = math.modf(raw_time)
|
||||
local minutes = math.floor(60 * hour_fraction)
|
||||
time = ("%d:%0.2d"):format(hours, minutes)
|
||||
remaining_time = ("%d:%0.2d"):format(hours, minutes)
|
||||
end
|
||||
|
||||
-- calculate wear level from (last full / design) capacity
|
||||
local wear = "N/A"
|
||||
if bat_info.watthour0 and bat_info.watthour4 then
|
||||
local l_full = tonumber(bat_info.watthour0)
|
||||
local design = tonumber(bat_info.watthour4)
|
||||
wear = math.floor(l_full / design * 100)
|
||||
end
|
||||
|
||||
-- dis-/charging rate as presented by battery
|
||||
local rate = bat_info.power0
|
||||
local wear = math.floor(battery.last_full_capacity,
|
||||
battery.design_capacity)
|
||||
|
||||
-- Pass the following arguments to callback function:
|
||||
-- * battery state symbol (↯, -, !, + or N/A)
|
||||
-- * remaining_capacity (in percent)
|
||||
-- * remaining_time, by battery
|
||||
-- * remaining capacity (in percent)
|
||||
-- * remaining time, as reported by the battery
|
||||
-- * wear level (in percent)
|
||||
-- * present_rate (in Watts)
|
||||
callback{state, percent, time, wear, rate}
|
||||
end })
|
||||
end }
|
||||
-- * present_rate (in Watts/hour)
|
||||
return callback({ state, charge, remaining_time,
|
||||
wear, battery.charging_rate })
|
||||
end)
|
||||
end
|
||||
|
||||
return helpers.setasyncall(bat_openbsd)
|
||||
|
|
Loading…
Reference in New Issue