Stories about Software


RESTful Home Automation

Here are the general steps to get a REST service going on your Raspberry Pi, using Python. One thing that I’ve learned from blogging over the last several years is that extremely detailed, granular how-tos tend to be the most yawned-at posts. So this is just a quick overview of how you can accomplish the goal without going into a lot of detail. If you want that detail, you can drill into the links I’m providing or else feel free to ask questions in comments or via email/twitter.

  1. Go out and buy these things: USB transceiver, plugin transceiver, lamp module (optional)
  2. On your Pi, install apache with sudo apt-get install apache2.  This is the web server.
  3. Also on your Pi, install web2py with sudo apt-get install python-webpy.  This is the module that makes setting up a REST service a snap.
  4. Install some driver dependencies (I will probably later roll these into what I’m doing) with “sudo apt-get install libusb-1.0 python-usb”.  Here are more detailed instructions from the page of the home automation python driver that I’m using.
  5. Follow the instructions on that page for disabling interfering kernel drivers.
  6. Give your user space account permissions to hit the USB device from the referenced instruction page, but note a typo where he says “sudo nano /etc/udevrules.d/cm19a.rules” and you really want
    “sudo nano /etc/udev/rules.d/cm19a.rules”.
  7. Now go get my stuff from github and run a web server using python rest.py <port>

That’s all there is to it.  Right now, at the time of writing, you would go to http://<your pi’s ip>:<port>/office/on to basically turn everything from A on.  A and office are both hard-coded, but that’s going to change in the next few days as I grow this service to support adding rooms and lights via PUT, and storing them as JSON documents on the server.  You’ll be able to add a light with PUT, supplying the room, light, and X10 code, and then you’ll subsequently be able to toggle it with http://pi:port/room/light/{on/off}

You can also just install Andrew’s driver and use it as-is.  It even has a web mode that supports query parameters.  The reason I didn’t do things that way is because (1) I wanted a REST service and (2) I wanted to be able to customize everything as I went while learning a new language.


Getting Started with Raspberry Pi

What and Why?

(If you’re here because you googled for a RPi tutorial, I’d suggest skipping to the next section)

I’ve recently throttled back on being all .NET all the time, mainly because I’m trying to spend more time working on my home automation. Toward that end, I recently picked up a Raspberry Pi. Since the organization’s home page neglects to include an elevator pitch as to what it actually is, I’ll summarize by saying that the Raspberry Pi (or RPi, for short) is a fully functional computer that’s about the size of a credit card and contains a good cross section of the device I/O that you might want, including audio, HDMI, USB, and ethernet. Oh, and they’re $35.

I’d imagine that most of you reading have either heard of this or, if you haven’t, you’re thinking of half a dozen uses now that you’ve read my description. But if you aren’t, here are a few uses you might find attractive: tiny media PC, small robot controller, car OBD troubleshooter device, Roomba brainwasher (I totally want to do this and use it to chase my cats around). One could also use it, as I plan to, for home automation.

My purpose here with my first RPi is going to be relatively simple — I’m going to offload the home automation controlling functionality of my home’s server onto it. The server I’m currently using is a repurposed dinosaur that I took with me to college (P2, 400 MHz processor, and tricked out to the max in slots with a whopping 3 128 MB sticks of RAM). It chugs along with an old Fedora installation, running a web server, SVN, a few databases, samba, and a few other goodies, as well as being hooked up to my big external drive where media is stored and eventually whisked into the cloud via Crash Plan. Add to this the fact that there’s a firecracker module plugged into its serial port to make the jump from my software to the electrical, and this is a pretty busy old machine that may not be long for this world. So I’d like gradually to parcel out its functionality to a handful of other machines to minimize my exposure to an extremely annoying failure, and the RPi is perfect, spec-wise and form-factor-wise, for the home automation web server.

Before Getting Started

So your Pi arrived in the mail, it has no installed OS, no instructions, and you’re not really sure what to do. No worries. I was like you, and I fumbled through it cobbling together a variety of guides and tutorials, and here, centralized in one place, is how I did it. This is the dead simple, option-free way to get something going with your RPi. All you’re going to get from this tutorial is an OS and web server on the device, but you’re not going to have to pick

RaspberryPiFirst off, prerequisites. To get started, here’s what you need:

  1. The RPi, obviously (pictured)
  2. A formatted Mini SD card that will act as the hard drive (pictured), or optionally a MicroSD card with a mini adapter. Either way, it needs at least 2 GB of space
  3. A micro-USB electronic device charger (i.e. an “anything but Apple” cell phone charger) to power the Pi.
  4. A desktop, Windows computer with either an onboard or connected SD card reader/writer
  5. An internet connection
  6. (Optional) HDMI to DVI adapter if you plan to spend a significant amount of time with your RPi plugged into a monitor.

You can probably make it happen without most of these things, but this is what I was working with when I did it, so if you have a Mac or want a different Linux distro on your RPi, this isn’t the tutorial for you.

Linux on the Pi

Here are the steps that I followed:

  1. First, download the zipped OS, “Raspbian Wheezy” for the RPi at this link, which will actually trigger the download. If that becomes defunct or you want to find it on your own, you can go to the RPi download site.
  2. Now that you have the OS, you need a means of putting it on the SD card. For that, you’ll need the Win32 Image writer (link triggers actual download of zip) or find the download yourself at their site.
  3. Plug your SD card into your SD reader/writer.
  4. Extract the contents of both of the zip files that you downloaded and launch the disk manager utility with administrator rights. If it takes a long time to load, there’s probably a driver issue with your SD card — that happened to me, but the fix was very specific to my hardware and is thus beyond the scope of this tutorial.
  5. Choose the Wheezy-Raspbian img file and the drive in which your SD card is mounted on your computer (below). For me the only option was the drive with the SD card, but make sure you double check that it’s the right one — I don’t want to be responsible for your frying some drive you need with a Linux install.WinDiskManager
  6. When you’re sure you’re not blowing anything you need away, click “Write,” and then click “OK” when warned.
  7. The write process will take a while, with specifics depending on your hardware. For me it took about 10 minutes. At the end, a “Write Successful” dialog will appear.
  8. Pop the SD card out of the computer and put it into the RPi.
  9. Plug your RPi’s HDMI into a TV (or monitor with the adapter) and plug a USB keyboard and mouse into the RPi.
  10. Now plug the RPi into power and let it boot up. It should look like a normal Linux boot sequence:
  11. Once it boots up, you’ll be shown some initial configuration options. I enabled SSH and expanded the root partition to use my entire 8 Gig SD card. Your mileage may vary here, but I bought the SD card just for the Pi and I have no interest in leaving the Pi plugged into my bedroom TV on a permanent basis, preferring to remote in.
  12. I also enabled booting into desktop, though I may later get rid of that option since the Pi will be headless. From there I selected “Finish” and rebooted. This took a while since it resized the root partition on reboot.
  13. Once it booted, it booted to a cute little desktop with the RPi logo in the background and you can configure it like any other Linux distro.
  14. One early thing to note is that the default user/pass is pi/raspberry — this will help if you drop into a console tty. (i.e. you hit ctrl-alt-f4)
  15. On the desktop, I noted that wheezy ships with WPA-supplicant for wifi config, which is handy if you have a wifi USB dongle, though I did not go this route — I have known much pain from using wpa_supplicant 5-6 years ago with AES before the utility was mature.
  16. After playing with the RPi desktop a bit, I powered down and disconnected from the TV, setting it up headless in my office, to be accessed via SSH.
  17. At this point, I tunneled in via SSH and ran an update. I had seen that things weren’t working on the desktop because it needed updating, so, first things first. “sudo apt-get update” did the trick (after about 4 or 5 minutes).
  18. To put apache on there, I did “sudo apt-get install apache2”. Ah, apt-get, the original app store.
  19. Finally, if you’re going to have a web server, it makes sense to give it a static IP. There’s nothing specific to Wheezy about this — it’s just standard Linux networking involving modifications to the network/interfaces file.

And, viola! The transformation from RPi in the box it shipped in to little web server is complete.


Configuring Fedora and MongoDB

In my last post, I covered installing MongoDB on Fedora. This is another post as much for my reference as for anything else, and I’ll go over here getting set up so that my application successfully uses the MongoDB server.

When I left off last time, I had successfully configured the server to allow me to create documents using the mongo command line utility. So, I created a collection and a document and was ready to access it from my web application. Following the examples in the MongoDB java tutorial, I created the following implementation of my HouseService interface that I had previously hard coded room values into:
Read More


Setting up MongoDB on Fedora

This is one of those posts as much for my own reference as anything else, and if it helps others, then bonus.

I installed MongoDB on my old Fedora server just now, and while it was actually pretty straightforward to do, I figured I’d document the steps. The first thing to remember is that there are two separate installs: the client and the server (this is what tripped me up on the MongoDB site’s documentation). There isn’t some deal where running server install also gives you a client.

So, to set up a smooth, easy install with yum, the first thing you need to do is create the file “/etc/yum.repos.d/10gen.repo”. Once you’ve created that file, open it and add the following:

Now, once you’ve got that in place, run the command, “yum install mongo-10gen mongo-10gen-server”. This will install both the client and the server. When the client and the server are in place, you can start the server by running “/etc/init.d/mongod start”. Finally, if you’re like me, you probably want the server to run automatically. If that’s the case, execute the command “chkconfig mongod on”.

And, you’re set. MongoDB server is installed and running and will also run on your next reboot.


Fixing the Crackle and Pop in Ubuntu Sound

So, as I blogged previously, I’ve been re-appropriating some old PCs and sticking Ubuntu 11.10 on them. I had one doing exactly what I wanted it to do in the context of my home automation network with one small but annoying exception. Whenever I would play music through headphones or speakers, there would be a crackling noise. A google search turned up a lot of stuff that I had to weed through, but ultimately, this is what did the trick:

I opened /etc/pulse/default.pa and found the line

load-module module-udev-detect

This was located in an “ifexists” clause. It should be replaced by this:

load-module module-udev-detect tsched=0

From there, reboot. I can’t speak to whether this will fix everyone’s crackle or just some people’s, and I can’t speak to why this setting isn’t enabled by default, but c’est la vie. This is what did the trick for me, and hopefully it fixes the problem for someone else as well.