RaspberryPi Home Energy Monitor

Monitoring the household energy usage with a Raspberry Pi, Current Cost ENVI (Model:CC128) Home Energy Monitor, LedBorg from PiBorg and controlled with Python.
image

The Harware

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

London to Brighton Bike Ride 2011

The British Heart Foundation London to Brighton Bike Ride is an annual 54mile cycle from the Capital to the South Coast to rise funds for one of this Countries largest charities. This year the ride took place on 19th June and I joined 27,000 other cyclists for a day out in the English countryside.

Through work we managed to enter three teams of seven cyclists and arranged minibus transport to London. We were by no means an elite bunch and had a variety of ages and styles of bicycles ranging from serious road bikes with thin slick tyres and carbon fibre frames to heavy mountain bikes. I had a new hybrid bike with a light aluminium mountain bike style frame and medium road tyres so was looking forward to a reasonable ride.

Final checks to my bike before the start of 54 miles

Getting ready for the next 54 miles

We left Portsmouth at 6am heading for our 9am start time. Making good time we arrived with over half an hour to spare and after unloading the bikes and a few final checks we made our way to Clapham Common.

Before we reached the starting area I had managed to loose most of my work colleagues so decided to just get on with it and meet everyone at the end. There were after all thousands of other cyclists and one red t-shirt looks pretty much like the next.

I waited with the masses for our signal to start and at 8:50 in the morning I was on my way. Cycling out of London was slow due to the high number of cyclists, even though we had staggered start times (starting from 6am).

Some of the roads had been closed to traffic or made one way for the day with cyclists on the left side and cars travelling in the same direction but on the ‘wrong’ side. Throughout the day we had Marshals along the route and many Police who assisted keeping us safe and moving in the right direction.

There were a number of rest stops along the route to refill water bottles and grab a bite to eat. The first was just over 10mile from the start at Woodmansterne Village Hall where I stopped briefly (at 10:25) to see if I could see anybody I knew. No such luck so I rejoined the wave of cyclists travelling south.

Once out of London I started to make better progress and got to the Burstow Scouts refreshment stop which is about halfway (28 miles) at 12:00. After a quick burger I was back on my way.

Turners Hill, 19th June 2011

27,000 cyclists travel through Turners Hill

Another half hour (12:40) and I was at Turners Hill where I found one of my work colleagues. We completed the last 20miles together and it really made a difference to be cycling with somebody I had something in common with (even if it was only that we worked in the same building).

Before we had got much further we were held back by the Marshals due to an incident. Once we were released we made our way down the hill and continued until the Wivelsfield refreshment stop to prepare for Ditchling Beacon.

A nice gentle ride for the next 5 miles brought us to the part of the ride I was least looking forward too. Before you reach Ditching Beacon there is a road that climbs 500 feet which I failed twice before to cycle more than 100 meters up. This time was no different and I walked by bike nearly the entire way to the top. It was well worth the effort though as I could see for miles.

One of the best things about the uphill parts is of course the down hill parts and after a short cycle across the ridge we were on our way down towards Brighton. We passed more Marshals telling us to slow down and to mind the ambulances at the bottom of the hill. I didn’t realise until we reached them that they were actually helping a cyclist that had fallen on the downhill stage.

It was not long and we were on the roads leading into Brighton where we joined normal traffic. Having been cycling for the best part of 50 miles without the worry of heavy traffic to finally join other vehicles on the road was strange to begin with.

Completed 54 miles

Finished the 2011 BHF London to Brighton

Finally we made it through to Marina Drive and approached the finish line. At about 15:40 I had finished and was given my participants medal as I passed through to try and find the rest of my team and the mini bus home.

A really great day to raise funds for a great cause that would not have been possible without the help of the organisers, Marshals, Police, Paramedics and First Aiders along the route, thank you all.

House move 27 May 2010

Removal van

  • Removal van arrived 8:40, left 11:30
  • Call from estate agents saying we could collect keys 12:45
  • Arrived at house 13:40
  • Picked kids up from schools and got back to new house at 15:40
  • Removal van left 16:00
  • Beds up by 19:30
  • Chinese at 20:00
  • Bed 21:00

 

Everybody loves the new house, plenty of space and kids can get to sleep without the older one disturbing the younger ones. Martin went around the house looking at everything saying ‘That’s perfect!’ to everything when he first got here.
BT line installed Friday by about 11:00, called Orange and they can’t do anything about broadband until line has been active for 2 working days so said call back Tues eve. Also could take upto 10 working days to active. So I’m paying for broadband for about two weeks with no service and it’s my fault for moving house!
Using mobile broadband on the 3 network with a USB dongle. Seems reasonable but not sure how long 1Gb will last, not going to visit iPlayer for a while.

Multi threaded LabVIEW execution

Using four different RS485 serial ports to communicate with four data acquisition devices, each with four channels it should be possible to sent commands to the each device in turn while waiting for a response from the first. This will greatly reduce the time required to poll all channels. So why is it taking over 40 seconds for all channels on all ports when it takes less than 10 seconds to poll all channels on one device. LabVIEW should be able to run each port in a separate thread.
We created a VI to handle the communication with the serial device. This would construct the command string, flush the receive buffer, write the command string to the serial port and wait for the response from the DAQ device. When the require data had been received the response string is decoded and the measured value is passed to the calling VI. Using four of these VI’s wired to run in parallel, each with a different serial port set this VI worked.
Next we wanted to take ten samples from each channel of each device and run some basic statistical filtering to eliminate noise. We have our VI to take a single measurement so just putting this in a FOR loop to iterate ten times should give us the data we need. Now the communications appear to be taking too long. We are only taking ten readings from each channel and as we are running each serial port in parallel we should not be seeing the execution time increase we are. A quick check, ten readings from four channels with the communication specification stating that each channel should return within 250ms should give us around 10 seconds not the 40+ seconds we are getting.
Logging was added to the read from serial port VI using a little VI I use all the time. It allows me to log a string of data to a text file with a time stamp. Analysing this in Excel and plotting the timestamps by serial port showed some interesting results. The parallel execution was only in the layout of the block diagram, not the execution. Each serial port was accessed in turn only after all readings for that port were taken. So how did that happen?
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.
Now we are able to take all the required measurements within about 12 seconds. This just leaves the filtering of each channel. A Producer-Consumer loop architecture was chosen for this so the measurements were taken in the Producer loop which were placed on a queue. Filtering was done in the Consumer which waited for data to appear on the queue before processing it. This prevented the filtering affecting the timing of the data acquisition.

Running LabVIEW as a Windows Service

Today I finally got around to using Visual Studio to create a Windows Service that will call a LabVIEW executable every 10 minutes to log temperature to a database.

We have been running a LabVIEW application as a service using a free version of FireDemon but found today that our corporate anti virus software marks the executable as a Trojan. Getting an exception for this will take ages so after referring to google I found an article on MSDN with the title Windows Services: New Base Classes in .NET Make Writing a Windows Service Easy.

In under an hour I had created a service, installed and tested it as described in the above article.

Our application requires an up-to-date temperature to be available to a number of machines. To measure the temperature we are using a USB data acquisition device connected to a thermocouple which is polled by one PC periodically and then updates a database. We have the LabVIEW code to take the measurements and log the temperature as we were using FireDemon to run this as a service.

We have Measurement Studio which allows us to use our data acquisition devices under Visual Studio but as we have LabVIEW code already in place to do the data acquisition and updating the database I will use this for now. Rewriting in Visual Studio is a job for another day.

After a few modifications to the example code in the MSDN article I managed to get our LabVIEW code executing every 10 minutes.

Since implementing this NI have produced a network attached DAQ device which we are currently looking at for future projects.