battery-widget: Sanitize total charge computation
The code to parse the output of `acpi -i` is fragile as it does not guarantee that the same number of battery status and capacities are read. This causes a wrong computation of the total charge level when batteries of status "Unknown" are reported. For instance, this is what `acpi -i` reports with a Wacom Intuos S attached to a Thinkpad T460s: $ acpi -i Battery 0: Unknown, 0%, rate information unavailable Battery 1: Not charging, 98% Battery 1: design capacity 1857 mAh, last full capacity 1513 mAh = 81% Battery 2: Not charging, 98% Battery 2: design capacity 2051 mAh, last full capacity 1711 mAh = 83% Fix the code by guaranteeing that for each battery status parsed there is also a capacity, which is zero if no capacity can be parsed. This effectively causes the exclusion of such batteries when computing the total charge level.
This commit is contained in:
parent
0aba2f2e13
commit
ed355dbf46
|
@ -125,12 +125,21 @@ local function worker(user_args)
|
||||||
local battery_info = {}
|
local battery_info = {}
|
||||||
local capacities = {}
|
local capacities = {}
|
||||||
for s in stdout:gmatch("[^\r\n]+") do
|
for s in stdout:gmatch("[^\r\n]+") do
|
||||||
|
-- Match a line with status and charge level
|
||||||
local status, charge_str, _ = string.match(s, '.+: ([%a%s]+), (%d?%d?%d)%%,?(.*)')
|
local status, charge_str, _ = string.match(s, '.+: ([%a%s]+), (%d?%d?%d)%%,?(.*)')
|
||||||
if status ~= nil then
|
if status ~= nil then
|
||||||
|
-- Enforce that for each entry in battery_info there is an
|
||||||
|
-- entry in capacities of zero. If a battery has status
|
||||||
|
-- "Unknown" then there is no capacity reported and we treat it
|
||||||
|
-- as zero capactiy for later calculations.
|
||||||
table.insert(battery_info, {status = status, charge = tonumber(charge_str)})
|
table.insert(battery_info, {status = status, charge = tonumber(charge_str)})
|
||||||
else
|
table.insert(capacities, 0)
|
||||||
local cap_str = string.match(s, '.+:.+last full capacity (%d+)')
|
end
|
||||||
table.insert(capacities, tonumber(cap_str))
|
|
||||||
|
-- Match a line where capacity is reported
|
||||||
|
local cap_str = string.match(s, '.+:.+last full capacity (%d+)')
|
||||||
|
if cap_str ~= nil then
|
||||||
|
capacities[#capacities] = tonumber(cap_str) or 0
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
|
@ -144,6 +153,9 @@ local function worker(user_args)
|
||||||
-- this is arbitrary, and maybe another metric should be used
|
-- this is arbitrary, and maybe another metric should be used
|
||||||
end
|
end
|
||||||
|
|
||||||
|
-- Adds up total (capacity-weighted) charge and total capacity.
|
||||||
|
-- It effectively ignores batteries with status "Unknown" as we
|
||||||
|
-- treat them with capacity zero.
|
||||||
charge = charge + batt.charge * capacities[i]
|
charge = charge + batt.charge * capacities[i]
|
||||||
capacity = capacity + capacities[i]
|
capacity = capacity + capacities[i]
|
||||||
end
|
end
|
||||||
|
|
Loading…
Reference in New Issue