profzei / Matebook-X-Pro-2018

💻 macOS on Huawei Matebook X Pro 2018
Apache License 2.0
364 stars 48 forks source link

Implementing battery thresholds #29

Open ldan93 opened 4 years ago

ldan93 commented 4 years ago

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.

profzei commented 4 years ago

@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 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

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

Have a merry christmas and happy new year btw!

ldan93 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

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 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

@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 commented 3 years ago

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

ldan93 commented 3 years ago

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 :

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

Some remarks :

profzei commented 3 years ago

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

Do you think it is possible implement a script?

ldan93 commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

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.

nekr0z commented 3 years ago

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 commented 3 years ago

@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 commented 3 years ago

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.

PLTorrent commented 2 years ago

@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 commented 2 years ago

@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 commented 2 years ago

@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 commented 2 years ago

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