IPS 6.3 / Umsetzung LCN Commandos

Hallo zusammen,

ich habe ein paar Test zur 6.3 und der Umsetzung zur Auswertung der Quiitierung gemacht:
a) Schalten eines Ausgangs ( $noerror = RequestAction($id_Test_State, $State); )

Wenn ich es richtig beobachte, wird das Schalten des Ausgangs schon nach Empfang der Quittierung in IPS gesetzt.
(z.B. -M000013!).
Das passt aus meiner Sicht nicht, es bestätigt lediglich, das der Befehl am Modul angekommen ist.
Die Umsetzung in IPS sollte erst erfolgen, wenn das auch durch das Modul gemeldet wird (z.B. :M000013A3100).
Ich muss leider beobachten, da die Meldung zum Status des Ausgangs auch mal etwas braucht. (> 4 Sekunden)

Was mir immer noch fehlt ist eine Wiederholung des Befehls, wenn es nicht umgehend Quittiert wird.

Bei dem Befehl LCN_SendCommand sehe ich keine Auswertung der Quittierung.

Das ist korrekt.

Das wäre über den Ablaufplan möglich. Dort gibt es passende Retry’s.

Wenn ich in den Quellcode gucke, kann das eigentlich nicht sein. Die Variable wird erst gesetzt, wenn das echte Feedback von Gerät kommt. Wir haben das „direkt“ setzen bei einigen anderen System implementiert → Das Verhalten ist dann aber eigentlich immer über den Satz „Emuliere Status“ veränderbar. Bei LCN warten wir jedoch immer auf das echte Feedback des Wertes.

paresy

Thema Quittierung:
Die Quittierung stellt sicher, das das Kommando am Modul angekommen ist.
Das ist in meinem Verständnis mehr eine Absicherung das der Bus frei ist.
Wiederholungen auf Applikationsebene führen zu langen Laufzeiten / Verzögerungen und machen selbst einfache Abläufe komplex. Das kann viel besser innerhalb von IPS umgesetzt werden.

Durch die Auswertung der Quittierung und Wiederholung würde vermutlich auch die meisten Fehlermeldung zu den Statusabfragen sich erledigen und Warnungen bei Kommandos.

Gibt dafür einen Grund?
Ich nutze den Befehl gerne um Tasten ins LCN System zusenden.

Ich werde einen neunen Trace machen und sende dir das Ergebnis, vielleicht interpretiere ich es falsch.

Gruß
Jan Peter

Hallo paresy,

[quote=„paresy, post:2, topic:130378“]

Das habe ich mir wieder angesehen und es lässt sich nicht bestätigen.

Folgende Versuchs Reihe
Ausgang Schalten (bei Fehler wird der Befehl wiederholt)

Event wertet Ausgang Aus / Timeout 30 Sekunden
2 Sekunden Warten
Ausgang Umschalten (bei Fehler wird der Befehl wiederholt)

Das Ganze 10.000Mal.

Ergebnis:
35 Kollisionen = > LCN Befehl meldet Fehler ( $noerror = RequestAction($id_Test_State, $State); )
Aber auch 4 mal der Event nicht ausgelöst.

Im Trace sieht das wie folgt aus:


Schalten
09/24/22 02:02:26 | TXT | WAITING | >M000013!A3DI100000<LF>
09/24/22 02:02:26 | HEX | WAITING | 3E4D30303030313321413344493130303030300A
09/24/22 02:02:26 | TXT | TRANSMIT | >M000013!A3DI100000<LF>
09/24/22 02:02:26 | HEX | TRANSMIT | 3E4D30303030313321413344493130303030300A

Quittierung
09/24/22 02:02:26 | TXT | RECEIVED | -M000013!
09/24/22 02:02:26 | HEX | RECEIVED | 2D4D30303030313321

Ausgang ist geschaltet
09/24/22 02:02:26 | TXT | RECEIVED | :M000013A3100
09/24/22 02:02:26 | HEX | RECEIVED | 3A4D3030303031334133313030
// so soll es sein...


Schalten
09/24/22 02:02:27 | TXT | WAITING | >M000013!A3DI000000<LF>
09/24/22 02:02:27 | HEX | WAITING | 3E4D30303030313321413344493030303030300A
09/24/22 02:02:27 | TXT | TRANSMIT | >M000013!A3DI000000<LF>
09/24/22 02:02:27 | HEX | TRANSMIT | 3E4D30303030313321413344493030303030300A

keine Quittierung
09/24/22 02:02:27 | TXT | RECEIVED | %M000013.A01208245
09/24/22 02:02:27 | HEX | RECEIVED | 254D3030303031332E413031323038323435

Ausgang ist geschaltet
09/24/22 02:02:27 | TXT | RECEIVED | :M000013A3000
09/24/22 02:02:27 | HEX | RECEIVED | 3A4D3030303031334133303030

Schalten
09/24/22 02:02:28 | TXT | WAITING | >M000013!A3DI100000<LF>
09/24/22 02:02:28 | HEX | WAITING | 3E4D30303030313321413344493130303030300A
**// 4 Sekunden passiert nichts**
09/24/22 02:02:32 | TXT | TRANSMIT | >M000013!A3DI100000<LF>
09/24/22 02:02:32 | HEX | TRANSMIT | 3E4D30303030313321413344493130303030300A

???? Erneutes Schalten
09/24/22 02:02:32 | TXT | WAITING | >M000013!A3DI000000<LF>
09/24/22 02:02:32 | HEX | WAITING | 3E4D30303030313321413344493030303030300A

Quittierung
09/24/22 02:02:32 | TXT | RECEIVED | -M000013!
09/24/22 02:02:32 | HEX | RECEIVED | 2D4D30303030313321

???? Erneutes Schalten
09/24/22 02:02:32 | TXT | TRANSMIT | >M000013!A3DI000000<LF>
09/24/22 02:02:32 | HEX | TRANSMIT | 3E4D30303030313321413344493030303030300A

Quittierung
09/24/22 02:02:32 | TXT | RECEIVED | -M000013!
09/24/22 02:02:32 | HEX | RECEIVED | 2D4D30303030313321

Ausgang ist geschaltet
09/24/22 02:02:32 | TXT | RECEIVED | :M000013A3000

Timeout???
09/24/22 02:02:32 | HEX | RECEIVED | 3A4D3030303031334133303030
09/24/22 02:02:33 | TXT | TRANSMIT | ^ping507<LF>
09/24/22 02:02:33 | HEX | TRANSMIT | 5E70696E673530370A
09/24/22 02:02:33 | TXT | RECEIVED | ^ping507-
09/24/22 02:02:33 | HEX | RECEIVED | 5E70696E673530372D
.... kein M013

// Jetzt geht es weiter
09/24/22 02:02:58 | TXT | WAITING | >M000013!A3DI100000<LF>
09/24/22 02:02:58 | HEX | WAITING | 3E4D30303030313321413344493130303030300A
09/24/22 02:02:58 | TXT | TRANSMIT | >M000013!A3DI100000<LF>
09/24/22 02:02:58 | HEX | TRANSMIT | 3E4D30303030313321413344493130303030300A
09/24/22 02:02:58 | TXT | RECEIVED | -M000013!
09/24/22 02:02:58 | HEX | RECEIVED | 2D4D30303030313321

Meines Erachtens entsteht es, da der Timeout für die Quittierung 5 Sekunden ist.
Das ist länger als meine Wartezeit. Der Ausgang wurde geschaltet, obwohl keine Quittierung ist erfolgt ist.
// Eine Automatische Befehlswiederholung nach kurzem Timeout hätte es anders aussehen lassen.
Unbeantwortet bleibt wann dann die Quittierung gekommen wäre

Das ist soweit zwar logisch, erklärt aber nicht warum 4 Sekunden lang auf dem Bus eine Ruhe war.
Das kann ich nicht erklären, als wäre alles stehen geblieben auf dem LCN Bus.

Ich bitte dich hiermit die Befehlswiederholung mit einem kurzen Timeout einzubauen. 5 Sekunden Timeout sind wirklich lang.

Hallo paresy,

ich habe den Versuch wiederholt mit einer Wartezeit von 10 Sekunden.
Das Ergebnis entspricht meiner Erwartung, alle Schaltvorgänge sind sauber verlaufen.

Das ändert nichts an der Anfrage, eine Befehlswiederholung einzubauen, wenn die Quittierung nicht innerhalb kurzer Zeit kommt.

Die 5 Sekundenwartezeit passieren leider zu häufig.

Gruß
Jan Peter

Die 5 Sekunden kommen nicht von ungefähr. Insbesondere beim Abfragen von Werten der alten Module dauert es mal länger. Wobei dort @ralf sagte, dass die sehr sehr unzuverlässig kommen und das Log zumüllen. Ich bin am überlegen dies ohne Quittierung laufen zu lassen (da unkritisch) und dann könnte man die Wartezeit auch reduzieren. Falls da jemand Tests machen will, wie lange sowas dauern sollte, dann wäre das cool. (Andere System bekommen von uns 2 Sek)

Da wir aktuell in anderen Systemen ebenfalls keine Wiederholungen auf Systemebene anbieten, sehe ich hier wenig Chance, dass wir bei LCN damit kurzfristig anfangen werden.

paresy

Naja, nach deinen letzten Änderungen gibt es immer mal wieder Fehlermeldungen, aber deutlich weniger wie vorher. Ohne Quittung würde halt keine Fehler mewhr verursachen, wenn das konfigurierbar wäre, wäre es super, aber ich kann auch so damit leben.

Die Quittierung ist ein zusätzliches Signal auf dem Bus, nicht viel Content aber dennoch zusätzlich.
Von daher entsteht zusätzlicher Traffic.
Die Wartezeit reduzieren ist eine Spielart, die das eigentliche Problem nicht löst.

Mein Verständnis zu dieser Quittierung (Korrektur immer gerne)
Die Quittierung signalisiert dem Sender, das sein Befehl an das Modul gesendet werden konnte.
Der Bus war frei. Ist der Bus verstopft, gibt es keine Quittung. (es gibt keine Bus ist frei Kennung)
Daher hilft dann nur eine Wiederholung.

Bei meinem System, (46 Module) werden ca. 35 Befehle von 10.000 nicht quittiert (5 Sekunden Timeout). Das bezieht sich jedoch auf einen Durchschnitt.
Leider gibt es auch Lastspitzen, da merke ich es deutlicher. Dazu ist mir kein Weg eingefallen es in Zahlen umzusetzen. (muss ich drüber Nachdenken)

Das ihr ungerne Wiederholungen anbietet ist bei mir angekommen, löst bei mir die Frage aus warum? Hier würde das System wesentlich robuster werden.

Gibt dafür einen Grund?

Gruß Jan Peter

Es gibt diverse Arten von Quittierungen. Du müsstest explizit angeben, welche Art von Quittierung du erwartest. (Das war übrigens ein expliziter Wunsch von dir, dass wir die Quittierungen strikter durchführen :slight_smile: ) D.h. manchmal kommt die Quittierung mit : und manchmal kommt halt nur ein Wert mit % den wir aus Quittierung annehmen. Wir müssten also einen LCN_SendCommandEx anbieten dem du mitteilen kannst, worauf du eigentlich wartest. Theoretisch kann es ja sein, dass auf einen Befehl gar keine Antwort kommen muss. Das muss also konfigurierbar sein je nach PCHK Befehl.

Leider recht simpel: Der eher hohe Aufwand rechtfertigt aktuell nicht die Nachfrage nach solch einem Feature. Zumal der Ablaufplan ein Wiederholen Feature integriert hat, über den man kritische Abläufe realisieren könnte.

paresy

Hallo paresy,

Ich war davon ausgegangen, das alle Funktionsbefehle eine Quittierung anfordern können.
Beispiel:

M000013!MWT12 // Befehl
-M000013! // Quittung

Mir ging es nur um die Auswertung der Quittierung.
%xxx sind Messwerte, !xxx sind Statusmeldungen.

Moin,
ich glaube, wir müssen Unterschiede sehen …
Die LCN-Module „unter sich“ haben ‚nur‘ eine Kollisionserkennung (schauen also ob der ‚Bus frei‘ ist), eine Quittung für ein ausgeführtes Kommando lösen die Module nicht aus - zumindest sieht man da nichts im Bus-Monitor der LCN-Pro. Die Quittung kommt nur beim programmieren von Modulen mit der Pro.
Die Module reagieren nur auf eine Statusmeldung, was bei aufgerufenen Kommandos eigentlich zwangsläufig immer die Folge ist. Solche Meldungen können (nach einer älteren Aussage der LCN-Hotline) auch mal „verschluckt“ werden - vor allem beim dimmen mit großer Rampe (was eigentlich alle 2% eine Meldung erzeugt) ist das gut zu beobachten. Damit ist z.B. auch ein Schalt-Kommando an eine LED („Lämpchen“, für Summenbildung etc.) sicherer als das nur auf eine Meldung reagieren zu lassen.
Aus dem Gefühl/Erfahrung ist dieser „Effekt“ bei älteren Anlagen/Modulen häufiger zu beobachten.
Meine Versuche mit einem ‚nagelneuen‘ LCN-VISU (das jetzt laut ‚Waschzettel‘ eine Kollisionserkennung integriert haben soll) zeigen bei Auslösungen über die PCHK keinerlei Quittungen im Busmonitor. Die (bei mir schon recht seltene) „Nichtausführung“ von Kommandos ist aber auch damit immer noch vorhanden.

Ich weiß, dass die im Symcon fehlende Quittung von der LCN-Hotline beanstandet und gefordert wurde. Der Zeitrahmen in dem @paresy das umgesetzt hat ist typisch (für mich auch „legendär“) für Symcon. Einen wirklichen „Nutzen“ kann ich aber bislang nicht erkennen - ich sehe das ein wenig als „Ausrede“ der Hotline, weil sie derzeit keine bessere Idee zur ‚Fehlerbehebung‘ hatten. Da schiebt man das eben auf „systemfremde“ Hard- und Software. Soll heißen: warum hat man jetzt im VISU plötzlich eine Kollisionserkennung (= „sie arbeiten daran“)?

Das ist nur meine Meinung/Erfahrung.
Grüße, Uwe

Hallo parsey, hallo zusammen,

wird es zum 6.4 eine Wiederholung der LCN Befehle geben?

Hintergrund: Ich habe mir für die Abfrage der Temperatur bei den alten Modulen eine Routine geschrieben zur Abfrage. Seit dem kommt hier nicht mehr zu Warnungen / Fehlern und langen Wartezeiten.
Vorgehen:

  • Senden des Befehls zur Abfrage
  • Warten auf Messwert oder Quittung / max 1 Sekunde
  • Bei Timeout Wiederholung der Abfrage (Nach 4 Timeouts Fehlermeldung)

Ansonsten: Wiederholung alle 60 Sekunden zur Messwert Ermittlung

Gruß
Jan Peter

Nein. Ich plane aber die Quittierungen für die Anfrage der Werte von alten Module zu deaktivieren (da die total unzuverlässig sind und genau dieses Problem haben), sodass man die Quittierungen aktiv haben kann (für das Zuverlässige) und aus hat für diesen Problemfall :slight_smile:

paresy

Hallo paresy,

kann man so machen.
Ein Aber sei erlaubt, durch die Befehles Wiederholung (bei generischen Einbau) könnten ungewollte Wartezeiten als Warnungen stark reduziert werden.
Daher würde es mich weiterhin sehr freuen wenn ihr es umsetzen würdet.

Gruß Jan Peter

Moin @paresy ,
finde ich gut - eigentlich kann man die gesamte Anfrage für Messwerte bei neuen Modulen auch gänzlich deaktivieren. Ab FW 17… „plappern“ die Module ohnehin bei jeder Wertänderung ihre Messwerte in den Bus.
Das gilt aber nicht für andere abzufragende Werte (z.B. ‚Tableau-Lämpchen‘), die müss(t)en auch bei aktuellen Modulen immer noch abgefragt werden. Die Logik/Summen ersetze ich (dank deines Messe-Tipps) mittlerweile durch eure Aktivliste. Das funktioniert viel besser als die ständige Pollerei und Reaktion auf ‚unsichere‘ Statusmeldungen. Wobei mir (auffällig in meiner älteren Anlage zu Hause) auch ab und an mal eine Statusmeldung eines Ausgangs untergeht (meistens sind das die mit Rampe 0 nur geschalteten Ausgänge - da kommt halt nur eine Meldung). Ich schicke deshalb in längeren Abständen (und beim Symcon-Start) eine Statusabfrage der Aktoren per PCK in den Bus.
Das ist „systembedingt“ wohl nicht anders möglich.

Grüße, Uwe

1 „Gefällt mir“

Hallo zusammen,
ich eine zentrale Umsetzung einer Quittungsauswertung und Befehlswiederholung umgesetzt.
Das läuft super und es kommen bei mir keinen Warnungen etc durch LCN provoziert.
Anbei das Konzept.

Wenn Interesse besteht sende ich gerne auch die entsprechenden Skripte und erstelle eine Anleitung.

Im Kern Skript werden überschneide Befehle an ein Modul verhindert, die Quittierung ausgewertet mit entsprechender Umsetzung einer Commando Wiederholung bei Bedarf.

Gruß Jan Peter

1 „Gefällt mir“

Hallo Peter,

super Arbeit !
Bitte teile die Scripte / Anleitung.
Grüße
Silvio

Moin Jan Peter,
ich wäre auch daran interressiert und würde das gerne ausprobieren (kann ja nur besser werden).

BTW: sehen wir uns im Januar in Lübeck? Im persönlichen Gespräch lässt sich doch viel besser „lästern“ als ich das in einem Forum tun würde :melting_face:

Grüße, Uwe

Hallo zusammen,

hiermit die Anleitung.
a) So sieht meine Strukur aus:

b) Die Sockets:

  1. Server Socket einrichten (z.B. Name Server Socket LCN Out) einrichten, Port 2000
  2. IP und Port des LCN Client Socket anpassen IP 127.0.0.1, Port 2000
    (nun sende IPS alle Commandos an den Server Socket)
  3. Client Socket einrichten (z.B. Name Client Socket LCN In), die IP Adresse zeigt eure LCN Anbindung (in der Regel Port 4114)

Die Scripte in der LCN Kategorie an legen.
a) Script „Mxx LCN Repeat“ (Name muss so lauten)

<?php
$id_client_socket = XXXXXX;
$id_server_socket = XXXXXX;

if ($_IPS['SENDER'] == "Execute")
{
    return;
}
  
if ( ($id_RequestStatus =  @IPS_GetObjectIDByIdent('RequestStatus', $_IPS['SELF'])) == false)
{
    $Name = "RequestStatus";
    $Ident = "RequestStatus";

    $id_RequestStatus = IPS_CreateVariable(3);
    IPS_SetParent($id_RequestStatus,$_IPS['SELF']);
    IPS_SetName($id_RequestStatus, $Name);
    IPS_SetIdent($id_RequestStatus, $Ident);
    IPS_SetVariableCustomAction($id_RequestStatus, $_IPS['SELF']);
    SetValueString($id_RequestStatus, 'none');
}

$startstring = substr($_IPS['MESSAGE'], 0 ,2);
    

// Warten wenn der vorhergehende Befehl noch nicht verarbeitet ist
if ( ($_IPS['SENDER'] == "RunScript") and ($_IPS['SENDER_NAME'] == "Server") )
{
    if ($startstring == '>M') 
    {
        // warten darauf, das letzte Befehl des Moduls verarbeitet wurde
        for ($WaitCounter = 1; ( ($WaitCounter <= 6) and ( GetValueString($id_RequestStatus) != 'none') )    ; $WaitCounter++) 
        {
            if ($WaitCounter > 3)
            {
                IPS_LogMessage( IPS_GetName($_IPS['SELF']) , ' overlap ' . $WaitCounter);
            }
            ips_sleep(300);
        }

        $requesttype = substr($_IPS['MESSAGE'], 8 ,3);

        switch ($requesttype)
        {
            case '!MW': //Messwert Anfrage
            {
                SetValueString($id_RequestStatus, 'Messwert');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;

            case '!RE': // Sollwert Anpassung
            {
                SetValueString($id_RequestStatus, 'Regler');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;
        
            case '!A1': // Ausgang schalten
            {   
                SetValueString($id_RequestStatus, 'Ausgang 1');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;
            case '!A2': // Ausgang schalten
            {
                SetValueString($id_RequestStatus, 'Ausgang 2');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;
            case '!A3': // Ausgang schalten
            {
                SetValueString($id_RequestStatus, 'Ausgang 3');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;   
            case '!A4': // Ausgang schalten
            {
                SetValueString($id_RequestStatus, 'Ausgang 4');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;

            case '!R8': // Relais schalten
            case '!RL': // Relais schalten
            {
                SetValueString($id_RequestStatus, 'Relais');
                $_IPS['MESSAGE'][10] = '8';
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;

            case '!TS': // Taste Senden
            {
                SetValueString($id_RequestStatus, 'Taste');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;

            case '!LA': // Lämpchen
            {
                SetValueString($id_RequestStatus, 'Laempchen');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;

            case '!SM': // Satusabfrage
            {
                SetValueString($id_RequestStatus, 'Statusabfrage');
                //SetValueString($id_RequestCommand, $_IPS['MESSAGE']);
            }
            break;

            default:
                IPS_LogMessage('LCN_Repeat', 'Unbekannter Coammdo Typ '. $startstring . " " .$requesttype); 
            break;
        }

        // erstes Kommando senden
        CSCK_SendText($id_client_socket ,$_IPS['MESSAGE'].chr(10)); // an den Client Socket LCN
        
        for ($RepeatCounter = 1; ($RepeatCounter <= 12); $RepeatCounter++) 
        {
            IPS_Sleep(100);
            $RequestStatus = GetValueString($id_RequestStatus);
   
            if ($RequestStatus == 'requested')
            {
                 SetValueString($id_RequestStatus, 'none');
                 return;
            }
            else
            {
                //echo '.';
                CSCK_SendText($id_client_socket ,$_IPS['MESSAGE'].chr(10)); // an den Client Socket LCN
            }
        }

        IPS_LogMessage('LCN Repeat', 'Retrys aufgebraucht ' . $_IPS['SELF'] .' '. $RequestStatus );
        return;
    }
    else
    {
        IPS_LogMessage('LCN_Repeat', 'Unbekannter Coammdo Typ '. $_IPS['MESSAGE'] );    
    }

}

if ( ($_IPS['SENDER'] == "RunScript") and ($_IPS['SENDER_NAME'] == "Client") )
{
    $modulidtring = substr($_IPS['MESSAGE'], 5 ,3);
    $RequestStatus = GetValueString($id_RequestStatus);

    switch ( $RequestStatus )
    {
        case 'Messwert': // Messwertanfrage
        {
            //if ( ($startstring == '%M') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Messwert erhalten
            if ( (substr($_IPS['MESSAGE'], 0 ,9) == '%M000' . $modulidtring . '.') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Messwert erhalten
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
               // echo '? Messwert '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;

        case 'Regler': //Sollwert Anpassung
        {
            //if ( (substr($_IPS['MESSAGE'], 0 ,9) == '%M000' . $modulidtring . 'S') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Sollwert erhalten
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!')// Sollwert erhalten
            {
                // Antwort :M00000x??255
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Regler '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;

        case 'Taste': //Taste wurde gesendet
        {
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!')
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Taste '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;


        case 'Ausgang 1': //Ausgang geschaltet
        {   
            //if ( (substr($_IPS['MESSAGE'], 0 ,10) == ':M000' . $modulidtring . 'A1') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Ausgang erhalten
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!')
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Ausgang '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;

        case 'Ausgang 2': //Ausgang geschaltet
        {   
            //if ( (substr($_IPS['MESSAGE'], 0 ,10) == ':M000' . $modulidtring . 'A2') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Ausgang erhalten
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!')
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Ausgang '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;

        case 'Ausgang 3': //Ausgang geschaltet
        {   
            //if ( (substr($_IPS['MESSAGE'], 0 ,10) == ':M000' . $modulidtring . 'A3') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Ausgang erhalten
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!')
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Ausgang '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;

        case 'Ausgang 4': //Ausgang geschaltet
        {   
            //if ( (substr($_IPS['MESSAGE'], 0 ,10) == ':M000' . $modulidtring . 'A4') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Ausgang erhalten
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!')
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Ausgang 4'. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;


        case 'Relais': //Relais geschaltet
        {   
            //if ( (substr($_IPS['MESSAGE'], 0 ,9) == ':M000' . $modulidtring . 'R') or ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') )// Relais erhalten
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!')
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Relais '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;

        case 'Laempchen': // Lämpchen geschaltet
        {   
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') //
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Lämpchen '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;

        case 'Statusabfrage': //Status Abfrage
        {   
            if ($_IPS['MESSAGE'] == '-M000' . $modulidtring . '!') //
            {
                SetValueString($id_RequestStatus, 'requested');
            }
            else 
            {
                //echo '? Statusabfrage '. $RequestStatus . " " . $_IPS['MESSAGE'];
            }
        }
        break;
        
        default:
            //IPS_LogMessage('LCN_Repeat', 'Unbekannter Request Typ '. $_IPS['MESSAGE'] ); 
        break;

    }

    SSCK_SendText($id_server_socket ,$_IPS['MESSAGE'].chr(10)); // an den Server Socket LCN
    return;
}


if ($_IPS['SENDER'] == "TimerEvent")
{
    return;
}

Im Script Cient Socket und Server Socket eintragen

b) Script „Konfiguriere LCN Repeat“

<?php
$parent =  IPS_GetParent($_IPS['SELF']);
$script_id_repeat = IPS_GetScriptIDByName('Mxx LCN Repeat', $parent);


if (false)
{
    foreach( IPS_GetChildrenIDs($_IPS['SELF']) as &$instance) 
    {
        if (   substr( IPS_GetName($instance), 0 , 2 ) == 'M0')
        {
            //IPS_DeleteScript($instance, true);    
        }
    }

    foreach( IPS_GetChildrenIDs(IPS_GetParent( $_IPS['SELF'] )) as &$instance) 
    {
        if (  IPS_GetName($instance) == 'Transfer_Tabelle')
        {
            //IPS_DeleteScript($instance, true);    
        }
    }

}

if (true)
{
    $objects = IPS_GetInstanceListByModuleID("{0E31FED6-E465-4621-95D4-AAF2683C41EC}");
    $number_of_moduls = count($objects);

    $script_transfer_tabelle = '<?php' . chr(10) . '$'. 'Transfer_Tabelle = [' .chr(10) ;

    foreach( $objects as &$instance) 
    {
        
        $name = IPS_GetName( $instance)  ;
        $int_modul_id = intval(  substr($name, strlen($name) -4, 3 ), 10 ) ;
        $modul_id = sprintf("%'.03d", $int_modul_id);
        
        $Script_name = 'M' . $modul_id.  ' LCN Instance ' . $instance;
        
        if (( ($script_id = IPS_GetObjectIDByName($Script_name,$_IPS['SELF'] )) == false ) )
        {
            $script_id = IPS_CreateScript(0); 
            IPS_SetParent($script_id, $_IPS['SELF']);
            IPS_SetName($script_id, $Script_name);
        }

        IPS_SetScriptContent($script_id, 
        "<?php" .chr(10)
        .'$'."id_basis_skript = $script_id_repeat;" . chr(10)
        ."include (".'$'."id_basis_skript . '.ips.php');" );

         $script_transfer_tabelle .= '[ "Modul_id" => '. $int_modul_id . ', "script_id" => ' . $script_id .  ' ],'. chr(10); 
    }

$script_transfer_tabelle .= ' ]; '; // Transfertabelle abschliessen

if (( ($script_id = IPS_GetObjectIDByName('Transfer_Tabelle',ips_getparent($_IPS['SELF']) )) == false ) )
{
    $script_id = IPS_CreateScript(0); 
    IPS_SetParent($script_id, ips_getparent($_IPS['SELF']));
    IPS_SetName($script_id, 'Transfer_Tabelle' );
}

IPS_SetScriptContent($script_id, $script_transfer_tabelle);

}

Dieses Script ausführen.
Wenn es richtig gelaufen ist, entsteht für jedes LCN ein Script und im Verzeichnis liegt jetzt zusätzlich ein Script mit dem Namen „Transfer Tabelle“.

c) Script „Transfer Client to Modul“

<?php
$id_client_Socket = XXXXXXX;

$id_transfer_tabelle = IPS_GetScriptIDByName('Transfer_Tabelle', IPS_GetParent( $_IPS['SELF']));
include ("$id_transfer_tabelle.ips.php");


if ($_IPS['SENDER'] == 'RegisterVariable')
{
    //echo $_IPS['INSTANCE'];
    $string = explode(chr(0x0A),$_IPS['VALUE'] );

    for ($i=0; ( $i <= (count($string) -1) ); $i++)
    {
        if (strlen($string[$i]) >= 3)
        {
            auswertung($string[$i], $_IPS['INSTANCE'], $Transfer_Tabelle, $id_client_Socket );
        }
    }
};


function auswertung($lcninput, $Instance, $transfer_tab, $id_client_Socket )
{
    $segmentid = substr($lcninput, 1 ,4);

    if ($segmentid == 'M000')
    {
        $Modul_id = substr($lcninput, 5, 3);
        $int_Modul_id = intval($Modul_id);
    
        $paramter  = Array("MESSAGE" => $lcninput, "SENDER_NAME" => 'Server');
  
        $ex_script_id = get_script_id($transfer_tab, $int_Modul_id);
        
        IPS_RunScriptEx($ex_script_id, $paramter);
            
        //IPS_RunScriptEx($transfer_tab[$int_Modul_id]['script_id'], $paramter);
        return;
    }
    else
    {
        CSCK_SendText ($id_client_Socket, $lcninput.chr(10)) ;
    }
}




function get_script_id($Transfer_Tabelle, $serach_Modul)
{
    $instance = false;

    foreach( $Transfer_Tabelle as &$index) 
    {
        if (intval($index["Modul_id"]) == $serach_Modul)
        {
            $instance = $index["script_id"];
        }
    }    
    return $instance;
}

Im Script euren Client Socket eintragen

d) Script „Transfer Client to Modul“ anlegen

<?php
$Username = 'LCN USERNANEM';
$Password = 'LCN Password';

$id_client_Socket = XXXXXX;
$id_Server_Socket = XXXXXX;


$id_transfer_tabelle = IPS_GetScriptIDByName('Transfer_Tabelle', IPS_GetParent( $_IPS['SELF']));
include ("$id_transfer_tabelle.ips.php");


if ($_IPS['SENDER'] == 'RegisterVariable')
{
    //echo $_IPS['INSTANCE'];
    $string = explode(chr(0x0A),$_IPS['VALUE'] );

    for ($i=0; ( $i <= (count($string) -1) ); $i++)
    {
        if (strlen($string[$i]) >= 3)
        {
            auswertung($string[$i], $_IPS['INSTANCE'], $Transfer_Tabelle, $id_client_Socket, $id_Server_Socket, $Username, $Password) ;
        }
    }
};


function auswertung($lcninput, $Instance, $transfer_tab, $id_client_Socket, $id_Server_Socket,  $Username, $Password)
{
    $segmentid = substr($lcninput, 1 ,4);
    
    if ($segmentid == 'M000')
    {
        $Modul_id = substr($lcninput, 5, 3);
        $int_Modul_id = intval($Modul_id);
    
        $paramter  = Array("MESSAGE" => $lcninput, "SENDER_NAME" => 'Client');
    
        $ex_script_id = get_script_id($transfer_tab, $int_Modul_id);
        
        IPS_RunScriptEx($ex_script_id, $paramter);
            
        //IPS_RunScriptEx($transfer_tab[$int_Modul_id]['script_id'], $paramter);
        
        return;
    }
    else
    {
       //     SSCK_SendText ($id_Server_Socket, $lcninput.chr(10)) ;
      
        if ($lcninput == 'Username:')
        {
            CSCK_SendText($id_client_Socket , $Username .chr(10));
        }
        else if ($lcninput == 'Password:')
        {
            CSCK_SendText($id_client_Socket , $Password .chr(10));
        }
        else if ((substr($lcninput, 1 , 4) == 'ping'))
        {
            SSCK_SendText ($id_Server_Socket, $lcninput.chr(10)) ;
        }
        else if ((substr($lcninput, 0 , 5) == '+M004'))
        {
            SSCK_SendText ($id_Server_Socket, $lcninput.chr(10)) ;
        }
        else
        {
            echo 'da ist was offen ', $lcninput;
            SSCK_SendText ($id_Server_Socket, $lcninput.chr(10)) ;
        }
    }

}


function get_script_id($Transfer_Tabelle, $serach_Modul)
{
    $instance = false;

    foreach( $Transfer_Tabelle as &$index) 
    {
        if (intval($index["Modul_id"]) == $serach_Modul)
        {
            $instance = $index["script_id"];
        }
    }    
    return $instance;
}

Im Script LCN User / Password, Client Socket und Server Socket eintragen.

d) Instanz Register Variable Client anlegen.
Ziel Script: „Transfer Client to Modul“
Gateway: Client Socket LCN IN

e) Instanz Register Variable Server anlegen.
Ziel Script: „Transfer Server to Modul“
Gateway: Server Socket LCN OUT

Ich hoffe nicht vergessen zu haben. Viel erfolg. Fragen immer gerne

1 „Gefällt mir“