NEWS
[Frage]Skript zur Steuerung ONVIF Kameras
-
Hallo,
hat schon jemand von Euch ein Skript realisiert, das ONVIF-kompatible Kameras (PTZ-)steuern kann? Es gibt schon was
Gruß
Pix
-
Servus,
würde mich auch sehr interessieren.
Habe nun eine Preisgünstige Kamera hier, die den Offenen Standard unterstützt. Wenn das nun auch noch ioBroker könnte, wäre das ne coole Sache.
-
…ja würde auch mir "rein passen"! Hab gerade zwei Foscam Kameras in Betrieb genommen und nun gilt es diese natürlich zu "smarthomifizieren"
-
> …ja würde auch mir "rein passen"! Hab gerade zwei Foscam Kameras in Betrieb genommen und nun gilt es diese natürlich zu "smarthomifizieren" ;)
Gerade bei den Foscams ist das steuern via VIS relative einfach über die CGI-Befehle möglich. Habe ich bei meinem PTZ Kameras so gemacht und funktioniert sehr gut.Such mal in Netz nach CGI Foscam, da sollte es Infos zu geben (Befehlsübersicht).
-
> Such mal in Netz nach CGI Foscam, da sollte es Infos zu geben (Befehlsübersicht).
`…ja danke, die hab ich schon mal runter geladen. Erste Ernüchterung...ich kann nicht manuell, also via CGI eine Aufnahme starten, aber es wir sich schon ein workaround finden
Liebe Grüße
tom
-
Hallo
Ich wollte mal fragen ob es jemand irgendwie geschafft onvif cameras in Iobroker zu integrieren.
Ich könnte mir vorstellen das als Script an zulegen , und dann im Szenen Adapter zu verarbeiten.
Datenpunkte könnten zB. sein:
PTZ Rechts
PTZ Links
Zoom
PTZ Hoch
PTZ Runter
PTZ Positionen
Bewegung erkannt –---> MQTT
Ideen hab ich ,aber Ich kann sie nicht umsetzen.
Vielleicht hat ja der Fuchs eine Idee ?
Danke und Grüsse von der Spree
-
Hallo,
nach langem Tüfteln habe ich es diesen Sommer geschafft, meine ONVIF Kamera einzubinden.
Es wird ein Node-Modul benötigt, dass im Javascript Adapter eingestellt werden muss (https://www.npmjs.com/package/node-onvif von futomi (https://github.com/futomi/node-onvif/tree/master/sample))
/* Kinderzimmer Kamera 1 ONVIF Steuerung meiner einzigen ONVIF Kamera via Javascript https://github.com/futomi/node-onvif/tree/master/sample hostname: "192.168.178.XXX", username: "username", password: "passwort" Presets direkt in Kamera-Webserver (sihe hostname) speichern. Todo: Presets speichern und dabei Snapshot für Preview in vis.0 speichern Presets löschen und dabei neutrales Vorschaubild in vis.0 erstellen Wie AutoPan oder Pattern oder Tour aufrufen? 23.07.2017 Presets zugefügt 14.08.2017 Test beendet, umbeannt */ const fC = false; const logging = false; const dest_path = '/Users/pix/Documents/iobroker/iobroker-data/webcam/'; // OS X Pfad const pfad = 'javascript.' + instance + '.VIS.Kamera.1.PTZ.'; const idSpeed = pfad + 'Geschwindigkeit'; const idStoppzeit = pfad + 'Stoppzeit'; const idStopp = pfad + 'Stopp'; const idRechts = pfad + 'rechts'; const idLinks = pfad + 'links'; const idHoch = pfad + 'hoch'; const idRunter = pfad + 'runter'; const idZoomIn = pfad + 'ZoomIn'; const idZoomOut = pfad + 'ZoomOut'; const idGotoPreset = pfad + 'gotoPreset'; const onvif = require('node-onvif'); const fs = require('fs'); createState(idSpeed, 1, fC, { def: 1, min: 0, max: 1, name: 'Kamera 1 PTZ Geschwindkeit bei Bewegung', desc: 'Geschwindigkeit von 0-1 bei der Bewegung', type: 'number' }); createState(idStoppzeit, 1, fC, { def: 0, min: 0, name: 'Kamera 1 PTZ Stoppzeit', desc: 'Dauer in Sekunden bis zum Stopp der Bewegung', type: 'number', unit: 's' }); createState(idStopp, false, fC, { def: false, name: 'Kamera 1 PTZ Stopp', desc: 'Sofortiger Stopp der Bewegung', type: 'boolean', role: 'switch' }); createState(idRechts, false, fC, { def: false, name: 'Kamera 1 PTZ rechts', desc: 'Bewegung nach rechts', type: 'boolean', role: 'switch' }); createState(idLinks, false, fC, { def: false, name: 'Kamera 1 PTZ links', desc: 'Bewegung nach links', type: 'boolean', role: 'switch' }); createState(idHoch, false, fC, { def: false, name: 'Kamera 1 PTZ oben', desc: 'Bewegung nach oben', type: 'boolean', role: 'switch' }); createState(idRunter, false, fC, { def: false, name: 'Kamera 1 PTZ unten', desc: 'Bewegung nach unten', type: 'boolean', role: 'switch' }); createState(idZoomIn, false, fC, { def: false, name: 'Kamera 1 PTZ Zoom in', desc: 'Bild vergößern', type: 'boolean', role: 'switch' }); createState(idZoomOut, false, fC, { def: false, name: 'Kamera 1 PTZ Zoom out', desc: 'Bild verkleinern', type: 'boolean', role: 'switch' }); createState(idGotoPreset, 0, fC, { def: 0, name: 'Kamera 1 PTZ Preset Wähler', desc: 'Preset auswählen (Zahlen von 1 bis X)', type: 'number' }); /* log('Start the discovery process.'); // Find the ONVIF network cameras onvif.startDiscovery((info) => { // Show the device name and the URL of the end point log('- ' + info.urn); log(' - ' + info.name); log(' - ' + info.xaddrs[0]); }); // Stop the discovery process in 3 seconds setTimeout(() => { onvif.stopDiscovery(() => { log('Stopped the discovery process.'); }); }, 3000); */ // Create an OnvifDevice object const device = new onvif.OnvifDevice({ xaddr: 'http://192.168.178.xxx:8999/onvif/device_service', user : 'username', pass : 'passwort' }); function movePTZ (ptz_x, ptz_y, ptz_z, stoptime) { // https://github.com/futomi/node-onvif#ptzmoveparams-callback device.init((error) => { if (error) { log('[ERROR] ' + error.message); return; } else { // +++ CONTROL via PTZ var ptzlog = ''; ptz_x = (ptz_x <=1 && ptz_x >=-1) ? ptz_x : 0; ptz_y = (ptz_y <=1 && ptz_y >=-1) ? ptz_y : 0; ptz_z = (ptz_z <=1 && ptz_z >=-1) ? ptz_z : 0; if (ptz_x > 0) ptzlog = 'Schwenk nach rechts'; if (ptz_x < 0) ptzlog = 'Schwenk nach links'; if (ptz_y > 0) ptzlog = 'Schwenk nach oben'; if (ptz_y < 0) ptzlog = 'Schwenk nach unten'; if (ptz_z > 0) ptzlog = 'Zoom in'; if (ptz_z < 0) ptzlog = 'Zoom out'; ptzlog += ' für ' + stoptime + 's'; if (logging) log(ptzlog); // Create the parameters var params = { 'speed': { x: ptz_x, // Speed of pan (in the range of -1 to 1.0) y: ptz_y, // Speed of tilt (in the range of -1 to 1.0) z: ptz_z // Speed of zoom (in the range of -1 to 1.0) }, 'timeout': 30 // seconds }; // Move the camera device.ptzMove(params, (error) => { if (error) { log(error.message, 'error'); } else { log('Camera moved!'); } }); // Stop to the PTZ in X seconds setTimeout(() => { device.ptzStop((error) => { if (error) { log(error.message, 'error'); } else { log('Succeeded to stop after ' + stoptime + ' seconds.'); } }); }, stoptime * 1000); // stopzeit } }); } function stopMoving () { device.ptzStop((error) => { if (error) { log(error.message, 'error'); } else { log('Succeeded to stop.'); } }); } // https://github.com/futomi/node-onvif#gotopresetparams-callback-method function gotoPreset (presetNumber) { // 1,2,3 kommt als ganze Zahl if (presetNumber > 0) { device.init((error) => { if (error) { log('[ERROR] ' + error.message, 'error'); return; } /*else {*/ // The OnvifServicePtz object var ptz = device.services.ptz; if (ptz) { //var profile = device.getCurrentProfile(); // debug //log(JSON.stringify(profile, null, ' ')); // debug log var params = { 'ProfileToken': 'MainStream', 'PresetToken' : presetNumber.toString(), 'Speed' : {'x': 1, 'y': 1, 'z': 1} }; device.services.ptz.gotoPreset(params, (error, result) => { if (error) { log('[ERROR] ' + error.message, 'error'); } else { if (logging) log('Preset: ' + JSON.stringify(result.data, null, ' ')); // statt result.['data'] log('Camera moved to Preset #' + presetNumber.toString()); } }); } else { log('[ERROR] Your ONVIF network camera does not support the PTZ service.'); } //} }); } else { log('Preset für Kamera 1 kein valider Preset-Wert'); // debug log } } // Bild an telegram schicken function sendImage (pfad, bildtext) { setTimeout(function() { sendTo('telegram.1', { text: pfad, caption: bildtext }); log('Webcam Bild per telegram verschickt'); }, 2 * 1000); } function saveImage () { // Initialize the OnvifDevice object device.init((error) => { if (error) { log('[ERROR] ' + error.message, 'error'); return; } else { if (logging) log('The OnvifDevice object has been initialized successfully.'); // +++ Get the detailed device information var device_info = device.getInformation(); if (logging) log(JSON.stringify(device_info, null, ' ')); // +++ Get the UDP stream URL var url = device.getUdpStreamUrl(); if (logging) log('UDP-Stream: ' + url); // +++ Get Profile var profile = device.getCurrentProfile(); if (logging) log('Profile: ' + JSON.stringify(profile, null, ' ')); // Viele Infos // für debug: //log('http: ' + profile.stream.http); var cam_info = 'ONVIF Bild' + '\n' + 'Model: ' + device_info.Model + '\n' + 'Firmware: ' + device_info.FirmwareVersion + '\n' + 'Seriennummer: ' + device_info.SerialNumber + '\n' + 'Harware ID: ' + device_info.HardwareId + '\n' + 'RTSP-Stream: ' + url; // +++ Get the data of the snapshot log('fetching the data of the snapshot...'); device.fetchSnapshot((error, res) => { if (error) { log(error.message, 'error'); return; } // Save the data to a file and send via telegram fs.writeFile(dest_path + 'onvif_snapshot.jpg', res.body, function (error) { // Anpassen an die OS X gegebenheiten (oder per Telegram senden) if (error) { log(error.message, 'error'); } else { sendImage(dest_path + 'onvif_snapshot.jpg', cam_info); log('Image sent!'); } }); }); } }); } // Start beim Setzen auf true // Links on(idLinks, function (obj) { if (!obj.state.ack && obj.state.val) { var stoppzeit = getState(idStoppzeit).val; var speed = getState(idSpeed).val; movePTZ(-1 * speed , 0, 0, stoppzeit); setStateDelayed(idLinks, false, 500); // ggf , 500 + (stoppzeit * 1000) } }); // rechts on({id: idRechts, val: true}, function (obj) { if (!obj.state.ack && obj.state.val) { var stoppzeit = getState(idStoppzeit).val; var speed = getState(idSpeed).val; movePTZ(1 * speed , 0, 0, stoppzeit); setStateDelayed(idRechts, false, 500); } }); // oben on(idHoch, function (obj) { if (!obj.state.ack && obj.state.val) { var stoppzeit = getState(idStoppzeit).val; var speed = getState(idSpeed).val; movePTZ(0, 1 * speed, 0, stoppzeit); setStateDelayed(idHoch, false, 500, 500); } }); // rechts on(idRunter, function (obj) { if (!obj.state.ack && obj.state.val) { var stoppzeit = getState(idStoppzeit).val; var speed = getState(idSpeed).val; movePTZ(0, -1 * speed, 0, stoppzeit); setStateDelayed(idRunter, false, 500); } }); // vergrößern on(idZoomIn, function (obj) { if (!obj.state.ack && obj.state.val) { var stoppzeit = getState(idStoppzeit).val; var speed = getState(idSpeed).val; movePTZ(0, 0, 1 * speed, stoppzeit); setStateDelayed(idZoomIn, false, 500); } }); // verkleinern on(idZoomOut, function (obj) { if (!obj.state.ack && obj.state.val) { var stoppzeit = getState(idStoppzeit).val; var speed = getState(idSpeed).val; movePTZ(0, 0, -1 * speed, stoppzeit); setStateDelayed(idZoomOut, false, 500); } }); // sofortiger Stopp on(idStopp, function (obj) { if (!obj.state.ack && obj.state.val) { stopMoving(); setStateDelayed(idStopp, false, 500); setState(idGotoPreset, 0); } }); // bei Bedienung aller Knöpfe sofert Preset Anzeige löschen // klappt noch nicht so richtig, da laufende Fahrt zum Presetpunkt noch beendet wird on({ id: [idStopp, idZoomOut, idZoomIn, idRunter, idHoch, idRechts, idLinks], change: 'any' }, function (obj) { if (!obj.state.ack && obj.state.val) { setState(idGotoPreset, 0); } }); // zum bereits gespeicherten Preset X fahren (Ganze Zahl, kommt aus VIS, Scenes oder Script) on(idGotoPreset, function (obj) { if (!obj.state.ack && obj.state.val) { gotoPreset(parseInt(obj.state.val,10)); // wird später zu einem String gewandelt //setStateDelayed(idGotoPreset, 0, 500); // reset } }); // Skriptstart //setTimeout(saveImage, 15000); // setTimeout(goHome, 1000); /* setTimeout(function() { movePTZ(1,0,0,5); // rechts, 2 sek }, 1000); */
So wie das Skript hier veröffentlicht ist, läuft es bei mir (natürlich noch Nutzernamen, Passwort und Kamera-IP:Onvif-Pport anpassen).
Durch setzen der Objekte kann die Kamera bewegt werden. Sieht dann bei mir so aus:
Die drei Presets habe ich natürlich in der Kamera gespeichert, aber das Node-Modul lässt es auch zu, dort Positionen festzulegen und abzufahren. War mir zu aufwendig 8-) .Viel Erfolg!
Gruß
Pix
PS: Leider habe ich derzeit, überhaupt keine Zeit, daraus einen Adapter zu machen. Aber geplant ist es eigentlich schon :roll:
Edit 7.3.2019 nach Portierung ins neue Forum Skript bereinigt
-
Ick freu ma. Werde ich denn gleich mal testen.
Danke
-
Es geht. DANKE. jetzt kann ich erstmal ein bisschen spielen.
-
Eine Frage habe ich noch zum Part Telegram.
Durch welche Aktion kann ich mir ein Bild zu schicken lassen ?
Die Ptz Funktionen habe ich erstmal durch Node-red realisiert aber wie funktioniert jetzt der Aufruf für sendImage per Telegram?
-
Hallo,
freut mich, dass es klappt.
Die Ptz Funktionen habe ich erstmal durch Node-red realisiert aber wie funktioniert jetzt der Aufruf für sendImage per Telegram? `
Öhömmm :oops: Da habe ich wohl den Aufruf vergessen. Oder vielmehr habe ich vergessen, den Telegram Teil nach dem testen wieder rauszulöschen, denn das Zusenden nach Bewegungsalarm mache ich woanders.Kannst also die Funktionen sendImage() und saveImage() zwischen Zeile 256 und Zeile 315 komplett löschen, wenn du telegram nicht brauchst. Ebenso natürlich dann auch oben in Zeile 43 die Einbindung von fs.
Du kannst dir aber ei weiteres Objekt anlegen und dann zB über eine manuelle Auslösung in VIS ein Bild schicken lassen.
Gruß
Pix
-
Hallo zusammen,
ich weise nochmal darauf hin, dass das Paket node-onvif unbedingt nodejs 4 oder höher voraussetzt. Der Entwickler spricht sogar davon, dass nodejs 4 demnächst schon nicht mehr unterstützt wird.
https://www.npmjs.com/package/node-onvif#dependencies
Wer also plant, demnächst das Skript zu nutzen, aber sein nodejs 4 nicht updaten will, sollte sich noch schnell den jetzigen Stand des Moduls sichern/installieren.
Gruß
Pix
-
Ok. Verstehe. Ich könnte das auch ander machen mit Telegram aber ich dachte wenn es da schon mal drin steht kann man es auch nutzen. Ich Probier mal ein bisschen. Danke
-
Eine weitere Voraussetzung scheint wohl zu sein, dass die ONVIF Implementierung auf der WebCam Screenshots unterstützen muss, was bei mir nicht der Fall ist.
Ich konnte den server.js starten, die WebCam wurde gefunden, leider kein Bild angezeigt.
Die Pfeile im WebUi konnten den Kamerakopf verändern, aber so, wie man das von der Richtung des Pfeils im UI erwartet hätte.
Ich vermute, das Script verwendet auch die Screenshotfunktion, oder?
-
ich habe bei zwei Cameras, die onvif unterstützen probiert, aber leider ohne Erfolg. Discovery findet auch nichts.
javascript.1 2017-11-02 20:52:43.583 info script.js.common.Cam.onvif_wansview: Stopped the discovery process. javascript.1 2017-11-02 20:52:40.587 info script.js.common.Cam.onvif_wansview: registered 15 subscriptions and 0 schedules javascript.1 2017-11-02 20:52:40.580 info script.js.common.Cam.onvif_wansview: Start the discovery process. javascript.1 2017-11-02 20:52:40.568 info Start javascript script.js.common.Cam.onvif_wansview javascript.1 2017-11-02 20:52:40.525 info Stop script script.js.common.Cam.onvif_wansview javascript.1 2017-11-02 20:52:24.367 info script.js.common.Cam.onvif_wansview: Stopped the discovery process. javascript.1 2017-11-02 20:52:21.367 info script.js.common.Cam.onvif_wansview: registered 15 subscriptions and 0 schedules javascript.1 2017-11-02 20:52:21.364 info script.js.common.Cam.onvif_wansview: Start the discovery process. javascript.1 2017-11-02 20:52:21.353 info Start javascript script.js.common.Cam.onvif_wansview javascript.1 2017-11-02 20:52:21.170 info Stop script script.js.common.Cam.onvif_wansview
-
Hallo Marty56,
falls die Links-rechts-Bewegung vertauscht ist, kann das daran liegen, dass meine Kamera kopfüber hängt.
Hallo Lobomau,
das hier ist ein Skript, das ich für meine noname Kamera mit Hilfe der Beispiele auf der Github Seite des Onvif Moduls gebaut habe.
Bitte probiere etwas mehr aus. Ich habe Monate gebraucht.
Gruß
Pix
-
ich habe bei zwei Cameras, die onvif unterstützen probiert, aber leider ohne Erfolg. Discovery findet auch nichts.
javascript.1 2017-11-02 20:52:43.583 info script.js.common.Cam.onvif_wansview: Stopped the discovery process. javascript.1 2017-11-02 20:52:40.587 info script.js.common.Cam.onvif_wansview: registered 15 subscriptions and 0 schedules javascript.1 2017-11-02 20:52:40.580 info script.js.common.Cam.onvif_wansview: Start the discovery process. javascript.1 2017-11-02 20:52:40.568 info Start javascript script.js.common.Cam.onvif_wansview javascript.1 2017-11-02 20:52:40.525 info Stop script script.js.common.Cam.onvif_wansview javascript.1 2017-11-02 20:52:24.367 info script.js.common.Cam.onvif_wansview: Stopped the discovery process. javascript.1 2017-11-02 20:52:21.367 info script.js.common.Cam.onvif_wansview: registered 15 subscriptions and 0 schedules javascript.1 2017-11-02 20:52:21.364 info script.js.common.Cam.onvif_wansview: Start the discovery process. javascript.1 2017-11-02 20:52:21.353 info Start javascript script.js.common.Cam.onvif_wansview javascript.1 2017-11-02 20:52:21.170 info Stop script script.js.common.Cam.onvif_wansview ```` `
Was auch stimmen muss ist der Port. Ich habe auch mehrere Kameras und bei der einen Kamera hab ich ein Port 10080
-
Was auch stimmen muss ist der Port. Ich habe auch mehrere Kameras und bei der einen Kamera hab ich ein Port 10080 `
Ja, das ist bei meiner wansview w2 das Problem. Ich weiß den port nicht. Nichts gefunden im Handbuch oder google.Bei der FDT 720p kann ich den port wählen, hab 8080 gelassen.
-
@pix:Öhömmm :oops: Da habe ich wohl den Aufruf vergessen. Oder vielmehr habe ich vergessen, den Telegram Teil nach dem testen wieder rauszulöschen, denn das Zusenden nach Bewegungsalarm mache ich woanders. `
Hi Pix,
danke für das Script. Genial! Könntest Du mir vielleicht mitteilen wie Du das Zusenden nach Bewegungsalarm gelöst hast?
vg
Falk
-
Wollte mal kurz ein Feedback abgeben und mich recht herzlich für dein Skript bedanken.
Funktioniert Sehr gut, nachdem man die richtigen Einstellungen eingetragen hat,
Da du ja sogar einen Logmodus eingebaut hast, konnte ich (als ich den gesehen habe) meinen "ProfileToken" auslesen lassen und somit nun auch endlich meine Presets abfahren.
Vielen Vielen Dank.
lauft übrigens bei mir mit Nodejs 8.1.1
Gruß Marcus