Unterstützung bei der PicoC Programmierung

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • mlutz
    Dumb Home'r
    • 20.01.2024
    • 15

    #1

    Unterstützung bei der PicoC Programmierung

    Hallo zusammen,

    für ein komplexeres Projekt muss ich die wechselnde Externe Adresse eines Miniservers abgreifen, da die Weiterleitung über https://User:PW@dns.loxonecloud.com/...o/Schalter/Ein nicht funktioniert.
    Wenn ich die Werte der URL aus dem Browser nach dem aufrufen über https://dns.loxonecloud.com/MAC verwende (https://User:PW@<(IPMAC)>.dyndns.loxonecloud.com:PORT/jdev/sps/io/Schalter/Ein) geht es. Allerdings Ändern sich Port /IP Regelmäßig

    Um Abhilfe zu Schaffen, habe ich versucht mittels PicoC einen Programcode zu entwickeln. Dieser Code sollte eigentlich nach einem Wechsel von 0 auf 1 am Eingang I1 die "Standard Adresse" (https://<(IPMAC)>dyndns.loxonecloud.com:PORT) liefern. Der Code Startet jedoch nicht.(Etxt bleibt in der LiveView bei Start)
    ​​​

    // Variable zur Speicherung des letzten Zustands von I1
    int last_input_i1 = 0;

    void main() {
    // Aktuellen Zustand des Eingangs I1 abrufen
    int current_input_i1 = GetInput("I1");

    // Prüfen, ob ein Wechsel von 0 auf 1 stattgefunden hat
    if (current_input_i1 == 1 && last_input_i1 == 0) {
    // Seriennummer des Ziel-Miniservers
    char serial_number[20];
    strcpy(serial_number, "504FMAC");

    // DNS-Server und Port
    char host[50];
    strcpy(host, "dns.loxonecloud.com");
    int port = 80;

    // HTTP-Request manuell aufbauen
    char request[256] = "GET /";
    strcat(request, serial_number);
    strcat(request, " HTTP/1.1\r\nHost: ");
    strcat(request, host);
    strcat(request, "\r\nConnection: close\r\n\r\n");

    // Puffer für die Antwort
    char response[1024] = {0};

    // Verbindung herstellen
    int socket = TcpConnect(host, port);
    if (socket < 0) {
    Log("Fehler: Verbindung zu %s:%d fehlgeschlagen", host, port);
    last_input_i1 = current_input_i1; // Zustand aktualisieren
    return;
    }

    // Anfrage senden
    if (TcpSend(socket, request, strlen(request)) < 0) {
    Log("Fehler: Senden der Anfrage fehlgeschlagen");
    TcpClose(socket);
    last_input_i1 = current_input_i1; // Zustand aktualisieren
    return;
    }

    // Antwort empfangen
    int received = TcpReceive(socket, response, sizeof(response) - 1);
    if (received <= 0) {
    Log("Fehler: Keine Antwort vom Server erhalten");
    TcpClose(socket);
    last_input_i1 = current_input_i1; // Zustand aktualisieren
    return;
    }
    response[received] = '\0'; // Null-terminierte Zeichenkette

    // Verbindung schließen
    TcpClose(socket);

    // Antwort anzeigen
    Log("Antwort vom Server: %s", response);

    // Header von der Antwort trennen (suchen nach "\r\n\r\n")
    char *body = strstr(response, "\r\n\r\n");
    if (body != NULL) {
    body += 4; // Überspringe die Header-Trennung
    } else {
    Log("Fehler: Ungültige Antwort erhalten");
    last_input_i1 = current_input_i1; // Zustand aktualisieren
    return;
    }

    // Überprüfen, ob der Body nicht leer ist
    if (strlen(body) > 0) {
    // RemoteConnect-URL auf Ausgang TXT1 ausgeben
    SetOutput("TXT1", body);
    Log("RemoteConnect-URL: %s", body); // Debug Log
    } else {
    Log("Fehler: Leerer Antwortbody");
    }
    }

    // Letzten Zustand des Eingangs I1 speichern
    last_input_i1 = current_input_i1;
    }
    Hat jemand ne Idee, woran es liegen könnte?
    Alternative Wege über Loxberry oder ähnliches gehen leider nicht, da ich nur einen MiniserverV2 zur Verfügung habe

    Vielen Dank
    mlutz
  • Jan W.
    Lox Guru
    • 30.08.2015
    • 1369

    #2
    Was siehst Du denn im Log?

    Der "Dyn-DNS" Dienst von Loxone arbeitet anders, als andere DynDNS Dienst. Während die anderen Dienste DEINE öffentliche IP-Adresse auf DNS Anfragen zurückliefern und prinzipbedingt (bei DNS Anfragen nach A-Records) keinen Port zurückliefern, erwartet der Dienst von Loxone eine HTTP Verbindung und liefert ein HTTP Redirect als Antwort mit der von Dir gesuchten öffentliche IP-Adresse und Port, d.h. liefert ein HTTP Response Code 307 (Temporary Redirect) und in der Payload ein Text ähnlich zu:
    Temporary Redirect. Redirecting to http://62.68.193.88:2244/

    Ich würde erwarten, dass "body" in Deinem Code eine ähnliche Ausgabe zu dem o.a. Beispiel liefert. Dort solltest Du den hinteren Teilstring ab "http://" ausschneiden und zu diesem Server die eigentliche TCP Verbindung aufbauen - das ist Dein neuer "host". Ich würde aber bei HTTP bleiben, denn Pico-C hat keine Library, um einfach https nutzen zu können. Leider wurde die Pico-C Implementierung von Loxone nie weiterentwickelt.

    Warum es mit dem Browser geht? Der ist intelligent und liefert Dir nicht die Redirect-Antwort, sondern führt den Redirect aus.

    Vielleicht wäre es einfacher gewesen, einen anderen "normalen" Dyn-DNS Dienst zu verwenden, aber Dein Code ist ja schon fast fertig.

    Es ist normal, dass der Programmcode in "Start" bleibt, sofern er nicht durch ein Ereignis abgebrochen wurde. In Deinem Code fehlt noch die Endlosschleife, denn Du möchtest sicherlich nicht nur einmalig den Wert setzen, sondern immer sobald er sich ändert. Siehe z.b. die Beispiele von Loxone am Ende von https://updatefiles.loxone.com/Knowl...rogramming.pdf. Ich würde noch einen Statusbaustein an TeQ anhängen, um den Status in der Loxone App bzw. im Webinterface verfolgen zu können.

    Miniserver v14.5.12.7, 2x Ext., 2x Relay Ext., 2x Dimmer Ext., DMX Ext., 1-Wire Ext., Gira KNX Tastsensor 3 Komfort, Gira KNX Präsenzmelder, Fenster- und Türkontakte, Loxone Regen- und Windsensor, Gira Dual Q Rauchmelder vernetzt, 1x Relais-Modul
    Loxberry: SmartMeter, MS Backup, CamConnect, Weather4Lox
    Lüftung: Helios KWL EC 370W ET mit Modbus TCP - via Pico-C
    Heizung: Stiebel Eltron WPF 5 cool (Sole-Wasser WP) mit ISG, FB-Heizung mit 18 Kreisen, Erdsonde - via modbus/TCP
    Node-RED: IKEA Tradfri

    Kommentar

    • mlutz
      Dumb Home'r
      • 20.01.2024
      • 15

      #3
      Im Log sehe ich leider weder unter http://miniserver/dev/fsget/log/def.log noch unter http://miniserver/dev/fsget/log/user.log etwas. Auch der Loxone Monitor über Diagnose -> Debug Info zeigt mir keinerlei Info.

      Das der DynDNS Dienst von Loxone eine Weiterleitung ist war mir bewusst, nur ändert sich diese weitegeleitet Adresse ja leider regelmäßig und ich benötige die Adresse zum schalten eines Bausteins eines anderen Miniservers ca 1mal in der Woche, deshalb auch noch kein Loop im Programm.

      Wo hat der Programm Baustein bei dir TEQ als Ausgang? Ich habe nur die hier
      Klicke auf die Grafik für eine vergrößerte Ansicht

Name: image.png
Ansichten: 115
Größe: 16,2 KB
ID: 450597
      Hast du zufällig noch einen anderen Weg Parat, wie ich an die RemoteConnect URL kommen könnte?

      Kommentar

      • Jan W.
        Lox Guru
        • 30.08.2015
        • 1369

        #4
        Im Log sehe ich leider weder unter http://miniserver/dev/fsget/log/def.log noch unter http://miniserver/dev/fsget/log/user.log etwas. Auch der Loxone Monitor über Diagnose -> Debug Info zeigt mir keinerlei Info.
        Ich habe die Meldungen für das Log mit ''printf()" geschrieben, nicht mit "Log()". Es gibt wohl lt. Doku auch "setlogtext()". Diese Meldungen sind in der def.log, die z.B. mit http://<miniserver-ip>/dev/fsget/log/def.log abgerufen werden kann. Das Debugging ist etwas umständlich, da der neue Code in die Config eingetragen wird und dann die Config in den Miniserver geladen wird, aber das hast Du ja sicherlich schon festgestellt.

        Das der DynDNS Dienst von Loxone eine Weiterleitung ist war mir bewusst, nur ändert sich diese weitergeleitete Adresse ja leider regelmäßig.
        Es ist schon klar, dass Du einen DynDNS Dienst benötigst, da Dein anderer Miniserver sich hinter einer öfter wechselnden öffentlichen IP-Adresse befindet. Mit einem anderen Dyn-DNS Dienst hättest Du Dir die Auswertung des HTTP Redirects erspart, weil die DNS Abfrage bei anderen DynDNS Diensten direkt die öffentliche IP-Adresse des anderen MS geliefert hätte.

        ich benötige die Adresse zum schalten eines Bausteins eines anderen Miniservers ca 1mal in der Woche, deshalb auch noch kein Loop im Programm.
        Den Loop solltest Du zum Testen schon einbauen, denn sonst hat Dein Input I1 den Wert vom Start des Miniservers. Siehe z.B. hier https://www.loxforum.com/forum/germa...-c-problemchen für die Verwendung von "getinputevent", damit Dein Code nur läuft, wenn sich der Input geändert hat. Der Vergleich mit dem jeweils vorherigen Wert sollte aber auch nicht viel mehr CPU Zeit verbrauchen. Wichtig ist ein möglichst großer (für Dich sinnvoller) Wert für "sleep", damit Dein Programm nicht zu viel CPU Zyklen verbraucht.

        Wo hat der Programm Baustein bei dir TEQ als Ausgang?
        Irgendwann hat Loxone den Fehlerausgang umbenannt. Hier https://www.loxforum.com/forum/germa...ten#post196553 ist noch ein Screenshot mit dem alten Namen. Beides sind aber Ausgänge für ein Fehlertext, d.h. zeigen ein Fehler beim Pico-C Interpreter an. "Start" bedeutet, dass es keinen Fehler gibt.

        Ich habe gerade gesehen, dass Du überall ein "return" im Code hast. Damit springt man aus einer Unterfunktion heraus, d.h. die "return"s müssen entfernt werden. Pico-C benötigt kein "main()", sondern der Code, den ein normales C-Programm in "main()" hat, wird ohne diese Funktion verwendet. Schau Dir die Beispiele aus der Doku von Loxone an.

        Ich vermute, dass Die Funktion "main()" in Pico-C wie jede andere Funktion behandelt wird, d.h. Du hast eine Funktion definiert, die aber nie aufgerufen wird. Der Fehlerausgang bleibt dann wohl bei "Start" stehen, weil kein Fehler gefunden wurde und Dein Programm ohne einen einzigen aktiven Befehl beendet wurde (außer int last_input_i1 = 0.

        Ich habe nie ein Programm ohne Endlosschleife bzw. mit "main()" auf dem MS getestet, daher ist dies nur eine Vermutung. Bei näherem Hinsehen frage ich mich, ob es die Funktion "TcpConnect" in Pico C überhaupt gibt? Wahrscheinlich wirst Du diese Fehler erst sehen, wenn der Pico-C Interpreter den Code ausführen möchte und dann feststellt, dass es die Funktion nicht gibt.

        Hast du zufällig noch einen anderen Weg Parat, wie ich an die RemoteConnect URL kommen könnte?
        Wenn Du den Loxone Cloud DNS Dienst verwendest, dann ist Dein Code im Prinzip schon richtig. Es fehlen aber noch ein paar Befehle und im Code sind noch ein paar Fehler drin.

        Hab gerade zufällig gesehen, dass Pico-C auch eine Funktion "httpget()" hat, aber ich weiß nicht, was die bei einem Redirect zurückliefert.
        Zuletzt geändert von Jan W.; 29.12.2024, 18:25.
        Miniserver v14.5.12.7, 2x Ext., 2x Relay Ext., 2x Dimmer Ext., DMX Ext., 1-Wire Ext., Gira KNX Tastsensor 3 Komfort, Gira KNX Präsenzmelder, Fenster- und Türkontakte, Loxone Regen- und Windsensor, Gira Dual Q Rauchmelder vernetzt, 1x Relais-Modul
        Loxberry: SmartMeter, MS Backup, CamConnect, Weather4Lox
        Lüftung: Helios KWL EC 370W ET mit Modbus TCP - via Pico-C
        Heizung: Stiebel Eltron WPF 5 cool (Sole-Wasser WP) mit ISG, FB-Heizung mit 18 Kreisen, Erdsonde - via modbus/TCP
        Node-RED: IKEA Tradfri

        Kommentar

        • Jan W.
          Lox Guru
          • 30.08.2015
          • 1369

          #5
          Bin gerade zufällig darüber gestolpert: man kann auch die URL http://dns.loxonecloud.com/?getip&snr=eee0005800xx aufrufen und bekommt dann vom Loxone Cloud DNS Dienst die IP-Adresse und Port im XML Format geliefert, z.B.:
          Code:
          jan@Jans-Mac-mini% curl -v -s "http://dns.loxonecloud.com/?getip&snr=eee00058xxxx"
          * Host dns.loxonecloud.com:80 was resolved.
          * IPv6: 2a01:4f8:1c1c:9df9::1
          * IPv4: 116.203.7.175
          *   Trying [2a01:4f8:1c1c:9df9::1]:80...
          * Connected to dns.loxonecloud.com (2a01:4f8:1c1c:9df9::1) port 80
          > GET /?getip&snr=eee00058xxxx HTTP/1.1
          > Host: dns.loxonecloud.com
          > User-Agent: curl/8.5.0
          > Accept: */*
          >
          < HTTP/1.1 200 OK
          < Access-Control-Allow-Origin: *
          < Content-Length: 157
          < Content-Security-Policy: default-src dns.loxonecloud.com *.dns.loxonecloud.com 'unsafe-inline' data:
          < Content-Type: text/xml; charset=utf-8
          < Date: Mon, 30 Dec 2024 12:07:44 GMT
          < Etag: W/"9d-6l3UDTnLJI3osr1ItfmN/Jjwv1M"
          <
          * Connection #0 to host dns.loxonecloud.com left intact
          <Answer cmd="getip" Code="200" IP="62.68.xx.xx:2255" PortOpen="1" PortOpenHTTPS="0" RemoteConnect="0" DNS-Status="registered" DataCenter="loxonecloud.com"/>%
          vs. HTTP Redirect Message über
          Code:
          jan@Jans-Mac-mini% curl -v -s "http://dns.loxonecloud.com/eee00058xxxx"
          * Host dns.loxonecloud.com:80 was resolved.
          * IPv6: 2a01:4f8:1c1c:9df9::1
          * IPv4: 116.203.7.175
          *   Trying [2a01:4f8:1c1c:9df9::1]:80...
          * Connected to dns.loxonecloud.com (2a01:4f8:1c1c:9df9::1) port 80
          > GET /eee00058xxxx HTTP/1.1
          > Host: dns.loxonecloud.com
          > User-Agent: curl/8.5.0
          > Accept: */*
          >
          < HTTP/1.1 307 Temporary Redirect
          < Access-Control-Allow-Origin: *
          < Content-Length: 60
          < Content-Security-Policy: default-src dns.loxonecloud.com *.dns.loxonecloud.com 'unsafe-inline' data:
          < Content-Type: text/plain; charset=utf-8
          < Date: Mon, 30 Dec 2024 12:09:43 GMT
          < Location: http://62.68.xx.xx:2255/
          < Vary: Accept
          <
          * Connection #0 to host dns.loxonecloud.com left intact
          Temporary Redirect. Redirecting to http://62.68.xx.xx:2255/
          Am Ende ist es wahrscheinlich egal, ob man nach "IP=" oder "http://" sucht.

          mlutz : Es gibt vielleicht noch einen ganz anderen Weg, siehe https://www.loxforum.com/forum/germa...848#post361848 und https://www.loxone.com/dede/blog/ver...one-explained/
          Miniserver v14.5.12.7, 2x Ext., 2x Relay Ext., 2x Dimmer Ext., DMX Ext., 1-Wire Ext., Gira KNX Tastsensor 3 Komfort, Gira KNX Präsenzmelder, Fenster- und Türkontakte, Loxone Regen- und Windsensor, Gira Dual Q Rauchmelder vernetzt, 1x Relais-Modul
          Loxberry: SmartMeter, MS Backup, CamConnect, Weather4Lox
          Lüftung: Helios KWL EC 370W ET mit Modbus TCP - via Pico-C
          Heizung: Stiebel Eltron WPF 5 cool (Sole-Wasser WP) mit ISG, FB-Heizung mit 18 Kreisen, Erdsonde - via modbus/TCP
          Node-RED: IKEA Tradfri

          Kommentar

          • mlutz
            Dumb Home'r
            • 20.01.2024
            • 15

            #6
            Die Info mit http://dns.loxonecloud.com/?getip&snr=eee0005800xx ist MEGA Danke.

            Ich hab inzwischen mit dem Status Baustein und der Texterkennung(Oktett1: IPHTTPS="\v Oktett4:\i.\i\i.\i\i.\i\v) den String für die URL passend Zusammengestellt. Jetzt muss ich es nur noch irgendwie hinbekommen diesen String an meinen Virtuellen Ausgang auszuführen. Um die Schaltaktion durchzuführen.
            Klicke auf die Grafik für eine vergrößerte Ansicht

Name: image.png
Ansichten: 83
Größe: 22,6 KB
ID: 450734

            Die Idee mit Trust hatte ich auch schon, sind aber 2 völlig unterschiedliche Systeme die außer diesem einen true/ false nichts miteinander zu tun haben sollen.

            Kommentar

            • Jan W.
              Lox Guru
              • 30.08.2015
              • 1369

              #7
              Vielleicht hilft Dir der Link weiter: https://www.loxforum.com/forum/germa...289#post173289
              Miniserver v14.5.12.7, 2x Ext., 2x Relay Ext., 2x Dimmer Ext., DMX Ext., 1-Wire Ext., Gira KNX Tastsensor 3 Komfort, Gira KNX Präsenzmelder, Fenster- und Türkontakte, Loxone Regen- und Windsensor, Gira Dual Q Rauchmelder vernetzt, 1x Relais-Modul
              Loxberry: SmartMeter, MS Backup, CamConnect, Weather4Lox
              Lüftung: Helios KWL EC 370W ET mit Modbus TCP - via Pico-C
              Heizung: Stiebel Eltron WPF 5 cool (Sole-Wasser WP) mit ISG, FB-Heizung mit 18 Kreisen, Erdsonde - via modbus/TCP
              Node-RED: IKEA Tradfri

              Kommentar

              Lädt...