Current Cost Electricity Monitor

From SifWiki

Jump to: navigation, search

Contents

Introduction

After getting fed up of waiting for the "Eco Eye" device I bought late last year to release a USB cable for hooking up to my Linux box, I gave up and bought a Current Cost. The Current Cost was up and running in 20 minutes and is a much nicer device than the Eco Eye.

This is how to interface to the device with Python and store the data in a MySQL or RRDTool database and also how to graph the data with either RRDTool or Munin.

Grab The Electricity Data

Dead simple this bit, Python is lovely and lightweight for doing work with the serial port, whether that be via the Prolific chipset USB <-> Serial adapters or whether it's from a traditional Serial port it makes no difference. This chunk of code will loop round pulling off a reading every 6 seconds then average out the values and spit them out to a temporary file in the /tmp directory.

I chose this method because it means I can easily add in a statement to dump the 6 second reading to a local MySQL database and still keep averaged readings handy for munin to graph for me. I could have hit the database again and used that to do the averaging, but this seems to be less cpu intensive and the more finer grained level of detail will always be available in the MySQL DB, should I need it.

The data from the Current Cost is spat out in an XML format, which is trivial to parse with minidom - we're ignoring the historical data which is spat out every couple of hours as this code will be logging just an average value every 5 minutes. The try/catch statement in the Python ignores any readings it gets which don't conform to the standard format.

We just log an average every 5 minutes because our munin task only runs every 5 minutes, there's no point using just the current value at the time munin runs as we'll have a skewed picture of usage. You can change the value in the loop to suit the period your munin task runs (Mine runs every 5 minutes, and I think it's 5 minutes in standard installs, but YMMV).

#!/usr/bin/env python
import serial
import os
import xml.dom.minidom

ser = serial.Serial( port='/dev/ttyUSB0', baudrate=57600, bytesize=8, parity='N',
        stopbits=1, timeout=2, xonxoff=0, rtscts=0, interCharTimeout=1 )
try:
  conn = MySQLdb.connect (host = "localhost", user = "insertuser", passwd = "insertuser", db = "homeautomation") # amend to suit your db credentials
  cursor = conn.cursor ()
except MySQLdb.Error, e:
  print "Error %d: %s" % (e.args[0], e.args[1])
  sys.exit (1)

x = 0 ; readings = [] # setup the list and initialise the loop

while 1:
        while(x < 50): # change the value here to adjust the averaging
         line = ser.readline().strip()
         if line != :
                 try:
                        doc = xml.dom.minidom.parseString(line)
                        watts = doc.getElementsByTagName("watts")[0].firstChild.data
                        readings.append(int(watts))
                        cursor.execute ("INSERT INTO electricity (reading) VALUES (%s);" % int(watts)) # amend to suit your db structure
                        x+=1
                 except Exception:
                        pass
        else:
                averagedReading = sum(readings)/ len(readings)
                os.system("echo \"%s\" > /tmp/current_cost" % averagedReading)
                x = 0 ; readings = []

Graph With Munin

Munin is awesome for graphing this kind of data, such a lovely extensible little tool which lets you write plugins in seconds, this one is probably as simple as it's possible to write...

#!/bin/bash
case $1 in
   config)
        cat <<'EOM'
graph_title Electricity Usage
graph_vlabel Electricity watt/kW
graph_category sensors
graph_info Average usage over a minute from the Current Cost device
power.label watts
power.draw AREA
EOM
        exit 0;;
esac

echo power.value `cat /tmp/current_cost`

Drop that into /usr/share/munin/plugins/current_cost and then `ln -s /usr/share/munin/plugins/current_cost /etc/munin/plugins/current_cost`, pop a `/etc/init.d/munin-node restart` and you're golden.

Links