Skip to content

Instantly share code, notes, and snippets.

@EarlGray
Last active January 12, 2022 20:35
Show Gist options
  • Save EarlGray/702f730b9e56acd0edc70588e0526f84 to your computer and use it in GitHub Desktop.
Save EarlGray/702f730b9e56acd0edc70588e0526f84 to your computer and use it in GitHub Desktop.
dmytrish-sleep.service

This is a set of systemd timers and services that ensures that computer goes to bed at night (00:00-07:00), hopefully helping me to go to bed as well.

dmytrish-sleep.timer starts sending desktop notifications about computer going to sleep 1 minute before the night start and then suspends the computer. Then it tries to ensure that computer sleeps during the night time: it puts computer back to sleep in a loop until the morning time.

Files:

  • /etc/systemd/system/dmytrish-sleep.timer
  • /etc/systemd/system/dmytrish-sleep.service
  • /usr/local/sbin/dmytrish-sleep.py

Enable it:

$ sudo systemctl daemon-reload
$ sudo systemctl enable --now dmytrish-sleep.timer
#!/usr/bin/env python3
import os, sys, time, subprocess
from datetime import datetime
from configparser import ConfigParser
from systemd import journal
import notify2
NOT_BEFORE = datetime.strptime('00:00', '%H:%M').time()
NOT_AFTER = datetime.strptime('07:00', '%H:%M').time()
CHECK_INTERVAL = 0.5
COUNTDOWN = 60
NOTIF_UID = 1000
def syslog(message):
journal.send(message, SYSLOG_IDENTIFIER='dmytrish-sleep')
def sleep_start():
pid = os.fork()
if pid:
os.waitpid(pid, 0)
return good_night(NOT_BEFORE, NOT_AFTER)
os.setuid(NOTIF_UID)
os.environ['XDG_RUNTIME_DIR'] = f"/run/user/{NOTIF_UID}"
notify2.init('dmytrish-sleep')
n10n = notify2.Notification('dmytrish-sleep', f'Computer goes to bed in {COUNTDOWN} seconds')
n10n.icon = 'system-suspend'
n10n.timeout = COUNTDOWN * 1000
n10n.urgency = notify2.URGENCY_CRITICAL
try:
for countdown in range(COUNTDOWN, 0, -5):
if not (NOT_BEFORE <= datetime.now().time() <= NOT_AFTER):
break
n10n.update('dmytrish-sleep', f'Computer goes to bed in {countdown} seconds')
n10n.show()
time.sleep(5)
finally:
n10n.close()
def good_night(not_before, not_after):
syslog('good night')
while not_before <= datetime.now().time() <= not_after:
p = subprocess.run('systemctl suspend -i', shell=True, capture_output=True)
if not (p.returncode == 0 or b'operation in progress' in p.stderr):
if p.stdout: syslog(f'stdout: {p.stdout}')
if p.stderr: syslog(f'stderr: {p.stderr}')
break
time.sleep(CHECK_INTERVAL)
else:
syslog('good morning')
if __name__ == '__main__':
if sys.argv[1] == 'start':
sleep_start()
[Unit]
Description=dmytrish-sleep
[Service]
Type=oneshot
ExecStart=/usr/local/sbin/dmytrish-sleep.py start
[Unit]
Description=dmytrish-sleep
[Timer]
OnCalendar=*-*-* 00:00:00
Persistent=false
AccuracySec=1sec
[Install]
WantedBy=timers.target
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment