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