Wrong Battery Charge Level Displayed - How to Fix
#1
Bug 
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.

I haven't found much discussion of this (though there was this: https://forum.pine64.org/showthread.php?tid=17056). Who else is seeing this?

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:

https://gitlab.freedesktop.org/upower/up...4d_236_242

Code:
    /* 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.
  Reply
#2
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):

Code:
$ sudo apk add glib-dev gobject-introspection-dev libgudev-dev libmobiledevice-dev gtk-doc
  • Now we can download the UPower source code:

Code:
$ git clone https://gitlab.freedesktop.org/upower/upower.git
  • 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  Wink , 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:

Code:
$ sudo mv /usr/libexec/upowerd /usr/libexec/upowerd.orig
$ sudo cp ./src/upowerd /usr/libexec/
$ sudo chmod +x /usr/libexec/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.
  Reply
#3
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...

Sad
  Reply
#4
(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...

Sad

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.
  Reply
#5
(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):

Code:
$ sudo apk add glib-dev gobject-introspection-dev libgudev-dev libmobiledevice-dev gtk-doc
  • Now we can download the UPower source code:

Code:
$ git clone https://gitlab.freedesktop.org/upower/upower.git
  • 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  Wink , 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:

Code:
$ sudo mv /usr/libexec/upowerd /usr/libexec/upowerd.orig
$ sudo cp ./src/upowerd /usr/libexec/
$ sudo chmod +x /usr/libexec/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.
  Reply
#6
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:

Code:
$ sudo mv /usr/libexec/upowerd /usr/libexec/upowerd.orig
$ sudo cp /home/mobian/upowerd /usr/libexec/
$ sudo chmod +x /usr/libexec/upowerd

For Manjaro, the directory is different:

Code:
$ sudo mv /usr/lib/upowerd /usr/lib/upowerd.orig
$ sudo cp /home/manjaro/upowerd /usr/lib/
$ sudo chmod +x /usr/lib/upowerd

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.


Attached Files
.zip   upowerd.zip (Size: 260.86 KB / Downloads: 78)
  Reply
#7
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.

Any chime-in would be much appreciated.
  Reply
#8
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.

Code:
batt1="$(cat /sys/class/power_supply/ip5xxx-battery/capacity)"
batt2="$(cat /sys/class/power_supply/axp20x-battery/capacity)"
batt3="= $(($batt1 + $batt2))%"
uptime="$(sudo tuptime | awk -F'=' '/System uptime:/ {print substr($2, 1, length($2)-3)}')"
weather="$(curl -s http://rss.accuweather.com/rss/liveweather_rss.asp\?metric\=${METRIC}\&locCode\=20902 \ | sed -n '/Currently:/ s/.*: \(.*\): \([0-9]*\)\([CF]\).*/\2°\3 \1/p')"
s="battery: $batt1% + $batt2% $batt3\n\nuptime: $uptime\n\nweather: $weather"
echo -e $s | gxmessage -file -


And that will produce, via gxmessage:


Code:
battery: 100% + 98% = 198%

uptime: 1d 0h 52m

weather: 64°F Partly Cloudy
  Reply


Possibly Related Threads…
Thread Author Replies Views Last Post
  Increasing battery life slondr 8 2,898 03-19-2024, 02:15 PM
Last Post: aular
  Genode OS Now Live (finally a battery friendly PP OS?) PineFone 0 1,464 02-04-2023, 09:38 AM
Last Post: PineFone
  Interested in learning OS-level programming 8453sixtyfour 6 6,317 04-30-2022, 05:10 PM
Last Post: TRS-80
  Megapixels 1.3.0 - colors feels wrong hashfactory 0 1,112 09-11-2021, 09:26 AM
Last Post: hashfactory
  Pine phone Battery life vs operating system bcnaz 19 21,208 08-27-2021, 09:35 PM
Last Post: bcnaz
  Battery Charge Status not reporting correctly? (KDE Community Edition) Gregorius Techneticies 11 8,708 02-12-2021, 01:01 PM
Last Post: Giddyup
  Battery life for various OS & UI lat 8 9,526 12-21-2020, 08:20 PM
Last Post: ryo
  Low Battery indication (Manjaro/PostmarketOS with phosh) MamlinAV 3 4,375 12-16-2020, 03:44 AM
Last Post: dukla2000
  theoretical battery life on Pinephone hiimtye 6 6,707 12-12-2020, 01:48 AM
Last Post: jmorris

Forum Jump:


Users browsing this thread: 1 Guest(s)