HTTP Eingang - Befehlserkennung / Hexadezimal aufsplitten möglich?

Einklappen
X
 
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge
  • Steiny
    Dumb Home'r
    • 11.07.2016
    • 28

    #16
    Hallo Tico,

    ich bin jetzt schon ein gutes Stück weiter, aber leider noch nicht ganz am Ziel.
    Nachdem ich einige Sensoren habe die extra abgefragt werden müssen, habe ich die Abfrage HTTP-Abfrage über PicoC gelöst, der mir dann jeweils gleich die vollen 8 HEX als Dezimal-Wert liefert. Somit spare ich mir eine vielzahl an HTTP-Abfragen und nachdem der Wert als Ganzes kommt ist auch kein Zeitversatz (flackern) dabei.
    D.h. also z.B. für den HEX-Wert 44174C3C bekomme ich 1142377532 in dezimal retour, den ich dann lt. Post #14 weiterverarbeite - leider stimmt das Endergebniss aber nicht.

    Hat das vl. mit der Reihenfolge der Bytes zu tun ?

    Vielen Dank!
    MFG
    Zuletzt geändert von Steiny; 24.10.2021, 17:21.

    Kommentar

    • Tico
      Lox Guru
      • 31.08.2016
      • 1035

      #17
      Ja, ich gehe davon aus, dass die korrekte Byte-Reihenfolge entscheidend sein wird. Ich kann mir auch vorstellen, dass die Bit-Reihenfolge wichtig sein könnte.

      Ich habe mit dezimal 1142377532 und der normalen Byte-Reihenfolge begonnen.
      Ich sehe ein Ergebnis = 590.174

      Ich habe dann mit dezimal 1142377532 begonnen und die Byte-Reihenfolge umgekehrt.
      Ich sehe ein Ergebnis = 0.012

      Ich habe dann mit 44174C3C begonnen und die Reihenfolge umgekehrt (C3C47144). Der Dezimalwert hierfür ist 3284431172.
      Ich habe dann die normale Byte-Reihenfolge verwendet und erhalte ein Ergebnis = -370.827

      Ich habe dann den Dezimalwert 3284431172 verwendet und die umgekehrte Byte-Reihenfolge benutzt.
      Ich sehe ein Ergebnis = 893.744.

      Wahrscheinlich gibt es noch einige andere Varianten...
      Ich spreche kein Deutsch. Gib Google Translate die Schuld, wenn ich unverständlich bin.

      Kommentar

      • Steiny
        Dumb Home'r
        • 11.07.2016
        • 28

        #18
        Danke für die Rückmeldung und Bemühungen!

        44174C3C/1142377532 sollte als tatsächlichen Wert 605.191 ergeben, siehe: https://www.h-schmidt.net/FloatConverter/IEEE754.html
        D.h. die normale Byte-Reihenfolge kommt mit 590.174 am ehesten hin, aber eben nicht ganz. Es dürfte wo im Detail noch ein Rechenfehler stecken. Bleibt die Frage wo.

        MFG
        Zuletzt geändert von Steiny; 25.10.2021, 08:54.

        Kommentar

        • Steiny
          Dumb Home'r
          • 11.07.2016
          • 28

          #19
          Bin noch ein Stück weiter gekommen.

          Ich bin wieder von 1142377532 (HEX 44174C3C) ausgegangen und habe es in deine Loxone-Funktion gegeben.
          Wenn man das nun mit dem Floatconverter (https://www.h-schmidt.net/FloatConverter/IEEE754.html) vergleicht, werden Sign, Exponent, Mantissa prinzipiell richtig gebildet, aber bei der letzten Formel geht was schief.

          Sollte in die Berechnung als Mantissa nicht der andere Wert (1.182013988494873 / gelb markiert) einfließen?
          Wenn ichs mit diesem Wert manuell durchrechne komme ich schon eher auf das richtige Ergebniss.

          Fragt sich nun wie man bei der Mantissa von 1526844 auf 1.182013988494873 kommt. Leider übersteigt das jetzt aber definitiv meine mathematischen Fähigkeiten.

          Hast du dazu vielleicht noch eine Idee ? Od. bin ich am Holzweg.

          Vielen Dank!!

          Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 3_2021-10-25 12_00_18-IEEE-754 Konverter.png Ansichten: 0 Größe: 46,8 KB ID: 322313
          Angehängte Dateien

          Kommentar

          • Tico
            Lox Guru
            • 31.08.2016
            • 1035

            #20
            Ja, Sie sind auf jeden Fall auf dem richtigen Weg!

            Die vorhandenen Mantissenformeln erzeugen die korrekte Dezimalcodierung der Mantisse. Die erforderliche Formel muss den Wert der Mantisse erzeugen.

            Ich habe die Mantissen-Kaskade mit neuen Formeln überarbeitet, die den Wert erzeugen.

            Dadurch wird der erwartete Wert von 605,191 korrekt wiederhergestellt. Auch mit einer Vielzahl von Eingabewerten getestet.
            Angehängte Dateien
            Ich spreche kein Deutsch. Gib Google Translate die Schuld, wenn ich unverständlich bin.

            Kommentar


            • Lenardo
              Lenardo kommentierte
              Kommentar bearbeiten
              wow
          • Steiny
            Dumb Home'r
            • 11.07.2016
            • 28

            #21
            Perfekt - jetzt funktioniert es wie es soll - alle Werte von allen Sensoren stimmen.

            Nochmal vielen, vielen Dank für die Unterstützung!! Ohne dich hätte ich das wohl nicht zum laufen gebracht! :-)

            MFG Steiny

            Kommentar

            • Tico
              Lox Guru
              • 31.08.2016
              • 1035

              #22
              Sie sind herzlich willkommen. Ich bin froh, dass Sie durchgehalten haben. Die bestehende Formel lieferte vernünftige Werte (bei der Anwendung einer Solaranlage in Watt), aber sie waren nicht einmal annähernd genau!

              Ich bin neugierig auf Ihren PicoC-Code, der den 8-Hex-Wert abruft. Würden Sie ihn bitte ohne sensible Daten (Benutzer/Passwort usw.) posten?

              Das #-Symbol in der Menüleiste bietet einen gewissen Schutz für den angezeigten Code.

              Code:
              Code hier
              Ich spreche kein Deutsch. Gib Google Translate die Schuld, wenn ich unverständlich bin.

              Kommentar

              • Steiny
                Dumb Home'r
                • 11.07.2016
                • 28

                #23
                Sehr gerne!

                Hier mein PicoC Programm zum Abfragen der HTTP Quellen.

                Es werden in einer Schleife in Summe 3 separate Sensoren (Quellen) auf REST-API Webservice-Basis abgefragt. Als Ergebnis erhält man in meinem Fall jeweils einen String im JSON-Format der einen 30 stelligen HEX-Wert enthält.
                Je Sensor werden dann aus dem HEX-Wert 4 Werte ( 3 x 8 HEX, 1 x 4 HEX) extrahiert und auf den entspr. Dezimalwert umgewandelt. Der Dezimalwert wird dann direkt in Virtuelle Eingänge (setio/VIx) geschrieben.

                Somit werden im Vergleich zur Variante mit HTTP-Eingängen in Loxone, eine Vielzahl weniger HTTP-Calls gegen das Webservice geschickt, da zur Ermittlung aller Werte eines Sensors, dieser nur 1 x abgefragt wird (versus 7 Abfragen mit HTTP-Eingängen).
                Zudem sind die Sensorwerte selbst auch in sich (je Abfrage) konsistent, da kein zeitlicher Versatz, aufgrund mehrfacher HTTP-Abfragen des gleichen Sensors, auftritt.
                Und zu guter Letzt ist man auch nicht an die 10 Sekunden Begrenzung beim Abfragezyklus von HTTP-Eingängen gebunden und kann somit die Werte (falls erforderlich) zeitnaher erfassen.

                Code:
                int hex2int(char *hex) {
                int val = 0;
                while (*hex) {
                // get current character then increment
                int byte = *hex++;
                // transform hex character to the 4bit equivalent number, using the ascii table indexes
                if (byte >= '0' && byte <= '9') byte = byte - '0';
                else if (byte >= 'a' && byte <='f') byte = byte - 'a' + 10;
                else if (byte >= 'A' && byte <='F') byte = byte - 'A' + 10;
                // shift 4 to make space for new digit, and add the 4 bits of the new digit
                val = (val << 4) | (byte & 0xF);
                }
                free (*hex);
                return val;
                }
                
                int dezvalue;
                char* sensor1Wert = "";
                char* url;
                int i;
                
                while(TRUE)
                {
                for(i = 1; i <= 3; i++) {
                if(i == 1)
                {
                // Sensor 1
                url = "/iolinkmaster/port[1]/iolinkdevice/pdin/getdata";
                }
                else if (i == 2)
                {
                // Sensor 2
                url = "/iolinkmaster/port[2]/iolinkdevice/pdin/getdata";
                }
                else if (i == 3)
                {
                // Sensor 3
                url = "/iolinkmaster/port[3]/iolinkdevice/pdin/getdata";
                }
                
                char* sensor1 = httpget("1.1.1.1",url);
                if ((sensor1 != NULL) && (sensor1 != 0))
                {
                int sensor1Len = strlen(sensor1);
                //printf("sensor1Len=%d",sensor1Len);
                if (sensor1Len == 174)
                {
                char* sensor1Str = strstrskip(sensor1,"value");
                if ((sensor1Str != NULL) && (sensor1Str != 0))
                {
                int sensor1StrLen = strlen(sensor1Str);
                //printf("sensor1StrLen=%d",sensor1StrLen);
                if (sensor1Len != sensor1StrLen && sensor1StrLen == 47)
                {
                //printf(sensor1Str);
                
                // Wert 1 - 8 HEX
                strncpy(sensor1Wert, sensor1Str+3, 8);
                //printf(sensor1Wert);
                
                dezvalue = hex2int(sensor1Wert);
                //printf("dezvalue=%d",dezvalue);
                if(dezvalue >= 0)
                {
                if(i == 1)
                {
                setio("VI2",dezvalue);
                }
                else if (i == 2)
                {
                setio("VI7",dezvalue);
                }
                else if (i == 3)
                {
                setio("VI11",dezvalue);
                }
                }
                free (sensor1Wert);
                
                // Wert 2 - 8 HEX
                strncpy(sensor1Wert, sensor1Str+11, 8);
                //printf(sensor1Wert);
                
                dezvalue = hex2int(sensor1Wert);
                //printf("dezvalue=%d",dezvalue);
                if(dezvalue >= 0)
                {
                if(i == 1)
                {
                setio("VI3",dezvalue);
                }
                else if (i == 2)
                {
                setio("VI8",dezvalue);
                }
                else if (i == 3)
                {
                setio("VI12",dezvalue);
                }
                }
                free(sensor1Wert);
                
                // Wert 3 - 8 HEX
                strncpy(sensor1Wert, sensor1Str+19, 8);
                //printf(sensor1Wert);
                
                dezvalue = hex2int(sensor1Wert);
                //printf("dezvalue=%d",dezvalue);
                if(dezvalue >= 0)
                {
                if(i == 1)
                {
                setio("VI5",dezvalue);
                }
                else if (i == 2)
                {
                setio("VI9",dezvalue);
                }
                else if (i == 3)
                {
                setio("VI13",dezvalue);
                }
                }
                free (sensor1Wert);
                
                // Wert 4 - 4 HEX
                strncpy(sensor1Wert, sensor1Str+27, 4);
                //printf(sensor1Wert);
                
                dezvalue = hex2int(sensor1Wert);
                //printf("dezvalue=%d",dezvalue);
                if(dezvalue >= 0)
                {
                if(i == 1)
                {
                setio("VI6",dezvalue);
                }
                else if (i == 2)
                {
                setio("VI10",dezvalue);
                }
                else if (i == 3)
                {
                setio("VI14",dezvalue);
                }
                }
                free (sensor1Wert);
                }
                }
                free(sensor1Str);
                }
                }
                free(sensor1);
                sleeps(5);
                }
                sleeps(10);
                }

                Vielleicht hilft das ja auch mal jemanden. Funktioniert bei mir bis jetzt bestens. ;-)

                MFG,
                Steiny
                Zuletzt geändert von Steiny; 26.10.2021, 19:35.

                Kommentar


                • Tico
                  Tico kommentierte
                  Kommentar bearbeiten
                  Sehr hilfreich. Danke!
              • romildo
                Lebende Foren Legende
                • 25.08.2015
                • 5113

                #24
                In Bezug auf IEEE754 ab Pos 11, habe ich auch noch etwas damit rumexperimentiert.
                Sofern nur der Floatwert als Ergebnis benötigt wird, sollte das auch relativ einfach umsetzbar sein.
                Hier mein Ergebnis:
                Die Formelbausteine 6 xUp, 2 x Up und Dez, habe ich von hier übernommen.
                Klicke auf die Grafik für eine vergrößerte Ansicht  Name: IEEE754_Config1.png Ansichten: 1 Größe: 73,7 KB ID: 322598
                Der Foremelbaustein Float besitzt folgenden Inhalt:
                Code:
                ((-1^(((I1-INT(I1/2^32)*2^32)-(I1-INT(I1/2^31)*2^31))/2^31)))*((((I1-INT(I1/2^23)*2^23)-(I1-INT(I1/2^0)*2^0))/2^0)+2^23)/(2^(23-((((I1-INT(I1/2^31)*2^31)-(I1-INT(I1/2^23)*2^23))/2^23)-127)))
                Nachtrag:
                Hier noch eine Variante, welche mit einem Eingangsbefehl auskommt:
                Klicke auf die Grafik für eine vergrößerte Ansicht  Name: IEEE754_Config2.png Ansichten: 0 Größe: 94,7 KB ID: 322613
                Klicke auf die Grafik für eine vergrößerte Ansicht  Name: IEEE754_Status2.png Ansichten: 0 Größe: 37,8 KB ID: 322612
                Formel Float:
                (((((I1-INT(I1/2^23)*2^23)-(I1-INT(I1/2^0)*2^0))/2^0)+2^23)/(2^(23-((((I1-INT(I1/2^31)*2^31)-(I1-INT(I1/2^23)*2^23))/2^23)-127))))*I2
                Zuletzt geändert von romildo; 27.10.2021, 17:40.
                lg Romildo

                Kommentar

                • Tico
                  Lox Guru
                  • 31.08.2016
                  • 1035

                  #25
                  romildo - sehr schön!

                  Hast du immer noch deinen Virtual Input Prüfstand eingerichtet? Ich bin neugierig, ob du etwas ausprobieren könntest.

                  Als ich mir das ursprünglich angeschaut habe, hat der Miniserver 8 Hex-Zeichen nicht erfolgreich mit \h verarbeitet. Das war damals mit Version 11.xx und möglicherweise einem Miniserver Gen1 (ich kann mich nicht erinnern).

                  Ich befürchte, dass meine SD-Karte den Mittelfinger hebt, wenn ich noch mehr schreibe... Ich muss einen unbenutzten Miniserver als Prüfstand einrichten.



                  Klicke auf die Grafik für eine vergrößerte Ansicht  Name: 8 hex characters.png Ansichten: 164 Größe: 19,6 KB ID: 322668
                  Zuletzt geändert von Tico; 18.02.2023, 02:57. Grund: Updated link to wiki
                  Ich spreche kein Deutsch. Gib Google Translate die Schuld, wenn ich unverständlich bin.

                  Kommentar


                  • Labmaster
                    Labmaster kommentierte
                    Kommentar bearbeiten
                    Tico
                    Das ist doch aber richtig, zumindest sofern man den hex integer als 32bit SIGNED interpretiert ???

                  • Tico
                    Tico kommentierte
                    Kommentar bearbeiten
                    Ahhh, jetzt fange ich an zu verstehen... Nennen Sie es Unwissenheit meinerseits.

                    Der Miniserver liest das äußerste linke Hex-Zeichen als Vorzeichen für eine vorzeichenbehaftete 32-Bit-Hex-Ganzzahl, wenn er \h verwendet

                    0-7 = positiv
                    8-F = negativ

                    Der Höchstwert ist 2,147,483,647, der Mindestwert -2,147,483,648.

                    Vielen Dank!
                    Zuletzt geändert von Tico; 28.10.2021, 14:21.

                  • romildo
                    romildo kommentierte
                    Kommentar bearbeiten
                    Maxwert Hex negativ:FF7FFFFF Dez: -340282346638528859811704183484516925440
                    Maxwert Hex positiv: 7F7FFFFF Dez: 340282346638528859811704183484516925440
                    Minwert Hex: 3A83126F Dez: 0.001
                    Bemerkung:
                    Der Minwert bezieht sich auf mein Beispiel, da in Loxone maximal 3 Stellen hinter dem Komma angezeigt werden.
                    Sofern man noch kleinere Werte anzeigen möchte, müsste dann ab diesem Wert eine Entscheidung getroffen werden

                    FFFFFFF wird als FFFFFFFx interpretiert und ist grösser wie FF7FFFFF was zu einem Überlauf führt.
                    Zuletzt geändert von romildo; 28.10.2021, 10:57.
                Lädt...