[opensuse-kernel] Aliens ate /proc/acpi/battery/BAT*
I have a hunc "this is a feature, not a bug" ;-), but with the update to kernel 4.0, /proc/acpi/battery/BAT* is gone. Is there a way (config option we could enable) to get this back? If not, how can I best re-implement something like the little script below (which works for more than one battery in case you are wondering about the complexity): #!/bin/bash sum() { s=0; while read l; do i=`echo $l | cut -d' ' -f1` printf "%5s " "$i" s=$(($s+$i)) done printf " = %s\n" "$s" } for v in "design capacity" "last full capacity" "remaining capacity" "rate"; do printf "%18s = " "$v" cat /proc/acpi/battery/BAT*/* | grep "$v:" | cut -d: -f2 | sum done Gerald -- Dr. Gerald Pfeifer <gp@suse.com> Sr. Director Product Management and Operations, SUSE -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
Hi Gerald, Le Tuesday 05 May 2015 à 16:20 +0200, Gerald Pfeifer a écrit :
I have a hunc "this is a feature, not a bug" ;-), but with the update to kernel 4.0, /proc/acpi/battery/BAT* is gone.
Is there a way (config option we could enable) to get this back?
It was removed on purpose by: commit 9eb6ba436281fa55e9eb5442d69d09a388b47706 Author: Jeff Mahoney <jeffm@suse.com> Date: Mon Mar 23 11:02:52 2015 -0400 config: disable CONFIG_ACPI_PROCFS_POWER (i386/x86_64) (boo#917728) CONFIG_ACPI_PROCFS_POWER is deprecated and should be disabled. Of course, re-enabling it would temporarily solve your problem, but we really want to get rid of it in the long run, so the best option is to update your custom script to use the "new" sysfs interface instead. You should be able to find under /sys/class/power_supply/BAT* almost everything you used to see in /proc/acpi/battery/BAT*.
If not, how can I best re-implement something like the little script below (which works for more than one battery in case you are wondering about the complexity):
#!/bin/bash
sum() { s=0; while read l; do i=`echo $l | cut -d' ' -f1` printf "%5s " "$i" s=$(($s+$i)) done printf " = %s\n" "$s" }
for v in "design capacity" "last full capacity" "remaining capacity" "rate"; do printf "%18s = " "$v" cat /proc/acpi/battery/BAT*/* | grep "$v:" | cut -d: -f2 | sum done
The following should work except for the "rate" which isn't mentioned in the sysfs interface. I seem to understand that this isn't considered a property of the battery so you have to derive it yourself from the the other numbers over an arbitrary period. #!/bin/bash sum() { s=0; while read l; do i=`echo $l | cut -d' ' -f1` i=$(($i/1000)) printf "%5s " "$i" s=$(($s+$i)) done printf " = %s\n" "$s" } for v in "energy_full_design" "energy_full" "energy_now"; do printf "%18s = " "$v" cat /sys/class/power_supply/BAT*/$v | sum done Hope that helps, -- Jean Delvare SUSE L3 Support -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
Le Wednesday 06 May 2015 à 14:22 +0200, Jean Delvare a écrit :
The following should work except for the "rate" which isn't mentioned in the sysfs interface. I seem to understand that this isn't considered a property of the battery so you have to derive it yourself from the the other numbers over an arbitrary period.
Would that work for you? #!/bin/bash # Sample time in seconds SAMPLE_TIME=10 declare -a energy_full_design energy_full energy_now sum() { local v=$1 shift s=0; printf "%18s = " "$v" while [ $# -gt 0 ]; do i=$(($1/1000)) printf "%5s " "$i" s=$(($s+$i)) shift done printf " = %s\n" "$s" save=$s } energy_full_design=(`cat /sys/class/power_supply/BAT*/energy_full_design`) energy_full=(`cat /sys/class/power_supply/BAT*/energy_full`) energy_now=(`cat /sys/class/power_supply/BAT*/energy_now`) sum "design capacity" "$energy_full_design" sum "last full capacity" "$energy_full" sum "remaining capacity" "$energy_now" sum_then=$save sleep $SAMPLE_TIME energy_now=(`cat /sys/class/power_supply/BAT*/energy_now`) sum "remaining capacity" "$energy_now" sum_now=$save rate=$((($sum_now-$sum_then)/$SAMPLE_TIME)) printf "%18s = %5s\n" "rate" "$rate" (I'm not necessarily proud of everything in this script.) -- Jean Delvare SUSE L3 Support -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
Am 06.05.2015 um 14:22 schrieb Jean Delvare:
The following should work except for the "rate" which isn't mentioned in the sysfs interface. I seem to understand that this isn't considered a property of the battery so you have to derive it yourself from the the other numbers over an arbitrary period.
"power_now" is basically what the "rate" was, but it's expressed in microwatts while in /proc it could be either mA or mW IIRC. -- Stefan Seyfried "For a successful technology, reality must take precedence over public relations, for nature cannot be fooled." -- Richard Feynman -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
Hallo Stefan, Le Thursday 07 May 2015 à 21:09 +0200, Stefan Seyfried a écrit :
Am 06.05.2015 um 14:22 schrieb Jean Delvare:
The following should work except for the "rate" which isn't mentioned in the sysfs interface. I seem to understand that this isn't considered a property of the battery so you have to derive it yourself from the the other numbers over an arbitrary period.
"power_now" is basically what the "rate" was, but it's expressed in microwatts while in /proc it could be either mA or mW IIRC.
Baah, thanks for pointing out the obvious, I must have been blind :( Whatever the unit is, it's impressively undocumented. So anyway Gerald's script can be simplified again to: #!/bin/bash sum() { s=0; while read i; do i=$(($i/1000)) printf "%5s " "$i" s=$(($s+$i)) done printf " = %s\n" "$s" } for v in "energy_full_design" "energy_full" "energy_now" "power_now"; do printf "%18s = " "$v" cat /sys/class/power_supply/BAT*/$v | sum done -- Jean Delvare SUSE L3 Support -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
On Thu 2015-05-07, Jean Delvare wrote:
So anyway Gerald's script can be simplified again to:
Super! Thanks a lot, Jean (and Stefan). I've been travelling the last two weeks, hence did not respond earlier. Below you'll find the script as I am using it now, which works both off /sys/class/power_supply and /proc/acpi/battery, so across different versions of openSUSE and SUSE Linux Enterprise. (Somehow the "if ls /sys/class/power_supply/BAT* >/dev/null; then" strikes me as overkill. Is there a way to accomplish this easier? Or can we assume the first battery always has index 0 and simply check for BAT0?) Gerald ====== script ====== #!/bin/bash sum() { s=0; while read l; do i=`echo $l | cut -d' ' -f1` printf "%5s " "$i" s=$(($s+$i)) done printf " = %5s\n" "$s" } if ls /sys/class/power_supply/BAT* >/dev/null; then for v in "energy_full_design" "energy_full" "energy_now" "power_now"; do printf "%18s = " "$v" #cat /sys/class/power_supply/BAT*/$v | sed -e 's/\(.*\)\([0-9][0-9]\)0000$/\1.\2/' | sum cat /sys/class/power_supply/BAT*/$v | sed -e 's/000$//' | sum done else for v in "design capacity" "last full capacity" "remaining capacity" "rate"; do printf "%18s = " "$v" cat /proc/acpi/battery/BAT*/* | grep "$v:" | cut -d: -f2 | sum done fi -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
Hallo Gerald, On Sat, 16 May 2015 12:50:19 -0400 (EDT), Gerald Pfeifer wrote:
On Thu 2015-05-07, Jean Delvare wrote:
So anyway Gerald's script can be simplified again to:
Super! Thanks a lot, Jean (and Stefan). I've been travelling the last two weeks, hence did not respond earlier.
You're welcome, no problem.
Below you'll find the script as I am using it now, which works both off /sys/class/power_supply and /proc/acpi/battery, so across different versions of openSUSE and SUSE Linux Enterprise.
(Somehow the "if ls /sys/class/power_supply/BAT* >/dev/null; then" strikes me as overkill. Is there a way to accomplish this easier? Or can we assume the first battery always has index 0 and simply check for BAT0?)
That would rather be a question for Thomas, but I'm afraid it's not even guaranteed that batteries show up as BAT*, even though I think all laptops I've seen so far used that name. But the first battery may not be BAT0, for example on my old Panasonic Toughbook CF-18 it's named BATA. To be on the bulletproof side I think you must check that sysfs attribute "type" has value "Battery". You can avoid the call to "ls", with a construct like: if [ -n "$(shopt -s nullglob ; echo /sys/class/power_supply/BAT*)" ] Not sure if it's significantly faster though. It might be easier to just check for -d /sys/class/power_supply anyway, as I would guess that in practice it's always populated when present?
====== script ====== #!/bin/bash
sum() { s=0; while read l; do i=`echo $l | cut -d' ' -f1` printf "%5s " "$i" s=$(($s+$i)) done printf " = %5s\n" "$s" }
if ls /sys/class/power_supply/BAT* >/dev/null; then for v in "energy_full_design" "energy_full" "energy_now" "power_now"; do printf "%18s = " "$v" #cat /sys/class/power_supply/BAT*/$v | sed -e 's/\(.*\)\([0-9][0-9]\)0000$/\1.\2/' | sum cat /sys/class/power_supply/BAT*/$v | sed -e 's/000$//' | sum
This assumes that the last 3 digits are always 000, which doesn't have to be true. sed -e 's/...$//' would be safer.
done else for v in "design capacity" "last full capacity" "remaining capacity" "rate"; do printf "%18s = " "$v" cat /proc/acpi/battery/BAT*/* | grep "$v:" | cut -d: -f2 | sum done fi
-- Jean Delvare SUSE L3 Support -- To unsubscribe, e-mail: opensuse-kernel+unsubscribe@opensuse.org To contact the owner, e-mail: opensuse-kernel+owner@opensuse.org
participants (3)
-
Gerald Pfeifer
-
Jean Delvare
-
Stefan Seyfried