12-22-2022, 07:05 PM (This post was last modified: 12-26-2022, 11:59 AM by acid andy.)
I've been playing with flashing different versions of the PinePhone OSes and noticed that when I use versions updated in the last few months, the charge level displayed on the battery icon is now incorrect. I've seen this on both Mobian and PostmarketOS with Plasma mobile and Phosh.
More specifically, on my PinePhone it displays a quarter of the battery percentage it used to show.
In frustration, I took a look at the code and Phosh just pulls the charge level from upowerd for the "display" device which seems to be the right way to do it.
So, I went looking at the documentation and then the source code for the UPower daemon. Sure enough, the way the battery percentage is calculated was changed in July this year:
/* use percentage weighted for each battery capacity
* fall back to averaging the batteries.
* ASSUMPTION: If one battery has energy data, then all batteries do
*/
if (energy_full_total > 0.0)
percentage_total = 100.0 * energy_total / energy_full_total;
else
percentage_total = percentage_total / num_batteries;
That code after the "else" didn't used to be there, so it's probably what's dividing up the charge level to a fraction of what it should be on the PinePhone. The PinePhone seems to report multiple battery devices that have no charge, in addition to one that corresponds to what I would expect.
I'm not too sure what or who are at fault here - whether the PinePhone is reporting battery data in a non-standard or incomplete way, or if there's a bug in UPower, so not sure where to raise the issue.
I think I'm going to see how easy it is to compile a patched version of the UPower daemon, with that line after the "else" removed, to solve the issue on my PinePhone.
12-23-2022, 07:47 PM (This post was last modified: 12-23-2022, 11:11 PM by acid andy.)
I can confirm that commenting out that line of code in the UPower daemon results in the correct charge level being displayed again on my PinePhone.
To see if you need this fix, go into your Power settings and see how many batteries it displays. You'll probably see up to 4 of them. Unless you have the PinePhone keyboard connected, it's likely only one of them will show greater than 0% charge. This one is the actual charge level of your PinePhone's battery. The others seem to be little more than red herrings that confuse UPower!
If the displayed level of charge on the top tray is much lower than the one visible on the Power settings (If 4 batteries are shown, it may be exactly a quarter of it), and your distro isn't more than about 6 months old, then you most likely need the fix. If the two charge levels match up then you're all good. (Note: I have read that when the PinePhone keyboard's battery is connected it can actually read up to 200% - the fix I'm describing here won't stop that behavior, although to me in a way that makes sense when you have two real batteries connected).
I'll give you an outline of how I built the UPower daemon on my PinePhone. This was on postmarketOS but it should be similar on your distro, maybe with a different package manager.
First we need some tools to edit and build the code:
Code:
$ sudo apk add meson ninja gcc g++ cmake git nano
UPower has quite a few dependencies. I had to search for their package names when the build kept complaining they were missing. I don't have a full list of the commands I ran, so you may need some others (Let me know if you still get build errors and I may be able to help out):
Now, the fun part, we get to apply the patch, the old-fashioned way:
Code:
$ cd upower/src
$ nano up-daemon.c
You need to go to somewhere near line 249 where the following block of code is:
Code:
g_debug ("Calculating percentage and time to full/to empty for %i batteries", num_batteries);
/* use percentage weighted for each battery capacity
* fall back to averaging the batteries.
* ASSUMPTION: If one battery has energy data, then all batteries do
*/
if (energy_full_total > 0.0)
percentage_total = 100.0 * energy_total / energy_full_total;
else
percentage_total = percentage_total / num_batteries;
You need to comment out the "else" and the line that follows it:
Code:
g_debug ("Calculating percentage and time to full/to empty for %i batteries", num_batteries);
/* use percentage weighted for each battery capacity
* fall back to averaging the batteries.
* ASSUMPTION: If one battery has energy data, then all batteries do
*/
if (energy_full_total > 0.0)
percentage_total = 100.0 * energy_total / energy_full_total;
/* else
* percentage_total = percentage_total / num_batteries; */
In nano press Ctrl-X then Y then Return to save it.
Now we can try and set up our meson build directory:
Code:
$ cd ..
$ meson setup build
Read any error messages that come back here and correct them. For me, they were all about missing dependencies which meant installing the corresponding packages.
If your OS isn't using systemd , it might say something like "ERROR: Dependency "systemd" not found, tried pkgconfig and cmake".
To disable the systemd dependency, we need to do:
Code:
$ nano ./meson_options.txt
Find the section:
Code:
option('systemdsystemunitdir', type : 'string', description : 'Directory for systemd service files ("no" to disable)')
And add a line saying "value : 'no',":
Code:
option('systemdsystemunitdir', type : 'string', value : 'no', description : 'Directory for systemd service files ("no" to disable)')
Ctrl-X then Y then Return again to save it.
Then you can try again:
Code:
$ meson setup build
Once the build setup completes successfully we can try and compile UPower:
Code:
$ cd build
$ meson compile
If you got that far, congratulations, we should be nearly done. After carefully backing up your system, you could try and use ninja to fully install UPower (In which case you may find it wants to put everything under /usr/local/ instead of just /usr/ which may need a prefix configuring), but instead I just found the "upowerd" executable it had built - strangely inside build/src - and copied that into /usr/libexec after first renaming my original upowerd:
Cross your fingers, reboot, and hopefully your PinePhone still boots and even better the indicated charge level should be accurate again! If something broke, you need to reinstate the backup copy of /usr/libexec/upowerd that you made. If it's on an SD card, you could boot off your eMMC or put the card in another computer to fix it. If it's on the eMMC, boot off an SD card and fix it on the phone.
Good luck. I'd love to hear from anyone who attempts this and may be able to offer help if you get stuck with the build. Not many people are talking about this issue so it would be great to gauge how many are affected so we can look at who to talk to about a more permanent fix either in the PinePhone distros or UPower.
I accept no responsibility for any loss or damage resulting from the use of what I've written here. You could break your phone. Be careful and take backups.
I'm puzzled why there are 121 views and still no replies.
Are people not responding because their battery level display works fine on recent Phosh? If so, I need to know so I can work out why it's only going wrong on my device.
Or do people not really use this forum much anymore? I'm not really into Discord...
(12-29-2022, 07:59 AM)acid andy Wrote: I'm puzzled why there are 121 views and still no replies.
Are people not responding because their battery level display works fine on recent Phosh? If so, I need to know so I can work out why it's only going wrong on my device.
Or do people not really use this forum much anymore? I'm not really into Discord...
That's a fair question.
I've been using Arch Linux and have noticed sometimes it charges to 99% , sometimes to 95% and sometimes to 93% (and then to 99% if I unplug & then plug it back in ), but I'm focusing on other things for the next few weeks and am not fiddling with the Pine Phone.
(12-23-2022, 07:47 PM)acid andy Wrote: I can confirm that commenting out that line of code in the UPower daemon results in the correct charge level being displayed again on my PinePhone.
To see if you need this fix, go into your Power settings and see how many batteries it displays. You'll probably see up to 4 of them. Unless you have the PinePhone keyboard connected, it's likely only one of them will show greater than 0% charge. This one is the actual charge level of your PinePhone's battery. The others seem to be little more than red herrings that confuse UPower!
If the displayed level of charge on the top tray is much lower than the one visible on the Power settings (If 4 batteries are shown, it may be exactly a quarter of it), and your distro isn't more than about 6 months old, then you most likely need the fix. If the two charge levels match up then you're all good. (Note: I have read that when the PinePhone keyboard's battery is connected it can actually read up to 200% - the fix I'm describing here won't stop that behavior, although to me in a way that makes sense when you have two real batteries connected).
I'll give you an outline of how I built the UPower daemon on my PinePhone. This was on postmarketOS but it should be similar on your distro, maybe with a different package manager.
First we need some tools to edit and build the code:
Code:
$ sudo apk add meson ninja gcc g++ cmake git nano
UPower has quite a few dependencies. I had to search for their package names when the build kept complaining they were missing. I don't have a full list of the commands I ran, so you may need some others (Let me know if you still get build errors and I may be able to help out):
Now, the fun part, we get to apply the patch, the old-fashioned way:
Code:
$ cd upower/src
$ nano up-daemon.c
You need to go to somewhere near line 249 where the following block of code is:
Code:
g_debug ("Calculating percentage and time to full/to empty for %i batteries", num_batteries);
/* use percentage weighted for each battery capacity
* fall back to averaging the batteries.
* ASSUMPTION: If one battery has energy data, then all batteries do
*/
if (energy_full_total > 0.0)
percentage_total = 100.0 * energy_total / energy_full_total;
else
percentage_total = percentage_total / num_batteries;
You need to comment out the "else" and the line that follows it:
Code:
g_debug ("Calculating percentage and time to full/to empty for %i batteries", num_batteries);
/* use percentage weighted for each battery capacity
* fall back to averaging the batteries.
* ASSUMPTION: If one battery has energy data, then all batteries do
*/
if (energy_full_total > 0.0)
percentage_total = 100.0 * energy_total / energy_full_total;
/* else
* percentage_total = percentage_total / num_batteries; */
In nano press Ctrl-X then Y then Return to save it.
Now we can try and set up our meson build directory:
Code:
$ cd ..
$ meson setup build
Read any error messages that come back here and correct them. For me, they were all about missing dependencies which meant installing the corresponding packages.
If your OS isn't using systemd , it might say something like "ERROR: Dependency "systemd" not found, tried pkgconfig and cmake".
To disable the systemd dependency, we need to do:
Code:
$ nano ./meson_options.txt
Find the section:
Code:
option('systemdsystemunitdir', type : 'string', description : 'Directory for systemd service files ("no" to disable)')
And add a line saying "value : 'no',":
Code:
option('systemdsystemunitdir', type : 'string', value : 'no', description : 'Directory for systemd service files ("no" to disable)')
Ctrl-X then Y then Return again to save it.
Then you can try again:
Code:
$ meson setup build
Once the build setup completes successfully we can try and compile UPower:
Code:
$ cd build
$ meson compile
If you got that far, congratulations, we should be nearly done. After carefully backing up your system, you could try and use ninja to fully install UPower (In which case you may find it wants to put everything under /usr/local/ instead of just /usr/ which may need a prefix configuring), but instead I just found the "upowerd" executable it had built - strangely inside build/src - and copied that into /usr/libexec after first renaming my original upowerd:
Cross your fingers, reboot, and hopefully your PinePhone still boots and even better the indicated charge level should be accurate again! If something broke, you need to reinstate the backup copy of /usr/libexec/upowerd that you made. If it's on an SD card, you could boot off your eMMC or put the card in another computer to fix it. If it's on the eMMC, boot off an SD card and fix it on the phone.
Good luck. I'd love to hear from anyone who attempts this and may be able to offer help if you get stuck with the build. Not many people are talking about this issue so it would be great to gauge how many are affected so we can look at who to talk to about a more permanent fix either in the PinePhone distros or UPower.
I accept no responsibility for any loss or damage resulting from the use of what I've written here. You could break your phone. Be careful and take backups.
Hi,
I just got my pinephone and keyboard last week and had exactly this problem. I followed your build process and now the battery shows upto 200%, before it was always upto 65%.
Thats was really super helpfull. Thank you so much for this!
I'am on the latest postmarketOS phosh version.
I still have an issue that percentage is not displayed correct when I turn off the keyboard battery. So when I start the phone with the keyboard battery off. It shows 100% (phone is fully charged) When I then turn the keyboard battery on it shows 180% (keyboard is almost fully charged) but when I turn the keyboard battery off it stays at 180%. One small issue is also that the Battery symbol is broken when keyboard battery is on.
Many thanks, @acid andy Your research and work solved a tough problem.
For Mobian and Manjaro Phosh, I had a difficult time compiling upowerd (I'm generally terrible at compiling), starting with the issue that the compiling programs/libs have different names in Debian and Manjaro. But I finally got to the end and the attached upowerd runs successfully on both my Debian and Manjaro setups.
As acid andy already warns, it is very important to back up your original upowerd. Then, operating on assumption that compiled upowerd is in your home directory, move the file. In Mobian:
If the compiled upowerd doesn't work, the fallout is non-fatal: slow boot, no access to Settings, question mark in place of battery percentage. Just delete the compiled upowerd, rename the saved original back to upowerd, and reboot.
Again, hats off to acid andy, and I hope the attached upowerd saves people some hassle, but buyer beware and all that.
With Manjaro Beta Phosh Ver. 33, this compiled upowerd now fails. Somehow, the version update has borked it. Furthermore, https://gitlab.freedesktop.org/upower/upower.git has not been updated recently, so I don't believe a recompile would result in a working pp/kb battery gauge.
06-12-2023, 01:04 PM (This post was last modified: 06-12-2023, 01:06 PM by jakfish.)
Here's a temporary workaround as long as you have gxmessage installed (and tuptime, if you want an accurate uptime between boots). For US weather, enter your own zipcode.