diff --git a/helpers.lua b/helpers.lua
index bbe6da1..e7807e5 100644
--- a/helpers.lua
+++ b/helpers.lua
@@ -31,6 +31,7 @@
-- along with Vicious. If not, see .
-- {{{ Grab environment
+local ipairs = ipairs
local pairs = pairs
local rawget = rawget
local require = require
@@ -273,13 +274,33 @@ function helpers.sysctl_async(path_table, parse)
path = table.concat(path, " ")
spawn.with_line_callback("sysctl " .. path, {
- stdout = function(line)
- if not string.find(line, "sysctl: unknown oid") then
- local key, value = string.match(line, "(.+): (.+)")
- ret[key] = value
+ stdout = function (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
+ output_done = function () parse(ret) end
})
end
-- }}}
diff --git a/widgets/bat_openbsd.lua b/widgets/bat_openbsd.lua
index 689e836..fe7665d 100644
--- a/widgets/bat_openbsd.lua
+++ b/widgets/bat_openbsd.lua
@@ -18,68 +18,77 @@
-- along with Vicious. If not, see .
-- {{{ 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
- [1] = "-", -- discharging
- [2] = "!", -- critical
- [3] = "+", -- charging
- [4] = "N/A", -- unknown status
- [255] = "N/A" } -- unimplemented by the driver
+local bat_openbsd = {}
+function bat_openbsd.async(format, warg, callback)
+ local battery_id = warg or "bat0"
-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 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)
+ }
- 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)]
+ local sysctl_args = {}
+ for _, v in pairs(fields) do table.insert(sysctl_args, v) end
- -- battery capacity in percent
- local percent = tonumber(
- bat_info.watthour3 / bat_info.watthour0 * 100)
+ 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 time
- if tonumber(bat_info.power0) < 1 then
- time = "∞"
- else
- local raw_time = bat_info.watthour3 / bat_info.power0
- local hours, hour_fraction = math.modf(raw_time)
- local minutes = math.floor(60 * hour_fraction)
- time = ("%d:%0.2d"):format(hours, minutes)
- end
+ local states = {
+ [0] = "↯", -- not charging
+ [1] = "-", -- discharging
+ [2] = "!", -- critical
+ [3] = "+", -- charging
+ [4] = "N/A", -- unknown status
+ [255] = "N/A" -- unimplemented by the driver
+ }
+ local state = states[battery.state]
- -- 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
+ local charge = tonumber(battery.remaining_capacity
+ / battery.last_full_capacity * 100)
- -- dis-/charging rate as presented by battery
- local rate = bat_info.power0
+ local remaining_time
+ 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:
- -- * battery state symbol (↯, -, !, + or N/A)
- -- * remaining_capacity (in percent)
- -- * remaining_time, by battery
- -- * wear level (in percent)
- -- * present_rate (in Watts)
- callback{state, percent, time, wear, rate}
- end })
- end }
+ 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, as reported by the battery
+ -- * wear level (in percent)
+ -- * present_rate (in Watts/hour)
+ return callback({ state, charge, remaining_time,
+ wear, battery.charging_rate })
+ end)
+end
+
+return helpers.setasyncall(bat_openbsd)