Uncaught SyntaxError:Expected ',' or ']' after element in JSON at position 389

Begonnen von RPort, 12 Januar 2025, 20:26:23

Vorheriges Thema - Nächstes Thema

RPort

Problem:
Js-Exception in fhemweb.js Zeile 1335 var d= JSON.parse(l);
Es kommt ein Popup mit der Meldung oben.

Der Inhalt der Var l als String content:
["EG_GaesteWC_Raumthermos","0.3 °C, 21.3/21.0 °C, Ventil: 10 % auto HEATING","<div id=\u0022EG_GaesteWC_Raumthermos\u0022  title=\u00220.3 °C, 21.3/21.0 °C, Ventil: 10 % auto HEATING\u0022 class=\u0022col2\u0022><a href=\u0022/fhem?cmd.EG_GaesteWC_Raumthermos=set EG_GaesteWC_Raumthermos on&room=EG%5FGaesteBad&fwcsrf=csrf_104235452321702\u0022>0.3 °C, 21.3/21.0 °C, Ventil: 10 % a["PatrickBad_INT0000003","22.2/22.0  Level=0","<div id=\u0022PatrickBad_INT0000003\u0022  title=\u002222.2/22.0  Level=0\u0022 class=\u0022col2\u0022><a href=\u0022/fhem?cmd.PatrickBad_INT0000003=set PatrickBad_INT0000003 on&room=EG%5FPATRICKBAD&fwcsrf=csrf_104235452321702\u0022>22.2/22.0  Level=0</a></div>"]

Json-Literal:
"[\"EG_GaesteWC_Raumthermos\",\"0.3 °C, 21.3/21.0 °C, Ventil: 10 % auto HEATING\",\"<div id=\\u0022EG_GaesteWC_Raumthermos\\u0022  title=\\u00220.3 °C, 21.3/21.0 °C, Ventil: 10 % auto HEATING\\u0022 class=\\u0022col2\\u0022><a href=\\u0022/fhem?cmd.EG_GaesteWC_Raumthermos=set EG_GaesteWC_Raumthermos on&room=EG%5FGaesteBad&fwcsrf=csrf_104235452321702\\u0022>0.3 °C, 21.3/21.0 °C, Ventil: 10 % a[\"PatrickBad_INT0000003\",\"22.2/22.0  Level=0\",\"<div id=\\u0022PatrickBad_INT0000003\\u0022  title=\\u002222.2/22.0  Level=0\\u0022 class=\\u0022col2\\u0022><a href=\\u0022/fhem?cmd.PatrickBad_INT0000003=set PatrickBad_INT0000003 on&room=EG%5FPATRICKBAD&fwcsrf=csrf_104235452321702\\u0022>22.2/22.0  Level=0</a></div>\"]"

Analyse:
Der Fehler tritt auf bei Devices, bei denen im stateformat das Zeichen ° (Temperatur-Grad) verwendet wird. Beim erstmaligen Laden der Seite wird das Zeichen auch so dargestellt. Sobald das zugehörige Reading aktualisiert wird, erscheint in der Anzeige °
Dann passiert mehr oder weniger lange nichts.. wenn man die Seite länger stehen lässt, kommt das Fehler-Popup, d.h. frühestens bei der zweiten Aktualisierung
Bei einem Raum mit vielen Thermostaten, kommt der Fehler entsprechend häufig.

Systemumgebung:
FHEM ist aktuell
Chrome auf Windows 11
ich habe keinen Unterschied festgestellt, ob longpoll = 1 oder websocket

rudolfkoenig

Ich habe in meinem Test-Setup kein Problem ein Reading mit ° zu setzen oder im Betrieb zu aktualisieren.

Im gezeigten JSON faellt mir auf, dass die berechnete Anzeige (der dritte Wert im JSON Array) mehrere Probleme hat:
- es gibt einen zusaetzlichen [ nach dem dritten "Ventil", das ist der primaere Grund fuer den JSON Fehler
- das generierte HTML ist nicht komplett, ein a und ein div Tag werden nicht geschlossen.

Ich habe den String wegen besserer Lesbarkeit etwas umformatiert, damit man die Probleme einfacher sieht:

[
  "EG_GaesteWC_Raumthermos",
  "0.3 °C, 21.3/21.0 °C, Ventil: 10 % auto HEATING",
  "<div id='EG_GaesteWC_Raumthermos'
        title='0.3 °C, 21.3/21.0 °C, Ventil: 10 % auto HEATING'
        class='col2'>
    <a href='/fhem?cmd.EG_GaesteWC_Raumthermos=set EG_GaesteWC_Raumthermos on&room=EG%5FGaesteBad&fwcsrf=csrf_104235452321702'>
      0.3 °C, 21.3/21.0 °C, Ventil: 10 %
      a["PatrickBad_INT0000003","22.2/22.0  Level=0",
        <div id='PatrickBad_INT0000003'
            title='22.2/22.0  Level=0'
            class='col2'>
          <a href='/fhem?cmd.PatrickBad_INT0000003=set PatrickBad_INT0000003 on&room=EG%5FPATRICKBAD&fwcsrf=csrf_104235452321702'>
            22.2/22.0  Level=0
          </a>
        </div>"
]

Wenn weitere Hilfe benoetigt wird, dann benoetige ich die Definition samt Attribute der betroffenen Geraete (Stichwort "Copy for forum.fhem.de").

RPort

Das eigentliche Problem scheint mir, dass aus ° ein ° wird.
Der Verdacht, dass das daraus resultieren könnte, dass Front- und Backend unterschiedliche Codierungen nutzen, scheint durch folgende Erkenntnis erhärtet:

FHEM zeigt Codierung in UTF-8
Ich nutze Homematic (IP). Die Weboberfläche der CCU3 zeigt ISO-8859-1.
-> Kann es sein, dass beim Update der Werte der Thermostate in der Routine für das stateformat die Codierung durcheinander kommt?
   Die fehlerhafte HTML wäre dann ein Folgefehler bei der Offsetbildung (Zeile 1319ff in fhemweb.js), weil ° nun einmal länger ist als °, wird am Schluss jeweils ein Zeichen abgeschnitten.
   Die js-Exception tritt aber erst nach mehreren Roundtrips ein - wenn durch das (mehrmalige) Abschneiden das Json invalide wird.
-> Welche Codierung nutzt stateformat in diesem Fall?

rudolfkoenig

Zitat-> Welche Codierung nutzt stateformat in diesem Fall?
Falsche Frage: stateFormat aendert nichts an der Kodierung.

FHEM Vorgabe: alle Daten, die nach FHEM reingelesen werden, muessen intern in UTF-8 Format vorliegen.
Beim Rausschreiben wird das je nach Zielgeraet konvertiert, fuer WEB ist keine Konvertierung notwendig.

Da manche perl-Bibliotheken nicht mitspielen, gibt es "attr global encoding unicode".
In diesem Fall gilt: interne Daten sind in unicode/wide-char Format, bei der Ausgabe (z.Bsp. in FHEMWEB) muss konvertiert werden, da man wide-char nicht per syswrite loswerden kann.
Leider beachten manche Module weder diese globale Einstellung, noch konvertieren sie alles nach UTF-8, deswegen gibt es (selten) Darstellungsfehler.

Wenn Du vermutest, dass die Daten von der CCU3 nicht konvertiert werden, dann ist das ein Fall fuer dieses Modul, und nicht fuer FHEMWEB.

Das o.g. JSON Syntaxfehler hat aber damit nichts zu tun.

Alles nur meine Vermutung, da ich nichts Konkretes zum Nachstellen habe.

RPort

Ich habe das Problem für mich gelöst - als Doku für die "Nachwelt":

---------------
Setting zur Analyse des Problems:
In den Chrome-Entwicklertools den Schalter "Breakpoints - Pause on uncaught exceptions" gesetzt und in fhem Everything geöffnet
-> Break erfolgt (nach ggf. längerer Wartezeit) in fhemweb.js Zeile 1335   var d = JSON.parse(l);

-> Inspektion der Variablen
-> XMLHttpRequest.response Zeile 1310 stimmt bereits nicht
input = FW_pollConn.responseText  ist also schon falsch

=> Problem liegt nicht in fhemweb, sondern im Backend
------------------
Hypothese:
Problem liegt daran, dass Frontend mit UTF-8 codiert und Backend mit einer 1-Byte Codierung (anscheinend verwendet Homematic ISO-8859-1).

ISO-8859-1 Codierung von °C  benötigt 16 Bite 2 Byte
1011000001000011

UTF-8 Codierung von °C benötigt 24 Bit, d.h. 3 Byte
110000101011000001000011
(UTF-8 nutzt variable Zahl von Bytes, je nachdem um welches Zeichen es sich handelt. Für ° werden 2 Byte benötigt)

-> wenn 110000101011000001000011 (UTF-8 für °C) als ISO-8859-1 Codierung interpretiert wird, wird daraus °C
   Das deckt sich mit dem Systemverhalten

Meine Spekulation, die nicht stimmen muss - ich bin kein "Insider":
-> Falls im Backend substrings gebildet/kopiert werden, indem
    - die Zahl der Zeichen bestimmt wird
    - und diese Zahl als Anzahl zu kopierender Bytes verwendet wird,
   werden am Ende der UTF-8 Codierung Zeichen abgeschnitten - entsprechend der Zahl der Vorkommen der ° im zu kopierenden Text.
   Das würde jedenfalls genau dem fehlerhaften Inhalt des responseText entsprechen.
   
-----------------
Prüfung, ob die Verwendung von ° in stateformat das Auftreten der js-exception verursacht
-> und 1. Lösungsversuch:

in den stateformat das Zeichen ° durch Grad- ersetzt - d.h. jetzt gibt es nur noch ASCII-Zeichen
   -> Die Darstellung ist natürlich nicht mehr schön
   -> Es treten aber (nach 8 h warten) keine Exceptions mehr auf
   
   => Die exceptions werden (in meiner Systemkonstellation mit sehr vielen Homematic (IP) Heizkörper und Raumthermostaten)
      durch Verwendung von ° in stateformat verursacht.
      Diese Exceptions treten aber nur sporadisch (ggf. nach mehreren Roundtrips) auf und anscheinend eher/ häufiger,
     - wenn es mehrere (>3) Vorkommen von ° pro stateformats gibt und
     - wenn man einen Raum mit vielen Thermostaten anzeigt (insb. Everything)

------------------
2. Lösungsversuch
in stateformat wieder ° verwendet
attr global encoding unicode   (standard ist bytestream - aber was ist das?)
-> Die Darstellung von ° ist nun korrekt, d.h. ° wird als ° gezeigt.
   Das Modul IPCAM (Schnappschuss) scheint aber nicht mehr zu funktionieren.
-> Da anscheinend die Funktion nicht mehr gegeben ist, wollte ich im produktiven System damit nicht weiter
   experimentieren.
-> zurück auf: attr global encoding bytestream
   
 -----------------
3. Lösungsversuch -> erfolgreich
   in den stateformat das Zeichen ° durch &deg; ersetzt (Die Umgebung ist ja html und so wird nur noch der ASCII-Zeichenvorrat benutzt)
   -> Die Darstellung von ° ist nun korrekt, d.h. ° wird als ° gezeigt.
   -> Die Exceptions treten nicht mehr auf   (nach 8 h warten)
   => Problem gelöst :-)
   
Rudolf, Danke für die Hilfe!

rudolfkoenig

Zitat(standard ist bytestream - aber was ist das?)

UTF-8, siehe mein Schreiben von vorhin:
ZitatFHEM Vorgabe: alle Daten, die nach FHEM reingelesen werden, muessen intern in UTF-8 Format vorliegen.