You are not logged in.
After having spent a bunch of hours trying to make the Intel Rapid Start Technology work on my Dell XPS 13 without any result, I decided to roll my own.
This script makes the computer wake up after N seconds from suspension, sending it into hibernation to save precious battery. Just place it in /usr/lib/systemd/system-sleep and set it as executable for everyone.
#!/bin/bash
logtag="delayed_hibernation: "
if [ ! -f /etc/delayed_hibernation.conf ]; then
echo "${logtag}Missing configuration file, aborting."
exit 1
fi
ENABLE=$(grep "^[^#]" /etc/delayed_hibernation.conf | grep "ENABLE=" | awk -F'=' '{ print $2 }')
if [ "$ENABLE" = "" ]; then
echo "${logtag}Missing enable parameter, aborting."
exit 1
elif [ "$ENABLE" != "0" ] && [ "$ENABLE" != "1" ]; then
echo "${logtag}Bad enable parameter, aborting."
exit 1
fi
TIMEOUT=$(grep "^[^#]" /etc/delayed_hibernation.conf | grep "TIMEOUT=" | awk -F'=' '{ print $2 }')
if [ "$TIMEOUT" = "" ]; then
echo "${logtag}Missing timeout parameter, aborting."
exit 1
elif [[ ! "$TIMEOUT" =~ ^[0-9]+$ ]]; then
echo "${logtag}Bad timeout parameter, aborting."
exit 1
fi
if [ "$ENABLE" = "1" ]; then
if [ "$2" = "suspend" ]; then
curtime=$(date +%s)
if [ "$1" = "pre" ]; then
if [ -f /var/run/delayed_hibernation.fail ]; then
echo "${logtag}Failed hibernation detected, skipping setting RTC wakeup."
else
echo "${logtag}Setting RTC wakeup..."
echo "$curtime" > /var/run/delayed_hibernation.lock
rtcwake -m no -s "$TIMEOUT"
fi
elif [ "$1" = "post" ]; then
if [ -f /var/run/delayed_hibernation.fail ]; then
rm /var/run/delayed_hibernation.fail
fi
sustime=$(cat /var/run/delayed_hibernation.lock)
if [ $((curtime - sustime)) -ge "$TIMEOUT" ]; then
echo "${logtag}Automatic resume detected, hibernating."
systemctl hibernate || echo "${logtag}There has been an error during hibernation, suspending!" && touch /var/run/delayed_hibernation.fail &&
systemctl suspend
else
echo "${logtag}Manual resume detected, disabling RTC wakeup."
rtcwake -m disable
fi
rm /var/run/delayed_hibernation.lock
fi
fi
fi
And this is the configuration file, to be saved as /etc/delayed_hibernation.conf:
## Enable or disable delayed hibernation.
## Possible values: 1 (enabled), 0 (disabled)
ENABLE=1
## Set the time to spend in suspension before the computer hibernates.
## (The value is in seconds)
TIMEOUT=1500
Most of the credit goes to Derek Pressnall from this AskUbuntu answer, I've just adapted it for systemd and refactored it to support external configuration and some other caveats.
Let me know if there's anything that can be done to improve it!
This script also comes as an AUR package: https://aur.archlinux.org/packages/delayed_hibernation/
Last edited by nmaggioni (2015-12-27 00:16:08)
Offline
Thanks for this! However, it isn't hibernating or suspending again after it wakes up. Would you help me identifying why it isn't working? The log is correctly recognizing automatic wakeup, but it doesn't hibernate after this, not even suspends as it should after systemctl hibernate returns error (checked this).
Offline
[Post deleted.]
Last edited by ned98 (2015-12-26 21:52:52)
Offline
Hi gabrielsimoes, I'm glad that you find this useful.
Would you mind posting the suspension log?
journalctl -b -u systemd-suspend
I've updated the first post as well with a newer version of the script.
Offline
Would you mind posting the suspension log?
journalctl -b -u systemd-suspend
I've updated the first post as well with a newer version of the script.
journalctl -b -u systemd-suspend with the new version:
Dec 26 20:14:34 thor systemd[1]: Starting Suspend...
Dec 26 20:14:34 thor systemd-sleep[26190]: delayed_hibernation: Setting RTC wakeup...
Dec 26 20:14:34 thor systemd-sleep[26190]: rtcwake: wakeup using /dev/rtc0 at Sat Dec 26 22:14:44 2015
Dec 26 20:14:34 thor systemd-sleep[26190]: Suspending system...
Dec 26 20:14:44 thor systemd[1]: Started Suspend.
Dec 26 20:14:46 thor systemd-sleep[26190]: delayed_hibernation: Automatic resume detected, hibernating.
Dec 26 20:14:46 thor systemd-sleep[26190]: Failed to hibernate system via logind: There's already a shutdown or sleep operation in progress
Dec 26 20:14:46 thor systemd-sleep[26190]: delayed_hibernation: There has been an error during hibernation, suspending!
Dec 26 20:14:46 thor systemd-sleep[26190]: Failed to suspend system via logind: There's already a shutdown or sleep operation in progress
EDIT: Just thinking here, if systemctl hibernate fails every time, would systemctl suspend call itself recursively every 25 min?
Last edited by gabrielsimoes (2015-12-26 22:36:43)
Offline
It seems that the bug got introduced by systemd 227 and still exists in 228. All the available solutions refer to the service variant of the script, I'll try to find something that applies to /usr hooks as well.
EDIT: actually yes, it'd repeat itself by suspending every N mins, thanks for the heads up! I've updated the first post with a new version.
Last edited by nmaggioni (2015-12-26 23:56:52)
Offline
I came up with a poor man's solution: call the script via a service with the patch above applied. This way you keep the suspension failover if the hibernation fails.
Move /usr/lib/systemd/system-sleep/delayed_hibernation.sh to /usr/local/bin/ and create the service file in /etc/systemd/system/delayed-hibernation.service :
[Unit]
Description=Delayed hibernation trigger
Before=suspend.target
Conflicts=hibernate.target hybrid-suspend.target
StopWhenUnneeded=true
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStart=/usr/local/bin/delayed_hibernation.sh pre suspend
ExecStop=/usr/local/bin/delayed_hibernation.sh post suspend
[Install]
WantedBy=sleep.target
Enable the service as usual and then patch suspend.target as per this post. Here's the excerpt, modified to suit this case:
# cp -p /usr/lib/systemd/system/suspend.target /etc/systemd/system/ # echo 'Requires=delayed-hibernation.service' >> /etc/systemd/system/suspend.target # systemctl daemon-reload
Logs will now be found in the delayed-hibernation.service unit. Let me know if this workaround works for you too!
Last edited by nmaggioni (2015-12-26 23:43:48)
Offline
Let me know if this workaround works for you too!
Works perfectly! Thanks a lot!
Offline