Regenberechnung

Hi, ich habe ein altes php Skript was mir ein wenig Kopfzerbrechnen macht.

Das Skript funktioniert auch ohne Fehler, wenn es regent.

Wenn es in der letzten Stunde nicht geregent hat bekomme ich immer folgenden Fehler:

Notice: Undefined offset: -1 in C:\ProgramData\Symcon\scripts\27668.ips.php on line 45

Ich habe viel probiert, u.a. den Teil der Berechnung bei keinem Regen der letzten Stunde auszusetzten, aber dann geht meist was anderes nicht.

Ich hoffe mir kann jemand einen Denkanstoss oder einen Tipp geben ( Mein Problem habe ich markiert)

Hier das Skript:

<?php

/*

**********************************************************************************************

 Berechnet die Niederschlagsmenge der letzten Stunden

**********************************************************************************************

File     :  Niederschlagsmengen berechnen

Trigger  :  Zyklisch

Interval :  5 Minuten

*/

$archiveID = 28648 ;       // Archive-Handler-ID 

$objectID = 42219 ;     // Variablen-ID Gesamtniederschlag

$updatetime = IPS_GetVariable($objectID);       // Variable abfragen

$updatetime = $updatetime['VariableUpdated'];     // Letztes Update $objectID

$nsm_g = GetValueFloat($objectID);    // Gesamte Niederschlagsmenge

$ende = time();         // JETZT

$stunden = 60*60;    // 1 Stunde a 60 Minuten mit 60 Sekunden

//Umwandlung Regen in Text

$Regen = getvalue(13995/*[Wetter\HM-WDS100-C6-O IEQ0547256:1\Windrichtung in Grad]*/);

if ( ($Regen == 0) ) {$RegenString = "Kein Regen";}

if ( ($Regen == 1) ) {$RegenString = "Es regnet";}

SetValueString(25137 , $RegenString);

// Scriptstart

// Auslesezeiten der Datenbank

$start_1h = time()-(1*$stunden);     // Datenbank auslesen ab 1 Stunde vor JETZT

$start_24h = time()-(24*$stunden);     // Datenbank auslesen ab 24 Stunden vor JETZT

$mitternacht = mktime(0,0,0,date("n"),date("j"),date("Y"));     // Timestamp - Heute 0:00 Uhr

// Abfrage 1 Stunde

if (($ende - $updatetime) < (1*$stunden))

{

$buffer_1h = AC_GetLoggedValues($archiveID, $objectID, $start_1h, $ende, 0);

$anzahl = count($buffer_1h);

*

hier ist das Problem ---- > $wert = $buffer_1h [$anzahl-1];

*

echo "$wert";

$ns_1h = $wert['Value'];

$nsm_1h = round($nsm_g - $ns_1h,2);

    // Sicherheitsabfrage, falls Gesamtniederschlag der Station auf Null

    if ((($nsm_g - $ns_1h) == $nsm_g)  or ($nsm_1h < -0.01))

    {$nsm_1h = 0;}

}

SetValueFloat(21592 , $nsm_1h);      // Variablen schreiben

// Abfrage 24 Stunden

if (($ende - $updatetime) < (24*$stunden))

{

$buffer_24h = AC_GetLoggedValues($archiveID, $objectID, $start_24h, $ende, 0);

$anzahl = count($buffer_24h);

$wert = $buffer_24h[$anzahl -1];

$ns_24h = $wert['Value'];

$nsm_24h = round($nsm_g - $ns_24h,2);

   // Sicherheitsabfrage, falls Gesamtniederschlag der Station auf Null

    if ((($nsm_g - $ns_24h) == $nsm_g) or ($nsm_24h < -0.01))

    {$nsm_24h = 0;}

}

SetValueFloat(40249 , $nsm_24h);       // Variablen schreiben

// Abfrage Heute

if ($updatetime > $mitternacht)

{

$buffer_heute = AC_GetLoggedValues($archiveID, $objectID, $mitternacht, $ende, 0);

$anzahl = count($buffer_heute);

$wert = $buffer_heute[$anzahl-1];

$ns_heute = $wert['Value'];

$nsm_heute = round($nsm_g - $ns_heute,2);

   // Sicherheitsabfrage, falls Gesamtniederschlag der Station auf Null

    if ((($nsm_g - $ns_heute) == $nsm_g)  or ($nsm_heute < -0.01))

    {$nsm_heute = 0;}

}

SetValueFloat(51943 , $nsm_heute);       // Variablen schreiben

echo "Buffer: $anzahl Niederschlagsmenge (1h):$nsm_1h L (24h):$nsm_24h L (Heute):$nsm_heute L"."\r\n";

ich bin dankbar für jedenTipp

Hallo Jan,

nach grober Durchsicht, kann ich die folgenden Tipp geben:
Im Archive werden meines Wissens nur daten geloggt wenn sich was ändert, d.h. wenn es in der letzten Stunde nicht geregnet hat, dann wird auch nichts geloggt und dein Array $buffer_1h ist leer.
Damit ist $anzahl = 0 und wenn du dann -1 rechnest, tritt der Fehler auf.
Du musst nach „$anzahl = count($buffer_1h);“ prüfen ob $anzahl > 0 ist und wenn nicht musst du den $wert = 0 setzen.

VG Hofi61

Update: Ich hätte erst scrollen sollen :open_mouth:.

Das Problem entsteht jeweils bei AC_GetLoggedValues, wenn es keine Daten im Archiv gibt für die Zeitspanne. Dannkommt ein False zurück und die weitere Verarbeitung führt zu der Fehlermeldung.

Es muss bei jedem buffer_* setzen erst geprüft werden, ob es überhaupt Daten im Array gibt, danach kann erst die Folgeverarbeitung passieren bzw. muss der Schritt übersprungen werden.

Danke für die Antwort, dies habe ich schon getestet, aber ich bekomme keinen Wert für den $buffer_1h den ich vergleichen kann, ab da komme ich einfach nicht weiter. Ich wollte mir den Wert über echo ausgeben lassen, bekomme dann aber auch einen Fehler. Wie kann ich den Vergleichen wenn ich keinen Wert kenne?

Der Wert von $buffer_1h ist dann false.

Du hast wahrscheinlich versucht, dir den Wert mit echo ausgeben zu lassen. Echo zeigt aber ‚false‘ nicht an. Nimm zur Ausgabe lieber var_dump.

Die Lösung wird sein:

if ($buffer_1h !== false) {
...
}

Tzja, ist irgendwie komisch, oder ich habe wirklich ein totals Verständnisproblem im Moment.

zuerst hole ich mir den Wert für $buffer_1h, danch prüfe ich ob false und wenn dies zutrifft sollte doch der Code in der geschwungenen Klammer nicht ausgeführt werden. Aber er macht es trotzdem.
Ich bekomme wieder den Fehlercode:
Notice: Undefined offset: -1 in C:\ProgramData\Symcon\scripts\54993.ips.php on line 46

$buffer_1h = AC_GetLoggedValues($archiveID, $objectID, $start_1h, $ende, 0);
if ($buffer_1h !== false) {
$anzahl = count($buffer_1h);
$wert = $buffer_1h[$anzahl-1];
$ns_1h = $wert['Value'];
}

AC_GetLoggedValues gibt ein leeres Array zurück und nicht false, wenn es keine Werte in dem entsprechenden Zeitraum gibt. Ich vermute, da liegt der Fehler.

Entweder Dr.Niels Hinweis oder

der Buffer hat nur einen Wert und du ziehst 1 ab, dann knallt es auch.

So habe ich das irgendwann mal angepasst:

// Abfrage 1 Stunde

if (($ende - $updatetime) < (1*$stunden)) {

    $buffer_1h = AC_GetLoggedValues($archiveID, $objectID, $start_1h, $ende, 0);

    $anzahl = count($buffer_1h);

    if ($anzahl == 0) {

        $nsm_1h = 0;

    } else {

        $wert = $buffer_1h[$anzahl-1];

        $ns_1h = $wert['Value'];

        $nsm_1h = round($nsm_g - $ns_1h,2);

        // Sicherheitsabfrage, falls Gesamtniederschlag der Station auf Null

        if ((($nsm_g - $ns_1h) == $nsm_g)  or ($nsm_1h < -0.01)) {

            $nsm_1h = 0;

        }

    }

}

Super Ihr seit die besten, es geht so wie ich es will.

vielen Dank für alle Antworten.
:wink:

Sorry, da lag ich falsch und Dr.Niels hat natürlich Recht :slight_smile:

Somit musst du auf ein leeres Array prüfen:

if ($buffer_1h !== []) {
...

oder halt mit count()