NEWS
SOLVED Get JSON from exec in Function - Solved!
-
Hallo zusammen,
ich verzweifle seit einiger Zeit an - wahrscheinlich - einer Kleinigkeit.Ich möchte mit JavaScript die Parameter meiner UniFi Kamera auslesen. Das funktioniert soweit auch ....
Ich habe folgende Funktion geschrieben:// grundlegende Parameter wie Server, AppKey und KameraIDs sind in einem Global-Skript ausgelagert. function myVideoGetCamera(Name) { var fReturn; var fCameraID; // KamaraID anhand des Namens ermitteln switch(Name) { case "Flur": fCameraID = myVideoCamFlur; break; case "Garten": fCameraID = myVideoCamGarten; break; default: console.log("Kamera nicht gefunden!"); return "err"; } // Abfrage zusammensetzen var fCommand = "curl -i --url 'https://" + myVideoServer + "/api/2.0/camera/" + fCameraID + "/?apiKey=" + myVideoAPIKey + "' --header 'Content-Type: application/json' --header 'Accept: application/json' --insecure -X GET"; // Abfrage ausführen fReturn = exec(fCommand, function(err, response, errmsg) { if(err) { console.log("Fehler in der Abfrage: " + errmsg); return "err"; } var fJSON = JSON.parse(response.substr(response.search("{"),response.length-response.search("{"))); // PROBLEM --> An dieser Stelle kann ich mit einem Console.log(fJSON.data[0].recordingSettings.motionRecordEnabled) z. B. den Status der Aufnahme bei Bewegungserkennung auslesen. Ich erhalte also ein korrektes JSON. Dieses möchte ich nun zurückgeben an fReturn. Das funktioniert schon nicht! return fSJON; }); // PROBLEM --> Hier würde ich gerne das JSON Objekt aus der Funktion zurückgeben, aber ich bekomme es aus der exec-Routine nicht heraus. return fReturn; }
Ich hoffe irgendwer kann mir helfen.
Als Workarround könnte ich neben dem Namen noch den gewünschten Parameter mitgeben. Allerdings müsste das dann alles hinterlegt werden. Als Switch (Parameter) und dann jeden Parameterin einen JSON-Pfad überführen und das dann in einen State wegschreiben und anschließend wieder auslesen. Aber das kann ja nicht die Lösung sein ....Vielen Dank für euer Feedback!
Gruß Info![alt text](![image url](image url)) -
Hi @paul53
danke Dir für das Feedback. Dann kann ich das nicht so bauen wie ich es mir vorgestellt habe.
Das Substr kürzt mir den eigentlichen Response des curl ein, da hier auch noch der Header mit zurückgegeben wird. Daher schneide ich den Teil bis der ersten { - also dem Begin des JSONs - ab.Ich habe es in der Zwischenzeit als Workarround so umgebaut, das ich mit einem 60s Trigger die Kamera auslese und dann mit dem Callback in einen State abspeichere. Wenn ich die Werte brauche, kann ich diese als JSON aus dem State lesen und den gewünschten Parameter extrahieren...
/* ============================================================================= > Ließt alle Parameter einer Kamera aus und gibt sie als JSON zurück ==============================================================================*/ on({id: 'VIS.82.Ticker_60s', change: "ne"}, function (f) { console.log("Read UniFi Video Cam's"); // Kamera Flur auslesen var fCameraID = myVideoCamFlur; var fCommand = "curl -i --url 'https://" + myVideoServer + "/api/2.0/camera/" + fCameraID + "/?apiKey=" + myVideoAPIKey + "' --header 'Content-Type: application/json' --header 'Accept: application/json' --insecure -X GET"; exec(fCommand, function(err, response, errmsg) { if(err) { console.log("Fehler in der Abfrage: " + errmsg); } else { setState('VIS.82.UniFi-Video.Flur.ParameterSet', response.substr(response.search("{"),response.length-response.search("{"))); } }); // Kamera Garten auslesen fCameraID = myVideoCamGarten; fCommand = "curl -i --url 'https://" + myVideoServer + "/api/2.0/camera/" + fCameraID + "/?apiKey=" + myVideoAPIKey + "' --header 'Content-Type: application/json' --header 'Accept: application/json' --insecure -X GET"; exec(fCommand, function(err, response, errmsg) { if(err) { console.log("Fehler in der Abfrage: " + errmsg); } else { setState('VIS.82.UniFi-Video.Garten.ParameterSet', response.substr(response.search("{"),response.length-response.search("{"))); } }); });
Auslesen kann ich dann zum Beispiel ob die Kamera gerade mit Bewegungserkennung aufnimmt mit:
JSON.parse(getState('VIS.82.UniFi-Video.Flur.ParameterSet').val).data[0].recordingSettings.motionRecordEnabled;
-
@Info
Aus der Callback-Funktion kann nichts zurück gegeben werden, weil der Rückgabewert ausgewertet würde, bevor die Callback-Funktion ausgeführt wird. Die Auswertung muss in einer Funktion erfolgen, die aus der Callback-Funktion aufgerufen wird. Wozu soll .substr() gut sein ?// Abfrage ausführen exec(fCommand, function(err, response, errmsg) { if(err) { console.log("Fehler in der Abfrage: " + errmsg); return; } var obj = JSON.parse(response); // JSON --> Objekt auswertung(obj); // In dieser Funktion wird das Objekt ausgewertet }); }
-
Hi @paul53
danke Dir für das Feedback. Dann kann ich das nicht so bauen wie ich es mir vorgestellt habe.
Das Substr kürzt mir den eigentlichen Response des curl ein, da hier auch noch der Header mit zurückgegeben wird. Daher schneide ich den Teil bis der ersten { - also dem Begin des JSONs - ab.Ich habe es in der Zwischenzeit als Workarround so umgebaut, das ich mit einem 60s Trigger die Kamera auslese und dann mit dem Callback in einen State abspeichere. Wenn ich die Werte brauche, kann ich diese als JSON aus dem State lesen und den gewünschten Parameter extrahieren...
/* ============================================================================= > Ließt alle Parameter einer Kamera aus und gibt sie als JSON zurück ==============================================================================*/ on({id: 'VIS.82.Ticker_60s', change: "ne"}, function (f) { console.log("Read UniFi Video Cam's"); // Kamera Flur auslesen var fCameraID = myVideoCamFlur; var fCommand = "curl -i --url 'https://" + myVideoServer + "/api/2.0/camera/" + fCameraID + "/?apiKey=" + myVideoAPIKey + "' --header 'Content-Type: application/json' --header 'Accept: application/json' --insecure -X GET"; exec(fCommand, function(err, response, errmsg) { if(err) { console.log("Fehler in der Abfrage: " + errmsg); } else { setState('VIS.82.UniFi-Video.Flur.ParameterSet', response.substr(response.search("{"),response.length-response.search("{"))); } }); // Kamera Garten auslesen fCameraID = myVideoCamGarten; fCommand = "curl -i --url 'https://" + myVideoServer + "/api/2.0/camera/" + fCameraID + "/?apiKey=" + myVideoAPIKey + "' --header 'Content-Type: application/json' --header 'Accept: application/json' --insecure -X GET"; exec(fCommand, function(err, response, errmsg) { if(err) { console.log("Fehler in der Abfrage: " + errmsg); } else { setState('VIS.82.UniFi-Video.Garten.ParameterSet', response.substr(response.search("{"),response.length-response.search("{"))); } }); });
Auslesen kann ich dann zum Beispiel ob die Kamera gerade mit Bewegungserkennung aufnimmt mit:
JSON.parse(getState('VIS.82.UniFi-Video.Flur.ParameterSet').val).data[0].recordingSettings.motionRecordEnabled;