FHZ vollständig (empfangen&senden) durch CUL/CUN(O) ersetzen

Ich habe eine neue Version des Scriptes erstellt, welche bei ESA als ID jetzt beide Teile einsetzt (V0.14). Damit sollten die Zähler auch getrennt sein. Damit werden allerdings auch die Zähler im IPS neu angelegt. Bitte mal testen.

Tommi

Perfekt. Super Vielen dank.
Jetzt wurde beide ESA eingelesen.

Wenn ich es richtig verstanden habe dann sind die gezählten Ticks. (die Variable TOTAL).
dann nur noch von mir umzurechnen.
D.h. Variable / 75 Umdrehungen /kwh. - bzw. 150.?

Nur so als Hinweis für andere.

Sehr cool - und ich wollte den Busware Stick verschenken :slight_smile:

Wenn ich es richtig verstanden habe dann sind die gezählten Ticks. (die Variable TOTAL).

Ich habe die ESA* nicht selber. Sie wurden aber wie folgt beschrieben


# total    =  total (cumulated) value in ticks as read from the device
# current  =  current value (average over latest 5 minutes) in device units
# ticks    =  ticks per kWh setup in ESA1000WS (depends on the meter)

Tommi

ich schreib mir einfach mal manuell die werte am zähler ab, und vergleich dann…

meine aber das ich zu meinem kurzfristigen FHEM Ausflug auch „total“ für einen Plot hergenommen habe.

Irgendwie passen die zahlen leider nicht :frowning:

ich hab meine alte fhem umgebung mal rausgekramt -
unter fhem waren diese beiden Sensoren als ESA2000_LED geführt - dort haben die zahlen gepasst.

hier die definition eines der beiden Devices:


CODE 5cca
DEF 5cca
IODev CUL_0
NAME ESA2000_LED_5cca
NR 40
STATE CNT: 31+ CUM: 441.653 CUR: 0.000 TICKS: 75 LR
TYPE ESA2000

meine 64_ESA2000.pm sieht so aus:

##############################################
# (c) by STefan Mayer (stefan(at)clumsy.ch)  #
#                                            #
# please feel free to contact me for any     #
# changes, improvments, suggestions, etc     #
#                                            #
##############################################
# $Id: 64_ESA2000.pm 2076 2012-11-04 13:49:43Z rudolfkoenig $

package main;

use strict;
use warnings;

my %codes = (
  "011e" => "ESA2000_LED",
);


#####################################
sub
ESA2000_Initialize($)
{
  my ($hash) = @_;

#                        S0119FA011E00007D6E003100000007C9 ESA2000_LED

  $hash->{Match}     = "^S................................\$";
  $hash->{DefFn}     = "ESA2000_Define";
  $hash->{UndefFn}   = "ESA2000_Undef";
  $hash->{ParseFn}   = "ESA2000_Parse";
  $hash->{AttrList}  = "IODev do_not_notify:0,1 showtime:0,1 loglevel:0,1,2,3,4,5,6 ignore:0,1 ".
                       "model:esa2000-led,esa2000-wz,esa2000-s0,esa1000wz-ir,esa1000wz-s0,esa1000wz-led,esa1000gas base_1 base_2 ".
                       $readingFnAttributes;
}

#####################################
sub
ESA2000_Define($$)
{
  my ($hash, $def) = @_;
  my @a = split("[ 	][ 	]*", $def);

  return "wrong syntax: define <name> ESA2000 CODE" if(int(@a) != 3);
  $a[2] = lc($a[2]);
  return "Define $a[0]: wrong CODE format: specify a 4 digit hex value"
  		if($a[2] !~ m/^[a-f0-9][a-f0-9][a-f0-9][a-f0-9]$/);


  $hash->{CODE} = $a[2];
  $modules{ESA2000}{defptr}{$a[2]} = $hash;
  AssignIoPort($hash);
  return undef;
}

#####################################
sub
ESA2000_Undef($$)
{
  my ($hash, $name) = @_;
  delete($modules{ESA2000}{defptr}{$hash->{CODE}})
        if(defined($hash->{CODE}) &&
           defined($modules{ESA2000}{defptr}{$hash->{CODE}}));
  return undef;
}

#####################################
sub
ESA2000_Parse($$)
{
  my ($hash, $msg) = @_;

# 0 00 0000 0001 11111111 1222 222222 2333
# 0 12 3456 7890 12345678 9012 345678 9012
# S                                            Sensorkennung
#   ss                                         Sequenze und Sequenzwiederhohlung mit gesetzten höchsten Bit
#      dddd                                    Device
#           cccc                               Code
#                vvvvvvvv vvvv vvvvvv vvvv     Valves
#                tttttttt                      Gesamtimpules
#                         aaaa                 Impule je Sequenz
#                              zzzzzz          Zeitstempel seit Start des Adapters             (ESA1000)
#                                     kkkk     Impulse je kWh/m3
#
# Examples:
# ---------
# S 01 19FA 011E 00007D6E 0031 000000 07C9     ESA2000_LED      Zählerkonstante = 2000
# S 12 5E42 011E 00000030 0002 000000 0206     ESA2000_WZ       Zählerkonstante = 600
# S 48 6062 011E 00000061 0001 000000 002B     ESA2000_WZ       Zählerkonstante = 75
# S 93 5DDA 011E 00004F85 0000 000000 0205     ESA2000_WZ       Zählerkonstante = 600
# S 16 68C5 011E 000000BB 0000 001FB4 03CB     ESA1000WZ_LED    Zählerkonstante = 1000
# S AB 0595 031E 000A047E 0000 227C46 0004     ESA1000GAS       Zählerkonstante = 1
# S 1C 0785 011E 00011CDA 0002 0D056C 004C     ESA1000WZ_LED    Zählerkonstante = 75
# S 6E 003D 011E 00037650 0011 02C1DA 07D0     ESA1000WZ_S0     Zählerkonstante = 2000
# S A3 0543 031E 0000099C 0064 001147 000F     ESA1000GAS       Zählerkonstante = 10

  $msg = lc($msg);
  my $seq = substr($msg, 1, 2);
  my $dev = substr($msg, 3, 4);
  my $cde = substr($msg, 7, 4);
  my $val = substr($msg, 11, 22);

  Log 5, "ESA2000 msg $msg";
  Log 5, "ESA2000 seq $seq";
  Log 5, "ESA2000 device $dev";
  Log 5, "ESA2000 code $cde";

  my $type = "";
  foreach my $c (keys %codes) {
    $c = lc($c);
    if($cde =~ m/$c/) {
      $type = $codes{$c};
      last;
    }
  }

  if(!defined($modules{ESA2000}{defptr}{$dev})) {
    Log 3, "Unknown ESA2000 device $dev, please define it";
    $type = "ESA2000" if(!$type);
    return "UNDEFINED ${type}_$dev ESA2000 $dev";
  }

  my $def = $modules{ESA2000}{defptr}{$dev};
  my $name = $def->{NAME};
  return "" if(IsIgnored($name));

  my $now = TimeNow();
  my (@v, @txt);

#  ($sec,$min,$hour,$mday,$mon,$year,$wday,$yday,$isdst) = gmtime(time);
#  $year = $year + 1900;

  if($type eq "ESA2000_LED") {

    @txt = ( "repeat", "sequence", "total_ticks", "actual_ticks", "ticks_kwh", "raw", "total_kwh", "actual_kwh", "diff_kwh", "diff_sec", "diff_ticks", "last_sec", "raw_total_kwh", "max_kwh", "day_kwh", "month_kwh", "year_kwh", "rate", "day_hr_kwh", "day_lr_kwh", "month_hr_kwh", "month_lr_kwh", "year_hr_kwh", "year_lr_kwh" );

# } elsif ($type eq "ESA1000GAS") {
#
#    @txt = ( "repeat", "sequence", "total_ticks", #"actual_ticks", "ticks_m3", "raw", 
#             "total_m3", "actual_m3", "diff_m3", "diff_sec", #"diff_ticks", "last_sec", "raw_total_m3", 
#             "max_m3", "day_m3", "month_m3", "year_m3", "rate", 
#             "day_hr_m3", "day_lr_m3", "month_hr_m3", #"month_lr_m3", "year_hr_m3", "year_lr_m3" );
#
  } else {

    Log 3, "ESA2000 Device $dev (Unknown type: $type)";
    return "";

  }

    # Codierung Hex
    #  0 "repeat"
    $v[0] =  int(hex($seq) / 128) ? "+" : "-";
    #  1 "sequence"
    $v[1] =  hex($seq) % 128;
    #  2 "total_ticks"
    $v[2] =  hex(substr($val,0,8));
    #  3 "actual_ticks"
    $v[3] =  hex(substr($val,8,4));
    #  4 "ticks_kwh"
    $v[4] =  hex(substr($val,18,4)) ^ hex(substr($msg,3,2));    # XOR high byte of device-id

    my $corr = 1;
    if ($type eq "ESA1000GAS") {
      $corr = 1000/$v[4];
    }

    # check if low-rate or high-rate. note that this is different per electricity company! (Here weekday from 6-20 is high rate)
    my ($sec,$min,$hour,$mday,$month,$year,$wday,$yday,$isdst) = localtime;

    # 17 "rate"
    if ( (0 < $wday ) && ($wday < 6) && (5 < $hour) && ($hour < 20) ) {
      $v[17] = "HR";
    } else {
      $v[17] = "LR";
    }

    #  5 "raw"
    $v[5] = sprintf("CNT: %d%s CUM: %d CUR: %d  TICKS: %d %s",
                         $v[1], $v[0], $v[2], $v[3], $v[4], $v[17] );

    #  9 "diff_sec"
    # 11 "last_sec"
    my $vt = time();
    $v[9] =  $vt - (defined($def->{READINGS}{$txt[11]}{VAL}) ? $def->{READINGS}{$txt[11]}{VAL} : $vt); # seconds since last update

    #  2 "total_ticks"
    #  3 "actual_ticks"
    #  4 "ticks_kwh"
    #  7 "actual_kwh"
    #  8 "diff_kwh"
    #  9 "diff_sec"
    # 10 "diff_ticks"
    # 11 "last_sec"
    $v[7] = -1;
    $v[8] = sprintf("%.4f", $v[3]/$v[4]/$corr);    # calculate kWh diff from readings (raw from device....), whats this relly?
    if($v[9] >= 110) {
      # Zeitdifferenz zu gering (ESA 120s bis 184s bzw 300s)
#      $v[9] = (($v[9] lt 110) ? 150 : $v[9]);
      $v[11] = $vt;
      if(defined($def->{READINGS}{$txt[2]}{VAL}) && $def->{READINGS}{$txt[2]}{VAL} <=$v[2]) {    # check for resetted counter.... only accept increase in counter
        $v[10] = $v[2] - $def->{READINGS}{$txt[2]}{VAL};                                         # should be the same as actual_ticks if no packets are lost
        $v[7] = sprintf("%.3f", $v[10]/$v[4]/$corr/$v[9]*3600);                                        # calculate kW/h since last update
      }
    } elsif (!defined($def->{READINGS}{$txt[11]}{VAL})) {
        $v[11] =  $vt
    }

    if(defined($v[10])) {
      my $kwh = $v[10]/$v[4]/$corr;
      #  6 "total_kwh"
      $v[6] = $kwh + (defined($def->{READINGS}{$txt[6]}{VAL}) ? $def->{READINGS}{$txt[6]}{VAL} : 0); # cumulate kWh to ensure tick-changes are calculated correctly (does this ever happen?)

      #     Day          #     Month          #     Year
      # 14 "day_xx"      # 15 "month_xx"      # 16 "year_xx"
      # 18 "day_hr_xx"   # 20 "month_hr_xx"   # 22 "year_hr_xx"
      # 19 "day_lr_xx"   # 21 "month_lr_xx"   # 23 "year_lr_xx"
      for(my $i = 0; $i < 3; $i++) {
        $v[$i+14] = $kwh + (defined($def->{READINGS}{$txt[$i+14]}{VAL}) && (substr($now,0,10-$i*3) eq substr($def->{READINGS}{$txt[$i+14]}{TIME},0,10-$i*3)) ? $def->{READINGS}{$txt[$i+14]}{VAL} : 0);           # cumulate kWh to ensure tick-changes are calculated correctly (does this ever happen?)
        if ($v[17] eq "HR" ) {
          $v[$i*2+18] = $kwh + (defined($def->{READINGS}{$txt[$i*2+18]}{VAL}) && (substr($now,0,10-$i*3) eq substr($def->{READINGS}{$txt[$i*2+18]}{TIME},0,10-$i*3)) ? $def->{READINGS}{$txt[$i*2+18]}{VAL} : 0); # high-rate
        } else {
          $v[$i*2+19] = $kwh + (defined($def->{READINGS}{$txt[$i*2+19]}{VAL}) && (substr($now,0,10-$i*3) eq substr($def->{READINGS}{$txt[$i*2+19]}{TIME},0,10-$i*3)) ? $def->{READINGS}{$txt[$i*2+19]}{VAL} : 0); # low-rate
        }
      }

      #  7 "actual_kwh"
      # 13 "max_kwh"
      if(!defined($def->{READINGS}{$txt[13]}{VAL})) {
        $v[13] = $v[7];    # update max kw/h
      } elsif($v[7] >= $def->{READINGS}{$txt[13]}{VAL}) {
        $v[13] = $v[7];    # update max kw/h
      }

      #  2 "total_ticks"
      #  4 "ticks_kwh"
      # 12 "raw_total_kwh"
      $v[12] = $v[2]/$v[4]/$corr;   # calculate kWh total since reset of device (does only make sense if ticks per kWh does not change!!)
      # add counter_1 and counter_2 (Hoch- und Niedertarif Basiswerte)
      if(defined($attr{$name}) &&
        defined($attr{$name}{"base_1"})) {
          $v[12] = sprintf("%.3f", $v[12] + $attr{$name}{"base_1"});
      }
      if(defined($attr{$name}) &&
        defined($attr{$name}{"base_2"})) {
          $v[12] = sprintf("%.3f", $v[12] + $attr{$name}{"base_2"});
      }

    } else {
      #  6 "total_kwh"
      $v[6] = (defined($def->{READINGS}{$txt[6]}{VAL}) ? $def->{READINGS}{$txt[6]}{VAL} : 0);
    }

    $val = sprintf("CNT: %d%s CUM: %0.3f CUR: %0.3f TICKS: %d %s",
                       $v[1], $v[0], $v[6], $v[7], $v[4], $v[17]);

  #
  # from here readings are effectively updated
  #
  readingsBeginUpdate($def);

  Log GetLogLevel($name,4), "ESA2000 $name: $val";

  if ( (defined($def->{READINGS}{"sequence"}{VAL}) ? $def->{READINGS}{"sequence"}{VAL} : "") ne $v[1] ) {
    my $max = int(@txt);
    for( my $i = 0; $i < $max; $i++) {
      if (defined($v[$i])) {
        readingsBulkUpdate($def, $txt[$i], $v[$i]);
      }
    }

    readingsBulkUpdate($def, "type", $type);
    readingsBulkUpdate($def, "state", $val);

  } else {
    Log GetLogLevel($name,4), "ESA2000/DISCARDED $name: $val";
  }
  #
  # now we are done with updating readings
  #
  readingsEndUpdate($def, 1);

  return $name;
}

1;

=pod
=begin html

<a name="ESA2000"></a>
<h3>ESA2000</h3>
<ul>
  The ESA2000 module interprets ESA2000 type of messages received by the CUL,
  currently only for ESA2000 LED devices.
  <br><br>

  <a name="ESA2000define"></a>
  <b>Define</b>
  <ul>
    <code>define <name> ESA2000 <code>
        [base1 base2]</code> <br>
    <br>
    <code> is the 4 digit HEX code identifying the devices.<br><br>

    <b>base1/2</b> is added to the total kwh as a base (Hoch- und Niedertarifzählerstand).
  </ul>
  <br>

  <a name="CUL_EMset"></a>
  <b>Set</b> <ul>N/A</ul><br>

  <a name="CUL_EMget"></a>
  <b>Get</b> <ul>N/A</ul><br>

  <a name="CUL_EMattr"></a>
  <b>Attributes</b>
  <ul>
    <li><a href="#ignore">ignore</a></li><br>
    <li><a href="#do_not_notify">do_not_notify</a></li><br>
    <li><a href="#showtime">showtime</a></li><br>
    <li><a href="#loglevel">loglevel</a></li><br>
    <li><a href="#model">model</a> (ESA2000_LED)</li><br>
    <li><a href="#IODev">IODev</a></li><br>
    <li><a href="#readingFnAttributes">readingFnAttributes</a></li><br>
  </ul>
  <br>
</ul>


=end html
=cut

Welche Zahlen passen nicht?

Tommi

Meine 64_ESA2000.pm (von fhem5.4) hat auch den Tag $Id: 64_ESA2000.pm 2076 2012-11-04 13:49:43Z, aber kompletten anderen Inhalt…

Die 64_ESA2000.pm war bei mir von Anfang diesen Jahres aus dem FHEM Forum übernommen.

Die Ticks + deren TOTAL können nicht passen.
TOTAL = GEsamtanzahl an ticks / also umdrehungen.

wenn ich einen zähler mit 150U /kwh habe, dann muss ich die totalen / 150 rechnen.

Ich habe an einem zählern z.b. gerade mal 300W mehr in einem Tag. (Was nicht sein kann - da 24h Lüftungsanlage mit durchschnittlich ca.30W + Wärmepumpe Warmwassererzeugung (ca. 1 - 1,5kwh)…

In fhem waren die zahlen plausibel…

bringt das ESA_LOG was aus fhem:

2013-02-23_18:36:42 ESA2000_LED_5e69 repeat: +
2013-02-23_18:36:42 ESA2000_LED_5e69 sequence: 44
2013-02-23_18:36:42 ESA2000_LED_5e69 total_ticks: 37885
2013-02-23_18:36:42 ESA2000_LED_5e69 actual_ticks: 3
2013-02-23_18:36:42 ESA2000_LED_5e69 ticks_kwh: 150
2013-02-23_18:36:42 ESA2000_LED_5e69 raw: CNT: 44+ CUM: 37885 CUR: 3  TICKS: 150 LR
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 actual_kwh: -1
2013-02-23_18:36:42 ESA2000_LED_5e69 diff_kwh: 0.02
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 last_sec: 1361641002
2013-02-23_18:36:42 ESA2000_LED_5e69 raw_total_kwh: 252.566666666667
2013-02-23_18:36:42 ESA2000_LED_5e69 max_kwh: -1
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 rate: LR
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 
2013-02-23_18:36:42 ESA2000_LED_5e69 CNT: 44+ CUM: 0.000 CUR: -1.000 TICKS: 150 LR
2013-02-23_18:39:00 ESA2000_LED_5e69 repeat: +
2013-02-23_18:39:00 ESA2000_LED_5e69 sequence: 45
2013-02-23_18:39:00 ESA2000_LED_5e69 total_ticks: 37888
2013-02-23_18:39:00 ESA2000_LED_5e69 actual_ticks: 3
2013-02-23_18:39:00 ESA2000_LED_5e69 ticks_kwh: 150
2013-02-23_18:39:00 ESA2000_LED_5e69 raw: CNT: 45+ CUM: 37888 CUR: 3  TICKS: 150 LR
2013-02-23_18:39:00 ESA2000_LED_5e69 total_kwh: 0.02
2013-02-23_18:39:00 ESA2000_LED_5e69 actual_kwh: 0.521739130434783
2013-02-23_18:39:00 ESA2000_LED_5e69 diff_kwh: 0.02
2013-02-23_18:39:00 ESA2000_LED_5e69 diff_sec: 138
2013-02-23_18:39:00 ESA2000_LED_5e69 diff_ticks: 3
2013-02-23_18:39:00 ESA2000_LED_5e69 last_sec: 1361641140
2013-02-23_18:39:00 ESA2000_LED_5e69 raw_total_kwh: 252.586666666667
2013-02-23_18:39:00 ESA2000_LED_5e69 max_kwh: 0.521739130434783
2013-02-23_18:39:00 ESA2000_LED_5e69 day_kwh: 0.02
2013-02-23_18:39:00 ESA2000_LED_5e69 month_kwh: 0.02
2013-02-23_18:39:00 ESA2000_LED_5e69 year_kwh: 0.02

die auszug aus der fhem.cfg:


define autocreate autocreate
attr autocreate autosave 1
attr autocreate device_room %TYPE
attr autocreate filelog ./log/%NAME-%Y-%m.log
attr autocreate icon icoSYSTEM
attr autocreate weblink 1
attr autocreate weblink_room Plots

# Disable this to avoid looking for new USB devices on startup
define initialUsbCheck notify global:INITIALIZED usb create
attr initialUsbCheck icon icoLuefter


define CUL_0 CUL /dev/ttyACM0@9600 1034
attr CUL_0 rfmode SlowRF
#
# ab hier gehts mit dem Gesamten Stromzähler los
define ESA2000_LED_5cca ESA2000 5cca
attr ESA2000_LED_5cca icon icoBlitz
attr ESA2000_LED_5cca room ESA2000
define FileLog_ESA2000_LED_5cca FileLog ./log/ESA2000_LED_5cca-%Y.log ESA2000_LED_5cca
attr FileLog_ESA2000_LED_5cca logtype Strom_Gesamt:Power,text
attr FileLog_ESA2000_LED_5cca room ESA2000
define weblink_ESA2000_LED_5cca weblink fileplot FileLog_ESA2000_LED_5cca:Strom_Gesamt:CURRENT
attr weblink_ESA2000_LED_5cca label "Stromverbrauch Gesamt / Min $data{min1}, / Max $data{max1}, / Zuletzt $data{currval1}, / Durchschnitt $data{avg1}"
attr weblink_ESA2000_LED_5cca room Plots
#
# ab hier gehts mit dem WP Stromzählerlos 5e69
define ESA2000_LED_5e69 ESA2000 5e69
attr ESA2000_LED_5e69 icon icoBlitz
attr ESA2000_LED_5e69 room ESA2000
define FileLog_ESA2000_LED_5e69 FileLog ./log/ESA2000_LED_5e69-%Y.log ESA2000_LED_5e69
attr FileLog_ESA2000_LED_5e69 logtype Strom_WP:Power,text
attr FileLog_ESA2000_LED_5e69 room ESA2000
define weblink_ESA2000_LED_5e69 weblink fileplot FileLog_ESA2000_LED_5e69:Strom_Gesamt:CURRENT
attr weblink_ESA2000_LED_5e69 label "stromverbrauch WP / Min $data{min1}, / Max $data{max1}, / Zuletzt $data{currval1}, / Durchschnitt $data{avg1}"
attr weblink_ESA2000_LED_5e69 room Plots

was mir auffällt der Empfangsmodus wurde in (rfmode SlowRF) gesetzt?
attr CUL_0 rfmode SlowRF

was mir auffällt der Empfangsmodus wurde in (rfmode SlowRF) gesetzt?

Der RF-Mode muss normalerweise nicht geändert werden, weil alle anderen von meinem Script decodierten Typen auch SlowRF sind. Was anderes ist z.B. Homematic.

Die Ticks + deren TOTAL können nicht passen.
TOTAL = GEsamtanzahl an ticks / also umdrehungen.

Die absoluten Werte müssten identisch sein, da die gleichen Felder genommen werden, weil $val bei FHEM dort anfängt, wo bei mir Position in $line 11 ist

$total_cnt=hexdec(substr($line,11,8));
$current_cnt=hexdec(substr($line,19,4));
$timestamp=hexdec(substr($line,23,6));
$ticks=hexdec(substr($line,29,4));

zu FHEM


my $val = substr($msg, 11, 22);
#  2 "total_ticks"
$v[2] =  hex(substr($val,0,8));
#  3 "actual_ticks"
$v[3] =  hex(substr($val,8,4));
#  4 "ticks_kwh"
$v[4] =  hex(substr($val,18,4)) ^ hex(substr($msg,3,2));    # XOR high byte of device-id  

Die Felder für total und current sollten also identisch sein. Nur die Ticks/kwh passen nicht, weil das xor bei mir fehlt. Der Wert selbst sollte aber statisch sein. In meinem Script müsste also Zeile 910 so aussehen, um es genauso einzustellen


$ticks=hexdec(substr($line,29,4)) ^ hexdec(substr($line,3,2));

Tommi

Hallo,

bei mir bleiben die Werte „konstant“ komisch :slight_smile:

Das habe ich nachgetragen: $ticks=hexdec(substr($line,29,4)) ^ hexdec(substr($line,3,2));

Unter „Strom Übersicht“ -> Habe ich das Skript zur Berechnung des Stromverbrauchs eingehängt,
damit füttere ich die Variablen 47021 Stromverbrauch Gesamt, und 53114 Stromverbrauch WP + KWL.

Ich habe z.b. seit zwei Tagen meine Wärmepumpe am laufen.
D.h. am Zähler ESA 5CCA wo derzeit 71 W angezeigt werden, müssten wesentlich mehr drüberlaufen.

Bin auf em Schlauch was ich hier falsch mache.

Bleibt eigentlich nur noch ein Reset der ESAs und neu einstellen - aber in FHEM hats „gepasst“…?

Hier ein paar Screenshots und mein Skript zur Berechnung des Stromverbrauchs.

Berechnungsskript:


<?
$stromwaermepumpe = GetValueInteger(48455 /*[Strom\ESA  5CCA-011E	otal]*/);
$stromverbrauchgesamt = GetValueInteger(59092 /*[Strom\ESA  5E69-011E	otal]*/);
$berechnunggesamt = $stromverbrauchgesamt/75;
$berechnungwaermepumpe = $stromwaermepumpe/150;
//$round_delta_gesamt = round ($berechnunggesamt, 1);
//$round_delta_waermepumpe = round ($berechnungwaermepumpe, 1);

SetValueInteger (47021 /*[Strom\Strom Übersicht\Stromverbrauch Gesamt]*/, $berechnunggesamt);
SetValueInteger (53114 /*[Strom\Strom Übersicht\Stromverbrauch WP + KWL]*/, $berechnungwaermepumpe);
?>

CUL_RegVar:

<?php
/**
RegVar-Script für busware.de CUL/CUN receiver
protocol decodes translated from FHEM project
http://www.koeniglich.de/fhem/fhem.html
testet with IPS 3.0 and CUN FW 1.46 (ESA not tested)
www.tdressler.net/ipsymcon
V0.14 07.09.2013
@package CUN
*/

//Regvar-Instance
$reg=26972 /*[Busware CUL\Register Variable]*/;
if (!IPS_InstanceExists($reg)) {
               print "Instance with ID $reg doesnt exists";
               return;
}
$inst=IPS_GetInstance($reg);
$ityp=$inst['ModuleInfo']['ModuleName'];
if ($ityp!="Register Variable") {
               print "Instance $reg is not a 'Register Variable' Instance";
               return;
}
//get message variable
$lmid=getVid('AuxMessage',$reg,3);
//autocreate IPS Objects, set to false if you dont want this
$autocreate=true;

//logging
$logdir='../logs/';
$cullog=$logdir."cul.log";
$emlog=$logdir."culem.log";
$fs20log=$logdir."culfs20.log";
$fhtlog=$logdir."culfht.log";
$wslog=$logdir."culws.log";
$hmslog=$logdir."culhms.log";
$esalog=$logdir."culesa.log";

//manual executed
if ($IPS_SENDER == "Execute")
{
/*
     Start/Stop Parent,
     set Modus vis CUL_Status Event script capturing Status change
*/
   //Status variablen
     $versid=getVid('Version',$reg,3);
     $mid=getVid('Modus',$reg,3);
     //Parent=ClientSocket or ComPort
     $sid=IPS_GetParent($reg);
     if ($sid) {
        $inst=IPS_GetInstance($sid);
        $ityp=$inst['ModuleInfo']['ModuleName'];
        if ($ityp=="Client Socket") {
               setValue($mid,"");
               setValue($versid,"");
               //stop
               CSCK_SetOpen($sid,false);
               IPS_ApplyChanges($sid);
               sleep(1);
               //start
               CSCK_SetOpen($sid,true);
               IPS_ApplyChanges($sid);
          }elseif($ityp=="Serial Port") {
               setValue($mid,"");
               setValue($versid,"");
               //stop
               ComPort_SetOpen($sid,false);
               IPS_ApplyChanges($sid);
               sleep(1);
               //start
               ComPort_SetOpen($sid,true);
               IPS_ApplyChanges($sid);
          }else{
             print "Modultyp wrong";
             return;
          }
          sleep(1);
          $modus=getValue($mid);
          print "Modus: $modus 
";
          $version=getValue($versid);
          print "Version: $version
\r";
   }else{
        print "Parent not found";
   }
}
//register variable triggerd action
elseif ($IPS_SENDER == "RegisterVariable")
{
  // bereits im Puffer der Instanz vorhandene Daten in $data kopieren
  $data  = RegVar_GetBuffer($reg);
  // neu empfangene Daten an $data anhängen
  $data .= $IPS_VALUE;
   //logging
   //IPS_Logmessage('CUL',$data);
     logge($cullog,$data);

     //split lines
     $rows=preg_split("/
/",$data);
     //reset Regvar Buffer
     $data="";
     RegVar_SetBuffer($reg, "");

     foreach($rows as $line) {
//---------------EM1000-----------------------------------

          if (preg_match("/^E[0-9A-F]{18,20}\s*\$/",$line)) {
      //  E0101E2997805002F02
               $type=substr($line,2,1);
               $addr=substr($line,3,2);
               $catname='Strom';
               $sensorname='EM1010 Sensor';
               $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                 'Signal'=>array('type'=>1,'profile'=>''),
                             'Last'=>array('type'=>1,'profile'=>'~UnixTimestamp'),
                                             'Total'=>array('type'=>2,'profile'=>'~Electricity'),
                                             'Actual'=>array('type'=>2,'profile'=>'~Power'),
                                             'Peak'=>array('type'=>2,'profile'=>'~Power'),
                                             'total_cnt'=>array('type'=>1,'profile'=>''),
                                             'basis_cnt'=>array('type'=>1,'profile'=>''),
                                             'cf_power'=>array('type'=>2,'profile'=>''),
                                             'cf_energy'=>array('type'=>2,'profile'=>''));
               $varids=get_ips_vars($addr,$vartypes,$catname,$sensorname);
               if (is_null($varids)) {
                  //no vars available, maybe autocreate disabled
                    continue;
               }
               $cf1=$varids['cf_power']['val'];
               $cf2=$varids['cf_energy']['val'];
               $basis_cnt=$varids['basis_cnt']['val'];
               $total_cnt_last=$varids['total_cnt']['val'];
               $last=$varids['Last']['val'];
               //ips_logmessage($catname,"1:$cf1,2:$cf2,B:$basis_cnt,T:$total_cnt_last,L:$last");

               /*
               Set corretion factor
               corr1 is the correction factor for power
               corr2 is the correction factor for energy
               */
               $cfnew=(($cf1==0)||($cf2==0));
               if($addr >= 1 && $addr <= 4) {                // EMWZ: nRotation in 5 minutes
                        $cf1 = ($cf1 ? $cf1 : 150);                         //Zählerkonstanzte U/kwh
                        $cf2 = ($cf2 ? $cf2 : 150);
                        $corr1=12/$cf1;
                        $corr2=1/$cf2;

                 } elseif ($addr >= 5 && $addr <= 8) {          // EMEM
                       $cf1 = ($cf1 ? $cf1 : 0.01);
                        $cf2 = ($cf2 ? $cf2 : 0.001);
                        $corr1=$cf1;
                        $corr2=$cf2;

                 } elseif($addr >= 9 && $addr <= 12) {          // EMGZ: 0.01
                  $cf1 = ($cf1 ? $cf1 : 0.01);
                   $cf2 = ($cf2 ? $cf2 : 0.01);
                   $corr1=$cf1;
                   $corr2=$cf2;

              } else {
               IPS_Logmessage($catname,"Wrong Address:$addr");
               return;
              }
               //store default factors
               if ($cfnew) {
                    SetValue($varids['cf_power']['id'],$cf1);
                    SetValue($varids['cf_energy']['id'],$cf2);
               }

/*
          Decode Packet
          description from CUL_EM.pm
       Ettaacc111122223333
        tt:type 01=EM-1000s, 02=EM-100-EM, 03=1000GZ
        aa:address, depending on the type above 01:01-04, 02:05-08, 03:09-12
        cc:counter, will be incremented by one for each message
        1111: cumulated value
        2222: last value (Not set for type 2)
        3333: top value  (Not set for type 2)
    seqno    =  number of received datagram in sequence, runs from 2 to 255
       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  =  current value (average over latest 5 minutes) in device units
    peak     =  maximum value in device units
*/


               $seqno=hexdec(substr($line,5,2));
               //total value
               $total_cnt=hexdec(substr($line,9,2).substr($line,7,2));
               //counter overflow, max value 65535
               if($total_cnt< $total_cnt_last) {
                $basis_cnt += 65536 /*[Kein(e)]*/;
                SetValue($varids['basis_cnt']['id'],$basis_cnt);
              }
              $total    = ($basis_cnt+$total_cnt)*$corr2;
              SetValue($varids['total_cnt']['id'],$total_cnt);

           //check time diff tp previous
             $now=time();
               $tdiff=$now-$last;

               // peak and current (5min) value
               if ($type<>2) {
                    $current_cnt=hexdec(substr($line,13,2).substr($line,11,2));
                    $peak_cnt=hexdec(substr($line,17,2).substr($line,15,2));
                    $current  = $current_cnt*$corr1;
                   $peak     = $peak_cnt*$corr1;
               }else{
                  //calculate current as counter difference
                    if ($total_cnt>=$total_cnt_last) {
                         $current_cnt=$total_cnt-$total_cnt_last;
                    }else{
                       //add overflow
                         $current_cnt=$total_cnt+65536-$total_cnt_last;
                    }
              //type 2 has no peak and current entry
                    $current  = $current_cnt*$corr1;
                    $peak=0;
                    $peak_cnt=0;
               }

               //store in IPS
             SetValue($varids['Total']['id'],$total);
             SetValue($varids['Actual']['id'],$current);
             SetValue($varids['Peak']['id'],$peak);
               SetValue($varids['Last']['id'],$now);

               //signal
               if ( strlen($line)>19) {
                  SetSignal($varids['Signal']['id'],substr($line,19,2));
               }
               //logging to IPS log
               $val = sprintf("SEQ: %d CNT: %d Basis: %d DIFF: %d TIME:$tdiff CUM: %0.3f  5MIN: %0.3f  PEAK: %d TOP: %0.3f",
                         $seqno, $total_cnt, $basis_cnt,$current_cnt,$total, $current,$peak_cnt, $peak);
               $text= "Type $type Addr:$addr, $val";

             //logging
                 IPS_Logmessage($catname,$text);
               logge($emlog,"$line=>Dev $addr:".$text."
");

     }//if pregmatch
//-----------------------FS20
     elseif (preg_match("/^F[0-9A-F]{8,12}\s*\$/",$line)) {
          //F1F1E013A4F
                 $hcode=substr($line,1,4);
               $addr=substr($line,5,2);
               $cde=substr($line,7,2);
               $id=hex2four($hcode.$addr);
               if (strlen($id)==12)$id=substr($id,0,4).' '.substr($id,4,4).' '.substr($id,8,4);
               $catname='FS20CUL';
               $sensorname='FS20 ';
               $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                             'Status'=>array('type'=>3,'profile'=>''),
                                             'Signal'=>array('type'=>1,'profile'=>'')
                             );
               $varids=get_ips_vars($id,$vartypes,$catname,$sensorname);
               if (is_null($varids)) {
                  //no vars available, maybe autocreate disabled
                    continue;
               }
               $fs20_codes = array(
               //definitions taken from fhem 10_fs20.pm
                      "00" => "off",
                      "01" => "dim06%",
                      "02" => "dim12%",
                      "03" => "dim18%",
                      "04" => "dim25%",
                      "05" => "dim31%",
                      "06" => "dim37%",
                      "07" => "dim43%",
                      "08" => "dim50%",
                      "09" => "dim56%",
                      "0a" => "dim62%",
                      "0b" => "dim68%",
                      "0c" => "dim75%",
                      "0d" => "dim81%",
                      "0e" => "dim87%",
                      "0f" => "dim93%",
                      "10" => "dim100%",
                      "11" => "on",          // Set to previous dim value (before switching it off)
                      "12" => "toggle",     // between off and previous dim val
                      "13" => "dimup",
                      "14" => "dimdown",
                      "15" => "dimupdown",
                      "16" => "timer",
                      "17" => "sendstate",
                      "18" => "off-for-timer",
                      "19" => "on-for-timer",
                      "1a" => "on-old-for-timer",
                      "1b" => "reset",
                      "1c" => "ramp-on-time",      //time to reach the desired dim value on dimmers
                      "1d" => "ramp-off-time",     //time to reach the off state on dimmers
                      "1e" => "on-old-for-timer-prev", // old val for timer, then go to prev. state
                      "1f" => "on-100-for-timer-prev", // 100% for timer, then go to previous state
               );
               $dur = 0;
            $cx = hexdec($cde);
            if($cx & 0x20) {
              $dur = hexdec(substr($line, 9, 2));
              $i = ($dur & 0xf0) / 16;
              $j = ($dur & 0xf);
              $dur = pow(2,$i)*$j*0.25;
              $cde = sprintf("%02x", $cx & ~0x20);
              //signal
               if ( strlen($line)>11) {
                  SetSignal($varids['Signal']['id'],substr($line,11,2));
               }
            }else{
                 //signal
               if ( strlen($line)>9) {
                  SetSignal($varids['Signal']['id'],substr($line,9,2));
               }
          }
            $v = $fs20_codes[$cde];
            if(!$v) $v = "unknown Code $cde" ;
            if($dur) $v .= " DUR: $dur" ;


          $text= "$v($cde)";
          SetValue($varids['Status']['id'],$v);


          //logging
            IPS_Logmessage($catname,$text);
          logge($fs20log,"$line=>Dev $id: ".$text."
");

     } //if pregmatch
//------------------FHT----------------------------------
     elseif (preg_match("/^(T[0-9A-F]{8,12})\s*\$/",$line,$res)) {
           //T4414B90106
               //T0A4700BA00
               //T500CFD8237

               $varids=null;
               $res=$res[1];
               $dev = substr($res, 1, 4);
                 $cde = substr($res, 5, 2);
         if(strlen($res) <12 ) {
            //TFK with signal
             $dev = substr($res, 1, 6);
             $cde = substr($res, 7, 2);
             $val=$res;
               $catname='FHTTFKCUL';
               $sensorname='FHTTFK ';
               $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                 'Signal'=>array('type'=>1,'profile'=>''),
                           'Window'=>array('type'=>3,'profile'=>''),
                           'Warnings'=>array('type'=>3,'profile'=>''),
                           'Status'=>array('type'=>3,'profile'=>''));
               $varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
               if (is_null($varids)) {
                  //no vars available, maybe autocreate disabled
                    continue;
               }

                      $FHT_tfk_codes = array(
                   "02" => "Window:Closed",
                   "82" => "Window:Closed",
                   "01" => "Window:Open",
                   "81" => "Window:Open",
                   "0C" => "Sync:Syncing",
                   "91" => "Window:Open, Low Batt",
                   "11" => "Window:Open, Low Batt",
                   "92" => "Window:Closed, Low Batt",
                   "12" => "Window:Closed, Low Batt",
                   "0F" => "Test:Success");

            switch ($cde) {

               case "01":
               case "81": $win="open";
                    SetValue($varids['Window']['id'],$win);
                        break;
               case "02":
               case "82": $win="closed";
                    SetValue($varids['Window']['id'],$win);
                        break;
               case "11":
               case "91": $win="open";
                    $warn="Low Batt";
                        SetValue($varids['Window']['id'],$win);
                    SetValue($varids['Warnings']['id'],$warn);
                        break;
               case "12":
               case "92": $win="closed";
                      $warn="Low Batt";
                      SetValue($varids['Window']['id'],$win);
                    SetValue($varids['Warnings']['id'],$warn);
                        break;
                    default: break;
            }
            //signal
               if ( strlen($res)>9) {
                  SetSignal($varids['Signal']['id'],substr($res,9,2));
               }

            $val="";
            $cmd=isset($FHT_tfk_codes[$cde])?$FHT_tfk_codes[$cde]:"Unknown TFK:$cde";
            SetValue($varids['Status']['id'],"$cmd");
            $text="FHT TFK:";
            $text.= " $cmd" ;


      //logging
            IPS_Logmessage($catname,$text);
          logge($fhtlog,"$line=>Dev $dev:".$text."
");
         } else {
               $catname='FHTCUL';
               $sensorname='FHT ';
               $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                 'HC'=>Array('type'=>3,'profile'=>''),
                                 'Signal'=>array('type'=>1,'profile'=>''),
                                             'Low'=>array('type'=>3,'profile'=>''),
                           'Position'=>array('type'=>3,'profile'=>''),
                                             'Warnings'=>array('type'=>3,'profile'=>''),
                                             'Soll'=>array('type'=>2,'profile'=>'~Temperature'),
                                             'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
                                             'Status'=>array('type'=>3,'profile'=>''));
               $varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
               if (is_null($varids)) {
                  //no vars available, maybe autocreate disabled
                    continue;
               }
               $FHT_codes = array(
                      "00" => "actuator",
                      "01" => "actuator1",
                      "02" => "actuator2",
                      "03" => "actuator3",
                      "04" => "actuator4",
                      "05" => "actuator5",
                      "06" => "actuator6",
                      "07" => "actuator7",
                      "08" => "actuator8",

                      "14" => "mon-from1",
                      "15" => "mon-to1",
                      "16" => "mon-from2",
                      "17" => "mon-to2",
                      "18" => "tue-from1",
                      "19" => "tue-to1",
                      "1A" => "tue-from2",
                      "1B" => "tue-to2",
                      "1C" => "wed-from1",
                      "1D" => "wed-to1",
                      "1E" => "wed-from2",
                      "1F" => "wed-to2",
                      "20" => "thu-from1",
                      "21" => "thu-to1",
                      "22" => "thu-from2",
                      "23" => "thu-to2",
                      "24" => "fri-from1",
                      "25" => "fri-to1",
                      "26" => "fri-from2",
                      "27" => "fri-to2",
                      "28" => "sat-from1",
                      "29" => "sat-to1",
                      "2A" => "sat-from2",
                      "2B" => "sat-to2",
                      "2C" => "sun-from1",
                      "2D" => "sun-to1",
                      "2E" => "sun-from2",
                      "2F" => "sun-to2",

                      "3E" => "mode",
                      "3F" => "holiday1",          # Not verified
                      "40" => "holiday2",          # Not verified
                      "41" => "desired-temp",
                      "XX" => "measured-temp",          # sum of next. two, never really sent
                      "42" => "measured-low",
                      "43" => "measured-high",
                      "44" => "warnings",
                      "45" => "manu-temp",          # No clue what it does.

                      "4B" => "ack",
                      "53" => "can-xmit",
                      "54" => "can-rcv",

                      "60" => "year",
                      "61" => "month",
                      "62" => "day",
                      "63" => "hour",
                      "64" => "minute",
                      "65" => "report1",
                      "66" => "report2",
                      "69" => "ack2",

                      "7D" => "start-xmit",
                      "7E" => "end-xmit",

                      "82" => "day-temp",
                      "84" => "night-temp",
                      "85" => "lowtemp-offset",         # Alarm-Temp.-Differenz
                      "8A" => "windowopen-temp"

               );


               // additional warnings
               $FHT_warnings = array(
                      "battery"       => 1,
                      "lowtemp"       => 1,
                      "window"        => 1,
                      "windowsensor"  => 1,
               );

               $FHT_priority = array(
                      "desired-temp"=> 1,
                      "mode"     => 2,
                      "report1"     => 3,
                      "report2"     => 3,
                      "holiday1"     => 4,
                      "holiday2"     => 5,
                      "day-temp"     => 6,
                      "night-temp"     => 7,
               );

               $FHT_c2m = array(0 => "auto", 1 => "manual", 2 => "holiday", 3 => "holiday_short");
               $hc=hexdec($dev);
               $house=sprintf("%02d %02d",($hc >>8), ($hc & 255));
               SetValue($varids['HC']['id'],"$house");
               $text="Dev: $dev (HC $house)";
              if(strlen($line) > 9) $val = substr($line, 9, 2);


         //signal
               if ( strlen($line)>11) {
                  SetSignal($varids['Signal']['id'],substr($line,11,2));
               }
            if(!$val || $cde == "65" || $cde == "66") {
              // This is a confirmation message. We reformat it so that
              $confirm = 1;
                 }

            $val = hexdec($val);

            $cmd = isset($FHT_codes[$cde])?$FHT_codes[$cde]:"";
               if(!$cmd) {
                   $cmd= "(Unknown: $cde =>$val)";
                   $val="";
                   //continue;
                   goto fhtlog;
                 }

                 if( preg_match("/-from/",$cmd) || preg_match("/-to/",$cmd)) {
                   $val = sprintf("%02d:%02d", $val/6, ($val%6)*10);

                 } elseif($cmd == "mode") {
                   if(isset($c2m[$val])) $val = $c2m[$val] ;

                 } elseif(preg_match("/.*-temp/",$cmd)) {
                    $val=$val/2;
                   if ($cmd== "desired-temp") {
                      SetValue($varids['Soll']['id'],$val);
                   }
                   $val = sprintf("%.1f", $val);
                 } elseif($cmd == "lowtemp-offset") {
                   $val = sprintf("%d.0", $val);

                 } elseif(preg_match("/^actuator/",$cmd)) {
                    $id=substr($line,6,1);
                      $sval = substr($line,7,2);
                      $fv = sprintf("%d%%", (integer)(100*$val/255+0.5));

                 if(preg_match("/[AB]0/i",$sval)) { $val = $fv; }   # sync in the summer
                   elseif(preg_match("/.0/",$sval)) { $val = "syncnow"; }
                   elseif(preg_match("/.1/",$sval)) { $val = "99%"; } # FHT set to 30.5, FHT80B=="ON"
                   elseif(preg_match("/.2/",$sval)) { $val = "0%"; }  # FHT set to  5.5
                   elseif(preg_match("/.6/",$sval)) { $val = "$fv"; }
                   elseif(preg_match("/.8/",$sval)) { $val = "offset: $fv"; }
                   elseif(preg_match("/.A/",$sval)) { $val = "lime-protection"; }
                   elseif(preg_match("/.C/",$sval)) { $val = sprintf("synctime: %d", int($val/2)-1); }
                   elseif(preg_match("/.E/",$sval)) { $val = "test"; }
                   elseif(preg_match("/.F/",$sval)) { $val = "pair"; }
                   else { $val = "unknown_$sval: $fv"; }

                   $pos=strpos($val,"%");
                   if (! ($pos===false)) {
                         if ($id=="0") {
                        SetValue($varids['Position']['id'],$val);
                        }else{
                           $pid==getVid('Position'.$id,IPS_GetParent($varids['ID']['id']));
                                   if (! $pid==false) {
                                      SetValue($pid,$val);
                                   }
                              }
                }


                 } elseif($cmd == "measured-low") {

                   SetValue($varids['Low']['id'],$val);
                   //continue;
                   goto fhtlog;

                 } elseif($cmd == "measured-high") {

                  // if(defined($varids['Low']['val'])) {
                    $low=$varids['Low']['val'];
                $off =  0;
                $val = $val*256 + $low;
                $val /= 10;
                SetValue($varids['Temperatur']['id'],$val);
                    $val = sprintf("%.1f (Celsius)", $val+$off);
                $cmd = "measured-temp";


              } elseif($cmd == "warnings") {


                   # initialize values for additional warnings
                   # parse warnings
                   if($val & 1) {
                     $nVal  = "Battery low";
                     $nBattery = "low";
               }
                   if($val & 2) {
                     if($nVal) $nVal .= "; " ;
                  $nVal .= "Temperature too low";
                  $nLowTemp = "warn";
                   }
                   if($val &32) {
                     if($nVal) $nVal .= "; " ;
                     $nVal .= "Window open";
                     $nWindow = "open";
                   }
                   if($val &16) {
                     if($nVal) $nVal .= "; " ;
                     $nVal .= "Fault on window sensor";
                     $nSensor = "fault";
                   }

                   # set default values or new values if they were changed
                  $valBattery = isset($nBattery)? $nBattery : "ok";
                   $valLowTemp = isset($nLowTemp)? $nLowTemp : "ok";
                   $valWindow  = isset($nWindow)? $nWindow : "closed";
                   $valSensor  = isset($nSensor)? $nSensor : "ok";
                   $val = isset($nVal)? $nVal : "none";

                  # set additional warnings and trigger notify

                   $text.= " battery: $valBattery";
                  $text.= " lowtemp: $valLowTemp";
                   $text.= " window: $valWindow";
                   $text.= " windowsensor: $valSensor";
                   SetValue($varids['Warnings']['id'],"$val");
               }


         //finish
         fhtlog:
            if(substr($line,7,1) == "7") {        # Do not store FHZ acks.
              $cmd = "FHT:$cmd";
             $text.="
".$cmd;
            } else {
              //if($cmd == "measured-temp")
               $text.= " $cmd: $val" ;
               SetValue($varids['Status']['id'],"$cmd: $val");
            }
            //logging
            IPS_Logmessage($catname,$text);
          logge($fhtlog,"$line=>Dev $dev:".$text."
");
     }//if strlen
   }//if preg

//---------------------Wetter(WS300)-----------------------------------------
     elseif (preg_match("/^K[0-9A-F]{6,16}\s*\$/",$line)) {
               //K11245265,K41815177F4
               $tlist = array("0"=>"temp",
               "1"=>"temp/hum",
               "2"=>"rain",
               "3"=>"wind",
               "4"=>"temp/hum/press",
               "5"=>"brightness",
               "6"=>"pyro",
               "7"=>"temp/hum");
               $a=str_split($line);
               $len=strlen($line)-1; //last is cr
               $firstbyte = hexdec($a[1]);
               $typebyte=$a[2];
                 $cde = ($firstbyte&7);
                 $type = isset($tlist[$typebyte]) ? $tlist[$typebyte] : "unknown";
                 $typebyte=$typebyte & 7;
               $varids=null;
               $val="no data";


               $catname='WSCUL';
               $sensorname='WS ';
               $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                 'Signal'=>array('type'=>1,'profile'=>''),
                           'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
                           'Humidity'=>array('type'=>1,'profile'=>'~Humidity')
                                        );
               $varids=get_ips_vars($a[1],$vartypes,$catname,$sensorname);
               if (is_null($varids)) {
                  //no vars available, maybe autocreate disabled
                    continue;
               }
          if (($firstbyte&7)==7) {
            if($typebyte == 0 && $len > 6) {           # temp
                     $sgn = ($firstbyte&8) ? -1 : 1;
                     $tmp = $sgn * ($a[6].$a[3].".".$a[4]);
                     $val = "T: $tmp";
                     $hum=0;
                     SetValue($varids['Temperatur']['id'],$tmp);
                        SetValue($varids['Humidity']['id'],$hum);

              }

              if($typebyte == 1 && $len > 8) {           # temp/hum
                $sgn = ($firstbyte&8) ? -1 : 1;
                $tmp = $sgn * ($a[6].$a[3].".".$a[4]);
                //$hum = ($a[7].$a[8].".".$a[5]) ;
                $hum = ($a[7].$a[8]) ;
                $val = "T: $tmp  H: $hum";
                $devtype = "PS50";
                $family = "WS300";
                SetValue($varids['Temperatur']['id'],$tmp);
                   SetValue($varids['Humidity']['id'],$hum);
              }
              //signal
               if ( $len>9) {
                  SetSignal($varids['Signal']['id'],substr($line,19,2));

               }

            }else{
              if ($len < 12 ) {                 #  S300TH
                     $sgn = ($firstbyte&8) ? -1 : 1;
                     $tmp = $sgn * ($a[6].$a[3].".".$a[4]);
                     //$hum = ($a[7].$a[8].".".$a[5]);
               $hum = ($a[7].$a[8]) ;
                         $val = "T: $tmp  H: $hum";
                     $devtype = "S300TH";
                     SetValue($varids['Temperatur']['id'],$tmp);
                        SetValue($varids['Humidity']['id'],$hum);
                     //signal
                         if ( $len==11) {
                            SetSignal($varids['Signal']['id'],substr($line,9,2));

                         }
              } elseif($len > 13) {          # KS300/2

                $c =  255;
                $rain = sprintf("%0.1f", hexdec($a[14].$a[11].$a[12]) * $c / 1000);
                $wnd  = sprintf("%0.1f", $a[9].$a[10].$a[7] );
                $hum  = sprintf( "%02d", $a[8].$a[5]);
                $tmp  = sprintf("%0.1f", ($a[6].$a[3].$a[4]),
                             (($a[1] & 0xC) ? -1 : 1));
                $ir = ((hexdec($a[1]) & 2)) ? "yes" : "no";
                    SetValue($varids['Temperatur']['id'],$tmp);
                        SetValue($varids['Humidity']['id'],$hum);
                $val = "T: $tmp  H: $hum  W: $wnd  R: $rain  IR: $ir";
           }
           //signal
               if ( $len==15) {
                  SetSignal($varids['Signal']['id'],substr($line,15,2));
               }
      }
               $text="Dev $cde ($type): $val";
               IPS_Logmessage($catname,$text);
               logge($wslog,"$line (Len:$len)=>".$text."
");
          }//if preg
//--------------------HMS-------------------------------------------------------
          elseif (preg_match("/^H[0-9A-F]{12,14}\s*\$/",$line)) {
               //H37AE01240000
         $codes = array(
                      0 => "HMS100TF",
                      1 => "HMS100T",
                      2 => "HMS100WD",
                      3 => "RM100-2",
                      4 => "HMS100TFK", # Depending on the onboard jumper it is 4 or 5
                      5 => "HMS100TFK",
                      6 => "HMS100MG",
                      8 => "HMS100CO",
                      14 => "HMS100FIT"
               );

              $type = hexdec(substr($line,6,1));
              $stat = $type > 1 ? hexdec(substr($line,7,2)) : hexdec(substr($line,5,2));
              $prf  = $type > 1 ? "02" : "05";
              $bat  = $type > 1 ? hexdec(substr($line,5,1))+1 : 1;
              $dev = substr($line,1,4);
              $val = $type > 1 ?  "000000" : substr($line,7);
               $catname='HMSCUL';
               $sensorname='HMS ';
               //if (!isset($sensorname)) $sensorname='HMS ';
               switch ($type) {
                  case 0://TF
                              $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                       'Signal'=>array('type'=>1,'profile'=>''),
                                       'Type'=>array('type'=>3,'profile'=>''),
                           'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
                           'Humidity'=>array('type'=>1,'profile'=>'~Humidity'),
                           'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
                                        );
                                        break;
                  case 1://T
                              $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                       'Signal'=>array('type'=>1,'profile'=>''),
                                       'Type'=>array('type'=>3,'profile'=>''),
                           'Temperatur'=>array('type'=>2,'profile'=>'~Temperature'),
                           'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
                                        );
                                        break;
                  case 4://TFK Switch1
                  case 5://TFK Switch2
                        $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                       'Signal'=>array('type'=>1,'profile'=>''),
                                       'Type'=>array('type'=>3,'profile'=>''),
                                 'Kontakt'=>array('type'=>0,'profile'=>'~Switch'),
                                 'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
                                        );
                                        break;

                  case 2://WD
                  case 3://RM100
                    case 6://Gas MG
                  case 8://Gas CO
                  case 14://FIT
                        $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                          'Signal'=>array('type'=>1,'profile'=>''),
                                       'Type'=>array('type'=>3,'profile'=>''),
                                 'Alarm'=>array('type'=>0,'profile'=>'~Alert'),
                                 'Battery'=>array('type'=>0,'profile'=>'~Battery.Reversed')
                                        );
                                        break;

                  default://type not known
                          IPS_LogMessage($catname,"Unknown type: $type");
                                        continue 2;
               }
               $varids=null;
               $varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
               if (is_null($varids)) {
                  //no vars available, maybe autocreate disabled
                    continue;
               }

               SetValue($varids['Battery']['id'],($bat==1));
               if (! ($varids['Type']['val']) == $codes[$type]) {
                    SetValue($varids['Type']['id'],$codes[$type]);
               }
               switch($type) {
                  case 0: //TF
                  # Codierung <t1><t0><f0><t2><f2><f1>
                              $hum=(Integer)(substr($val, 4, 2).substr($val, 2, 1))/10;
                                   SetValue($varids['Humidity']['id'],$hum);
                    case 1://T
                          $tmp=(substr($val, 3, 1).substr($val, 0, 2))/10;
                          if (($stat & 128)>0) $tmp=-$tmp;
                              SetValue($varids['Temperatur']['id'],$tmp);
                              break;
                    case 2:
                    case 3:
                    case 6:
                    case 8:
                    case 14: SetValue($varids['Alarm']['id'],($stat>0));
                                   break;
                    case 4:
                    case 5: SetValue($varids['Kontakt']['id'],($stat>0));
                                   break;
                    default:
                       IPS_LogMessage($catname,"Type $type for Dev $HA not known");
                       break;
               }
               //signal
               if ( strlen($line)>13) {
                    SetSignal($varids['Signal']['id'],substr($line,13,2));
               }
         $text="Dev $dev ($type:".$codes[$type]."): Stat:$stat, Bat: $bat Val: $val";
               IPS_Logmessage($catname,$text);
               logge($hmslog,"$line =>".$text."
");

          }//if preg

          //--------------------ESA-------------------------------------------------------
          elseif (preg_match("/^S[0-9A-F]{32,34}\s*\$/",$line)) {
  # definitions taken from FHEM 64_ESA2000.pm
  # S6E003D011E00037650001102C1DA07D01D
  # S 6E 003D 011E 00037650 0011 02C1DA 07D0 1D
  #              1           2           3
  # 0 12 3456 7890 12345678 9012 345678 9012 34
  # seqno        =  number of received datagram in sequence mod 128(repeated if seqno/128 >0)
  # code         =  device code
  # type           = type of sensor: 011E: ESA1000-WZ, ...
  # total_cnt    =  total (cumulated) value in ticks as read from the device
  # 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)
         $codelist = array(
                      "003D" => "ESA1000-S0",
                      "0055" => "ESA1000-S0",
                      "44C7" => "ESA2000_LED",
                      "0178" => "ESA2000_LED",
                      "0595" => "ESA1000GAS",
                      "01FA" => "ESA2000_LED"
               );
          $tlist=array("011E"=>"ESA1000-WZ");

              $seqno= hexdec(substr($line,1,2))%128;
              $code = substr($line,3,4);
              $type = substr($line,7,4);
               $dev=$code."-".$type;
              $total_cnt=hexdec(substr($line,11,8));
              $current_cnt=hexdec(substr($line,19,4));
              $timestamp=hexdec(substr($line,23,6));
              //$ticks=hexdec(substr($line,29,4));
               $ticks=hexdec(substr($line,29,4)) ^ hexdec(substr($line,3,2));
               $catname='Strom';
               $sensorname = isset($codelist[$code]) ? $codelist[$code] : "ESA ";
               $varids=null;
               $vartypes=array(  'ID'=>array('type'=>3,'profile'=>''),
                                 'Signal'=>array('type'=>1,'profile'=>''),
                                   'total'=>array('type'=>1,'profile'=>''),
                               'current'=>array('type'=>1,'profile'=>''),
                               'ticks'=>array('type'=>1,'profile'=>'')
                                        );
               $varids=get_ips_vars($dev,$vartypes,$catname,$sensorname);
               if (is_null($varids)) {
                  //no vars available, maybe autocreate disabled
                    continue;
               }
               SetValue($varids['total']['id'],$total_cnt);
               SetValue($varids['current']['id'],$current_cnt);
               SetValue($varids['ticks']['id'],$ticks);
               //signal
               if ( strlen($line)>32) {
                    SetSignal($varids['Signal']['id'],substr($line,33,2));
               }
              $text="Dev $dev : Tot:$total_cnt, Cur: $current_cnt Ticks: $ticks";
               IPS_Logmessage($catname,$text);
               logge($esalog,"$line =>".$text."
");

          }//if preg
          #-----------unknown/unimplemented cul message------
          elseif (! preg_match("/^\s*$/",$line)) {

                  IPS_Logmessage('CUL','MSG:'.$line);
                  setValue($lmid,$line);
             }
     }//foreach
}//if  sender

//-------------------------------------------------------------------------------

/**
* IPS Variablen handler
* creates variables as needed
* returns assoc. Array with IPS Variable ID and Value
* @param integer Sensor Address
* @param array Array with Variable Names, Types and Profiles
* @param string Sensor Group Master Categorie Name
* @param string Sensor default name, will be extended with $addr
*/
function get_ips_vars($addr,$vartypes,$cat,$sens) {

     $varids=null;

     $master=@IPS_GetObjectIDByName($cat,0);
     //no master cat, create new
     if (!$master) {
        $master=IPS_CreateCategory();
        IPS_SetName($master,$cat);
        IPS_SetParent($master,0);
          if ($master>0) {
             IPS_LogMessage('CUL', "Master category created, ID=$master
");
        }else{
               IPS_LogMessage('CUL', "Can't create Master Category
");
               return null;
          }
     }

  $id=0;
  if ($master>0) {
  //get chilren sensors
   $Sensors=IPS_GetChildrenIDs($master);
   foreach($Sensors as $sid) {
        $name=IPS_GetName($sid);
      //print "$sid:".$name."
";
          //get vars for each sensor
          $vars=IPS_GetChildrenIDs($sid);
      foreach($vars as $vid) {
       $obj=IPS_GetObject($vid);
         $vname=$obj['ObjectName'];
         $typ=$obj['ObjectType'];
         if ($typ==2) { //Variable
              //if ID, here is the address
              if ($vname="ID") {
                   $i=GetValue($vid);
                   //go out if matches, $id returns the sensor categorie id
                   if ($i===$addr) {
                      $id=$sid;
                      break;
                   }
              }
         }
      }
      if ($id>0) break;
   }
     if ($id==0) {
          //Sensor with address $addr not found in IPS
          if ($GLOBALS['autocreate']==false) {
               //autocreate disable, ignore new device
               return null;
          }
          //create new sensor
        $id=ips_createCategory();
        ips_setName($id,$sens.' '.$addr);
        ips_setParent($id,$master);
          //creates all needed variables for the new sensor
          foreach (array_keys($vartypes) as $name) {
           $typ=$vartypes[$name]['type'];
         $profile=$vartypes[$name]['profile'];
               $vid=IPS_CreateVariable($typ);
               ips_setname($vid,$name);
               ips_setParent($vid,$id);
         IPS_SetVariableCustomProfile($vid,$profile);
               //preload variables
               SetValue($vid,0);
         $varids[$name]['id']=$vid;
         $varids[$name]['val']=0;
         //Store address in $ID for next time
         if ($name=='ID') {
              SetValue($vid,$addr);
              $varids[$name]['val']=$addr;
               }
          }
     }else{
        //found matching cat, collect ids and vals for this sensor
        $vars=IPS_GetChildrenIDs($id);
      foreach($vars as $vid) {
         $obj=IPS_GetObject($vid);
         $name=$obj['ObjectName'];
         $typ=$obj['ObjectType'];
         if ($typ==2) { //Variable
              $val=GetValue($vid);
              $varids[$name]['id']=$vid;
              $varids[$name]['val']=$val;
         }

      }

     }
     //returns IDs and Values of this Sensor, Name is Key
     return $varids;
     }
}
//#############################
//
/**
* converting CUL Hex IDs into ELV-4-Ids
* translated from 10_fs20
* @param string $v Hex-Value
* @returns string ELV-ID
*/
function hex2four($v){
  $r = "";
  foreach  (str_split($v) as $x) {
    $r .= sprintf("%d%d", (hexdec($x)/4)+1, (hexdec($x)%4)+1);
  }
  return $r;
}

//#############################
/**
* do simple logging
* @param string $logfile Filename for logfile
* @param string $text
* @returns void
*/

function logge($logfile,$text) {
     if (strlen($logfile)>0) {
          $log=fopen($logfile,"a+");
          if ($log) {
             $d=date("r");
               fwrite($log,"$d $text");
               fflush($log);
               fclose($log);
          }
     }
}
/**
* Get ID by name if exists, else create
* @Param String Name
* @param integer Parent-ID
* @param integer Variable Typ (0..3)
* @return integer ID
*/
function getVid($name,$par,$typ) {
     $vid = @IPS_GetVariableIDByName($name, $par);
     if ($vid === false) {
          $vid=IPS_CreateVariable($typ);
          ips_setname($vid,$name);
          ips_setParent($vid,$par);
          setValue($vid,'');
     }
     return $vid;
}
/**
* set signal strange (in dB)
* @Param Integer ID Signal Variable
* @param String Hex-Byte
*/

function setSignal($sid,$hex) {
     $rssi=hexdec($hex);
   if ($rssi>=128)  {
          $rssi=(($rssi-256)/2)-74;
     } else {
          $rssi=($rssi/2)-74;
     }
     $rssi=intval($rssi);
     //IPS_Logmessage('CUL',"Signal: $rssi ($hex) Id $sid");
   setValue($sid,$rssi);
}

?>

Screenshots:


Hallo zusammen,

hat jemand vielleicht schon seine FHT Komponenten mit den CuxD Skripten von Tommi laufen? Meine FS20 Komponenten habe ich bereits angebunden. Fehlen mir eigentlich „nur noch“ meine FHTs.

Wenn ich es richtig verstanden habe, werden die Daten von den FHTs zwar empfangen, man kann aber - ohne weiteres - nichts senden.

Falls doch: Hat jemand vielleicht einen Tipp für mich?

Hallo Specky,

ich habe seit langem einen FHT Stellmotor (von insgasmt vier) mit dem CUNO laufen. Im Prinzip funktioniert es, ist aber sehr aufwendig einzurichten.

Joachim

Hi Joachim,

ich danke dir für deine schnelle Antwort. Die Stellmotoren möchte ich eigentlich nicht direkt steuern, lieber das jeweilige Raumthermostat.

Wie steuerst du denn die Stellmotoren an?

Specky

Hallo Specky,

die Ist-Temperatur wird via 1-Wire-Sensoren gemessen, wird dann in einem Software-PID-Regler im IPS verarbeitet und an den Stellmotor gesendet.
Die FHT-Steuergeräte fand ich nicht so richtig schön, die Einstellungen erfolgen über iFront bzw. Webfront, dieses ist aber nicht sonderlich oft notwendig da im Hintergrund eine detaillierte Wochen- bzw. Tagesverlauf den jeweiligen Sollwert vorgibt.
Wenn es Dich interessiert, stelle ich gerne die dafür benötigten Skripte zur Verfügung…

Joachim

Hallo Joachim,

vielen Dank für dein Angebot! Da ich aber diverse FHT80b einsetze, habe ich mir aus Tommis CUL_FS20Send Skript ein CUL_FHTSend Skript gebastelt. Mit dem Ergebnis bin ich nun ich recht zufrieden.

Specky

Hallo Specky,

ich bin auch auf der Suche nach einem Skript zum Senden der FHT-Befehle und habe gerade deinen Eintrag gelesen:

Würdest du mir/uns dein Skript zur Verfügung stellen?

Gruß
Anderle

Hallo Anderle,

da es schon wieder etwas her ist, kann ich nicht mehr genau sagen, was alles zu tun ist, um die Skripte ans Laufen zu bekommen. Habt also Nachsicht mit mir…

Das Skript „CULFHTSEND“ wird bei Variablenaktualisierung der folgenden Variablen aufgerufen:

[ul]
[li]Soll modus (Ausstehend)
[/li][li]Soll Temperatur (Ausstehend)
[/li][li]Soll
[/li][/ul]

Sie finden sich unter den jeweiligen, automatisch generierten FHTCUL Einträgen. Ich glaube, ich habe die Namen nachträglich geändert, bzw. selbst angelegt.

CULFHTSEND

<?php
/**
* CUN/CUL FHTEvent Script,
* Add as OnChange EventHandler to "Soll Modus (Ausstehend)", "Soll Temperatur (Ausstehend)" and "Soll" Variable
* @package CUN
*/

//Regvar-Instance to Clientsocket
$reg=44167 /*[CUL Serial Port\CUL Register Variable]*/;
if (!IPS_InstanceExists($reg)) {
			print "Instance with ID $reg doesnt exists";
			return;
}
$inst=IPS_GetInstance($reg);
$ityp=$inst['ModuleInfo']['ModuleName'];
if ($ityp!="Register Variable") {
			print "Instance $reg is not a 'Register Variable' Instance";
			return;
}
//Status change
// http://fhz4linux.info/tiki-index.php?page=FHT+protocol
// CC 3E Modus
// CC 41 Temperatur


if (($IPS_SENDER == "Variable") || ($IPS_SENDER == "WebFront"))
{
	$me = $IPS_VARIABLE;
	$name = IPS_GetName($me);
	$fht = IPS_GetParent($me);
	$fhtname = IPS_GetName($fht);
	$fhtid = IPS_GetObjectIDByName("ID", $fht);
	$fhtsoll = GetValueFloat(IPS_GetObjectIDByName("Soll", $fht));
	
	switch ($name) {
		case "Soll Modus (Ausstehend)":$val="3E" . sprintf("%02X", $IPS_VALUE);break;
		case "Soll Temperatur (Ausstehend)":
		   if ($IPS_VALUE <> $fhtsoll) {
				$val="41" . sprintf("%02X", $IPS_VALUE * 2);
			break;
			} else {
				return;
			}
		case "Soll":SetValueFloat(IPS_GetObjectIDByName("Soll Temperatur (Ausstehend)", $fht), $fhtsoll);return;
		default: print "Unknown Name $name"; return;
	}
	
	if ($fhtid == false) {
		$addr=FHT_GetAddress($fht);
      $hc = sprintf("%02X", substr($addr, 0, 2)) . sprintf("%02X", substr($addr, 2, 2));
		IPS_LogMessage("FHTCUL","Adresse: " . $addr . " - " . $hc);
	} else {
	   $hc = GetValueString($fhtid);
	}
	
	$cul='T'.$hc.$val;
	IPS_LogMessage("FHTCUL","Send ($name)$fht ($fhtname) -> $hc ($val)=$cul");
	RegVar_SendText($reg, $cul . "
");
	
} else {
	print "Sender not Variable or WebFront";
}
//#############################
/**
* converting ELV IDs into CUL Hex-Ids
* translated from 10_fs20
* @param string $v ELV ID
* @returns string Hex- Value
*/

function four2hex($v){

  $r = 0;
  foreach  (str_split($v) as $x) {
    $r = $r*4+($x-1);
  }
  $out="";
  $len=strlen($v);
  switch ($len) {
   case 4:$out=sprintf("%02X",$r);break;
   case 8:$out=sprintf("%04X",$r);break;
	}
  return $out;
}

?>

Hallo Specky,

super - danke!

Hat mir sehr geholfen und ist jetzt schon erfolgreich im Einsatz :slight_smile:

Hab das Skript auf meine Variablennamen angepaßt und das Rücklesen des Modes vom Thermostat eingefügt.
Hier meine Änderungen:

<?php
/**
* CUN/CUL FHTEvent Script,
* Add as OnChange EventHandler to "Soll Modus (Ausstehend)", "Soll Temperatur (Ausstehend)" and "Soll" Variable
* @package CUN
*/

//Regvar-Instance to Clientsocket
$reg=49017 /*[Hardware\CUL\Register Variable]*/ ;
if (!IPS_InstanceExists($reg)) {
			print "Instance with ID $reg doesnt exists";
			return;
}
$inst=IPS_GetInstance($reg);
$ityp=$inst['ModuleInfo']['ModuleName'];
if ($ityp!="Register Variable") {
			print "Instance $reg is not a 'Register Variable' Instance";
			return;
}

//Status change
// http://fhz4linux.info/tiki-index.php?page=FHT+protocol
// CC 3E Modus
// CC 41 Temperatur

if (($IPS_SENDER == "Variable") || ($IPS_SENDER == "WebFront"))
{
	$me = $IPS_VARIABLE;
	$name = IPS_GetName($me);
	$fht = IPS_GetParent($me);
	$fhtName = IPS_GetName($fht);
	$fhtID = IPS_GetObjectIDByName("ID", $fht);
	$fhtModeActive = GetValueInteger(IPS_GetObjectIDByName("ModeActive", $fht));
	$fhtSetValueActive = GetValueFloat(IPS_GetObjectIDByName("TemperatureSetActive", $fht));
	
	switch ($name) {
		case "ModePending":
			if ($IPS_VALUE <> $fhtModeActive) {
				$val="3E".sprintf("%02X", $IPS_VALUE);
				break;
			} else {
				return;
			}
			break;
		case "TemperatureSetPending":
		   if ($IPS_VALUE <> $fhtSetValueActive) {
				$val="41".sprintf("%02X", $IPS_VALUE * 2);
				break;
			} else {
				return;
			}
		case "ModeActive":
			SetValueInteger(IPS_GetObjectIDByName("ModePending", $fht), $fhtModeActive);
			return;
		case "TemperatureSetActive":
			SetValueFloat(IPS_GetObjectIDByName("TemperatureSetPending", $fht), $fhtSetValueActive);
			return;
		default:
			print "Unknown Name $name";
			return;
	}

	if ($fhtID == false) {
		$addr=FHT_GetAddress($fht);
      $hc = sprintf("%02X", substr($addr, 0, 2)) . sprintf("%02X", substr($addr, 2, 2));
		IPS_LogMessage("FHTCUL","Adresse: ".$addr." - ".$hc);
	} else {
	   $hc = GetValueString($fhtID);
	}

	$cul='T'.$hc.$val;
	IPS_LogMessage("FHTCUL","Send ($name) $fht ($fhtName) -> $hc ($val)=$cul");
	RegVar_SendText($reg, $cul."
");

} else {
	print "Sender not Variable or WebFront";
}
//#############################
/**
* converting ELV IDs into CUL Hex-Ids
* translated from 10_fs20
* @param string $v ELV ID
* @returns string Hex- Value
*/

function four2hex($v){

  $r = 0;
  foreach  (str_split($v) as $x) {
    $r = $r*4+($x-1);
  }
  $out="";
  $len=strlen($v);
  switch ($len) {
   case 4:$out=sprintf("%02X",$r);break;
   case 8:$out=sprintf("%04X",$r);break;
	}
  return $out;
}

?>

Du hast im Code den folgenden Link als Befehlsreferenz angegeben: http://fhz4linux.info/tiki-index.php?page=FHT%20protocol

Dort finde ich aber nur Befehle zwischen Thermostat und Stellantrieb/Ventil - oder übersehe ich hier was?
Welche Befehle gibt es denn noch für die Thermostate (Update aller Variablen anfordern, Zeitplan hinterlegen etc.)?

Gruß
Anderle

Hi Anderle,

schön, dass es bei dir funktioniert. Deine Änderungen werde ich sicherlich auch noch (irgendwann) integrieren. Habe halt z.Z. andere Baustellen…

Ich kann leider auch nicht mehr sagen, wo ich die Befehle für das FHZ-Protokoll weg hatte. Ich bin immer mal wieder auf der Suche, wie man die Uhrzeit über CUL setzen kann.

Falls du da was weißt, lass mich gerne teilhaben.

Besten Gruß,

Specky