baptx

gnome-calendar_wake_up

Aug 2nd, 2026 (edited)
71
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 14.19 KB | None | 0 0
  1. # gnome-calendar_wake_up.py
  2. #!/usr/bin/env python3
  3. # Extract alarm trigger time of calendar events (combining event time and reminder time)
  4. # https://icalendar.readthedocs.io/en/latest/how-to/usage.html#read-calendar-from-file
  5. # https://icalendar.readthedocs.io/en/latest/reference/api/icalendar.cal.event.html#icalendar.cal.event.Event.alarms
  6. # Not displaying a warning if ACTION is of type AUDIO instead of DISPLAY to avoid additional loop (https://github.com/collective/icalendar/issues/1421)
  7.  
  8. import icalendar
  9. from pathlib import Path
  10. ics_path = Path("/home/mobian/.local/share/evolution/calendar/system/calendar.ics")
  11. calendar = icalendar.Calendar.from_ical(ics_path)
  12. for event in calendar.events:
  13. #print(int(event.alarms.times[0].trigger.timestamp())) # only needed if we want to substract seconds to wake up system earlier
  14. print("OnCalendar=" + str(event.alarms.times[0].trigger))
  15.  
  16.  
  17. # gnome-calendar_wake_up.sh
  18. #!/usr/bin/env bash
  19. # Gnome Calendar event reminders using systemd timers to wake up device during sleep (tested with Mobian / Phosh on the PinePhone)
  20. # Based on Gnome Clocks scripts https://github.com/sbeaugrand/debinst/blob/master/mobian/clks.sh and https://github.com/sbeaugrand/debinst/blob/master/mobian/clks.py
  21. # Issue: https://salsa.debian.org/Mobian-team/devices/sunxi-support/-/work_items/7 / https://gitlab.gnome.org/GNOME/gnome-calendar/-/work_items/1579
  22. # Script needs to be run each time we configure a new event reminder.
  23. # Another script is called to extract event information using the icalendar Python library (https://askubuntu.com/questions/1258143/interacting-with-gnome-calendar-via-the-cli-adding-and-reading-events/1553440#1553440)
  24. # If you don't see a visual notification, there is a workaround by disabling sound in the event reminder (https://gitlab.gnome.org/GNOME/gnome-calendar/-/work_items/1280).
  25. # The OS may not produce sound if the event reminder has a DISPLAY action instead of an AUDIO action, so this script handles sound using mpv in addition to the visual notification with the ability to repeat sound notification (by default 3 times every 5 minutes within 10 minutes like done with the calendar and alarm app on Sailfish OS with a ring time of around 30 seconds by looping the sound, long enough to not miss the alarm if a train passes nearby) unless we close a terminal window or press Ctrl+C (device will go back to sleep if there is a 3rd sound notification unless a process is preventing it and blinking notification led will either turn off or have fixed blue light which is random).
  26. # If you snooze an alarm, it will not wake up the phone, neither use both the visual and sound notification, you need to change the event time instead and run the script again.
  27. # You can use "pipx install icalendar" instead of configuring a venv manually to also have the icalendar command available globally.
  28. # Debian package python3-icalendar uses an old version that does not support import from file yet.
  29. # Before running the script, you may need to change the sound file in the shell script code and the ICS file path in the Python code.
  30. # To automatically run the script, copy /usr/share/applications/org.gnome.Calendar.desktop to ~/.local/share/applications/ (which persists after updates) to comment the DBusActivatable=true line by adding "#" before it and replace the Exec= line with this (using bash instead of /bin/bash does not work for the D-BUS service file of apps like Birdie but works for desktop and service files in this script):
  31. # Exec=bash -c "gnome-calendar %U & kgx -e bash -c 'source ~/.local/share/pipx/venvs/icalendar/bin/activate && /path/to/gnome-calendar_wake_up.sh'"
  32. # Calendar and script will be started at the same time but script will only run after you type the password in the terminal (if started after the calendar is closed there is delay to display the window which can result in forgetting to save wake up timers).
  33. # Even if the alarm app and calendar app use the same sound for alarms, you should be able to notice if the alarm app and calendar app are ringing at the same time (view the visual notification to confirm you did not ignore an alarm or have it mistaken with another alarm).
  34. # If Phosh crashes and restarts during an alarm, you will not see the event reminder notification so it is recommended to open Gnome Calendar as a workaround to check if we did not miss an alarm (this can be done automatically after login by copying the desktop file or creating a symlink in ~/.config/autostart/ like mentioned on https://forum.pine64.org/showthread.php?tid=17278 instead of executing commands in ~/.profile which broke login in a infinite loading spinner loop that could be fixed with SSH access from a computer). In addition, we can restart the alarm with the script gnome-calendar_wake_up_autostart.sh.
  35. # Other issues / mobile specific issues noticed with Gnome Calendar: events happening next year are not displayed on the calendar so you should click on the day or week to see the event (another workaround without guessing the day / week is to view the following month and go back to the previous month); events created accidentally on several months by changing the year of an event cannot be edited so you should edit the ICS file and restart Phosh with "sudo systemctl restart phosh" (maybe there is a better solution to restart Gnome Calendar but executing "killall evolution-calendar-factory" fails to show visual notifications: https://askubuntu.com/questions/1359547/how-do-fix-my-gnome-calendar/1359559#1359559); landscape view crashes the app; editing the date of an event does not display a calendar unless we scroll down to have enough space.
  36. # Make sure to have the volume level loud enough to hear alarms or follow instructions from https://gitlab.gnome.org/GNOME/calls/-/work_items/745#note_2745975:
  37. # "Use media roles in pipewire / feedbackd and you can set the alarm volume indendently, see e.g. https://phosh.mobi/posts/role-based-routing (works for alarms too btw and makes sure the speaker is used for alarm sounds)"
  38.  
  39. #python_venv="/home/mobian/.local/share/pipx/venvs/icalendar/bin/python" # not needed if activating venv in desktop file (which avoids unnecessary script customizations and makes script independant from venv)
  40. python_script="gnome-calendar_wake_up.py" # file is expected to be in the same folder as gnome-calendar_wake_up.sh
  41. # Copy the calendar original sound file /usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga to another location to avoid missing file after update (canberra-gtk-play only prevents error for path change)
  42. sound_file="/home/mobian/Downloads/alarm-clock-elapsed.oga" # only works with full path, not ~/Downloads/alarm-clock-elapsed.oga
  43.  
  44. path=`dirname $0`
  45.  
  46. # Use other files and service names to avoid interference with alarm app Wake Mobile or Birdie (for system and user wake up timer)
  47. if [ "$1" = "off" ]; then
  48. if systemctl -q is-enabled system-wake-up_gnome-calendar.timer; then
  49. sudo systemctl disable system-wake-up_gnome-calendar.timer
  50. fi
  51. if systemctl -q is-active system-wake-up_gnome-calendar.timer; then
  52. sudo systemctl stop system-wake-up_gnome-calendar.timer
  53. fi
  54. if systemctl --user -q is-enabled wake-up_gnome-calendar.timer; then
  55. systemctl --user disable wake-up_gnome-calendar.timer
  56. fi
  57. if systemctl --user -q is-active wake-up_gnome-calendar.timer; then
  58. systemctl --user stop wake-up_gnome-calendar.timer
  59. fi
  60. exit 0
  61. fi
  62.  
  63. # System Wake Up Timer (needed to wake up device)
  64. dir=/etc/systemd/system
  65. sudo mkdir -p $dir
  66.  
  67. file=$dir/system-wake-up_gnome-calendar.timer
  68. # Overwrite file instead of checking if file exist to avoid handling an additional file and to avoid ignored changes if we want to change configuration of an existing file
  69. sudo tee $file > /dev/null << EOF
  70. [Unit]
  71. Description=System Wake Up Timer
  72. [Install]
  73. WantedBy=timers.target
  74. [Timer]
  75. Persistent=false
  76. WakeSystem=true
  77. AccuracySec=1us
  78. EOF
  79.  
  80. # call script only once to avoid unnecessary ICS file parsing
  81. #time=`$python_venv $path/$python_script`
  82. time=`$path/$python_script`
  83. # https://linuxsimply.com/bash-scripting-tutorial/array/print-array/
  84. #for item in ${time[@]}
  85. #do
  86. # timestamp_system=$(($item - 5)) # wake up system 5 seconds before event alarm is sometimes needed to show visual notification and blinking notification led (should not be needed anymore maybe because of the "Command completed" notification, the visual notification has a random delay of few seconds anyway)
  87. # date_system=`date +'%Y-%m-%d %H:%M:%S' -d "@$timestamp_system"`
  88. # echo "OnCalendar=$date_system" | sudo tee -a $file
  89. #done
  90. echo "$time" | sudo tee -a $file # preserve new lines using quotes in echo (using tee to display data)
  91.  
  92. # System Wake Up Action
  93. file=$dir/system-wake-up_gnome-calendar.service
  94. sudo tee $file > /dev/null << EOF
  95. [Unit]
  96. Description=System Wake Up Action
  97. [Service]
  98. ExecStart=/usr/bin/true
  99. EOF
  100.  
  101. sudo systemctl daemon-reload
  102. if ! systemctl -q is-enabled system-wake-up_gnome-calendar.timer; then
  103. sudo systemctl enable system-wake-up_gnome-calendar.timer
  104. fi
  105. sudo systemctl restart system-wake-up_gnome-calendar.timer
  106.  
  107. # User Wake Up Timer (needed to play sound notification)
  108. dir=~/.config/systemd/user
  109. mkdir -p $dir
  110.  
  111. file=$dir/wake-up_gnome-calendar.timer
  112. cat > $file << EOF
  113. [Unit]
  114. Description=User Wake Up Timer
  115. [Install]
  116. WantedBy=timers.target
  117. [Timer]
  118. Persistent=true
  119. AccuracySec=1us
  120. EOF
  121. #for item in ${time[@]}
  122. #do
  123. # date=`date +'%Y-%m-%d %H:%M:%S' -d "@$item"`
  124. # echo "OnCalendar=$date" >> $file
  125. #done
  126. echo "$time" >> $file
  127.  
  128. # User Wake Up Action
  129. file=$dir/wake-up_gnome-calendar.service
  130. # When the sleep command waits a few seconds or minutes between sound notifications, automatic sleep is not working even after "gnome-session-inhibit --inhibit suspend --inhibit-only" process ends or starting bash with "gnome-session-inhibit --inhibit suspend" so we need to execute "systemctl sleep" at the end of the service file script (the device will only sleep if there is no other gnome-session-inhibit preventing sleep) or use RuntimeMaxSec (which takes more time before going to sleep)
  131. # also using RuntimeMaxSec to avoid issue of automatic sleep before a second alarm ended like it happened with the script for Gnome Clocks
  132. # RuntimeMaxSec is needed if we play sound indefinitely (e.g. the command does not terminate like cvlc) and to allow future sound notifications if paused in notifications screen
  133. # RuntimeMaxSec must be at least 15 seconds since 10 seconds is not enough to display visual notification and make the notification led blink (710 seconds which includes by default the 2 sleeps of 300 seconds to allow repeating the sound 3 times within around 10 minutes, adding 105 seconds if we play a sound of 35 seconds by using mpv --loop=4 to play 5 times a sound of less than 7 seconds, adding 5 seconds to have time to finish script by ending process gnome-session-inhibit and going to sleep)
  134. # gnome-session-inhibit needed to get the blinking notification led and to allow repeating sound notifications within 10 minutes to bypass the default sleep time after 5 minutes (sleep of 295 instead of 300 seconds is not needed since automatic sleep that starts at 300 seconds by default is inhibited)
  135. # Trying to disable the blue led that randomly stays on during sleep is not working with "echo 0 > /sys/class/leds/blue\:indicator/brightness" (error "Device or resource busy")
  136. cat > $file << EOF
  137. [Unit]
  138. Description=User Wake Up Action
  139. [Service]
  140. ExecStart=kgx -e bash -c "gnome-session-inhibit --inhibit suspend --inhibit-only & pid=\$!; command=\"mpv --loop=4 $sound_file\"; for((i=1;i<3;++i)); do \$command; sleep 300; done; \$command; kill \$pid; systemctl sleep"
  141. RuntimeMaxSec=710
  142. EOF
  143.  
  144. systemctl --user daemon-reload
  145. if ! systemctl --user -q is-enabled wake-up_gnome-calendar.timer; then
  146. systemctl --user enable wake-up_gnome-calendar.timer
  147. fi
  148. systemctl --user restart wake-up_gnome-calendar.timer
  149.  
  150.  
  151. # gnome-calendar_wake_up_autostart.py
  152. #!/usr/bin/env python3
  153. # Extract alarm trigger time of calendar events (combining event time and reminder time)
  154. # https://icalendar.readthedocs.io/en/latest/how-to/usage.html#read-calendar-from-file
  155. # https://icalendar.readthedocs.io/en/latest/reference/api/icalendar.cal.event.html#icalendar.cal.event.Event.alarms
  156. # Not displaying a warning if ACTION is of type AUDIO instead of DISPLAY to avoid additional loop (https://github.com/collective/icalendar/issues/1421)
  157.  
  158. import icalendar
  159. from pathlib import Path
  160. ics_path = Path("/home/mobian/.local/share/evolution/calendar/system/calendar.ics")
  161. calendar = icalendar.Calendar.from_ical(ics_path)
  162. for event in calendar.events:
  163. #print(int(event.alarms.times[0].trigger.timestamp())) # only needed if we want to substract seconds to wake up system earlier
  164. print("OnCalendar=" + str(event.alarms.times[0].trigger))
  165.  
  166.  
  167. # gnome-calendar_wake_up_autostart.sh
  168. #!/usr/bin/env bash
  169. # Script to call in a desktop file in ~/.config/autostart/ to play an alarm sound for Gnome Calendar event reminders from the last 15 minutes in case a UI like Phosh restarts after a crash that can happen even without user interaction (tested with Mobian / Phosh on the PinePhone)
  170. # A desktop file gnome-calendar_wake_up_autostart.desktop can be created with this content (without # at the beginning of lines, adjust executable path if needed):
  171. # [Desktop Entry]
  172. # Type=Application
  173. # Exec=bash -c 'source ~/.local/share/pipx/venvs/icalendar/bin/activate && ~/Downloads/scripts/gnome-calendar_wake_up_autostart.sh'
  174.  
  175. python_script="gnome-calendar_wake_up_autostart.py" # file is expected to be in the same folder as gnome-calendar_wake_up.sh
  176. # Copy the calendar original sound file /usr/share/sounds/freedesktop/stereo/alarm-clock-elapsed.oga to another location to avoid missing file after update (canberra-gtk-play only prevents error for path change)
  177. sound_file="/home/mobian/Downloads/alarm-clock-elapsed.oga" # only works with full path, not ~/Downloads/alarm-clock-elapsed.oga
  178.  
  179. path=`dirname $0`
  180.  
  181. time=`$path/$python_script`
  182. date=`date +%s`
  183. for item in ${time[@]}
  184. do
  185. diff=$(($date - $item))
  186. if (($diff >= 0 && $diff <= 900)); then
  187. kgx -e bash -c "gnome-session-inhibit --inhibit suspend --inhibit-only & pid=\$!; command=\"mpv --loop=4 $sound_file\"; for((i=1;i<3;++i)); do \$command; sleep 300; done; \$command; kill \$pid; systemctl sleep"
  188. fi
  189. done
  190.  
Advertisement
Add Comment
Please, Sign In to add comment