INSTAR Deutschland GmbH

Node-RED und SQL Logging



In diesem Tutorial möchten wir Node-RED verwenden, um Informationen von unserer INSTAR Full HD-Kamera abzurufen, deren Wert im Node-RED-Dashboard anzuzeigen und in eine SQL-Datenbank einzugeben.

Im ersten Beispiel werden wir den aktuelle Helligkeitswert auslesen, der vom internen Lichtsensor erfasst wurde. Mit diesem Wert können Sie erkennen, wann Ihre Kamera den Infrarot-Cutfilter (IRCut) umschaltet. Dies ist eine nützliche Information, wenn Sie die Kamerakonfiguration basierend auf dem Tag- und Nachtmodus ändern möchten (z. B. die Empfindlichkeit der Bewegungserkennung ändern oder eine andere Position anfahren möchten).

Der genaue Wert, wann der Wechsel erfolgt, hängt von Ihrem Kameramodell ab und muss zuerst bestimmt werden:


alasql in node-red


Der gleiche Mechanismus kann zum Erstellen von Sicherungen für die Kamerakonfiguration oder Systemprotokollen verwendet werden. Als Beispiel verwenden wir Node-RED, um das Systemlogbuch der Kamera zu sichern.

Scrollen Sie nach unten auf dieser Seite, um die vollständigen Flows zu finden, und importieren Sie sie in Ihre Node-RED-Installation, um den Tutorial folgen zu können. Stellen Sie jedoch sicher, dass Sie zuerst node-red-contrib-alasql wie unten beschrieben installieren.

Arbeiten mit AlaSQL in Node-RED

AlaSQL ist eine in Javascript geschriebene Open-Source-SQL-Datenbank mit einem starken Fokus auf Abfragegeschwindigkeit und Datenquellenflexibilität sowohl für relationale als auch für schemenlose Daten. Die Datenbank kann Node-RED hinzugefügt werden, indem Sie node-red-contrib-alasql installieren:


alasql in node-red

alasql in node-red


Das Paket bietet uns einen Node, mit dem wir SQL-Abfragen wie CREATE, SELECT, INSERT und DROP zum Erstellen von Tabellen verwenden und Daten hinzufügen können. Es gibt auch einen zusätzlich Out-File- und In-File-Node, mit dem wir unsere Tabellen in einer Datei sichern und aus dieser Sicherung unsere Datenbank neu erstellen können.

Um eine Tabelle für unsere Daten zu erstellen, können wir einen AlaSQL-Knoten mit dem folgenden Befehl verwenden:

CREATE TABLE lightSensor (camera string, brightness number)

alasql in node-red


Klicken Sie auf den Inject-Knoten neben dem CREATE-Knoten, um die Tabelle zu erstellen, falls diese noch nicht vorhanden ist (der Injektionsknoten ist konfiguriert, dass er 5 Sekunden nach dem Start von Node-RED die Tabelle automatisch erstellt).

Schließen Sie unsere Kamera an Node-RED an

Als Beispiel können wir eine Verbindung zur HTTP-API der INSTAR IP Full HD-Kamera herstellen, indem wir einen CGI Befehle wie folgt verwenden (Vergessen Sie nicht, die IP-Adresse und Ihr Kamera-Login anzupassen!):

http://user:password@192.168.2.115/param.cgi?cmd=getsaradcstate

alasql in node-red


Der Befehl ruft die aktuelle Helligkeit auf, die vom internen Lichtsensor der Kamera aufgezeichnet wurde. Wir müssen etwas RegEX verwenden var brightness = msg.payload.replace(/^\D+|\D+$/g, ""); um die Antwort der Kamera zu bereinigen:


alasql in node-red


Die Regular-Expression übernimmt die Kameraantwort var saradc_state="208";, extrahieren den Wert (in diesem Fall 208) und setzt diesen Wert auf msg.payload. Was dann direkt in einem node-red-dashboard Node verwendet werden kann:


alasql in node-red

alasql in node-red


Schreiben der Daten in die SQL-Datenbank

Für den AlaSQL-Knoten können wir einen Einfügebefehl verwenden, um die Messung zu unserer Datenbanktabelle hinzuzufügen (CREATE TABLE lightSensor (camera string, brightness number)):

INSERT INTO lightSensor VALUES ('192.168.2.115',?)

alasql in node-red


Der Inject-Knoten ist so konfiguriert, dass er einmal pro Minute ausgelöst wird. Sie können überprüfen, ob bereits Werte in der SQL-Tabelle gespeichert sind, indem Sie auf den Inject-Knoten neben dem SELECT Knoten klicken - SELECT * FROM lightSensor. Öffnen Sie das Debug-Panel in Node-RED, um die Ausgabe zu sehen - es sollte jede Zeile in der lightSensor -Tabelle auflisten.

Sichern Sie die Tabelle in eine Datei

Sobald wir alle benötigten Daten gesammelt haben, können wir mithilfe eines AlaSQL-Knotens alle Daten von einer Kamera selektieren SELECT * FROM lightSensor WHERE camera IN ('192.168.2.115') und einen AlaSQL Out-File-Knoten verwenden, um diese Informationen in eine Datei zu schreiben (xlsx, csv, json usw.). (Stellen Sie sicher, dass der Ordner /home/pi/.node-red/sql/ vorhanden ist und NodeRED über die erforderlichen Schreibrechte verfügt.)


alasql in node-red


Sichern Sie das Systemprotokoll Ihrer Kamera

Um das Systemprotokoll Ihrer Kamera abzurufen, können Sie den folgenden Pfad verwenden (ändern Sie bitte das Login und die IP-Adresse entsprechend Ihrer Kameraeinstellung):

http://admin:instar@192.168.2.116/tmpfs/syslog.txt

alasql in node-red


Sobald wir diesen Befehl senden, antwortet unsere Kamera mit einer einfachen Textdatei, in der alle aufgezeichneten Kameraereignisse aufgelistet sind. Um diese Informationen in eine Datenbank schreiben zu können, müssen wir sie zunächst mit regulären Ausdrücken bereinigen:


alasql in node-red


Jetzt können wir einen AlaSQL-Knoten verwenden, um die Informationen in unsere Datenbanktabelle einzufügen - z.B. sysLog116:

INSERT INTO sysLog116 VALUES (CURRENT_TIMESTAMP,?);

alasql in node-red


Der folgende Knoten in der Sequenz löscht die Protokolldatei auf Ihrer Kamera, um doppelte Ereigniseinträge in unserer Datenbank zu vermeiden:

http://admin:instar@192.168.2.116/param.cgi?cmd=cleanlog&-name=sys

Wie zuvor müssen wir diese Tabelle zuerst durch Auslösen des Knotens CREATE erstellen, wenn die Tabelle noch nicht vorhanden ist (dies ist wiederum automatisiert und sollte 5s nach dem Start von Node-RED automatisch geschehen):

CREATE TABLE sysLog116 (ts TIMESTAMP VARCHAR(80), event string);

alasql in node-red


Flow Export

So importieren Sie einen Flow

Öffnen Sie das Hauptmenü und wählen Sie Importieren -> Zwischenablage. Daraufhin wird ein Dialogfeld geöffnet, in dem Sie den Flow importieren können. Kopieren Sie den JSON-Flow unten in die Zwischenablage Ihres Systems. Klicken Sie anschließend auf die Schaltfläche Importieren.

Light Sensor Readout

alasql in node-red

[{"id":"54e58600.85c09c","type":"alasql","z":"4e79509.5da71b","name":"SELECT","query":"SELECT * FROM lightSensor","x":260,"y":220,"wires":[["f74b0716.9b1e78"]]},{"id":"f74b0716.9b1e78","type":"debug","z":"4e79509.5da71b","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":450,"y":129,"wires":[]},{"id":"c7d0d4c9.343eb8","type":"inject","z":"4e79509.5da71b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":123,"y":220,"wires":[["54e58600.85c09c"]]},{"id":"64f88aa9.618984","type":"alasql","z":"4e79509.5da71b","name":"CREATE","query":"CREATE TABLE lightSensor (camera string, brightness number)","x":280,"y":100,"wires":[["f74b0716.9b1e78"]]},{"id":"3f95a33a.3bc3fc","type":"inject","z":"4e79509.5da71b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"5","x":130,"y":100,"wires":[["64f88aa9.618984"]]},{"id":"88a397a8.148378","type":"alasql","z":"4e79509.5da71b","name":"INSERT","query":"INSERT INTO lightSensor VALUES ('192.168.2.115',61),('192.168.2.116',66),('192.168.2.117',67),('192.168.2.118',2),('192.168.2.15',59),('80.152.227.12',2)","x":260,"y":160,"wires":[["f74b0716.9b1e78"]]},{"id":"c0deb77.6afab48","type":"inject","z":"4e79509.5da71b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":123,"y":160,"wires":[["88a397a8.148378"]]},{"id":"20947549.54031a","type":"alasql","z":"4e79509.5da71b","name":"DROP","query":"DROP TABLE lightSensor","x":260,"y":40,"wires":[["f74b0716.9b1e78"]]},{"id":"d73e17f7.7800f8","type":"inject","z":"4e79509.5da71b","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":123,"y":40,"wires":[["20947549.54031a"]]},{"id":"2f0fb36e.ef2d1c","type":"http request","z":"4e79509.5da71b","name":"192.168.2.115","method":"GET","ret":"txt","paytoqs":false,"url":"http://admin:instar@192.168.2.115/param.cgi?cmd=getsaradcstate","tls":"","proxy":"","authType":"basic","x":320,"y":340,"wires":[["8e66245b.715848"]]},{"id":"8e66245b.715848","type":"function","z":"4e79509.5da71b","name":"brightness","func":"msg.topic = \"brightness\";\n\nvar brightness = msg.payload.replace(/^\\D+|\\D+$/g, \"\");\n\nmsg.payload = brightness;\n\nreturn msg;","outputs":1,"noerr":0,"x":488,"y":340,"wires":[["eed46a9f.8c8608","79b12832.8cfbf8","72dc17cb.ff6178"]]},{"id":"eed46a9f.8c8608","type":"ui_chart","z":"4e79509.5da71b","name":"Brightness","group":"58c9cffc.1484f","order":1,"width":"0","height":"0","label":"Brightness (IN-9008)","chartType":"line","legend":"false","xformat":"HH:mm:ss","interpolate":"bezier","nodata":"","dot":false,"ymin":"","ymax":"","removeOlder":1,"removeOlderPoints":"","removeOlderUnit":"3600","cutout":0,"useOneColor":false,"colors":["#1f77b4","#aec7e8","#ff7f0e","#2ca02c","#98df8a","#d62728","#ff9896","#9467bd","#c5b0d5"],"useOldStyle":false,"outputs":1,"x":653,"y":339,"wires":[[]]},{"id":"79b12832.8cfbf8","type":"ui_text","z":"4e79509.5da71b","group":"58c9cffc.1484f","order":3,"width":0,"height":0,"name":"","label":"Current Brightness","format":"{{msg.payload}}","layout":"row-spread","x":672,"y":379,"wires":[]},{"id":"72dc17cb.ff6178","type":"alasql","z":"4e79509.5da71b","name":"lightSensor","query":"INSERT INTO lightSensor VALUES ('192.168.2.115',?)","x":630,"y":300,"wires":[[]]},{"id":"1a556423.56677c","type":"inject","z":"4e79509.5da71b","name":"1min Trigger","topic":"","payload":"","payloadType":"date","repeat":"60","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":340,"wires":[["2f0fb36e.ef2d1c"]]},{"id":"5bfab4c7.fead1c","type":"inject","z":"4e79509.5da71b","name":"20 Min Trigger","topic":"","payload":"","payloadType":"date","repeat":"1200","crontab":"","once":false,"onceDelay":0.1,"x":140,"y":480,"wires":[["6c59f580.919d0c"]]},{"id":"6c59f580.919d0c","type":"alasql","z":"4e79509.5da71b","name":"SELECT 115","query":"SELECT * FROM lightSensor WHERE camera IN ('192.168.2.115')","x":310,"y":480,"wires":[["2d6e1036.6d267"]]},{"id":"2d6e1036.6d267","type":"alafile out","z":"4e79509.5da71b","name":"xlsx","filename":"/home/pi/.node-red/sql/lightSensor_115","format":"xlsx","columns":"*","headers":true,"x":450,"y":480,"wires":[]},{"id":"58c9cffc.1484f","type":"ui_group","z":"","name":"192.168.2.115","tab":"32dce8be.80f688","disp":true,"width":"6","collapse":false},{"id":"32dce8be.80f688","type":"ui_tab","z":"","name":"Brightness","icon":"fa-sun-o","order":11,"disabled":false,"hidden":false}]

System Log Backup

alasql in node-red

[{"id":"98abb348.a5e48","type":"inject","z":"e3ee2ba4.3b3d68","name":"24hrs Trigger","topic":"","payload":"","payloadType":"date","repeat":"86400","crontab":"","once":false,"onceDelay":0.1,"x":120,"y":100,"wires":[["3e24cc90.b66634"]]},{"id":"3e24cc90.b66634","type":"http request","z":"e3ee2ba4.3b3d68","name":"Get Log 116","method":"GET","ret":"txt","paytoqs":false,"url":"http://admin:instar@192.168.2.116/tmpfs/syslog.txt","tls":"","proxy":"","authType":"basic","x":220,"y":53,"wires":[["eb0870ff.5a5e1"]]},{"id":"ccf12822.059a18","type":"inject","z":"e3ee2ba4.3b3d68","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":380,"wires":[["bd6d09c3.782788"]]},{"id":"40908c9f.0b1474","type":"inject","z":"e3ee2ba4.3b3d68","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":true,"onceDelay":"5","x":110,"y":205,"wires":[["efc4323e.4c5bc"]]},{"id":"73c283ff.d3003c","type":"inject","z":"e3ee2ba4.3b3d68","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":265,"wires":[["bded183e.8941a8"]]},{"id":"aca8074.2662bf8","type":"inject","z":"e3ee2ba4.3b3d68","name":"","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":100,"y":325,"wires":[["43e99a76.7f6154"]]},{"id":"43e99a76.7f6154","type":"alasql","z":"e3ee2ba4.3b3d68","name":"SELECT","query":"SELECT * FROM sysLog116","x":237,"y":325,"wires":[["8d1cd7bf.de6d98"]]},{"id":"b333dff4.6e8f","type":"alasql","z":"e3ee2ba4.3b3d68","name":"INSERT","query":"INSERT INTO sysLog116 VALUES (CURRENT_TIMESTAMP,?);","x":360,"y":265,"wires":[[]]},{"id":"efc4323e.4c5bc","type":"alasql","z":"e3ee2ba4.3b3d68","name":"CREATE","query":"CREATE TABLE sysLog116 (ts TIMESTAMP VARCHAR(80), event string);","x":263,"y":205,"wires":[[]]},{"id":"bd6d09c3.782788","type":"alasql","z":"e3ee2ba4.3b3d68","name":"DROP","query":"DROP TABLE sysLog116","x":237,"y":380,"wires":[[]]},{"id":"8d1cd7bf.de6d98","type":"debug","z":"e3ee2ba4.3b3d68","name":"","active":true,"tosidebar":true,"console":false,"tostatus":false,"complete":"false","x":390,"y":325,"wires":[]},{"id":"3f7d0a1e.da1be6","type":"inject","z":"e3ee2ba4.3b3d68","name":"20 Min Trigger","topic":"","payload":"","payloadType":"date","repeat":"","crontab":"","once":false,"onceDelay":0.1,"x":110,"y":500,"wires":[["317d8b07.06a1a4"]]},{"id":"317d8b07.06a1a4","type":"alasql","z":"e3ee2ba4.3b3d68","name":"SELECT 116","query":"SELECT * FROM sysLog116;","x":278,"y":500,"wires":[["c31a719a.72d4a"]]},{"id":"c31a719a.72d4a","type":"alafile out","z":"e3ee2ba4.3b3d68","name":"json","filename":"/home/pi/.node-red/sql/syslog_116","format":"json","columns":"*","headers":true,"x":418,"y":500,"wires":[]},{"id":"eb0870ff.5a5e1","type":"function","z":"e3ee2ba4.3b3d68","name":"syslog","func":"msg.topic = \"syslog\";\n\nstr = msg.payload.replace(/(\\r\\n|\\n|\\r)/gm,\" \").replace(/\\[/g, '').replace(/\\]/g, \"\").replace(/\\./g, \";\");\n\nvar syslog = str.split(/;\\s/);\n\nmsg.payload = syslog;\n\nreturn msg;","outputs":1,"noerr":0,"x":318,"y":100,"wires":[["7e28ffaa.12763"]]},{"id":"7e28ffaa.12763","type":"alasql","z":"e3ee2ba4.3b3d68","name":"sysLog116","query":"INSERT INTO sysLog116 VALUES (CURRENT_TIMESTAMP,?);","x":417,"y":54,"wires":[["ac0d4d61.2265a"]]},{"id":"bded183e.8941a8","type":"function","z":"e3ee2ba4.3b3d68","name":"","func":"msg.payload = [\"2019_06_17 09:08:48 ipc_server start\", \"2019_06_17 09:09:00 ircut: display switch(color -> blackwhite)\", \"2019_06_17 09:09:02 ircut: display switch(blackwhite -> color)\", \"2019_06_17 09:09:02 user=admin login for live stream\", \"2019_06_17 09:09:10 user=%61%64%6D%69%6E login for mjpeg stream\", \"2019_06_17 09:15:50 motion detection(area=1) alarm\", \"2019_06_17 09:26:52 motion detection(area=1) alarm\", \"2019_06_17 09:31:25 motion detection(area=1) alarm\", \"2019_06_17 09:31:51 motion detection(area=1) alarm\", \"2019_06_17 09:32:12 motion detection(area=1) alarm\", \"2019_06_17 09:33:29 motion detection(area=1) alarm\", \"2019_06_17 09:43:52 motion detection(area=1) alarm\", \"2019_06_17 09:45:43 user=%61%64%6D%69%6E logout from mjpeg stream\", \"2019_06_17 10:29:59 motion detection(area=1) alarm\", \"2019_06_17 10:30:01 motion detection(area=1) alarm\", \"2019_06_17 10:30:11 motion detection(area=1) alarm\", \"2019_06_17 10:30:13 motion detection(area=2) alarm\", \"2019_06_17 10:30:20 motion detection(are\"]\nreturn msg;","outputs":1,"noerr":0,"x":230,"y":265,"wires":[["b333dff4.6e8f"]]},{"id":"ac0d4d61.2265a","type":"http request","z":"e3ee2ba4.3b3d68","name":"Delete Log","method":"GET","ret":"txt","paytoqs":false,"url":"http://admin:instar@192.168.2.116/param.cgi?cmd=cleanlog&-name=sys","tls":"","proxy":"","authType":"basic","x":507,"y":100,"wires":[[]]}]