2

I am totally new to raspberry pi and I am trying to get the IRSEND command to work in my custom service. My objective is when my pi is about to shutdown or reboot that it would execute a shell script that sends the command

irsend SEND_ONCE 'TVNAME' KEY_POWER

from my pi to the transmitter. I wrote a service in /etc/systemd/system/myservice.service Within that that service file I have:

[Unit]
Description=Turn off tv and lights on shutdown
DefaultDependencies=no

[Service]
Type=oneshot
ExecStart=/bin/bash /usr/bin/myscript.sh


[Install]
WantedBy=shutdown.target reboot.target halt.target

After I created the service I did sudo systemctl daemon-reload and sudo systemctl enable myservice.service.

When I start the service on the command prompt it executes just fine, but when I shutdown or reboot the Pi the TV is still on. Any clues or pointers as to what I am doing wrong?

4
  • I am a little bit confused. Do you mean this: (1) Your service/ bash script with irsend command can switch off you home TV set, when running by a terminal command. (2) But when using systemctl to execute the same command when shut down or reboot, the TV refuses to go off?
    – tlfong01
    Mar 6, 2020 at 5:35
  • 1
    @tlfong01 So when I execute my bash script through the command line everything works fine. Then when I execute sudo systemctl start myservice.service on the command line everything works fine. But when I say sudo shutdown now the tv does not turn off. I know it is executing my shell script when it shuts down because I have a python script that shuts off an led light that is controlled by a gpio pin.
    – Ikigai99
    Mar 6, 2020 at 16:05
  • 1
    how do you know that the script turns off the LED? ... it could be the shutdown that turns it off
    – jsotola
    Mar 7, 2020 at 0:12
  • 1
    @jsotola I know the script is turning it off because they are the neo pixel lights that are being powered by an external 5v power supply and won't shut off unless I unplug the lights from the power source or tell it through code to go low.
    – Ikigai99
    Mar 7, 2020 at 1:14

2 Answers 2

1

Maybe LIRC service shuts down before your custom service has a chance to run?

Try adding

[Unit]
Requires=lircd.service

To your service file.

Another idea is to specify the relationship with shutdown/reboot targets in [Unit] section rather than [Install]. Normally, both should work but it doesn't hurt to try:

[Unit]
Before=shutdown.target reboot.target halt.target
1

In your unit file you are using ExecStart= and yes, it is just doing what it is named: it will start the service. To run a script only on shutdown you have to use ExecStop= so your Unit should look similar to this:

[Unit]
Description=Turn off tv and lights on shutdown
After=graphical.target

[Service]
Type=oneshot
RemainAfterExit=yes
User=pi
WorkingDirectory==/home/pi
ExecStop=/full/path/to/irsend SEND_ONCE 'TVNAME' KEY_POWER

[Install]
WantedBy=graphical.target



UPDATE: because of the discussion in the comments, here some tests I have made to get an idea how it works.

Look at the properties to find runtime dependencies with:

rpi ~$ systemctl show shutdown-test.service

To get dependencies:

rpi ~$ systemctl list-dependencies shutdown-test.service

Documentation of the System Manager Shutdown phase.

To get shutdown messages from the systemd journal I made it persistent:

rpi ~$ sudo mkdir -p /var/log/journal
rpi ~$ sudo systemd-tmpfiles --create --prefix /var/log/journal

After reboot then look at the previous journal before booting with:

rpi ~$ journalctl --boot=-1

If you modify the [Install] section, don`t forget to:

rpi ~$ sudo systemctl disable shutdown-test.service
rpi ~$ sudo systemctl enable shutdown-test.service

To be on the save side boot two times after modifying the Unit file. I have seen situations where on first boot only the changes are registered and take effect after the second boot. Use correct targets as shown in System Manager Shutdown, in particular with WantedBy.

Test Case 1:

[Unit]
Description=Shutdown Test
DefaultDependencies=no
[Service]
Type=oneshot
ExecStart=/bin/echo 'shutdown test executed'
[Install]
WantedBy=reboot.target poweroff.target halt.target kexec.target

# dependencies
shutdown-test.service
● └─system.slice

rpi ~$ journalctl --boot=-1 --unit=shutdown-test.service
-- Logs begin at Sat 2020-03-07 14:45:36 GMT, end at Sat 2020-03-07 18:41:01 GMT. --
Mar 07 18:40:04 raspberrypi systemd[1]: Starting Shutdown Test...
Mar 07 18:40:05 raspberrypi echo[708]: shutdown test executed
Mar 07 18:40:06 raspberrypi systemd[1]: shutdown-test.service: Succeeded.
Mar 07 18:40:06 raspberrypi systemd[1]: Started Shutdown Test.

Note that the service is only started in the general shutdown stage but not stopped. This is for my opinion not a clean service management. In the shutdown stage there should services only stop not start.

# snippet from the journal
rpi ~$ journalctl --boot=-1 | egrep ' Stopp| Start| echo'
Mar 07 18:48:32 raspberrypi systemd[1]: Stopping LVM event activation on device 179:2...
Mar 07 18:48:32 raspberrypi systemd[1]: Stopped target Graphical Interface.
                                        ^^^^^^^
Mar 07 18:48:32 raspberrypi systemd[1]: Stopped target Multi-User System.
                                        ^^^^^^^
Mar 07 18:48:32 raspberrypi systemd[1]: Stopping Availability of block devices...
Mar 07 18:48:32 raspberrypi systemd[1]: Stopped target Bluetooth.
Mar 07 18:48:32 raspberrypi systemd[1]: Stopping Bluetooth service...
Mar 07 18:48:32 raspberrypi systemd[1]: Starting Shutdown Test...
                                        ^^^^^^^^
Mar 07 18:48:32 raspberrypi systemd[1]: Stopped target Sound Card.
Mar 07 18:48:32 raspberrypi systemd[1]: Stopped target Login Prompts.
Mar 07 18:48:32 raspberrypi echo[715]: shutdown test executed
                            ^^^^
Mar 07 18:48:32 raspberrypi systemd[1]: Stopping Serial Getty on ttyS0...
--- snip ---
Mar 07 18:48:33 raspberrypi systemd[1]: Started Shutdown Test.
                                        ^^^^^^^
Mar 07 18:48:33 raspberrypi systemd[1]: Stopped Save/Restore Sound Card State.
Mar 07 18:48:33 raspberrypi systemd[1]: Stopped dphys-swapfile - set up, mount/unmount, and delete a swap file.
Mar 07 18:48:33 raspberrypi systemd[1]: Stopped rng-tools.service.

As you can see there are no dependencies because they are disabled. So the Shutdown Test is started after Stopped target Graphical Interface and Multi-User System. Stopping services is random.

Test Case 2:

With DefaultDependencies=yes the shutdown-test.service is never executed:

rpi ~$ journalctl --boot=-1 --unit=shutdown-test.service
-- Logs begin at Sat 2020-03-07 14:55:33 GMT, end at Sat 2020-03-07 19:06:49 GMT. --
-- No entries --

Test Case 3:

[Unit]
Description=Shutdown Test
After=graphical.target
[Service]
Type=oneshot
RemainAfterExit=yes
ExecStop=/bin/echo 'shutdown test executed'
[Install]
WantedBy=graphical.target

rpi ~$ journalctl --boot=-1 --unit=shutdown-test.service
-- Logs begin at Sat 2020-03-07 14:56:33 GMT, end at Sat 2020-03-07 19:14:00 GMT. --
Mar 07 19:12:19 raspberrypi systemd[1]: Started Shutdown Test.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopping Shutdown Test...
Mar 07 19:13:03 raspberrypi echo[715]: shutdown test executed
Mar 07 19:13:03 raspberrypi systemd[1]: shutdown-test.service: Succeeded.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped Shutdown Test.

# snippet from the journal
Mar 07 19:13:03 raspberrypi systemd[1]: Stopping Bluetooth service...
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped Daily apt download activities.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped target System Time Synchronized.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopping Shutdown Test...
                                        ^^^^^^^^
Mar 07 19:13:03 raspberrypi echo[715]: shutdown test executed
                            ^^^^
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped Bluetooth service.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped LVM event activation on device 179:2.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped Shutdown Test.
                                        ^^^^^^^
Mar 07 19:13:03 raspberrypi systemd[1]: Stopping User Manager for UID 1000...
Mar 07 19:13:03 raspberrypi systemd[649]: Stopped target Default.
Mar 07 19:13:03 raspberrypi systemd[649]: Stopped target Basic System.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped target Graphical Interface.
                                        ^^^^^^^
Mar 07 19:13:03 raspberrypi systemd[649]: Started Exit the Session.
Mar 07 19:13:03 raspberrypi systemd[1]: Stopped target Multi-User System.
                                        ^^^^^^^
Mar 07 19:13:03 raspberrypi systemd[1]: Stopping Login Service...
Mar 07 19:13:03 raspberrypi systemd[1]: Stopping dphys-swapfile - set up, mount/unmount, and delete a swap file...

Here is everything as expected. The service is starting on bootup and stopping within the shutdown stage like any other service. We have default dependencies and defined After=graphical.target in the Unit, which ensures that the Shutdown Test stops before target Graphical Interface. So my suggestion is: to avoid problems with dependencies you should use this Unit as template.

If your shutdown script still doesn't run, you should check if it find the same environment when starting from the command line. Maybe there is a path, environment variable, or library missing. Check the journal for error messages, execute systemctl status myservice.service. I have modified the Unit file to possibly meet some of these conditions.

4
  • 1
    Note that the OP is using "shutdown" as a WantedBy target, and ExecStart for shutdown should happen at about the same time as ExecStop for "multi-user". It should not run on RPi startup. Mar 6, 2020 at 11:43
  • 1
    @DmitryGrigoryev DefaultDependencies are that shutdown.target conflicts with any other service that should start. The OP has set DefaultDependencies=no so I do not oversee the implication just in conjunction with shutdown.target. I will have a further look at it but I believe its better to run with DefaultDependencies.
    – Ingo
    Mar 6, 2020 at 13:18
  • 1
    So I went and changed my service script to match what Ingo had posted and it had no effect to turning off the TV. Then I went and added Requires=lircd.service under unit and placed Before=shutdown.target reboot.target halt.target as @DmitryGrigoryev had suggested and result was the same.
    – Ikigai99
    Mar 6, 2020 at 15:59
  • 1
    @Ikigai99 I have modified the example Unit and made some tests.
    – Ingo
    Mar 7, 2020 at 20:11

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.