[gelöst] Nodes überwachen: outstandingAck und alive Prüfung

Begonnen von alru, 27 März 2018, 20:13:15

Vorheriges Thema - Nächstes Thema

alru

Moin,

ich habe jetzt meine ersten "Gehversuche" mit MySensors hinter mir und will da noch ein paar weitere Projekte realisieren.
Bei Homematic finde ich die bidirektionale Kommunikation sehr schön. Bei MySensors könnte man evtl. mit "requestAck" ein wenig Übertragungssicherheit in die Kommunikation der Nodes bringen.

Ich würde gerne eine Überwachung implementieren, um bei nicht erreichbaren Nodes eine Notification zu erzeugen und dachte mir, das müsste mit diesem Attribut machbar sein.

Im Gateway sehe ich auch, wenn ein "outstandingACK" registriert wurde. Allerdings finde ich keine Info, welcher Node die Ursache dafür ist. Setzt man den Verbose-Level auf 5, dann findet man im Log Hinweise auf die Node-ID. Der Log-Eintrag ist aber ein wenig unstrukturiert, ich hab keine Ahnung wie man den auswerten soll.

Gibt es noch einen besseren Weg, um den Node-Status abzufragen?
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)

Mathea

Hi Stefan,

ich habe festgestellt, dass ein abgesetzter Befehl zu den MySensor Nodes im fhem Eventmanager doppelt vorkommt. Einmal ohne Doppelpunkt zwischen dem Reading des Gerätenamens und dem zu setzenden Wert, und einmal mit. Das eine ist der von fhem abgesetzte Befehl, das andere die zurückkommende ACK-Message des Nodes. Du könntest eine generische DOIF Funktion schreiben, die eine Art Timeout abwartet nachdem ein Befehl von fhem an ein MySensors Device abgesetzt wurde. Sollte das ACK-Event nicht innerhalb einer gewissen Zeitspanne zurückkommen, kannst du das Gerät als "offline" markieren.

Ich befürchte, dass es allein mit dem "outstandingACK" Reading ansonsten nicht möglich ist, da es, wie du schon sagtest, keinerlei Information über das beteiligte Device preisgibt.

Gruß,
Mathea

alru

#2
Hi Mathea,

das war der entscheidende Hinweis! Es funktioniert mit den von dir beschriebenen Events.
Mit einem DOIF werte ich jetzt die Events aus und schreibe die Ergebnisse in ein userReading vom Device.
Allerdings macht mir die Auswertung, bzw. das von dir genannte "...eine Art Timeout..." noch Probleme. Der Vergleich zwischen dem Status vom Device und dem ACK-Wert müsste etwas verzögert werden. Wie ich den Start so einer Abfrage verzögern kann, habe ich noch nicht herausgefunden.

Update:
Ich hab das "Timeout" Problem jetzt so gelöst: Ein DOIF speichert zunächst den Befehl und das darauf folgende ACK-Event ab. Danach wird (zeitverzögert) ein zweites DOIF getriggert, das die beiden Werte vergleicht. Wenn beide nicht gleich sind, dann wird eine Fehlermeldung generiert. Ist ein bisschen aufwändig, aber geht.
Ich werde jetzt als nächsten versuchen das auch für Sensoren zu implementiere, die eigentlich keine Befehle empfangen, sondern nur Daten senden. Das wird dann zeitgesteuert (ein mal pro Tag) getriggert, damit man weiß, dass der Sensor noch lebt.
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)

Beta-User

Zwischeneinwurf:

An sich finde ich die Idee, eine Art "alive"-Status zu haben sehr gut!

Eigentlich dürfte es nicht das Hexenwerk sein, sowas direkt in die Module zu implementieren.

Sieht da noch jemand Bedarf?

Würde das der Spur nach so angehen:
- Zwei neu Attribute (timeoutAck und timeoutAlive) fürMySensors-Device (beides Sekundenangaben)
- Ist das jeweilige Attr. gesetzt: internen Timer setzen. Kommt innerhalb der Zeiten eine Info: Device bekommt den Status "ALIVE"; Läuft der jeweils ab ohne Rückmeldung, gibt's entweder den Status "NO ACK" oder "DEAD" (mit Event - da kann man dann ein notify, DOIF oder was auch immer andocken).
- Jede erhaltene Message setzt den allg. Timer zurück, eine Ack-Message löscht den Ack-Timer.

Wenn mich jemand Modulentwicklungserfahrenes an die Hand nimmt und das nicht droht, zum Performance-Killer zu werdeb, mache ich mich gelegentlich mal dran... Die "???" gefallen mir schon länger nicht ;) . Liege ich richtig, das Timer-Handling evtl. nach Zeile 251 anzusiedeln?

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

alru

Moin,

eine schöne Idee, das im Modul zu integrieren. Das würde die Überwachung natürlich viel eleganter lösen.

Ich habe eine Anmerkung zu dem vorgeschlagenen Ablauf:
In meiner selbst gestrickten Lösung über DOIFs war es mir wichtig, dass nicht nur "irgendein" ACK zurück kommt, sondern das zum gesendeten Befehl passende ACK. Wenn das bei der Lösung im Modul Berücksichtigung finden könnte, würde ich mich freuen.
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)

Beta-User

Danke für die schnelle Rückmeldung, mal schauen, was sich machen läßt.

Allerdings glaube ich einerseits nicht so richtig, dass das auf die Art einfach so geht, andererseits aber auch nicht, dass das ein praktisches Problem darstellt:
Die Überwachung der Sendequeue macht das IO-Modul in der sub onAcknowledge($$) ab Zeile 398. Für einen einfachen Status sollte es m.E. aber genügen, wenn mit dem jeweils letzten Setzen einer Ack-Message ein Timer losläuft bzw. erneuert wird, der dann bei Ablauf der Zeit schlicht meldet, wenn die Ack-Warteschlange nicht leer ist. Gibt es ein Problem mit der Kommunikation, kann man das dann erkennen, gibt es keins, sind die Ack's auch alle durchgelaufen und man braucht diese ganzen Details gar nicht...

Wenn es dann im Fehlrfall doch benötigt wird, könntest du in einer entsprechenden notify-Routine immer noch den Mechanismus wie im IO-Modul verwenden, um die ganze Warteschlange anzuzeigen.

Aber erst mal sollte sowas überhaupt funktionieren, das wird erst mal Herausforderung genug 8) .
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Beta-User

#6
Hallo zusammen,

anbei eine erste Version eines entsprechend angepaßten Moduls zum Testen.
Scheint bei mir problemlos zu sein, allerdings wie üblich: ohne Funktionsgarantie!

Es gibt die beiden neuen, nicht voneinander abhängigen Attribute timeoutAck und timeoutAlive. Beides sind Sekundenwerte, wobei für timeoutAlive ein Wert sinnvoll sein dürfte, der etwas länger ist als 2-3 reguläre Sendungszyklen einer Node. Ein Ack sollte dagegen recht zügig durchlaufen, hier reichen m.E. also wenige Sekunden.

Hat das GW nach Ablauf der Zeit timeoutAck noch eine zuzustellende Sendung an eine Node, wird der Status des Devices zu "NACK" mit Event und bleibt auch so, bis die nächste Message an die Node zugestellt wurde und die Queue dann leer ist.
Solange alles sauber durchläuft, ändert sich hier der Status des Devices nie.

Setzt man timeoutAlive, muß innerhalb der Zeit irgendeine Anfrage oder ein Wert von der Node gesendet werden, dann wird der Status auf "ALIVE" gesetzt, ansonsten wird er zu "DEAD", es sei denn, der Status sei "NACK" (das bleibt also immer, es sei denn der oben beschr. Fall tritt ein).

Fragen oder Anregungen: gerne...
Wenn mehr das hilfreich finden, können die Anpassungen gerne nach erfolgreichem Test auf mehr Installationen in die allg. Codebasis rein. Ich finde es jedenfalls eine nette Option und hoffe, die Lösung ist auch nicht sonderlich resourcenfressend. Wäre natürlich schön, das würde jemand mal prüfen, der mehr Ahnung von Perl hat als meinereiner.

Gruß, Beta-User

EDIT: Anhang gelöscht, neue Version siehe Folgebeiträge
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

SensorMane

Hallo,

von mir erstmal ein Daumen hoch! So eine Möglichkeit fehlt mir schon lange. Ich habe bisher immer die Zeit bei den Readings mit anzeigen lassen, um zu sehen ob ein Node noch aktiv ist. Ist für mich wichtig, weil ich auch Batteriegepufferte Sensoren z.B. im Garten draußen habe.
Das aufwendige Anzeigen der Timestamps würde damit entfallen, man könnte dann ja direkt eine Anzeige implementieren die auf das inaktive Gerät hinweist.

Mal schauen wann ich das Testen kann und ob ichs hinkriege!

Danke für eure Bemühungen jedenfalls!

Beta-User

Zitat von: SensorMane am 10 April 2018, 11:09:40
Das aufwendige Anzeigen der Timestamps würde damit entfallen, man könnte dann ja direkt eine Anzeige implementieren die auf das inaktive Gerät hinweist.
Da das "state"-Reading genutzt wird, wird das ALIVE/DEAD/NACK direkt beim Device auch schon in der Raumübersicht angezeigt. Z.B.in einer ReadingsGroup sollte das auch problemlos abzufragen sein. Und es werden beim Wechsel des Status Events generiert, man kann also z.B. ein notify darauf ansetzen.

Apropos Events: Ist die Benennung für euch so ok? Ich habe da nicht lange drüber gehirnt oder Quervergleiche angestellt (HM kennt NACK, aber sonst...?). Vielleicht hat jemand bessere Ideen, bevor zu viele notify im Umlauf sind ;) .

Zitat von: SensorMane am 10 April 2018, 11:09:40
Mal schauen wann ich das Testen kann und ob ichs hinkriege!
Ist nicht sonderlich schwer: .pm tauschen (Rechte beachten), reload ausführen, Attribut(e) setzen, warten...

Viel Erfolg!
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

alru

Moin,

ich hab jetzt einmal einpaar Testfälle durchgespielt und finde die Funktionalität der neuen Attribute klasse.

Das Verhalten in folgendem Testfall finde ich nicht ganz schlüssig:
timoutAck=10
timeoutAlive=30

Der Ausgangsstatus ist ALIVE. Legt man den Node jetzt "tot" wechselt der Status nach DEAD. Wird nun ein Befehl abgeschickt erfolgt der Wechsel nach NACK.
Soweit alles OK.
Wird jetzt der Node wieder zum Leben erweckt, wird der letzte Befehl gesendet und ausgeführt. Im GW wird dann auch outstandingAck wieder auf 0 gesetzt.
Immer noch alles OK.
Allerdings erfolgt jetzt kein Wechsel vom Node Status auf ALIVE. Er bleibt bei NACK stehen, bis ein neuer Befehl erfolgreich gesendet wird. Das entspricht aber nicht dem tatsächlichen Verhalten.

@Beta-User: Ich habe mir daraufhin noch mal deine Beschreibung durchgelesen. Vermutlich hast du das Verhalten hier beschrieben
Zitat von: Beta-User am 08 April 2018, 11:13:42
...
Hat das GW nach Ablauf der Zeit timeoutAck noch eine zuzustellende Sendung an eine Node, wird der Status des Devices zu "NACK" mit Event und bleibt auch so, bis die nächste Message an die Node zugestellt wurde und die Queue dann leer ist.
...

Ich kann irgendwie den Grund für dieses Verhalten nicht nachvollziehen. Ich hätte jetzt wieder einen Wechsel auf ALIVE erwartet.

Kleine Notiz am Rande: Mein "notify", das ich eigentlich mal für die Homematic Geräte programmiert habe, um mir bei fehlenden ACK eine Pushover Nachricht zu senden, hat mich zu meiner Überraschung bei diesen Tests sofort informiert, läuft also super!
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)

Beta-User

Moin,

Danke für die positive Rückmeldung!

Was das beobachtete Verhalten angeht, ist das "works as designed" (und versucht zu beschreiben).

Es gibt hier zwei Wege, das zu lösen:
- Man könnte den ack-Timer ständig erneuern, um zu sehen, ob es (doch noch) was neues gibt. Das wäre zwar möglich, aber ob das sinnvoll wäre, bin ich nicht so recht sicher: Wir haben dann ja (zu irgend einem Zeitpunkt) ein Problem in der Kommunikation, und eine vollständige Selbstheilung ist eher die Ausnahme, es sind eher Benutzereingriffe erforderlich. Dann kann man ja einen Befehl senden und sieht das Ergebnis dann wieder recht zeitnah.
- Man kann auch die "andere", eigentlich unabhängige Auswertungs-/Timererneuerungsroutine für "Alive" mit nutzen, um zu prüfen, ob das Problem gelöst ist. Das erfordert zwar, dass auch das  2. Attribut gesetzt ist, im Zusammenspiel erscheint mir das aber sinnvoll und sollte durch eine Änderung in Zeile 648 zu machen sein (statt unless ...):

if ($hash->{STATE} ne "NACK" or $hash->{STATE} eq "NACK" and @{$hash->{IODev}->{messagesForRadioId}->{$hash->{radioId}}->{messages}} == 0) {


Mutige können gerne mit testen, konnte selbst erst mal nur einen (erfolgreichen) Schnelltest machen ;) .

Dass notify, die für HM angelegt sind sauber funktionieren, ist super, das war der Hintergedanke der Benennung mit "NACK". Der Begriff ist damit gesetzt, oder? Sonst Rückmeldungen zu "ALIVE/DEAD"?

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

alru

Moin,

zur den noch vorgeschlagenen Lösungen:
(1. Lösungsweg)
Ich kann deinem "works as designed" nach nochmaliger Überlegung zustimmen. Letztendlich ist es schon sinnvoll, den letzten Fehlerzustand festzuhalten, auch wenn ich den mit einer Notification erhalte.
Also meinetwegen kann das so bleiben !

(2.Lösungsweg)
Deinen zweiten Lösungsweg habe ich nicht so ganz verstanden und auch den Code habe ich nicht ausprobiert.

Einen Hinweis noch: "NACK" würde ich sehr gerne so behalten, "ALIVE/DEAD" sind bei HM klein geschrieben. das wäre zur Vereinheitlichung noch schön, wenn man das ändern könnte.

Also ein echter Mehrwert diese Änderung!!!
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)

Beta-User

#12
So,

anbei eine aktualisierte Fassung, ungetestet, aber mit dem Zutrauen, dass das so funktioniert ;) .

Changelog:
- "alive" und "dead" statt der großgeschriebenen Varianten. Danke für den Hinweis!
- Zeile 648 geändert wie vorhin beschrieben.

Zu dem 2. Punkt: sobald alles wieder läuft und nichts mehr zuzustellen ist, kann der Status m.E. auch wieder auf "alive" gesetzt werden (macht HM ja auch ähnlich, nur dass dort die Sendeversuche irgendwann abgebrochen werden, was MySensors nach meinem Stand der Erkenntnisse nicht macht). Dann hat man den jeweils letzten bekannten Stand.

Das finde ich eigentlich ein besseres "Design"... Deswegen ist es jetzt soweit drin, als es keinen wesentlichen zusätzlichen Rechen-und Prüfungsaufwand darstellt. (Ich mußte auch erst lernen, wie man sowas überhaupt umsetzt, deswegen habe ich das Ausgangs-"Design" erst mal eher in der Basisvariante gehalten).

Aber den (weiteren)  Aufwand, das aktiv durch eine Erneuerung des Ack-Timers zu prüfen würde ich nicht treiben wollen (wäre vom Code her kein großes Problem, man könnte dabei auch ggf. dann die Prüfintervalle immer länger werden lassen). Im Prinzip betrifft das aber eh' nur rein passive Nodes (die nicht zyklisch irgendwas senden); wer da ein Ack will, wird die Node in der Regel sowieso über irgendeinen Automatismus ansprechen (at, weekdayTimer...), dann ist ja auch wieder eine neue Message da, die den Status ggf. zurücksetzt.

Zitat von: alru am 11 April 2018, 08:55:35
Also ein echter Mehrwert diese Änderung!!!
:) Mal schauen, ob sich noch mehr finden, die das genauso sehen...

Gruß, Beta-User

EDIT: Anhang gelöscht, da jetzt per update verfügbar
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

Beta-User

Zitat von: Beta-User am 11 April 2018, 09:45:38
ungetestet, aber mit dem Zutrauen, dass das so funktioniert ;) .
Jetzt auch etwas getestet: Scheint zu funktionieren, wie es soll :) .
Ich lösche daher die Ausgangsversion in dem ersten Post dazu.

Gruß, Beta-User
Server: HP-elitedesk@Debian 12, aktuelles FHEM@ConfigDB | CUL_HM (VCCU) | MQTT2: MiLight@ESP-GW, BT@OpenMQTTGw | MySensors: seriell, v.a. 2.3.1@RS485 | ZWave | ZigBee@deCONZ | SIGNALduino | MapleCUN | RHASSPY
svn: u.a MySensors, Weekday-&RandomTimer, Twilight,  div. attrTemplate-files

alru

Moin,

kann ich bestätigen. Meine Tests waren ok. Ich wäre mit der Version erst mal glücklich!
Gruß,

Stefan
(Raspi 3B - Stretch / HM-LGW / HomeMatic / MySensors)