Matebook-X-Pro-2018 icon indicating copy to clipboard operation
Matebook-X-Pro-2018 copied to clipboard

Implementing battery thresholds

Open ldan93 opened this issue 4 years ago • 25 comments

First, thank you for your great work !

There is one feature of our Matebook that I miss from Windows/Linux : setting battery thresholds.

What is it ?

When you use your laptop plugged in the AC power for a long time, it’s healthier to keep your battery mid-charged. So, if you rarely use your Matebook in battery mode, setting a threshold greatly increases your battery’s lifespan in the long-run.

How does it work ?

There is a minimum and a maximum values stored inside the Embedded Controller (EC) within the ACPI tables. For example, if you set it to 50 / 60, your battery will charge up to a value between 50% and 60% and then, the computer will only drain power from AC, letting your battery idle.

Under Windows, this feature is handled by Huawei’s built-in « PC Manager ». Under Linux, it has been implemented through scripts writing custom values to the EC tables (https://github.com/nekr0z/linux-on-huawei-matebook-13-2019/blob/master/batpro) or through cleaner ACPI methods (https://github.com/aymanbagabas/Huawei-WMI).

How can we make it work under MacOS ?

From what I understand from nekr0z’s script, to implement this feature, all we have to do it to write the minimum and maximum thresholds to the 0xe4 and 0xe5 registries of the EC’s tables (https://github.com/nekr0z/linux-on-huawei-matebook-13-2019/issues/2#issuecomment-483827901).

People successfully implemented this feature for other laptop brands using RehabMan’s kext OS-X-ACPI-Poller (https://github.com/RehabMan/OS-X-ACPI-Poller). An example with Lenovo laptops : https://www.insanelymac.com/forum/topic/342280-battery-charge-thresholds-and-related-controls/

This method seems to be very similar to RehabMan’s approach to controlling fans through custom EC values : https://www.tonymacx86.com/threads/new-fan-control-dsdt-for-silent-fan-at-higher-temps.72043/

I’ve spent some time collecting all of the useful details, but actually implementing this feature for the Matebook X Pro is way beyond my personal abilities… ATM, I use a Linux USB installation to set the threshold from there, and I then reboot to MacOS. But this is far from convenient, and the values get reset from time to time…

I think adding this feature to your guide would be very nice and useful for many users. Would you be interested to have a look at it ? Even though I’m a total beginner with Hackintosh, I would do my best to help you, of course.

ldan93 avatar Jun 28 '20 10:06 ldan93

@ldan93 I didn't think it was possible! Definitely worth a try ... as soon as I have a moment of time I start studying the material you have shared. Thanks a lot also for the willingness to collaborate, certainly accepted!

profzei avatar Jun 30 '20 13:06 profzei

On my macbook pro 16 I use the Al Dente App. https://github.com/davidwernhart/AlDente this way I can keep my battery at 70% since I have it mostly docked to my monitor. I tried this program on the MateBook Pro X. Unfortunately, it doesn't work.

wiregen avatar Sep 17 '20 00:09 wiregen

@wiregen : Hi, the app seems very interesting! Have you tried disabling ACPIBatteryManager.kext and enabling SMCBatteryManager.kext in config.plist? If the app works with this change, you need to remember that SMCBatteryManager.kext is, at the moment, related to clamshellStateChanged... issue!

profzei avatar Sep 20 '20 22:09 profzei

@profzei It doesn't work :( I tried the changes that you suggested but AlDente still doesn't work. As soon as I change the charge threshold, it returns to 3 immediately (the default value)

samwzlim avatar Dec 02 '20 05:12 samwzlim

@wiregen Have you got it to work? For the longest time, I have been trying to implement battery charge thresholds on my mbxp hackintosh

samwzlim avatar Dec 24 '20 09:12 samwzlim

@profzei I hope you can look into this matter at your availability because with everyone now WFH (and for the forseeable future), setting battery charge thresholds is a godsend. I can literally plug my laptop in the whole day somewhere between 30-80% and not worry about battery degradation (albeit temperature is smth to monitor).

What I've tried but failed:

  • Disabling ACPIBatteryManager.kext and enabling SMCBatteryManager.kext in config.plist. No effect upon using various charge threshold apps for macos, namely AlDente, battery charge limiter

  • Turning on battery protection under PC Manager on Windows 10, however, upon booting into macos, the charge thresholds are no longer active (the weird thing is that it the charge thresholds stay active on macos sometimes, but very rarely)

Have a merry christmas and happy new year btw!

samwzlim avatar Dec 24 '20 09:12 samwzlim

In order to implement this feature, we need to find a way to modify the 0xe4 and 0xe5 registries of the EC’s tables from MacOS... From my limited understanding of the documentation I read, an ACPI method could be the way to go, but I don't know how to implement it.

About apps such as Aldente or the native MacOS "Battery Health management feature" : I guess they cannot work before we cleanly implement this feature with a dedicated kext. @zhen-zen achieved to implement battery threshold in YogaSMC.kext for some Lenovo laptops. I have no idea how to transpose this work to our Matebook, maybe we could ask him for some advice ?

EDIT : @samwzlim : what you can do ATM is setting up a Linux USB live key (for example Ubuntu 20.10). From Linux, inside a terminal, use this command : echo 45 55 | sudo tee /sys/devices/platform/huawei-wmi/charge_control_thresholds

(In my example, the battery stops charging between 45 and 55%. Of course you can change these values.)

This persists across reboots. However, when the Matebook is unplugged, it tends to "forget" this setting. This is quite annoying... But when the laptop is constantly plugged in, the setting is consistent (from my observations).

ldan93 avatar Dec 27 '20 15:12 ldan93

@ldan93 thanks for your reply! unfortunately, i don't have linux installed on my mbxp or any linux machines near me, so I can't do what you suggested me to do. Are there any alternatives? About what you mentioned above that, I am completely clueless as to how that would work 😅

samwzlim avatar Dec 29 '20 15:12 samwzlim

You don't need a Linux machine to set up a Linux USB Key. Under Windows, you can use Rufus to create such a key. Then boot to that usb device to access a Linux environnement.

ldan93 avatar Dec 29 '20 15:12 ldan93

I found something interesting. So I went into windows and in the Matebook PC Manager I set the battery limit. I restarted into MacOS BigSur and my Mac wouldn't charge past 50%. It seems like this modifies the bios I believe and limits the charging systemwide.

Downside is if you restart it goes back to charging to 100%

wiregen avatar Dec 29 '20 17:12 wiregen

@wiregen I tried doing that but it doesn't work most of the time. Did you just boot into windows, set the battery limit in PC Manager and restarted into macos?

samwzlim avatar Dec 30 '20 02:12 samwzlim

@profzei

After some digging into the code of Huawei WMI, I can identify the ACPI methods related to Battery Protection : Capture d’écran 2020-12-30 à 15 17 16

So, reading the thresholds must be done with \GBTT, and setting new thresholds with \SBTT.

Indeed, these two methods are present in our DSDT :

Capture d’écran 2020-12-30 à 15 20 39

I will try to see what would be the next steps, i.e. how to call these methods with RehabMan's OS-X-ACPI-Debug, OS-X-ACPI-Poller, and ioio kexts/utilies.

ldan93 avatar Dec 30 '20 14:12 ldan93

@ldan93 Great! Please, share your results here! Atm, I'm quite busy with fixing other aspects for our MBXP...

profzei avatar Jan 02 '21 13:01 profzei

Great news : I found a way to trigger battery protection from MacOS. It's not a very elegant implementation, but it works.

  1. You need ACPI Debug in the kext folder + enabled in config.plist
  2. You need this SSDT-RMDT.aml in the ACPI folder + enabled in config.plist : SSDT-RMDT.aml.zip
  3. You need the ioio utility

From the terminal with ioio (in the "Release" folder), you can call the following commands :

  • ./ioio -s org_rehabman_ACPIDebug dbg1 5 : set thresholds to 40-60%
  • ./ioio -s org_rehabman_ACPIDebug dbg2 5 : set thresholds to 60-80%
  • ./ioio -s org_rehabman_ACPIDebug dbg3 5 : set thresholds to 80-90%
  • ./ioio -s org_rehabman_ACPIDebug dbg0 5 : disable battery protection
  • ./ioio -s org_rehabman_ACPIDebug dbg4 5 : display the current thresholds (in hexadecimal numbers) (in the logs, not in the Terminal)

You can check if the commands are effective by reading the logs in Console.app : search for "ACPIDebug" while you use ioio

Some remarks :

  • There is a slight difference between the way MacOS display battery percent in battery applet indicator and this utility. Ex : the 80% threshold set with ioio actually corresponds to 84% in MacOS menu bar.
  • From my observation, when you set a protection mode, the laptop keeps charging up to the upper threshold before actually enabling the battery protection mode.

ldan93 avatar Jan 05 '21 06:01 ldan93

@ldan93 Thank you very much for your work and detailed explanation!

Do you think it is possible implement a script?

profzei avatar Jan 05 '21 17:01 profzei

Of course ! Please find attached a basic script implementing these features with a picker : Capture d’écran 2021-01-05 à 20 20 14

battery_thresholds.sh.zip

The script expects ioio to be in /Applications/Utilities/ Don't forget to set ioio and the script as executable

ldan93 avatar Jan 05 '21 19:01 ldan93

@ldan93 Great contribution for our Matebook X Pro! I'll test it asap and probably I'll link it in next release (probably in the weekend) where I share all my under cover work!

profzei avatar Jan 06 '21 15:01 profzei

Cool !! Let me know if everything is working as expected on your side. I'm looking forward to seeing it upstreamed in a coming release !

I'm sure there are better ways to implement this. A nice icon in MacOs menu bar would be awesome, but atm this script should do the trick. I'll continue investigating the topic and let you know if I make any progress.

ldan93 avatar Jan 06 '21 16:01 ldan93

I may be really wrong here, since I have no experience with MacOS to speak of, but if

  1. there's a command (or a set of commands) that can be used to set the battery thresholds, and
  2. there's a command (or a set of commants) that can be used to get those thresholds as a terminal output (in any capacity, decimal, hex, binary, whatever), and
  3. there's at least one person willing to assist with debugging (since I don't have MacOS),

then I think making matebook-applet work on MacOS is an endeavour I might be willing to undertake in my spare time...

nekr0z avatar Jan 17 '21 14:01 nekr0z

@nekr0z This is a great news!

if there's at least one person willing to assist with debugging

I'm the maintainer of this repo, I'm not a "real" developer, I'm not a student (so I have a job and related duties) but I would like to assist with debugging in my spare time! Maybe also @ldan93 who wrote and tested his actual script?

profzei avatar Jan 17 '21 14:01 profzei

I'm not a "real" developer, I'm not a student (so I have a job and related duties) but I would like to assist with debugging in my spare time!

Don't worry, neither am I. Believe it or not, I teach medicine for living.

I have opened a specific issue for that so as not to clutter your repo and this issue with tangentially related things. Anybody with any relevant skills/craft/knowledge/time (even if just a little) is welcome to participate.

nekr0z avatar Jan 18 '21 06:01 nekr0z

@profzei

Did someone manage to actually implement this? What is currently the best way to set battery protection?

Also as this seems to be ACPI setting maybe it would be possible to set it in config.plist. I guess most users just use one scheme most of the time like home (40-70) or office (70-90)?

PLTorrent avatar Oct 22 '21 15:10 PLTorrent

@profzei et al.

I have just implemented quick and a bit dirty way of activating battery thresholds for MBXP. Using the directions and tips from this thread I created a small ACPI patch to activate battery saving thresholds during system startup. Obviously it is not an interactive solution as changing thresholds is a bit of work, but does not require installing ACPI Debug Kext. From my experience I usually just set family mode (40-70) and use it all the time, hence limited need for changing the setting in my case.

In case one wants to use 40-70 thresholds all you have to do is to copy SSDT-BATTHR.aml from SSDT-BATTHR.zip to EFI->OC->ACPI and add it to ACPI -> Add in your config.plist. Next restart the system and thresholds are applied.

If you want to change the thresholds grab a copy of MaciASL from here: https://github.com/acidanthera/MaciASL/releases and open SSDT-BATTHR.dsl from the SSDT-BATTHR.zip and change the thresholds here:

// Set Battery threshold to 0xXX - 0xYY: /SBTT(0xYYXX0000)
\SBTT (0x46280000)

Thresholds should be converted to hex i.e. 20-65 would be 0x14-0x41 so it gives 0x41140000 and we put it into code:

// Set Battery threshold to 0xXX - 0xYY: /SBTT(0xYYXX0000)
\SBTT (0x41140000)

Then save it as ACPI Machine Language Binary (aml) and the rest is the same, i.e. copy to EFI -> OC -> ACPI and add to config.plist and the reboot.

Let me know if this works for you ;]

PLTorrent avatar Oct 23 '21 14:10 PLTorrent

@PLTorrent Thank you for your contribution!

What you provided is very similar to what I wrote more than one year ago just for myself... Why did I not share, in a such case, my work within my repo? Since it is a static and rough solution (as you said...) which however fits very well my needs... probably not others... and I really didn't want to hear all related (possible) complaints!

A very elegant solution, instead, was proposed by @ldan93 i.e. porting on macOS Matebook-applet project, but, as you said, it is complicated making it very clean! Knowledge for programming in macOS is required...

profzei avatar Oct 23 '21 17:10 profzei

Does your code work without reboot ? If that is the case I could make a simple GUI for it.

BigEmperor26 avatar Feb 21 '22 11:02 BigEmperor26