Extracting Measurement Data

Hi all,

I am currently working on a little experiment with the Flukso. As a prerequisite I need to store the energy consumption of my household in a database. I have enabled SSH on the Flukso WLAN interface as described here:

http://vanheusden.com/misc/blog/2009-10-11-flukso.php

I also use rsyslog on another machine to log the flukso lines in a FIFO file. Now, based on an email conversation with Bart, I have these pulse lines coming in:

Nov 11 12:58:10 192.168.1.101 flukso: received pulse from /dev/ttyS0: 0e0bb5a7cc5e4d1f127d81a1c1837c83:0000024739

Each pulse line signals that a Watt-hour has been consumed. Now, I want to wait for at least 5 Minutes and integrate the pulses during this interval. Here is what I do:

(1) Wait for pulse line. Set start time once one is received. Count the pulse. The end time for this interval is set to the start time plus five minutes.
(2) When the next pulse is received, I count it and compare the current time with the end time. If the end time has been reached, go to (3), otherwise (2).
(3) Now, finalize the measurement. The average power in Watts is computed as follows:

watts=#pulses / (5min*60 / 3600)

I do, however, suspect a mistake here, but I can't grasp it. The values I get out of this are close to the values shown at the Flukso website. But especially for low power consumption the values are a little bit off.

Can anyone spot my problem?

Thanks,
-Mathias

PS: First post ever!

icarus75's picture

Hi Mathias,

The lower the power consumption, the higher the time in between Wh pulses will be. For example: 100W = 100Wh/3600s = 1Wh/36s. So if your house is consuming 100 watts, the Wh pulses will arrive at 36 second intervals. The time interval thus cannot be trusted to be close to 5min. So I would alter your formula to count average power like this:

watts = #Wh_pulses*3600/(T3-T1)

T1 = start time (s)
T3 = end time (s)

HTH
Bart.

gonium's picture

Hi Bart,

thanks for the quick response. I think my problem description was not exact enough - I use the formula you have described above. Let me post some code to make my setup clear.

I have a script that parses the lines of the rsyslog daemon. The relevant part looks like this:

  1. puts "Will integrate readings over #{measurementInterval} minutes" if $verbose
  2. pulseIntegrator=PulseIntegrator.new(measurementInterval);
  3. # code to open named pipe etc. removed
  4. if /\w\s(\d+:\d+:\d+).*flukso.*pulse.*:(\d+)$/ =~ line
  5.   puts line if $verbose
  6.   watthours=$2.to_f
  7.   pulseIntegrator.addPulse();
  8.   if (pulseIntegrator.isElapsed?())
  9.     fluksoReading=pulseIntegrator.getFluksoReading();
  10.     pulseIntegrator.reset();
  11.     puts "FluksoReading: #{fluksoReading}" if $verbose
  12.     db.storeReading(fluksoReading);
  13.   end
  14. end

I removed some of my diagnostic code for brevity. As you can see, each time that I receive a pulse message, I add it to an PulseIntegrator instance (see below). If the Integrator is elapsed, I evaluate the recorded pulses:

  1. # Aggregates pulses and consolidates them
  2. class PulseIntegrator
  3.   def initialize(durationInMinutes)
  4.     @durationInMinutes=durationInMinutes;
  5.     reset();
  6.   end
  7.   def addPulse()
  8.     if (@firstSampleTime == nil)
  9.       @firstSampleTime=Time.now
  10.     end
  11.     @lastSampleTime=Time.now
  12.     @pulses+=1;
  13.   end
  14.   def getPulses()
  15.     return @pulses
  16.   end
  17.   def isElapsed?
  18.     return Time.now > @endTime
  19.   end
  20.   def getFluksoReading()
  21.     # seconds betweeen this and the last timestamp
  22.     interval=@lastSampleTime - @firstSampleTime;
  23.     puts "Interval is #{interval}";
  24.     watts=(@pulses.to_f/(interval/3600))
  25.     return FluksoReading.new(watts, @lastSampleTime, interval);
  26.   end
  27.   def reset
  28.     @startTime=Time.now;
  29.     @endTime=@startTime + (@durationInMinutes * 60)
  30.     @pulses=0;
  31.     @firstSampleTime=nil; #@startTime; # was: nil
  32.     @lastSampleTime=nil;
  33.   end
  34.   def to_s
  35.     return "Start=#{@startTime}, End=#{@endTime}, Pulses={#{@pulses}}"
  36.   end
  37. end

As you can see I use timestamps on the local machine to evaluate the pulses. Using this code I have recorded the following readings:

  1. Thu Nov 12 14:56:28 +0100 2009 - 28.4429450915661 W (379.707515 s)
  2. Thu Nov 12 14:48:01 +0100 2009 - 41.9130232351481 W (257.676473 s)
  3. Thu Nov 12 14:41:39 +0100 2009 - 27.5423658344847 W (522.830903 s)

The format is timestamp - watts (seconds of measurement interval). The website reports a relatively constant power consumption of 30 Watts. So there is a significant difference between the website values and the values I extract.

Thanks for your help,
-Mathias

EDIT: The intendation of the code tag seems to be broken :-)

icarus75's picture

Hi Mathias,

I've started with your last remark by enabling GeSHi code filtering in the forum. I've slightly edited the markup of your post by substituting 'code' by 'ruby'. It doesn't solve your problem yet, but it does make it a lot prettier. :-)

Cheers,
Bart.

icarus75's picture

For my understanding: If I calculate the interval time between your log entries, I get 382s (2-3) and 507s (1-2). These intervals don't seem to remotely match your interval calculations: 257s and 379s respectively. Am I overlooking something?

yschaeff's picture

A quick view of your code made me wonder:

why do you keep track of the time of the first and the last pulse? What I think you want to do is count the pulses from start of measurement to the end of it.

you now 'forget' to 'count' some time before and after the first and last pulse. Especially for short intervals this would give a large error (accidentally your error is always positive). This is in line with Icarus' observations.

gonium's picture

Hi,

I think you're right. I need to revisit that code, thank you for your comments! I was busy working on other sides of the project, which is now up and running in a first version. You can see it here:

http://twitter.com/fluksobot

I try to write more about the motivation behind the twitter bot later today.

Cheers,
-Mathias

icarus75's picture

Hi Mathias,

Is this some shrewd plan of yours to force us to look at your panoramic photography(cc)? :-P

Great stuff!!
Bart.

gonium's picture

Damn, my plan is screwed :-) Now, I need to create a new plan for world dominance...

-Mathias