-1

I have a python script which makes use of the standard RPi I/O's where I am detecting multiple inputs and storing values to a database. The script runs without exiting until the Pi is powered off.

The scripts write values to a database which are accessed by a Django application on the same machine. Therefore I would know whether inputs are being detecting by navigating to my localhost to check what is being displayed on my Django app.

Script located at /home/pi/Desktop/myscript.py

I want to be able to run this script whenever the raspberry pi is booted. I have tried several methods shown here so far but none have worked.

Autostart

I have also followed the instructions here, but the script does not seem to execute on startup.

As per instructions:

sudo nano /etc/xdg/lxsession/LXDE-pi/autostart
@lxterminal -e "/home/pi/myscript.sh"

and I create the myscript.sh file:

cd /home/pi
sudo nano myscript.sh
sudo /usr/bin/python3 /home/pi/Desktop/myscript.py

The above method does not run the script for me, (or at least inputs are not detected)

Crontab

I also tried including the script in my cron file as below:

Edit the file:

sudo crontab -e

Add line to file (here a python script):

@reboot python3 /home/pi/Desktop/myscript.py &

This does not work either.

rc.local

Lastly I have tried the below method:

All you need to do here is put ./myscript in the rc.local text file. If it's in python, put python myscript.py.

cd /etc
sudo nano rc.local

I then write:

python3 /home/pi/Desktop/myscript.py &

I have read here, however, that:

hings initiated from rc.local should either execute and finish quickly (a few seconds or less) or else fork to the background.


None of the above methods have worked, meaning that no inputs were detected, and I can't seem to understand why? Any help would be appreciated.

EDIT

On trying the below answer I get the following in my journal:

-- Logs begin at Thu 2016-11-03 18:16:43 CET, end at Mon 2018-09-03 06:10:07 CEST. -- Sep 03 06:10:07 raspberrypi systemd1: Started My script.

I can confirm that the script is actually running, since I am printing database values to a text file using:

     #At the end of the shift we are writing db to csv file before deleting table data
    c.execute("SELECT * FROM LineOEE03")
    with open('/home/pi/Desktop/OEE/Logs/output '+moment+'.csv', 'w', newline='') as csv_file:
        csv_writer = csv.writer(csv_file)
        csv_writer.writerow([i[0] for i in c.description])
        csv_writer.writerows(c)

Indeed, a text file was created at the desired directory with the current date and time.

rrz0
  • 123
  • 10
  • 1
    Adding some logging might help; be sure that includes the shell wrapper suggested, so that (e.g.) "Command not found" or something will get logged if your process completely fails to execute. – goldilocks Aug 31 '18 at 13:01
  • not work for me is a totally useless description of what happens .... if you want someone to spend time to help you, then do not make them guess about your problem .... provide clear description of what actually happens and why that is not suitable for you ........... please add the descriptions to each of the sections in your post – jsotola Sep 02 '18 at 01:01
  • @goldilocks thanks for the suggestions, will look into that. – rrz0 Sep 03 '18 at 04:06

1 Answers1

2

The problem is that you don't tell us what's going wrong with all your attempts, neither error messages nor what I/O you want to do with your script. But I'm sure you can solve your problem with systemd because there are many options to setup the environment: standard input and standard output, setting working directories and environment variables and user accounts, define dependencies to other services and so on. Because lack of information I suggest to start with this simple systemd service unit that we can improve as needed with your feedback. I assume you are using Raspbian. Create a new service unit with:

rpi ~$ sudo systemctl edit --force myscript.service

In the empty editor insert these statements, save them and quit the editor:

[Unit]
Description=My script

[Service]
ExecStart=/usr/bin/python3 /home/pi/Desktop/myscript.py

[Install]
WantedBy=multi-user.target

This is really a bare unit and I would be surprised if it runs without error. But try to start it with:

rpi ~$ sudo systemctl start myscript.service

Then you can look into the journal what error messages are produced:

rpi ~$ journalctl --pager-end --unit=myscript.service

For example I got in the journal:

-- Logs begin at Thu 2016-11-03 17:16:43 UTC, end at Sat 2018-09-01 18:37:03 UTC. --
Sep 01 18:37:03 raspberrypi systemd[1]: Started My script.
Sep 01 18:37:03 raspberrypi python3[962]: /usr/bin/python3: can't open file '/home/pi/Desktop/myscript.py': [Errno 2] No such file or directory
Sep 01 18:37:03 raspberrypi systemd[1]: myscript.service: Main process exited, code=exited, status=2/INVALIDARGUMENT
Sep 01 18:37:03 raspberrypi systemd[1]: myscript.service: Unit entered failed state.
Sep 01 18:37:03 raspberrypi systemd[1]: myscript.service: Failed with result 'exit-code'.

Tell me what you find. I will improve my answer then. You can edit the unit again with:

rpi ~$ sudo systemctl edit --full myscript.service

If it works you can enable the service for startup with:

rpi ~$ sudo systemctl enable myscript.service

Update:
Here are some clarifications to this answer according to your comment:

Ingo, the above procedure has worked so far. I am able to detect inputs and display on my website. Can you please explain what you mean by: "Then we have to look what other services your script needs to be up before running and we will define dependencies.", please? Also, what other useful commands should I define? I have been seeing Restart=Always , StandardError=syslog and other similar commands.

First of all: I'm surprised that it works out of the box :-)

It shows me again that systemd makes a big job. It is intended to define services as simple as possible and do many things in the background for you. What's really going on whith your service you can show with:

rpi ~$ systemctl show myscript.service
rpi ~$ systemctl show

I have thought your script needs some other services to run, for example a database. This would tell us the error messages and we would have to define a dependency After=mydatabase.service in the [Unit] section.

As far as I see there are no other useful commands to use. The useful commands are defined by default, for example StandardError=syslog. Particularly Restart=Always isn't useful. It's from people who are not able to make stable services and try to make them run by "fixing" the symptom. If your service stops running look why and fix it. I know only less services that really need this for example spawning tty login consoles.

Ingo
  • 42,107
  • 20
  • 85
  • 197
  • Thanks for the above, will implement and tell you how it goes. Regarding I/O, I am simply detecting an input rising edge on two different pins, and then performing calculations depending on these two inputs. – rrz0 Sep 03 '18 at 04:07
  • Ingo, the above procedure has worked so far. I am able to detect inputs and display on my website. Can you please explain what you mean by: "Then we have to look what other services your script needs to be up before running and we will define dependencies.", please? Also, what other useful commands should I define? I have been seeing Restart=Always , StandardError=syslog and other similar commands. – rrz0 Sep 03 '18 at 06:54
  • @Rrz0 I have updated my answer. If possible could you please accept the answer? It will help others to show that your question has an answer. – Ingo Sep 03 '18 at 09:35
  • Thanks for your time writing this helpful answer. Excuse my ignorance but I have encountered related issue and will post the link here such that anyone with knowledge in this particular area may visit: https://raspberrypi.stackexchange.com/questions/88773/executing-multiple-scripts-on-startup-in-a-particular-order – rrz0 Sep 03 '18 at 09:41