diff -urN fhem-5.3/FHEM/00_CUL.pm fhem-5.3-mine/FHEM/00_CUL.pm
--- fhem-5.3/FHEM/00_CUL.pm	2012-10-28 19:15:27.000000000 +0100
+++ fhem-5.3-mine/FHEM/00_CUL.pm	2013-02-10 19:19:10.000000000 +0100
@@ -46,7 +46,7 @@
 
 my $clientsSlowRF = ":FS20:FHT:FHT8V:KS300:USF1000:BS:HMS: " .
                     ":CUL_EM:CUL_WS:CUL_FHTTK:CUL_RFR:CUL_HOERMANN: " .
-                    ":ESA2000:CUL_IR:CUL_TX";
+                    ":CUL_ESA:ESA2000:CUL_IR:CUL_TX";
 
 my $clientsHomeMatic = ":CUL_HM:HMS:CUL_IR:";  # OneWire emulated as HMS on a CUNO
 
@@ -64,9 +64,10 @@
     "9:CUL_FHTTK" => "^T[A-F0-9]{8}",
     "A:CUL_RFR"   => "^[0-9A-F]{4}U.",
     "B:CUL_HOERMANN"=> "^R..........",
-    "C:ESA2000"   => "^S................................\$",
-    "D:CUL_IR"    => "^I............",
-    "E:CUL_TX"    => "^TX[A-F0-9]{10}",
+    "C:CUL_ESA"   => "^S..0.............................\$",
+    "D:ESA2000"   => "^S..1.............................\$",
+    "E:CUL_IR"    => "^I............",
+    "F:CUL_TX"    => "^TX[A-F0-9]{10}",
 );
 my %matchListHomeMatic = (
     "1:CUL_HM" => "^A....................",
diff -urN fhem-5.3/FHEM/19_CUL_ESA.pm fhem-5.3-mine/FHEM/19_CUL_ESA.pm
--- fhem-5.3/FHEM/19_CUL_ESA.pm	1970-01-01 01:00:00.000000000 +0100
+++ fhem-5.3-mine/FHEM/19_CUL_ESA.pm	2013-02-10 19:18:44.000000000 +0100
@@ -0,0 +1,313 @@
+# This module is based on CUL_EM
+#
+# Modified by
+#
+#   Gerd Kehrer (booster2 AT gmx dot net)
+#   - Initial work
+#   - Decoding of the ESA messages
+#   - ESA1000WZ support
+#
+#   Andre Beckedorf (andre AT beckedorf dot net)
+#   - ESA1000Z/ESA1000GAS support
+#   - Calculation of average power
+#   - Plot config file
+
+##############################################
+package main;
+
+use strict;
+use warnings;
+
+#####################################
+sub
+CUL_ESA_Initialize($)
+{
+  my ($hash) = @_;
+
+#			 SAB0595031E000A047E0000227C460004
+#			 S1C0785011E00011CDA00020D056C004C
+#			 S6E003D011E00037650001102C1DA07D01D
+
+  $hash->{Match}     = "^S..0.............................\$";
+  $hash->{DefFn}     = "CUL_ESA_Define";
+  $hash->{UndefFn}   = "CUL_ESA_Undef";
+  $hash->{ParseFn}   = "CUL_ESA_Parse";
+  $hash->{AttrList}  = "IODev do_not_notify:0,1 showtime:0,1 ".
+                       "model:ESA1000WZ-LED,ESA1000WZ-S0,ESA1000GAS loglevel ignore:0,1";
+}
+
+#####################################
+sub
+CUL_ESA_Define($$)
+{
+  my ($hash, $def) = @_;
+  my @a = split("[ \t][ \t]*", $def);
+
+  return "wrong syntax: define <name> CUL_ESA <type> <id> ".
+                                "[corr1 corr2 CostPerUnit BasicFeePerMonth]"
+            if(int(@a) < 4 || int(@a) > 8);
+
+  $hash->{Type} = $a[2];
+  $hash->{ID} = $a[3];
+
+  if($a[2] eq hex("0595")) {
+    # ESA1000Z/ESA1000GAS (using impulse transducer for the Elster-Kromschroeder BK-G4)
+    # corr1 is the correction factor to convert the device units to m^3
+    # (usually the counter constant set in the ESA1000GAS)
+    $hash->{corr1} = (int(@a) > 4 ? $a[4] : 0.001);
+    # corr2 is the correction factor in unit kWh/m^3 to convert from m^3 to kWh
+    # (check your gas bill!)
+    $hash->{corr2} = (int(@a) > 5 ? $a[5] : 9.525);
+    # Do not use the ticks reported by the device...
+    $hash->{override_ticks} = 1;
+
+    $hash->{timestamp_diff_threshold} = 0;
+  } else {
+    $hash->{corr1} = 1;
+    $hash->{corr2} = 1;
+
+    # timestamp_diff_threshold should alleviate the effects of under-sampling that might 
+    # occur at the meter, for instance when the disc of the power meter is turning too
+    # slowly such that the time span between the impulses is too long. In this case the 
+    # unit is transmitting zero values eventhough there is still something going on.
+    # Value is in 10 sec units.
+    $hash->{timestamp_diff_threshold} = 130;
+  }
+
+  $hash->{CostPerUnit} = (int(@a) > 6 ? $a[6] : 0);
+  $hash->{BasicFeePerMonth} = (int(@a) > 7 ? $a[7] : 0);
+
+  $modules{CUL_ESA}{defptr}{$a[3]} = $hash;
+  AssignIoPort($hash);
+  return undef;
+}
+
+#####################################
+sub
+CUL_ESA_Undef($$)
+{
+  my ($hash, $name) = @_;
+  delete($modules{CUL_ESA}{defptr}{$hash->{ID}});
+  return undef;
+}
+
+#####################################
+sub
+CUL_ESA_Parse($$)
+{
+  my ($hash,$msg) = @_;
+
+  # S6E003D011E00037650001102C1DA07D01D
+  # S 6E 003D 011E 00037650 0011 02C1DA 07D0 1D
+  #              1           2           3
+  # 0 12 3456 7890 12345678 9012 345678 9012 34
+
+  my @a = split("", $msg);
+
+  # seqno        =  number of received datagram in sequence
+  # type         =  type of sensor: 003D: ESA1000WS-S0, ...
+  # id           =  ID of sensor
+  # total_cnt    =  total (cumulated) value in ticks as read from the device
+  # basis_cnt    =  correction to total (cumulated) value in ticks to account for
+  #                 counter wraparounds
+  # total        =  total (cumulated) value in device units
+  # current_cnt  =  current value (average over latest 5 minutes) in device units
+  # timestamp    =  current time from start of device in 10 sec units
+  # ticks        =  ticks per kWh setup in ESA1000WS (depends on the meter)
+
+  my $seqno = hex($a[1].$a[2]);
+  my $type = hex($a[3].$a[4].$a[5].$a[6]);
+  my $id = hex($a[7].$a[8].$a[9].$a[10]);
+  my $total_cnt = hex($a[11].$a[12].$a[13].$a[14].$a[15].$a[16].$a[17].$a[18]);
+  my $current_cnt = hex($a[19].$a[20].$a[21].$a[22]);
+  my $timestamp = hex($a[23].$a[24].$a[25].$a[26].$a[27].$a[28]);
+  my $ticks = hex($a[29].$a[30].$a[31].$a[32]);
+
+  # these are the raw readings from the device
+  my $val = sprintf("CNT: %d  CUM: %d  CUR: %d  TIME: %d",
+                         $seqno, $total_cnt, $current_cnt, $timestamp);
+
+  if($modules{CUL_ESA}{defptr}{$id}) {
+    my $def = $modules{CUL_ESA}{defptr}{$id};
+    $hash = $def;
+    my $n = $hash->{NAME};
+    return "" if(IsIgnored($n));
+    my $tn = TimeNow();                 # current time
+    my $c= 0;                           # count changes
+    my %readings;
+
+    Log GetLogLevel($n,5), "CUL_ESA $n: $val";
+    $readings{RAW} = $val;
+
+    #
+    # calculate readings
+    #
+    # initialize total_cnt_last
+    my $total_cnt_last = 0;
+    if(defined($hash->{READINGS}{total_cnt})) {
+      $total_cnt_last= $hash->{READINGS}{total_cnt}{VAL};
+    }
+
+    # initialize total_cnt_last_avg
+    my $total_cnt_last_avg = 0;
+    if(defined($hash->{READINGS}{total_cnt_last_avg})) {
+      $total_cnt_last_avg= $hash->{READINGS}{total_cnt_last_avg}{VAL};
+    }
+
+    # initialize timestamp_last
+    my $timestamp_last = 0;
+    if(defined($hash->{READINGS}{timestamp})) {
+      $timestamp_last= $hash->{READINGS}{timestamp}{VAL};
+    }   
+
+    # initialize timestamp_last_avg
+    my $timestamp_last_avg = 0;
+    if(defined($hash->{READINGS}{timestamp_last_avg})) {
+      $timestamp_last_avg= $hash->{READINGS}{timestamp_last_avg}{VAL};
+    }   
+
+    # initialize basis_cnt
+    my $basis_cnt = 0;
+    if(defined($hash->{READINGS}{basis})) {
+      $basis_cnt = $hash->{READINGS}{basis}{VAL};
+    }
+    
+    # correct counter wraparound
+    if($total_cnt < $total_cnt_last) {
+      $basis_cnt += $total_cnt_last;
+      $readings{basis} = $basis_cnt;
+
+      $timestamp_last = 0;    
+      $timestamp_last_avg = 0;
+      $total_cnt_last = 0;
+      $total_cnt_last_avg = 0;
+    }
+
+    #
+    # translate from device units to real units
+    #
+    my $corr1 = $hash->{corr1};
+    my $corr2 = $hash->{corr2};
+
+    # check whether we should override the ticks value
+    if(defined($hash->{override_ticks})) {
+      $ticks = $hash->{override_ticks};
+    }
+
+    my $total    = ($basis_cnt + $total_cnt) / $ticks * $corr1 * $corr2;
+    my $current  = $current_cnt / $ticks * $corr1 * $corr2;
+    
+    $val = sprintf("CNT: %d CUM: %0.3f  CUR: %0.3f  TIME: %d",
+                         $seqno, $total, $current, $timestamp);
+    $hash->{STATE} = $val;
+    $hash->{CHANGED}[$c++] = "$val";
+
+    $readings{total_cnt}   = $total_cnt;
+    $readings{current_cnt} = $current_cnt;
+    $readings{seqno}       = $seqno;
+    $readings{total}       = $total;
+    $readings{current}     = $current;
+    $readings{timestamp}   = $timestamp;
+    $readings{ticks}       = $ticks;
+
+    Log GetLogLevel($n,4), "CUL_ESA $n: $val";
+
+    my $timestamp_diff = $timestamp - $timestamp_last_avg;
+    my $total_cnt_diff = $total_cnt - $total_cnt_last_avg;
+
+    # Calculate average power for timestamp_diff if we got a change in the total value
+    # or if the timespan was bigger than x seconds without any change in the total value.
+    if (($timestamp_diff > 0 && $total_cnt_diff > 0) || $timestamp_diff > $hash->{timestamp_diff_threshold}) {
+      my $avg_power = ($total_cnt_diff / $ticks) / ($timestamp_diff * 10 / 3600) * $corr1 * $corr2;
+          
+      $val = sprintf("AVG: %0.3f", $avg_power);
+      $hash->{CHANGED}[$c++] = "$val";
+      Log GetLogLevel($n,4), "CUL_ESA $n: $val";
+      
+      $readings{total_cnt_last_avg} = $total_cnt;
+      $readings{timestamp_last_avg} = $timestamp;
+      $readings{avg_power} = "$avg_power (kW)";
+    }
+    
+    if ($timestamp_diff <= 0 || $total_cnt_diff <= 0) {
+      $readings{total_cnt_last_avg} = $total_cnt;
+      $readings{timestamp_last_avg} = $timestamp;   
+    }    
+
+    ###################################
+    # Start CUMULATE day and month
+    my $tsecs_prev;
+
+    #----- get previous tsecs
+    if(defined($hash->{READINGS}{tsecs})) {
+      $tsecs_prev= $hash->{READINGS}{tsecs}{VAL};
+    } else {
+      $tsecs_prev= 0; # 1970-01-01
+    }
+
+    #----- save actual tsecs
+    my $tsecs= time();  # number of non-leap seconds since January 1, 1970, UTC
+    $readings{tsecs}       = $tsecs;
+
+    #----- get cost parameter
+    my $cost = $hash->{CostPerUnit};
+    my $basicfee = $hash->{BasicFeePerMonth};
+
+    #----- check whether day or month was changed
+    if(!defined($hash->{READINGS}{cum_day})) {
+      #----- init cum_day if it is not set
+      $val = sprintf("CUM_DAY: %0.3f CUM: %0.3f COST: %0.2f", 0, $total, 0);
+      $readings{cum_day}   = $val;
+
+    } else {
+
+      if( (localtime($tsecs_prev))[3] != (localtime($tsecs))[3] ) {
+        #----- day has changed (#3)
+        my @cmv = split(" ", $hash->{READINGS}{cum_day}{VAL});
+        $val = sprintf("CUM_DAY: %0.3f CUM: %0.3f COST: %0.2f",
+                        $total-$cmv[3], $total, ($total-$cmv[3])*$cost);
+        $readings{cum_day} = $val;
+        Log GetLogLevel($n,3), "CUL_ESA $n: $val";
+
+
+        if( (localtime($tsecs_prev))[4] != (localtime($tsecs))[4] ) {
+
+          #----- month has changed (#4)
+          if(!defined($hash->{READINGS}{cum_month})) {
+            # init cum_month if not set
+            $val = sprintf("CUM_MONTH: %0.3f CUM: %0.3f COST: %0.2f",
+                       0, $total, 0);
+            $readings{cum_month} = $val;
+
+          } else {
+            @cmv = split(" ", $hash->{READINGS}{cum_month}{VAL});
+            $val = sprintf("CUM_MONTH: %0.3f CUM: %0.3f COST: %0.2f",
+                       $total-$cmv[3], $total,($total-$cmv[3])*$cost+$basicfee);
+            $readings{cum_month} = $val;
+            Log GetLogLevel($n,3), "CUL_ESA $n: $val";
+
+          }
+        }
+      }
+    }
+    # End CUMULATE day and month
+    ###################################
+
+
+    foreach my $k (keys %readings) {
+      $hash->{READINGS}{$k}{TIME}= $tn;
+      $hash->{READINGS}{$k}{VAL} = $readings{$k};
+      $hash->{CHANGED}[$c++] = "$k: $readings{$k}";
+    }
+    return $hash->{NAME};
+
+  } else {
+
+    Log 1, "CUL_ESA detected, Code $type $id $val";
+    return "UNDEFINED CUL_ESA_$id CUL_ESA $type $id";
+
+  }
+
+}
+
+1;
diff -urN fhem-5.3/FHEM/64_ESA2000.pm fhem-5.3-mine/FHEM/64_ESA2000.pm
--- fhem-5.3/FHEM/64_ESA2000.pm	2012-10-28 19:15:27.000000000 +0100
+++ fhem-5.3-mine/FHEM/64_ESA2000.pm	2013-02-10 19:48:05.042879800 +0100
@@ -25,7 +25,7 @@
 
 #                        S0119FA011E00007D6E003100000007C9 ESA2000_LED
 
-  $hash->{Match}     = "^S................................\$";
+  $hash->{Match}     = "^S..1.............................\$";
   $hash->{DefFn}     = "ESA2000_Define";
   $hash->{UndefFn}   = "ESA2000_Undef";
   $hash->{ParseFn}   = "ESA2000_Parse";
diff -urN fhem-5.3/FHEM/98_autocreate.pm fhem-5.3-mine/FHEM/98_autocreate.pm
--- fhem-5.3/FHEM/98_autocreate.pm	2012-10-28 19:15:27.000000000 +0100
+++ fhem-5.3-mine/FHEM/98_autocreate.pm	2013-02-10 17:34:17.000000000 +0100
@@ -14,6 +14,8 @@
 my %flogpar = (
   "CUL_EM.*"
       => { GPLOT => "power8:Power,", FILTER => "%NAME:CNT.*" },
+  "CUL_ESA:.*"
+      => { GPLOT => "cul_esa:Power,", FILTER => "%NAME:(AVG:|CNT:|CUM_).*" },
   "CUL_WS.*"
       => { GPLOT => "temp4hum6:Temp/Hum,",  FILTER => "%NAME:T:.*" },
   "CUL_FHTTK.*"
diff -urN fhem-5.3/www/gplot/cul_esa.gplot fhem-5.3-mine/www/gplot/cul_esa.gplot
--- fhem-5.3/www/gplot/cul_esa.gplot	1970-01-01 01:00:00.000000000 +0100
+++ fhem-5.3-mine/www/gplot/cul_esa.gplot	2010-10-23 10:45:17.000000000 +0200
@@ -0,0 +1,28 @@
+############################
+# Display the power reported by the ESA1000
+# Corresponding FileLog definition:
+# define <filelogname> FileLog /var/log/fhem/em-%Y.log <emdevname>:(CNT:|AVG:).*
+
+set terminal png transparent size <SIZE> crop
+set output '<OUT>.png'
+set xdata time
+set timefmt "%Y-%m-%d_%H:%M:%S"
+set xlabel " "
+
+set title '<L1>'
+set ylabel "Work (kWh)"
+set y2label "Power (kW)"
+set grid
+set ytics
+set y2tics
+set format y "%.1f"
+set format y2 "%.1f"
+
+#FileLog 4:AVG:0:
+#FileLog 8:CNT:0:
+
+plot \
+  "< awk '/AVG/{print $1, $4}' <IN>"\
+     using 1:2 axes x1y2 smooth csplines title 'Power (kW)' with lines lw 2, \
+  "< awk '/CNT/{print $1, $8}' <IN>"\
+     using 1:2 axes x1y1 smooth csplines title 'Work (kWh)' with lines
diff -urN fhem-5.3/www/gplot/cul_esa_month.gplot fhem-5.3-mine/www/gplot/cul_esa_month.gplot
--- fhem-5.3/www/gplot/cul_esa_month.gplot	1970-01-01 01:00:00.000000000 +0100
+++ fhem-5.3-mine/www/gplot/cul_esa_month.gplot	2011-05-30 15:09:46.000000000 +0200
@@ -0,0 +1,28 @@
+############################
+# Display the power reported by the ESA1000
+# Corresponding FileLog definition:
+# define <filelogname> FileLog /var/log/fhem/em-%Y.log <emdevname>:(CUM_MONTH:|CUM_DAY:).*
+
+set terminal png transparent size <SIZE> crop
+set output '<OUT>.png'
+set xdata time
+set timefmt "%Y-%m-%d_%H:%M:%S"
+set xlabel " "
+
+set title '<L1>'
+set y2label "Month (kWh)"
+set ylabel "Day (kWh)"
+set grid
+set ytics
+set y2tics
+set format y "%.1f"
+set format y2 "%.1f"
+
+#FileLog 5:CUM_MONTH:0:
+#FileLog 5:CUM_DAY:0:
+
+plot \
+  "< awk '/CUM_MONTH:/{print $1, $5}' <IN>"\
+     using 1:2 axes x1y2 smooth csplines title 'Month (kWh)' with lines lw 2, \
+  "< awk '/CUM_DAY:{print $1, $5}' <IN>"\
+     using 1:2 axes x1y1 smooth csplines title 'Day (kWh)' with lines
