Monitoring Home Electricity Consumption with a Raspberry Pi – part 2

1. What you need

  • A Raspberry Pi
  • A Current Cost Meter
  • A RJ45 to USB converter cable

2. Setting Up the Raspberry Pi

Install the latest version of the Rasbian image onto a suitable SD card, insert into the Pi, connect to a network and boot-up.

If you need help follow the instructions here at the Raspberry Pi website.

3. Get the necessary software packages

With the Pi connected to a network with Internet access run the following commands (some may take a while and you may have to confirm with a “yes”):

sudo apt-get update
sudo apt-get upgrade
sudo apt-get install lighttpd rrdtool
sudo apt-get install python3-dev python3-numpy

This installs all of the necessary packages we need.

4. Download and Install PySerial

PySerial is used to communicate with Serial Ports (here a USB port) and handle receiving the data from the Current Cost Display.

To download PySerial do the following (as the user pi , with a home directory of /home/pi)

cd ~ ; mkdir pyserial
cd pyserial

On the Pi start a graphical display (startx) open the Midori Browser and navigate to https://pypi.python.org/pypi/pyserial 

Download the latest version of PySerial (was 2.6 in May 2013) and save it into the pyserial directory you created earlier.

Either at the command prompt, or in a Terminal Window:

cd ~
cd pyserial
tar -xvpf./pyserial-2.6.tar.gz  # check the file name is correct
cd pyserial2.6                  # dir name = version downloaded
sudo python setup.py install    # this installs pyserial

5. Add the user Pi to the dialout group

To be authorized to use the USB port the user Pi has to be a member of the Linux group called “dialout” to make this so, enter:

sudo usermod -a -G dialout pi

6. Download the web-site files, lighttpd config files, RRD and Python scripts.

Go to the following URL on GitHub  https://github.com/naylogj/powermon.git and download the powermon.tar file and save in the home directory of the user Pi (i.e. in /home/pi).

tar -xvpf./powermon.tar

This will unpack several subdirectories.

7. Setting up the webserver/website
The next step is to install the web site files in /var/www and setup the lighttpd configuration.
At this point think of a user id (not Pi !) and password for accessing the website.
Edit the light.user file, and copy the config files.

cd /home/Pi/currentcost/lighthttpd
nano light.user         # edit the file (see below)** and save.
sudo cp light.user /etc/lighttpd/light.user
sudo cp lighttpd.conf /etc/lighttpd/lighttpd.conf

**Replace user:password with your-user-id:your-password and save it again.

Install the web site files by:

sudo chown -R pi /var/www
sudo chgrp -R www-data /var/www
sudo usermod -G www-data pi
cp -rp /home/pi/currentcost/www/* /var/www
cd /var
sudo chgrp -R www-data ./www
sudo chmod -R 760 ./www
cd ~
sudo /etc/init.d/lighttpd restart

The last command will restart the webserver.
If you open a web browswer and point it at the IP address of your Raspberry Pi (e.g. http://192.168.x.y) then the front page of the web-site should appear. If you click on a link, you should get challanged to enter the user id and password you specified above.

8. Creating the RRD store

This is the file that stores all of the data recieved from the Current Cost Meter.  To create this do:

cd /home/pi/currentcost/setup
./rrdcreate.sh

9. Installing the Powermon service and crontab entries

To install the powermon service (which automatically starts the data collection python script at bootup) do the following:

cd /home/pi/currentcost/init
sudo cp powermon /etc/init.d/powermon
sudo update-rc.d powermon defaults

To install the automatic (cron) jobs to update the graphs do the following:

cd /home/pi/currentcost/setup
crontab -e       # go to the bottom of the
# comments and read in (CTRL+R in nano)
# the pi_crontab file
# save the file (accept the offered file name)
# check this has worked by running
crontab -l

10. Start the data collection service get_data_rrd.py
To start the data collection service issue the following command:

sudo /etc/init.d/powermon start

You should now be collecting data .. wait 10 minutes and check your website.

Advertisements
This entry was posted in Energy, hacking, Raspberry PI, tinkering. Bookmark the permalink.

16 Responses to Monitoring Home Electricity Consumption with a Raspberry Pi – part 2

  1. Paul says:

    Oddly enough, on my RPi, the following was needed to get the webpage to work:
    sudo chmod 0755 -R /var/www
    sudo chmod g+s -R /var/www

  2. Paul says:

    Also,
    the lighttpd.conf section below should match the user chosen in the light.user file:

    auth.require = ( “/pc” =>
    (
    “method” => “basic”,
    “realm” => “secured”,
    “require” => “user=mychosenusername”
    )

  3. Andy White says:

    Glad to see someone else got use of vbusdecode , it seems to be a small world of people doing this kinda thing …

    I like the re-use of the nook, am tempted to try find one now and try it out.

  4. Richard says:

    Thank you for this great blog. It works for me but at seemingly random intervals it “crashes” with :

    Traceback (most recent call last):
    File “/home/pi/currentcost/bin/get_data_rrd.py”, line 56, in
    xmlTagTemp = dom.getElementsByTagName(‘tmpr’)[0].toxml()
    IndexError: list index out of range

    I assume its not receiving data and so fails but do you have any ideas how I could prevent this?

    • Gaz99 says:

      Hi Richard,

      yes, you are correct. This happens when no temperature data is found. I have learnt a lot more Python since I wrote this, it can be improved by including the code in a try except loop.

      # get the temperature
      try:
      xmlTagTemp = dom.getElementsByTagName('tmpr')[0].toxml()
      xmlDataTemp = xmlTagTemp.replace('','').replace('','')
      except:
      xmlDataTemp = "0"

      if DEBUG: print "Temperature = " + xmlDataTemp + "\n";

      So basically if the xml parse errors xmlDataTemp will be set to “0”
      Don’t forget to get the indentation correct for the changed block of code. Let me know if this fixes the issue for you and I will update the code on GitHub.
      thanks
      Gareth

      • Gaz99 says:

        sigh…. WordPress is not showing the correct indentation. All of the 3 above lines of code that start “xml…” should be indented compared to the try / except construct.

  5. Richard says:

    Thanks Gareth! I’ve added the code you suggested – will let you know how it goes but at moment, looks okay.

    Richard

  6. david says:

    guys i’m stuck. website working..tick. Everything installed without a problem. All connected up. I just don’t seem to be able to get any data to appear on the charts. They just flat line. The box is working as a standalone monitor but seems either the data isn’t get to the pi via the cable or its something else. Serial port recognises a connected device through USB. So I’m stuck. All help is appreciated. I’ve even amended the temperature code as suggested above but nothing.

    • Paul says:

      Hi David,

      When I first got my unit running, I used the DEBUG flag to check comms.
      On my unit a baud rate of 57600 is required.
      So, in get_data_rrd.py, for my unit:
      # baudrate for envir = 57600, not 9600
      ser = serial.Serial(port=’/dev/ttyUSB0′,
      baudrate=57600,
      bytesize=serial.EIGHTBITS,
      parity=serial.PARITY_NONE,
      stopbits=serial.STOPBITS_ONE,
      timeout=3)
      #
      while 1:
      line = ser.readline()
      if DEBUG: print(line); # << this should print the output from the currentcost if comms are working
      if line:
      try:
      dom = parseString(line)
      except:
      continue # if we get a corrupted XML line then ignore and continue (wait for next one)
      #
      #etc

      Paul

      • Paul says:

        PS. make sure you get the indentation correct – WordPress ate all my indentation in my reply 🙂

  7. david says:

    making some progress. Didn’t think of running the debug, doh. I’m somewhat of a noobie. From the data below is appears all is working communication wise as the data is being received. Perhaps the syntax error below is stopping the data being written to the data file? Any ideas what that means at the end?

    00003141010CC020007711.0600552000000000021.6002.5002.0002.9000.8000.5000.5000.5001.2000.6001.0002.2001.3001.100120009000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000

    Temperature = 21.6

    Power = 00000

    sh: 1: Syntax error: end of file unexpected
    /usr/bin/rrdtool update /home/pi/currentcost/data/powertemp.rrd N:00000:21.6

    • david says:

      Fixed! Clearly id messed up the get_data_rrd.or file. Copied and pasted it from GIT. Changed ch1 to ch2 and reboot. Sorted, thanks for the debug clue.

  8. Paul says:

    Firstly, I have commented out all code relating to temperature as my unit appears to not supply it, yours might be different:
    # get the temperature

    # -> tmpr failing sometimes, so we dont bother reading it
    #xmlTagTemp = dom.getElementsByTagName(‘tmpr’)[0].toxml()
    #xmlDataTemp = xmlTagTemp.replace(”,”).replace(”,”)

    # -> set temperature value to 0 string so rrdtool still gets a value
    xmlDataTemp = ‘0’ # this may be relevant to later use in cmdstring…
    #if DEBUG: print “Temperature = ” + xmlDataTemp + “\n”;

    As yours seems to show a tmpr value, I’d leave that alone for now.

    Secondly, your debug indicates a 0 value for power, which brings me to the next change I had to make in get_data_rrd.py:

    # get channel 2 and then the watts
    # you may need to change the occurrences of “ch2” to “ch1″ for your display.

    # In my case ‘ch1’ is required:
    xmlTagWatts = dom.getElementsByTagName(‘ch1’)[0].toxml()
    xmlDataWatts = xmlTagWatts.replace(”,”).replace(”,”)
    if DEBUG: print “Power = ” + xmlDataWatts + “\n”;

    Lastly, your error message indicates the string being passed to rrdtool is not being terminated properly.
    I would suggest replacing the value of xmlDataTemp before setting the cmdstring as a test:

    xmlDataTemp = ‘0’

    # Now update the RRD file with the parameters in the order Power then temperature
    cmdstring = ‘/usr/bin/rrdtool update ‘ + RRD + ‘ N:’ + xmlDataWatts + “:” + xmlDataTemp
    os.system(cmdstring)
    if DEBUG: print cmdstring;

  9. Paul says:

    PS: I see WordPress ate my angle brackets and ch1 values in the xmlDataWatts replace functions.
    Suffice to say, where the original github code had ‘ch2’, I had to replace this with ‘ch1’

  10. David says:

    It works, thanks all for your help.

  11. Gaz99 says:

    Hi guys, sorry for not responding sooner, I have been away. Thanks for helping each other out. @David glad it is all working for you now, @Paul thanks. I just added another post about something else I have been doing. Hope you like it. Gaz99

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s