I have a question about systemd .timer and .service functionality.
I’m trying to find a way to open VLC in terminal (nvlc) and start a radio stream at a specific time.
The end goal is to have my computer wake up from suspend and start playing music in the mornings.
This is what I have so far:
radio.timer:
[Unit]
Description=Stream radio through nvlc
[Timer]
# Run the service every day
#OnCalendar=*-*-* 07:30:00
OnUnitActiveSec=2min
WakeSystem=true
Unit=radio.service
[Install]
#WantedBy=default.target
#WantedBy=multi-user.target
WantedBy=timers.target
radio.service:
[Unit]
Description=Stream radio through nvlc
StopWhenUnneeded=true
[Service]
Type=simple
User=bart
Group=users
#Environment="QT_PLUGIN_PATH=/usr/lib64/qt5/plugins/platforms"
#Environment="QT_QPA_PLATFORM=/usr/lib64/qt5/plugins/platforms"
Environment="QT_QPA_PLATFORM_PLUGIN_PATH=/usr/lib64/qt5/plugins/platforms"
ExecStart=/home/bart/bin/scripts/radio.sh
[Install]
#WantedBy=default.target
WantedBy=multi-user.target
I get this with or without the QT_QPA_PLATFORM_PLUGIN_PATH env var.
I’m guessing this has to do with running the script through systemd and not a regular user ?
Also not sure about the WantedBy= directives…
How do solve this?
You do not show where all those files are (we prefer to seen complete command/ouput copy/pastes, in this case the cat statements are missing). Are these system or user files?
Then you say your system “wakes up from suspend”, but you do not tell how (maybe I am to stupid to understand this). But there is no information on in what status the system is the. Are there one or more users logged in (in the CLI or in the GUI). You are talking about konsole, thus it looks as if you assume that there is at least one user logged in in the GUI and uses KDE. Is that true?
Then, when these systemd files are managed on the system level, it is clear that what is defined in ExecStart is started as a root owned process in the background. That process will not know where to open the window with konsole.
Yes, of course, that works. The problem is the combination with wake up from suspend.
AFAIK, the wake up can only be done through system service, not a user service.
But I haven’t even gotten to that part yet, I’m still trying to run the script as the given user/group (as given in {Service} block).
Manual says to use those directives to “override” the root user which runs the service manager (at least, that’s my understanding).
Even if it runs as user bart (in the background), it still does not know that it must use some DISPLAY to open the window on. You forgot that Unix/Linux is a multi-user/multi-session system. There can be nil, one, two or more GUI sessions running when that script starts. Which one to use? And then still that user will normally have blocked the outside world from opening windows in his/her session (imagine when every user on the system could open windows in your personal session, that would include an invisible window over the whole space that even could see what you type).
I doubt. When the system sleeps, no systemd deamon will run to activate services. Thus my question (you did not answer) how is the “wake from suspend” done>
Program started outside of your session knows nothing about X11/Wayland server it needs to connect to nor does it have any of the environment usually set when your session is started. If your user session (and so systemd instance) remains active, you can initiate user service using
It will connect to your systemd user instance and create transient service running the given command in your user environment. See man systemd-run for details.
erlangen:~ # systemctl status init.scope
● init.scope - System and Service Manager
Loaded: loaded
Transient: yes
Active: active (running) since Thu 2023-06-01 07:25:36 CEST; 47min ago
Docs: man:systemd(1)
Tasks: 1 (limit: 4915)
CPU: 1.691s
CGroup: /init.scope
└─1 /usr/lib/systemd/systemd --switched-root --system --deserialize=39
Jun 01 08:05:01 erlangen systemd[1]: Started Stream radio through nvlc.
Jun 01 08:05:01 erlangen systemd[1]: Started systemd-stdio-bridge -punix:path=${XDG_RUNTIME_DIR}/bus.
Jun 01 08:05:01 erlangen systemd[1]: Started Session 9 of User karl.
Jun 01 08:05:01 erlangen systemd[1]: run-u129.service: Deactivated successfully.
Jun 01 08:05:01 erlangen systemd[1]: radio0.service: Deactivated successfully.
Jun 01 08:05:01 erlangen systemd[1]: session-9.scope: Deactivated successfully.
Jun 01 08:06:37 erlangen systemd[1]: Started systemd-stdio-bridge.
Jun 01 08:06:37 erlangen systemd[1]: Started Session 10 of User karl.
Jun 01 08:06:37 erlangen systemd[1]: run-u133.service: Deactivated successfully.
Jun 01 08:06:37 erlangen systemd[1]: session-10.scope: Deactivated successfully.
erlangen:~ #
User systemd:
karl@erlangen:~> systemctl status --user init.scope
● init.scope - System and Service Manager
Loaded: loaded
Transient: yes
Active: active (running) since Thu 2023-06-01 07:26:02 CEST; 47min ago
Docs: man:systemd(1)
Tasks: 2 (limit: 4915)
Memory: 3.9M
CPU: 326ms
CGroup: /user.slice/user-1000.slice/user@1000.service/init.scope
├─6082 /usr/lib/systemd/systemd --user
└─6083 "(sd-pam)"
Jun 01 07:35:01 erlangen systemd[6082]: Started Stream radio through nvlc.
Jun 01 07:35:07 erlangen systemd[6082]: radio.service: Consumed 5.702s CPU time.
Jun 01 07:46:26 erlangen systemd[6082]: Started KMail - Mail Client.
Jun 01 07:54:38 erlangen systemd[6082]: Started KMail - Mail Client.
Jun 01 07:55:06 erlangen systemd[6082]: Started Firefox - Web Browser.
Jun 01 07:58:53 erlangen systemd[6082]: Started Firefox - Web Browser.
Jun 01 08:03:01 erlangen systemd[6082]: Started Stream radio through nvlc.
Jun 01 08:03:08 erlangen systemd[6082]: radio.service: Consumed 6.788s CPU time.
Jun 01 08:05:01 erlangen systemd[6082]: Started Stream radio through nvlc.
Jun 01 08:05:16 erlangen systemd[6082]: radio.service: Consumed 14.471s CPU time.
karl@erlangen:~>
Ok thanks for your replies, everyone.
So I followed the path @arvidjaar and @karlmistelberger suggested and managed to get the music playing
This brings me to the last step; putting it all together and have the system wake up from sleep through the timer.
To summarize; the workflow ATM is as follows:
I’m the sole user of the system, logged in all the time
putting system into sleep / suspend is done with power button / Ctrl+Alt+Del → select “Sleep”
radio.timer should wake system @ fixed time (OnCalendar= ) and execute radio-trigger.service
radio-trigger.service executes user service (radio.service)
OnCalendar= uses wallclock timer, not monotonic
WakeSystem= a different monotonic clock (CLOCK_BOOTTIME) is selected that continues to advance while the system is suspended and thus can be used as the trigger to resume the system.
The problem now is that if I enable WakeSystem, this actually prevents the system going into sleep mode.
I get this in dmesg output:
PM: suspend entry (shallow)
[103158.437593] Filesystems sync: 0.014 seconds
...
[103158.613636] sd 0:0:0:0: [sda] Stopping disk
[103159.714554] PM: Some devices failed to suspend, or early wake event detected
[103159.714923] sd 0:0:0:0: [sda] Starting disk
...
My current files are: /etc/systemd/system/radio.timer
[Unit]
Description=Trigger radio-trigger.service
[Timer]
# Run the service every day
OnCalendar=*-*-* 07:30:00
WakeSystem=true
Unit=radio-trigger.service
[Install]
WantedBy=timers.target
/etc/systemd/system/radio-trigger.service
[Unit]
Description=User radio service
Wants=network-online.target
After=network-online.target
[Service]
Type=oneshot
ExecStart=/usr/bin/systemctl --user -M bart@.host start radio.service
~/.config/systemd/user /radio.service
[Unit]
Description=Play Radio stream on wakeup
[Service]
Type=simple
ExecStart=/usr/bin/konsole --new-tab -e "nvlc http://ais-edge23-dal02.cdnstream.com:80/1340_128"
[Install]
WantedBy=multi-user.target
Any more insight is welcome, or alternative way to wake from suspend (cron ?)…
I’ve read a lot these days but nothing suggests this shouldn’t work…
I take the liberty to also quote from the man page:
WakeSystem=
Takes a boolean argument. If true, an elapsing timer will cause the system to resume from suspend, should it be suspended and if the system supports this. Note that this option will only make sure the system resumes on the appropriate times, it will not take care of suspending it again after any work that is to be done is finished. Defaults to false.
The bold part is mine. This points IMHO to the hardware/firmware of the system. Either it can, it can not, or it is configurable in the BIOS/UEFI.
BTW, it is still not clear to me why you want to run the music program with a terminal emulator (konsole). Direct starting it seems more logical to me. Or am I missing something?
Thank you, I noticed that part too.
Obviously, my computer can go into suspend mode - and resume - because I’ve been doing that (manually) for 10+ years now
I don’t see why it wouldn’t work through a service ? Seems more like order-of-execution problem, not hardware related.
The manual also doesn’t state this option can prevent the computer from going into sleep mode either, which is what’s happening now.
On the konsole part; it’s always open and it works for now. it’s not the major issue
OK seems like a permission issue, found this in journalctl:
jun 01 17:55:38 bart.tumbleweed systemd[1]: Failed to start System Suspend.
░░ Subject: A start job for unit systemd-suspend.service has failed
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ A start job for unit systemd-suspend.service has finished with a failure.
░░
░░ The job identifier is 56009 and the job result is failed.
jun 01 18:01:54 bart.tumbleweed (sd-pam)[7030]: pam_systemd(login:session): Failed to release session: Access denied
jun 01 20:42:52 bart.tumbleweed sudo[13687]: pam_unix(sudo:auth): conversation failed
jun 01 20:42:52 bart.tumbleweed sudo[13687]: pam_unix(sudo:auth): auth could not identify password for [root]
jun 01 20:47:37 bart.tumbleweed kernel: PM: Some devices failed to suspend, or early wake event detected
jun 01 20:47:43 bart.tumbleweed kernel: PM: Some devices failed to suspend, or early wake event detected
jun 01 20:47:48 bart.tumbleweed kernel: PM: Some devices failed to suspend, or early wake event detected
jun 01 20:47:48 bart.tumbleweed systemd-sleep[14060]: Failed to put system to sleep. System resumed again: Device or resource busy
░░ Subject: System sleep state suspend left
░░ Defined-By: systemd
░░ Support: https://lists.freedesktop.org/mailman/listinfo/systemd-devel
░░
░░ The system has now left the suspend sleep state.
Great insight from infamous host erlangen: it works.
erlangen:~ # journalctl --since 08:54 -u systemd-suspend.service -u radio0.timer -u radio0.service
Jun 02 08:54:21 erlangen systemd[1]: radio0.timer: Deactivated successfully.
Jun 02 08:54:21 erlangen systemd[1]: Stopped Stream radio through nvlc.
Jun 02 08:54:21 erlangen systemd[1]: Stopping Stream radio through nvlc...
Jun 02 08:54:21 erlangen systemd[1]: Started Stream radio through nvlc.
Jun 02 08:54:33 erlangen systemd[1]: Starting System Suspend...
Jun 02 08:54:33 erlangen systemd-sleep[24658]: INFO: Skip running /usr/lib/systemd/system-sleep/grub2.sleep for suspend
Jun 02 08:54:33 erlangen systemd-sleep[24656]: Entering sleep state 'suspend'...
Jun 02 08:55:08 erlangen systemd-sleep[24656]: System returned from sleep state.
Jun 02 08:55:09 erlangen systemd-sleep[24685]: INFO: Skip running /usr/lib/systemd/system-sleep/grub2.sleep for suspend
Jun 02 08:55:09 erlangen systemd[1]: Started Stream radio through nvlc.
Jun 02 08:55:09 erlangen systemd[1]: systemd-suspend.service: Deactivated successfully.
Jun 02 08:55:09 erlangen systemd[1]: Finished System Suspend.
Jun 02 08:55:09 erlangen systemd[1]: radio0.service: Deactivated successfully.
erlangen:~ #
User journal:
karl@erlangen:~> journalctl --since 08:54 --user --unit init.scope
Jun 02 08:55:09 erlangen systemd[6082]: Started Stream radio through nvlc.
Jun 02 08:55:09 erlangen systemd[6082]: Starting KScreen OSD service...
Jun 02 08:55:09 erlangen systemd[6082]: Started KScreen OSD service.
Jun 02 08:56:07 erlangen systemd[6082]: radio.service: Consumed 58.255s CPU time.
karl@erlangen:~>
erlangen smoothly suspended, resumed and played music.
erlangen:~ # systemctl cat radio0.timer
# /etc/systemd/system/radio0.timer
[Unit]
Description=Stream radio through nvlc
[Timer]
OnCalendar=*-*-* 08:55:00
WakeSystem=true
[Install]
WantedBy=timers.target
erlangen:~ #