NEWS
Json-String in Objekte schreiben
-
Hallo,
ich versuche aktuell meinen Json-String den ich von einem Hichi Wifi IR Smartmeter bekomme auf entsprechende Objekte zu schreiben. Aktuell verusche ich aus verschiedenen Beiträgen mir ein funktionierendes Skript zusammenzustellen, leider ohne wirklichen Erfolg.
Kann mir jemand von euch bitte dabei weiterhelfen.hier der ursprüngliche String den ich per MQTT erhalte:
{"sn":{"Time":"2023-12-10T08:19:18","SM":{"1_8_0":2374.95355910,"2_8_0":23592.80211428,"16_7_0":487.01,"36_7_0":260.22,"56_7_0":107.08,"76_7_0":119.71,"32_7_0":231.6,"52_7_0":235.0,"72_7_0":231.6,"96_1_0":"***********"}},"ver":1}
Hier etwas leserlicher:
{ "sn":{ "Time":"2023-12-10T08:19:18", "SM":{ "1_8_0":2374.95355910, "2_8_0":23592.80211428, "16_7_0":487.01, "36_7_0":260.22, "56_7_0":107.08, "76_7_0":119.71, "32_7_0":231.6, "52_7_0":235.0, "72_7_0":231.6, "96_1_0":"***********" } },
Mein Skript sieht aktuell wie folgt aus:
on({id: 'mqtt.0.tasmota/discovery/3494548E85FC/sensors', change: "any"}, function (obj) { var 1_8_0; var 2_8_0; var 16_7_0; var 36_7_0; var 56_7_0; var 76_7_0; var 32_7_0; var 52_7_0; var 72_7_0; var 96_1_0; //der try ist wichtig das der adapter nicht abschmiert bei einem fehler, hiermit pasen wird die json in ein object try {obj = JSON.parse(getState('mqtt.0.tasmota/discovery/3494548E85FC/sensors').val); } catch (e) { console.error('Cannot parse: ' + getState('mqtt.0.tasmota/discovery/3494548E85FC/sensors').val); return; } 1_8_0 = obj.Bezung; 2_8_0 = obj.Export; 16_7_0 = obj.Leistung_aktuell; 36_7_0 = obj.Leistung_L1; 56_7_0 = obj.Leistung_L2; 76_7_0 = obj.Leistung_L3; 32_7_0 = obj.Spannung_L1; 52_7_0 = obj.Spannung_L2; 72_7_0 = obj.Spannung_L3; 96_1_0 = obj.Seriennummer; setState('javascript.0.Hichi_Wifi_IR.Bezug', obj[''].Bezug, true); setState('javascript.0.Hichi_Wifi_IR.Export', obj[''].Export, true); setState('javascript.0.Hichi_Wifi_IR.Leistung_aktuell', obj[''].Leistung_aktuell, true); setState('javascript.0.Hichi_Wifi_IR.Leistung_L1', obj[''].Leistung_L1, true); setState('javascript.0.Hichi_Wifi_IR.Leistung_L2', obj[''].Leistung_L2, true); setState('javascript.0.Hichi_Wifi_IR.Leistung_L3', obj[''].Leistung_L3, true); setState('javascript.0.Hichi_Wifi_IR.Spannung_L1', obj[''].Spannung_L1, true); setState('javascript.0.Hichi_Wifi_IR.Spannung_L2', obj[''].Spannung_L2, true); setState('javascript.0.Hichi_Wifi_IR.Spannung_L3', obj[''].Spannung_L3, true); setState('javascript.0.Hichi_Wifi_IR.Seriennummer', obj[''].Seriennummer, true); });
Als Fehlermeldung erhalte ich aktuell folgendes:
15:15:21.913 error javascript.0 (17262) script.js.common.Hichi_Wifi_IR.MQTT_Parsen compile failed: at script.js.common.Hichi_Wifi_IR.MQTT_Parsen:3
Worin liegt aktuell das Problem?
-
Syntaxfehler in Zeile 3. Sollte auch rot unterstrichen sein
const 12 = 15 const 13 = 17 const result = 12 + 13
was kommt da wohl raus Zahlen sind am Anfang von Bezeichnern nicht erlaubt.
-
@chrischros sagte in Json-String in Objekte schreiben:
Hichi Wifi IR Smartmeter
ist der Hichi am Tasmota ESP dran ?
-
@ralla66 ja ist er.
Ich weiß ich kann dann auch den Sonof Adapter nutzen, das habe ich auch funktioniert soweit auch alles bestens.
Da ich aber noch mehr Sensoren habe die per MQTT senden wollte ich das alles zentral haben. -
@chrischros sagte: Worin liegt aktuell das Problem?
(Variablen-)Bezeichner dürfen nicht mit einer Ziffer beginnen. Außerdem:
Bezug = obj.sn.SM['1_8_0'];
-
@chrischros sagt: Mein Skript sieht aktuell wie folgt aus:
Vorschlag:
on('mqtt.0.tasmota/discovery/3494548E85FC/sensors', function (dp) { let obj = {}; //der try ist wichtig das der adapter nicht abschmiert bei einem fehler, hiermit pasen wird die json in ein object try {obj = JSON.parse(dp.state.val).sn.SM; } catch (e) { console.error('Cannot parse: ' + dp.state.val); return; } setState('javascript.0.Hichi_Wifi_IR.Bezug', obj['1_8_0'], true); setState('javascript.0.Hichi_Wifi_IR.Export', obj['2_8_0'], true); setState('javascript.0.Hichi_Wifi_IR.Leistung_aktuell', obj['16_7_0'], true); setState('javascript.0.Hichi_Wifi_IR.Leistung_L1', obj['36_7_0'], true); setState('javascript.0.Hichi_Wifi_IR.Leistung_L2', obj['56_7_0'], true); setState('javascript.0.Hichi_Wifi_IR.Leistung_L3', obj['76_7_0'], true); setState('javascript.0.Hichi_Wifi_IR.Spannung_L1', obj['32_7_0'], true); setState('javascript.0.Hichi_Wifi_IR.Spannung_L2', obj['52_7_0'], true); setState('javascript.0.Hichi_Wifi_IR.Spannung_L3', obj['72_7_0'], true); });
-
@paul53 vielen Dank, sieht etwas schlanker aus als bei mir.
Eine Frage noch, wird bei setState auch ein Object angelegt oder nur der Wert aktualisiert? -
@chrischros sagte: wird bei setState auch ein Object angelegt oder nur der Wert aktualisiert?
Es wird nur der Zustand aktualisiert. Der Datenpunkt muss bereits existieren.
Erstelle eigene Datenpunkte besser unter "0_userdata.0". -
@paul53 ok, danke für den Hinweis.
werde dann mal alles in "0_userdate.0" schreiben.setState('0_userdate.0.Hichi_Wifi_IR.Bezug', (kWh));
Wenn ich einen eigenen Datenpunkt erstellen möchte, würde das so klappen?
createState('0_userdate.0.Hichi_Wifi_IR.Bezug'', 0,{type: 'nummer',name: 'Bezug kWh Zahl', read: true,write: true,role: 'value.watt'})
Diese Zeilen müssten dann auch ganz an den Anfang des Skrips, noch vor
on('mqtt.0.tasmota/discovery/3494548E85FC/sensors', function (dp) {
oder?
-
@chrischros sagte: würde das so klappen?
Nein, so:
createState('0_userdata.0.Hichi_Wifi_IR.Bezug', 0, {type: 'number', name: 'Bezug', unit: 'kWh', read: true, write: false, role: 'value.energy'})
@chrischros sagte in Json-String in Objekte schreiben:
Diese Zeilen müssten dann auch ganz an den Anfang des Skrips, noch vor on
Ja, oder in einem zusätzlichen Skript, das anschließend gelöscht werden kann.
Erstelle manuell im Tab "Objekte" ein Objekt (Typ "folder" oder "device") unter "0_userdata.0" mit dem Namen "Hichi_Wifi_IR". -
@paul53 sagte in Json-String in Objekte schreiben:
Hichi_Wifi_IR
Super danke, wie sieht das dann bei z.B. der Seriennummer aus, die sowohl aus Zahlen und Buchstaben besteht?
createState('0_userdata.0.Hichi_Wifi_IR.Seriennummer', 0, {type: 'mixed', name: 'Seriennummer', read: true, write: false, role: 'state'})
-
@chrischros sagte: Seriennummer
type: 'string'
-
eine Zeichenkette die keine nummer ist ist ein string.
-
Vielen Dank für die Unterstützung.
Habe das jetzt noch etwas angepasst, sieht nun so aus:createState('0_userdata.0.Hichi_Wifi_IR.Bezug', 0, {type: 'number', name: 'Bezug', unit: 'kWh', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Export', 0, {type: 'number', name: 'Export', unit: 'kWh', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_aktuell', 0, {type: 'number', name: 'Leistung_aktuell', unit: 'W', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_L1', 0, {type: 'number', name: 'Leistung_L1', unit: 'W', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_L2', 0, {type: 'number', name: 'Leistung_L2', unit: 'W', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_L3', 0, {type: 'number', name: 'Leistung_L3', unit: 'W', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Spannung_L1', 0, {type: 'number', name: 'Spannung_L1', unit: 'V', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Spannung_L2', 0, {type: 'number', name: 'Spannung_L2', unit: 'V', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Spannung_L3', 0, {type: 'number', name: 'Spannung_L3', unit: 'V', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Seriennummer', 0, {type: 'string', name: 'Seriennummer', read: true, write: false, role: 'state'}) on('mqtt.0.tasmota/discovery/3494548E85FC/sensors', function (dp) { let obj = {}; //der try ist wichtig das der adapter nicht abschmiert bei einem fehler, hiermit pasen wird die json in ein object try {obj = JSON.parse(dp.state.val).sn.SM; } catch (e) { console.error('Cannot parse: ' + dp.state.val); return; } setState('0_userdata.0.Hichi_Wifi_IR.Bezug', obj['1_8_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Export', obj['2_8_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_aktuell', obj['16_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_L1', obj['36_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_L2', obj['56_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_L3', obj['76_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Spannung_L1', obj['32_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Spannung_L2', obj['52_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Spannung_L3', obj['72_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Seriennummer', obj['96_1_0'], true); });
Würde das soweit passen oder gibt es noch Fehler darin?
-
ich weiß gerade nicht ob obj im Fehlerfall
{}
oderundefinied
enthält. Das solltest du checken in dem du einen absichtlich Fehler erzeugst. Ansonsten siehts gut aus.Noch was kleinkarriertes, wenn du rolen benutzten willst, hier findest du die richtigen: https://github.com/ioBroker/ioBroker.docs/blob/master/docs/en/dev/stateroles.md
-
@chrischros sagte: gibt es noch Fehler darin?
Der Initialisierungswert für die Seriennummer sollte ein Leerstring sein - keine 0.
Die Rollen passen nicht. Leistung: "value.power", Spannung: "value.voltage". -
habe das Skript angepasst:
createState('0_userdata.0.Hichi_Wifi_IR.Bezug', 0, {type: 'number', name: 'Bezug', unit: 'kWh', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Export', 0, {type: 'number', name: 'Export', unit: 'kWh', read: true, write: false, role: 'value.energy'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_aktuell', 0, {type: 'number', name: 'Leistung_aktuell', unit: 'W', read: true, write: false, role: 'value.power'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_L1', 0, {type: 'number', name: 'Leistung_L1', unit: 'W', read: true, write: false, role: 'value.power'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_L2', 0, {type: 'number', name: 'Leistung_L2', unit: 'W', read: true, write: false, role: 'value.power'}) createState('0_userdata.0.Hichi_Wifi_IR.Leistung_L3', 0, {type: 'number', name: 'Leistung_L3', unit: 'W', read: true, write: false, role: 'value.power'}) createState('0_userdata.0.Hichi_Wifi_IR.Spannung_L1', 0, {type: 'number', name: 'Spannung_L1', unit: 'V', read: true, write: false, role: 'value.voltage'}) createState('0_userdata.0.Hichi_Wifi_IR.Spannung_L2', 0, {type: 'number', name: 'Spannung_L2', unit: 'V', read: true, write: false, role: 'value.voltage'}) createState('0_userdata.0.Hichi_Wifi_IR.Spannung_L3', 0, {type: 'number', name: 'Spannung_L3', unit: 'V', read: true, write: false, role: 'value.voltage'}) createState('0_userdata.0.Hichi_Wifi_IR.Seriennummer', ' ', {type: 'string', name: 'Seriennummer', read: true, write: false, role: 'state'}) on('mqtt.0.tasmota/discovery/3494548E85FC/sensors', function (dp) { let obj = {}; //der try ist wichtig das der adapter nicht abschmiert bei einem fehler, hiermit pasen wird die json in ein object try {obj = JSON.parse(dp.state.val).sn.SM; } catch (e) { console.error('Cannot parse: ' + dp.state.val); return; } setState('0_userdata.0.Hichi_Wifi_IR.Bezug', obj['1_8_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Export', obj['2_8_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_aktuell', obj['16_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_L1', obj['36_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_L2', obj['56_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Leistung_L3', obj['76_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Spannung_L1', obj['32_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Spannung_L2', obj['52_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Spannung_L3', obj['72_7_0'], true); setState('0_userdata.0.Hichi_Wifi_IR.Seriennummer', obj['96_1_0'], true); });
Ist der Leerstring so richtig eingepflegt?
-
@chrischros sagte: Ist der Leerstring so richtig eingepflegt?
Das ist zwar ein String mit einem Leerzeichen, ist aber auch in Ordnung.
-
@ticaki sagte: ob obj im Fehlerfall {} oder undefinied enthält.
Das spielt keine Rolle, da
obj
im Fehlerfall nicht ausgewertet wird. -
@paul53
Recht hast du, hab das return übersehen.