Python script running in a Raspberry Pi without initialization - python

I have written a python script which waits for a keyboard input and it will run in a Raspberry Pi.
I want it to run as soon as the Raspi gets powered (without the need to log in and to type the command in order to start the script). Note that it is not a deamon, since it will interact with the user. How can I do that?

I found the instructions on this page:
http://www.akeric.com/blog/?p=1976
very helpful to achieve what you are asking. Specifically the page describes how to configure the pi to automatically log in to one of the shells and how you can then run a script as the shell starts up.
Note that when I used this approach, the pi was not exposed to the outside world, so I did not check this approach for possible security weaknesses.
belated edit since the original answer was 'link only':
including the relevant content from the link to summarize the necessary steps here in case the link falls dead:
edit inittab (e.g. using nano):
sudo nano /etc/inittab
replace this line:
1:2345:respawn:/sbin/getty 115200 tty1
with this:
1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1
This will automatically login on tty1 upon startup. Then you can start your script e.g. by including it into the .bashrc.

Related

Start python script on startup - python script runs after login on raspberry pi?

I would like to run a python script directly on startup of the raspberry pi. I can execute the script by calling /home/pi/scripts/script.py. Now I tried to add the script to /etc/rc.local or /etc/profile or start it with systemd. For all cases the script is only executed after a connection to the pi via SSH and a login to the pi.
Therefore I would like to know who I could execute the script on boot (startup) without having to do a login?
You were on the right track with systemd and unit files.
First read this:
[https://www.digitalocean.com/community/tutorials/understanding-systemd-units-and-unit-files]
You probably used multi-user.target as wanted-by but that is too late.
You could use
sudo systemd-analyze critical-chain
to see which .targets might be better for your need.For example basic.target looks good.
You can of course also state in the unit file explicitly that your unit (.service) needs to be loaded before for example ifup#eth0.service
Use sudo systemctl list-units or sudo systemctl list-unit-files to see everything that in this respect is going on.

My (working) raspberry pi program doesn't work right when I run it on boot

I'm writing a script that (basically) controls some motors from raspi gpio pins. I've been making it right for a while now, and when I boot the pi and run the program manually it works just fine. I also have a portion of the code that allows me to use my phone to connect via bluetooth and send some data to control the motors. That also works fine on a manual run of the program.
Now I am trying to make the program start automatically on boot, as this will eventually go in a larger machine (boat) and I won't be hooking a monitor etc. to it. I'm currently doing this through a cron job with the #reboot tag. Looks like this:
#This enables GPIO (as far as I know). The program fails without this command being run first.
#reboot sudo pigpiod
#This runs the python program. ampersand forks the process because it should run continuously.
#reboot python3 /home/pi/Desktop/BoatBrain.py &
#and this lets me connect my phone over bluetooth. The python program has
#a portion takes data from that connection. ampersand forks the process, which
#seems like the right thing to do, since it looks like it blocks other things.
#That is also why it is at the end of the cron table.
#reboot sudo rfcomm watch hci0 &
When I reboot, the jobs all run, and I can connect my phone, so it must have passed the line executing the python script, but the servo I have connected just jitters in place uncontrollably. Let me restate that when I take the cronjobs away and run this manually, the program works correctly with few to no jitters, so it doesn't feel like an electrical problem...
If you need any more information please let me know and I'll be happy to provide it. I have a tendency to leave things out without realizing XD
Thanks!
Did you add anything to ~/.profile? It might be why it works when you invoke the commands yourself. If so, create a file in sudo vi /etc/profile.d/servo.sh with the same couple lines you added to ~/.profile. Then the system will have those on reboot.
Also, you could put all the three commands in one shell script and just put the script in the crontab. then the script can control that they start in order. You could also have the cronjob write output to a logfile and then see what it says. Also you can check when the cron runs by looking in /var/log/syslog
Oh, also for testing, you can change #reboot to a start time like 10 * * * * and then you can get the cron working without having to reboot. Then later, change it back to #reboot to try it with reboot.
Either something is missing that your login has (.profile), the commands are starting too quickly at the same time and need to start in a controlled order or the system isn't completely ready yet, but I doubt that one.

Unable to access pi camera through web browser

I am writing a Python CGI script that I want to run on my laptop's browser. This script will SSH into two Pis, and give the command to take a photo. The server hosting this script is on one of the Pis that I want to SSH into, and that Pi also is acting as an access point for the other Pi and my laptop to connect to (everything is a LAN, not connected to the Internet).
I am successfully able to run this script on my laptop's browser to run simple commands like ls -l on both Pis and print out the results for both on the browser. But, I ultimately want to be able to give the raspistill command to both Pis. When I do this, only the Pi with the server is taking the image, but the other Pi is not. I assume it's because permissions aren't set properly for the server (I tried running the commands as sudo but still no luck). However, if I run the same script on a Python IDLE it works fine. Can somebody help me identify the issue?
Here is my script:
#! /usr/bin/env python3
from pssh import ParallelSSHClient
import cgi
print("Content-Type: text/plain\r\n")
print("\r\n ")
host = ['172.24.1.1','172.24.1.112']
user = 'XXXX'
password = 'XXXX'
client = ParallelSSHClient(host, user, password)
output = client.run_command('raspistill -o test.jpg', sudo=True)
// AMENDMENT:
for line in output['172.24.1.1'].stdout: // works as well with '172.24.1.112'
print(line)
AMENDMENT:
Apparently, if I output anything from the stdout it works fine. Why is this the case? Is is just waiting for me flush the output or something? I suspect this might be a issue with the pssh package I am using.
In your pi, go into the terminal and type sudo raspi-config and then navigate with the keys to camera and then enable it. This will restart you pi.
From https://www.raspberrypi.org/documentation/configuration/camera.md:
Use the cursor keys to move to the camera option, and select 'enable'.
On exiting raspi-config, it will ask to reboot. The enable option
will ensure that on reboot the correct GPU firmware will be running
with the camera driver and tuning, and the GPU memory split is
sufficient to allow the camera to acquire enough memory to run
correctly.
After this, go into sudo raspi-config and enable ssh (which is another option just like pi-camera). Link for this here
After thoroughly reading through the documentation for the pssh module, my problem had to do with the exit codes and how they are handled.
The documentation about run_command states that:
function will return after connection and authentication establishment and after commands have been sent to successfully established SSH channels.
And as a result:
Because of this, exit codes will not be immediately available even for
commands that exit immediately.
Initially, I was just blindly running the run_command expecting the commands to finish, but it turns out I need to get the exit codes to truly finish the processes the commands are running. The documentations states a couple of ways to do this:
At least one of
Iterating over stdout/stderr to completion
Calling client.join(output) is necessary to cause parallel-ssh to wait for commands to finish and be able to gather exit codes.
This is why in my amendment to the code, where I was outputting from stdout, the commands seemed to work properly.

how to replace the desktop interface with a python application

I am creating a GUI interface that will be using a 7" touch display with a raspberry pi 3. I want the GUI to take the place of the desktop, I do not want it displayed in a window on the desktop. any thoughts on how to do that. I have read the raspberry pi documentation to edit the rc.local script to start the application at login, but I can not figure out how to set up the python GUI with out creating a window
Your pi boots up and displays a console - just text - by running a program (getty). Then you run another application called a graphical display manager which then runs a window manager. On a pi it is usually gnome but there are many others,.. this window manager is what displays your GUI window. What you want is obviously possible, it is just that it is non-trivial to do. What you are talking about is either kiosk-mode application still running 'on the desktop' as you say but which obscures the desktop completely and does not allow you to switch or de-focus or an even more complicated JeOS like Kodi/XBMC bare metal installation running without your current window manager. Your python would have to do the job of the display manager and the window manager and it would be very, very slow.
Use a really light window manager and go kiosk mode. Or you could go with text! There are libraries eg ncurses but I'm not sure how that would work with your touch screen display.
1.
Disable graphical interface i.e. stop the desktop manager from running.
On Raspbian you can use raspiconfig to do it.
2.
Set up autologin into bash
3.
Block startx from automatically running desktop manager
4.
Add your app to be started from .bash_rc when autologin is performed.
To setup autologin first create a script called autologin in /bin directory that does:
#! /bin/bash
/bin/login -f pi
Note: pi is an user on raspbian that won't ask for password when sudo-ing.
To use the created script edit /etc/inittab:
Scroll down to where terminals are assigned and change tty1's line to be:
1:2345:respawn:/sbin/getty -n -l /bin/autologin 38400 tty1
Take care that ids are matching old tty1 settings.
Then in the user's home directory (/home/pi) add (if it's not already there) a file named ".xinitrc" containing just:
#! /bin/bash
cat
This will prevent X server from invoking desktop manager when started.
Now add in /home/pi's .bashrc your app or better a script that will run your app (at the end):
export DISPLAY=:0
/home/pi/Desktop/appstart &
startx
And appstart is:
#! /bin/bash
# Wait a second for X server to start:
sleep 1
# Now X is running and we have to switch into video terminal using chvt (change virtual terminal) command
# Graphic terminal is on Raspbian tty7
sudo chvt 7
# Start the app:
python /home/pi/Desktop/myapp/myapp.py
After all this is set up what will hapen is the following:
1.
You run Raspberry Pi and it autologins into user pi
2.
When Bash logs in it executes /home/pi/.bashrc
3.
.bashrc sets $DISPLAY variable because there are no X displays yet, runs starting script as a background job and starts X server.
4.
X server won't enter desktop manager because /home/.xinitrc will stop it step short of it.
5.
Starting script sleeps for a second to ensure that X is running and able to send graphics to tty7, switches to tty7 so that user doesn't have to do it manually, and then runs your application which will show up.
If your app is not graphical you will see only one big nothing. :D
Problems here are that you definitely should create an user just for this stuff. If your app crashes or user switches to tty1 and terminates X there he/she is in bash, logged in.
Depends on what level of security you need. You can do a lot of things to prevent abuse. For example, use fcntl to change mode tty1 is in so that it cannot receive key input any longer.
Or use some other tricks, or rearange this procedure somewhat, or ensure that tty1 runs everything in jobs with nohup, then logs out etc, etc.

Raspberry Pi - Run Python script at Startup using "screen" session

I have really tried looking around but all the examples I find do not work for me.
I have a python script in a Raspberry Pi that starts using CRON....all good!
I would like to be able to debug the ouput that the script prints in screen from time to time so the "screen" command needs to be used to create a session and ensure that I can login and logoff using putty as needed.
I also add the "&" so it will run in background.
So currently I did:
1) Open cron
sudo crontab -e
2) Add the following line
#reboot python /home/pi/python/monitor.py &
This works correctly, I just need to know how to make a "screen" session open before launching the python script.
Thank you very much for your help!

Categories

Resources