Chrooted blog

Lenovo Thinkpad X300 , battery management and tp_smapi

← Previous entry · Next entry →

This article briefly presents a "solution" to the battery switching issue mentioned at the bottom of this blog entry.

Indeed, while having two batteries ensures a (very) long battery life, you have to switch manually from the secondary battery to the primary, in order to prevent deep discharges that harms lithium batteries.

Until now, I used to manage it by typing some aliases in my shell, but it is clearly not convenient nor reliable (Sometimes, I simply forget it).

But now, one little bash script and one line in your root's crontable, and the job's done :)

There is battery_switch.sh (deprecated, see baswim.sh below). It basically allows automatic switching to main battery when a given percentage level is reached by the secondary battery. Some parameters are available by editing variables values directly in the script, but only LOW_LEVEL is really interesting.

The cron line I use:

# sudo crontab -e

# m h  dom mon dow   command
*/5 *   *   *   *   /opt/bin/battery_switch.sh

Of course it is aware of your laptop's status. In fact, if it switched to the main battery (by forcing the main battery to discharge), and then you re-plug your laptop, it will cease to force discharge and will return to normal state.

Since I may not be clear, do a

tail -F /var/log/battery_switch.log

to get relevant information.

I hope that will help :)

EDIT: please find there baswim (battery switching improved) a new script that provides a *really* interesting feature: It permits to switch from one battery to another according to both remaining percentage and cycles count.
It follows this simple scheme:

1) Get batteries cycle status 
2) Decide which battery should discharge first based on cycles and remaining percentage
(above the low_level) 
3) Get AC status
3) If AC is unplugged, begin discharge with chosen battery
4) If needed by long unplugged operation, switch to the other battery


It basically a hack from the first script, there are some oddities (one line functions...) but hey it works (surprisingly)!

EDIT: A little but likely important update. This time, both scripts can handle two cases: one battery plus dvd-drive or both batteries.

EDIT:
If you want baswim to be a little more aware of acpi events,
you can make some symbolic links in /etc/acpi/battery.d and /etc/acpi/ac.d.

ln -s /opt/bin/baswim.sh /etc/acpi/battery.d/
ln -s /opt/bin/baswim.sh /etc/acpi/ac.d/

Then, baswim will be executed every time you plug or unplug your AC.

# · 16 comments

Add comment

Nick:
Comment:


Antispam: (2+7)²
Create an account to get rid of this!
URL:
Mail:
Remember me

16 comments

1. Bender Friday 29 May 2009, 00:05

Heh that's nice. :)

Honestly I didnt believe that you really would write a script so I wrote a C-programm my own to do something quite similar to your script. :D

My programm checks once every minute if the AC adapter is plugged in. If it is not it switches every 10 minutes to the battery with the most remaining capacity. So the batterys are discharged more or less equally.

If you're interested I can send you the source-code but I'm not sure if it's completely bugfree. On my laptop everything was fine.

Best regards,
Bender

2. Rboissat Friday 29 May 2009, 01:27 by Romain Boissat

Bender: Sure, I'll be interested in getting your source code, I may improve my script :) Please use the email address provided in this blog's credits.

Your approach seems correct, however I wonder if switching so often is not harmful... I'll try to get some documentation about it. Yours has an advantage, because you get an homogeneous cycle rate on both batteries, even with short discharges. On the contrary, with mine if you use your laptop for around 2 hours repeatedly, only the bay battery will have cycles (for instance, my bay battery has twice cycles as the main battery).

That's why I wonder if it is worth to improve my script that way:
1) Get AC status
2) Get batteries cycle status
3) Decide which battery should discharge first based on cycles and remaining percentage (above the low_level)
3) begin discharge with this one
4) switch if needed by long operation to the other

What do you think about it? I have read that lithium batteries in sane health could provide hundred of cycles, but it is not a reason to *not* optimize our consumption a little :)

3. Rboissat Friday 29 May 2009, 03:01 by Romain Boissat

Bender: I just finished debugging my scripts and fully tested them. If you downloaded one or both of them, feel free to grab them again.

4. Bender Friday 29 May 2009, 11:16

You got mail.. :)

5. Bender Friday 29 May 2009, 11:30

I've taken a look at your new script and I think it's really nice. Especially that it check's whether the smapi module is loaded or not and executes it if needed. My program simply crashes if the module isn't loaded. :S And that you have a log file to write the status changes is a nice feature too.

Unfortunately i'm quite clueless about scripting. How do you execute the script once every x minutes? As far as I can see, the script doesn't call himself again after some amount of time right?

6. Rboissat Friday 29 May 2009, 12:16 by Romain Boissat

Bender: You have to add a cron line in your root's crontab. Please refer to WP: Cron, 'man cron' and 'man crontab'.

Basically, type sudo crontab -e to edit the root's crontable, then add a line such as

*/5 *   *   *   *   /opt/bin/baswim.sh


to run baswim every 5 minutes. You can adapt it according to where you put the script in your filesystem.

Thanks for the email :)

7. Bender Friday 29 May 2009, 13:04

Ah I'll try that. Thanks!

8. Bender Saturday 30 May 2009, 12:20

I just took a closer look at the baswim script and I found 2 variables which I think are never used:

BAT_STATUS=`cat $SMAPI_PATH/BAT$CHOSEN_BAT/state`
BAT_DISCHARGE_STATUS=`cat $SMAPI_PATH/BAT$CHOSEN_BAT/force_discharge`

But it's a really nice script and I think now that it gets called when the ac cable is plugged in or out, I'll use it instead of my own program. :)

In my opinion one modification would be great: that if as far as one battery is below LOW_LEVEL, the script chooses the battery only depending on the remaining percentage and not first by the cycle count.

I think as it is now it has the following disadvantage (as an example): Because I think it's better for the battery, my LOW_LEVEL is set to 40%. Now that my bay battery is quite new, it's cycle count is way lower than the one of my main battery. If my main battery gets below 40%, the script will always choose the bay battery until the end of days (until it's empty?) because of its lower cycle count.

So what I'd prefer would be:

- If both batterys are above LOW_LEVEL choose the one with the lower cycle count
- If one battery is below LOW_LEVEL, choose the one with the higher remaining capacity

Best regards and have a nice weekend, :)
Bender

9. Bender Saturday 30 May 2009, 13:29

I've found another issue which you should have a look at:

ensure_bbat() {
if [ -d $SMAPI_PATH/BAT1 ]
then
return 0
else
echo "No Bay battery. Exiting...">>$LOG_FILE
exit
fi
}

If I get this right, you're checking if the bay battery is installed by checking if there is a directory called $SMAPI_PATH/BAT1 right?

The problem is, that directory exists even if the bay battery isn't installed. Fortunately that's no problem, because there is a file "$SMAPI_PATH/BATX/installed" where you can check whether the battery is installed or not.

I suggest that you check both, if BAT0 && BAT1 is installed, because it is also possible, that somebody has only his bay and no main battery installed. In that case the script should do nothing too. :)

10. Rboissat Saturday 30 May 2009, 16:55 by Romain Boissat

Bender: thanks! I've fixed the script, reducing verbosity too. About your concern, it is already the case:
1) if a battery has a lower cycle it is chosen;
2) but if its level is below the limit then it switches to the other battery.

Concerning your 40% level, I think it's really too high: your sacrificing a *huge* amount of battery life for just several more cycles, and yet, it is not proven reliably. If I were you, I would stick with the 10%.

With this limit, whatever battery you want to use, it will harm it... Then you should either suspend your laptop or plug it :)

But if you don't feel at ease with this behavior, feel free to adapt the script to yours needs :)

11. Bender Saturday 30 May 2009, 18:12

What I intend is to avoid deep discharges.. well the question is how "deep" is deep? I read an article some time ago where was written that it would be the best for LiIon batterys to operate between 40-90%. I don't know if it makes a big difference if they are discharged to 10% but I want to play it safe. Btw. I wouldn't sacrifice battery time at all, the only difference would be that they are discharged equally at a certain level. One example:

Lets assume we have two batterys with equally capacity at 90% (so 180% together), and we're using the laptop on battery for some time which consumes 110%. If we're using 10% as borderline it would be like this:

Battery A: 90%
Battery B: 90%

-> A discharges down to 10%
-> switch to Battery B, discharges for the remaining 30%

-> Battery A: 10%
-> Battery B: 60%

My thought was:

Battery A: 90%
Battery B: 90%

-> A discharges to 40% (higher borderline)
-> B discharges to 40%
-> Now both batterys are below LOW_LEVEL and they switch every 10-20 minutes for the remaining 10%

-> Battery A: 35-40%
-> Battery B: 35-50%

If you're using the battery more, both batterys will discharge equally and it is more unlikely that they operate at very low levels. Perhaps the 10% border is perfectly fine and I'm just too cautious but I think I'll try it nevertheless. If it really doesn't matter I had at least a good opportunity to have a little glimpse at scripting in unix. ;-)

12. Bender Saturday 30 May 2009, 18:15

Ehm one little mistake.. if both batterys are discharging alternating they both go down to 30-40%, not 35-40%, depending on which battery is discharging how long. Well it's weekend.. :)

13. Rboissat Saturday 30 May 2009, 19:09 by Romain Boissat

Bender: Beyond the complexity you may face in scripting your idea, I think you are misunderstanding the 40%-90%, which is the recommended storage range. Concerning normal operation, you can read some different ranges, but quite wider, thus lowering the low level (indeed, 90% is the max recommended).

Moreover, lithium batteries do not live very long, whatever precautions you take... It's even recommended to look at the manufacturing date when purchasing! I may however be a bit severe on the low-level I chose (10%), according to this site, it should be around 20% instead. I let the user choose :)

14. Toe Friday 30 April 2010, 19:11

Thanks a lot! This is working for me (Kubuntu 10.04, X300) - and a solution for a problem I have long been thinking about.

15. Rboissat Saturday 01 May 2010, 00:22 by Romain Boissat

Toe: Glad to read this. Don't hesitate if you want to provide any feedback!

16. Wes Friday 14 May 2010, 14:20

I stumbled upon your posts about the x300
power management. Thank you! I have long
wanted to have both batteries discharge
"together" (I have an old fujitsu p7010
with a bay battery and the engineeers at
fujitsu set this up right).

» Comment this entry...
» Comments feed