Web Sever side scripting Python + GPIO


36 posts   Page 1 of 2   1, 2
by RaspberryPiBeginners » Thu Jun 14, 2012 10:41 pm
Has anyone seen any good examples of people using Python as a server side scripting to control the GPIO i've only seen people do it with PHP so far.
Click here for my unofficial YouTube Channel > http://goo.gl/oFYBD
User avatar
Posts: 217
Joined: Fri May 11, 2012 6:54 am
Location: Soham, Cambridgeshire
by andyl » Fri Jun 15, 2012 8:51 am
I'm not sure what the problem is.

Writing a simple CGI is dead easy and there are plenty of examples. Adding in the few lines of code that flashes a LED (from the Python GPIO examples people have already done) is easy.

So is the issue that you don't know how to setup and write a CGI program in Python?
Posts: 265
Joined: Tue Jan 10, 2012 11:05 am
by RaspberryPiBeginners » Fri Jun 15, 2012 10:32 am
Yeah i'm not really great at programming my skills are more networking and security. It's all good i've done some CGI programing in the past i'll just have to do some reading. Thanks for the reply.

I was just being lazy and wondering if someone had already dont it, i've got the Python working with the GPIO so half way there.
Click here for my unofficial YouTube Channel > http://goo.gl/oFYBD
User avatar
Posts: 217
Joined: Fri May 11, 2012 6:54 am
Location: Soham, Cambridgeshire
by sharpapotheosis » Fri Jun 15, 2012 11:32 am
http://fragments.turtlemeat.com/pythonwebserver.php gives a pretty neat tutorial on how to build a basic web server without using Apache and the likes. It means it can be as light as you want it to for the Pi.
Posts: 58
Joined: Thu May 24, 2012 6:47 pm
by RaspberryPiBeginners » Sun Jun 17, 2012 5:21 pm
OK so i finally got it working. Comments please on my implementation, i know it's not right.

HTML + PHP code

Code: Select all
<html>
<head>
<?php
if (isset($_POST['RedON']))
{
exec('sudo python /var/www/gpio/red_on.py');
}
if (isset($_POST['RedOFF']))
{
exec('sudo python /var/www/gpio/red_off.py');
}
if (isset($_POST['YellowON']))
{
exec('sudo python /var/www/gpio/yellow_on.py');
}
if (isset($_POST['YellowOFF']))
{
exec('sudo python /var/www/gpio/yellow_off.py');
}
if (isset($_POST['GreenON']))
{
exec('sudo python /var/www/gpio/green_on.py');
}
if (isset($_POST['GreenOFF']))
{
exec('sudo python /var/www/gpio/green_off.py');
}
?>

  <title></title>
</head>
<body>
<form method="post">
  <table
 style="width: 75%; text-align: left; margin-left: auto; margin-right: auto;"
 border="0" cellpadding="2" cellspacing="2">
    <tbody>
      <tr>
        <td style="text-align: center;">Turn LED on</td>
        <td style="text-align: center;">Turn LED off</td>
      </tr>
      <tr>
        <td style="text-align: center;"><button name="RedON">Red On</button></td>
        <td style="text-align: center;"><button name="RedOFF">Red Off</button></td>
      </tr>
      <tr>
        <td style="text-align: center;"><button name="YellowON">Yellow On</button></td>
        <td style="text-align: center;"><button name="YellowOFF">Yellow Off</button></td>
      </tr>
      <tr>
        <td style="text-align: center;"><button name="GreenON">Green On</button></td>
        <td style="text-align: center;"><button name="GreenOFF">Green Off</button></td>
      </tr>
    </tbody>
  </table>
</form>
</body>
</html>



And the python turning on example

Code: Select all
from time import sleep
import RPi.GPIO as GPIO
GPIO.setup(13, GPIO.OUT)
GPIO.output(13, False)


And the python turning off example

Code: Select all
from time import sleep
import RPi.GPIO as GPIO
GPIO.setup(13, GPIO.OUT)
GPIO.output(13, True)
Click here for my unofficial YouTube Channel > http://goo.gl/oFYBD
User avatar
Posts: 217
Joined: Fri May 11, 2012 6:54 am
Location: Soham, Cambridgeshire
by RaspberryPiBeginners » Tue Jun 19, 2012 8:44 am
No comments :( bummer
Click here for my unofficial YouTube Channel > http://goo.gl/oFYBD
User avatar
Posts: 217
Joined: Fri May 11, 2012 6:54 am
Location: Soham, Cambridgeshire
by wob86 » Tue Jun 19, 2012 11:09 am
Interesting way of doing it, but quick question by calling sudo for every call of python wont it be checking for sudo password?
I like the way you have done it but am wondering that if you try and make it control more or have more buttons then the code will just become reams and reams of if statements. As a suggestion have you considered looking at Django? I used it once or twice in the past and if you can do basic python + web code then it is easy to pick up. Basically it is a way of embedding you python code straight into the webpage rather than calling lots of seperate scripts.
Posts: 8
Joined: Wed Mar 07, 2012 10:41 am
by RaspberryPiBeginners » Tue Jun 19, 2012 11:23 am
I want to take the "sudo" statement out but it wont work without it. I need to move from if statements to switch statement's.
Click here for my unofficial YouTube Channel > http://goo.gl/oFYBD
User avatar
Posts: 217
Joined: Fri May 11, 2012 6:54 am
Location: Soham, Cambridgeshire
by texy » Tue Jun 19, 2012 12:30 pm
RaspberryPiBeginners wrote:OK so i finally got it working. Comments please on my implementation, i know it's not right.

HTML + PHP code

Code: Select all
<html>
<head>
<?php
if (isset($_POST['RedON']))
{
exec('sudo python /var/www/gpio/red_on.py');
}
if (isset($_POST['RedOFF']))
{
exec('sudo python /var/www/gpio/red_off.py');
}
if (isset($_POST['YellowON']))
{
exec('sudo python /var/www/gpio/yellow_on.py');
}
if (isset($_POST['YellowOFF']))
{
exec('sudo python /var/www/gpio/yellow_off.py');
}
if (isset($_POST['GreenON']))
{
exec('sudo python /var/www/gpio/green_on.py');
}
if (isset($_POST['GreenOFF']))
{
exec('sudo python /var/www/gpio/green_off.py');
}
?>

  <title></title>
</head>
<body>
<form method="post">
  <table
 style="width: 75%; text-align: left; margin-left: auto; margin-right: auto;"
 border="0" cellpadding="2" cellspacing="2">
    <tbody>
      <tr>
        <td style="text-align: center;">Turn LED on</td>
        <td style="text-align: center;">Turn LED off</td>
      </tr>
      <tr>
        <td style="text-align: center;"><button name="RedON">Red On</button></td>
        <td style="text-align: center;"><button name="RedOFF">Red Off</button></td>
      </tr>
      <tr>
        <td style="text-align: center;"><button name="YellowON">Yellow On</button></td>
        <td style="text-align: center;"><button name="YellowOFF">Yellow Off</button></td>
      </tr>
      <tr>
        <td style="text-align: center;"><button name="GreenON">Green On</button></td>
        <td style="text-align: center;"><button name="GreenOFF">Green Off</button></td>
      </tr>
    </tbody>
  </table>
</form>
</body>
</html>



And the python turning on example

Code: Select all
from time import sleep
import RPi.GPIO as GPIO
GPIO.setup(13, GPIO.OUT)
GPIO.output(13, False)


And the python turning off example

Code: Select all
from time import sleep
import RPi.GPIO as GPIO
GPIO.setup(13, GPIO.OUT)
GPIO.output(13, True)


I,m guessing this will head towards one of your tutorials ;)
Can you explain step by step what to do with this code, and what it is doing? I know how to control the GPIO lines (see my thread on driving an LCD), but I know nothing of webservers, etc.
Thanks,
Texy
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2458
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by ghans » Tue Jun 19, 2012 1:01 pm
Well it's easy enough.
This is a dynamically created webpage. Normally , a web page consists of HTML markup , but dynamic web-pages work like this:

1. A browser (a client) asks for a web page
2. The server acknowledges the request (i.e. Apache2)
3. The server realises that the browser required a dynamic webpage
4. The server invokes its CGI module , which interfaces with a language interpreter (PHP is overly popular)
Note: You should normally be able to use any language you want (including C or Phyton itself)
5. The interpreter executes the dynamic parts - as you can see PHP code can be " embedded " into plain HTML
6. The ouput is being sent as plain HTML to the client

To the code :

The HTML part presents a Form with push-buttons.
This Form will be submitted with the so-called POST Method.

The PHP Part checks POST data and executes Phyton scripts using phyton (Note what I said at 4.)

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org
Posts: 4769
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany
by RaspberryPiBeginners » Tue Jun 19, 2012 1:05 pm
^^ what he said :D
Click here for my unofficial YouTube Channel > http://goo.gl/oFYBD
User avatar
Posts: 217
Joined: Fri May 11, 2012 6:54 am
Location: Soham, Cambridgeshire
by croston » Tue Jun 19, 2012 1:14 pm
There is a guide to using Python for web scripting and GPIO in the Raspberry Pi Educational user guide. Unfortunately this has not been released yet. It is too long to copy and paste the relevant bits here.
User avatar
Posts: 465
Joined: Sat Nov 26, 2011 12:33 pm
Location: Blackpool
by ghans » Tue Jun 19, 2012 1:14 pm
Some suggestions to avoid exec() :

1. Do it all python. Most Webserver CGI modules allow to use any scripting language.
2. Use a shared file between the Phyton part and the PHP part. (check via looping in background)
3. Use a shared database between the Phyton part and the PHP part.
4. Use pipes or another message-passing mechanism. (write a little "server")

I do not know if this is really necessary but this exec("sudo somecommand") makes me feel uneasy.

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org
Posts: 4769
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany
by texy » Tue Jun 19, 2012 1:21 pm
Everything s easy when you know how. I'm afraid I'll be needing more help than that, but google is my friend.
Thanks
Texy
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2458
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by RaspberryPiBeginners » Tue Jun 19, 2012 1:24 pm
ghans wrote:...makes me feel uneasy


That's exactly why I've posted it here because it works but it makes me uneasy too. However if it's in your home environment who cares? But at the same time it's always best to do things the right way first time around.
Click here for my unofficial YouTube Channel > http://goo.gl/oFYBD
User avatar
Posts: 217
Joined: Fri May 11, 2012 6:54 am
Location: Soham, Cambridgeshire
by ghans » Tue Jun 19, 2012 1:27 pm
Are familiar with weservers ?
If not, apt-get apache2 and then type "localhost" in your browser (on the same machine).
Right-click to see the source.

Just search fo HTML tutorials and put your files in /var/www

ghans
• Don't like the board ? Missing features ? Change to the prosilver theme ! You can find it in your settings.
• Don't like to search the forum BEFORE posting 'cos it's useless ? Try googling : yoursearchtermshere site:raspberrypi.org
Posts: 4769
Joined: Mon Dec 12, 2011 8:30 pm
Location: Germany
by Rasathus » Tue Jun 19, 2012 8:47 pm
I started work on this with the intention on turing it into a quick tutorial. It utilises the python flask framework, and the RPi gpio module. The debian mainline flask version is rather old so i would suggest you use the pip version.

Code: Select all
sudo apt-get install python-pip && sudo pip install RPi.GPIO flask


You should then be able to place this code in your app.py ...

Code: Select all
# import our RPi.GPIO module and reference it as gpio
import RPi.GPIO as gpio

from flask import Flask, redirect, url_for
app = Flask(__name__)

@app.route("/")
def status():
    # get the current input state from our feedback loop
    input_state = gpio.input(17)
    # Check out input state and map it to a human readable status
    if input_state :
        led_status = "On"
    else:
        led_status = "Off"
    return """<html><body><div style="text-align: center;"><h2 style="text-align: center;">The LED is currently %s.</h2></br><h3>Turn LED ...</h3><a href="/on">On</a>  |  <a href="/off">Off</a></div>""" % led_status

@app.route("/on")
def led_on():
    # Turn pin 4 on (high)
    gpio.output(04,True)
    return redirect(url_for('status'))

@app.route("/off")
def led_off():
    # Turn pin 4 off (low)
    gpio.output(04,False)
    return redirect(url_for('status'))

if __name__ == "__main__":
    # specify the setmode method were going to use, Im using the BCM mode, as this seems to corrolate with the wikis pin layout.
    gpio.setmode(gpio.BCM)
    # register GPIO 4 as an output pin
    gpio.setup(04,gpio.OUT)
    # register GPIO 17 as an input pin
    gpio.setup(17,gpio.IN)
    app.run(host="0.0.0.0")


The intended circuit would have a transistor, with the base connected via a resistor to gpio4, from the transistor side of the resistor, gpio17 would be connected, via another resistor. The led would then be connected inline with the transistor, which can be driven by the 5v bus, via yet another resistor. Its probably a rather over complicated circuit though, but an interesting example of using transistors, and allows the pi to be replaced with a switch from the 5v bus to test the circuit should you wish.

Once connected up, you can run your webapp with the command

Code: Select all
sudo python app.py


Note the necessity of sudo, due to the gpio access permissions. At this point it will start listening on port 5000 for connections ie.

Code: Select all
http://<ipAddress>:5000


WARNING :- This effectively means your pi is running a webserver as root, leaving it rather vulnerable, do not put this on a hostile network ( The Internet )
Pi1 - Revision 002 - Used for some circuit experimentation and learning.
Pi2 - Revision 002 - Currently powering the 'Monstrosity Rover' project.
Pi3 - Revision 004 - Raspberry Pi Laptop using a Motorola Lapdock.

Take a look @ rasathus.blogspot.co.uk
Posts: 45
Joined: Sat Jun 02, 2012 11:37 am
Location: Reading, UK
by Jamesc359 » Tue Jun 19, 2012 10:31 pm
If you're concerned about it being vulnerable, why not run a python server behind a firewall, then utilize PHP running on a real webserver to contact the python server.
Posts: 1
Joined: Tue Jun 19, 2012 10:26 pm
by Rasathus » Wed Jun 20, 2012 12:16 pm
If you're concerned about it being vulnerable, why not run a python server behind a firewall, then utilize PHP running on a real webserver to contact the python server.


If your going to write a tutorial around the concept, you probably don't want to require additional hardware, over and above the raspberry pi. Additionally there doesn't really seem to be much point in introducing the user to two languages, python and php, when it can be done in one.

If the tutorial needs to produce a more secure application, suitable for web deployment, then maybe you'd be best off creating a service to run as root, which dealt with GPIO triggering. And then have the web server interact with that service.
Pi1 - Revision 002 - Used for some circuit experimentation and learning.
Pi2 - Revision 002 - Currently powering the 'Monstrosity Rover' project.
Pi3 - Revision 004 - Raspberry Pi Laptop using a Motorola Lapdock.

Take a look @ rasathus.blogspot.co.uk
Posts: 45
Joined: Sat Jun 02, 2012 11:37 am
Location: Reading, UK
by domesday » Wed Jun 20, 2012 12:36 pm
The python part is unnecessary as all the python library is doing is interacting with the system files and php can do that directly.

May I suggest you take a look at what the python library does and duplicate it in php ?
Posts: 258
Joined: Fri Oct 21, 2011 5:53 pm
Location: UK
by karl101 » Wed Jun 20, 2012 8:51 pm
I shall have to write something about using python with a webserver. I've set dozens of them up, In the meantime, look at mod_wsgi for apache and the flask framework for python. Avoid mod_python for apache its been depreciated.

PHP does not look to have the quality hardware hooks that Python has, but I suppose it's not meant to.

Karl,
Posts: 63
Joined: Wed Jan 11, 2012 10:09 am
by oni305 » Thu Jun 21, 2012 5:37 pm
then maybe you'd be best off creating a service to run as root, which dealt with GPIO triggering. And then have the web server interact with that service.


to manage the GPIO I think I will use a CGI script (on apache) capable of handling a socket and a separate python program (as root) for the GPIO
Posts: 12
Joined: Thu Jun 21, 2012 11:07 am
by karl101 » Sat Jun 23, 2012 8:13 pm
Hello,
I said I would write something, and I have. Here's how to get python and Apache talking to each other, get access to the UART and GPIO without having to run Apache as root:

http://www.g7smy.co.uk/?p=27

Karl.
Posts: 63
Joined: Wed Jan 11, 2012 10:09 am
by texy » Sat Jun 23, 2012 10:09 pm
I'll take a look tomorrow - looks interesting.
One question though - how do I, or anyone else point there browser at my pi? I need to find out my ip address, ie my routers external ip address(ADSL port address) and though reference port 80, ie 123.456.123.456:80 ?

Texy
"2.8inch TFT LCD + Touch screen" add-on boards for sale here :
http://www.raspberrypi.org/phpBB3/viewtopic.php?f=93&t=65566
50p goes to the Foundation ;-)
Forum Moderator
Forum Moderator
Posts: 2458
Joined: Sat Mar 03, 2012 10:59 am
Location: Berkshire, England
by domesday » Sat Jun 23, 2012 10:36 pm
If you are using the browser on the Pi you can simply point it to http://127.0.0.1 (the loopback address)

If you are on the local network you just need to find out the IP address of the Pi, assuming it is using DHCP then just use the command ifconfig in the command prompt to find the address.

If you want to do it from outside on the general internet you will first have to set-up a port forwarding rule on your router.
Posts: 258
Joined: Fri Oct 21, 2011 5:53 pm
Location: UK