Things I'll Forget In A Month Tech scratchpad and musings

10Nov/110

plmtools-imeter

I've packaged up a new release of the modified plmtools package for talking to the iMeter. I think the code has diverged from the base plmtools enough to warrant a rebranding, so I'm (uncreatively) naming the fork 'plmtools-imeter'. I've posted a page for the project over on the main site (but for the impatient among you, here's a direct link).

Improvements from the previous release include support for both Revision 1.1 and 1.15 iMeters (thanks to Erik Wile for his detective work regarding that issue) and a variety of other smaller improvements.

A bit over a week ago I presented my research group's recent work on building monitoring using home automation devices at the BuildSys 2011 workshop in Seattle. Our paper on this work ('Exploiting Home Automation Protocols for Load Monitoring in Smart Buildings') was facilitated in part by the plmtools-imeter package.

25Apr/1110

plmtools for the iMeter Solo and/or the GuruPlug

Update (11/10/2011): I've posted an updated version of the code that fixes the issue with the new 1.15 iMeters: see my more recent post.

Update (9/26/2011): Smarthome has come out with a new revision of the iMeter that breaks this utility -- the meter firmware seems to have changed, and the new one does not provide all the information of the old. To see if you have the old meter (that does work), look for a sticker on the back side of the iMeter. If you see a "V1.1", then you have the old one (good). If you see a "Rev. 1.15", then you have the new one (bad). I'm working on figuring out the 1.15 protocol to get this utility working again with the new ones.


One of my current research projects involves instrumenting a house with a lot of Insteon home-automation devices and collecting data from them. I've been using the very useful Linux plmtools utilities to talk to the Insteon devices programmatically. However, the plmtools suite has a few shortcomings for my purposes: one, the current release doesn't compile or run on ARM-based machines (such as the GuruPlugs I'm using) and two, it has no functionality for talking to the new Insteon power meter, the iMeter Solo. The iMeter Solo basically works exactly like a Kill-A-Watt meter, except that since it's an Insteon device it's possible to interface with it.

I've dealt with both of the above problems. I've fixed the ARM-specific problems in the code so it runs great on the GuruPlug, and I've added functionality for querying the current wattage level from an iMeter Solo. I imagine there are others who would like to use plmtools on ARM-based machines, and as far as I know there are no existing tools that allow you to query the iMeter from within Linux. Now, you can query the current watt draw reported by the iMeter using a simple 'insteon mydevice meter' command.

Also note that the iMeter Solo is frequently advertised alongside a special 'HouseLinc'-enabled version of the PLM that's required to use the HouseLinc software that can talk to the iMeter. This is unnecessary for my solution, which works just fine on a regular PLM.

You can download the modified plmtools here. See the included README for details both on how the base plmtools utilities work as well as how the added meter functionality works. I'm trying to get in touch with the original author of plmtools to see if I can get these changes integrated into a future release on SourceForge, but so far haven't had any luck.

22Feb/1115

Configuring the GuruPlug as a wireless client

By default, the GuruPlug comes configured to act as an access point, which is probably not what most people want. Unfortunately, getting the plug to act as a reliable wifi client is nontrivial. Most existing tutorials on the topic are pretty in-depth - I'm going to give a quick and dirty method for getting wifi configured and working reliably. It's been working nonstop on my plug for several weeks with no dropouts, kernel panics, or the like.

Most of this howto is derived from info gleaned from the Plug Computer wiki, the Plug Computer forum, and tweaks I made myself.

We're going to install a custom 2.6.33.7 kernel. A prebuilt image and modules are provided on the Plug Computer wiki. A note about u-boot: I'm not sure if the included bootloader on the plugs can boot custom kernels, but if you opt to upgrade it, I recommend the version linked here. I'm not going to discuss the bootloader setup any further in this post.

Login to your plug as root, then download and install the kernel image:

wget http://www.plugcomputer.org/plugwiki/images/4/4c/UImage_linux_kernel_2_6_33_7.tar.bz2
tar xvfj UImage_linux_kernel_2_6_33_7.tar.bz2
cp uImage /boot/
chown root:root /boot/uImage

And now the kernel modules:

wget http://www.plugcomputer.org/plugwiki/images/0/0a/2_6_33_7_modules.tar.bz2
tar xvfj 2_6_33_7_modules.tar.bz2
mv 2.6.33.7 /lib/modules/

Now we'll grab an archive of the wifi drivers and firmware, some custom wifi initialization scripts, and the wifi configuration file. We'll store all this stuff in /root.

wget http://blog.zortrium.net/files/wifi-files.tar.gz
tar xvzf wifi-files.tar.gz
mv wifi-files/* /root/

There are three main wifi files. The script that runs before Linux brings up the wireless interface is /root/wifi_pre.sh and executes some firmware voodoo to get client mode working properly. The script that runs after the interface is up is /root/wifi_post.sh and turns on a blue LED to give a visual indication that the wireless came up successfully. Finally, there's the wireless settings file /root/wifi.conf.

Open up wifi.conf and input your wireless settings. The file should be self-explanatory and basically fill-in-the-blanks for most setups, but you can read 'man wpa_supplicant.conf' for all the gory details and possible settings.

Now we need to configure Linux to cleanly bring up the wireless interface. Open up /etc/network/interfaces and input the following entry for the wireless interface mlan0:

auto mlan0
iface mlan0 inet dhcp
pre-up /root/wifi_pre.sh
post-up /root/wifi_post.sh
wpa-conf /root/wifi.conf

This will cause the plug to DHCP a wireless address -- you can also assign a static IP as you would for any other interface.

Finally, the default GuruPlug filesystem includes a bunch of garbage in /etc/rc.local. Remove any stuff pertaining to wireless (my rc.local has nothing in it at all).

And that's pretty much it. Assuming your plug is properly configured to boot from /boot/uImage, you should be able to restart and Linux will bring up the wireless at the same time it brings up the wired interface (if configured in /etc/network/interfaces). The blue LED will confirm that the wireless came up successfully.

Update (4/11): One problem I've encountered that may bite you later is that the uImage file is (re)generated by updates to the installed kernel package -- which is probably still installed on the plug, even though we overwrote the kernel image. This means that the next time you update your software and an update to the (unneeded) kernel package is pulled down, your custom uImage will be overwritten and the plug will be rendered unbootable the next time it starts. You should be able to avoid this problem by renaming the custom uImage to something else (like /boot/uImage-custom) and then changing the bootloader to boot from that rather than the standard /boot/uImage. Otherwise, when your image gets overwritten, you'll need to manually replace your custom uImage (easy enough if you're running off an SD card).

8Feb/106

My Plug for the SheevaPlug

A month or two ago I picked up a Marvell SheevaPlug to use as a multipurpose home server. Previously, I'd been running all my network services (primarily this web site and an SSH server) on my iMac, but this had several downsides: I had to leave my iMac on all the time, and, more seriously, all my services went down every time I wanted to reboot into Windows. Being a lifelong Mac user, I didn't have an old PC lying around to dedicate as a full time Linux server, and my tiny apartment wouldn't accommodate a tower very well anyways. The SheevaPlug was an ideal alternative -- tiny, silent, very low power, and powerful enough for my home needs.

The plug comes with a 1.2 GHz single-core ARM processor, 512 MB of RAM, 512 MB of built-in flash (preloaded with an Ubuntu 9.04 installation), and a gigabit Ethernet port. The processor isn't going to compete with a typical dual or quad-core Intel processor, but it's got plenty of punch for a regular Linux installation and beats the heck out of a typical NAS box. The flash is something of a problem, since it's quite easy to fill up the 512 MB with applications and obviously you can't store any appreciable amount of media on it. Luckily, the plug also has a USB 2.0 port and an SD card slot. The board itself also has an eSATA connection, but the most common SheevaPlug model (manufactured by GlobalScale Technologies) doesn't have it exposed. Some newer manufacturers have started building in an eSATA port and some adventurous souls have successfully modded their plugs to expose the existing connection, but I don't trust myself that much with a soldering iron so I've stuck to USB for external hard drives. My plug and all peripherals only cost me about $200 total for the plug ($99, purchased here), a 500 gig hard drive ($50), an external USB enclosure ($30), and annoyingly steep shipping costs for the plug ($20). I'm not using the SD card slot at the moment, but a popular use for it is to put the kernel and OS on an SD card and just use a USB hard drive for media -- this is beneficial both because the bootloader is more reliable booting from an SD card than USB and also because it allows easily swapping out the OS on multiple cards.

The default Ubuntu installation is fully functional, which is nice because you can just connect the ethernet cable and SSH into the plug. Unfortunately, there are a few weird or broken things in the default install that make doing a clean install desirable. A bigger problem is that you can't upgrade the plug to Ubuntu 9.10 because 9.10 builds with an incompatible ARM instruction set, so as soon as support for 9.04 ends, you're out of luck. This is why a significant number of people have loaded other distros onto it (Debian and Gentoo being the two I've seen most mentioned). Being most familiar with Ubuntu, I went with Debian, which also has a great installation site courtesy of Martin Michlmayr. I installed everything on my USB hard drive and left the internal flash untouched as a backup. Booting the kernel off USB is a little flaky due to the buggy u-boot bootloader, but once the plug is booted it's rock solid for weeks on end.

I'm running a whole pile of services on my plug 24/7:

  • This web site: Apache 2, PHP 5, and MySQL 5, with WordPress for the blog.
  • The Transmission BitTorrent client, controlled via the slick web interface. Transmission is nice and efficient and rarely makes my plug sweat even when maxing out my cable connection.
  • mt-daapd for serving music to iTunes clients on my network, gradually switching over to forked-daapd for both music and video streaming to Front Row.
  • An NFS server sharing a dedicated media partition on the external hard drive -- I use this to share a single iPhoto library across my iMac and two laptops, and also house my music collection on it. I've set my iMac to manage my NFS music collection in iTunes directly, so whenever I import new music on my Mac, it gets copied over to the SheevaPlug automatically where it's picked up by forked-daapd and shared across the network. This also lets me easily sync my iPod on my Mac without maintaining two copies of my music library. I picked NFS for sharing vs AFP or Samba because (1) I don't have any Windows clients to worry about, and (2) NFS easily has the best performance. My LAN is only 100 mbit rather than gigabit, but the SheevaPlug easily maxes out my bandwidth (~11-12 MB/sec). I've read accounts that on a gigabit network, the plug can push around 30 MB/sec over NFS, though significantly less with Samba.

I'm constantly refining how I use my plug, but I've been very happy with how it's worked out, and I can now turn off or reboot my Mac into Windows at will without interrupting my site, torrents, or music streaming. Getting everything running just right definitely requires some careful research and trial and error, though -- don't expect to get everything working in one night (or one weekend, for that matter). Lastly, I should point you to the most useful general SheevaPlug resources on the web I found:

  • The aforementioned Debian on SheevaPlug site for getting a fresh Debian installation running
  • The ComputingPlugs wiki -- lots of good info for getting set up initially, though some of the kernel specific stuff (like patches) are out of date.
  • The OpenPlug wiki -- I referred to this a couple of times when I couldn't find things on the ComputingPlugs site, and finally,
  • The Plug Computer Forums -- forums for everything from the bootloader to software installations to hardware mods. Lots of good stuff and a place to ask questions if you're stuck.

Happy hacking!

Filed under: Plug Computers 6 Comments
31Jan/103

forked-daapd and libantlr3c on SheevaPlug

11/10 Update: As several people have pointed out, since this post was written, forked-daapd has been added to the standard Debian repositories. Thus, if you are running Debian Squeeze (or newer), installing it is now as simple as 'apt-get install forked-daapd' and none of the below is necessary.


I recently purchased a SheevaPlug to use as a home server in an environment of mostly Macs.  I'll post in more detail about my SheevaPlug setup later, but here I wanted to detail how I got forked-daapd running. I've got a Debian installation on my plug (previously Lenny, now upgraded to Squeeze) and while installing most things is as easy as 'apt-get install package', getting forked-daapd running turned out to be a major pain due to one of the dependency libraries, libantlr3c. I'm not aware of anyone else who installed libantlr3c on the SheevaPlug, so I'm posting how I got it to work here.

The forked-daapd package is very new and very under development, so there aren't any packages in the Debian repositories. Over at the Ubuntu forums, someone posted instructions on compiling forked-daapd on Ubuntu 9.10. Since Ubuntu and Debian are quite similar under the hood, I figured the same instructions should work on my plug, but problems occurred with getting the libantlr3c libraries to compile. After installing all the dependency libraries from the repositories, the configure script ran to completion, but the resulting make failed immediately. The first error was a bad compiler flag '-m32', which does nothing on an ARM machine like the plug anyways, so I just deleted it from the makefile, but then I started getting weird errors during the make like

/usr/lib/gcc/arm-linux-gnueabi/4.3.2/include/stddef.h:214: error: duplicate 'unsigned'
/usr/lib/gcc/arm-linux-gnueabi/4.3.2/include/stddef.h:214: error: two or more data types in declaration specifiers

It turns out that something went wrong in the configure script and it couldn't find a bunch of standard headers that were exactly where they ought to be in /usr/include, and thus the generated antlr3config.h was completely wrong. The only solution I found was hand-editing this file to have the correct values -- once I did that, I was able to manually compile and install the static library.

The forked-daapd instructions at the Ubuntu forums used antlr 3.1.3 -- I used 3.2 and didn't have any problems, but make sure you use the same version of the jar file and the C headers. The instructions below are what I used to install 3.2 (after dealing with dependencies by running the configure script and installing the next missing dependency until it succeeded):

Install antlr3 from the repos and grab and extract the C header sources:

sudo apt-get install antlr3
wget http://antlr.org/download/C/libantlr3c-3.2.tar.gz
tar xvfz libantlr3c-3.2.tar.gz

Grab my modified antlr3config.h, or modify the faulty one generated by ./configure to suit your system:

wget http://blog.zortrium.net/files/sheeva-antlr3config.h
mv sheeva-antlr3config.h libantlr3c-3.2/antlr3config.h

Now we manually compile and build a static library file. If your antlr3config.h is right and you have all the dependencies, the compilation should go off without a hitch.

cd libantlr3c-3.2/src
gcc -c -O2 -I.. -I../include *.c
ar cru libantlr3c.a *.o
ranlib libantlr3c.a

Now install the header files and library file into /usr/local:

sudo cp libantlr3c.a /usr/local/lib/
sudo cp ../antlr3config.h /usr/local/include/
sudo cp ../include/*.h /usr/local/include/

Now we have to fix the system-installed antlr to use the right jarfile:

wget http://www.antlr.org/download/antlr-3.2.jar
sudo mv antlr-3.2.jar /usr/share/java/
sudo vi /usr/bin/antlr

At the last step, just change the classpath line in /usr/bin/antlr (which is just a text file) to point to the new jarfile -- for instance, I changed mine to

export CLASSPATH=/usr/share/java/stringtemplate.jar:/usr/share/java/antlr-3.2.jar

Finally, after all of this, you're back in sync with the Ubuntu instructions and can proceed from the 'Configure and build forked-daapd' section. Forked-daapd itself has a bunch of other dependencies I had to install, but all were easily installed from the Debian repositories. The only snag I ran into was that the Lenny version of avahi-daemon is too old for forked-daapd -- this was one of the factors that prompted me to upgrade my plug to Squeeze, at which point I didn't have any other issues. Forked-daapd is now running great on my plug and streaming movies to my Mac clients over Front Row.

Filed under: Plug Computers 3 Comments