Optimizing Battery Management on Linux Phones: A Dive into PinePhone and Librem 5

Hey everyone,

I’ve fully switched to using the Librem 5 as my daily driver and love it, but the battery management has been a bit of a project for me. Leaving it plugged in all day doesn’t sit right with me when the battery stays fully charged and keeps drawing power. So, I’ve been experimenting with ways to tweak this. I’ve managed to set up a system where the battery cuts off from charging when it hits a certain point but remains available for discharge down to a lower threshold if the phone needs it.

Here’s how the scripts work under various conditions:

  • Standard Charging: The phone charges to a predetermined upper limit (like 90%) and then stops to prevent battery strain.
  • Continuous Power Supply: If it remains plugged in post-charge, the phone priorities drawing power directly off the charger, sparing the battery , and only use the battery if the power supply is not producing enough juice.
  • Reconnection Nuances: Unplugging and replugging doesn’t immediately resume charging. It waits until the battery drops below a set lower threshold (say, 60%), which helps in maintaining battery health by avoiding short, unnecessary charge cycles.
  • Handling Power Fluctuations: For those times when the power source is unstable or you’re frequently plugging and unplugging, the script ensures that repetitive charging doesn’t kick in unless truly needed.
  • Customization: The thresholds for both the upper and lower limits can be adjusted to fit personal usage patterns and battery longevity goals.

Project Repositories:

On the PinePhone, managing this was pretty straightforward because the driver includes a ‘charge behavior’ driver that you can manipulate directly. For the PinePhonePro, you can find the charge behaviour control at this path:

/sys/class/power_supply/{battery_type}/charge_behaviour

The Librem 5, however, threw a curveball my way. It doesn’t support modifying charge behavior through the usual driver settings. The workaround I found on the wiki, using the charge LED as a control point. Here’s how I control it:

/sys/class/leds/chg_en/brightness

This lets me toggle the charging on and off

I’m looking to further refine these scripts and maybe even bundle them into a Flatpak. My next goals are adding rtcwake for it to check after every 30 mins for notifications and battery level, and maybe control the battery cutoff via I2C but that will require some testing.

Feel free to contribute and let me know what you all think about it.

If someone has a better method or can suggest a better workaround for the Librem 5, I’m all ears.

Heads-up: This setup is still very much DIY. Make sure you really dig into the scripts before deploying them. If your phone turns into Charmander that is all on you!

Cheers!

12 Likes

You may be interested in controlling temperature and CPU/GPU frequencies:

2 Likes

Do you do the thing with multiple batteries? I have 5 batteries for my Librem 5 so I almost never charge the unit itself – whenever I need it, I just put a full battery in off of one of the chargers.

However, if I need to battery swap while the device is still on, for a “fast charge” as I joking call it, I do that by attaching power, ripping out the battery, putting the full battery in, and then unattaching from power. It takes about 3 seconds, but technically it means there was a momentary “short charging cycle” of a second or two for both the “before” and “after” battery. Do you suppose this negatively impacts the health of these batteries? Would your script prevent that?

1 Like

I have never heard this could be a problem. Can you provide more background on this?

1 Like

Swapping batteries is a great way to go if you don’t like having the charger or power bank connected most of the time. Personally, I just don’t like the hassle of replacing batteries regularly. As for the wear, no, I don’t think 3 seconds would have any significant effect since you’re just swapping. Should be totally fine as far as I can tell.

1 Like

The concern with short, unnecessary charge cycles mostly applies to situations where they happen frequently, like topping off a battery from 90% to 100% multiple times a day. While lithium-ion batteries are durable, minimizing those shallow cycles at reduce long-term wear.

Each time the charger reconnects, the battery’s charging circuit ramps up, creating additional strain. This frequent start-stop charging behavior can accelerate wear over time, especially if the battery is near full charge. So the script tries to avoid that.

1 Like

Will definitely give this a trial run.

2 Likes

Good to know! Thanks! I will give the script a try as well.

2 Likes

That would be an interesting task. Did you have something in mind that should be done when the mobile heats up? or just prevent it all together? Because I do blv that there would be less heating if the battery is not being charged.

2 Likes

I am reminded about all of the power optimizations Apple has done over the years to improve battery life on their product lines, with underclocking being the most notable practice before the ARM silicon transition.

Am I wrong to think that this only controls the LED charging light and not the actual charging functionality?

3 Likes

You are not. But the system is designed in this way. The red led is also connected to enable charge pin of BQ25895 (charge controller) and directly controls the charge

3 Likes

Also I have been testing it for a week works as intended :slightly_smiling_face:

2 Likes

I loaded this optimizing strategy on my Librem 5 and am pleased with the significant reduction in temperature of the phone when using it while listening to music while the phone is charging or when I’m using the browser when connected to the Nexdock. Previously, when performing these tasks, the phone would get very hot too touch and the charging LED would begin to flash. Now the phone’s temperature stays slightly above ambient temperature while charging and performing these tasks for hours at a a time. Excellent contribution alivellani. It would be nice if a similar strategy also be applied to the Librem 11. Thank you.

4 Likes

I’m happy to see people testing and enjoying it. I bought a small Anker Zolo power bank and attached it to the phone with Velcro tape. The power bank provides a constant power supply, while a script manages the battery by disabling charging at 90% and then running directly off the power source. This setup gives me a full day’s worth of battery, which I find quite handy.

I don’t own a Libre11 device; otherwise, I would have shared some scripts for that as well. :slightly_smiling_face:

1 Like

This seems excellent. I hope the two interactions of heat and power consumption/usetime get better with this.

I haven’t had time to try yet, so a usecase question: if it only resumes charging from 60%, but I have for example 70, but want to top off the batter to full to get through the day (when I know charging isn’t possible), I can’t get it to charge immediately and need to wait for it to drain? Is there a way to force charging (“I got 15mins before I have to go and I need all the power you can get in that time”)?

2 Likes

I’ve deployed @alivellani solution also and have been really happy. I’m finding that if I do need to charge back up as you mention @JR-Fi if I reboot it will reset the settings and start charging. Even if the 60% mark hasn’t been reached.

4 Likes

I had the same need and have developed a control app where you can run the following command to force charge enable or disable but needs some work as it only works if the battery is inside the higher and lower threshold bounds.

python3 control_battery.py enable/disable

As soon as I am done I will update github and post it here.
I should also update the documentation on how to stop the script gracefully but if someone wants a quick solution for now they can run this and reboot

systemctl disable manage_librem_battery.service

and when you want it to run again, you can

systemctl enable --now manage_librem_battery.service

2 Likes

or you could do this :grinning:

1 Like