Hibernate from suspend if battery gets low

This is commented in the sleep.conf, which according to the file description should indicate it was set as a compile time default.
It is now uncommented… No changes observed.

That is strange if the handler of lid switch should be related to this issue. Is it so that xfce4 power manager is unable to handle the suspend-then-hibernate option? Is the only workaround to use another power manager?

Default (commented, hence compiled in) was 60min. I set it to 2 min for my testing. My testing reveals that if this setting is not set, the suspend-then-hibernate works identically to suspend. (It never hibernates.)

I’ll not put too much effort into how to trigger it automatically until it is working when triggered manually by

# systemctl suspend-then-hibernate

I have no indication that suspend-then-hibernate will trigger hibernate if battery gets low. It seems to set a wake up timer only. Maybe there is a setting somewhere to enable this behavior? (Similar to the behavior that hibernate timer never triggers if HibernateDelaySec=60min is left commented.)

What I’m looking for is either a way to enable suspend-then-hibernate to do battery check, or a way to modify the commands ran when the timeout to hibernate is triggered.
Or a completely different way to trigger action on low battery while suspended.

Where can I find the source code for the suspend-then-hibernate function?

Here is something interesting from release notes of systemd 253 (I’m on 256)

    * systemd-sleep 'HibernateDelaySec=' setting is changed back to
      pre-v252's behaviour, and a new 'SuspendEstimationSec=' setting is
      added to provide the new initial value for the new automated battery
      estimation functionality. If 'HibernateDelaySec=' is set to any value,
      the automated estimate (and thus the automated hibernation on low
      battery to avoid data loss) functionality will be disabled.

Release page: Release systemd v253 · systemd/systemd · GitHub

Sounds like IF HibernateDelaySec is set in sleep.conf, the battery level monitoring is disabled… So one can’t have both. Thats OK with me, I’m only looking for the battery monitor function. Now, why doesn’t it work? Is there a low battery threshold to set somewhere?

Another interesting thing, from man systemd-sleep.conf

If the system has battery and HibernateDelaySec= is not set, low-battery alarms (ACPI _BTP) are tried first for
detecting battery percentage and wake up the system for hibernation. If not available, or HibernateDelaySec= is
set, the system would regularly wake up to check the time and detect the battery percentage/discharging rate. The
rate is used to schedule the next detection. If that is also not available, SuspendEstimationSec= is used as last
resort.
Added in version 239

As the changelog for 253 states, there were changes to this area in 252 and 253. Documentation seems not to be updated.

I’m wondering if the sleep state could be affecting the wake up events during suspend. How do I change manjaro to use s2idle state when suspended?

How can the 5% battery level be changed to i.e. 20%? (Thinking maybe the calculation of when 5% is reached fails and the wake up timer is triggered to late? Maybe the level of reminding battery is confused with voltage drop in battery when the system wakes up to hibernate, hence bios cuts power at the moment hibernate is about to start when battery is that low?)

Systemd is becoming more and more a monstrous, buggy and badly documented mess in my opinion.

Here is something even more interesting from https://unix.stackexchange.com/questions/700186/acpi-trigger-wakeup-on-low-battery-while-suspended-in-order-to-hibernate

It turns out this actually works somewhat out of the box. (Though battery support may vary.)

The ACPI driver will wake from sleep when /sys/class/power_supply/BATn/charge_now drops below /sys/class/power_supply/BATn/alarm.

Looking at my /sys/class/power_supply/BATn/alarm

# cat /sys/class/power_supply/BAT0/alarm 
0

So here is probably the core of my problem: The low battery alarm is set to 0! How can this be changed? I guess just editing that file is not the right way to do it

1 Like

Have you tried to sudo tee the value? If it works you can make a script or service to check or change on startup. You can see for example battery_conservation package from aur.

Of course nothing changed - nothing was changed …
It’s still the same setting as was the default already.

That’s probably not true.
The guy who asked the question just threw this out there as a guess - it’s not an answer confirmed by anyone.

This whole directory, with everything in it, does not exist when the system isn’t running (aka is in sleep mode)
… can’t write to it at that time … or check a value you wrote to it …

1 Like

But the suspend-then-hibernate process is able to read that information prior to suspending. I don’t find it likely that the 5% threshold is hardcoded and not configurable. There must be a way to increase that value?

Yes, of course - and it’ll read the then current value.

And the value is probably easy to change
either by directly writing it
or via sysctl (/etc/sysctl.conf or /etc/sysctl.d/some_file)

But it’s only a value that once was - not what is current.

But I’ll withdraw from this discussion as I don’t know enough about the subject to be actually helpful.

ps:
here is how it is supposed to work:
(it did apparently change over time - now the system can wake up and take a measurement and decide how to proceed, before it was just a set time period)

Power management/Suspend and hibernate - ArchWiki

also have a look further down at section 5 re your .service not being present - it’s run via other targets / another service
one example they give is:
/etc/systemd/system/user-suspend@.service

It does not help because he asks something completely different.

2 Likes

Thank you @Teo
Ok, then I misunderstood. Sorry about that. Before there’s any more confusion, I’ve removed the post.

1 Like

I’ve been looking through the code for systemd sleep hoping to figure where the low battery threshold comes from, but I can’t find it. Neither do I find where battery level is used for triggering hibernate. I do find where hibernate is triggered by timer, and where timer is extended if AC is connected, and where time to next wake up is calculated based on battery reminding capacity - and 30 minutes is subtracted. But it looks like there is no low battery threshold anywhere, which seems that the hibernate is triggered only when calculated reminding battery is less than 30 minutes. As the reminding battery is calculated until battery is 0, I suspect my problem is that bios cuts of battery before the reminding time calculation concludes that there is less than 30 minutes left.

I guess the forum posts talking about low battery threshold of 5% are based on the result that 30 minutes reminding battery does calculate to about 5% on some laptops.

Currently I don’t see any way to improve on this other than to edit the formula used to calculate reminding time.

1 Like