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
20 51 02
CC02 03777 1
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