Jump to content

[PHP] Watchdog und die Verbindungsfehler


Recommended Posts

Hi!

 

Ich hätte da mal gerne ein Problem ...

Aktuell bastele ich ja an einer Raumsteuerung. Das Standard-Setup für einen Raum besteht aus einem Master mit WiFi-Extension, einem Thermo-Sensor und einem DualRelay-Bricklet. Das DR ist an 220V angeschlossen und schaltet (erst mal) ein Gira 112200 Heizungsventil. Das ist erst mal das Basis-Setup

Software-Seitig habe ich ein kleines PHP-Skriptchen geschrieben, dass jede Minute seine Liste mit Bricks durchgeht und eine WiFi-Verbindung zum Thermo-Bricklet aufmacht, die Temperatur ausliest und dann entscheidet ob es das DualRelay schaltet oder nicht.

Die Funktionalität ist da und es rennt auch soweit gut, aber .....

 

Nun kommen meine beiden Probleme:

 

1. Ab und an hängt sich so ein Stapel mal weg und ist nicht mehr erreichbar.

Natürlich passiert das gerne, wenn man nicht da ist (dann bleibt die Hütte kalt oder wird brühwarm) oder bei Stapeln, die nur schwer zu erreichen sind (Wetterstation draussen).

 

2. Hier muss ich voranschicken, dass ich noch ziemlich am Anfang meiner PHP-Lernkurve bin. Ich lasse mein Skript durch seine Liste mit Stapeln rennen und grase so Raum für Raum ab. Solange alles ok ist, rennt das auch gut durch; wenn nun z.B. der dritte Stapel nicht erreicht werden kann, bricht das Skript mit einem Fatal Error in den TF-PHP-Dateien ab. Das hat zur Folge, dass die ersten beiden Räume zwar noch geregelt werden, der Dritte und alle folgenden aber nicht mehr.

 

Die beiden Probleme hängen somit direkt bei mir zusammen. Einerseits muss ich den Fehler abfangen, dass ich z.B. ein nicht erreichbares Modul einfach übergehe und den nächsten Raum aber wieder regeln kann ....   

-> Wie mache ich das am dümmsten in PHP?

 

Andererseits wäre es toll, wenn es einen Watchdog im Modul gäbe, der es automatisch resettet, wenn es 'hängt'.

-> Gibt es so etwas?

Das wäre z.B. für den Urlaub toll, denn der Stapel muss ja auch den Heizkörper aufdrehen, wenn z.B. die Raumtemperatur unter 5°C sinkt (Frostschutz)

 

Vielen Dank für eure Tips!

Link zu diesem Kommentar
Share on other sites

Hallo mikrolinux,

ich habe ebenfalls mehrere Stacks am Laufen und habe das Ganze so gelöst, daß ich ein Bash-Skript in der crontab eingetragen habe. In diesem Bash-Skript werden nacheinander meine Python-Skriptchen aufgerufen - für jeden Stack eines. Meldet sich ein Stack nicht zurück, dann braucht das pythonskript recht lange (wartet auf den timeout), aber dannach werden die anderen brav abgearbeitet.

Vielleicht bringt Dir eine solche Arbeitsweise auch ein bischen was....

Link zu diesem Kommentar
Share on other sites

Hi!

 

Hmmmh, in der crontab steht bei mir die Ausführung des PHP-Skripts. Ich könnte eine Schleife voranschicken die einen Ping oder so macht und wenn nichts kommt wird die jeweilige IP in eine Defects-Liste eingetragen.

Das ist in etwa, was ich in PHP machen will, nur weiß ich nicht recht, wie ich das implementieren soll. Ich habe mal versucht den Verbindungsaufbau in try und catch abzubilden, bin aber kläglich gescheitert - mangels Erfahrung und Kenne.

 

Ich möchte es nur möglichst einfach konfigurierbar halten. Mein Ziel ist es einen RasPi-Host zu haben (das läuft schon) der über ein Web-Interface konfiguriert werden kann. Ich würde bspw. meinem Vater einen Raspi in die Hand drücken, der kauft sich die TF-Bausteinchen für n Räume und kann loslegen. Vielleicht kann man auch ein Raumsteuer-Set draus machen oder was auch immer.

Jedenfalls will ich es letztlich DAU-freundlich haben und da finde ich eine Schleife, die eine Tabelle abarbeitet am besten. Aktuell lese ich die Geräte-Konfigs (IP, Baustein-IDs etc) aus einer MySQL-Tabelle in ein Array und arbeite das in einer Schleife ab. Beim Verbindungsaufbau muss es in PHP doch irgendwie die Möglichkeit geben, das Zustandekommen der IP-Verbindung zu checken und Fehler abzufangen .... ?

 

Das löst aber noch nicht das zweite Problem. Otto Normaluser findet es ws. ziemlich ätzend, wenn er alle paar Tagen einen der 'Raum-Controller' resetten muss. daher der Watchdog. Mir ist bei der Gelegenheit auch aufgefallen, dass Bausteine die mit dem weissen TF-Netzteil ausgestattet sind häufiger ausfallen, als solche, die mit einem 'dickeren' Netzteil (Tablet-Ladegerät) versehen sind. Scheint mit dem Strombedarf zusammen zu hängen.

Vor dem Hintergrund wäre jedenfalls ein Watchdog nicht schlecht, der das Ganze (Master und WiFi) ins Leben zurück holt ....

Link zu diesem Kommentar
Share on other sites

Zu der Sache wie du am Besten auf Fehler reagierst:

 

Exception-Handling ist der richtige Weg.

Ich muss jetzt ein wenig raten wie dein Script bisher aussieht, ich nehme mal diesen Pseudo-code:

foreach (row in MySQLDatabase)
{
   connectToHostAndRegulateRoomTemperature()
}

 

das Try-catch soll jetzt also im Fehlerfall diesen einen Raum auslassen, aber nicht die gesamte Schleife abbrechen, also ab damit in den Rumpf der Schleife:

foreach (row in MySQLDatabase)
{
   try
   {
       connectToHostAndRegulateRoomTemperature()
   }
   catch(exception)
   {
      logError("could not set room temperature for room X")
   }
}

 

Ist alles pseudo-code, die genaue Syntax von PHP habe ich gerade nicht im Kopf.

Link zu diesem Kommentar
Share on other sites

Innerhalb meiner Python-Skripte habe ich auch eine Fehlerbehandlung, da ja nix zurückkommt, wenn der Stack nicht erreichbar ist. Und nach der Werteerfassung ja Diagramme gezeichnet werden.

Diese Skripte sind einfach, aber dumm... ich setze dann Dummywerte ein. Dafür habe ich mir ein Flag für jeden Eintrag kreiert.

Link zu diesem Kommentar
Share on other sites

Hi!

 

Ich habe's am WE dann doch noch raus gekriegt. Ich hatte ja schon den Ansatz mit try und catch, den AuronX ja auch bestätigt hatte.Nach etwas fummeln ( = beseitigen von Verständnisproblemen und Tipperfehlern) läuft es jetzt ...

 

// Wenn die IP-Connection nicht hergestellt werden kann, Fehler ausgeben
try {
  if ( !($ipcon = new IPConnection($host, $port) ) ) // Create IP connection to brickd
         { throw new Exception( "brickd im Netz nicht erreichbar" ); }
    }
catch ( Exception $e ) {
  $error = "Controller nicht im Netzwerk erreichbar!";
  goto ende;
    };

 

Die Fehlerbehandlung habe ich zur Vereinfachung auf das Setzen einer Fehlervariablen und den Sprung zu einer Endemarke gesetzt.

In meinem Raumsteuer-PHP kommt da dann entsprechender Ausgabe-Code für die Site, bzw. überspringt es das Ansteuern der nicht erreichbaren Bricklets/Aktoren.

Der Ansatz ist das Herstellen einer IP-Connection, wie sie sich in den PHP-Beispiel-Skripten findet. So kann man es hier rauskopieren und in die Samples einfügen.

Kann es auch den Fall geben, dass einzelne Bricklets an einem Brick nicht erreichbar sind, während andere funktionieren? Oder ist das einer der ganz unwahrscheinlichen Fehler?

 

Jetzt muss mir nur noch was zum Thema Watchdog einfallen  ;)

Link zu diesem Kommentar
Share on other sites

Ich meinen Watchdog mit Hilfe eines Monoflops auf einem IO-Bricklet realisiert:

Das Monoflop wird alle 2s ausgeführt.

In dem Callback wird zum einen das Monoflop selbst und auf dem Host ein Alarm(10) nachgetriggert.

Wenn der Callback nicht kommt schlägt das Alarmsignal zu und man kann den Stack resetten.

Auf dem OpenWrt muss ich dann in der Regel noch den brickd abschiessen und vom init neustaerten lassen. Ich vermute mal das er den Reset durch das fehlende gudev nicht mitbekommt.

In dieser Kombination läuft es bei mir aber inzwischen recht kontinuierlich.

Codebeispiele könnte ich nur in C beisteuern, ich denke die Prinzipien sind aber bereits ausreichend beschrieben.

Link zu diesem Kommentar
Share on other sites

Ein 'Raumsteuer-Controller' ist bei mir modular. Minimum ist es ein Master mit WiFi-Extension mit einem Temperatur-Bricklet für reine Messung. Allerdings habe ich die Räume bisher immer auch mit einem zusätzlichen Dual-Relay-Bricklet zur Steuerung der Heizkörper versehen. Weiterhin kann es noch ein Display oder weitere Dual-Relays geben.

Der Durchlauf ist so, dass aus der Device-Tabelle die ID-s und IPs etc gelesen werden. Steht was sinnvolles drin, ist das entsprechende Bricklet angesteuert, bei "000" ist es nicht vorhanden. Damit ist dann die Konfig für den Raum klar und es geht weiter mit der Modus-Ermittlung (Arbeitswoche/Wochenende/Sonderzeitplan/Übersteuert/Lüften). Anhand von Modus und Zeit ergibt sich die Solltemperatur aus dem jeweiligen Profil für den jeweiligen Raum.

Mit der Solltemperatur renne ich in die Steuerung und baue die Verbindung auf, lese die Status fer Bricklets aus und daraus ergibt sich wie es weiter geht -> Heizungsventil auf/zu, Steckdose gemäss Schaltwunsch an/aus ...

 

Ich denke ich versuche mal die Geschichte mit try und catch auf die Bricklets auszudehnen. Es kann ja auch sein, dass man sich beim Konfigurieren der Controller vertippert. Dann hätte ich den Fall, dass die IP-Connection aufgebaut werden kann, das Bricklet aber nicht zugefügt werden kann. Dann hätte ich gerne eine Meldung der Art 'xxx-Sensor für den Raum yyy nicht erreichbar. Bitte Konfiguration und Hardware prüfen' oder so ähnlich auf der Website stehen und einen Log-Eintrag.

 

Die Geschichte mit dem Watchdog kann ich schätzungsweise so nicht anwenden, da der brickd auf dem Master/WiFi läuft, der ja nicht mehr erreichbar ist...

Da habe ich aktuell echt keine Idee

Link zu diesem Kommentar
Share on other sites

Üblicherweise sind entweder alle Bricks erreichbar oder keines.

Ah, wir beide wieder. Gleiches Thema, gleiche Dis­ku­tanten ;D

Wie konnte skippi den o.g. Watchdog nur realisieren ? Dafür brauchte er einen Bricklet extra. Könnte nicht der Fall eintreten, dass man ev. alle Pins vom IO braucht etc. Ja dann wäre ein zentraler Callback im Master eine prima Ergänzung. Hast was gegen einen Callb. im Master einzuwenden ?

 

Die Geschichte mit dem Watchdog kann ich schätzungsweise so nicht anwenden, da der brickd auf dem Master/WiFi läuft, der ja nicht mehr erreichbar ist...

Warum nicht ? Wenn dir ein Callback vom Master/Bricklet periodisch sozusagen mitteilt, der Stack ist noch da, und du beim Eintreten des Events (solange ein Verbind. bestand) einen eigenen Alarmtimer neustartest, also wie skippi beschrieb.

Link zu diesem Kommentar
Share on other sites

Äh ja, dann weiss ich zwar, dass der Controller irgendwann weg ist, aber was fange ich damit an? Dass der Stack nicht erreichbar ist bekomme ich mit, da ich alle Stacks zyklisch abfrage und ansteuere.

Ich muss ihn ja automatisch wieder ans Laufen kriegen, sonst wird es entweder brühwarm oder eisekalt, oder Licht/Fernsehher, jehen nicht mehr aus oder irgendwann die Rollos nicht rauf oder runter.

Die automatisierte Initialisierung bei Fehlern ist mein eigentliches Problem.

 

Edit: Blödsinn geschrieben, ich muss da noch watt mehr lesen  ;D

Link zu diesem Kommentar
Share on other sites

Dafür brauchte er einen Bricklet extra.

Äh ganz so ist es nicht. Ich steuere meine Verbraucher über Halbleiterrelais anstatt über das Dual-Relay Bricklet. Das hat den Vorteil, das man auch PWM's für Thermoantriebe oder Wellenpaketsteuerungen für Umwälzpumpen fahren kann.

Da das IO4 leider etwas wenig Treiberleistung für viele der Optokoppler hat, habe ich ein IO16 eingesetzt und damit ein paar Reservekanäle.

Damit könnte Mikrolinux vielleicht auch einen Autoreset erzeugen:

Kostet aber noch einen Kanal:

Ich glaube der Resetzustand ist ein Pullup (müsste zumindest Input sein damit es funktioniert). Man könnte eine IO-Line auf den Reset verdrahten und mittels Monoflop auslösen. Ein zweites Monoflop müsste vorher den Callback aufrufen, in dem man dann beide retriggert.

Kommt der Callback nicht, löst das Monoflop den Reset aus.

Allerdings: Da die Monoflops auch in Software realisiert sind würde ich für wirklich kritische Anwendungen lieber ein externes 2. Monoflop nehmen.

Ich gebe NIC aber auch recht: ein 'Hartbeat'-Timer auf den Masterbricks würde für viele Anwendungsfälle ausreichen. Idealerweise würde man ihn aber gleich so bauen, dass er auch als Watchdog agieren kann und (zumindest) den lokalen Stack zurücksetzten kann.

Link zu diesem Kommentar
Share on other sites

Stacks zyklisch abfrage und ansteuere

Müsste man nicht wenn das von der TF-Hardware per Callback quasi autom. ausgelöst wird.

 

Ich muss ihn ja automatisch wieder ans Laufen kriegen, sonst wird es entweder brühwarm oder eisekalt, oder Licht/Fernsehher, jehen nicht mehr aus oder irgendwann die Rollos nicht rauf oder runter.

Wenn du den exakten Zeitpunkt hast wenn der Stack ausfällt, warum löst Du dann nicht softw.seitig den Reset aus ?

Die automatisierte Initialisierung bei Fehlern ist mein eigentliches Problem.

Was meinst du mit Initialisierung ? Nach dem Reset wird der Enum-Callback der IPConnection ausgelöst, könntest du dann nicht deine Init-Schritte ausführen ?

Link zu diesem Kommentar
Share on other sites

Hmmh, da schlägt dann gnadenlos zu, dass ich geradeso die ersten ein, zwei Schritte im PHP hinter mich gebracht habe und mich freue, dass es überhaupt geht  ;)

Ich habe da momentan noch ein ganz einfaches Weltbild: Linux sagt dem brickd was er tun soll. Die Themen Callback und Objektorientierung im PHP kamen da bisher noch nicht vor  :-[

Der Stack steht ja irgendwo im Haus und wird per WiFi angesteuert. Wenn der sich jetzt irgendwann in die Reaktionslosigkeit verabschiedet, kann ich ihm ja nicht mehr sagen, dass er reset() ausführen soll, also muss ich es irgendwie hinkriegen dass er das selber tut. Nur wie?

Da fehlt mir einfach der Background ...

 

Für Ideen (lies mal hier, lies mal da ...) wäre ich echt dankbar!

Link zu diesem Kommentar
Share on other sites

Dann lass die Callbacks erstmal beiseite.

erreichbar ist bekomme ich mit, da ich alle Stacks zyklisch abfrage und ansteuere

Wenn du in deiner Implementation periodisch abfragst und der Stack ist weggeraucht, solltest du eine Exception bekommen. Versuche beim Auftreten der Exception ev. ein Reset des Stacks auszulösen, das wiederum löst (hoffentlich) den Enum-Callback aus. Von hier erneut das Initialisieren etc.

Öffne dann mal den Brick-Viewer und starte eine neue IP-Connection, zeigt der Viewer wieder den Stack an ?

Link zu diesem Kommentar
Share on other sites

Da müsste ich warten bis wieder einer 'kippt', das kann ein paar Tage dauern...

 

Wenn ich das PHP-Skript manüle starte, zeigt er mir in solchen Fällen einen Fehler im Tinkerforge IP-Connection-Skript, Zeile 281 mit dem Fehler 'No route to host', was mir den Verdacht nahelegt, dass der IP-Stack im BrickD des Stacks platt ist und nicht mehr reagiert, oder?

Link zu diesem Kommentar
Share on other sites

Versuche beim Auftreten der Exception ev. ein Reset des Stacks auszulösen, das wiederum löst (hoffentlich) den Enum-Callback aus. Von hier erneut das Initialisieren etc.

 

Dazu wollte ich dich gerade befragen, aber da es jetzt durchgestrichen ist glaube ich, dass wir uns jetzt doch einig sind :D

 

Ah, wir beide wieder. Gleiches Thema, gleiche Diskutanten

Wie konnte skippi den o.g. Watchdog nur realisieren ? Dafür brauchte er einen Bricklet extra.

 

Warum ein extra Bricklet? Reicht nicht eines der vorhandenen Bricklets um die Erreichbarkeit zu prüfen?

Habe die Details unserer letzten Diskussion leider vergessen, aber ich glaube es war sowas wie, dass ich gegen ein Hardware-Ping bin und du dafür ^^

 

Wenn du dir soetwas vorstellst wie: Programm fragt "ping", Stack antwortet "pong", dann nimm einfach ein enumerate gegen ein einzelnes Brick.

Wenn du dir etwas vorstellst wie: Der Stack sagt peiodisch "pong", dann finde ich das im Moment ziemlich cool, zumindest bequemer als immer ping zu rufen und man könnte argumentieren, dass nur die halbe Bandbreite nötig ist ^^

Link zu diesem Kommentar
Share on other sites

@AuronX

Dein Ping-Pong ist mir doch etwas zu verwirrend :o

Zumindest skippi hat mich verstanden:

ein 'Hartbeat'-Timer auf den Masterbricks würde für viele Anwendungsfälle ausreichen. Idealerweise würde man ihn aber gleich so bauen, dass er auch als Watchdog agieren kann und (zumindest) den lokalen Stack zurücksetzten kann.

 

Wenn du dir etwas vorstellst wie: Der Stack sagt peiodisch "pong", dann finde ich das im Moment ziemlich cool

Ja, und mit was wird dann so ein Pong ausgelöst ? Mit einem periodischen Callback im Master, wenn ich nicht irre...

 

@mikrolinux

Man muss hier unterscheiden zw. dem Konzept des Funknetzes via Chibi (das es nicht mehr gibt) und dem dezentralen WIFI. Für ersteres habe ich einen Master-Brick als Chibi-Master, der permanent zentral am Host-PC hängt, der sollte im Dauerbetrieb stabil bleiben. Und nur für diesen ließe sich bei Ausfall eines Funk-Slaves ein Reset auslösen.

In Deinem Fall gibt es nur den Stack mit WIFI, also dezentral und dafür ließe sich software-seitig im Host-PC natürlich kein Reset auslösen.

Es gibt einige Beiträge bzgl. Reconnect am WIFI, da bin ich nicht am laufenden, ev. gibt es dazu Änderungen durch das neue Protokoll:

http://www.tinkerunity.org/forum/index.php/topic,895.0.html

http://www.tinkerunity.org/forum/index.php/topic,867.15.html

Link zu diesem Kommentar
Share on other sites

Ja, und mit was wird dann so ein Pong ausgelöst ? Mit einem periodischen Callback im Master, wenn ich nicht irre...

 

Ich wollte auch sagen, dass ich dir in meiner aktuellen Gedankenlage zustimme :D

 

Also du registrierst halt nen Callback und sagst wie oft du dir das Pong wünschst. Zwischendurch würdest du aber nichts mehr dafür an den Stack senden.

 

Das mit dem automatischen Reset des Stacks verstehe ich noch nicht ganz:

Wird der Stack reseted wenn sich der angeschlossene PC (also das Programm von dir) nciht mehr meldet? oder wann? Da sollte man aufpassen, dass man keine Neustart-Endlosschleifen baut, wenn das eigene Programm abstürzt ^^

Link zu diesem Kommentar
Share on other sites

@AuronX: Nein, ich dachte eigentlich umgekehrt  ;)

Mein Proggi läuft zyklisch, gestartet durch cron. Es grast dann seine Liste von Stacks ab und steuert an, was es erreichen kann, was nicht da ist (die besagten abgeschmierten WiFi-Stacks) wird einfach übersprungen.

Das Problem ist also mitten im Stack, bzw. Master-WiFi. Es scheint dabei ja so zu sein, dass der komplette IP-Stack darniederliegt und sich nicht mehr melden kann. Interessant wäre ein Watchdog auf dem Stack, der z.B. ein Ping auf eine frei wählbare IP (z.B. den Raumsteuerungs-Server) macht und den Stack resettet, wenn er sie nicht mehr erreicht.

 

 

 

Edit: Mir ist gestern noch aufgefallen, dass der Stack, der am häufigsten ausfiel noch mit der Master-FW 1.4.0 lief, alle anderen recht stabil mit 1.4.6. Ich habe ihn dann erst mal 'nach-geflasht'. Jedenfalls ist jetzt alles homogen auf dem selben Stand.

Link zu diesem Kommentar
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Gast
Reply to this topic...

×   Du hast formatierten Text eingefügt.   Formatierung jetzt entfernen

  Only 75 emoji are allowed.

×   Dein Link wurde automatisch eingebettet.   Einbetten rückgängig machen und als Link darstellen

×   Dein vorheriger Inhalt wurde wiederhergestellt.   Clear editor

×   Du kannst Bilder nicht direkt einfügen. Lade Bilder hoch oder lade sie von einer URL.

×
×
  • Neu erstellen...