Autostarting Python scripts on boot using crontab on rasbian - python

I am a pretty new python programmer and am a little bit familiar with crontab. What I am trying to do is probably not the best practice but it is what I am most familiar with.
I have a raspberry pi with a couple python scripts I want to run on boot and stay running in the background. They are infinite loop programs. They are tested and working in a cmd terminal and have been function for a couple weeks. Just getting tired on manually starting them up. When the pi goes through a power cycle.
So I did a sudo crontab -e and added this line as my only entry
#reboot /usr/bin/python3 /usr/bin/script.py &
If I copy paste this exactly (minus the #reboot) it will run successfully in the cmd line.
I am using a cmd:
pgrep -af pythonto check to see if it is running. I normally see two scripts running there but not the one I am trying to add.
I am not sure where I am going wrong or my best method to troubleshoot my issue. From the research I have been doing it seems like it should work.
Thanks for your help
Kevin

You might find it easier to create a systemd service file for each program that you want to start when you Raspberry Pi boots. systemd comes with a few more tools to help you debug your configuration.
This is what an example systemd service file (located at /etc/systemd/system/myscript.service) would look like:
[Unit]
Description=My service
After=network.target
[Service]
ExecStart=/usr/bin/python3 /usr/bin/script.py
WorkingDirectory=/home/pi/myscript
StandardOutput=inherit
StandardError=inherit
Restart=always
User=pi
[Install]
WantedBy=multi-user.target
and then you can enable this program to run on boot with the command:
sudo systemctl enable myscript.service
These examples are from Raspberry Pi's documentation about systemd. But because systemd is widely used in the Linux world, so you can also follow documentation and StackOverflow answers for other Linux distributions.

Related

How can i run multiple infinite files on boot of raspberry pi?

i have a file for my discord bot which i run on boot and now i also made a react.js app and i also want this to run on boot. But when i put:
cd /home/pi/kickzraptor-site && npm run start
also in my .bashrc file, only the first one gets run because its an infinite loop i think. How can i run both on startup? Thanks! (This is the line already at the bottom of my bashrc file)
echo Running bot.py scipt...
sudo python3 /home/pi/bot.py
Fastest way (not recommended) is to add & at the end of the command so that the program doesn't block for further processes. sudo python3 /home/pi/bot.py &
Recommended way is to create a systemd service that runs during or after the boot is completed (depending on its configuration). This method is also good for error handling and it provides more ability on the program.

Multithreaded Python application in background

I have a Python application myapp on a Raspberry Pi, with a front end control panel made with Dash. I run the Dash app in its own thread so that I can use it to manipulate some settings inside myapp.
When I SSH in to the Raspberry Pi, I want to start the Python application myapp in the background and then close the remote shell window and just let it spin and do its thing. After having written this question I found I have to use nohup for this according to
nohup python path/to/myapp.py &
For other python apps just
python path/to/other_app &
seems to suffice.
So I guess I already have the answer to my question. But, while at the subject, is this the preferred and only solution?
It depends a lot on what specific linux variant you're running, but generally speaking the best way is to your let your system's service manager handle that. In most cases these days that means systemd.
Create a service config file-
[Unit]
Description=My Python Service
[Service]
Type=simple
ExecStart=/path/to/my/python/service.py
[Install]
WantedBy=multi-user.target
Put this in the /lib/systemd/system/ with a name like mypythonapp.service.
Run systemctl daemon-reload so systemd knows to look for the new file.
Run systemctl enable mypythonapp.service to tell it to run the app on start.
Run systemctl start mypythonapp.service to tell it to run the app immediately.
Now your script will have logging, will restart when crashed or when the system reboots, and you don't have to manually kick it off.

How can I automatically run 2 python scripts at the same time in a virtual environment when booting up the Raspberry Pi?

Note: I'm new to everything so bare with me.
I'm using a RPi 4B with Buster. My goal is to automatically run 2 python scripts at the same time when the pi first boots up. Both scripts are in a virtual environment. The first script is called sensor.py which basically uses an ultrasonic distance sensor to continuously calculate distances between the sensor and an object. The other is an object recognition script from Tensorflow Lite called TFLite_detection_webcam.py that identifies objects from a camera feed. I can't use rc.local for autorunning because the object recognition script uses a picamera feed as an input, which rc.local doesn't support. So my preferred option is using autostart. I was able to successfully get the sensor.py script to autorun by issuing this in the terminal: sudo nano /etc/xdg/lxsession/LXDE-pi/autostart and adding this to it: /home/pi/tflite1/tflite1-env/bin/python3 /home/pi/tflite1/sensor.py. In this case, tflite1-env is the virtual environment being activated. However, I don't know how to get the second script to run. To run it regularly, I would issue the following into the terminal and the camera feed would pop up on the screen as a window.
cd tflite1
source tflite1-env/bin/activate
python3 TFLite_detection_webcam.py --modeldir=TFLite_model
I've tried to get this script to run by adding this to the autostart file: /home/pi/tflite1/tflite1-env/bin/python3 /home/pi/tflite1/TFLite_detection_webcam.py --modeldir=TFLite_model but it doesn't seem to be working. I've tried to run it using shell files, but every time that I run a shell file in the autostart file such as adding ./launch.sh to the bottom, nothing happens. Any help getting the second script to run at the same time as the first upon startup would be greatly appreciated. Thanks in advance.
Use Systemd. Set up Systemd unit files in /etc/systemd/system, e.g.
kitkats-sensor.unit
[Unit]
After=network.target
[Service]
ExecStart=/home/pi/tflite1/tflite1-env/bin/python3 /home/pi/tflite1/sensor.py
WorkingDirectory=/home/pi/tflite1/
User=pi
Group=pi
kitkats-tflite.unit
[Unit]
After=network.target
[Service]
ExecStart=/home/pi/tflite1/tflite1-env/bin/python3 /home/pi/tflite1/TFLite_detection_webcam.py --modeldir=TFLite_model
WorkingDirectory=/home/pi/tflite1/
User=pi
Group=pi
Then enable the unit files with systemctl enable kitkats-tflite and systemctl enable kitkats-sensor (to have them autostart) and systemctl start kitkats-tflite (and sensor) to start them right away.
You can then see them in e.g. systemctl, and their logs are diverted to journalctl.

systemd service not executing notify-send

I want to generate pop-ups for certain events in my python script. I am using 'notify-send' for that purpose.
subprocess.Popen(['notify-send', "Authentication", "True/False"])
The above command executes fine on terminal but when I run it from systemd-service it does not generate any pop-up.
When I see logs there are no errors.
You need to first set the environment variable so that the root can communicate with the currently logged user and send the notification in GUI.
In my case, I did it as follow:
[Unit]
Description=< write your description>
After=systemd-user-sessions.service,systemd-journald.service
[Service]
Type=simple
ExecStart=/bin/bash /<path to your script file>.sh
Restart=always
RestartSec=1
KillMode=process
IgnoreSIGPIPE=no
RemainAfterExit=yes
Environment="DISPLAY=:0" "XAUTHORITY=/home/<User name>/.Xauthority"
[Install]
WantedBy=multi-user.target
Here,
RemainAfterExit=yes
is very important to mention in service file.
make sure to change all the parameters like Description, User name and path to your script file.
also, make sure that script file has executable permission by executing the command
sudo chmod +x <path to your script file>.sh
Here my script file is written in bash which shows the notification by using the same 'notify-send' command.
Now here the Environment parameter is doing all the magic.
you can read more about this behavior and the problem discussed overhere.
I certainly don't know the complete working of these files or how this worked, but for me, it worked just fine.
So you can give it a try.
please let me know if this worked or not in your case.
Running graphical applications requires the DISPLAY environment variable to be set, which would be set when run it from the CLI, but not when run from systemd (unless you explicitly set it).
This issue is covered more in Writing a systemd service that depends on XOrg.
I agree with the general advise that systemd may not be the best tool for the job. You may be better off using an "auto start" feature of your desktop environment to run your app, which would set the correct things in the environment that you need.
If running notify-send for desktop notifications in cron, notify-send is sending values to dbus. So it needs to tell dbus to connect to the right bus. The address can be found by examining DBUS_SESSION_BUS_ADDRESS environment variable and setting it to the same value.
Copy the value of DISPLAY and DBUS_SESSION_BUS_ADDRESS from your running environment and set them in [Service].Environment section
More info on the Arch Wiki:
https://wiki.archlinux.org/index.php/Cron#Running_X.org_server-based_applications

Run pigpiod daemon - Using python or Ubuntu boot

In order to use pigpio Module in Python (remote GPIO for Raspberry Pi ), pigpiod has to be loaded to memory on each RPi.
what is the right way to to it ? during Ubuntu's boot or a part of Python's script ?
since It needs sudo pigpiod- how is it done (both Ubuntu and Python )?
An alternative it to use the reboot option within cron
Run:
crontab -e
then add the entry:
#reboot /pathtoexecutable
This will run the process every time the system boots.
I haven't used pigpiod, but I'm assuming it's a daemon (a long running Linux process) that you want to start at boot. The standard way to do that in most modern Linux systems (including Raspberri Pi, I think) is to use systemd. Give the following commands a try:
systemctcl start pigpiod # start it now
systemctl enable pigpiod # start it each boot
systemctl status pigpiod # make sure it started
# https://www.digitalocean.com/community/tutorials/how-to-use-journalctl-to-view-and-manipulate-systemd-logs
journalctl -u pigpiod # Use this to see logs.
If systemctl complains about not being able to find the service, you'll have to create a service file for it. This is a text file you place in a directory that tells systemd how to deamonize the process. Here is a blog post where someone does this, and Google should find you others if it doesn't help.
Then you should be able to connect with Python.
Answered in gpiozero documentation

Categories

Resources