WIIPS - neues Update

Hallo Torro,
ich hab im Moment nicht die Zeit, sofort wg. Abgleich mit Deinem Modul zu schauen, aber hier erstmal vorab meins, das seit nun ca. 2 Monaten stabil läuft

  • basiert im Kern u. rechnerisch auf HJH’s Modul (was ja im Forum ausgiebig diskutiert wurde, angepaßte Originalzeilen sind sogar noch auskommentiert drin)

  • ist von mir lediglich erweitert bzgl.
    a) Anpassung Variablennamen
    b) Erweiterung um Stunden- und Monatswerte

Außerdem von mir auf Robustheit getrimmt. Heißt, es synchronisiert sich (soweit möglich) auch noch, wenn „Werte verlorengingen“, also Computer mal ne Zeit aus war usw. Der Tageszähler im Sensor zählt ja erstmal weiter.


<?
/*
*******************************
IP-SYMCON Event Scripting
*******************************
File     : KS300_Regenerfassung.ips.php
// Trigger  : Regenzaehler_neu <<-org
Trigger  : KS300.Rain (OnUpdate)
Interval : 600 sec (als Sync bei längerer Trockenheit auf 7:30 usw.)
Author   : HJH
Date     : 25.05.07

Das Skript wir durch die Integer Variable "Regenzaehler_neu" OnUpdate getriggert.
"Regenzaehler_neu" ist der Zählerstand, den die KS300 ca. alle 3 Minuten meldet.

[Anpassung GW 9.10.2007]:
Aus Kompatibilitätsgründen wird hier die Variable
"Regenzaehler_neu" durch "KS300.Rain" bereitgestellt.
"Regenzaehler_alt" wird durch "KS300.Rain.old" gebildet.
"Liter_heute" wird durch "KS300.Rain.literDay" gebildet.

[Erweiterung GW 13.10.2007]:
- Erweiterung um Stunden- und Monatszähler
- Erweiterung Zählerstandsvariablen (.literDay, .literHour, .literMonth)
- Timestamp-Variablen für Zeitpunkt letztes Zählerstand-Reset
   - als Unix-Zeitstempel (.timestamp) [Integer]
   - als darstellbarer String (.time) [String]
  sind Basis einer Reset-Auslösung, die nachträglich auch dann auslöst,
  wenn PC oder Programm zum geplanten Zeitpunkt nicht aktiv waren
  
  Primärzähler ist der Tageszähler, da dieser durch extern Einflüsse
  geändert wird (Regen, Reset im KS300 um 7:00(?) oder bei Batteriewechsel usw.)
  
  Werteübernahme nach literMonth bzw. literHour:
   Klasse Hour:
   bei jedem Durchlauf im Script:
      Differenzbildung zwischen bisher gespeichertem und jetzt zur
      Übernahme anstehendem Tages-Literwert
         - Bildung des Tages-Literwertes (Wippenschläge * Faktor)
         - wenn Differenz zu literDay positiv: Addition zum Stundenzähler
         - dann erst Speicherung des neuen Wertes in literDay
      (für Monatszähler ungeeignet, da nur auf Differenzbildung basierend, aber
       potenzieller Verlust von Differenzwerten möglich, z.B. wenn PC/Programm einige Zeit
       inaktiv war, obwohl diese fehlenden Werte "noch in den später eintreffenden
       Tageswerten wieder drin waren", also dort heraus noch hätten gewonnen
       werden können) --> also: Werte gleich daher nehmen --> so spät wie möglich
       vorliegender Tageswert ist Tageswert unmittelbar vor dessen Reset
    Klasse Month:
      Addition des bis dato vorliegenden Tageswertes bei jedem Tageswert-Reset
      zum Monatswert
  
  Resetbedingungen:
   Klasse      [H]auptbedingung / [N]ebenbedingung(en)
   ---------------------------------------------------
   Hour        [H]: Minute(jetzt) = 00
               [N1]: Minute(jetzt) > Minute(reset)+60
               [N2]: Minute(jetzt) < Minute(reset)

   Day         [H]: Zeit(jetzt) = 07:00
               [N1]: Zähler(jetzt) < Zähler(aktuell)
                  (also vor Werteübernahme nach "literDay"
                   d.h. es hat im KS300 ein Reset stattgefunden)
               [N2]: timestamp(jetzt) > timestamp(reset) + 24 * 60 * 60 (=24h)

   Month       [H]: Monat(jetzt) <> Monat(reset)
   
   bei jedem Reset für die jeweils zutreffende Klasse:
   setzen der .liter*.time- und .liter*.timestamp-Variablen, sowie Übernahme
   der alten aktiven Werte nach .literLast*
  
- Erweiterung um Variablen zum letzten Zählerstand vor Reset
  .literLastDay, .literLastHour, .literLastMonth [Float]

- Erweiterung um alt-Zählerstart-Zeitpunkt-Variablen (=vorherige Resetzeit)
  .literLast*.time [String]

*/

include "_globals.ips.php";

define("UMRECHNUNGSFAKTOR", 0.2469); // Faktor für die Umrechnung der Wippenschläge in Millimeter

$jetzt = time();

// aktuelle Werte einlesen
//$rza = GetValueInteger("Regenzaehler_alt"); // vorausgegangene Messung
//$rzn = GetValueInteger("Regenzaehler_neu"); // aktuelle Messung
$rza = GetValueInteger("KS300.Rain.old"); // vorausgegangene Messung
$rzn = GetValueInteger("KS300.Rain"); // aktuelle Messung

// zur Fehlerbereinigung die unteren Nibbles vertauschen
$rzn = (($rzn & 0x00f0) >> 4)  // oberes  Nibble des LSB 4x rechts schieben (entspricht Division durch 16)
     + (($rzn & 0x000f) << 4); // unteres Nibble des LSB 4x links schieben  (entspricht Multiplikation mit 16)

// Zählerstand abspeichern
//SetValueInteger("Regenzaehler_alt", $rzn);
SetValueInteger("KS300.Rain.old", $rzn);

// Zählerüberlauf abfangen
if ($rza > $rzn) $rzn += 256;

// Zuwachs (Wippenschläge) seit der letzten Messung
$Zuwachs = $rzn - $rza;

// Berechnung der aktuellen Regenmenge in mm (entspricht l/m²) für den laufenden Tag
//$lpd = GetValueFloat("Liter_heute");

$lpd = GetValueFloat("KS300.Rain.literDay");
$lpdOld=$lpd;
$difLpd = $Zuwachs*UMRECHNUNGSFAKTOR;
$lpd += $difLpd;

// Reset-Handler
$miJetzt = date("i", $jetzt);
$hJetzt = date("H", $jetzt);
$moJetzt = date("m", $jetzt);
// Stundenzähler:
$lph = GetValueFloat("KS300.Rain.literHour") + $difLpd;
$miResetH = date("i", GetValueInteger("KS300.Rain.literHour.timestamp"));
//  Stundenzähler Reset?
if ( ($miJetzt==0) or ($miJetzt > ($miResetH + 60)) or ($miJetzt < $miResetH)) {
   rainReset("Hour", $lph, $jetzt);
//  oder Stundenzähler inkrementieren?
} else {
   if ($difLpd > 0) {
      SetValueFloat("KS300.Rain.literHour", $lph);
   }
}

// Tageszähler:
$tsD = GetValueInteger("KS300.Rain.literDay.timestamp");
//  Tageszähler Reset?
if ( (($hJetzt==7) and ($miJetzt==0)) or (time() > ($tsD + (24*60*60))) or ($lpd < $lpdOld)) {
   //  Monatszähler Reset?
   $moResetMo = date("m", GetValueInteger("KS300.Rain.literMonth.timestamp"));
   $lpm = GetValueFloat("KS300.Rain.literMonth") + $lpd;
   if ($moJetzt <> $moResetMo) {
      rainReset("Month", $lpm, $jetzt);
   } else {   // Monatszähler inkrementieren
      SetValueFloat("KS300.Rain.literMonth", $lpm);
   }
   rainReset("Day", $lpd, $jetzt);
//  oder Tageszähler inkrementieren?
} else {
   SetValueFloat("KS300.Rain.literDay", $lpd);
}

//SetValueFloat("Liter_heute", $lpd);
   echo "fettich!";

function rainReset ($klasse, $wert, $nu) {
   $lastTs=GetValueInteger("KS300.Rain.liter".$klasse.".timestamp");
   if (time() > $lastTs + 60) {  // nicht mehrfach in gleicher Minute durchführen
      SetValueFloat("KS300.Rain.literLast".$klasse, $wert);
      SetValueFloat("KS300.Rain.liter".$klasse, 0.0);
      SetValueString("KS300.Rain.literLast".$klasse.".time", GetValueString("KS300.Rain.liter".$klasse.".time") );
      SetValueString("KS300.Rain.liter".$klasse.".time", date("d.m.Y", $nu)." ".date("H:i:s", $nu) );
      SetValueInteger("KS300.Rain.liter".$klasse.".timestamp", $nu);
//      echo "huhu reset:".$klasse.";";
   }
}

?>