You are not logged in.

#1 2015-08-17 21:00:20

nmaggioni
Member
Registered: 2015-08-17
Posts: 7

Delayed hibernation (aka Intel Rapid Start)

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.

delayed_hibernation.sh
#!/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:

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

#2 2015-12-26 20:53:20

gabrielsimoes
Member
Registered: 2015-12-26
Posts: 3

Re: Delayed hibernation (aka Intel Rapid Start)

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

#3 2015-12-26 21:51:43

ned98
Member
From: Italy
Registered: 2014-05-20
Posts: 2

Re: Delayed hibernation (aka Intel Rapid Start)

[Post deleted.]

Last edited by ned98 (2015-12-26 21:52:52)

Offline

#4 2015-12-26 21:55:20

nmaggioni
Member
Registered: 2015-08-17
Posts: 7

Re: Delayed hibernation (aka Intel Rapid Start)

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

#5 2015-12-26 22:31:13

gabrielsimoes
Member
Registered: 2015-12-26
Posts: 3

Re: Delayed hibernation (aka Intel Rapid Start)

nmaggioni wrote:

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

#6 2015-12-26 22:38:44

nmaggioni
Member
Registered: 2015-08-17
Posts: 7

Re: Delayed hibernation (aka Intel Rapid Start)

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

#7 2015-12-26 23:29:08

nmaggioni
Member
Registered: 2015-08-17
Posts: 7

Re: Delayed hibernation (aka Intel Rapid Start)

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 :

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:

nOrNIc wrote:
# 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! smile

Last edited by nmaggioni (2015-12-26 23:43:48)

Offline

#8 2015-12-27 00:14:27

gabrielsimoes
Member
Registered: 2015-12-26
Posts: 3

Re: Delayed hibernation (aka Intel Rapid Start)

nmaggioni wrote:

Let me know if this workaround works for you too! smile

Works perfectly! Thanks a lot!

Offline

Board footer

Powered by FluxBB