Ankündigung

Einklappen
Keine Ankündigung bisher.

Gibt es einen Befehl für eine Abbruchbedingung in PHP?

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

    Gibt es einen Befehl für eine Abbruchbedingung in PHP?

    Komme hier einfach nicht weiter

    Vielleicht weiss jemand von Euch Rat

    Ich logge seit Langem zig Gerätedaten per Modbusbefehl meiner PV und Batterie-WR. Das funktioniert sehr bisher sehr gut.

    Jetzt habe ich das Problem, dass der BatterieWR zuweilen ausfällt (ist eine andere Baustelle). Da das PHP-Script aber von jedem Register eine Antwort erwartet, bleibt es schlichtweg an der nicht antwortenden Stelle stehen...

    Ich würde gerne eine Abbruchbedingung schaffen wollen- z.B. wenn eine Abfrage nicht antwortet (innerhalb Zeit x), brech diese Abfrage ab und mache im Programm weiter.

    Das sieht zusammengestaucht auf das Wesentliche, das sind duzende von Werte, etwa so aus:

    PHP-Code:

    $STP6000WattP3 
    Modbussigned ("192.168.2.105",4,30781,10);  //aktuelle Erzeugung in Watt P3 Wird in Variable geschrieben 
    Sollte diese Abfrage nicht antworten bleibt das PHP Script stehen. Ich hätte gerne hier eine Art Abruchbedingung/Wartezeit etc pp. Erfolgt keine Antwort soll das PHP-Script an der nächsten Zeile weiterlaufen

    Grüsse
    Carsten
    Zuletzt geändert von Carstene; 15.11.2023, 13:24.

    #2
    Wie ich es angehen würde: Beim Aufbau der Verbindung einen angemessenen Timeout für die Anfragen setzen und um die Ausleseroutinen herum try/except zur Fehlerbehandlung verwenden, wenn bei Überschreitung des Timeout ein Fehler geschmissen wird. Ist ein bisschen plump/pragmatisch, sollte aber funktionieren.

    /tom

    Kommentar


      #3
      Zitat von Carstene Beitrag anzeigen
      Ich hätte gerne hier eine Art Abruchbedingung/Wartezeit etc pp. Erfolgt keine Antwort soll das PHP-Script an der nächsten Zeile weiterlaufen
      https://gist.github.com/avalanche123/3085581

      Kommentar


        #4
        Hm.... ich habe irgendwie das Problem, dass diese Scripte laufen müssen um dann bei Abbruchbedingung ihren Dienst tun

        Wenn aber das angefragte Script nicht antwortet, läuft auch die Schleife nicht weiter/durch

        Ich müsste etwas finden, wo quasi als "Hülle" eine Zeit runter läuft, egal ob innerhalb der Hülle der Aufruf ins Stocken gerät, und alles innerhalb dieser Hülle nach Zeit x abricht, der Gesamtcode dann weiter bearbeitet wird

        Mit break bekomme ich es nicht hin.... mit try auch irgendwie nicht

        Kommentar


          #5
          Wie schon geschrieben - 'timeout' ist das Zauberwort.

          Ist eine Eigenschaft der Verbindung und wird eingestellt, wenn die Verbindung aufgebaut wird.
          Der Abbruch der Anfrage erfolgt automatisch, wenn die eingestellte Zeit erreicht wird - im oben verlinkten Beispiel nach 1.5s.

          Damit das gesamte Script nicht an dieser Stelle wegen des timeout-Fehlers abgebrochen wird, packt man das Auslesen in ein 'try'.

          /tom

          Kommentar


            #6
            Das mit dem try hab ich bisher ausprobiert

            eine Fehlermeldung habe ich noch nicht bekommen – ob es funktioniert, wird sich zeigen

            mein Verständnis für das time out ist, dass dann das gesamte PHP Skript abgebrochen wird. Das ist nicht unbedingt Ziel der Übung

            leicht verstehe ich da ja auch etwas falsch,


            ich kann einen Block/Funktion bilden, wo die relevanten Abfragen reinkommen könnten

            Es ist nur ein Gerät, was an diesem Punkt Probleme bereitet

            vielleicht müsste ich dann diese Funktion zeitlich beschränken

            muss mich da mal rein fuchsen

            Kommentar


              #7
              Zitat von Carstene Beitrag anzeigen
              mein Verständnis für das time out ist, dass dann das gesamte PHP Skript abgebrochen wird.
              Nein, das ist die Zeit für eine einzelne Anfrage, deshalb heisst es ja auch `readTimeoutSec`. Und wenn Du die Anweisung für die Anfrage in ein 'try' einbettest, kannst Du steuern, ob das Script abgebrochen oder weiter ausgeführt wird. Das ist auch sehr schön im Beispiel von wintermute sowie im ersten Beispiel vom oben verlinkten php.net zu sehen, wo eine Division durch 0 abgefangen und das Script trotzdem weiter ausgeführt wird.

              /tom
              Zuletzt geändert von Tom Bombadil; 19.11.2023, 12:14.

              Kommentar


                #8
                Manchmal ist Lesen doch mehr als Buchstaben ansehen......

                Hatte irgendwo nen Brett vom Kopf (der Länge nach)

                Habe das zweite Beispiel genommen und nochmals neu getestet. Ich hatte total vergessen, dass ich JEDE Anfrage einzeln in diesen try-Block packen müsste. Abgebrochen wird ja der try-Block an der betroffen Stelle, alles weitere im Block wird nicht durchgeführt. Das hatte ich falsch umgesetzt zu Anfang

                Das ist quick and dirty und bringt offensichtlich den gewünschten Schritt

                In meinem Fall würde die Gruppe der Anfragen mit der gleichen IP reichen (Wenn eine Modbus-Anfrage auf IP x nicht antwortet, antworten die anderen auch nicht)

                Werde das mal implemtieren Erledigt - bin zuversichtlich dass es laufen wird


                Vielen Dank

                Zuletzt geändert von Carstene; 19.11.2023, 17:29.

                Kommentar


                  #9
                  Ich musste komplett umdisponieren.. So wie es es aufgebaut habe, hatte es leider nicht funktioniert

                  Die Lösung präsentiere ich trotzdem:

                  PHP-Code:

                  <?php

                  function Modbus ($IP,$DevID,$Register,$lange//Definition der Function zum Auslesen der Register an den WRn
                  {
                  require_once 
                  dirname(__FILE__) . '/../../Phpmodbus/ModbusMaster.php';
                  // Create Modbus object an Adresse
                  $modbus = new ModbusMaster($IP"TCP");
                  try {
                      
                  $recData $modbus->readMultipleRegisters($DevID$Register$lange); //Tagesertrag in kWH
                      
                  echo $modbus;
                  }
                  catch (
                  Exception $e) {  
                      echo 
                  $modbus//  Zeige Fehlermeldung
                      
                  echo $e;
                       
                  //  exit;
                  }
                  // Chunk the data array to set of 4 bytes
                  $values array_chunk($recData2);
                      echo 
                  "<p>";

                  foreach(
                  $values as $nr => $bytes)
                      {
                      if (
                  $nr == 1// Wenn Position im Array == dann speicher diesen Wert ab
                      
                  {
                          return 
                  PhpType::bytes2signedInt($bytes);
                      }
                       }
                         
                  // $timeout->clear(); // clear timeout Seit das ausgeblendet ist funktionierts auch mit einem Fehler
                      
                  }

                  $STP6000WS1 Modbus ("192.168.2.105",4,30773,10);  //aktuelle Leistung String1

                  $SOC Modbus ("192.168.2.115",3,30845,10);  //SunnyIsland produzert Fehlermeldung wenn offline

                  echo "<p>";
                  echo 
                  "Ausgabe W STP: "$STP6000WS1;
                  echo 
                  "<p>";
                  echo 
                  "<p>";
                  echo 
                  "Ausgabe W STP: "$SOC;

                  ?>

                  Diesen Code bis Zeile 30 nutze ich seit Jahren. Er funktioniert Fehlerfrei und dennoch nicht so, wie es eventuell vorgesehen war

                  Fehlermeldungen druckt er aus, aber dann läuft der Code nicht weiter. Das try-Catch hat derProgrammierer schon genutzt... aber irgendwie brach nach einer Fehlermeldung das komplette Skript ab

                  Ich habe in Zeile 15 das exit auskommentiert und in Zeile 28 den timout

                  Jetzt läuft der Code durch, obwohl die Abfrage am SI einen Fehler wirft

                  Mal sehen ob es diesmal klappt

                  Kommentar


                    #10
                    Mit PHP habe ich bisher nichts gemacht, deshalb habe ich vielleicht eine "dumme" Anmerkung...

                    Mich wundert die Stelle deines Aufrufs für "$values = array_chunk($recData, 2);". Klappt das auch, wenn dein try einen Fehler fängt? Bekommt $recData auch im Fehler-Fall einen verwertbaren Inhalt? Wenn nein, würde ich befürchten, dass array_chunk Blödsinn macht. Wenn ja, wäre dein try irgendwie überflüssig.

                    Kommentar


                      #11
                      Moinmoin,

                      Ich habe damals dieses Modbusgedöhns selbst nur aus dem Netz aufgeschnappt und solange daran rumgefummelt, bis es das macht was es soll.

                      Würde mich nicht wundern, wenn noch einiges unsinnig dabei ist. Das dort (nicht von mir) eingebaute try catch liefert bei Erfolg einen kompletten Datensatz per Modbus, bei Misserfolg wirft er nur eine Fehlermeldung - bis hierhin funktioniert das try catch.

                      Der Array_chunk teilt das Array in zweier Blöcke ein, ich glaube das hing mit dem Signed und Unsigned Daten zusammen, also Darstellung grosser, bzw auch negativer Zahlen
                      Kann auch dein, dass damit Hexwerte gebildet werden... - so richtig genau weiss ich es nicht mehr

                      Ich muss an den WR mal das eine, mal das andere verwenden....

                      Kommentar

                      Lädt...
                      X