2

I have tried like 5 methods to get this script loaded after raspi3 load.

#!/usr/bin/python3.7
#sudo python /home/pi/masterBaseInterface.py


import socket               # Import socket module
import thread
import time
import serial


def get_ip_address():
  ip_address = '';
  s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  s.connect(("8.8.8.8",80))
  ip_address = s.getsockname()[0]
  s.close()
  return ip_address

def on_new_client(clientsocket,addr):
  while True:
    msg = clientsocket.recv(2048)
    if msg != "":
      if msg == "findingNemo":
        clientsocket.send('heyDad') 
      else:
        #msg = "5A00000d0a71"

        ser = serial.Serial(
          port='/dev/ttyUSB0',
          baudrate=115200,
          parity=serial.PARITY_NONE,
          stopbits=serial.STOPBITS_ONE,
          bytesize=serial.EIGHTBITS,
          timeout=2
        )

        print "Received message from client: "+msg
        msg = msg.replace('\n', ' ').replace('\r', '').replace(' ', '')      
        msg.strip() 

        print "Dispatching message to master base"
        ser.write(msg.decode('hex'))
        print "Message sent, waiting for response"
        #time.sleep(2)
        #output = ser.readline()
        output=""
        time.sleep(2)
        while ser.inWaiting() > 0:
          output += ser.read(10)

        if len(output)>0:
          output = output.replace('\n', ' ').replace('\r', '').replace(' ', '')
          print "Master base replies with "+output.encode('hex')
          clientsocket.send('OK,'+output.encode('hex'))  
          clientsocket.close()
          print "Message sent to client, connection closed"
          break
        else: 
          print "Master base not responding, sending error message to client"
          clientsocket.send('ER,noResponse') 
          clientsocket.close()
          print "Message sent to client, connection closed"
          break

        msg=""

      #clientsocket.send(output.encode('hex'))        
    #clientsocket.close()

s = socket.socket()         # Create a socket object
host = get_ip_address() # Get local machine name
port = 1000                # Reserve a port for your service.

print 'Server started with local IP '+ get_ip_address()
print 'Ready to serve clients'

s.bind((host, port))        # Bind to the port
s.listen(5)                 # Now wait for client connection.


while True:
   c, addr = s.accept()     # Establish connection with client.
   print 'Got connection from', addr
   thread.start_new_thread(on_new_client,(c,addr))
   #Note it's (addr,) not (addr) because second parameter is a tuple
   #Edit: (c,addr)
   #that's how you pass arguments to functions when creating new threads using thread module.
s.close()

Posting the script source because I don't know if it contains something illegal...

What I have tried? This crontab

@reboot sudo python /home/pi/masterBaseInterface.py

Also the rc.local thing

sudo nano /etc/rc.local
sudo python /home/pi/masterBaseInterface.py &

The bashrc too, but this ones only works when I login via ssh with putty

sudo nano /home/pi/.bashrc
echo Running at boot 
sudo python /home/pi/masterBaseInterface.py

I tried other things, but can't remmeber now. So, what's happening here?

  • Have you run the script manually in the foreground to see if it works or instead returns any sort of errors? – rpseu Jul 10 at 13:32
  • manually works good, no errors – Martin Ocando Corleone Jul 10 at 16:32
  • Well, that doesn't sound like a problem with the script, then. Between that and your response to my answer, I'm out of ideas. My script is running fine from rc.local. The issue may be specific to the OS version you are running, but I don't know the differences between them to help further. – rpseu Jul 10 at 17:30
  • You should use a systemd Unit file to start the script. What does the script do? Does it need networking available? Does it run only one short time on start up or does it stay in the background as a service? What exactly is the command do you use to start it on the command line? Please edit your question to add the information. – Ingo Jul 10 at 17:58
  • Maybe you need to remove the sudo part in your crontab? I can start my script without sudo just fine. – Marcel Jul 10 at 19:49
0

According to this site you may need to change your first line from this:

#!/usr/bin/python3.7

to this:

#!/usr/bin/env python3

The first line in my working script is this:

#!/usr/bin/env python

ETA: OK, you've tried this and it's still not working. My working script is launching from rc.local, and I've caught another difference. You've put this in your rc.local:

sudo python /home/pi/masterBaseInterface.py &

OTOH, my rc.local has this (equivalent):

/home/pi/masterBaseInterface.py &

You could try removing "sudo" and see if it works (I think rc.local is effectively running as root anyway). If it doesn't, you could try removing "python" as well, but you would need to make sure you have marked the script executable (chmod +x).

  • still not working with these changes – Martin Ocando Corleone Jul 10 at 16:33
  • I have edited my answer to add more advice that might be helpful (in spite of the comment reply I just made on the original post). – rpseu Jul 10 at 17:36
  • Please take note that using /etc/rc.local has limitations due to Compatibility with SysV. We have seen many problems here on this site using it. Following the recommendation of the developers from systemd you should avoid using it. – Ingo Jul 10 at 17:51
  • Considering the comment above this one, and assuming the change to remove sudo (and possibly python) from the command you use to call the script is effective at all, the same solution might resolve the crontab issue. – rpseu Jul 10 at 18:38
0

My suggestions are as follows:

Since you are running the script as a cron job, the PATH environment variable is not set, so the Python interpreter cannot be found and the script fails to run.

As your script already has #!/usr/bin/python3.7 on the first line, and assuming the path is indeed correct on your platform, then there is no need to prefix the commmand with python. You could just call your script directly like this:

/home/pi/masterBaseInterface.py

(Without python at the front) ... provided it has the executable flag set ie chmod +x /home/pi/masterBaseInterface.py

or add the full path to Python in your cron like this: @reboot sudo /usr/bin/python3.7 /home/pi/masterBaseInterface.py

(again make sure that the path is correct, you can run which python3 or possibly which python3.7 to verify.

Second suggestion would be to run the program in a screen session and log the console output to a file. If the execution fails you can see what actually happened in the console. One example here. An added bonus is that you can 'join' the console through SSH later and catch on the program while it's already running in its own screen session...

So I would always recommend using screen, especially for running unattended scripts. It is also convenient because you can attach and detach from sessions anytime, recover where you left after losing the SSH connection etc.

Third suggestion would be to add some logging and exception handling to your program, so that if it crashes while running in the background, you have details about the error in a log file. It helps a lot with debugging. Obviously, this will work only when Python is actually able to execute the script. But any program is always going to crash at some point for some reason. It's good to have a trace.

  • Well... I just tried to execute manually the script without the python preffix, and it doesn't work, it raises the error: print is missing the (), OK, I added them, try to run it again, and a new error: ModuleNotFoundError for serial... tried to install pyserial, and it says already installed. – Martin Ocando Corleone Jul 10 at 20:50
  • Changed the head, from python3.7 to 2.7 and it works, I can run the script manually without preffix, I think something is happening with that, I'm trying now to test again the options to get the script running on startup, just tested the crontab and didn't work. – Martin Ocando Corleone Jul 10 at 20:51
  • Thanks for your suggestions, I moved to v2.7, and it worked, but the main problem with this was: this script uses sockets, and tried to allocate these sockets BEFORE any network interface, also, it requires to use that interface and wasn't ready, so I added a 30 seconds delay just after library declaration section. Now it works good. If you want you can modify the answer. – Martin Ocando Corleone Jul 10 at 21:00

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.