Raspberry Pi – Control a separate running script from a Web Server

Let’s say that you have a running Flask server and you want your user to control the state (on/off) of a motion sensor via the GPIO. The most complex way is to create a multi-threading script which handles the server and GPIO code.

Another approach is to separate the server script from the GPIO script. Thus having two layers of scripts. This has the advantage to debug in isolation. For this technique one has to use Unix Signals which can be used to send signals from one process to another.

When you execute a script on your UNIX system, the system creates a process id (pid) which is different every time. A signal is a software interrupt which notifies a process with a significant event or request.

The following table gives a list of the most common signals:

NAMENUMBERDESCRIPTION
SIGHUP1Linux sends a process this signal when it becomes disconnected from a terminal.
SIGINT2Linux sends a process this signal when the user tries to end it by

 

pressing CTRL+C.

SIGILL4Linux sends a process this signal when it attempts to execute an illegal instruction.
SIGABRT6Linux sends a process this signal to the process when the process calls the ‘abort ()’ function
SIGFPE8Linux sends a process this signal when it has executed an invalid floating-point math instruction
SIGKILL9Linux sends a process this signal to end it immediately
SIGUSR110User programs can send this signal to other process
SIGUSR212User programs can send this signal to other process
SIGSEGV11Linux sends a process this signal when the program has attempted an invalid memory access
SIGPIPE13Linux sends a process this signal when the program has attempted to access a broken data stream, such as a socket connection that has been already closed
SIGALRM14A process can receive this signal from the Linux using the function alarm (), after a time period mentioned in its argument.
SIGTERM15Linux sends a process this signal requesting it to terminate
SIGCHLD17Linux sends a process this signal when a child process exits
SIGXCPU24Linux sends a process this signal when it exceeds the limit of

 

CPU time that it can consume.

SIGVTALRM26A process can receive this signal from the Linux using the function setitimer (), after a time period mentioned in its argument.

We are interested in SIGUSR1 and SIGUSR2 which can be used to send user signals.

Step 1:

First create the server layer (app.py). Documentation about Flask server can be found here.


from flask import *
import os
import signal

app = Flask(__name__)

@app.route('/')
def index():
    return render_template('index.html')

@app.route('/trigger1')
def process1():
    #read process id from text file
    fh=open("processid.txt","r")
    processId = int(fh.read())
    fh.close()

    #send signal to process id
    os.kill(processId, signal.SIGUSR1)

    return render_template('trigger1.html')

@app.route('/trigger2')
def process2():
    #read process id from text file
    fh=open("processid.txt","r")
    processId = int(fh.read())
    fh.close()

    #send signal to process id
    os.kill(processId, signal.SIGUSR2)

    return render_template('trigger2.html')

if __name__ == '__main__':
    app.run(debug=True,host='0.0.0.0')

Step 2:

Create the SignalReceiver.py script (you can modify this to control the GPIOs)


import os
import signal
import time

fh=open("processid.txt","w")
fh.write(str(os.getpid())) #get current process id and store in file
fh.close()

def handUSR1(signum,frame):
    print('triggered',signum)

def handUSR2(signum,frame):
    print('triggered',signum)

signal.signal(signal.SIGUSR1,handUSR1) #callback function for SIGUSR1 signal
signal.signal(signal.SIGUSR2,handUSR2) #callback function for SIGUSR2 signal

while(True):
    time.sleep(1)
    print("Waiting for signal")


Step 3: Run Server

flaskupload3.JPG

Step 4: Run SignalReceiver.py

flaskupload4.JPG

Step 5: 

In the browser, click Trigger 1 and Trigger 2 hyperlink buttons. Notice that SignalReceiver.py outputs ‘triggered 10′ and ‘triggered 12′. This means that both signals were sent and received correctly.

flaskupload5

Link to project: https://sourceforge.net/projects/pi-send-signals-to-scripts/

One thought on “Raspberry Pi – Control a separate running script from a Web Server

  1. Pingback: PI Send Signals to Scripts Python - Open Source Buzz

Leave a comment