TIA S_LHTTP_Get konsonanten werden nicht richtig intepretiert

Supermario73

Level-2
Beiträge
108
Reaktionspunkte
3
Zuviel Werbung?
-> Hier kostenlos registrieren
Hallo zusammen
Mit S_LHTTP_Get werden json Daten von einer URL gelesen. Dies funktioniert soweit. Der Text beinhaltet (ä, ö ,ü usw) und werden aber auf 2 Char aufgeteilt. Beispiel: 'Ã' 'œ' 'b' 'e' 'r' 'w' 'i' 'e' 'g' 'e' 'n' 'd'
ziel wäre: 'ü' 'b' 'e' 'r' 'w' 'i' 'e' 'g' 'e' 'n' 'd'

Hat da jemand eine Idee?

Code:
#S_LHTTP_Get(execute      := #S_LHTTP_Get_Execute,
                     hwID         := 0,
                     connID       := 1,
                     url          := #S_url,
                     queryParams  := 'lang=de&country=de',
                     responseData := "HTTP-Daten".ac_responseData);

Besten Dank für Eure Ideen
 
Zuletzt bearbeitet:
Das ganze basiert auf dem utf 8 Zeichensatz, in Tia wird json als Bytestream verarbeitet und wiedergegeben.. d.h. pro Zeichen ist ein Byte vorgesehen.. die Sondernzeichen zu denen auch unsere Umlaute gehören sind aber größer ein Byte (utf 8 kann Zeichen mit einer Länge von 1-4 Byte darstellen)


d.h. entweder die Zeichen auf der zu anfragenden Seite anpassen, oder im Tia den ganzen Bytstream verwurschteln
 
Bei utf8 sind das Werte von 00 bis 7F. Alle Zeichen des lateinischen Grundalphabets.
Alle Zeichen danach werden mit mindestens zwei Byte dargestellt.

Auch ein Array of Char ist im Endeffekt nur ein Bytestream (ich denke mal das so die Daten reinkommen und nur 1:1 als Char übergeben werden)

Also ein Zeichen = ein Byte = ein Char mit Werten von 00 bis 7F.

Deswegen wird auch immer wieder von den "alten Hasen" gepredigt, keine Leerzeichen zu verwenden sondern sich an etablierte Casings zu halten und auch einfach international in englisch zu arbeiten, bzw Sonderzeichen zu vermeiden.. um eben eine Lesbarkeit für Maschinen zu ermöglichen und zu erhalten.

1742994840004.png

D.h. eine 1:1 Umwandlung wird dir bei Zeichen ausserhalb des Grundalphabets immer falsch darstellen.

Deswegen hast du die Möglichkeit die Daten welche du abfragst so anzupassen, dass es maschinenlesbar ist, oder du bearbeitest das ganze in der Steuerung.. ich würde ersteres machen.

Wie ich auf json komme.. frag mich das nicht, da war ich noch ohne Kaffee ;)


Hier die aktuellen Bibliotheken von Siemens dafür:

Wir wissen auch nicht welche Tia Version du verwendest, welche Firmware der Cpu und einen Screenshot gibts leider auch nicht..
 
Hier noch mal als Beispiel dein Ü:

Dein Char kann das Ü darstellen, was daran liegt, dass sich Char den Ascii Zeichensatz (wohlmöglich an den erweiterten) verwendet:
 
Zuletzt bearbeitet:
Dem Http Request kann man mitgeben, welchen Zeichensatz man gerne hätte, z.B.:
Accept-Charset: utf-8

Inwiefern man das am oben verwendeten Baustein übergeben kann (bzw. er das intern handhabt) weiß ich nicht. Außerdem ist das nur ein Wunsch, ob der Server passend liefern kann ist das andere Thema.
 
TIA 19 wird verwendet
CPU 1512SP-1 PN V3.0
Genau diese Bibliotheken haben wir vewendet:
1743031841432.png

Die Schrittkette:

Code:
CASE #Si_Schrittnummer OF
    0:  // Start
        IF #IOx_Execute THEN
            #Si_Schrittnummer := 10;
        END_IF;
       
    10: // Initialisierung
        #S_LHTTP_Get_Execute := false;
        #Sx_LStream_JsonDeserializer_Execute := false;
       
        FILL_BLK(IN    := '*',
                 COUNT := 16201,
                 OUT   => "HTTP-Daten".ac_responseData[0]);
       
        FILL_BLK(IN    := 0,
                 COUNT := 16201,
                 OUT   => "HTTP-Daten".ab_responseData[0]);
       
        FOR #Ti_i := 0 TO 1200 DO
            "JSON-Daten".st_responseData[#Ti_i].type := 0;
            "JSON-Daten".st_responseData[#Ti_i].key := '';
            "JSON-Daten".st_responseData[#Ti_i].value := '';
            "JSON-Daten".st_responseData[#Ti_i].depth := 0;
            "JSON-Daten".st_responseData[#Ti_i].closingElement := false;
        END_FOR;
     
       #Si_Schrittnummer += 1;
       
    11: // URL zusammensetzen
        #S_url := #Cs_URL_current;
        #S_url := CONCAT_STRING(IN1 := #S_url, IN2 := 'weather');
        #S_url := CONCAT_STRING(IN1 := #S_url, IN2 := '?q=');
        #S_url := CONCAT_STRING(IN1 := #S_url, IN2 := #Is_Location);
        #S_url := CONCAT_STRING(IN1 := #S_url, IN2 := ',ch&mode=json&units=metric&lang=de&appid=');
        #S_url := CONCAT_STRING(IN1 := #S_url, IN2 := #Is_API_key);
       
        #Si_Schrittnummer += 1;
       
    12: // Daten vom Webserver abholen
        #S_LHTTP_Get(execute      := #S_LHTTP_Get_Execute,
                     hwID         := 0,
                     connID       := 1,
                     url          := #S_url,
                     queryParams  := 'application/json',
                     responseData := "HTTP-Daten".ac_responseData);
       
        #S_LHTTP_Get_Execute := true;
       
        IF #S_LHTTP_Get.done THEN
            #Si_Schrittnummer += 1;
        END_IF;
       
    13: // Array of Char umwandeln in Array of Byte
     
        #Ti_Ret_Val := BLKMOV(SRCBLK := "HTTP-Daten".ac_responseData, DSTBLK => "HTTP-Daten".ab_responseData);
        #Si_Schrittnummer += 1;
       
    14:  // JSON-Datenformat deserialisieren
        #S_LStream_JsonDeserializer(execute := #Sx_LStream_JsonDeserializer_Execute,
                                    search  := false,
                                    resultCount=>#Ti_Temp,
                                    tree    := "JSON-Daten".st_responseData,
                                    raw     := "HTTP-Daten".ab_responseData);
       
        #Sx_LStream_JsonDeserializer_Execute := true;
       
        IF #S_LStream_JsonDeserializer.done THEN
            #Si_Array_Index := 0;
            #Si_Schrittnummer += 1;
        END_IF;
       
    15:  // Daten in Struktur S_current_weather eintragen
       
        #Ti_i := #Si_Array_Index;
//und hier werden die Daten versorgt

Haben wir was übersehen, um den Datenstring in ascii einzulesen?

Besten Dank für Eure Hilfe!
 
Zuletzt bearbeitet:
Zuviel Werbung?
-> Hier kostenlos registrieren
Haben wir was übersehen, um den Datenstring in ascii einzulesen?
Dem Http Request kann man mitgeben, welchen Zeichensatz man gerne hätte, z.B.:
Accept-Charset: utf-8

Inwiefern man das am oben verwendeten Baustein übergeben kann (bzw. er das intern handhabt) weiß ich nicht. Außerdem ist das nur ein Wunsch, ob der Server passend liefern kann ist das andere Thema.
Wie @Oberchefe schrieb, recherchieren wie ihr die Daten als Ascii Zeichensatz anfragen könnt und ob
 
Ich weiss nicht was gemeint ist mit "Dem Http Request kann man mitgeben, welchen Zeichensatz man gerne hätte, z.B.:
Accept-Charset: utf-8"

Dem Request kann am queryParams etwas mitgegeben werden, habe einiges versucht, kam aber nicht zum Ziel, finde auch keine Doku was da alles möglich ist.
#S_LHTTP_Get(execute := #S_LHTTP_Get_Execute,
hwID := 0,
connID := 1,
url := #S_url,
queryParams := '',
length=> #Ti_Temp,
responseData := "HTTP-Daten".ac_responseData);
Es wird immer folgendes geschrieben:
1743068441595.png

Und das ganze in byte:
1743069012243.png
 
Was ist denn deine Erwartung @Supermario73 ?

Die verschiedenen Zeichensätze sind ja jetzt erklärt und definiert.

Entweder du sagst der Gegenstelle, dass die Daten so nicht verarbeitbar sind, oder du findest einen Weg, die Daten für dich verarbeitbar anzufragen, das hängt denke ich auch von der anzufragenden Seite ab.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Gesucht ist doch jetzt eine eventuell mögliche korrekte Syntax für die URL, die die Gegenstelle dazu überredet, einen erweiterten ASCII-Zeichensatz zu senden statt Unicode.
 
Die schnell Lösung sieht nun so aus:
Code:
FUNCTION "Baustein_1" : Void
{ S7_Optimized_Access := 'TRUE' }
VERSION : 0.1
   VAR_INPUT
      Is_Text : String;
   END_VAR

   VAR_OUTPUT
      Qs_Text : String;
   END_VAR

   VAR_TEMP
      Ts_String : String;
      Ti_p : Int;
   END_VAR


BEGIN
    #Ts_String := #Is_Text;
    #Ti_p := FIND(IN1 := #Ts_String, IN2 := 'Ü');
    IF #Ti_p <> 0 THEN
        #Ts_String := REPLACE(IN1 := #Ts_String, IN2 := 'Ü', L := 2, P := #Ti_p);
    END_IF;
    #Ti_p := FIND(IN1 := #Ts_String, IN2 := 'Ä');
    IF #Ti_p <> 0 THEN
        #Ts_String := REPLACE(IN1 := #Ts_String, IN2 := 'Ä', L := 2, P := #Ti_p);
    END_IF;
    #Ti_p := FIND(IN1 := #Ts_String, IN2 := 'Ö');
    IF #Ti_p <> 0 THEN
        #Ts_String := REPLACE(IN1 := #Ts_String, IN2 := 'Ö', L := 2, P := #Ti_p);
    END_IF;
    #Ti_p := FIND(IN1 := #Ts_String, IN2 := 'ü');
    IF #Ti_p <> 0 THEN
        #Ts_String := REPLACE(IN1 := #Ts_String, IN2 := 'ü', L := 2, P := #Ti_p);
    END_IF;
    #Ti_p := FIND(IN1 := #Ts_String, IN2 := 'ä');
    IF #Ti_p <> 0 THEN
        #Ts_String := REPLACE(IN1 := #Ts_String, IN2 := 'ä', L := 2, P := #Ti_p);
    END_IF;
    #Ti_p := FIND(IN1 := #Ts_String, IN2 := 'ö');
    IF #Ti_p <> 0 THEN
        #Ts_String := REPLACE(IN1 := #Ts_String, IN2 := 'ö', L := 2, P := #Ti_p);
    END_IF;
    #Ti_p := FIND(IN1 := #Ts_String, IN2 := 'ß');
    IF #Ti_p <> 0 THEN
        #Ts_String := REPLACE(IN1 := #Ts_String, IN2 := 'ss', L := 2, P := #Ti_p);
    END_IF;
    #Qs_Text := #Ts_String;
    
END_FUNCTION
 
Hi,
wäre es denn keine Möglichkeit den Empfang in einen WString zu schreiben, da sollte das dann ja richtig drinstehen, und dann in einen String zu konvertieren?

Deine Lösung müsstest du in einer Schleife laufen lassen die erst dann abgebrochen wird wenn nichts mehr gefunden/ersetzt wurde.
 
Zuviel Werbung?
-> Hier kostenlos registrieren
Hier ein paar Beispiele, wie im http Protokoll der Austausch zwischen Client und Server aussehen kann:


Ohne den o.a. Baustein genau zu kennen, würde ich erwarten, dass solche Parameter eventuell im oben genannten Eingangsparameter "queryParams" übergeben werden können.

Das sollte aber in der Hilfe bzw. der Doku zum Baustein stehen.
 
Zurück
Oben