1

I want to hibernate on low battery:

SUBSYSTEM=="power_supply", \ ATTR{status}=="Discharging", \ ATTR{capacity}=="[0-5]", \ RUN+="/usr/bin/systemctl hibernate", \ 

This works well if the system is awake. If suspended however, it doesn't hibernate until I wake it, then instead of allowing me to unlock it immediately hibernates.

How can I make this event either work while suspended, or trigger a wakeup (and then hibernate) itself, without me opening the lid?


I have tried adding:

 ATTR{power/wakeup}="enabled" 

without success. Indeed there is no wakeup currently in /sys/class/power_supply/BAT1/power/ - actually though /sys/class/power_supply/BAT1/device/power/wakeup exists and is already enabled.

I gather I can't make the udev rule run while suspended, I need to trigger it to wake on low battery separately (then the udev rule can run and hibernate).

This seems already implemented in drivers/acpi/battery.c:

 /* * Wakeup the system if battery is critical low * or lower than the alarm level */ if ((battery->state & ACPI_BATTERY_STATE_CRITICAL) || (test_bit(ACPI_BATTERY_ALARM_PRESENT, &battery->flags) && (battery->capacity_now <= battery->alarm))) acpi_pm_wakeup_event(&battery->device->dev); 

But that has not worked for me, I don't know if 'critical low' is another textual capacity level, I've only seen as low as 'Low', but it was at the time lower than the /sys/class/power_supply/BAT1/alarm.


NB: I am aware of hybrid-sleep, but that is not what I want, firstly since I would like to conserve some battery; but also so that I can use suspend-then-hibernate such that it hibernates on either low battery or time delay.

2 Answers 2

0

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.

The udev rule in my original question will then be able to run (and hibernate).

This does mean however that you probably want to ensure the value in alarm (as a percentage of that in charge_full) is the same as or only slightly higher than the upper end of the range given in the udev rule.

0

Systemd's systemctl suspend-then-hibernate knows when to hibernate before the battery level becomes too low. (In current versions of Systemd)

When the battery level is too low (less than 5%) or a certain timespan has passed, whichever happens first, the system is automatically woken up and then hibernated.

1
  • Your answer could be improved with additional supporting information. Please edit to add further details, such as citations or documentation, so that others can confirm that your answer is correct. You can find more information on how to write good answers in the help center. Commented Mar 27 at 5:08

You must log in to answer this question.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.