The Github lamp

— 2012-09-16 —

Update: This project is now on github: relekang/lumen

My arduino has been collecting dust in a drawer for a while. This weekend I figured why not hook it up with github post-receive hooks and do something cool. The hooks can be set up in the Service Hooks section of a repository's admin page on github. Just add a url to where the web.py site is running and github will send that url a POST request everytime someone pushes a commit to the repository. You can fin more info about post-receive hooks at help.github.com.

About two years ago I rebuilt a IKEA children-lamp to be controllable with high/low digital signals.

The IKEA lamp

I wrote this based on the serial example for the arduino. It turns the lamp on and off according to the commands on, off and blink.

String inputString = "";
boolean stringComplete = false;
int led = 5;

void setup() {
      Serial.begin(9600);  
      inputString.reserve(200); 
      pinMode(led, OUTPUT);
}

void loop() {
    if (stringComplete) {
        if(inputString == "on"){
            digitalWrite(led, HIGH);
        } else if (inputString == "off"){
            digitalWrite(led, LOW); 
        } else if (inputString == "blink"){
            digitalWrite(led, HIGH);
            delay(1000);
            digitalWrite(led, LOW); 
        } else {
            Serial.println(inputString); 
        }
        // clear the string:
        inputString = "";
        stringComplete = false;
    }
}
 
void serialEvent() {
    while (Serial.available()) {
        char inChar = (char)Serial.read(); 
        if (inChar == '\n') {
            stringComplete = true;
        } else {
            inputString += inChar;
        }
    }
}

The arduino is connected to my mac mini. I have some python code running on the mac to write stuff onto the serial connection between the mac and the arduino. I am using web.py and gunicorn to handle the web requests. The web.py-file lighthouse_keeper.py looks like this:

SERIALPORT = "/dev/tty.usbmodemfd121" 

class GithubHook:
    def POST(self):
        send_serial_data("blink\n")
        data = json.loads(web.input().payload)
        print "%s pushed to %s - %s" % (
            data['pusher']['name'], 
            data['repository']['name'], 
            data['repository']['homepage']
        )
        return ""

    def GET(self):
        return "Something is wrong"

def send_serial_data(data):
    #open serial port
    try:
        ser = serial.Serial(SERIALPORT, 9600)
    except serial.SerialException:
        return

    ser.write(data)

    #close serial port
    ser.close()

if __name__ == "__main__":
    app = web.application(urls, globals())
    app.run()

application = web.application(urls, globals(), True).wsgifunc()

To run gunicorn I just run the command:

gunicorn lighthouse_keeper
    arduino
    github
    git
    web.py