1

I developed a tiny webserver on Python. Its aim is to translate an URL's parameters (such as http://192.168.0.17:6066/?rly=7&status=1&port=ttyUSB0) in an command (here RLY71) and write it on a serial port (here /dev/ttyUSB0), where the Arduino is connected.

Here is the WebServer code (many many "print" for debugging purpose) :

__author__ = 'deadbird'

import time
import BaseHTTPServer
from urlparse import urlparse, parse_qs
import serial
from time import sleep

HOST_NAME = '192.168.0.17'
PORT_NUMBER = 6066


class MyHandler(BaseHTTPServer.BaseHTTPRequestHandler):

    def do_HEAD(s):
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()

    def do_GET(s):
        port = -1
        status = -1
        rly = -1

        """Respond to a GET request."""
        s.send_response(200)
        s.send_header("Content-type", "text/html")
        s.end_headers()
        s.wfile.write("<html><head><title>Piscine</title></head>")

        parameters = parse_qs(urlparse(s.path).query)
        if parameters.has_key('rly'):
            rly = parameters['rly'][0]

        if parameters.has_key('status'):
            status = parameters['status'][0]

        if parameters.has_key('port'):
            port = parameters['port'][0]

        if port != -1 and status !=-1 and rly !=-1:
            #ser = serial.Serial("/dev/ttyUSB0")
            #ser.write("RLY11\n")
            #ser.close()
            try:
                print "All parameters ok, sending command\n"

                print "Opening port: {0}".format(port)
                ser = serial.Serial("/dev/{0}".format(port), 9600, timeout=1)
                print "Opened port \'{0}\'".format(ser.name)
                if ser.isOpen():
                    print "Port successfully opened"
                    print "isWritable = {0}".format(ser.writable())
                else:
                    print "Cannot open port :("

                command = "RLY{0}{1}".format(rly, status)
                print "Command = \'{0}\'".format(command)

                print "Writing command on serial port"
                written = ser.write("RLY{0}{1}\n".format(rly, status))
                print "Bytes written = {0}".format(written)

                print "Reading result"
                ret = ser.readline()
                if len(ret) == 0:
                    s.wfile.write("NOTHING DONE")
                else:
                    print ret
                    s.wfile.write(ret)
                ser.flushOutput()
                ser.flushInput()
                ser.close()
            except (serial.SerialException, serial.SerialTimeoutException) as e:
                s.wfile.write(e)
        s.wfile.write("</body></html>")


if __name__ == '__main__':
    server_class = BaseHTTPServer.HTTPServer
    httpd = server_class((HOST_NAME, PORT_NUMBER), MyHandler)
    print time.asctime(), "Server Starts - %s:%s" % (HOST_NAME, PORT_NUMBER)
    try:
        httpd.serve_forever()
    except KeyboardInterrupt:
        pass
    httpd.server_close()
    print time.asctime(), "Server Stops - %s:%s" % (HOST_NAME, PORT_NUMBER)

This work perfectly on a Mac with PySerial installed. When I run the very same script on a RaspberryPi, nothing happens. For example, when I use the URL http://192.168.0.17:6066/?rly=7&status=1&port=ttyUSB0, the result on the console is the following:

192.168.0.16 - - [19/Apr/2014 20:59:28] "GET /?rly=7&status=1&port=ttyUSB0 HTTP/1.1" 200 -
All parameters ok, sending command

Opening port: ttyUSB0
Opened port '/dev/ttyUSB0'
Port successfully opened
isWritable = True
Command = 'RLY71'
Writing command on serial port
Bytes written = 6
Reading result
192.168.0.16 - - [19/Apr/2014 20:59:30] "GET /favicon.ico HTTP/1.1" 200 -

I tried chmown-ing the port to user "pi", chmod-ing it to 777, nothing changes.

I ran some more tests. I wrote this stripped down version if the script:

import serial
ser = serial.Serial("/dev/ttyUSB0")
ser.write("RLY11\n")
ser.close()

When I run it as a .py file, is fails. But when I run it from a command-line using python interactive shell (ie: line per line), it works! I have absolutely no idea of what to do, can someone help?

dsolimano
  • 8,870
  • 3
  • 48
  • 63
X99
  • 905
  • 10
  • 24
  • Add a shebang and mark the script as executable: http://stackoverflow.com/questions/7574453/shebang-notation-python-scripts-on-windows-and-linux – User Apr 20 '14 at 10:47

1 Answers1

0

Found out what was wrong, but can't explain why. Now I open the serial port at the very beginning and close it right after httpd.server_close(). Now it works perfectly, but I cannot explain the reason.

X99
  • 905
  • 10
  • 24