Unverified Commit 2c04232c authored by Slobodan Todorov's avatar Slobodan Todorov Committed by Mark Vander Stel
Browse files

Update battery functionality to add sysfs backend



Add sysfs function, tests, and documentation.
Set sysfs method as default.
Remove LP_BATTERY_ID from __lp_battery_acpi() as unreliable.

Co-authored-by: default avatarMark Vander Stel <mvndrstl@gmail.com>
parent 40fe15ee
......@@ -45,7 +45,7 @@ Battery
Can be disabled by :attr:`LP_ENABLE_BATT`.
.. versionchanged:: 2.1
:attr:`LP_BATTERY_ID` can be used to specify which battery to monitor.
Implemented `sysfs` method as the default way of getting battery status.
Development Environment
-----------------------
......
......@@ -54,6 +54,26 @@ Formatting
.. _`ANSI escape color code`: https://en.wikipedia.org/wiki/ANSI_escape_code#Colors
Battery
-------
.. function:: __lp_battery_acpi() -> var:lp_battery, var:lp_battery_status
Returns the status and remaining capacity of the battery, as reported by
the `acpi` tool. This function is available only on Linux, and requires
`acpi` to be installed.
.. versionadded:: 2.1
.. function:: __lp_battery_sysfs() -> var:lp_battery, var:lp_battery_status
Returns the status and remaining capacity of the battery, using `sysfs`.
This is the default method. If multiple batteries are present, returns the
status of the first battery found. This function is available only on Linux
systems.
.. versionadded:: 2.1
Git
---
......
......@@ -339,7 +339,7 @@ __lp_source_config() {
)
fi
LP_BATTERY_ID=${LP_BATTERY_ID:-0}
_LP_LINUX_POWERSUPPLY_PATH="/sys/class/power_supply"
# Debugging flags
LP_DEBUG_TIME=${LP_DEBUG_TIME:-0}
......@@ -510,8 +510,8 @@ lp_activate() {
if [[ "$LP_OS" = Darwin ]]; then
_lp_require_tool BATT pmset
else
_lp_require_tool BATT acpi
elif (( LP_ENABLE_BATT )); then
__lp_battery_detect || LP_ENABLE_BATT=0
fi
_lp_require_tool KUBECONTEXT kubectl
......@@ -2341,37 +2341,80 @@ _lp_wifi() {
# Get the battery status in percent.
case "$LP_OS" in
Linux)
_lp_battery() {
(( LP_ENABLE_BATT )) || return 5
__lp_battery_sysfs() {
local power_supply
for power_supply in "${_LP_LINUX_POWERSUPPLY_PATH}/"*; do
if ! [[ -r "${power_supply}/type" && -r "${power_supply}/present" && \
-r "${power_supply}/status" && -r "${power_supply}/capacity" ]]; then
continue
fi
local power_supply_type power_supply_present power_supply_scope
IFS= read -r power_supply_type <"${power_supply}/type"
[[ $power_supply_type == 'Battery' ]] || continue
IFS= read -r power_supply_present <"${power_supply}/present"
[[ $power_supply_present == '1' ]] || continue
# Scope is a property of a power supply
# Scope = System or missing - power supply powers the system
# Scope = Device - power supply powers a device
if [[ -r "${power_supply}/scope" ]]; then
IFS= read -r power_supply_scope <"${power_supply}/scope"
[[ $power_supply_scope == 'System' ]] || continue
fi
IFS= read -r lp_battery_status <"${power_supply}/status"
IFS= read -r lp_battery <"${power_supply}/capacity"
return 0
done
return 1
}
__lp_battery_acpi() {
local acpi
acpi="$(acpi --battery 2>/dev/null)"
# Check if we want a battery other than the default one
if [[ $LP_BATTERY_ID -gt 0 ]]; then
while IFS=$'\n' read -r line; do
# Find the desired battery by it's ID
if [[ $line =~ Battery\ $LP_BATTERY_ID ]]; then
acpi=$line # Use only desired battery output
break
fi
done <<<"$acpi"
fi
# Extract the battery load value in percent
# First, remove the beginning of the line...
lp_battery="${acpi#Battery *, }"
lp_battery="${lp_battery%%%*}" # remove everything starting at '%'
lp_battery_status="${acpi}"
}
__lp_battery_detect() {
local lp_battery lp_battery_status
unset _LP_BATTERY_FUNCTION
# First check SYSFS way.
_LP_BATTERY_FUNCTION=__lp_battery_sysfs
"$_LP_BATTERY_FUNCTION" 2>/dev/null
[[ -n "${lp_battery-}" ]] && return 0
# Try with ACPI.
_LP_BATTERY_FUNCTION=__lp_battery_acpi
"$_LP_BATTERY_FUNCTION" 2>/dev/null
[[ -n "${lp_battery-}" ]] && return 0
unset _LP_BATTERY_FUNCTION
return 1
}
_lp_battery() {
(( LP_ENABLE_BATT )) || return 5
unset lp_battery lp_battery_status
"$_LP_BATTERY_FUNCTION"
if [[ -z "${lp_battery}" ]]; then
if [[ -z "${lp_battery-}" ]]; then
# no battery level found
return 4
fi
# discharging
if [[ "$acpi" == *"Discharging"* ]]; then
if [[ "$lp_battery_status" == *"Discharging"* ]]; then
# under => 0, above => 1
return "$(( lp_battery > LP_BATTERY_THRESHOLD ))"
# not charging
elif [[ "$acpi" == *"Not charging"* ]]; then
elif [[ "$lp_battery_status" == *"Not charging"* ]]; then
return 4
# charging
else
......
......@@ -9,6 +9,7 @@ uname() { printf 'Linux'; }
unset -f uname
LP_ENABLE_BATT=1
_LP_BATTERY_FUNCTION=__lp_battery_acpi
typeset -a battery_outputs battery_statuses battery_values temp_outputs temp_values battery_ids
......@@ -19,7 +20,6 @@ battery_outputs+=(
""
)
battery_statuses+=(4)
battery_ids+=("")
battery_values+=("")
temp_outputs+=(
"Thermal 0: ok, 23.0 degrees C"
......@@ -32,7 +32,6 @@ battery_outputs+=(
)
battery_statuses+=(0)
battery_values+=(55)
battery_ids+=(0)
temp_outputs+=(
"Thermal 0: ok, -267.8 degrees C"
)
......@@ -40,13 +39,12 @@ temp_values+=(-267)
# Multiple batteries
battery_outputs+=(
"Battery 0: Discharging, 0%, rate information unavailable
"Battery 0: Discharging, 5%, rate information unavailable
Battery 1: Discharging, 0%, rate information unavailable
Battery 2: Discharging, 53%, 02:35:00 remaining"
)
battery_statuses+=(0)
battery_values+=(53)
battery_ids+=(2)
battery_values+=(5)
temp_outputs+=(
"Thermal 0: ok, 39.0 degrees C"
)
......@@ -66,7 +64,6 @@ function test_acpi_battery {
for (( index=0; index < ${#battery_values[@]}; index++ )); do
__battery_output=${battery_outputs[$index]}
LP_BATTERY_ID=${battery_ids[$index]}
LP_BATTERY_THRESHOLD=100
_lp_battery
......
# Error on unset variables
set -u
# Load Linux version of _lp_battery()
uname() { printf 'Linux'; }
. ../liquidprompt --no-activate
unset -f uname
LP_ENABLE_BATT=1
_LP_BATTERY_FUNCTION=__lp_battery_sysfs
typeset -a battery_types battery_presents battery_status battery_capacities battery_out_statuses battery_values
# Add test cases to these arrays like below
# Empty ("") means file doesn't exist
# Linux 5.11.0-38-generic #42~20.04.1-Ubuntu SMP Tue Sep 28 20:41:07 UTC 2021 x86_64 x86_64 x86_64 GNU/Linux
battery_types+=("Battery")
battery_presents+=("1")
battery_statuses+=("Discharging")
battery_capacities+=("67")
battery_out_statuses+=(0)
battery_values+=("67")
battery_scopes+=("")
# Full, not charging
battery_types+=("Battery")
battery_presents+=("")
battery_statuses+=("")
battery_capacities+=("")
battery_out_statuses+=(4)
battery_values+=("")
battery_scopes+=("System")
# Not a battery
battery_types+=("Mains")
battery_presents+=("")
battery_statuses+=("")
battery_capacities+=("")
battery_out_statuses+=(4)
battery_values+=("")
battery_scopes+=("")
# Wrong type of battery battery (Wireless mouse, some other)
battery_types+=("Battery")
battery_presents+=("1")
battery_statuses+=("")
battery_capacities+=("0")
battery_out_statuses+=(4)
battery_values+=("")
battery_scopes+=("Device")
test_sysfs_battery() {
_LP_LINUX_POWERSUPPLY_PATH=$(mktemp -d)
for (( index=0; index < ${#battery_values[@]}; index++ )); do
_LP_LINUX_POWERSUPPLY_PATH_DEVICE="${_LP_LINUX_POWERSUPPLY_PATH}/${index}"
mkdir "${_LP_LINUX_POWERSUPPLY_PATH_DEVICE}"
if [[ -n ${battery_types[index]-} ]]; then
printf '%s' "${battery_types[index]}" > "${_LP_LINUX_POWERSUPPLY_PATH_DEVICE}/type"
fi
if [[ -n ${battery_presents[index]-} ]]; then
printf '%s' "${battery_presents[index]}" > "${_LP_LINUX_POWERSUPPLY_PATH_DEVICE}/present"
fi
if [[ -n ${battery_statuses[index]-} ]]; then
printf '%s' "${battery_statuses[index]}" > "${_LP_LINUX_POWERSUPPLY_PATH_DEVICE}/status"
fi
if [[ -n ${battery_capacities[index]-} ]]; then
printf '%s' "${battery_capacities[index]}" > "${_LP_LINUX_POWERSUPPLY_PATH_DEVICE}/capacity"
fi
if [[ -n ${battery_scopes[index]} ]]; then
printf '%s' "${battery_scopes[index]}" > "${_LP_LINUX_POWERSUPPLY_PATH_DEVICE}/scope"
fi
LP_BATTERY_THRESHOLD=100
_lp_battery
assertEquals "sysfs battery below returns at index ${index}" "${battery_out_statuses[$index]}" "$?"
assertEquals "sysfs battery value at index ${index}" "${battery_values[$index]}" "${lp_battery-}"
_status=${battery_out_statuses[$index]}
(( _status < 4 )) && _status=$(( _status + 1 ))
LP_BATTERY_THRESHOLD=0
_lp_battery
assertEquals "sysfs battery above returns at index ${index}" "$_status" "$?"
assertEquals "sysfs battery value at index ${index}" "${battery_values[$index]}" "${lp_battery-}"
rm -r "$_LP_LINUX_POWERSUPPLY_PATH_DEVICE"
done
rm -r "$_LP_LINUX_POWERSUPPLY_PATH"
}
if [ -n "${ZSH_VERSION-}" ]; then
SHUNIT_PARENT="$0"
setopt shwordsplit ksh_arrays
fi
. ./shunit2
Supports Markdown
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment