Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Implementing battery thresholds #29

Open
ldan93 opened this issue Jun 28, 2020 · 25 comments
Open

Implementing battery thresholds #29

ldan93 opened this issue Jun 28, 2020 · 25 comments
Labels
documentation Improvements or additions to documentation enhancement New feature or request

Comments

@ldan93
Copy link

ldan93 commented Jun 28, 2020

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 (nekr0z/linux-on-huawei-matebook-13-2019#2 (comment)).

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.

@profzei
Copy link
Owner

profzei commented Jun 30, 2020

@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!

@wiregen
Copy link

wiregen commented Sep 17, 2020

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.

@profzei
Copy link
Owner

profzei commented Sep 20, 2020

@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!

@samwzlim
Copy link

samwzlim commented Dec 2, 2020

@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
Copy link

@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
Copy link

@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!

@ldan93
Copy link
Author

ldan93 commented Dec 27, 2020

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).

@samwzlim
Copy link

@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 😅

@ldan93
Copy link
Author

ldan93 commented Dec 29, 2020

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.

@wiregen
Copy link

wiregen commented Dec 29, 2020

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%

@samwzlim
Copy link

@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?

@ldan93
Copy link
Author

ldan93 commented Dec 30, 2020

@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.

@profzei
Copy link
Owner

profzei commented Jan 2, 2021

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

@ldan93
Copy link
Author

ldan93 commented Jan 5, 2021

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.

@profzei
Copy link
Owner

profzei commented Jan 5, 2021

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

Do you think it is possible implement a script?

@ldan93
Copy link
Author

ldan93 commented Jan 5, 2021

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

@profzei
Copy link
Owner

profzei commented Jan 6, 2021

@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!

@ldan93
Copy link
Author

ldan93 commented Jan 6, 2021

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.

@profzei profzei added documentation Improvements or additions to documentation enhancement New feature or request labels Jan 16, 2021
@nekr0z
Copy link

nekr0z commented Jan 17, 2021

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...

@profzei
Copy link
Owner

profzei commented Jan 17, 2021

@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?

@nekr0z
Copy link

nekr0z commented Jan 18, 2021

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.

@profzei profzei pinned this issue Feb 3, 2021
@PLTorrent
Copy link

PLTorrent commented Oct 22, 2021

@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
Copy link

@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 ;]

@profzei
Copy link
Owner

profzei commented Oct 23, 2021

@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...

@BigEmperor26
Copy link

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
documentation Improvements or additions to documentation enhancement New feature or request
Projects
None yet
Development

No branches or pull requests

7 participants