Monitoring the household energy usage with a Raspberry Pi, Current Cost ENVI (Model:CC128) Home Energy Monitor, LedBorg from PiBorg and controlled with Python.
The Harware
- Raspberry Pi
- Current Cost ENVI (Model:CC128) Home Energy Monitor
- Current Cost (USB) Data Cable
- LedBorg from PiBorg
Connecting the CC128 to the Pi – The Data Cable used to connect the CC128 to the Pi uses the Prolific PL2303 chip to connect a serial device (the CC128) via USB. The RJ45 connector goes into the back of the CC128 and the USB connector to the Pi. I had to use a short USB extender cable as the connector on the Data Cable was too large to fit with another USB device connected but using a powered USB hub would also have got round this small issue.
Establishing serial connection – The drivers for the Prolific PL2303 chip are part of the standard Raspbian “wheezy” distribution (I’m using 2012-12-16-wheezy-raspbian release) so the device was ready to use. To communicate with a serial device using Python first we need to install a serial library. This is easily done with a single command from the terminal:
sudo apt-get install python-serial
Now we can set up a serial connection and read data using a few lines of Python:
import serial
cc128 = serial.Serial("/dev/ttyUSB0", 57600, timeout=6)
cc128xml = cc128.readlines(6)
print cc128xml
The first line tells Python that we want the functions of the serial library to be available.
Line two will set up cc128 as an active connection to the device which maps to /dev/ttyUSB0 (this is the device name given to the USB serial device on my Pi) with a Baud rate of 57600 and a timeout of 6 seconds.
The third line performs the function readlines and puts the data in cc128xml.
Finally we print the data that is returned which looks like:
<msg><src>CC128-v0.12</src><dsb>00861</dsb><time>00:21:43</time><tmpr>20.3</tmpr><sensor>0</sensor><id>00077</id><type>1</type><ch1><watts>00341</watts></ch1></msg>
Parse the data – The data returned is as an XML string so we can use simple text searching to get the information we are interested in. The CC128 will return data roughly every 7 seconds and includes the current temperature and more importantly the current energy usage in watts. To find the required data we can search the returned text string for the relevant tags and select the data between them. Here I am finding the temperature:
tmprstart=cc128xml[0].find("<tmpr>")+len("<tmpr>")
tmprend=cc128xml[0].find("</tmpr>",tmprstart)
tmpr=float(cc128xml[0][tmprstart:tmprend])
The same method is used to get the power usage (watts) data from the returned string but as the device supports more than one channel I am making sure I find the ‘ch1′ tags first.
Now we have this data we can perform some range checking on the current power usage figure and decide to display a different colour to indicate low (green), normal (yellow) or high (red) usage.
if watts>2000:
colour="100" # Red
else:
colour="110" # Yellow
if watts<500:
colour="010" # Green
I have chosen limits of greater than 2000 Watts as high (red), below 500 Watts as low (green) and anything between as normal (yellow) but his could be extended with a greater range of colours or to give an indication of temperature if desired.
Making it light up – The final part is to make the RGB LED on the LedBorg board show the required colour. The drivers available from the PiBorg website make the board appear as a device that you can open and write to. Setting a specific colour is done by turning on the relevant elements of the RGB LED. There are individual elements for Red, Green and Blue and one digit is used to control each. It is possible to turn each element either off (0), on at 50% (1) or fully on (2). For this project I use the string ’100′ to set red, ’110′ to set both the red and green components on to give yellow and ’010′ for green. There are further examples on the PiBorg website.
Once we have decided the colour string to use we can open the LedBorg device, write the value and close it:
LedBorg = open('/dev/ledborg', 'w') # Open LedBorg for writing
LedBorg.write(colour) # Write colour to the LedBorg
LedBorg.close() # Close the LedBorg
Making it all work – To develop the Python code I used the Raspberry Pi WebIDE from Adafruit. It is currently an alpha release but is usable and has a great Schedule Manager that allows you to have your code run automatically at a set interval. For this application I have set the interval to 5 minutes and it appears to work very well.
The complete code – read-cc128-serial.py
import serial
cc128 = serial.Serial("/dev/ttyUSB0", 57600, timeout=6)
cc128xml = cc128.readlines(6)
try:
# Find the temperature
tmprstart=cc128xml[0].find("<tmpr>")+len("<tmpr>")
tmprend=cc128xml[0].find("</tmpr>",tmprstart)
tmpr=float(cc128xml[0][tmprstart:tmprend])
# Find ch1
ch1start=cc128xml[0].find("<ch1>")+len("<ch1>")
ch1end=cc128xml[0].find("</ch1>",ch1start)
ch1=cc128xml[0][ch1start:ch1end]
# Find the power in watts
wattsstart=ch1.find("<watts>")+len("<watts>")
wattsend=ch1.find("</watts>",wattsstart)
watts=int(ch1[wattsstart:wattsend])
print "Temperature " + str(tmpr) + "C, Power " + str(watts) + "watts"
except:
print cc128xml
#colour="000" # Off/Black
else:
if watts>2000:
colour="100" # Red
else:
colour="110" # Yellow
if watts<500:
colour="010" # Green
LedBorg = open('/dev/ledborg', 'w') # Open LedBorg for writing
LedBorg.write(colour) # Write colour to the LedBorg
LedBorg.close() # Close the LedBorg




The problem turned out to be that the part of the code that does the communication was not enabled for reentrant execution. Opening the VI Properties dialogue and selecting the Execution category allows us to set Reentrant execution.