Lenovo T530 - Battery Warnings

Ian Smith smithi at nimnet.asn.au
Mon Jul 8 11:39:19 UTC 2013


On Sun, 7 Jul 2013 02:59:56 -0300, Joseph Mingrone wrote:
 > Ian Smith <smithi at nimnet.asn.au> writes:
 > > On Fri, 14 Jun 2013 10:58:11 -0300, Joseph Mingrone wrote:
 > >
 > >  > I convinced a friend to try FreeBSD (9-STABLE amd64) on her Lenovo T530 and
 > >  > things are running quite well.  One problem is that, unlike other
 > >  > IBM/Lenovos, there is no beep to warn her when the battery is about to die.
 > >  > There is also no beep when (un)plugging the power.  Beeping does work before
 > >  > the OS is loaded (e.g. in the BIOS setup).  The BIOS version is 2.04.
 > >  > 
 > >  > Is there a fix for this?
 > >
 > > For AC<->battery changes, /etc/devd.conf already has devd perform:
 > >
 > > # Switch power profiles when the AC line state changes.  notify 10 { match
 > > "system" "ACPI"; match "subsystem" "ACAD"; action "/etc/rc.d/power_profile
 > > $notify"; };
 > >
 > > You won't need to mess with power_profile but it's instructive and logs power
 > > changes to /var/log/messages.
 > >
 > > If you made that, say: action "/etc/rc.d/power_profile $notify &&
 > > /root/my_script $notify";
 > >
 > > then my_script can do whatever, with or without using parameter $notify
 > >
 > > if '# kldload speaker && spkrtest' makes useful noises on the speaker, then it's
 > > easy to make up a couple of satisfactory and noticeable alert 'tunes'.  See
 > > speaker(4).  I used these for years on an old Compaq with APM, which also could
 > > be configured to run alerts at every 10% battery level change, charging or
 > > discharging, enabling such as suspend on low battery where that wasn't built in,
 > > or other actions to save power.
 > >
 > > devd.conf(5) as well as /etc/devd.conf shows:
 > >
 > >      ACPI Events related to the ACPI subsystem.  Subsystem ACAD AC line state
 > > ($notify=0x00 is offline, 0x01 is online).  Button Button state ($notify=0x00 is
 > > power, 0x01 is sleep).  CMBAT Battery events.  Lid Lid state ($notify=0x00 is
 > > closed, 0x01 is open).  Thermal Thermal zone events.
 > >
 > > with an example also for thermal overheating pending shutdown, but I'm yet to
 > > find examples of any CMBAT battery events, regarding your first concern.  That
 > > is, I've wondered about this myself ..
 > >
 > > Can anyone say, or point to, which ACPI CMBAT events get to devd?

So I went looking in /sys/dev/acpica/acpi_cmbat.c
	#define ACPI_BATTERY_BST_CHANGE 0x80
	#define ACPI_BATTERY_BIF_CHANGE 0x81

and just to refresh my failing (non-ECC) memory:
/sys/dev/acpica/acpiio.h:#define ACPI_BATT_STAT_DISCHARG        0x0001
/sys/dev/acpica/acpiio.h:#define ACPI_BATT_STAT_CHARGING        0x0002
/sys/dev/acpica/acpiio.h:#define ACPI_BATT_STAT_CRITICAL        0x0004
/sys/dev/acpica/acpiio.h:#define ACPI_BATT_STAT_NOT_PRESENT     0x0007

 > After an upgrade to 9-STABLE, the speakers started working.  I followed
 > you advice Ian to get the tones when switching between battery and AC.

Great.  You just about duplicated the charger [dis]connect noises, nice.

 > I also tried to play a sound when the battery enters a LOW state, but
 > hw.acpi.battery.state remains in 1 (discharging) until the battery runs
 > out of power.  A notification is triggered in devd when the battery hits
 > about 4%, but without a $notify I struggled to distinguish battery-related
 > events.  The solution I came up with is a bit of a hack, but it works (for now).
 > I run a cronjob to check the remaining power and if it's at or below 5%
 > play a warning.  Here is the script:
 > http://ftfl.ca:8080/admin/artifact/80e3121009ba836d1b6f57eda6207520b9807b63

Cool.  I offer a patch below.  Perhaps try logging the devd notifies as 
they happen, you may be able to use them if you distinguish using 0x80, 
which would beat needing to use a cronjob; devd is more or less instant.

BIF is about all battery info used by eg acpiconf -i0, and may or may 
not duplicate the BST notifies, which should be all you need here.

My comments are gratuitous, just suggestions.  If you do calibrate the 
battery fairly regularly the remaining percent and remaining time may 
tally somewhat, but certainly keep an eye on critical discharge (5) as 
it should be definitive; I tend to err on the safer side.  Maybe log 
more of your gathered vars on forced shutdown, to test assumptions?

cheers, Ian

=======
--- power	2013-07-07 22:34:34.000000000 +1000
+++ power.upd	2013-07-08 20:54:29.000000000 +1000
@@ -50,9 +50,9 @@
     cur_bat_prcnt=`sysctl -n hw.acpi.battery.life`
     cur_bat_state=`sysctl -n hw.acpi.battery.state`
     log_cmd="/usr/bin/logger -t battery -p daemon.notice"
-    shutdown_cmd="/sbin/shutdown -p ${shutdown_wait}"
     shutdown_time=2
     shutdown_wait=1
+    shutdown_cmd="/sbin/shutdown -p ${shutdown_wait}"
     tone_low="mst200o2ola.l8bc.~a.~>l2d#"
     wall_cmd="/usr/bin/wall"
     
@@ -60,10 +60,14 @@
 	bat_time=`sysctl -n hw.acpi.battery.time`
 	echo ${tone_low} > ${speaker}
 	$wall_cmd <<EOF
-"Battery is at ${bat_prcnt}%"
+"Battery is at ${cur_bat_prcnt}%"
 EOF
-	if [ x$bat_time = x$shutdown_time ] ; then
-	    shutdown_msg="Battery is at ${bat_prcnt}. Powering down in ${shutdown_wait} minute(s)."
+	# battery.time may not properly reflect battery.life, especially if
+	# the battery has not been calibrated for a while.  assume the worst
+	# and also take the battery/EC's word for state 'critical discharging'
+	if [ ${bat_time} -le ${shutdown_time} -o ${cur_bat_prcnt} -lt 5 \
+		-o ${cur_bat_state} -eq 5 ]; then
+	    shutdown_msg="Battery is at ${bat_prcnt}%. Powering down in ${shutdown_wait} minute(s)."
 	    $log_cmd ${shutdown_msg}
             $wall_cmd <<EOF
 ${shutdown_msg}
=======


More information about the freebsd-mobile mailing list