I want my laptop to wake up from suspended mode in the morning and alarm me to wake up using my mp3 file. How do I do it?
I tried apmsleep, but it doesn't work cause my PC doesnt have "suspend to RAM" feature in BIOS. What can I do? Thanks!
1.Basic alarm clock function
Entering suspend mode
for this solution, you need to enter suspend mode by running the script below. It makes the computer go into suspend mode and wakes you up at a (clock-) time, defined by you (in the script). playing your song.
Of course you can simply run the script manually to use it, but it is more convenient to make it available via a key combination, set in System Settings > Keyboard > Shortcuts > Custom Shortcuts
.
Set up
Paste the script below in an empty file, set the wake up (clock) time (in 1-24 hours, 1-60 minutes), set the path to your wake up song, and save it as wakeup.py
.
#!/usr/bin/env python3
import datetime
import subprocess
###############################################
# set wakeuptime and location of the mp3:
hour = 7
minutes = 15
command = "rhythmbox /path/to/wakeupsong.mp3"
###############################################
currtime = str(datetime.datetime.now().time()).split(":")[:2]
minutes_set = hour*60 + minutes
minutes_curr = int(currtime[0])*60 + int(currtime[1])
if minutes_curr < minutes_set:
minutes_togo = minutes_set - minutes_curr
else:
minutes_togo = minutes_set + 1440-minutes_curr
interval = minutes_togo*60
run = "rtcwake -m disk -s "+str(interval)+" && "+"sleep 20 &&"+command
subprocess.call(['/bin/bash', '-c', run])
make the script executable
Set a key combination to run the script; open System Preferences > Keyboard > Shortcuts > Custom Shortcuts
, add the command
sudo /path/to/wakeup.py (sudo = assuming you do the next step below)
and choose a key combination
The script needs administrator's privileges. To run it without having to enter the password, open the sudoers file:
sudo visudo
add the line to the very bottom of the file:
[your_username] ALL=NOPASSWD: [/path/to/wakeup.py]
Note that the sudoers file is an essential file; errors in the file possibly lead to serious problems, so be careful!
N.B.
gksu
: sudo apt-get install gksu
. In that case, the command to run
the script is gksu /path/to/wakeup.py
, and you will be prompted for
your password each time you run it.Now you can enter suspend mode with your key combination and you'll get woken by your wake up song.
2.Extended version including stop function when (any) key or mouse is hit
The differences between this one and the "basic" version is that in this one the alarm stops when any keystroke or mouse movement is detected (more convenient than stopping Rhythmbox on the computer when you just woke up), and that the alarm automatically exits after a defined period of time.
The setup is pretty much the same as the basic version, but xprintidle
needs to be installed, to detect keystroke- or mouse movement events:
sudo apt-get install xprintidle
The script:
#!/usr/bin/env python3
import subprocess
import time
import datetime
from threading import Thread
#-------------------------- edit settings below -------------------------------
max_wakeupduration = 1 # max time the song will play (minutes)
wakeup_hour = 7 # wake up hour (0-24)
wakeup_minute = 15 # wake up minute
wakeup_song = "/path/to/song.mp3" # path to wake up song
#------------------------------------------------------------------------------
def stop_wakeup():
time1 = int(time.time()); time2 = time1
last_idle = 0
playtime = max_wakeupduration*60
while time2 - time1 < playtime:
get_idle = subprocess.Popen(["xprintidle"], stdout=subprocess.PIPE)
curr_idle = int(get_idle.communicate()[0].decode("utf-8"))
if curr_idle < last_idle:
break
else:
last_idle = curr_idle
time.sleep(1)
time2 = int(time.time())
subprocess.Popen(["pkill", "rhythmbox"])
def calculate_time():
currtime = str(datetime.datetime.now().time()).split(":")[:2]
minutes_set = wakeup_hour*60 + wakeup_minute
minutes_curr = int(currtime[0])*60 + int(currtime[1])
if minutes_curr < minutes_set:
minutes_togo = minutes_set - minutes_curr
else:
minutes_togo = minutes_set + 1440-minutes_curr
return minutes_togo*60
def go_asleep():
sleeptime = calculate_time()
run = "rtcwake -m disk -s "+str(sleeptime)+" && "+"sleep 20"
subprocess.call(['/bin/bash', '-c', run])
combined_actions()
def play_song():
command = "rhythmbox "+wakeup_song
subprocess.Popen(['/bin/bash', '-c', command])
def combined_actions():
Thread(target = play_song).start()
Thread(target = stop_wakeup).start()
go_asleep()
Explanation
rtcwake
Both scripts are written around the rtcwake
command, as explained here. The command can be used to put the computer into suspend and wake up after a defined amount of time (and optionally run a command after wake up). The -m disk
option is used, since OP mentioned his computer does not support "suspend to RAM" feature in BIOS. See also man rtcwake
.
The stop function
The stop function works by a function that measures idle time every second while the song is playing, and remembers the last idle time. IF the last idle time exceeds the current one, it means a keystroke or mouse event has taken place, and Rhythmbox is killed.
sudo visudo /etc/sudoers
?
If you can have your laptop connected to internet by a cable, you can try to use an other computer or smartphone to send a "magic packet" to it, and wake it up.
Look for "wake on lan" (WOL).
I had troubles running Jacob's python script, so I rewrote it in bash. Just download it, make it executable and edit variables accordingly.
A couple of things: alarm time is set via date -d
. Some examples from man date
:
After wake up I use vlc -L
to play some music in a loop. If your path is a folder, it will try to play files in it. That's what I do.
Not sure if this is what you're looking for, but I just found a simple working 'alarm' that automatically wakes up from suspend mode:
sudo rtcwake -m freeze --date 05:30:00 ; cvlc /path/to/music.mp3
The -m freeze
option idles processors and freezes all running processes. While -m mem
will suspend to RAM and put the system into low-power state to conserve more power, according to rtcwake(8).
This code will first run the rtcwake
, suspend the computer until 5.30 a.m., leaving the console open while the computer sleeps, and then play the music using cvlc
(Console VLC). I'm not sure why the sudo
privilege must be included. I guess that's just the nature of rtcwake. The semicolon ;
is used so that the code on the left of the semicolon is run first, and then the second code (to the right of the semicolon) is run after the first code is completed. This is similar to running two commands separately:
[user@localhost ~] sudo rtcwake -m mem --date 05:30:00
[user@localhost ~] cvlc /path/to/music.mp3
But since we can't wait until the computer wakes again and play the music by ourselves, we interject these two commands with a semicolon ;
.
To use the VLC functionality, you can install it using the command below:
sudo apt-get install vlc
The cvlc
command will only play the music in the background without actually opening the VLC windows interface. To turn off the 'alarm', you can close the console or press Ctrl+C.
For system with systemd, the command can be scheduled with a temp systemd timer using systemd-run. The temp units are cleared when they complete and upon reboot.
systemd-run --collect --user --unit=alarm-clock --on-active="1h 30m" --timer-property=WakeSystem=true flatpak run io.bassi.Amberol ~/Music/test.mp3
This is the same effect as rtcwake -m no
and an at job. The suspend is independent of the command, so the system can be suspended or used as normal. It would still work if the system is not suspended or woken up and suspended again.
Note:
--user
) and waking from suspend (WakeSystem=true
) is available from systemd v254 onward.--collect
: Deletes the unit files even if it failed, else systemd complains about the dangling service file when using the same name, and a reboot or systemctl reset-failed
is needed.--unit
: Gives the units (a timer and a service file) a name. Might be easier to just omit this when scheduling multiple alarms.--on-active
takes more than just seconds. The format is here.flatpak run io.bassi.Amberol ~/Music/test.mp3
is the command.P.S.
--on-active
+ WakeSystem=true
is not working as intended as of v254.
--on-calendar
works correctly. e.g. --on-calendar="12:34:56"
(though this is recurring because no date is specified).