Monitoring Your Power Usage

I was lucky enough to attend LUG Radio and Ogg Camp recently and was inspired by a talk given by Andy Standford-Clark and his house that twitters. I had been sent a power monitor after switching power supplier, but never done much with it. Watching Andy’s energetic performance inspired my to dig it out and have a go at getting the data off it. Also the thought of adding twitter to anything was too strong to resist.

My unit is a branded version of Classic Current Cost unit with a standard transmitter. The first hurdle was to get the transmitter and the monitor talking again. The monitor has three buttons at the base, pressing and holding the middle button syncs the unit to the transmitter. It is possible to associate more than one transmitter to the monitor, the Classic model I believe can talk to 3 transmitters.

Next issue was connecting it to a PC, the unit didn’t come with a data cable. The output from the monitor is slow trickle of XML over a RJ45 serial connector. I found a suitable cable on eBay from Current Cost RJ45 to USB. They so sell the same cables on Amazon but on eBay the postage is free.

Connecting the cable is simple. To get access the feed is slightly more complex but luckily there are some great articles on the web. Connecting under Linux is fairly straight forward, there is fantastic article at http://www.linuxuk.org/2008/12/currentcost-and-ubuntu/. This explains how make the USB device available to read from as a device. Next you can use a Perl script from http://www.jibble.org/currentcost/ or read on for the Python I wrote to interpret the XML. I used the python-serial package from Karmic Koala Ubuntu.

#!/usr/bin/env python

import serial
from lxml import etree

# open the device, 2400 is baud rate
ser = serial.Serial('/dev/ttyUSB0', 2400, timeout=1)

while (True):
    reading = ser.readline()
    if reading:
        try:
            # use lxml to extract what we care about
            xml = etree.fromstring(reading)
            print xml.xpath('/msg/ch1/watts')[0].text
            print xml.xpath('/msg/tmpr')[0].text
        except:
            pass

This will print the watts and the temperature as the data is sent from the monitor via the serial cable.

Without any processing the input from the monitor looks like (replace the hrr with hr – I was losing the fight with html tags…):



    
        00002
        205102
    
    CC02037771
    01429
    00000
    00000
    18.2


For some more detailed information check out: http://mungbean.org/blog/?p=477 and also http://knolleary.net/2008/05/05/power-graphing/ for some tips on graphing.

To finish off below is a script to log the data into a sqlite database:

#!/usr/bin/env python

import serial
import twitter
import sqlite3

from sqlalchemy import *
from sqlalchemy.orm import sessionmaker, mapper

from datetime import datetime
from lxml import etree
from lxml.etree import XMLSyntaxError
ser = serial.Serial('/dev/ttyUSB0', 2400, timeout=1)

while (True):
    reading = ser.readline()
    if reading:
        try:
            xml = etree.fromstring(reading)
            watts = xml.xpath('/msg/ch1/watts')[0].text
            temp = xml.xpath('/msg/tmpr')[0].text
            now = datetime.now()
            time = now.strftime("%Y%m%d%H%M%S")

            metadata = MetaData()
            engine = create_engine('sqlite:////home/yourusername/Desktop/power.db')
            metadata.bind = engine
            Session = sessionmaker(bind=engine, autoflush=True)
            session = Session()
            session.autocommit = False

            # create a class to map to
            class Power(object): pass
            table = Table('power', metadata, autoload=True)
            mapper(Power, table)

            entry = Power()
            entry.datetime = time
            entry.watts = watts
            entry.temperature = temp
            session.add(entry)
            session.commit()
            
            break
        except XMLSyntaxError:
            pass