Raspberry Booting Services

Creating a Raspberry Pi service

Introduction

There are several ways to execute a piece of code when your Raspberry Pi boots. You can, for instance, use the nickname @reboot in crontab in order to launch an script after rebooting your machine. You can also configure crontab to run the script every X minutes. However, if you want to create a Raspberry Pi service that runs at boot time, considers dependencies and keeps on running in the background, you should use systemd.

Creating a Raspberry Pi service

Systemd is an init system used in Linux distributions to bootstrap the user space and to manage system processes after booting. It includes a collection of tools for a range of different tasks. Its primary purpose is to initialise, manage and track system services and daemons, both during start-up and while the system is running.

Monitoring Raspberry temperature with a service

In this example we will create a service that monitors the Raspberry temperature. This service will send an IFTTT notification to the configured smartphone containing the Raspberry’s Pi temperature when this is greater than a certain value. We want to run this script automatically when booting the system, and let it running forever. This is the bash code of our script:

#/bin/bash

maxTemp=65
minuteEnd=1
tag="tempMonitor"

while true
do
   GPUTemp=$(echo $(/opt/vc/bin/vcgencmd measure_temp) | egrep -o '[0-9]{2}.[0-9]{1}')
   CPUTemp=$(sed "s/\(...\)$/.\1/" < /sys/class/thermal/thermal_zone0/temp | egrep -o '[0-9]{2}.[0-9]{1}')

   if (( $(echo "$GPUTemp $maxTemp" | awk '{print ($1 > $2)}') )) || (( $(echo "$CPUTemp $maxTemp" | awk '{print ($1 > $2)}') ));
   then
      logger -t $tag "Sending alarm. CPU Temp: $CPUTemp. GPU Temp: $GPUTemp"
      curl -X POST -H "Content-Type: application/json" -d '{"value1":"'$CPUTemp'", "value2":"'$GPUTemp'"}' https://maker.ifttt.com/trigger/[YOUR_EVENT_NAME]/with/key/[YOUR_IFTTT_KEY] 2>1
   fi

loopWaitTime=$(( (((60 * (10 - ($(date +%-M) % 10))) + ((( minuteEnd * 60 )) - $(date +%-S))) % 300 ) ))
sleep $loopWaitTime

done

In order to know more about the IFTTT applets, read this post. I have used egrep to extract the temperatures with one decimal and awk to compare floating numbers. logger is used to log the sent alarms, as well as the temperatures recorded, in the system log syslog with the tag tempMonitor. The script will sleep and wake up in the minutes ended in 1 or 6 (01, 06, 11, 16, etc.). To know more about how to calculate this sleep time, see the following post.

Creating a service

To convert the previous script into a service, start creating a .service file with the following structure:

vi /home/dani/scripts/tempMonitor/tempMonitor.service

[Unit]
Description=Raspberry Temperature Monitor
After=network-online.target

[Service]
ExecStart=/bin/bash /home/dani/scripts/tempMonitor/tempMonitor.sh
WorkingDirectory=/home/dani/scripts/tempMonitor/
StandardOutput=inherit
StandardError=inherit
Restart=always
User=dani

[Install]
WantedBy=multi-user.target

Just adapt the code to the path used in your system. The line After=network-online.target will postpone the start of the service until the network is in up status. If you want to know more about some of the options used, I recommend you to read the following article.

Now copy the file into /lib/systemd/system with root user:

sudo cp /home/dani/scripts/tempMonitor/tempMonitor.service /lib/systemd/system/

Testing the service

Once this has been copied, you can attempt to start the service using the following command:

sudo systemctl start tempMonitor.service

Check if it is running correctly by doing:

sudo systemctl status tempMonitor.service

● tempMonitor.service - Raspberry Temperature Monitor
Loaded: loaded (/lib/systemd/system/tempMonitor.service; disabled)
Active: active (running) since dom 2018-02-04 19:43:11 CET; 2s ago
Main PID: 5709 (bash)
CGroup: /system.slice/tempMonitor.service
├─5709 /bin/bash /home/dani/scripts/tempMonitor/tempMonitor.sh
└─5728 sleep 300

feb 04 19:43:11 TrastoRaspberry systemd[1]: Started Raspberry Temperature Monitor.

Stop it using the following command:

sudo systemctl stop tempMonitor.service

And check again if the script is correctly stopped. Once everything is checked, you can configure your service to start automatically on reboot by using the following command:

sudo systemctl enable tempMonitor.service

From now on, you can check easier the status of the service by doing:

sudo service tempMonitor status/start/stop

Raspberry Pi service CPU Temp IFTTT Notification

10 thoughts on “Creating a Raspberry Pi service”

  1. Nice write up. Been searching most of the day on getting a script to run at bootup. Kept failing. Your instructions came up in a search and it worked.

  2. I am getting this problem:

    Active: failed (Result: exit-code) since Wed 2021-04-07 12:04:43 CDT; 16s ago

    when I check the status after starting the service. Have you seen this before?

  3. the examle script seems not to be up to date anymore, I’m getting errors starting it.
    the path to vcgencmd does not exist, actual is /bin/vcgencmd
    “<” now seems to be “<",
    the > also causes error messages:
    Feb 07 17:10:45 Medienserver bash[26739]: awk: 1: unexpected character '&'
    Feb 07 17:10:45 Medienserver bash[26739]: awk: line 1: extra ')'
    Feb 07 17:10:46 Medienserver bash[26742]: awk: 1: unexpected character '&'
    Feb 07 17:10:46 Medienserver bash[26742]: awk: line 1: extra ')'

    and calling man awk comes manual mawk, probably a newer version
    dont get the script flying, but in general the article is good for understanding services

Leave a Comment