PicoC Skript TCP Stream - Sonderzeichen

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • benni.st
    Smart Home'r
    • 06.01.2016
    • 45

    #1

    PicoC Skript TCP Stream - Sonderzeichen

    Hallo zusammen,

    ich habe einen Onkyo AV Receiver und würde gerne die Rückmeldungen anzeigen bzw. verarbeiten.
    Da der MS keinen TCP Eingang hat muss ich mir mit PicoC helfen.

    Nun stehe ich vor dem Problem, dass ich zwar die Daten vom Onkyo empfange,
    jedoch im String ein Ausrufezeichen "!" ist und ich da jetzt festhänge.

    Eine Rückmeldung vom Onkyo sieht z.B. mit dem TCP Programm Hercules so aus:

    Code:
    ISCP
    !1MVL19
    Bedeutet: Main Volume 25 (19 Hex = 25 Dezimal)

    Soweit sogut. Im Log der Config sieht das dann so aus:

    Klicke auf die Grafik für eine vergrößerte Ansicht

Name: log.PNG
Ansichten: 421
Größe: 3,2 KB
ID: 43525

    Nun würde ich gerne den 2. Teil des Strings auswerten,
    was eigentich machbar wäre wenn statt des Kästchens die Zeichen angezeigt würden.

    Ich finde in der Doku nichts wie man Ascii im String sucht oder ähnliches.

    Das Script sieht so aus:
    Code:
    #define RD_BLOCK_SIZE 1000
    
    char szBuffer[RD_BLOCK_SIZE]; 
    int nCnt;
    
    char ps[RD_BLOCK_SIZE]; 
    
    
    while(TRUE) {
    
      STREAM* pTcpStream = stream_create("/dev/tcp/192.168.21.8/60128",0,0); //Stream oeffnen
    
      if(pTcpStream != NULL) {
        
       for(int i = 0; i < 30; i++) {
         if(i > 0) {
    
           sleeps(1);
         }
          nCnt = stream_readline(pTcpStream,szBuffer,RD_BLOCK_SIZE,4000);
    if(nCnt > 0)
        {
        ps = szBuffer;
        printf ("DEBUG Stream %s ",ps); //String wird im Log angezeigt
        }
         }
     }
    }
    Kann mir da jemand helfen?

    Danke und Gruß
    benni.st
  • Jan W.
    Lox Guru
    • 30.08.2015
    • 1425

    #2
    Hallo benni.st,

    ein paar Fragen als Anregung:
    - liefert stream_readline in szBuffer einen nullterminierten String zurück? Bin mir da nicht sicher und die Doku ist sehr mau.
    - Welche Bytefolge liefert der Receiver genau, insbesondere CR und/oder LF nach jeder Zeile?
    - Werden diese Sonderzeichen von stream_readline entfernt?
    - Sind noch weitere Sonderzeichen enthalten?
    - Möchtest Du nach jedem stream_readline 1 Sek. warten?
    Ggf. mal selbst szBuffer[nCnt]=0 setzen oder für das Auslesen "stream_read" verwenden und Zeilenumbrüche selbst entfernen.

    Gruß Jan
    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

    • benni.st
      Smart Home'r
      • 06.01.2016
      • 45

      #3
      Danke für die Anregungen.
      Ich probiere das heute Abend aus.
      Was ich schon sagen kann, CR und LF sind mit im String.
      Ich werde mal die Ausgabe von Hercules in Hex und Ascii posten.

      Das mit der Zeit habe ich schon getestet, der Onkyo ist da ein bisschen sensibel.
      Muss ihn oft vom Netz nehmen weil er nicht mehr erreichbar ist, auch mit der App.

      Auch stream_close macht Probleme, weil ich auch Befehle über den TCP Ausgang zum Receiver schicke, diese gehen dann nicht raus.
      Unter Umständen müsste ich dann auch das Senden über PicoC machen.

      Kommentar

      • benni.st
        Smart Home'r
        • 06.01.2016
        • 45

        #4
        Zitat von Jan W.
        - liefert stream_readline in szBuffer einen nullterminierten String zurück? Bin mir da nicht sicher und die Doku ist sehr mau.
        Bin mir nicht sicher was du genau meinst aber vielleicht wird die Frage unten beantwortet.

        - Welche Bytefolge liefert der Receiver genau, insbesondere CR und/oder LF nach jeder Zeile?
        Der Receiver gibt folgendes aus:
        Code:
        ascii:
        ISCP#NUL#NUL#NUL#DLE#NUL#NUL#NUL#LF#SOH#NUL#NUL#NUL!1MVL16#SUB#CR#LF
        
        hex:
        {49}{53}{43}{50}{00}{00}{00}{10}{00}{00}{00}{0A}{01}{00}{00}{00}{21}{31}{4D}{56}{4C}{31}{38}{1A}{0D}{0A}
        Es sind in diesem Fall 26 Bytes, können aber je nach Anfrage mehr sein.

        DLE ist laut Google eine Escape-Sequenz, vielleicht nimmt der MS das wörtlich

        - Werden diese Sonderzeichen von stream_readline entfernt?
        Es wird alles nach dem ISCP entfernt, nCnt gibt mir bei stream_readline für den ersten Teil des Strings 4 zurück für den 2.Teil nur 1.
        Da fehlen schonmal 21 Zeichen.
        Stream_read allerdings gibt nCnt mit 26 zurück, jedoch sehe ich im Log wieder nur ISCP.

        Wenn ich stream_read richtig verstehe wird alles in ein Array geschrieben, Vielleicht steht da noch mehr drin, wie könnte ich alle Inhalte des Arrays ausgeben?

        - Sind noch weitere Sonderzeichen enthalten?
        So wie ich das sehe nicht.

        Zitat von PicoC Doku
        Strings are encoded in UTF-8.
        Die Zeichen sind alle in der UTF-8 Tabelle zu finden.

        - Möchtest Du nach jedem stream_readline 1 Sek. warten?
        Nicht unbedingt, wie oben geschrieben hängt sich der Receiver gerne mal auf, habs auch schon mit 100ms probiert.

        Ggf. mal selbst szBuffer[nCnt]=0 setzen oder für das Auslesen "stream_read" verwenden und Zeilenumbrüche selbst entfernen.
        hat leider nicht funktioniert, es wird nichts zurückgegeben.

        Gibts ne Möglichkeit szBuffer sofort in Hex o.ä. umzuwandeln?

        Kommentar

        • Jan W.
          Lox Guru
          • 30.08.2015
          • 1425

          #5
          Ich denke, dass Du mit stream_read arbeiten solltest - die Funktion liefert ja schon mal die richtige Länge. Strings haben als Markierung für Ende ein Byte mit "0". Da der Code vom Onkyo etliche Nullen enthält, funktioniert stream_readline wahrscheinlich nicht richtig. "Üblicherweise" lesen Funktionen mit "readline" bis zu einem LF, CR oder LF/CR und liefern einen String zurück.

          Bin mir nicht ganz sicher, aber wenn die Nullen beim Lesen ignoriert werden, dann liefert das erste Lesen {49}{53}{43}{50}{00}{00}{00}{10}{00}{00}{00}{0A} - wobei das "LF"=0A am Ende nicht mit in den String übernommen wird. Da ein String in C mit "0" endet ergibt sich {49}{53}{43}{50}{00} = ISCP (Länge = 4 Byte), , das zweite Lesen liefert den Rest aber der String wird dann zu {01}{00} verkürzt und hat 1 Byte Länge. Der ASCII Code 01 ist nicht darstellbar und daher bekommt Du den Output. Die Funktion stream_readline arbeitet also korrekt - liefert aber nicht das was Du möchtest.

          Bei der Ausgabe von Strings mit printf musst Du auch darauf achten, dass nur lesbare Zeichen richtig ausgegeben werden können (und natürlich CR/LF).

          Das zurückgegebene Array von "stream_read" kannst Du Zeichen für Zeichen überprüfen oder zum Test ausgeben. szBuffer[i] liefert ein einzelnes Zeichen aus der Bytefolge und kann z.B. mit printf als Dezimalzahl ausgegeben werden, aber auch mit einer Zahl verglichen werden.

          printf( "DEBUG Stream als Dezimalwerte: " );
          for ( j=0; j<nCnt; j++ ) {
          printf( "%d, ",(int)szBuffer[j] );
          }

          Ich weiß nicht, welche Bytefolge kommen muss, d.h. hier musst Du anhand der Anleitung von Onkyo die Auswertung der Bytefolge übernehmen. Statt einzelne Bytes kannst Du auch mit memcmp längere Bytefolgen vergleichen.
          Zuletzt geändert von Jan W.; 01.06.2016, 00:10.
          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

          • benni.st
            Smart Home'r
            • 06.01.2016
            • 45

            #6
            Es hat funktioniert.
            Mit stream_read werden die Bytes jetzt einzeln nacheinander ins Array geschrieben.
            Code:
            nCnt = stream_read(pTcpStream,szBuffer,1,150);
            Jetzt muss ich den String nur wieder zusammensetzen und kann darin suchen.

            Vielen Dank für deine Hilfe.

            Kommentar

            Lädt...