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.";";
}
}
?>