zackelia / bclm

macOS command-line utility to limit max battery charge
MIT License
1.9k stars 92 forks source link

keyNotFound(code: "CHWA") #49

Open Tackoil opened 3 months ago

Tackoil commented 3 months ago

After updating the macOS 15.0 beta 5, bclm is not working well. Running read or write will get an error (maybe) following.

keyNotFound(code: "CHWA")

I know that using the beta version of macOS is my own risk. Creating this issue is just for a notice about this change.

antoinelibert commented 1 month ago

Hello,

Unless Apple has since reverted the changes in a beta version of macOS 15.1, there's little the author can do. The bclm feature is solely dependent on a specific flag in the Mac's battery management hardware, which Apple has removed. The 80% limit is a hardware-handled feature.

There are alternative ways to recreate the 80% limit using software (see the tools listed earlier). Since they're software-based, they may not be as optimal during sleep, but some implementations are still effective. I've switched to Battery-Toolkit, which appears to be the most advanced and stable option, utilizing events instead of loops, handling wake and sleep events, offering an optional GUI, and actively maintained.

yuukiyuuna commented 1 month ago

Hello,

Unless Apple has since reverted the changes in a beta version of macOS 15.1, there's little the author can do. The bclm feature is solely dependent on a specific flag in the Mac's battery management hardware, which Apple has removed. The 80% limit is a hardware-handled feature.

There are alternative ways to recreate the 80% limit using software (see the tools listed earlier). Since they're software-based, they may not be as optimal during sleep, but some implementations are still effective. I've switched to Battery-Toolkit, which appears to be the most advanced and stable option, utilizing events instead of loops, handling wake and sleep events, offering an optional GUI, and actively maintained.

OK, thank you. I will try to use Battery-Toolkit as well. But I really hope Apple will restore this specific flag.

Jerrykooo commented 1 month ago

same issue on macos 12.7.6

zackelia commented 4 weeks ago

I took a look at this again now that macOS 15.1 is out, but still the same issue.

With some more experimentation, I am highly confident that com.apple.private.applesmc.user-access is in fact the required entitlement. I used dyld interposing on /usr/sbin/systemstats which has that entitlement and I could successfully read/write CHLS (albeit with SIP disabled so this isn't too viable anyways).

Like others in this issue mentioned for older versions of macOS, writing values such as 0x0150 didn't seem to have any effect on the battery. I looked over the Asahi driver code some more but it's not obvious to me that we're doing something wrong. If anybody is able to glean any more insights on the older versions of macOS I'd be curious to hear.

PiterrsPl commented 3 weeks ago

https://github.com/lslqtz/bclm_loop/tree/main > > Fork BCLM o nazwie BCLM_Loop, który mogę potwierdzić, działa na wydaniu Sequoia 15.0. Instaluje się i można go włączyć w taki sam sposób jak oryginalny BCLM. > > Pod maską może nie być tak czysty lub elegancki jak oryginalny BCLM, ponieważ działa w pętli jako usługa w tle (w przeciwieństwie do pisania do SMC), ale nadal wykonuje pracę w 100%, o ile mogę powiedzieć do tej pory, bez wpływu na żywotność baterii po odłączeniu zasilania. > > Nadal jednak mam nadzieję, że oryginalny BCLM może zostać naprawiony.

https://github.com/lslqtz/bclm_loop/tree/main Fork of BCLM called BCLM_Loop which I can confirm does work on Sequoia 15.0 release. It installs and can be enabled pretty much in the same fashion as the original BCLM. Under the hood it may not be as clean or elegant as the original BCLM as it runs in a loop as a background service (as opposed to writing to the SMC), but it still does the job 100% as far as I can tell so far with no impact on battery life when unplugged. Still hoping the original BCLM can be fixed though.

hi i have one question how to install this fork ? because its not so easy like using brew. please help me because I have spend few hours to install this fork and I have no idea how to do this .. my Mac is with m1 procesor

hi there is new release from bclm_loop how can I update this version ?

zship commented 3 weeks ago

Like others in this issue mentioned for older versions of macOS, writing values such as 0x0150 didn't seem to have any effect on the battery.

Just to double-check: are you saying that writing 0x0150 to CHLS had no discernible effect on macOS 15.1? Or on an older version?

Reason I ask is because I'm willing to jump through the same hoops as you (disable SIP, dyld interposing) if it works. Want to confirm before going down the rabbit-hole though, since I'm currently unfamiliar with dyld interposing. Thanks for your experimentation and reporting the results!

zackelia commented 3 weeks ago

@zship This was me running on 15.1. I have the code that does the dyld interposing so really it's just turning off SIP to test it out. If people wanted to look more at the SMC values, I could put a branch up that's capable of that at least.

zship commented 3 weeks ago

I'd definitely be interested. Have some time to experiment, too. I have some (small) context here FWIW: implemented a basic "calibration" script which writes CH0I/CH0C values and I have some idea of how those (used to) interact with CHWA.

If you manage to get some time to push your dyld interposing code, I'm sure that would be a great help! Even a gist or a separate work-in-progress/not-fully-working repo would likely be useful IMO, but whatever makes sense for you if/when you get time.

Would be happy to take measurements and report findings, if useful.

zackelia commented 2 weeks ago

@zship and others - I pushed an experimental repo for SMC testing on Seqouia: https://github.com/zackelia/smc-interpose

pencilcheck commented 1 week ago

wait, so bclm will start working by following the experimental repo? or is it still not?

zship commented 6 days ago

Short answer: no, as it is now the experimental script does not prevent the battery from charging past the 80% threshold.

Sorry, got busy again! I did manage to do one test run. The script appears to have set CHLS to 150 (80%) as intended, but my battery charged to 100% anyway. Planning to experiment with more CHLS values when I get a chance (which I think was the purpose of the experimental repo, thanks zackelia!).

A couple details of the test run I did on an M3 Macbook Pro, if helpful:

# battery is charged to 70%
$ pmset -g batt
Now drawing from 'AC Power'
 -InternalBattery-0 (id=21102691)       70%; AC attached; not charging present: true

# read CH0I and CH0C. CH0I=00 and CH0C=01 indicates "inhibit charging"
$ smc -k CH0I -r
  CH0I  [ui8 ]  0 (bytes 00)
$ smc -k CH0C -r
  CH0C  [hex_]  (bytes 01)

# run zackelia's experimental script (sets CHLS to 150/"80%")
$ DYLD_INSERT_LIBRARIES=./build/libsmc.dylib systemstats -h
1 80

# set CH0I and CH0C to the default values, indicating "auto"/"charge if needed"
$ sudo smc -k CH0I -w 00
$ sudo smc -k CH0C -w 00

# poll the battery percentage every minute
$ while true; do pmset -g batt; sleep 60; done
# above while loop is simplified... I actually processed the output a bit.
# (Mode=auto indicates CH0I=00, CH0C=00)
[2024-11-13 10:13:10] Percentage=70% Mode=auto
[2024-11-13 10:14:10] Percentage=71% Mode=auto
[2024-11-13 10:15:10] Percentage=72% Mode=auto
[2024-11-13 10:16:10] Percentage=73% Mode=auto
[2024-11-13 10:17:10] Percentage=74% Mode=auto
[2024-11-13 10:18:10] Percentage=75% Mode=auto
[2024-11-13 10:19:11] Percentage=76% Mode=auto
# ... continued to increment ...
[2024-11-13 10:53:13] Percentage=100% Mode=auto
[2024-11-13 10:54:13] Percentage=100% Mode=auto
# ... kept monitoring for a while just in case ...
# still at 100% after 2 hours
[2024-11-13 12:51:22] Percentage=100% Mode=auto
noszti commented 3 days ago

I have recently updated to MacOS 14.7.1 (from 14.5 (I think)) and experienced the “keyNotFound(code: "CHWA”): Searching that lead to me to this github thread. So I am using smc to manually set these values and switching to using the “CHLS” seems to have worked, but it seems like just a little too well, e.g. after:

$ sudo smc -k CHLS} -w 0150

My MacBook Pro (M3) only charges to 80%. However setting the value back to “0000”:

$ sudo smc -k CHLS} -w 0000

Seems to not revert the change (i.e. still stuck at max 80%).

I also tried setting 0164 (thinking that might be for 100%) but that does not do anything either (stuck at 80%) (Note that I did read the CHLS value before I started all this and it was 0000)

[edit]:

I t looks to me now all the above behavior (and anything else I reported below) seems to not have anything to do with CHLS values and is very likely the "heuristics" implemented by the "Optimized Battery Charging" setting of the OS. For example it now decided to charge to 100% (even though I have my MacBook on the power adapter pretty much constantly). And no value I set in CHLS seems to change that. (I guess I have not tried turning off optimized charging and seeing if that could make a difference wrt. CHLS values...)

zackelia commented 3 days ago

Interesting, I'll have to look more at macOS 14.7 to mess with CHLS.

Regarding your charge limit issues, rebooting should clear the SMC and fix your issue.

noszti commented 3 days ago

So it seemed like my Macbook (after messing with the "CHLS" values) was not charging at all (i.e. when I unplugged it (at the 80% it was holding the charge at) it went down to ~68% and when I plugged it back in it just held at that 68% instead of charging. Fortunately rebooting cleared this mode and started charging again. Also since the "Optimized Battery Charging" mode is enabled currently (should it be? Not sure if I had it that way or the update to 14.7 enabled it?) after the reboot and not messing with any SMC settings it did stop at 80% (with the drop down menu saying "will be charged by 1:30"). So not sure how my earlier setting CHLS to 0150 interfered with that exactly?

From what I recall with Sonoma 14.5 I had no issues, e.g. when I set CHWA to 01 it set the maximum charge at 80% and was charing fine when it was lower (although I did have to reset CHWA to 01 after every reboot - fortunately I did not reboot that often). And when I set it to 00 it charged to 100% without having to reboot. And if at 100% setting CHWA to 1 automatically discharged the battery until it reached 80%. Would be nice to have that behavior back.

Certainly there seem to lots of knobs/switches that could affect the behavior...