kontinuierliche Temperaturausgabe mit MAX-Thermostaten

Begonnen von Zwer2k, 26 Februar 2013, 01:03:14

Vorheriges Thema - Nächstes Thema

Zwer2k

Hallo zusammen,

hab mal ein Script erstellt mit dem man kontinuierliche Temperaturausgabe und somit saubere Plots bekommt.
Verlauf der Solltemperatur und Ventilposition werden in Plots nicht beeinflusst.

So sieht es dann aus:

(siehe Anhang / see attachement)


Funktionsbeschreibung:
Immer wenn der "mode" Verändert wird geben die Thermostate nach Zeit die zwischen 1 Sek. und 2 Min. sein kann (je nach dem wann "mode" verändert worden ist) die IST-Temperatur aus.
Der Script schaltet in bestimmten Zeitabständen die Thermostate von "auto" in "manual" und nach 10 Sek. wieder zurück.
Da die Thermostate die Temperatur immer zu einem festen Zeitpunkten ausgeben, kann der nächste Zeitpunkt berechnet und dadurch der Umschaltvorgang auf 10Sek. verkürzt werden.  

Im Array @MaxThermostate Thermostate die ihre Themperatur ausgeben sollen angeben.
Mit $Interval wird Zeitabstand in Min. angegeben.

In die fhem.cfg einfügen:

define at_ForceMAXTempUpdate at +*00:00:10 { \
 my @MaxThermostate = ("bu_Thermostat", "bo_Thermostat");;\
 my $Interval = 15;
 &ForceMAXTempUpdate($Interval, \@MaxThermostate);;\
}



Jetzt noch folgendes in die 99_myUtils.pm eintragen.

Ganz oben in der Datei:

use Time::Piece;
use DateTime;
use constant TIMEZONE => "Europe/Berlin";
$main::NextUpdate = ();


Danach wird die Subroutine eingetragen:

sub ForceMAXTempUpdate {
 my $UpdateInterval = $_[0];
 my @UpdateThermostat =  @{$_[1]};

 $UpdateInterval++ if ($UpdateInterval % 2 != 0);
 foreach my $therm (@UpdateThermostat) {
  my $curTime = DateTime->now(time_zone=>TIMEZONE);
  if ((!defined($main::NextUpdate{$therm}{"NextUpdate"})) || ($curTime>$main::NextUpdate{$therm}{"NextUpdate"})){
   my $th_time = $defs{$therm}{READINGS}{"temperature"}{TIME};
   my $th_val = $defs{$therm}{READINGS}{"desiredTemperature"}{VAL};
   my $th_mode = $defs{$therm}{READINGS}{"mode"}{VAL};
   my $tempTime=Time::Piece->strptime($th_time, "%Y-%m-%d %H:%M:%S");
   $tempTime = DateTime->from_epoch(epoch=>$tempTime->epoch,time_zone=>TIMEZONE);
   $tempTime->subtract(seconds => $tempTime->offset);
   my $nextUpd = $tempTime->clone;
   $nextUpd->add(seconds=>$UpdateInterval*60-15);
   while($curTime->epoch > $nextUpd->epoch){
    $nextUpd->add(minutes=>2);
   }
   if (defined($main::NextUpdate{$therm}{"NextUpdate"})){
    if (!defined($main::NextUpdate{$therm}{"Started"})){
     if (($th_mode eq "auto") || ($th_mode eq "manual")){
      fhem("set ".$therm." desiredTemperature ".($th_mode eq "manual" ? "auto" : "")." ".$th_val);
      $main::NextUpdate{$therm}{"Started"} = $curTime;
      $main::NextUpdate{$therm}{"temp"} = $th_val;
      $main::NextUpdate{$therm}{"mode"} = $th_mode;
     }
    } else {
     if ($tempTime > $main::NextUpdate{$therm}{"Started"}){
      if ($th_mode eq ($main::NextUpdate{$therm}{"mode"} eq "auto" ? "manual" : "auto")){
       fhem("set ".$therm." desiredTemperature ".($main::NextUpdate{$therm}{"mode"} eq "auto" ? "auto " : "").$main::NextUpdate{$therm}{"temp"});
      }
      undef $main::NextUpdate{$therm}{"Started"};
      $main::NextUpdate{$therm}{"NextUpdate"} = $nextUpd;
     }
    }
   } else {
    $main::NextUpdate{$therm} = ();
    $main::NextUpdate{$therm}{"NextUpdate"} = $nextUpd;
   }
   $main::NextUpdate{$therm}{"CurTime"} = $curTime;
  }
 }
}

Marvin

Das sieht ja mal richtig gut aus, so in der Richtung hatte ich mir auch was überlegt, aber auf Grund anderer Probleme noch nicht weiter verfolgt.
Das einzige was ich vielleicht problematisch finde ist, das wenn man viele Thermostate hat doch ziemlich viel Funkverkehr Auftritt.
Oder ist das kein Problem?

Marvin

Matthias Gehre

Angeheftet. Allerdings habe ich etwas Bedenken wegen der Batterielaufzeit.

Zwer2k

Zitat von: Marvin schrieb am Di, 26 Februar 2013 05:38Das sieht ja mal richtig gut aus, so in der Richtung hatte ich mir auch was überlegt, aber auf Grund anderer Probleme noch nicht weiter verfolgt.
Das einzige was ich vielleicht problematisch finde ist, das wenn man viele Thermostate hat doch ziemlich viel Funkverkehr Auftritt.
Oder ist das kein Problem?
Wenn ich den Aktualisierungsinterval für meine zwei Thermostate auf 4 Minuten runter setze bekomme ich Tatsächlich "Not enough credit". Es funken allerdings auch noch ein Wandthermostat alle 3 Min. und zwei weitere Heizkörperthermostate alle 6 Min. ihre Daten an CUL, dass allerdings ohne Hilfe von dem Script. Da muss CUL nur empfangen, keine Ahnung ob es sich auch auf Credits auswirkt, vermutlich aber schon. Bei einem Intervall ab 6 Min. scheint es problemlos zu funktionieren.

ZitatAllerdings habe ich etwas Bedenken wegen der Batterielaufzeit.
Wegen Batterielaufzeit hatte ich auch bedenken. Hab dann festgestellt, dass die Heizkörperthermostate die an einem Wandthermostat hängen auch schon alle 6 Min. mit dem kommunizieren. Dürfte denke ich nicht zu viel ausmachen, das meiste wird sicherlich der Antrieb verbrauchen.

Marvin

So wie ich das verstanden habe geht es bei den Credits nur ums Senden des CUL.

Aber ich denke, das selbst ein 15-30 min Intervall für eine gut erkennbare IST Temperatur ausreichend ist.
Solange die auto/manuell Umschaltung nicht zum agieren des Stellmotors führt, bin ich ganz deiner Meinung Jurij, das es sich nicht wirklich auf die Batterielebensdauer auswirk.
Sonst müsste ein Hinweis in der Bedienungsanleitung stehen, das bei gepairten Geräte sich die Lebensdauer der Batterien verkürzt.

Marvin

Joachim

Moin Jurij,

könntest du das auch Fritzbox-verträglich, also ohne DateTime.

das wäre super

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

Zwer2k

Zitat von: Joachim schrieb am Di, 26 Februar 2013 19:13könntest du das auch Fritzbox-verträglich, also ohne DateTime.
Eigentlich war genau das mein Ziel, Script sollte auf meiner FB7390 laufen, hab allerdings noch Freetz drauf. Die DateTime.pm wird aber bei der 7390 mit FHEM mitinstalliert. Du verwendest wie ich sehe FB7570 gibt es da eventuell Unterschiede bei FHEM.

Hab etwas gebraucht nach dem Parsen der Zeit mit Time::Piece->strptime($th_time, "%Y-%m-%d %H:%M:%S"); die Zeit mit richtigen Zeitzone zu versehen um die anschließend mit der aktuellen Zeit vergleichen zu können. Wenn jemand eine Idee hat wie es ohne DateTime hinzukriegen ist, dann könnte ich den Script anpassen.
Das hier Time::Piece->strptime($th_time, "%Y-%m-%d %H:%M:%S", "Europe/Berlin"); funktioniert leider nicht.

langerhannes

Hallo Jurij,

ich habe es sowie von Dir beschrieben installiert, aber es funzt nicht!
Ich erhalte folgende Fehlermeldung im Logfile:

Zitat2013.02.26 19:16:45 5: Triggering global (1 changes)
2013.02.26 19:16:45 5: Notify loop for global DELETED at_ForceMAXTempUpdate
2013.02.26 19:16:45 5: redefine at command at_ForceMAXTempUpdate as +*00:00:10 { \
 my @MaxThermostate = ("HK_Bad");\
 my $Interval = 15
2013.02.26 19:16:45 5: Triggering global (1 changes)
2013.02.26 19:16:45 5: Notify loop for global DEFINED at_ForceMAXTempUpdate
2013.02.26 19:16:55 5: exec at command at_ForceMAXTempUpdate
2013.02.26 19:16:55 5: Cmd: >{ \
 my @MaxThermostate = ("HK_Bad")<
2013.02.26 19:16:55 5: Cmd: >my $Interval = 15<
2013.02.26 19:16:55 3: Unknown command {, try help
Unknown command my, try help

Wo steckt mein Fehler?

Gruß

langerhannes
FHEM CUL FS20 auf Fritz 7390

MAX Thermostat und Fensterkontakt
Alarmanlage mit MAX Fensterkontakten

Joachim

Moin langerhannes,

Es ist nicht Dein Fehler, sondern der Fehler von Jurij

ändere mal den Eintrag in der fhem.cfg um

define at_ForceMAXTempUpdate at +*00:00:10 {\
 my @MaxThermostate = ("HK_Regler_Badezimmer", "HK_Regler_Buero");;\
 my $Interval = 15;;\
 &ForceMAXTempUpdate($Interval, \@MaxThermostate);;\
}

also ein ;\ hinter my $Interval = 15; zusätzlich, dann sollte es laufen.

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

langerhannes

FHEM CUL FS20 auf Fritz 7390

MAX Thermostat und Fensterkontakt
Alarmanlage mit MAX Fensterkontakten

Zwer2k

Ooops, da habe ich was vergessen. Danke Joachim.


Falls noch jemand Probleme mit DateTime hat, hier aktuelle Version die ohne auskommt. Hat noch paar kleine Verbesserungen.


In die fhem.cfg einfügen: (hier noch keine Änderungen)
define at_ForceMAXTempUpdate at +*00:00:10 {\
my @MaxThermostate = ("HK_Regler_Badezimmer", "HK_Regler_Buero");;\
my $Interval = 15;;\
&ForceMAXTempUpdate($Interval, \@MaxThermostate);;\
}




Folgendes in die 99_myUtils.pm eintragen. (hier hat sich einiges geändert)

Ganz oben in der Datei:
use Time::Piece;
$main::NextUpdate = ();



Und die Subroutine:
sub ForceMAXTempUpdate {
  my $UpdateInterval = $_[0];
  my @UpdateThermostat =  @{$_[1]};

  $UpdateInterval++ if ($UpdateInterval % 2 != 0);
  foreach my $therm (@UpdateThermostat) {
    my $curTime = gmtime() + localtime()->tzoffset;
    if ((!defined($main::NextUpdate{$therm}{"NextUpdate"})) || ($curTime>$main::NextUpdate{$therm}{"NextUpdate"})){
      my $th_time = $defs{$therm}{READINGS}{"temperature"}{TIME};
      my $th_val = $defs{$therm}{READINGS}{"desiredTemperature"}{VAL};
      my $th_mode = $defs{$therm}{READINGS}{"mode"}{VAL};
      my $tempTime=Time::Piece->strptime($th_time, "%Y-%m-%d %H:%M:%S");
      my $nextPlan = $tempTime + $UpdateInterval * 60 - 15;
      my $nextUpd = $nextPlan;
      $nextUpd = $nextUpd + 60 * 2 while($curTime->epoch > $nextUpd->epoch);

      if (defined($main::NextUpdate{$therm}{"NextUpdate"})){
        if (!defined($main::NextUpdate{$therm}{"Started"})){
          if ($nextPlan > $main::NextUpdate{$therm}{"NextUpdate"}) {
            $main::NextUpdate{$therm}{"NextUpdate"} = $nextUpd;
            return;
          }
          if (($th_mode eq "auto") || ($th_mode eq "manual")){
            fhem("set ".$therm." desiredTemperature "
                 .($th_mode eq "manual" ? "auto" : "")." ".$th_val);
            $main::NextUpdate{$therm}{"Started"} = $curTime;
            $main::NextUpdate{$therm}{"temp"} = $th_val;
            $main::NextUpdate{$therm}{"mode"} = $th_mode;
          }
        } else {
          my $oldMode = $main::NextUpdate{$therm}{"mode"};
          my $oldTemp = $main::NextUpdate{$therm}{"temp"};
          if ($tempTime > $main::NextUpdate{$therm}{"Started"}){
            if (($th_mode eq ($oldMode eq "auto" ? "manual" : "auto")) && ($th_val eq $main::NextUpdate{$therm}{"temp"})){
              fhem("set ".$therm." desiredTemperature ".($oldMode eq "auto" ? "auto " : "").$oldTemp);
            }
            undef $main::NextUpdate{$therm}{"Started"};
            $main::NextUpdate{$therm}{"NextUpdate"} = $nextUpd;
          } else {
            if ($curTime > $main::NextUpdate{$therm}{"Started"} + 60 * 4) {
              fhem("set ".$therm." desiredTemperature ".($oldMode eq "auto" ? "auto " : "").$oldTemp);
              undef $main::NextUpdate{$therm}{"Started"};
              $main::NextUpdate{$therm}{"NextUpdate"} = $nextUpd;
            }
          }
        }
      } else {
        $main::NextUpdate{$therm} = ();
        $main::NextUpdate{$therm}{"NextUpdate"} = $nextUpd;
      }
      $main::NextUpdate{$therm}{"CurTime"} = $curTime;
    }
  }
}


Joachim

Super, Danke

Bin am Testen

Gruß Joachim

Fehlermeldung:
Wenn man wie ich es immer bei Änderungen mache,
das fhem.log unddie fhem.save löscht, dann blockiert Dein Script FHEM, und meine Fritzbox geht auf 99%
FHEM-Last.
Das Problem scheint in dieser Zeile zu liegen:

--> $nextUpd = $nextUpd + 60 * 2 while($curTime->epoch > $nextUpd->epoch);

ein davor eingetragenes Log 3, "blabla"; wird abgearbeitet, ein danach eingetragenes Log 3, "blabla"; wird nicht
abgearbeitet.
Da ich Deinen Code noch nicht wirklich verstanden habe, kann ich nur die Vermutung aussprechen, dass der zu
diesem Zeitpunkt noch fehlende Zeitstempel (2013-02-28 16:41:02 MAX HK_Regler_Flur temperature: 17.9
was falsches in $th_time schreibt.

ich beobachte das weiter, aber vielleicht kannst Du das mal gegenchecken.

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

Zwer2k

Hallo Joachim,

was steht bei dem Thermostat in der FHEM Oberfläche unter Readings. Gibt es da ein Messwert für "temperature" und passende Zeit? Wenn ja dann sollte es ausreichend sein.

Mit einem Wandthermostat ist der Heizkörperthermostat nicht zufällig gekoppelt?
Gekoppelte Thermostate geben keine Ist-Temperatur aus. In der Logdatei von dem Thermostat sollte spätestens nach 2 Min. nach manuellen Umstellung von auto auf manuell Ist-Temperatur auftauchen.

Ansonsten schau mal was in beiden Variablen $therm, $curTime und $nextUpd steht.

Log (1, $therm."-".$curTime."-".$nextUpd);
Vor der Zeile
$nextUpd = $nextUpd + 60 * 2 while($curTime->epoch > $nextUpd->epoch);
einfügen.

Alle 3 sollte was enthalten.

Joachim

Moin Jurij,

Wahrscheinlich hatte ich mich nicht klar ausgedrückt,

Das Problem taucht nur auf, wenn FHEM neu gestartet wird, und man vorher die fhem.save gelöscht hat.
Zu diesem Zeitpunkt gibt es dann noch kein temperature Meßwert, und damit bleibt FHEM an der beschriebenen Stelle
stehen.
Wenn man nach dem Löschen der fhem.save ersteinmal die Einträge
> define at_ForceMAXTempUpdate at +*00:00:10 {\
> my @MaxThermostate = ("HK_Regler_Badezimmer", "HK_Regler_Buero");;\
> my $Interval = 15;;\
> &ForceMAXTempUpdate($Interval, \@MaxThermostate);;\
> }
in der fhem.cfg deaktiviert, und wartet, bis alle temperature Werte da sind, und dann einen Neustart mit den vorher
deaktivierten Einträgen macht, dann geht es, da ja dann die Werte aus der fhem.save genommen werden.

Aus Erfahrung weiß ich, dass es beim Testen sinnvoll ist, die fhem.sve zu löschen, und mache das jedesmal,
wenn ich etwas ausprobiere.

Wandthermostat ist zur Zeit keiner angeschlossen.
Was in den Variablen steht, sehe ich mir morgen an.
Eventuell kannst Du ja anhand der Beschreibung den Fehler reproduzieren

Gruß Joachim
FHEM aktuellste Version auf FB 7570 und 7390 mit Zebradem Toolbox Freetz
FHEM auf Raspberry
1-Wire mit LinkUSBi und Rs-Pi ds2482-800  1-Wire-9 Board; Max mit Cube, HMLAN
div. 1-Wire Sensoren; MAX-Thermostaten; Homematic-Komponenten, Zehnder KWL über RS-232

Zwer2k

Sorry, hab das mit dem löschen der Dateien überlesen :)
Ich lösche die Dateien nicht.

Wenn ich die Datein lösche, bekomme ich
Error parsing time at /var/InternerSpeicher/fhem/lib/perl5/5.12.2/mips-linux/Time/Piece.pm line 470.
und nicht die 99% Last.

Ich benötige daher Ausgabe von der Zeile

Log (1, $therm."-".$curTime."-".$curTime->epoch."-".$nextUpd."-".$nextUpd->epoch);
Vor der Zeile
$nextUpd = $nextUpd + 60 * 2 while($curTime->epoch > $nextUpd->epoch);
einfügen.

Der Script benötigt seine Startwerte, ich muss daher eine Abbruchbedingung nach "my $th_time = $defs{$therm}{READINGS}{"temperature"}{TIME};" einbauen, falls $th_time nicht richtig gesetzt wird.