KNX Telegramme blockieren alle Threads

Mir ist in letzter Zeit schön öfter aufgefallen, dass mir alle verfügbaren Threads zulaufen, weil KNX Nachrichten nicht mehr abgesetzt werden konnten und IPS dann praktisch steht.

Ich muss dazu sagen, das ich einige Scripte laufen habe, die mit KNX_WriteDPTxx auf den Bus schreiben, nach dem Serverstart auch recht viel und auch sonst alle 5 Sekunden.

Sobald jetzt aber der KNX IP Router mal kurz nicht erreichbar ist, laufen die Threads dann alle zu (aktuell 100 max.).
Diese Probleme hatte ich noch vor einiger Zeit nicht.
Kann es sein, das durch die vor einiger Zeit veränderte maximale Scriptlaufzeit die Threads jetzt länger blockiert werden was zu diesem Überlauf führt?

Wie kann ich das am Besten verhindern?
Kann ich im Script irgendwie abfangen, ob eine bestehende Verbindung zum Router existiert und ggf. das senden unterdrücken?

Danke u. viele Grüße,
Doc

Es gibt mittlerweile keine maximale Scriptlaufzeit mehr. Die Scripte laufen, bis sie korrekt beendet werden.
Wenn sich jetzt ein Befehl weghängt, wird er nie beendet. Da hat man sehr sehr schnell alle Threads voll. Ist mir mit snmp auch passiert. Meine Lösung war leider nur, dass ich aktuell auf die für mich eigentlich sehr wichtigen Daten über snmp verzichte.

Eigentlich sollten die KNX Befehle maximal 5 Sekunden auf eine Antwort warten. Hast du da irgendwie eine Schleife drin oder ähnliches?

paresy

Nein, Schleifen habe ich in den KNX Scripten keine drin.
Aber ich habe z.B. einige Scripte, die alle 6 Sekunden aufgerufen werden, um meine MDT GT2 Glastaster mit wechselnden Informationen zu beschreiben.

Ich hatte vor einiger Zeit ja schon mal den Raspi in Verdacht, aber auch auf dem Windows Rechner tritt das auf.
Hatte das heute mal getestet und das Netzwerkkabel vom KNX Router getrennt und schon liefen die Threads voll.

In den Scripten ist immer nur ein bis zwei KNX_Write Befehl drin, die Scripte werden aber deutlich länger als 5 Sekunden blockiert.
Wie kann ich das abfangen?

Wenn ich das so recht überlege, wenn ich im Script 2 KNX_Write Befehle habe und die dann damit das Script 10 Sekunden blockieren aber das Script durch den Scripttimer alle 6 Sekunden erneut aufgerufen wird?
Kann es daran liegen?

Definitiv. Du müsstest also deinen Timer auf 10s setzen. Dann würde das Problem nicht auftreten. :slight_smile:

paresy

Das ist mir aber zu lang und ich muss halt 2 Zeilen gleichzeitig beschreiben.
Kann ich den Status der Verbindung nicht vorher irgendwie abfragen?
Oder ggf. das Script für eine 2. Ausführung blockieren, wenn das alte noch läuft.
So ist das echt bescheiden das IPS hängt nur aufgrund fehlender Verbindung.

Sehr gute Idee. Klar!

paresy

Eine Möglichkeit den Verbindungsstatus vorher zu checken gibt es nicht?

Da die Verbindung bei UDP Stateless ist, weißt du nicht wirklich ob der Gegenüber gerade da ist oder nicht. Somit ist das meiner Meinung nach die beste Möglichkeit. Bis das KNX Gateway dies merkt und auf „rot“ schaltet kann es schon mal einen Moment dauern. Falls das in deinem Fall schnell genug geht, kannst du per IPS_GetInstance natürlich auch den Status prüfen.

paresy

Danke dir, werde ich morgen mal beides testen.
VG,
Doc

Hallo Michael,
ich habe mir gerade die hängenden Threads bei Verbindungsverlust noch einmal angeschaut.
Wenn ich dich richtig verstanden habe, müsste das Script bei 2x KNX_Write und unterbrochener Verbindung nach ca. 10s. automatisch abgebrochen werden.

Wenn ich mir die Threadliste anschaue, hängen die Threads aber auch nach 3 Min. noch da drin.
Habe ich da einen Denkfehler oder müssten die nicht schon lange abgebrochen sein?

// Script zum Beschreiben des MDT Smart Tasters

$ID_Instanz_Text1 = 13207;
$ID_Instanz_Text2 = 25027;
$ID_Zaehler = 38971;

// -------------------------------------
$Zaehler = GetValue($ID_Zaehler);

switch ($Zaehler) {
           
        case 0    : $Text1 = "Uhrzeit";
                    $Text2 = date("H:i");
                    SetValue($ID_Zaehler, ($Zaehler + 1));
                    break;

        case 1    : $Text1 = "Batterie";
                    $Text2 = GetValue(16223)."% / ".GetValue(19925)."W";
                    SetValue($ID_Zaehler, ($Zaehler + 1));
                    break;

        case 2    : $Text1 = "PV Leistung";
                    $Text2 = GetValue(27358)."W/".round(GetValue(16048),1)."kWh";
                    SetValue($ID_Zaehler, ($Zaehler + 1));
                    break;

        case 3    : $Text1 = "Netzbezug";
                    $Text2 = round(GetValue(36301),0)."W/".round(GetValue(22013),1)."kWh";
                    SetValue($ID_Zaehler, ($Zaehler + 1));
                    break;

        case 4    : $Text1 = "7Tage Inzidenz";
                    $Text2 = "Kleve: ".round(GetValue(49407),1);
                    SetValue($ID_Zaehler, ($Zaehler + 1));
                    break;

        case 5    : $Text1 = "7Tage Inzidenz";
                    $Text2 = "NRW: ".round(GetValue(24839),1);
                    SetValue($ID_Zaehler, ($Zaehler + 1));
                    break;

        case 6    : $Text1 = "7Tage Inzidenz";
                    $Text2 = "BRD: ".round(GetValue(37675),1);
                    SetValue($ID_Zaehler, 0);
                    break;                    

}

KNX_WriteDPT16($ID_Instanz_Text1, $Text1);
KNX_WriteDPT16($ID_Instanz_Text2, $Text2);

Jein. Wenn du zu viele Threads hast, werden die Anfragen ja nicht direkt nach 10 Sekunden abgebrochen, sondern erst, wenn diese auch versendet wurden. D.h. wenn die Befehle noch Warten um versendet werden zu können, staut es sich und es kann viel länger dauern.

paresy

Das hieße dann aber, das die KNX Anfragen/Abbrüche aus verschiedenen Scripten dann doch alle seriell nacheinander abgearbeitet werden und nicht aus verschiedenen Threads parallel?

Ich habe jetzt mal 4 Scripte mit Semaphore versehen, dann ist die Threadqueue bei einem Abbruch deutlich entspannter.
Beunruhigt mich aber ein bisschen, da hier auch viele Scripte lange hängen, die eher selten aufgerufen werden.

VG,
Doc

Korrekt. Wir warten immer kurz auf das ACK. Wenn das nicht mehr kommt, dann stockt es.

paresy

OK,
wäre es dann nicht besser dies intern von seitens IPS abzufangen?
Wenn z.B. ein KNX_Write an eine bestimmte GA kein ACK zur Folge hat, das weitere schreiben auf eben diese Instance bis zum ACK oder x Sekunden zu verhindern um ein Überlauf zu vermeiden?
Wenn man das alles jetzt auch noch in den Scripten abfangen muss, gerade bei Systemen mit großen KNX Installation wird das doch recht aufwendig.
Und bei einem Ausfall des KNX IP Interfaces/Routers aus welchen Gründen auch immer würde sich die Warteschlange doch immer weiter aufbauen, auch wenn nach 5 Sekunden das Paket verworfen wird?

Ich habe hier sehr viele Skripte, die ähnlich oft Dinge auf den Bus senden und hier läuft gar nichts zu? Auch wenn ich das IP Interface vom Netz nehme, läuft IPS weiter. Was mache ich falsch?

Du sendest nicht genügend schnell auf den Bus.
Nach Paresy’s Beschreibung müssten auch deine Threads zulaufen, wenn du schneller Daten „nachlegst“ als durch die 5s. Verzögerung wieder freigegeben werden.
Oder ist das ein Unterscheid, ob du ggf. ein IP-Interface nutzt oder einen IP Router?

Danke, werde das testen.

Da IPS kein Routing unterstützt, ist es egal.

Ich kann das Verhalten Bestätigen. Wenn die IP-Schnittstelle nicht da ist oder nicht erreichbar ist, hängen Threads, die etwas senden möchten, komplett fest. Irgendwann sind alle Threads zu.

Das ist gar nicht mal so gut …