Welcome to It-Slav.Net blog
Peter Andersson
peter@it-slav.net

I've already got a female to worry about. Her name is the Enterprise.
-- Kirk, "The Corbomite Maneuver", stardate 1514.0

Background

On my electricity meter I have a flashing LED. 1000 flashes is 1 watthour.

As a monitor geek I want to know my powerconsumption and find a 1-wire kit containing a counter and a sensor that could detect the flashing from the electricity meter.

I wrote a script that collect the data in an RRD database and graph it. 

 

 

Graph

 

The script

#!/usr/bin/perl
# By Peter Andersson peter@it-slav.net
#
# This program is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#
use RRDs;
use OW;
# define location of rrdtool databases
my $rrd = '/root/owfs/script/rrd_db';
# define location of images
my $img = '/home/peter/public_html/1-wire/energy';
# process data for each interface (add/delete as required)
&ProcessSensor(0, "Anderssons power consumption", "mother.mynet" , "3001" , "1D.A4F10C000000");
sub ProcessSensor
{
# process sensor
# inputs: $_[0]: sensor number (ie, 0/1/2/etc)
#         $_[1]: sensor description
        print "number:$_[0] desc:$_[1], server:$_[2] port:$_[3], id: $_[4]\n";
        my $owserver = "$_[2]:$_[3]";
        unless(OW::init($owserver)) {
            $status = $ERRORS{CRIT};
            $message = "OWServer not running at $owserver\n";
            exit $status;
        }
        # get temperature from sensor
        my $handle = OW::get("$_[4]/counters.A");
#       print "handle=$handle\n";
        $handle =~ s/^\s*(.*?)\s*$/$1/;
        ## Check if input is an integer or decimal
        unless (($handle =~ /^-?(?:\d+(?:\.\d*)?|\.\d+)$/) || ($handle =~ /^[+-]?\d+$/))
        {
                print "Not an integer or a decimal\n";
                return($ERRORS{CRITICAL});
        }
        $count=$handle;
        # remove eol chars
        chomp($count);
        print "sensor $_[0]: $count \n";
        # if rrdtool database doesn't exist, create it
        if (! -e "$rrd/energy$_[0].rrd")
        {
                print "creating rrd database for energy sensor $_[0]...\n";
                RRDs::create "$rrd/energy$_[0].rrd",
                        "-s 60",
                        "DS:energy:COUNTER:1200:0:U",
                        "RRA:AVERAGE:0.5:1:43200",
                        "RRA:AVERAGE:0.5:30:175200";
        }
        if ($ERROR = RRDs::error) { print "$0: failed to create $_[0] database file: $ERROR\n"; }
        # check for error code from count sensor
        #if (int $count eq 85)
        #{
        #        print "failed to read value from sensor $_[0]\n";
        #}
        #else
        #{
                # insert values into rrd
                RRDs::update "$rrd/energy$_[0].rrd",
                        "-t", "energy",
                        "N:$count";
                if ($ERROR = RRDs::error) { print "$0: failed to insert $_[0] data into rrd: $ERROR\n"; }
        #}
        # create graphs for current sensor
        &CreateGraph($_[0], "day", $_[1], 3600, hourly);
        &CreateGraph($_[0], "week", $_[1], 3600*24, daily);
        &CreateGraph($_[0], "month", $_[1], 3600*24*7, weekly);
        &CreateGraph($_[0], "year", $_[1], 3600*24*7*30, monthly);
        &CreateGraph($_[0], "decade", $_[1], 3600*24*7*365, yearly);
}
sub CreateGraph
{
# creates graph
# inputs: $_[0]: sensor number (ie, 0/1/2/etc)
#         $_[1]: interval (ie, day, week, month, year)
#         $_[2]: sensor description
#	  $_[3]: Moving avarage timeperiod
#	  $_[4]: Moving avarage timeperiod unit
print "Create graph $_[0], interval: $_[1], Moving avarage timeperiod: $_[3]s and moving avarage unit: $_[4]\n";
        RRDs::graph "$img/energy$_[0]-$_[1].png",
                "-s -1$_[1]",
                "-t $_[2]-$_[1]",
                "-h", "400", "-w", "1000",
                "-a", "PNG",
                "-v Watt",
                "--slope-mode",
		"-W", "WWW.It-Slave.Net - An It-Slave In The Digital Saltmine",
		"-l", "0",
                "DEF:energy=$rrd/energy$_[0].rrd:energy:AVERAGE:start=end-$_[3]s-1$_[1]",
                "CDEF:W=energy,3600,*",
		"CDEF:mean=W,$_[3],TREND",
		"AREA:mean#FF000044",
                "LINE1:mean#A00000:Moving average $_[4]:",
		"AREA:W#AAAAee99",
		"LINE1:W#AAAAEEFF:Power consumption\\n",
		"CDEF:energyK=energy,1000,/",
		"VDEF:value_sum=energyK,TOTAL",
  		"GPRINT:value_sum:Total consumption last $_[1]\\:%0.2lfkWh\\n",
  		"GPRINT:W:MIN:Instantaneous consumption\\: Min\\:%0.2lf%sW",
  		"GPRINT:W:AVERAGE:Average\\:%0.2lf%sW", 
  		"GPRINT:W:MAX:Max\\:%0.2lf%sW",
  		"GPRINT:W:LAST:Now\\:%0.2lf%sW\\n";
#		"COMMENT:\n                                            WWW.It-Slav.Net - An It-Slave In The Digital Saltmine";
        if ($ERROR = RRDs::error) { print "$0: unable to generate sensor $_[0] $_[1] graph: $ERROR\n"; }
}

 

Links


3 Responses to “Graphing powerconsumption using 1-wire”

  1. Mikael Says:

    82 kWh per day – are you running a data center?

  2. peter Says:

    Yes, a small one at home.

  3. temp master Says:

    hello ,
    i would like to monitor gas usage. 1 click is 0,1  m3.   I dont know where in script must i change that it will count right ?
    Thank you for the answer.

Leave a Reply





Book reviews
FreePBX 2.5
Powerful Telephony Solutions






Asterisk 1.6
Build a feature rich telephony system with Asterisk






Learning NAGIOS 3.0





Cacti 0.8 Network Monitoring,
Monitor your network with ease!