NEWS
(gelöst) Datenpunkte per RESTful API senden
-
Guten Morgen,
ich habe 2 Raspis mit IoBroker, einer mehr zum testen, der andere sozusagen das Produktivsystem. Jetzt will ich per simple-api.0 Adapter die Daten vom 1 (Test) zum 2 (Produktivsystem) übertragen. Ich mache das schon mit anderen Datenpunkten, wie denen vom BackItUp und dem RPI2 Adapter und das funktioniert super.
Jetzt möchte ich die DP vom Logparser vom 1 zum 2 schicken, um sie in VIS anzuzeigen. Dazu habe ich ein Blockly erstellt und darin eine Funktion mit diesem Script:var request = require ('request'); // Global let lastTimeUpdated = getState("logparser.0.lastTimeUpdated").val; // HomeMatic let jsonHom = getState("logparser.0.filters.Homematic.json").val; let jsonCountHom = getState("logparser.0.filters.Homematic.jsonCount").val; let nameHom = getState("logparser.0.filters.Homematic.name").val; // Info let jsonInfo = getState("logparser.0.filters.Info.json").val; let jsonCountInf = getState("logparser.0.filters.Info.jsonCount").val; let nameInf = getState("logparser.0.filters.Info.name").val; // WarnAndError let jsonWar = getState("logparser.0.filters.WarnAndError.json").val; let jsonCountWar = getState("logparser.0.filters.WarnAndError.jsonCount").val; let nameWar = getState("logparser.0.filters.WarnAndError.name").val; // Global request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.lastTimeUpdated?value=' +lastTimeUpdated); // HomeMatic request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.HomeMatic.json?value=' +jsonHom); request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.HomeMatic.jsonCount?value=' +jsonCountHom); request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.HomeMatic.name?value=' +nameHom); // Info request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.Info.json?value=' +jsonInfo); request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.Info.jsonCount?value=' +jsonCountInf); request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.Info.name?value=' +nameInf); // WarnAndError request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.WarnAndError.json?value=' +jsonWar); request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.WarnAndError.jsonCount?value=' +jsonCountWar); request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.WarnAndError.name?value=' +nameWar);
Es werden alle Werte sauber übertragen, bis auf die 3 "json". Im original JSON DP stehen diese Datensätze:
und ankommen tut nur:[{"date":"12.08.2023","severity":"<span class
das ist alles.
Ich habe schon die Instanzen von API und JS neu gestartet, dann gezielt ein Script nur für diesen einen DP angelegt, alles ohne Erfolg. Es gibt in den Protokollen keinerlei Fehlermeldungen dazu. Das es eigentlich funktionieren müsste, sehe ich an den DP vom BackItUp, da wird die historie.json sauber übertragen.
Da ich keine Ahnung vom Programmieren habe, habe ich ein anderes, wesentlich umfangreicheres, Script getestet. Wen es interessiert://const sourceSystemIP = "192.168.1.11"; // IP-Adresse des Quellsystems const targetSystemIP = "192.168.1.14"; // IP-Adresse des Zielsystems const targetPort = "8087"; // Port des Zielsystems const targetDataPoint = "0_userdata.0.LogParser_Raspi4.Info.json"; // Zieldatenpunkt auf dem Zielsystem const request = require("request"); // Lesen der Daten vom Quelldatenpunkt getState("logparser.0.filters.Info.json", (err, state) => { if (!err && state) { const dataToSend = state.val; // Erstellen der URL für die Ziel-REST-API const targetURL = `http://${targetSystemIP}:${targetPort}/set/${targetDataPoint}?value=${encodeURIComponent(dataToSend)}`; // Senden der Daten an das Zielsystem request.get(targetURL, (error, response, body) => { if (!error && response.statusCode === 200) { console.log("Daten erfolgreich an das Zielsystem übertragen."); } else { console.error("Fehler beim Übertragen der Daten an das Zielsystem:", error); } }); } else { console.error("Fehler beim Lesen des Quelldatenpunkts:", err); } }); function getState(dataPoint, callback) { }
Auch dabei das gleiche Problem. Um es schneller zu testen, habe ich anstatt einen Trigger auf einen DP zu mache, das Script über einen Zeitplan von alle 10 Sekunden laufen lassen. Ändert nichts, ich bekomme auch keinerlei Fehlermeldung oder sonstiges im LOG zu sehen. Als ob das Script gar nicht läuft.
Meine Adapter sind alle auf der aktuellen Stable Version.
Vielleicht sieht einer von auch einen Fehler, ich weiß nämlich nicht mehr weiter.Gruß Johannes
-
@jojo58
oha... gehobeneshttps://forum.iobroker.net/topic/67450/json-nach-iobroker-übertragen/5
und dazu:
const axios = require("axios") async function einfachausmeinemSkriptkopiert() { try { const {data} = await axios.post('http://'+getState('wled.0.c049efe62f6c._info.ip').val+'/json', { "bri":oBri, "seg": [{ "id": 0, "i": p }]}, { headers: { "Content-Type": 'application/json' } } ) } catch(error) { console.warn('wled unten nicht erreichbar!' + error) } }
request sollte man AFAIK nicht mehr nutzen.
EDIT: zusammengefasst sollte das dann wohl so aussehen:
// das hier muß einmal im Skript stehen const axios = require("axios") // hiermit sendest du die Daten: sollte selbst erklärend sein /* * ip: string "ip:port" * deinDatenpunkt: string "userdata_0.0.blabla" * deinJson: Dein Json :) */ postJson(ip, deinDatenpunkt, deinJson) //Das hier irgendwo unten wo es nicht stört async function postJson(ip, dp, value) { let json = typeof value == 'string' ? JSON.parse(value) : value try { const {data} = await axios.post('http://'+ip+'/setValueFromBody/'+dp, json, { headers: { "Content-Type": 'application/json' } } ) } catch(error) { console.warn('wled unten nicht erreichbar!' + error) } }
Falls es beim Probieren einen Fehler gibt, posten, ich behebe es dann.
-
@ticaki Vielen Dank schon mal für deine Hilfe. Leider habe ich, wie schon erwähnt, keine Ahnung vom Programmieren, aber ich werde mal versuchen deinen Ansatz umzusetzen. Ich kann zwar vieles nachvollziehen, aber mir fehlen einfach die Grundkenntnisse um Fehler zu finden.
JoJo
-
@jojo58
moment ich machs fertig da ist aber noch ein Fehler -
@jojo58
Jetzt sollte es funktionieren mußt nur den postJson aufruf anpassen -
@ticaki Ich habe es kopiert, meine Daten eingetragen und leider klappt es nicht. Erst mal eine Frage: Müssen die IP:Port DP und mein Json jeweils in Anführungszeichen stehen?
Kann es sein das es nicht das komplette Script ist? Mit meinen Daten sieht es so aus:// das hier muß einmal im Skript stehen const axios = require("axios") // hiermit sendest du die Daten: sollte selbst erklärend sein /* * ip: string "ip:port" * deinDatenpunkt: string "userdata_0.0.blabla" * deinJson: Dein Json :) */ postJson(192.168.1.14:8087, 0_userdata.0.LogParser_Raspi4.HomeMatic.json, logparser.0.filters.Homematic.json) //Das hier irgendwo unten wo es nicht stört async function postJson(ip, dp, value) { let json = typeof value == 'string' ? JSON.parse(value) : value try { const {data} = await axios.post('http://'+ip+'/setValueFromBody/'+dp, json, { headers: { "Content-Type": 'application/json' } } ) } catch(error) { console.warn('wled unten nicht erreichbar!' + error) } }
Dann kommt folgende Fehlermeldung:
14:11:08.093 error javascript.0 (27410) script.js.API_Daten_senden.LP_jsonInfo_senden compile failed: at script.js.API_Daten_senden.LP_jsonInfo_senden:13
-
@jojo58
Zeile 11
1 & 2 in Anführungszeichen
3. ingetState("HIER HIN").val
postJson("192.168.1.14:8087", "0_userdata.0.LogParser_Raspi4.HomeMatic.json", getState("logparser.0.filters.Homematic.json").val)
die 13 am Ende der Fehlerzeile zeigt dir welche Zeile falsch ist.
-
@ticaki Okay, das Script spuckt keine Fehler mehr aus, aber es werden auch nur ein paar Daten übertragen:
[ { "date": "12.08.2023", "severity": "<span class
Mich wundert echt, das es mit dem Historie.JSON vom BackItUp Adapter so schön klappt, und die hier so einen Ärger machen.
-
@jojo58
was kommt wenn du nur das im Skript hast:log(getState("logparser.0.filters.Homematic.json").val)
oha, da ist bestimmt ein Steuerzeichen hinter <span class
-
@jojo58
Für mich sieht es so aus, als ob ein oder ein nicht gültiges Zeichen in der URL zu übertragen.
Da wird abgebrochen, beziehungsweise nicht übertragen.
Kannst du den folgenden Befehl verwenden?
encodeURIComponent
https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/encodeURIComponent?retiredLocale=deEin ist zum Beispiel die Zeichen Folge %20
-
@ticaki Dann kommt:
14:44:36.838 info javascript.0 (27410) Start javascript script.js.API_Daten_senden.Test_API 14:44:36.860 info javascript.0 (27410) script.js.API_Daten_senden.Test_API: [ { "date": "12.08.2023", "severity": "<span class='logWarn logSeverity'>warn</span>", "from": "hm-rega.0", "message": "[2 Einträge] Script \"!# system.fn 0.1 !# !# Dieses Script gibt die FW-Versionsnummer und mehr systems\" ignored, b", "ts": 1691799750581 }, { "date": "12.08.2023", "severity": "<span class='logWarn logSeverity'>warn</span>", "from": "influxdb.0", "message": "Error on writePoint(\"{\"value\":12,\"time\":\"2023-08-12T00:21:39.143Z\",\"from\":\"system.adapter.hm-rpc.1\",", "ts": 1691799724657 }, { "date": "12.08.2023", "severity": "<span class='logWarn logSeverity'>warn</span>", "from": "influxdb.0", "message": "Error on writePoint(\"{\"value\":31,\"time\":\"2023-08-12T00:21:28.764Z\",\"from\":\"system.adapter.hm-rpc.1\",", "ts": 1691799721275 }, { "date": "12.08.2023", "severity": "<span class='logWarn logSeverity'>warn</span>", "from": "influxdb.0", "message": "Error on writePoint(\"{\"value\":33,\"time\":\"2023-08-12T00:20:21.862Z\",\"from\":\"system.adapter.hm-rpc.1\",", "ts": 1691799721275 }, { "date": "12.08.2023", "severity": "<span class='logWarn logSeverity'>warn</span>", "from": "influxdb.0", "message": "Error on writePoint(\"{\"value\":3.2,\"time\":\"2023-08-12T00:21:28.763Z\",\"from\":\"system.adapter.hm-rpc.1\"", "ts": 1691799721274 }, { "date": "12.08.2023", "severity": "<span class='logWarn logSeverity'>warn</span>", "from": "influxdb.0", "message": "Error on writePoint(\"{\"value\":0.26,\"time\":\"2023-08-12T00:21:28.523Z\",\"from\":\"system.adapter.hm-rpc.0", "ts": 1691799721265 } ] 14:44:36.861 info javascript.0 (27410) script.js.API_Daten_senden.Test_API: registered 0 subscriptions, 0 schedules, 0 messages, 0 logs and 0 file subscriptions
-
@jojo58
Das Hochkomma zerstört den String. -
@paul53 Kann man das irgendwie abfangen?
-
@paul53 @ticaki Ich habe das jetzt mal so versucht:
const axios = require("axios"); postJson("192.168.1.14:8087", "0_userdata.0.LogParser_Raspi4.HomeMatic.json", getState("logparser.0.filters.Homematic.json").val); // Das hier irgendwo unten, wo es nicht stört async function postJson(ip, dp, value) { let json = value; if (typeof value === 'string') { try { json = JSON.parse(value); } catch (error) { console.error('Fehler beim Parsen des JSON: ' + error); return; } } // JSON-Objekt in einen codierten JSON-String mit encodeURIComponent umwandeln const encodedJson = encodeURIComponent(JSON.stringify(json)); try { const { data } = await axios.post(`http://${ip}/setValueFromBody/${dp}`, encodedJson, { headers: { "Content-Type": 'application/x-www-form-urlencoded' // Änderung des Content-Type } }); console.log('Erfolgreich gesendet:', data); } catch (error) { console.warn('Ziel nicht erreichbar: ' + error); } }
Es kommt die Meldung: "Erfolgreich gesendet", aber es wird wieder nur bis zum ersten Hochkomma übertragen. Was kann ich noch machen?
[EDIT]
Jetzt wird das übertragen:%5B%7B%22date%22%3A%2212.08.2023%22%2C%22severity%22%3A%22%3Cspan%20class%3D'logWarn%20logSeverity'%3Ewarn%3C%2Fspan%3E%22%2C%22from%22%3A%22hm-rega.0%22%2C%22message%22%3A%22%5B2%20Eintr%C3%A4ge%5D%20Script%20%5C%22!%23%20system.fn%200.1%20!%23%20!%23%20Dieses%20Script%20gibt%20die%20FW-Versionsnummer%20und%20mehr%20systems%5C%22%20ignored%2C%20b%22%2C%22ts%22%3A1691799750581%7D%2C%7B%22date%22%3A%2212.08.2023%22%2C%22severity%22%3A%22%3Cspan%20class%3D'logWarn%20logSeverity'%3Ewarn%3C%2Fspan%3E%22%2C%22from%22%3A%22influxdb.0%22%2C%22message%22%3A%22Error%20on%20writePoint(%5C%22%7B%5C%22value%5C%22%3A12%2C%5C%22time%5C%22%3A%5C%222023-08-12T00%3A21%3A39.143Z%5C%22%2C%5C%22from%5C%22%3A%5C%22system.adapter.hm-rpc.1%5C%22%2C%22%2C%22ts%22%3A1691799724657%7D%2C%7B%22date%22%3A%2212.08.2023%22%2C%22severity%22%3A%22%3Cspan%20class%3D'logWarn%20logSeverity'%3Ewarn%3C%2Fspan%3E%22%2C%22from%22%3A%22influxdb.0%22%2C%22message%22%3A%22Error%20on%20writePoint(%5C%22%7B%5C%22value%5C%22%3A31%2C%5C%22time%5C%22%3A%5C%222023-08-12T00%3A21%3A28.764Z%5C%22%2C%5C%22from%5C%22%3A%5C%22system.adapter.hm-rpc.1%5C%22%2C%22%2C%22ts%22%3A1691799721275%7D%2C%7B%22date%22%3A%2212.08.2023%22%2C%22severity%22%3A%22%3Cspan%20class%3D'logWarn%20logSeverity'%3Ewarn%3C%2Fspan%3E%22%2C%22from%22%3A%22influxdb.0%22%2C%22message%22%3A%22Error%20on%20writePoint(%5C%22%7B%5C%22value%5C%22%3A33%2C%5C%22time%5C%22%3A%5C%222023-08-12T00%3A20%3A21.862Z%5C%22%2C%5C%22from%5C%22%3A%5C%22system.adapter.hm-rpc.1%5C%22%2C%22%2C%22ts%22%3A1691799721275%7D%2C%7B%22date%22%3A%2212.08.2023%22%2C%22severity%22%3A%22%3Cspan%20class%3D'logWarn%20logSeverity'%3Ewarn%3C%2Fspan%3E%22%2C%22from%22%3A%22influxdb.0%22%2C%22message%22%3A%22Error%20on%20writePoint(%5C%22%7B%5C%22value%5C%22%3A3.2%2C%5C%22time%5C%22%3A%5C%222023-08-12T00%3A21%3A28.763Z%5C%22%2C%5C%22from%5C%22%3A%5C%22system.adapter.hm-rpc.1%5C%22%22%2C%22ts%22%3A1691799721274%7D%2C%7B%22date%22%3A%2212.08.2023%22%2C%22severity%22%3A%22%3Cspan%20class%3D'logWarn%20logSeverity'%3Ewarn%3C%2Fspan%3E%22%2C%22from%22%3A%22influxdb.0%22%2C%22message%22%3A%22Error%20on%20writePoint(%5C%22%7B%5C%22value%5C%22%3A0.26%2C%5C%22time%5C%22%3A%5C%222023-08-12T00%3A21%3A28.523Z%5C%22%2C%5C%22from%5C%22%3A%5C%22system.adapter.hm-rpc.0%22%2C%22ts%22%3A1691799721265%7D%5D
Was ist das denn jetzt?
-
@jojo58 sagte: Kann man das irgendwie abfangen?
Wandle die HTML-Elemente in einfachen Text:
// HomeMatic let jsonHom = getState("logparser.0.filters.Homematic.json").val.replace(/<[^>]+>/g, '');
-
@paul53 In welcher Script Version soll ich die Zeile einbinden? Wenn ich das erste von @ticaki nehme, sieht es so aus:
// das hier muß einmal im Skript stehen const axios = require("axios") // hiermit sendest du die Daten: sollte selbst erklärend sein /* * ip: string "ip:port" * deinDatenpunkt: string "userdata_0.0.blabla" * deinJson: Dein Json :) */ postJson("192.168.1.14:8087", "0_userdata.0.LogParser_Raspi4.HomeMatic.json", getState("logparser.0.filters.Homematic.json").val) //Das hier irgendwo unten wo es nicht stört async function postJson(ip, dp, value) { // HomeMatic let jsonHom = getState("logparser.0.filters.Homematic.json").val.replace(/<[^>]+>/g, ''); try { const {data} = await axios.post('http://'+ip+'/setValueFromBody/'+dp, jsonHom, { headers: { "Content-Type": 'application/json' } } ) } catch(error) { console.warn('wled unten nicht erreichbar!' + error) } }
Das Script meldet keine Fehler, aber Daten werden auch nicht übertragen.
-
@jojo58 sagte: In welcher Script Version soll ich die Zeile einbinden?
In Deiner zuerst gezeigten Version bei allen JSON das .replace(/<[^>]+>/g, '') ergänzen.
-
@paul53 Ich habs zum testen für einen einzelnen DP, den WarnAndError genommen und wieder den Trigger Zeitplan alle 10 Sekunden.
var request = require ('request'); // WarnAndError let jsonWar = getState("logparser.0.filters.WarnAndError.json").val.replace(/<[^>]+>/g, ''); // let jsonWar = getState("logparser.0.filters.WarnAndError.json").val; // WarnAndError request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.WarnAndError.json?value=' +jsonWar);
Das Script startet ohne Fehler, aber es passiert nichts. Weder Fehler noch sonstige Meldungen. Und es wird nichts übertragen. Ich hatte den DP extra leer gemacht, und es kommt nichts an. Der Zeitstempel ändert sich auch nicht.
-
@jojo58 sagte: Der Zeitstempel ändert sich auch nicht.
Dann wird entweder nichts gesendet oder die Simple-API empfängt nichts.
Schau mal per log(jsonWar) das JSON an.
Ergänze request():// WarnAndError request('http://192.168.1.14:8087/set/0_userdata.0.LogParser_Raspi4.WarnAndError.json?value=' +jsonWar, function (error, response, result) { if (error) { log(error, 'warn'); } else { log(result); } });
Anmerkung: Zeile 1 ist nicht erforderlich, da der Javascript-Instanz bereits bekannt.
-
@paul53 Bitte entschuldige die späte Antwort. Wir haben unseren Enkel zu Besuch und der hatte Hunger.
Das Ergebnis der Ausgabe:18:20:34.023 info javascript.0 (27410) Start javascript script.js.API_Daten_senden.LP_jsonWarn_senden 18:20:34.053 info javascript.0 (27410) script.js.API_Daten_senden.LP_jsonWarn_senden: registered 0 subscriptions, 1 schedule, 0 messages, 0 logs and 0 file subscriptions 18:20:40.015 info javascript.0 (27410) script.js.API_Daten_senden.LP_jsonWarn_senden: 18:20:50.021 info javascript.0 (27410) script.js.API_Daten_senden.LP_jsonWarn_senden:
Ich habe den DP "logparser.0.filters.WarnAndError.json" mal kurz auf writeable gesetzt und wenn ich dann reingehe, zeigt der mir folgende Daten an:
Es sind also Daten vorhanden.Mache ich ein
log(getState("logparser.0.filters.Homematic.json").val)
bekomme ich als Ergebnis folgendes im Log:
Auch da gibt es also Daten.