Änderung am TUL Modul um das Aufhängen zu verhindern

Begonnen von strel, 12 September 2014, 16:59:37

Vorheriges Thema - Nächstes Thema

strel

Ein Kollege von mir hat FHEM mit KNX im Einsatz und immer wieder das Problem, dass sich Fhem aufhängt. Dieses Problem ist scheinbar nicht unbekannt und wir haben viele hinweise darauf, aber keine wirkliche Lösung gefunden. 
Da wir den Fehler sicher reproduzieren konnten, konnte ich das Problem einkreisen und eine Änderung schreiben um es zu verhindern.

Das Problem lag an der Funktion getRequestFixLength die solange in einer Schleife verbleibt, bis die gewünschte Anzahl an Bytes gelesen wurde. Wenn der Bus (aus welchem Grund auch immer) aus dem "Takt" gerät, hängt Fhem in dieser Schleife fest. Natürlich gebe ich allen Recht die jetzt sagen, man sollte die Ursache lösen und nicht die Symptome lindern. Dennoch bin ich der Meinung, dass ein einfacher Fehltritt, der bei einem Feldbus schon mal auftauchen kann, nicht gleich solche Folgen haben sollte. Zudem der Fehler in unserem Fall nicht an einer instabilen Spannungsversorgung, sondern an zu viel Traffic auf dem Bus kam.
Das bisherige Modul erwartet nach dem Senden eine gewisse Antwort (my $response = getRequestFixLength($hash,($#encmsg + 1)/2+1);), der aber in unserem Fall eine Wiederholung eines anderen Teilnehmer zuvor kam und somit den Bus aus dem Takt gebracht hat.

Um das Problem zu beheben habe ich eine nicht blockierende Funktion geschrieben, die keine feste Länge liest, sondern immer exakt ein Telegramm zurück liefert. Da ich sowohl das Kontrollbyte als auch die Checksumme überprüfe, sollte das ziemlich sicher Funktionieren und hat auch in unserem Fall (noch ohne Checksumme) den Fehler sicher umgangen. Wenn der Bus aus dem Takt gerät wird solange das erste Byte im Datenstrom verworfen bis wider ein gültiges Telegramm erkannt wurde. Somit bleibt im Ernstfall Fhem nicht hängen sondern bekommt höchstens ein, zwei Änderungen nicht mit.

Der einzige Nachteil an dieser Funktion ist, dass sie, wenn nicht genug Bytes zum lesen anstehen, um nicht zu Blockieren, erst ein mal undef zurück liefert und erst beim nächsten Aufruf die gesamte Nachricht. Bisher wurde aber ein undef als Rückgabewert als Fehler interpretiert und der Bus disconnectet. Um nicht das ganze Modul umschreiben zu müssen, habe ich das erst ein mal ausgeblendet. Das ist nicht schön, aber durch die neue Funktion sollte ein Disconnect nicht mehr nötig sein. Ich habe allerdings keine Ahnung, wie sich das auf die eibd Variante auswirkt.

Wenn Interesse besteht werde ich das geänderte Modul hier hoch laden, allerdings nicht vor Montag, da ich noch einen kleinen Fehler mit der Checksumme behoben habe, den ich noch testen muss. Aber ihr dürft gerne schon mal eure Meinung dazu äußern.

strel

Wie versprochen hier das veränderte Modul. Mit dem USBDev scheint es keine Probleme zu geben, die Variante mit dem eibd kann ich nicht testen. Ich werde noch ein paar Tage hier vorbei schauen, falls jemand einen Fehler entdeckt, aber ich bin hier kein ständiger Gast.