[gelöst] Probleme beim Feststellen, ob ein Dienst im lokalen Netz erreichbar ist

Begonnen von mikezulugolf, 04 Oktober 2019, 17:57:14

Vorheriges Thema - Nächstes Thema

mikezulugolf

Hallo allerseits,

nach einigem Studium der Commandref und des Forums, sowie einigen Versuchen bin ich an einem Punkt angelangt, an dem ich nicht so recht weiterkomme.  Und daher schreibe ich diesen Beitrag in der Hoffnung jemand kann mich in eine zielführendere Richtung schubsen.

Mein Kontext: 
Ich habe mir da einen ESP32-Mikrocontroller mit etwas one-wire drumherum zusammengelötet um verschiedene Temperaturen in der Haustechnik erfassen zu können und sie in einer DB zu speichern und die Temperaturverläufe zu visualisieren.  Der ESP32 ist per WLAN im Hausnetz eingebucht und liefert die Daten wie gewünscht. Auch hat er einen Mini-Webserver, über den ich die aktuellen Werte abfragen kann.

Mein Problem:
Alle paar Stunden (intermittierend zwischen 5h und 48h) bleibt das Ding hängen (liefert keine HTTP Response mehr) und muss resettet werden. Dazu habe ich das USB-Netzteil in einen HM-Schaltaktor gesteckt.  Wenn der ESP32 hängt, ist er oft noch über PING erreichbar, aber ein HTTP Request schlägt fehl (HTTP-Timeout). Wenn er über PING nicht erreichbar ist, dann läuft ein ein HTTP-Request auf "no route to host".

Lösungsversuche:

(1)
Monitoring über FHEMs "ping" Modul: funktioniert - teilweise.  Wenn ein ping auf den ESP32 noch Antwort gibt, kann der ESP32 Webserver schon Stunden/Tage keine Antwort mehr liefern. Wenn "ping" einen Fehler bringt, muss ich also auf jeden Fall einen Reset des ESP32 (über Poweron/off an den HM Schaltaktor) anstossen, aber das ist mir viel "zu spät".

(2)
Monitoring über HTTPMOD: Wenn der ESP32-Webserver läuft, kann ich die Response auslesen und ein passendes Reading generieren,was ich bis jetzt noch nicht gemacht habe. HTTPMOD hat da so ein (dachte ich) passendes Reading namens LAST_ERROR. Und da steht auch schön drin, was HttpUtils im Fehlerfall zurückliefert, wie z.B. "x.x.x.x: no route to host" oder "connect to http://x.x.x.x:80timed out".
Dann kann ich auf jeden Fall einen Reset anstoßen.
Dummerweise führt aber die nächste Ausführung von HTTPMOD nicht dazu, dass das Reading LAST_ERROR zurückgesetzt wird. Dort steht immer noch der letzte Fehler, den HTTPMOD gesehen hat, auch wenn seit dem ESP32-Reset mittlerweile HTTPMOD schon viele Male den ESP32-Webserver erreicht hat und dieser eine normale Antwort zurückgegeben hat.
Und dann finde ich im 98_HTTPMOD-pm unter den ToDos: reading mit Status je get (error, no match, ...)  - das was ich vermutlich bräuchte ist noch gar nicht implementiert. HttpUtils liefert zwar ein $err zurück, aber im Erfolgsfall ist das ein Leerstring und das führt in HTTPMOD.pm ( Zeile: readingsBulkUpdate ($hash, "LAST_ERROR", $err)      if ($err && AttrVal($name, "showError", 0)); ) eben nicht zu einem Update des Readings LAST_ERROR.

(3)
Monitoring über PRESENCE: Habe ich nicht ausprobiert, aber laut Doku läuft das auch über einen Ping ab, was in diesem Fall leider kein zuverlässiger zeitnaher Indikator ist, dass ein Reset gemacht werden müsste.
Wäre eine PRESENCE Funktion, die ein IP-Connect an x.x.x.x:80 versucht, ein möglicher Ausweg? Non-Blocking?

Vielen Dank im Voraus für Eure Ideen und Kommentare,
Grüße,
Richard.

der-Lolo

Ich benutze UDP um den ESP Nachrichten senden zu lassen. Im ESP Programm habe ich mir zusätzlich eine "alive" message programmiert die nach 5000 durchläufen gesendet wird...


Otto123

Hi,

ganz allgemein hatte ich mal diese Sub für die 99_myUtils gefunden:
sub ServiceMonitor($$)
# Usage: ServiceMonitor("Hostname","Portnummer")
# in Presence: function {ServiceMonitor("Hostname","Portnummer")}
{
    use Net::Ping;
    my ($host, $port)    = @_;
    my $status;
   
    # Create a new ping object
    my $p = Net::Ping->new("syn");
    $p->port_number($port);
    $p->ping($host,10);
   
    # perform the ping
    if ( $p->ack ) {
$status = 1;
    }
    else{
    $status = 0;
    }
   
    # close our ping handle
    $p->close();
    return $status;
   
}

Die verwende ich für einige Sachen zusammen mit dem Presence Modul. Webserver abfragen, SMB Server abfragen usw.

Nonblocking ist das Ding nicht wirklich, aber es hat bei mir noch nicht blockiert. Ich weiß nicht genau ob sich die Perl Routine wirklich irgendwie Blockieren lässt.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

frober

Warum überwachst du nicht den timestamp deiner Temperaturen.
Wenn sich dieser länger nicht ändert bootest du den ESP neu.

Dafür gibt es sogar ein Modul:

https://forum.fhem.de/index.php?topic=49408.msg410767.msg#410767
Raspi 3b mit Raspbian Buster und relativ aktuellem Fhem,  FS20, LGW, PCA301, Zigbee, MQTT, MySensors mit RS485(CAN-Receiver) und RFM69, etc.,
einiges umgesetzt, vieles in Planung, smile

********************************************
...man wächst mit der Herausforderung...

Prof. Dr. Peter Henning

Tipp: ESP herauswerfen, für 15 € einen Raspberry Pi Zero mit OWFS einbauen und das aus FHEM mit OWServer abfragen.

LG

pah

Tobias

Wenn der ESP andauernd hängen bleibt liegt's am Sketch ( eventuell läuft das SRAM voll??) oder am ESP selbst

Entweder den Sketch optimieren, den esp wechseln oder gleich auf einen raspi wechseln. Wobei der raspi aber auch kein Allheilmittel ist, der ist mir damals auch öfters stehen geblieben, da lag es aber an einem bog im usb Stack


Gesendet von iPhone mit Tapatalk
Maintainer: Text2Speech, TrashCal, MediaList

Meine Projekte: https://github.com/tobiasfaust
* PumpControl v2: allround Bewässerungssteuerung mit ESP und FHEM
* Ein Modbus RS485 zu MQTT Gateway für SolarWechselrichter

mikezulugolf

Vielen Dank für Eure interessanten Anregungen, mal sehen, was ich davon umsetze.

@Lolo: einen "alive" Heartbeat hatte ich noch nicht auf dem Radar, danke.

@Otto: Auch ein guter Tip. Danke.
Dazu habe ich auch ausprobiert:
   use LWP::Simple; if (get("http://x.x.x.x:80") eq "") {return 0; } else {return 1; }
das wäre auch eine Funktion für PRESENCE. Mach ich vielleicht so.

@frober: Danke. Ja, das könnte ich machen, wenn ich denn die Daten in FHEM sammeln würde.

@PAH: ja, ein Pi Zero wäre vielleicht die stabilere Platform, aber auch mit mehr Update-Pflege verbunden, danke.
Und die Platine müsste ich entsprechend auf den Pi umgestalten.......

@Tobias: Auch eine gute Anregung, danke. Habe ich gleich getestet. Nach etwas Warm-Up liefert ESP.getFreeHeap() konstant (über Stunden) so ca. 253k und heap_caps_get_free_size(MALLOC_CAP_8BIT) konstant ca. 199k zurück. Das sieht zumindest nicht nach einem offensichtlichen Leak aus.


CoolTux

Zitat von: mikezulugolf am 07 Oktober 2019, 13:55:03
Dazu habe ich auch ausprobiert:
   use LWP::Simple; if (get("http://x.x.x.x:80") eq "") {return 0; } else {return 1; }
das wäre auch eine Funktion für PRESENCE. Mach ich vielleicht so.

Probiere genau das einmal wenn der Endpoint nicht zu erreichen ist. Versuche dann mal Dein FHEM zu steuern oder gar das FHEMWEB zu erreichen.
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

mikezulugolf

@CoolTux:  Ja ... das blockiert - anscheinend für 3,5 Sekunden.  Der von Otto zitierte Code hat einen Timeout von 10 Sekunden ($p->ping($host,10);)
OK, da wäre der Timeout konfigurierbar, z.B. auf 1-2 Sekunden.

Oder läuft diese ServiceMonitor Routine etwa asynchron in einem separaten Thread und würde gar nicht blockieren?

Danke,
Richard.

CoolTux

Du bist ja nun schon relativ weit. Schau Dir doch mal im Wiki HttpUtils und die darin enthaltene Funktion zum nonBlocking Aufruf an.


Grüße
Du musst nicht wissen wie es geht! Du musst nur wissen wo es steht, wie es geht.
Support me to buy new test hardware for development: https://www.paypal.com/paypalme/MOldenburg
My FHEM Git: https://git.cooltux.net/FHEM/
Das TuxNet Wiki:
https://www.cooltux.net

Otto123

Zitat von: mikezulugolf am 07 Oktober 2019, 21:31:55
Oder läuft diese ServiceMonitor Routine etwa asynchron in einem separaten Thread und würde gar nicht blockieren?
Hallo Richard,

Die Routine an sich läuft dort wo man sie aufruft. Direkt aufgerufen kann sie also blockieren. Der Aufruf erfolgt aber im Presence Device und ehrlich gesagt weiß ich da nicht genau was passiert. Ich weiß allerdings, dass es bei vielen Presence Definitionen die zeitweise nicht erreichbar sind schon immer wieder eigenartige Logmeldungen gibt. Ich habe das aber bisher nicht weiter untersucht.

Gruß Otto
Viele Grüße aus Leipzig  ⇉  nächster Stammtisch an der Lindennaundorfer Mühle
RaspberryPi B B+ B2 B3 B3+ ZeroW,HMLAN,HMUART,Homematic,Fritz!Box 7590,WRT3200ACS-OpenWrt,Sonos,VU+,Arduino nano,ESP8266,MQTT,Zigbee,deconz

mikezulugolf

Manchmal liegt so ein Stabilitätsproblem nicht an der Software - ich habe dem ESP32 ein anderes Netzteil gegönnt und seither sind seine Hänger weg und damit auch die Notwendigkeit z-B. mit einer wie auch immer gearteten FHEM Konstruktion die Hänger festzustellen.

Trozudem nochmals vielen Dank für die lehrreichen Antworten.

Grüße,
Richard.