Battery-Toolkit icon indicating copy to clipboard operation
Battery-Toolkit copied to clipboard

When Battery Falls Below Charge Threshold, Power Adapter Does Not Auto-Enable

Open JohnGaver opened this issue 2 years ago • 37 comments

Here's my issue:

  1. Disable power adapter.
  2. Set battery charge threshold to 20%.
  3. Initiate battery consuming activity to drain battery.
  4. Battery is allowed to deplete to 0% and does not charge when it falls below 20%.

Is there a way to programmatically (or via the CLI) enable the power adapter when battery falls below the specified threshold?

This would fully address my concern. Thank you!

JohnGaver avatar Dec 09 '23 09:12 JohnGaver

Hmm. I’d say this behaviour is expected, but I understand why you’d want to automatically re-enable. If you want to, you could PR a GUI toggle to do this - I think the different PM functions are abstracted enough to easily implement this.

EDIT: Thinking of it, this requires keeping the percentChange event live when the power adapter is disabled. It’s usually disabled whenever the device is on battery. Keeping it live must not happen when on battery and the power adapter is enabled. Especially the edge-case of re-enabling the adapter and still being on battery must be considered. Other than that, it should be trivial. However, note that when the system goes to sleep with the power adapter disabled (there is another setting you can toggle), the event will not fire and the battery may deplete regardless.

mhaeuser avatar Dec 09 '23 10:12 mhaeuser

Sounds like that's exactly what I need, but I'm hardly fluent enough in Xcode to do that. Any chance you might be able to help out for a $100 tip per the project post here? No need to use Lazarus and just making this change in your existing app would suffice: https://www.upwork.com/jobs/~0116061a05654cb78e

JohnGaver avatar Dec 09 '23 12:12 JohnGaver

Manually toggling the power adapter on, I notice it requests elevation also. However, the Mac does not sleep, which is great (per your warning on the main page, which I suppose does not apply to this particular case). I wouldn't mind running the tool elevated permanently to work around the manual elevation issue for the helper tool it uses. The whole goal being automation, manual elevation would defeat the purpose. If a CLI is available, that would work too, of course. It could simply be run using sudo and on an as-needed basis.

JohnGaver avatar Dec 09 '23 13:12 JohnGaver

Did I understand you right that you expect the power adapter to be turned on when falling below the minimum threshold and then charge to the maximum? If you meant it should turn it on when reaching the minimum and then not charge, that should be an easy change. I implemented a PoC for the former at: https://github.com/mhaeuser/Battery-Toolkit/tree/poc_chargeEnableAdapter

I also attached a compiled copy. I briefly tested the feature and it appears to work, but I cannot give it extensive testing right now (if ever, I do not really have a use-case for this myself). Enable the new option and let me know how it goes.

Battery-Toolkit-poc_chargeEnableAdapter_v1.zip

Due to some "radical" changes (I needed to disable App Sandbox to comply with macOS 14.2 requirements and I needed to use a certificate with a new CN), it might be necessary to re-install the helper and/or reboot to upgrade from 1.2. I will run some tests about that before releasing it.

For various reasons, I cannot accept payments. If the feature works as intended for you, feel free to direct it to: https://www.kinderschutzbund-kaiserslautern.de/helfen-sie-mit/spenden/ (Kaiserslautern branch).

mhaeuser avatar Dec 09 '23 20:12 mhaeuser

The former scenario describes my use case, so this should be good to go. I've downloaded the necessary files and shall soon commence testing. Thank you very much, and I'll keep you posted with my progress. Would I need to manually uninstall the helper and/or the application at any point (if so, any instructions - for the helper in particular)?

JohnGaver avatar Dec 10 '23 12:12 JohnGaver

Ideally no, I hope the helper will simply update itself. Otherwise, you can manually unregister the old helper by launching the old app and invoking "Disable Background Activity" from the "Battery Toolkit" menu (not in the tray icon, but in the menu bar). I unfortunately cannot really test this right now, because the current release refuses to launch under 14.2 (due to the changes to App Sandbox). I might be able to set up a VM with an older version to test later. Feel free to report what happens on your system.

EDIT: A quick suggests a seamless update is not possible, as feared. However, it appears replacing the app with the new version and then rebooting works. In the absolute worst-case, there is an uninstall.sh script in the repository root to fully wipe the tool.

mhaeuser avatar Dec 10 '23 12:12 mhaeuser

Putting this into my workflow I just realized that I forgot to request the power adapter to be turned off when reaching the maximum charging threshold, and remaining off until depletion occurs below the threshold again.

Would another checkbox be useful to handle this - such as "Disable the adapter when turning off charging" - or maybe a modified original checkbox to the effect of "Sync power adapter enablement to battery charge thresholds"? The former may provide for more flexibility, although my scenario involves just the latter case.

JohnGaver avatar Dec 10 '23 12:12 JohnGaver

So you basically want the machine to constantly (dis)charge within [Min, Max]? Hmm, I did not question your original workflow too much (I thought it was more of a safeguard for if you disabled the power adapter and forgot to turn it back on, to prevent full depletion). In this case, are you sure that's what you want?

Macs draw power directly from the power adapter when connected, so when charging is turned off at the maximum threshold, it is (almost) as if the battery was disconnected. There may be small effects like battery drain when more power is needed than the power adapter can provide. This should reduce the battery wear compared to your constant charging workflow, though you still should re-calibrate the battery from time to time. Any specific reason you want it to work like this?

mhaeuser avatar Dec 10 '23 12:12 mhaeuser

That is exactly correct, I do want the machine to loop in a constant charge/discharge pattern between the minimum and maximum thresholds specified therein.

I don't understand how the turning off of charging at the maximum point amounts to a near battery disconnect - could you please help me understand what the significance of this would be?

I have a benchmark which attempts to maximize CPU utilization and can typically drain the battery in an hour regardless of Mac device. My goal is to maximize the number of power cycles in the shortest amount of time, in unattended fashion.

I'd just adapt the benchmark to turn off utilization while charging, if the workflow above is attainable.

JohnGaver avatar Dec 10 '23 14:12 JohnGaver

Any luck with this, do you think I might be able to copy/paste some code to achieve what I want based on what you already did with the first checkbox you added? If you might be so kind as to point me in the right direction (the places to check in the project) I'd be truly much obliged! I am a developer, just not an Xcode developer.

JohnGaver avatar Dec 17 '23 18:12 JohnGaver

Hey, I'm a bit busy at the moment and not yet sure whether I want to add this functionality to the tool. A hacky workaround that should roughly work as expected is here: https://github.com/mhaeuser/Battery-Toolkit/tree/poc_syncChargeAdapter

Pre-compiled version: Battery-Toolkit-poc_syncChargeAdapter-v1.zip

I say "roughly", because I don't think the behavior when manually invoking charging makes much sense now, but I would need time to think it through if I were to actually add this functionality. For the time being, I hope this works as-is.

mhaeuser avatar Dec 17 '23 19:12 mhaeuser

Thank you very much for your kindness. I will check this version and close the issue if it performs as desired and follow up with a donation as indicated.

JohnGaver avatar Dec 17 '23 19:12 JohnGaver

Just to confirm, the UI looks the same as compared to the previous custom build on this one. Would this be due to the reason that I have not rebooted yet?

JohnGaver avatar Dec 17 '23 23:12 JohnGaver

No, I didn’t update the UI to reflect the changes - as I said, it’s hacky. :)

mhaeuser avatar Dec 17 '23 23:12 mhaeuser

No worries at all :)

Just to be sure, when I check the "Enable the power adapter when requesting battery charging" box, it'll do that, and also disable the power adapter when the battery has reached the targeted charge, right (at least, assuming your hack in the back end took)?

JohnGaver avatar Dec 17 '23 23:12 JohnGaver

If it works, yes.

mhaeuser avatar Dec 17 '23 23:12 mhaeuser

So I set a very narrow limit to produce near instant results and it didn't work. However I have a ton of VMs running in the background and haven't rebooted, so there is still hope the service is not updated; and that it may work after a reboot - right? Worst case I figure I can diff your different versions shared on this thread and see if I can get involved that way!

JohnGaver avatar Dec 18 '23 00:12 JohnGaver

No, it should work without a reboot - the reboot was required previously only because the certificate CN changed and the app could not update the daemon itself, so rebooting picked up the new one implicitly. I find it unlikely that nothing works, so what exactly is happening around the thresholds?

mhaeuser avatar Dec 18 '23 08:12 mhaeuser

Just to make sure I'm testing the right binaries: This latest package wasn't even signed, and I did manually approve its helper (as well as manually approving the launch of the app to get past Gatekeeper upon first launch). And I probably never rebooted even after upgrading your public version with the first version on this thread (and now the latest version).

The scenario I tested specifically is for what happened when the battery charging threshold is set to 94% and the battery fell to 93%. It did not automatically re-enable the power adapter after I had manually disabled it from your menu at the start of my scenario. I had not even gotten to testing the part where power is automatically disabled upon exceeding the maximum charge threshold. Maybe I would need to start there first, for the automated dis/reconnects of power to happen?

JohnGaver avatar Dec 18 '23 11:12 JohnGaver

Oh - in case you didn’t test the previous binary I uploaded here or updated to 1.3, you indeed need to reboot. What you described should work if you toggled the new setting.

mhaeuser avatar Dec 18 '23 11:12 mhaeuser

Finally got the chance to reboot. Power adapter "disconnected" after reaching maximum designated charge - CHECK. Power adapter "reconnected" upon reaching minimum charge level - CHECK. Repeated cycle twice - CHECK. This is GOLD - thank you!!! Donation queued for processing. Will update when it clears the bank (since they provided an IBAN only). Many thanks again!!! Your kindness is truly appreciated :) Now I just need to figure out how to pause my own app while the battery is charging, so charge cycles may complete as quickly as possible.

JohnGaver avatar Dec 19 '23 01:12 JohnGaver

Good. :) Let’s leave the issue open for tracking, to maybe push this into main later.

mhaeuser avatar Dec 19 '23 08:12 mhaeuser

Just to confirm that the bank has processed the transfer. Per your request, I shall keep the issue open - while I am actually 100% satisfied currently with its resolution. Ex: Since I last wrote, 4 cycles have been drained on my M2 Max device; using the power band of 20% (the minimum allowed) - 77% (I noticed 80% is a dangerous number as reaching there the OS interferes with the charging directly [even with Battery-Toolkit active]; so setting the upper limit to 100% [or anything at/higher than 80%] runs the risk of being stuck in the final 20% "purgatory" where the battery is not charging but the power adapter has not been disconnected yet either [I also took 3 percentage points away to account for cases when battery charges may jump by more than 1% in a single hop]). It would of course have been interesting to observe whether charge cycles would have been consumed faster/slower setting more extreme ranges such as 3% on the low end and as high as 100% on the high end; but given how these extreme values would actually have a deleterious effect on battery hardware (to say nothing of OS interference on the upper bound side of things at least, as just described above), this is most probably unnecessary to say the least. Once again, many thanks :)

JohnGaver avatar Dec 19 '23 10:12 JohnGaver

Just to confirm that the bank has processed the transfer.

Thanks!

You can disable OS interference by turning off "Optimized Charging" in System Settings > Battery > Battery Health > Optimized Battery Charging, if required.

mhaeuser avatar Dec 19 '23 10:12 mhaeuser

Ah, that's great to know. Maybe I'd check that soon to see if it accelerates (or decelerates) the pace of accruing charge cycles - thoughts?

JohnGaver avatar Dec 19 '23 10:12 JohnGaver

Just wanted to say thank you again, as this has been working gorgeously for the past few days :D The only oddity I've noticed is what happens when a real power loss occurs (ex: cable yanked out physically), the system seems to take a few clicks here and there (not remembering exactly when and where) to reset after a re-plugging-in; but that's more than manageable given the rarity of the occurrence. Again, thank you so much - you've really made my day(s) with this :)

JohnGaver avatar Dec 20 '23 17:12 JohnGaver

Hi again! I hope your new year is off to a great start :) I just upgraded to Sonoma 14.4 and sadly this seems to have broken the automatic disabling of the power adapter at the maximum threshold, and the automatic enabling of the power adapter at the minimum threshold. Any thoughts on what might be the problem here and what could be done to fix it? Thank you very much for your help!

JohnGaver avatar Mar 07 '24 23:03 JohnGaver

Another finding with Sonoma 14.4 seems to be that the Enable Charging menu item doesn't show any longer! I have just realized a scenario where the device is plugged-in, but refuses to enter a charging state. The only menu options are to disable/enable the power adapter; nothing that controls charging though.

JohnGaver avatar Mar 08 '24 01:03 JohnGaver

@JohnGaver Hi - we got Apple'd. Fixed: Battery-Toolkit-1.4-poc_syncChargeAdapter.zip

mhaeuser avatar Mar 08 '24 20:03 mhaeuser

Awesome, will check this out right away!

So the sources for this latest release are in the Battery-Toolkit-poc_syncChargeAdapter branch, right?

Also, the uninstall script (I had tried fully uninstalling and reinstalling the old version as some of my acts of desperation before your most timely refresh) seemed to have a couple of issues:

  • sudo rm /private/var/root/Library/Preferences/me.mhaeuser.batterytoolkitd.plist was the correct path on my system. The path /Library/LaunchDaemons/me.mhaeuser.batterytoolkitd.plist could not be found.
  • The file /Library/PrivilegedHelperTools/me.mhaeuser.batterytoolkitd did not exist anywhere at all on my system.

Hope that helps.

JohnGaver avatar Mar 09 '24 14:03 JohnGaver