Start a Python script as a service on your Raspberry Pi

If you look up the Internet for the exact (or a similar) phrase, you’ll probably end up with a bunch of results explaining how to accomplish exactly that, in 2 to probably 3 different ways. I don’t know, there may be more, but this is an outline of my preferred way, and that is… as a service!

But, instead of doing this on the real HW, I decided I’m going to try it on an emulated Raspberry Pi, because I know the real deal works ‘just as well’. 🙂

There are plenty of tutorials on how to emulate a RPi, but I found this one very pleasant to follow: Raspberry Pi Emulator for Windows 10 Full Setup Tutorial and Speed Optimization. Kudos for that Jonathan! Note: as a homework assignment, I’ll try and repeat the same on my Linux machine. Note Note: If you follow the tutorial by using using the latest version of qemu, you’ll probably end up as me, with the following error when attempting to launch the start.bat script for the first time:

qemu-system-arm: -redir: invalid option

After some digging up, it turns out the -redir option has been deprecated in qemu, so instead of updating the script (another homework assignment for me :)), I decided to use the exact same qemu version as in the tutorial.

And again, I was warned about the -redir option being deprecated, albeit not so loudly this time:

qemu-system-arm: -redir tcp:2222::22: The -redir option is deprecated. Please use ‘-netdev user,hostfwd=…’ instead.

On top, I was greeting with this error:

Error: unrecognized/unsupported machine ID (r1 = 0x00000183).

Which led me to this post: Cross-compile Linux kernel for ARM and run on QEMU, where it’s nicely explained it’s ‘a kernel issue’, or rather ‘not having the SoC board code inside the kernel itself’ (due to issues linked to maintainability of the kernel itself…), and in my case: I used the latest ‘stretch’ release instead of the ‘jessie’ release of the qemu kernel as explained in the tutorial. This is quickly turning out to be a ‘My take on running a virtualized RPi using qemu’ instead of intended howto title!? 🙂

I finally got it to work:

Python script as a service

But to be perfectly honest, it wasn’t really worth the effort! It’s excruciatingly slow and  I don’t see any other reason going this route unless you don’t own a Raspberry Pi and you really need to test a piece of software (given the fact you cannot really test any hardware!), which is highly unlikely given the cost of a RPi!? If you do own one, I highly recommend doing a headless Raspbian install (you can look this up on the Internet) and then enable SSH (supposedly by placing an empty file with the name ‘ssh’ into the ‘boot’ folder of the RPi microSD card), enable VNC and so  on and so forth!

For my virtualized RPi I have enabled SSH and reconfigured it to boot in the terminal mode as the pi user, and used PuTTY (IP: 127.0.0.1, port: 2222) to connect to my ‘RPi’:

RPi under Qemu with SSH

Anyway, back to my topic!

 

Step 1

In your home folder, I suggest you first create a directory which will hold your Python scripts and a sub-directory which will hold the log files for the service scripts:

mkdir ~/Scripts

mkdir ~/Scripts/Logs

 

Step 2

Create a new Python script file under the Scripts folder:

touch ~/Scripts/ServiceScript.py

 

Step 3

Edit the file:

nano ~/Scripts/ServiceScript.py

and add whatever functionality you need to be launched at startup, e.g.:

print(“Python script launched as a service!”)

 

Step 4

Make sure your script executes correctly inside the terminal:

python3 ~/Scripts/ServiceScript.py

 

Step 5

Create your unit service file:

sudo touch /lib/systemd/system/ServiceScript.service

and edit it:

sudo nano /lib/systemd/system/ServiceScript.service

 

Step 6

Enter the following contents (e.g.) and save it:

[Unit]

Description=My Python script running as a service on boot up

After=multi-user.target

 

[Service]

Type=idle

ExecStart=/usr/bin/python3 /home/pi/Scripts/ServiceScript.py

StandardOutput=syslog

StandardError=syslog

SyslogIdentifier=ServiceScript

 

[Install]

WantedBy=multi-user.target

 

Step 7

Change the permission to the unit file:

sudo chmod 644 /lib/systemd/system/ServiceScript.service

 

Step 8

Put the changes made in /lib/systemd/system into an effect:

sudo systemctl daemon-reload

and enable your service:

sudo systemctl enable ServiceScript.service

 

Step 9

Create the following file:

sudo nano /etc/rsyslog.d/ServiceScript.conf

and add the following contents to it:

if $programname==’ServiceScript‘ then /home/pi/Scripts/Logs/ServiceScript.log & stop

 

Step 10

Re-start rsyslog:

sudo systemctl restart rsyslog

 

Step 11

At this point, you can either start your service by issuing:

sudo systemctl start ServiceScript.service

and see the immediate effect, or you can reboot your RPi by issuing:

sudo shutdown -r now

 

Step 12

Either way, you can see the output of your script by issuing:

sudo journalctl -u ServiceScript

Or also in your own log file, by issuing:

cat ~/Scripts/Logs/ServiceScript.log

 

And that’s a wrap! Credits go to: Five Ways To Run a Program On Your Raspberry Pi At Startup, How to redirect output of systemd service to a file & How to run a script as a service in Raspberry Pi – Raspbian Jessie where I got my inspiration from!