Autostart and automatically restart Python Script Raspberry Pi - python

I know how to autostart a python script (or so I thought). But I want a programm or something, if my python script is not running anymore, it should start the script again. Has anyone a idea how to do this?
Edit:
I tried running it as a service but that didnt work.
import bluetooth
import pygame
pygame.mixer.init()
server_sock=bluetooth.BluetoothSocket( bluetooth.RFCOMM )
port = 22
server_sock.bind(("",port))
server_sock.listen(1)
client_sock,address = server_sock.accept()
print ("Verbindung Hergestellt mit: ", address)
while True:
recvdata = client_sock.recv(1024)
print ("Nachricht bekommen: %s" % recvdata)
pygame.mixer.pause()
if (recvdata == b"h"):
sound = pygame.mixer.Sound('/home/maxi/Desktop/test.wav')
playing = sound.play()
if (recvdata == b"p"):
sound = pygame.mixer.Sound('/home/maxi/Desktop/test2.wav')
playing = sound.play()
if (recvdata == b"k"):
break
client_sock.close()
server_sock.close()
My startscript is:
[Unit]
Description=MaxiTest
After=multi-user.target
[Service]
Type=simple
Restart=always
ExecStart=/usr/bin/python3 /home/maxi/Desktop/btsound1.py
[Install]
WantedBy=multi-user.target

You can search more about how a python script can perform as a service or daemon. There are many solutions in this link:
How to make a Python script run like a service or daemon in Linux
Between all solutions, I prefer 3 of them (I'm not very familiar with raspberry-pi, so check compatibility):
Cronjob: You can create a cronjob for the script and the OS will run it every x seconds/minutes/... automatically and periodically.
Systemctl/Systemd: Create a custom service file for your script and start and enable it in Systemd. A complete guide is here:
https://medium.com/codex/setup-a-python-script-as-a-service-through-systemctl-systemd-f0cc55a42267
You chose systemd (after editing);
In /PATH_project/ create 2 bash scripts like this:
#!/bin/bash
# This is start.sh
cd /home/maxi/Desktop/
/usr/bin/python3 btsound1.py
And create stop.sh:
#!/bin/bash
for KILLPID in `ps ax | grep ‘myservice’ | awk ‘{print $1;}’`; do
kill -9 $KILLPID;
done
Then give execution permission to both files using:
chmod a+x start.sh
chmod a+x stop.sh
Then create a myservice.service file in /etc/systemd/system :
[Unit]
Description=myservice service
Wants=network-online.target
After=network.target network-online.target
[Service]
Type=simple
Restart=always
ExecStart=/bin/bash /home/maxi/Desktop/start.sh
ExecStop=/bin/bash /home/maxi/Desktop/stop.sh
RestartSec=5
TimeoutSec=60
RuntimeMaxSec=infinity
PIDFile=/tmp/mydaemon.pid
[Install]
WantedBy=multi-user.target
Then:
sudo systemctl daemon-reload
sudo systemctl start myservice.service
sudo systemctl status myservice.service
Benefits of using such bash scripts is that you can handle some more things in this way. For example if you are using a virtual environment, you can use source activate in start.sh file before running the script.py .
Supervisord: Install Supervisor and create a supervisord.conf file for your script. A good guide is here:
https://csjourney.com/managing-processes-with-supervisor-in-depth-tutorial/

I found what was the problem. I used rc.local and started the program 10 seconds after boot. The system needed time first to set up before I could start the script.

Related

Can't get script to run from systemd or cron

I have a setup where I have a servercabinet with an external display that shows various system information. I only want it to turn on when I am present though, and I have made it soundactivated using SoundMeter https://github.com/shichao-an/soundmeter and a cheap USB microphone. When run manually everything works as it sohuld, but when i try to run it as a systemd service or a cronjob, it wont execute the second script that starts the display. From the logs I can see that Soundmeter works as it should, but it doesn't fire up the display.
Systemd service:
[Unit]
Description=Soundmeter
[Service]
Type=simple
Restart=always
#RestartSec=120
User=pi
ExecStart=/usr/local/bin/soundmeter -t +25 -a exec -e /opt/sysdroidUHHD/trigger.sh
[Install]
WantedBy=multi-user.target
Cronjob
#reboot /usr/local/bin/soundmeter -t +25 -a exec -e /opt/sysdroidUHHD/trigger.sh &
Contents of trigger.sh
#!/bin/bash
python3 /opt/sysdroidUHHD/sysdroid_main.py
exit 0
Any and all help is appreciated.
Remove that exit 0 from trigger.sh. Make sure your sysdroid_main.py starts some server or daemon that won't exit.

Autoboot pi program issue (Raspberry Pi 4 , Python 3)

I currently am running a program through Thonny, and I want to make the pi autoboot that program whenever it turns on. I currently have the pi 4, and the code is run on Python3. Have tried many ways to autoboot such as using rc local, and bash rc, but none seem to work.
I recommend using the autostart file.
Edit the following file:
sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
The default should look something like:
#lxpanel --profile LXDE-pi
#pcmanfm --desktop --profile LXDE-pi
#xscreensaver -no-splash
Add the command to run your script utilizing the # prefix and save. The new autostart file should look like:
#lxpanel --profile LXDE-pi
#pcmanfm --desktop --profile LXDE-pi
#xscreensaver -no-splash
#python3 /home/pi/your_script.py
More info: https://www.raspberrypi.org/forums/viewtopic.php?t=294014
By using things like .bashrc, your program will only get executed when you open a command prompt or terminal.
You can use systemd services:
create a file your_service.service in /etc/systemd/system/ (you need to be root, so use sudo). The filename will be the name of your service, without the .service extension (in this case your service will be named your_service)
put this in it (without the comments):
[Unit]
Description=A short description of your service
After=network.target # <-- put this if your script needs network, otherwise you can omit this line
StartLimitIntervalSec=0
[Service]
Type=simple
Restart=always # use this to always restart the script if the process ends. If your script only needs to run once at startup and is not a daemon, don't use this.
RestartSec=1
User=root # user account used to run the service
ExecStart=python3 /path/to/your/script.py
[Install]
WantedBy=multi-user.target
Then, you can start your script with this command:
sudo systemctl start your_service
You can finally enable the service to be run automatically at startup with this command:
sudo systemctl enable your_service
You can find more documentation / tutorials on systemd services and on all the available options in the following links:
https://medium.com/#benmorel/creating-a-linux-service-with-systemd-611b5c8b91d6
https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
https://www.freedesktop.org/software/systemd/man/systemd.service.html
https://wiki.archlinux.org/title/Systemd

How can I put my python code in startup in raspberry pi

I wanted to put my python code in boot in raspberry pi.
I tried rc.local, ./bashrc but while booting program is working & I am using opencv + camera +voice command. That's not working in boot.
Please give me a way to run voice + camera + opencv + python code in boot.
I would suggest to make it run as a service as mentioned in method 4 of following article:
https://www.dexterindustries.com/howto/run-a-program-on-your-raspberry-pi-at-startup/
Step 1– Create A Unit File
Open a sample unit file using the command as shown below:
sudo nano /lib/systemd/system/sample.service
Add in the following text :
[Unit]
Description=My Sample Service
After=multi-user.target
[Service]
Type=idle
ExecStart=/usr/bin/python /home/pi/sample.py
[Install]
WantedBy=multi-user.target
You should save and exit the nano editor.
This defines a new service called “Sample Service” and we are requesting that it is launched once the multi-user environment is available. The “ExecStart” parameter is used to specify the command we want to run. The “Type” is set to “idle” to ensure that the ExecStart command is run only when everything else has loaded. Note that the paths are absolute and define the complete location of Python as well as the location of our Python script.
In order to store the script’s text output in a log file you can change the ExecStart line to:
ExecStart=/usr/bin/python /home/pi/sample.py > /home/pi/sample.log 2>&1
The permission on the unit file needs to be set to 644 :
sudo chmod 644 /lib/systemd/system/sample.service
Step 2 – Configure systemd
Now the unit file has been defined we can tell systemd to start it during the boot sequence :
sudo systemctl daemon-reload
sudo systemctl enable sample.service
Reboot the Pi and your custom service should run:
sudo reboot

Notify user while python running in background

So i have a code that i'm trying to run and when it finish it should display a message to the user saying what changes have happend. This works fine if i run it on terminal. But when i add it to a cronjob nothing happens and no error is shown.
It seems to me that it is losing the display session, but cant figure it how to solve it. Here is the show message code:
def sendmessage(message):
subprocess.Popen(['notify-send', message])
return
I also tried this version:
def sendmessage(message):
Notify.init("Changes")
n = Notify.Notification.new(message)
n.show()
return
Which gives the error (only in background also):
cannot open display:
Activated service 'org.freedesktop.Notifications' failed: Process org.freedesktop.Notifications exited with status
Would be very thankful for any help or alternative given.
I had a similar issue running a system daemon, where I wanted the user to be notified about a network bandwidth upload being exceeded.
The program was designed to run under systemd but at a push also under upstart.
You may get some mileage out of my configuration files:
systemd - bandwidth.service file
[Unit]
Description=Bandwidth traffic monitor
Documentation=man:bandwidth(7)
After=graphical.target
[Service]
Type=simple
Environment="DISPLAY=:0" "XAUTHORITY=/home/#USER#/.Xauthority"
PIDFile=/var/run/bandwidth.pid
ExecStart=/usr/bin/dbus-launch /usr/sbin/bandwidth_logd
ExecReload=/bin/kill -HUP $MAINPID
User=root
[Install]
WantedBy=graphical.target
upstart - bandwidth.conf file
#
# These are the scripts that run when a network appears.
# Use this on an upstart system in /etc/init
# test for systemd or upstart system with
# ps -p1 | grep systemd && echo systemd || echo upstart
# better
# ps -p1 | grep systemd >/dev/null && echo systemd || echo upstart
# Using upstart the script will need to daemonise which is a bugger
# so test for it and import Daemon_server.py
description "Bandwidth upstart events"
start on net-device-up # Start a daemon or run a script
stop on net-device-down # (Optional) Stop a daemon, scripts already self-terminate.
# Automatically restart process if crashed
respawn
# Essentially lets upstart know the process will detach itself to the background
expect fork
#Set environment variables
env DISPLAY=":0"
export DISPLAY
env XAUTHORITY="/home/#USER#/.Xauthority"
export XAUTHORITY
script
# You can put shell script in here, including if/then and tests.
# replace #USER# with your name and ensure that you have .Xauthority in $HOME
/usr/sbin/bandwidth_logd
end script
You will note that in both configuration files the environment becomes key and #USER# is replaced by a real user name with a valid .Xauthority file in their $HOME directory.
In the python code I use the following to emit the message(import notify2).
def warning(msg):
result = True
try:
notify2.init("Bandwidth")
mess = notify2.Notification("Bandwidth",msg,'/usr/share/bandwidth/bandwidth.png')
mess.set_urgency(2)
mess.set_timeout(0)
mess.show()
except:
result = False
return result

Run Python script on start-up (Arch Linux ARM on Raspberry Pi)

I have a Python script on my Raspberry Pi running on Arch Linux ARM. To start the script, I use this command:
sudo python2 screen/screen.py
and it works perfectly. Now, my question is, how I can run this script automatically on start-up?
In the folder /etc/systemd/system/ make a file named screen.service
The contents of that file might look like this (change for your use):
[Unit]
Description=Launches screen with my config
After=network.target
[Service]
Type=simple
ExecStart=command_you_want_to_run
RemainAfterExit=true
[Install]
WantedBy=multi-user.target
When you're finished run systemctl enable screen.service
The WantedBy line tells systemd where to make the symlink.
To learn more about the options for service unit files check out the docs: man systemd.service

Categories

Resources