|
| 1 | +-- Get battery info using /sys/class/power_supply/* files. Requires Linux |
| 2 | + |
| 3 | +local J = require("plenary.job") |
| 4 | +local L = require("plenary.log") |
| 5 | +local BC = require("util.chooser") |
| 6 | +local config = require("battery.config") |
| 7 | +local log = L.new({ plugin = "battery" }) |
| 8 | + |
| 9 | +-- Convert lowercase status from `/sys/class/power_supply/BAT?/status` |
| 10 | +-- to whether AC power is connected |
| 11 | +local status_to_ac_power = { |
| 12 | + ["full"] = true, |
| 13 | + ["charging"] = true, |
| 14 | + ["discharging"] = false, |
| 15 | + ["unknown"] = false, -- We don't know, so assume false |
| 16 | +} |
| 17 | + |
| 18 | +-- Parse the response from the battery info job and update |
| 19 | +-- the battery status |
| 20 | +local function parse_powersupply_battery_info(battery_paths, battery_status) |
| 21 | + local path_count = #battery_paths |
| 22 | + local battery_count = 0 |
| 23 | + |
| 24 | + if path_count > 0 then |
| 25 | + -- Read capacities of each battery |
| 26 | + local percents = {} |
| 27 | + for _, path in ipairs(battery_paths) do |
| 28 | + local f = io.open(path .. "/capacity", "r") |
| 29 | + if f then |
| 30 | + local charge = f:read("n") |
| 31 | + if charge then |
| 32 | + battery_count = battery_count + 1 |
| 33 | + table.insert(percents, charge) |
| 34 | + end |
| 35 | + f:close() |
| 36 | + end |
| 37 | + end |
| 38 | + |
| 39 | + -- Read status file of first battery |
| 40 | + local f = io.open(battery_paths[1] .. "/status", "r") |
| 41 | + local status |
| 42 | + if f then |
| 43 | + -- Read line (without newline character, with a default of unknown), to lowercase |
| 44 | + status = (f:read("l") or "unknown"):lower() |
| 45 | + f:close() |
| 46 | + else |
| 47 | + status = "unknown" |
| 48 | + end |
| 49 | + battery_status.ac_power = status_to_ac_power[status] |
| 50 | + -- Choose a percent |
| 51 | + local chosen_percent = BC.battery_chooser(percents, config.current.multiple_battery_selection) |
| 52 | + battery_status.percent_charge_remaining = chosen_percent |
| 53 | + -- Set battery count |
| 54 | + battery_status.battery_count = battery_count |
| 55 | + else |
| 56 | + battery_status.ac_power = true |
| 57 | + battery_status.percent_charge_remaining = 100 |
| 58 | + battery_status.battery_count = path_count |
| 59 | + end |
| 60 | +end |
| 61 | + |
| 62 | +local function get_battery_info_job(battery_status) |
| 63 | + return J:new({ |
| 64 | + -- Find symbolic links in /sys/class/power_supply that start with BAT |
| 65 | + -- These are the directories containing information files for each battery |
| 66 | + command = "find", |
| 67 | + args = { |
| 68 | + "/sys/class/power_supply/", |
| 69 | + "-type", "l", |
| 70 | + "-name", "BAT*", |
| 71 | + }, |
| 72 | + on_exit = function (j, return_value) |
| 73 | + if return_value == 0 then |
| 74 | + parse_powersupply_battery_info(j:result(), battery_status) |
| 75 | + log.debug(vim.inspect(battery_status)) |
| 76 | + else |
| 77 | + log.error(vim.inspect(j:result())) |
| 78 | + end |
| 79 | + end |
| 80 | + }) |
| 81 | +end |
| 82 | + |
| 83 | +return { |
| 84 | + get_battery_info_job = get_battery_info_job |
| 85 | +} |
0 commit comments