4

I have a raspberry pi python3 program "monitor.py" that works from the terminal
But it fails to run when I start it from boot.

Check status:

pi@raspberrypi:~ $ systemctl status monitor.service

● monitor.service - Service to start monitor in terminal on desktop  
  Loaded: loaded (/etc/systemd/system/monitor.service; enabled; vendor preset: enabled)  
   Active: failed (Result: exit-code) since Tue 2019-01-01 14:56:31 MST; 55s ago
  Process: 624 ExecStart=/usr/bin/python3 /home/pi/monitor.py >> /home/pi/Desktop/monitor.log (code=exited, status=1/  
 Main PID: 624 (code=exited, status=1/FAILURE)  

Jan 01 14:56:30 raspberrypi systemd[1]: Started Service to start monitor in terminal on desktop.  
Jan 01 14:56:31 raspberrypi python3[624]: Traceback (most recent call last):  
Jan 01 14:56:31 raspberrypi python3[624]:   File "/home/pi/monitor.py", line 6, in <module>  
Jan 01 14:56:31 raspberrypi python3[624]:     **cf = open (cmdfile,"w")**  
Jan 01 14:56:31 raspberrypi python3[624]: PermissionError: [Errno 13]   **Permission denied: 'cmdfile.txt'**  
Jan 01 14:56:31 raspberrypi systemd[1]: monitor.service: Main process exited, code=exited, status=1/FAILURE  
Jan 01 14:56:31 raspberrypi systemd[1]: monitor.service: Unit entered failed state.  
Jan 01 14:56:31 raspberrypi systemd[1]: monitor.service: Failed with result 'exit-code'.

Check for permissions:

pi@raspberrypi:~ $ ls -l cmdfile.txt
-rw-rw-rw- 1 pi pi 1 Dec 31 21:09 cmdfile.txt
pi@raspberrypi:~ $ ls -l monitor.py
-rwxrw-rw- 1 pi pi 506 Jan  1 09:50 monitor.py
pi@raspberrypi:~ $ ls -l /lib/systemd/system/monitor.service
-rwxr--r-- 1 root root 224 Dec 30 13:09 /lib/systemd/system/monitor.service
pi@raspberrypi:~ $ ls -l /home/pi/Desktop/monitor.log
-rw-r--r-- 1 pi pi 0 Jan  1 10:29 /home/pi/Desktop/monitor.log

The program monitor.py:

#!/usr/bin/python3

import time

cmdfile = "cmdfile.txt"
cf = open(cmdfile,"w")
cmd = 1
cf.write(str(cmd))
cf.close
isRunning = cmd
cntr = 0
wait = 10

while isRunning == cmd:
    cntr += 1
    print("Hello World:", cntr)
    cf = open(cmdfile,"r")
    cmd = int(cf.read())
    cf.close
    if isRunning != cmd:
        print("check interrupt")
        if cmd == 0:
            import os
            os.system("sudo reboot -h now")
        else: # incremented
            exit()

    time.sleep(wait)

The systemctl monitor.service:

[Unit]
Description=Service to start monitor in terminal on desktop
Wants=graphical.target
After=graphical.target
After=multi-user.target

[Service]
User=pi
Type=idle
ExecStart=/usr/bin/python3 /home/pi/monitor.py &  

[Install]
WantedBy=graphical.target
WantedBy=multi-user.target

Enable the new service:

pi@raspberrypi:~ $ sudo chmod 744 /lib/systemd/system/monitor.service
pi@raspberrypi:~ $ sudo systemctl daemon-reload
pi@raspberrypi:~ $ sudo systemctl enable monitor.service

Test the program:

pi@raspberrypi:~ $ ./monitor.py  #note dot at start of the line
Hello World: 1
Hello World: 2
Hello World: 3

Restart:

pi@raspberrypi:~ $ sudo reboot

Check Status:

pi@raspberrypi:~ $ systemctl status monitor.service

Stop: (requires password)

pi@raspberrypi:~ $ systemctl stop monitor.service

Edit again with:

pi@raspberrypi:~ $ sudo systemctl --full edit monitor.service

Edit Note -- modified the above: in monitor.service I changed the following.
Was:

ExecStart=/usr/bin/python3 /home/pi/monitor.py >> /home/pi/Desktop/monitor.log  

Now:

ExecStart=/usr/bin/python3 /home/pi/monitor.py &

To remove the log (simplify) and add the & (to exit)
It still fails but there is one less thing to question.

Ingo
  • 42,961
  • 20
  • 87
  • 207

1 Answers1

4

You'll need to add a working directory to your unit file as the Pi user won't have write access to put cmdfile.txt into the root of the volume (or whereever systemd roots itself).

in your Unit file add...

[Service]
WorkingDirectory=/home/pi

...and reload the daemon. You can change this to where you want but it must be somewhere pi can write to.