The Most Face Rockingest Project Blog on the Entire Fucking Web
The Pi Control Script
Published: July 8, 2013
My google AD, I know most hackers and DIY'ers hate ads but it brings in around 5 bucks on a good month and I use it to subsidize my hosting fee's so you can get access to my code :)

The Raspberry Pi was built as a cheap, educational computer platform for students. But it’s exposed GPIO pins, linux support and prices comparable to an Arduino, have all contributed to it’s meteoric rise as an ‘internet of things’ style embedded computer. Many projects have used it’s small form factor to control all types of things. For example, the Cloud Lamp project, that I recently built!

In the past, when I’ve wanted to connect a hardware project to the internet, I’ve gone with Arduino and an ethernet shield. The problem with this solution is that the price was high and the available space for software was limited. This is where the Raspberry Pi really shines! But in order for the Raspberry Pi to provide these great benefits, you’ll need your program to be able to communicate. In particular, a web-based API will make it a snap to communicate with. Python is a popular language for using the GPIO pins and so pairing that with the Twisted networking module makes for a powerful program.

First check out what I was able to accomplish using this technique, then, after the video, stay tuned for a simple, pared down and detailed tutorial of the basics. After that I jump into the code that powers the actual lamp!

A simple example and tutorial of the basics of turning a Raspberry Pi into a networked controller

First, let’s consider a simple example of a single bulb lamp connected to a powerswitch tail, which communicates with a Raspberry Pi on GPIO pin 17.

If you wanted to write a python program that would turn the lamp on, then off the code would look like this:

If you’ve programmed for an Arduino before, this code is really straightforward.

  • The first few lines are setup, import will load the Raspberry Pi GPIO library
  • The second sets the pin naming scheme
  • The third tells pin 17 to be an output pin.

Once the setup is taken care of you can turn the pin off or on now, easily. Which in turn turns the lamp off and on!

Now we can control the hardware, but what good is a controller program if it isn’t  listening? Here’s where Twisted comes in, let’s say we wanted to be able to turn the lamp off and on remotely. The code to listen for input over the web looks like this:

After including the twisted modules you’ll recognize the GPIO setup again.

The next chunk is our response class, it will define a standard ‘get’ request that we can use as an API to turn the bulb off and on. ‘lampAPI’ is the class name I chose, name it whatever you like. In the first IF statement, the first term in the condition is the URL variable. So if you want your API call to look like this ( http://127.0.0.1/API?foo=1 ) then you would put ‘foo’ in the quotes instead. Once you’ve confirmed that your variable made it into the request object, you can now check what the variable holds. That’s what the next two IF statements are doing. The variables can contain whatever you like. You could look for a zero or one, yes or no, off or on, etc. Again, you should recognize the GPIO statement from before, that will turn the light off or on, respectively. The return statement should be a string, and whatever it contains is what the client will spit out to the browser!

Lastly, the Twisted object is initialized, and the program enters an infinite loop where we check to see if there’s a new request, forever. Now you can turn your light off and on from anywhere by typing the following URL/commands:

  • http://[ip of rasberry pi]/API?light=on (Turn the light on)
  • http://[ip of rasberry pi]/API?light=off (Turn the light off)

Ok, this is great, but an API is an interface for robots, let’s make one for humans.

The first step is to set up the root object of the twisted object to pass files to the client, which is the primary job of a web-server. This can be done simply by changing:

to

Now, create a directory called ‘lampwww’ in the same directory as your python file. Anything called from the URL of the Pi will be passed along to the browser. The last step here is simply creating an html file with links that will call up our API. In it’s simplest form, it could look like the following (create a file called index.html and put it in the lampwww dir) :

If you browse to the IP of your lamp, you’ll see the heading and the two choices to turn the lamp on or off; Tada! Web-connected lamp.

Getting more sophisticated: showing what I added to get the functionality in my Cloud Lamp project

I crafted this simple example to make an easy to follow tutorial but there’s a whole lot of improvements that could be made. In my Cloud Lamp project for instance, I not only had light bulbs connected, I also had a 60 ‘pixel’ string of ws2801 LED’s. So what could we do with this type of display? How about creating different modes of operation, each with it’s own unique display.

Adding this functionality required a few key changes, first, the end of our example is an infinite loop that looks for changes from the network. We need to change this so that we can do other things besides listening. The statement,

will run the loop, but if we change that to

Now we’re not tied down to only listening for new connections. The end of our program would now be an infinite loop that includes but is not limited to, our listening statement, like this:

Next, how do we animate the LED’s in different modes, which is a continual process, while also listening for new connections. I opted for a simple list of IF’s that choose which animation subroutine to run on every loop iteration. A global ‘mode’ variable will decide which animation to iterate through. Each of the animation sub-routines is contained in a function that can be called on from the main while loop. In my infodisplay mode, I’m showing the state of the house (Whether all the doors are close or not, whether there’s motion in the house), the surf report and the weather report. I accomplished this by using the Beautiful Soup module to scrape a Magic Seaweed widget, Weather Underground’s API for the weather report and MicasaVerde’s json feed, all formatted to output into a serial list of multicolored LED’s.

I'm into the flat look these days :)

I’m into the flat look these days :)

And finally, I wrote a more sophisticated web interface, taking advantage of the ample speed and space available on the Raspberry Pi. Besides a fancier looking interface, the important part is multi-directional feedback powered by Jquery. Talking to the lamp is easy, i just use standard .click’s on the mode buttons and .get’s to call the API that I created. The web interface is also able to dynamically tell which mode it’s in and whether the bulbs are off or on. I do this by creating another API that spits out a Json feed of the state of all the lamp’s functions, like this:

Then, I use Jquery’s cross-domain capable Jsonp functionality to check the status every X number of seconds and update the interface. It’s fairly simple from a code perspective and the result is that even with multiple interfaces open, they will all update depending on the actual state of the Lamp!

Well, now that I’ve talked about most of what makes my Cloud Lamp Project tick, why not dig into all the code yourself? It’s up on Github, feel free to modify, use, scoff at or appreciate all of it! :)

[ml_raw_html]


 

The Cloud Lamp

Dig into all the code for my Lamp project or grab the whole package for your modifying pleasure!

[/ml_raw_html]

What’s next?

In addition to turning the light-bulbs off and on and running the LED’s internally, I’ve also got a mode that allows the LED’s to be controlled externally through a TCP stream. It’s too slow to be very functional right now, however. And still requires some debugging. To try that as well, here’s an example Processing.org script:

I will also be coding and publishing a Mi Casa Verde plugin that will allow you to control the functions of the Lamp and see it’s status through their home control system.

Finally, a few features I plan on adding to the setup are a brightness setting for all Modes and some kind of mechanism for letting modes have individual settings. Like frequency for the strobe lights, or speed of drops for the rain mode.

Let me know if you have any comments or questions down below! :)

--

Hey thanks for reading this far! Maybe you'll be interested in more of my projects? Check out my homepage :)
This entry was posted in Software and tagged , , , , . Bookmark the permalink. Follow any comments here with the RSS feed for this post. Post a comment or leave a trackback: Trackback URL.

19 Comments

  1. Posted Jul 12 at 7:23 pm | Permalink

    Great Project … enjoyed it very much … TnX

  2. Zoe Korn
    Posted Jul 13 at 9:49 am | Permalink

    Thanks for sharing this Raspberry Pi based project. Ir looks great and I am going to see if I can get it to work myself even though I am a newbie. Thanks again

    • Posted Jul 13 at 12:30 pm | Permalink

      My pleasure, that’s very cool that you’re going to try it. Please let me know if you run into trouble! You can email at falldeaf@gmail.com And if you get it up and running will you send me a pic? :)

      • Zoe Korn
        Posted Jul 14 at 8:45 am | Permalink

        Absolutely. But just to set expectations, this may take me a while. I am probably more of a “kit-builder” type than a “software coder” so my understanding things like your HTML/CSS coding for the buttons will take me some time to figure out.

  3. Posted Aug 06 at 1:16 pm | Permalink

    Hey thanks for the detailed how to, I’ve been using your code for a similar project. There’s a small error in your second code block, there should be a : after class lampAPI(Resource) ,being new to python that threw me off for awhile because I kept getting syntax errors on line 9. Thanks again!

    • Posted Aug 06 at 1:26 pm | Permalink

      Woops! You’re exactly right. Thanks for spotting that and posting the correction!

      I’m glad to hear that my how-to has helped with your project, what’cha workin’ on? :)

      • Posted Aug 07 at 1:38 pm | Permalink

        No problem. I’m working on a glowing cube that cycles through similar modes. It’s a raspberry pi with adafruit rgb leds mounted on the top.

        • Posted Aug 07 at 1:42 pm | Permalink

          I also had a quick question, I’ve been trying to include an infinite while loop within the if [Lights on] condition. I’d like the function to keep running while turned on. Am I just implementing it wrong or is it impossible?

          • Posted Aug 07 at 1:53 pm | Permalink

            That sounds like an awesome project! Will you be posting pics or video anywhere?

            For your question:

            There should only be one, main infinite loop, unless you want to do something completely different for a while. For instance, in my main loop, on every iteration, I check for network requests and redraw the LED’s. But, if a network request to go into “data stream mode” where a client is constantly sending in animation frames, then I go into a different loop.

            So unless you’re trying to change the functionality of your cube on the fly, you probably don’t want another loop. The main loop should handle everything. The key is to have all of your functions be non-blocking. So if one of your functions is an animation, don’t run the entire animation inside of your function. Just run one frame and increment a frame number every time your function is called.

            I hope that makes sense, is that what you were asking about?

          • Posted Aug 07 at 3:03 pm | Permalink

            Thank you that makes perfect sense! I will be posting a video and pictures once it’s more complete I’ll definitely post a link here when it’s close to done.

            I’m just wrapping my head around twisted and the way things work, I’ve mostly work with frontend stuff. I seem to be running into another error now when i add root = File(“lampwww”) I get an “NameError: name ‘File’ is not defined”

          • Posted Aug 07 at 3:15 pm | Permalink

            Opps never mind needed to import it from twisted.web.static import File

  4. dave
    Posted Sep 15 at 12:39 pm | Permalink

    how did yo scrap the images on magic seaweed and then get the color hashes from them aswell

    nice project by the way :)

    • Posted Sep 15 at 12:56 pm | Permalink

      Thanks for the compliment :)

      I went to the magic seaweed widget maker to get nice, simple html, then used python’s Beautiful Soup plugin to scrape out wave heights. The color coding is just a simple array based on ranges. 0 – yellow / 1-2 – light blue / 3 – 4 – aqua, etc

      Thanks for reading about my project!

  5. Ant
    Posted Oct 06 at 6:38 pm | Permalink

    Thanks for sharing. This is exactly what I was looking for when researching for a project of my own. I am not too familiar with python or linux systems so this might seem trivial. I am trying to recreate your results step by step and I have installed the necessarry modules and also apache thinking I need it to serve up the webpage. My problem is once I navigate to the test page and click ‘turn on’ I get Not Found

    The requested URL /API was not found on this server.

    I am thinking that is due to the locations of the files but I am not sure. Currently I have the lampd.py in “/www” and index.html in “/www/lampwww”. I also updated the html file with the correct IP address. Any help would be appreciated and thanks again for posting.

    • Posted Oct 06 at 6:48 pm | Permalink

      Hi Ant :)

      Very cool that you’re recreating my setup; I’d love to see some pics when you get it working!

      The lampd.py python script itself will not need Apache or any other web server, it is the webserver, via the Twisted python library.

      Just run it from the command line:
      $ sudo python lampd.py

      then, as long as the html files are wherever you specified in your python file, you should see the web page by pointing your browser to the IP of your Raspberry Pi.

      Good luck and please let me know if you need any more help. Feel free to email me directly at falldeaf@gmail.com, or stick with the comments, either way :)

  6. Anders
    Posted Dec 03 at 2:31 pm | Permalink

    Dear Sir!

    Thanks for some very inspiring projects. I’m currently watching a LED on my Raspberry Pi blink on and off as my buddy sits on the other side of the planet and presses a button on a website. The world is a wonderful place.

    However, I think it would be even more wonderful if the second GPIO call (line 3 in your first example, line 7 in your second) whould read “GPIO.setup” rather than “GPIO.setmode”, if I’m not mistaken?

    Best regards,
    /Anders

    • Posted Dec 03 at 2:45 pm | Permalink

      The world is indeed a wonderful place, and now, very slightly more so! Thank you for the correction. :)

  7. JM
    Posted Mar 02 at 5:13 pm | Permalink

    Any idea why I am getting this when I attempt to run basic code to turn on/off light? I’m just starting out so probably made a rookie mistake.

    /home/pi/twisted.py:3: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
    GPIO.setup(25, GPIO.OUT) #Tell pin 25 to be an output pin
    Traceback (most recent call last):
    File “/usr/bin/twistd”, line 13, in
    from twisted.scripts.twistd import run
    File “/home/pi/twisted.py”, line 7, in
    from twisted.web.resource import Resource
    ImportError: No module named web.resource

    No matter what I seem to do it can’t find the web.resource module.

18 Trackbacks

  1. […] Via falldeaf.com: […]

  2. […] with an Ethernet shield to add extensible interactivity to his project. But this one, which is a home automation lamp project, uses a Raspberry Pi instead. The concepts end up being very similar. But the cost of the hardware […]

  3. […] an Ethernet shield to add extensible interactivity to his project. But this one, which is a home automation lamp project, uses a Raspberry Pi instead. The concepts end up being very similar. But the cost of the hardware […]

  4. […] with an Ethernet shield to add extensible interactivity to his project. But this one, which is a home automation lamp project, uses a Raspberry Pi instead. The concepts end up being very similar. But the cost of the hardware […]

  5. […] with an Ethernet shield to add extensible interactivity to his project. But this one, which is a home automation lamp project, uses a Raspberry Pi instead. The concepts end up being very similar. But the cost of the hardware […]

  6. […] with an Ethernet shield to add extensible interactivity to his project. But this one, which is a home automation lamp project, uses a Raspberry Pi instead. The concepts end up being very similar. But the cost of the hardware […]

  7. […] with an Ethernet shield to add extensible interactivity to his project. But this one, which is a house automation light proposition, employs a Catcall Pi rather. The notions expire up existence mere kindred. Still the expense of […]

  8. […] The Pi Control Script | Fall Deaf via Hack a Day […]

  9. […] The Pi Control Script | Fall Deaf via Hack a Day […]

  10. […] The Pi Control Script [Fall Deaf via Hack a Day] […]

  11. […] The Pi Control Script | Fall Deaf via Hack a Day […]

  12. […] Th&#1077 Pi Control Script | Fall Deaf via Hack a Day […]

  13. […] Project Source: TnX && CrediT […]

  14. […] The Pi Control Script | Fall Deaf around Hack a Day […]

  15. […] The Pi Control Script | Fall Deaf via Hack a Day […]

  16. […] falldeaf shared: “In the past, when I’ve wanted to connect a hardware project to the internet, I’ve gone with Arduino and an ethernet shield. The problem with this solution is that the price was high and the available space for software was limited. This is where the Raspberry Pi really shines! But in order for the Raspberry Pi to provide these great benefits, you’ll need your program to be able to communicate. In particular, a web-based API will make it a snap to communicate with. Python is a popular language for using the GPIO pins and so pairing that with the Twisted networking module makes for a powerful program. First check out what I was able to accomplish using this technique, then, after the video, stay tuned for a simple, pared down and detailed tutorial of the basics. After that I jump into the code that powers the actual lamp!” (read more) […]

  17. […] wherever you may be. [Cool, right?]) maybe I will manage to gradually build up to this level. I am also expecting a delivery which will enable me to get started with another one: movement […]

  18. […] wherever you may be. Cool, right?) maybe I will manage to gradually build up to this level. I am also expecting a delivery which will enable me to get started with another one: movement […]

Post a Comment

Your email is never published nor shared. Required fields are marked *

*
*

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code class="" title="" data-url=""> <del datetime=""> <em> <i> <q cite=""> <strike> <strong> <pre class="" title="" data-url=""> <span class="" title="" data-url="">