Publishing CurrentCost data to the world

Posted by james on March 28th, 2009

A while ago, I started hacking around with a CurrentCost real-time energy monitor. This is a very nice little device that measures your electricity use, but more importantly has a serial output on the bottom so you can get data out of it.

Well, eventually I decided that while being able to get data off the meter was nice, it would be better if I could publish it somewhere. So, I wrote a program in Ruby to do exactly that. It reads data from the meter, and sticks it on the web. I'll go into a bit more detail in a minute, but first, you can download it (and get the source code) from github.

The program operates as a system daemon, which runs in the background on your Linux box (Mac should work as well) and uploads to various places. Adding new publishers is dead easy, so if you want to publish your data somewhere else, you can easily add it.

The Carbon Diet

First up, my own site, The Carbon Diet. This uploads your daily usage history from the meter into your carbon diet account so that you don't have to take so many meter readings to get an accurate graph. This is still pretty experimental and needs more work, but it's pretty useful already. You can see how it looks on my profile.

AMEE

Next, what I think of as the important one. AMEE, if you're not aware, AMEE is a neutral aggregation platform for sharing energy data and carbon calculations (disclaimer: I work for them these days). Think OpenID for your energy identity. Anyway, we have a nice "smart meter" demo which uses my currentcost app as the data source. Every minute, it uploads into an AMEE profile, and then another app makes a nice graph of the CO2 produced. In theory, the Carbon Diet could pull that data from AMEE instead of me publishing it directly, but that's still to come.

Pachube

Another energy data sharing service is Pachube (pronounced "patch bay"). As far as I can tell, this is more geared at art and design than rigorous data, but it's fun to play with. They've done a bunch of stuff with the CurrentCost, and now my app joins the throng. My pachube feed updates every 6 seconds - every time the meter sends data out.

Twitter

Finally, what would be the point of a web energy publisher if it couldn't tweet? If you really want to, you can see my minute-by-minute energy usage on Twitter by visiting @james_energy.

Running Mephisto on Ruby 1.8.7

Posted by james on November 4th, 2008

My server runs Ubuntu, and seeing as 8.10 (Intrepid Ibex) is out, I thought "woo, let's upgrade". Bad idea. Well, partly. Most of the upgrade went fine, but there was one problem. Intrepid comes with Ruby 1,8.7, which works fine with Rails >=2.1, but doesn't work with anything lower. Mephisto, on the other hand, doesn't work with Rails 2.1 yet, and is only usable with Rails <=2.0.2. So, you get an error starting Mephisto that looks like this:

So, I was faced with having to downgrade to Ruby 1.8.6 (a royal pain as Intrepid doesn't provide packages for it), or "fix" Mephisto to work with 2.1 (oh my god, don't even get me started). Fortunately, another solution presented itself.

I came across this blog post which describes the problem I was having. The gist (it's in Spanish) is that the main problem with Rails 2.0.2 and Ruby 1.8.7 is that Ruby 1.8.7 has added a String#chars function to the core language. Rails also adds this function, but the two have different return types, hence causing much breakage. The solution? Remove Ruby's String#chars and let Rails do its thing. Add this code to an initializer in your Rails 2.0.2 app, and it will work (better, at least) with Ruby 1.8.7.

begin
  String.class_eval { remove_method :chars }
rescue NameError
end

As you can tell by the fact that you're reading this blog, it works a treat. Hurrah!

EDIT: Another solution, which I only just worked out, would be to install the very badly-named Ruby Enterprise Edition, which sits alongside the system's Ruby and is call-compatible with 1.8.6. This makes a lot of sense if you're using passenger (mod_rails), as well.

Mocking Kernel#require

Posted by james on August 31st, 2008

The other day, I remembered to add coverage analysis to my AMEE-Ruby tests, using rcov. The results were pretty good - most of the code was already tested, except a few failure cases, and I quickly wrote some new tests to make sure those were working properly. One little bit of code stood out though. Because AMEE talks XML and JSON, my gem can use JSON, but only if the JSON gem is available on the system (XML support is built into core Ruby). Problem is, require calls throw errors if they fail, so I had to write some code to handle the load failure and carry on regardless. This is the code inside amee.rb:

begin
  require 'json'
rescue LoadError
  nil
end

Problem with this is that the gem is installed on my system, so the require never fails, and the rescue is never used. Rcov notices, and I can't get to 100% coverage, which is annoying.

So, mocking to the rescue. We have to make Kernel#rescue throw an error if we try to require 'json', even if the gem is installed. At first, I tried to use flexmock to do this, but couldn't make it work - if anyone knows how, please tell me. My final approach was to monkeypatch Kernel#require inside my test so that require 'json' (and only json) would fail:

it "should cope if json gem isn't available" do
  # Monkeypatch Kernel#require to make sure that require 'json'
  # raises a LoadError
  module Kernel
    def require_with_mock(string)
      raise LoadError.new if string == 'json' 
      require_without_mock(string)
    end
    alias_method :require_without_mock, :require 
    alias_method :require, :require_with_mock
  end
  # Remove amee.rb from required file list so we can load it again
  $".delete_if{|x| x.include? 'amee.rb'}
  # Require file - require 'json' should throw a LoadError,
  # but we should cope with it OK.
  lambda {
    require 'amee'
  }.should_not raise_error
end

We have to make a new require function, then use alias_method to rename the old one and install our new one in it's place. Rails includes alias_method_chain to make this easier, but that's not available in pure Ruby. Never mind. Once we've done the monkeypatch, we take amee.rb out of the $" array, which lists all the currently-required files, to make sure we can require it again, then simply run the require and make sure it catches the error that is thrown by our patched require. And the most satisfying part? The rescue is executed, the test works, and we get to 100% coverage. I've got a nice warm fuzzy feeling inside... mmmmmm.

CurrentCost data live on Pachube

Posted by james on August 29th, 2008

So, the other day I got a nice little tray icon working for my CurrentCost power monitor. That's great, but data is only really gets fun when it's mashable, so the next step was to get it online somehow.

Pachube is a site which aggregates data feeds from real-world (and virtual-world) devices, shows them on a map, makes graphs, things like that, so it seemed like a good first attempt at putting my power data online. My first thought was to get my app to post data at regular intervals to the service, but unfortunately Pachube doesn't work like that. Instead, it acts more like a news reader, not a publishing platform - Google Reader instead of Blogger, if that makes sense. So, I had to publish my feed live on the web and point Pachube at the URL.

First step: EEML. This is an XML-based format which Pachube reads which can contain not only multiple data feeds, but tags and other metadata. So (as seems to be the fashion), I wrapped it up in a Ruby gem, available from GitHub as ever. The gem simply provides utility classes to build an EEML feed and convert it to the XML-based format for delivery over the web.

Then, the final step was to publish the data on the web. For that, we need a web server. However, having a full web server for just one feed seemed overkill, and I didn't want to publish to yet another intermediate server, so we need to serve the data directly. Ruby to the rescue once again. WEBrick is a simple web server which is part of the core Ruby libraries. You create a server, write simple servlet classes, and mount them at particular locations. For instance:

# Create WEBrick server
s = WEBrick::HTTPServer.new( :Port => 50000 )
# A simple "hello world" servlet 
class HelloServlet < WEBrick::HTTPServlet::AbstractServlet
  def do_GET(request, response)
    response.status = 200
    response['Content-Type'] = "text/xml"
    response.body = "hello world"
  end
end
s.mount("/", HelloServlet)

Now, http://localhost:50000/ will say "hello world". From here it's a simple modification to publish the EEML feed. EEML-Ruby includes a simple EEML server script as an example. So, after building this into the tray app, now whenever my CurrentCost is connected and the app is running, it serves up EEML data to the web. You can see the data feed (fairly intermittent, as obviously the meter isn't always connected to my PC at the moment) live on Pachube.

Some successful CurrentCost hacking

Posted by james on August 22nd, 2008

After a bit of work, I've finally got my CurrentCost meter working in Ruby, and I now have a power monitor sitting in my system tray! There were a few stages involved...

Serial comms: The ruby-serialport library that already existed for Ruby was no good to me. Firstly, it didn't seem to be in a working state, but more importantly, the license it is under (GPL) is no good to me. So, I had to write my own. I've created a nice simple serial library (including a gem) for Ruby called RB232, which is available on GitHub. It only supports reading at the moment, and only works on Linux systems, but it's a start. Next!

Reading CurrentCost data: Once RB232 was in place, this was pretty easy. Just create a couple of classes to wrap up the process of getting data from the meter, and away you go. Easy. Also released as a Ruby gem on Github.

User interface: Last step was to make a simple user interface for the meter, which you can see in the picture above. It's a simple tray icon that changes colour based on power usage. It's based heavily on another very useful tool called cctrayrb, so many thanks to Daniel Parnell for doing the heavy GUI lifting there. The app is included as part of the currentcost-ruby gem mentioned above.

Anyway, it's all freely available, so if you have a CurrentCost meter and a serial cable for it, you can grab the code and get going. Enjoy :)