NEWS
[Gelöst] Was tut die Funktion jsonataExpression
-
@roga sagte in Was tut die Funktion jsonataExpression:
kann mir das jemand erklären?
-
Die Originialdokumentation findest Du hier: https://docs.jsonata.org/overview
Das ist ein sehr leistungsfähige Bibliothek, die Dir in NodeRed(da wird es noch viel mehr eingesetzt), in Javascript oder Blockly verwendet. Gerade das Blockly kann überhaupt nicht gut mit Objekten umgehen. Deswegen habe ich schon oft versucht auch Puzzle Freunde mit dieser genialen Bibliothek vertraut zu machen.
In der Doku findest Du auch ein try Fenster (das Du auch teilen kannst). Da kannst Du links selbst Eingangsdaten erstellen - rechts oben gibst Du Deinen Code ein - und unten siehst Du das Ergebnis.
Wenn Du da Hilfe brauchst - dann melde Dich mal - um Dir zu zeigen, wie effizient diese Bibliothek ist - folgendes Beispiel:
Selbst wenn das folgende Array nicht bereist sortiert wäre:
[{"total":0.274,"energy":0.0742,"tax":0.1998,"startsAt":"2023-09-22T14:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2783,"energy":0.0778,"tax":0.2005,"startsAt":"2023-09-22T13:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2798,"energy":0.079,"tax":0.2008,"startsAt":"2023-09-22T15:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2877,"energy":0.0856,"tax":0.2021,"startsAt":"2023-09-22T12:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2895,"energy":0.0872,"tax":0.2023,"startsAt":"2023-09-22T01:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2905,"energy":0.088,"tax":0.2025,"startsAt":"2023-09-22T02:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2908,"energy":0.0883,"tax":0.2025,"startsAt":"2023-09-22T00:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2908,"energy":0.0882,"tax":0.2026,"startsAt":"2023-09-22T16:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2914,"energy":0.0888,"tax":0.2026,"startsAt":"2023-09-22T03:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.294,"energy":0.091,"tax":0.203,"startsAt":"2023-09-22T04:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.294,"energy":0.0909,"tax":0.2031,"startsAt":"2023-09-22T11:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.2948,"energy":0.0917,"tax":0.2031,"startsAt":"2023-09-22T05:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.3043,"energy":0.0996,"tax":0.2047,"startsAt":"2023-09-22T10:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.3084,"energy":0.1031,"tax":0.2053,"startsAt":"2023-09-22T23:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.3118,"energy":0.1059,"tax":0.2059,"startsAt":"2023-09-22T22:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.3131,"energy":0.107,"tax":0.2061,"startsAt":"2023-09-22T17:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.3198,"energy":0.1126,"tax":0.2072,"startsAt":"2023-09-22T06:00:00.000+02:00","currency":"EUR","level":"EXPENSIVE"},{"total":0.3221,"energy":0.1146,"tax":0.2075,"startsAt":"2023-09-22T21:00:00.000+02:00","currency":"EUR","level":"NORMAL"},{"total":0.3265,"energy":0.1183,"tax":0.2082,"startsAt":"2023-09-22T09:00:00.000+02:00","currency":"EUR","level":"EXPENSIVE"},{"total":0.3446,"energy":0.1334,"tax":0.2112,"startsAt":"2023-09-22T20:00:00.000+02:00","currency":"EUR","level":"EXPENSIVE"},{"total":0.3473,"energy":0.1358,"tax":0.2115,"startsAt":"2023-09-22T08:00:00.000+02:00","currency":"EUR","level":"EXPENSIVE"},{"total":0.3481,"energy":0.1364,"tax":0.2117,"startsAt":"2023-09-22T18:00:00.000+02:00","currency":"EUR","level":"EXPENSIVE"},{"total":0.35,"energy":0.138,"tax":0.212,"startsAt":"2023-09-22T07:00:00.000+02:00","currency":"EUR","level":"EXPENSIVE"},{"total":0.376,"energy":0.1599,"tax":0.2161,"startsAt":"2023-09-22T19:00:00.000+02:00","currency":"EUR","level":"EXPENSIVE"}]
bekommst Du mit JSONATA mit einem simplen Einzeiler (in Blockly und JavaScript müsstest Du mindestens 2 mal Schleifen durchlaufen):
$[total=$min($$.total)].startsAt
die Uhrzeit raus, an dem der günstigeste Preis existiert. Wie gesagt dieses Array könnte auch völlig unsortiert sein. Du müssest also keine Sortierroutinen schreiben und Blockly kann sowas schon gar nicht. Und so was kannst Du in dem try Fenster selbst ausprobieren.
Hier mal zum selbst ausprobieren: https://try.jsonata.org/qD4MSRGIg
-
Vielen Dank für eure Hilfe! Ich habe mir das wesenlich einfacher vorgestellt, als was die Doku darüber erzählt. Ich dachte, es wäre einfach nur eine "normale" Funktion, wie z.B. formatDate(), console.log(), JSON.stringify() etc. etc. aber das scheint hier nicht der Fall zu sein. Das es sich dabei um eine Bibliothek handelt, war mir nicht bewusst. Da ich kein Programmierer bin, ist mir das irgendwie zu kompliziert. Ich komme gerade so halbwegs mit dem Scripten voran, da wird's mir bei Jsonata definitiv zu kompliziert.
Trotzdem allen ein herzliches Dankeschön! Wenigstens weiss ich jetzt, dass ich es nicht so einfach einsetzen kann.
-
@roga Na Du kannst es auch ganz einfach einsetzen - Du musst halt nur sagen, was Du willst und dann schauen wir uns das an.Oder gerade zum Formatieren von Werten.
-
@roga
Ja ist kompliziert. Wenn du aber Json-Daten konvertieren willst ist es am Ende einfach als das ganze in Javascript zu schreiben und erst recht als Blockly. -
naja, eigenlich hat ja Blockly das Javascript quasi für mich geschrieben. Ich wollte halt jetzt nur verstehen, was genau da passiert.
Als Beispiel:
Ich frage meine SQL-DB nach dem Gesamtverbrauch in KWh des gestrigen Tages ab:
DPPath = 'javascript.0.Energieverbrauch.Täglich.'; Query = 'SELECT date(from_unixtime(ts/1000)) as Intervall, ' + ' round((max(val) - min(val)) / 1000, 2) as KWh, ' + ' max(val) as MaxZählerstand, ' + ' min(val) as MinZählerstand ' + 'FROM iobroker.ts_number where id=10 and ' + ' val is not null and ' + ' date(from_unixtime(ts/1000)) = date(now()) - interval 1 day ' + 'group by Intervall;'; Response = JSON.parse(JSON.stringify(await sendToAsync('sql.0', 'query', Query))); SQLResult = Response.result;
und erhalten als Rückgabewert mit console.log(JSON.stringify(SQLResult)) folgede Daten im JSON-Format:
[{"Intervall":"2023-10-13T22:00:00.000Z","KWh":14.26,"MaxZählerstand":3295036.8,"MinZählerstand":3280780.5}]
Nun möchte ich daraus die "KWh" und das "Intervall" (entspricht dem Datum des gestrigen Tages) in die Variable "ConsumedPower" bzw. "Datum" extrahieren.
for (Item in SQLResult) { ConsumedPower = parseFloat(JSON.stringify(SQLResult[Item].KWh)); Datum = formatDate(getDateObject((await jsonataExpression(SQLResult[Item],'Intervall'))), "YYYY.MM.DD"); };
und an dieser Stelle habe ich eben das JsonataExpression() gesehen. Ich habe mir gedacht, wieso braucht's diese Funktion, kann das nicht so ähnlich extrahiert werden, wie "ConsumedPower"? also so:
Datum = formatDate(getDateObject(JSON.stringify(SQLResult[Item].Intervall)), 'YYYY.MM.DD');
Doch das gab mir kein Datum mehr zurück (undefined oder so). Auch ist mir aufgefallen, dass im Rückgabewert für das Datum das Format 'ISO-8601' ausgegeben wurde und das eigentliche Tagesdatum nicht gestern, sondern von vorgestern enthält:
"Intervall":"2023-10-13T22:00:00.000Z"
Wie gesagt, wenn ich das Datum mit jsonataExpression() extrahiere, erhalte ich das richtige Datum, so wie ich es gerne hätte:
Datum = formatDate(getDateObject((await jsonataExpression(SQLResult[Item],'Intervall'))), "YYYY.MM.DD"); console.log('Datum=' + Datum);
Rückabe:
Datum=2023.10.14
Und deshalb wollte ich wissen, was macht diese Funktion jsonataExpression() genau, bzw. wie wird aus diesem ISO-8601 Datumsformat (dessen Tag ja nicht gestern, sonder vorgestern ist) dass korrekte Datum von gestern??????
Ich hoffe, ich hab's irgendwie halbwegs verständlich erklärt, sonst einfach fragen.
schönes Wochenende
-
@roga sagte in [Gelöst] Was tut die Funktion jsonataExpression:
Datum = formatDate(getDateObject(JSON.stringify(SQLResult[Item].Intervall)), 'YYYY.MM.DD');
Da das Datum im JSON Format vorliegt reicht auch:
Datum = formatDate(new Date(SQLResult[Item].Intervall), 'YYYY.MM.DD');
-
@ticaki sagte in [Gelöst] Was tut die Funktion jsonataExpression:
Da das Datum im JSON Format vorliegt reicht auch:
Datum = formatDate(new Date(SQLResult[Item].Intervall), 'YYYY.MM.DD');LOL
Jetzt weiss ich zwar immer noch nicht, wie jsonataExpression() die Konvertierung gemacht hat, aber diese Lösung verstehe ich jetzt und sie funktioniert tatsächlich!!!!!
Vielen lieben Dank!
-
@roga Also nur um es grundsätzlich mal klar zustellen, ich habe jetzt mal zur Sicherheit in ein Objekt gewandelt.
Mit $ greifst Du auf das ganze Objekt zu, dass Du sonst via Attribut von .. bekommst.
Das ganze hat mit JSONATA also nichts zu tun.
Diese Zeit ist
"Intervall":"2023-10-13T22:00:00.000Z"
ist auch korrekt - da in allen Datenbanken die UTC gespeichert wird. Sprich diese Zeit entspricht 0:00 Uhr am 14.10.2023 - da UTC ja 2 Std. nachhängt.
Die Konvertierung liegt ggf. daran, dass daraus die lokale Zeit gemacht wurde.
-
@mickym sagte
"Intervall":"2023-10-13T22:00:00.000Z"
ist auch korrekt - da in allen Datenbanken die UTC gespeichert wird. Sprich diese Zeit entspricht 0:00 Ihr am 14.10.2023 - da UTC ja 2 Std. nachhängt.
Die Konvertierung liegt ggf. daran, dass daraus die lokale Zeit gemacht wurde.
Ach so! Jetzt verstehe ich das auch, ja macht durchaus Sinn und so gesehen ist es dann tatsächlich der 14.10.2023.
Wieder etwas wichtiges dazugelernt, vielen Dank!