Script: Bilder von Überwachungskamera per Telegram

Aus aktuellem Anlass und weil es immer wieder nachgefragt wird habe ich mal in meinem ioBroker-Notizbuch gestöbert und ein „altes“ Script (hat mir schon über 4000 Bilder geschickt) ausgegraben und etwas hübsch gemacht.

Im Script geht es darum, dass mein ioBroker mir beim Auslösen des Bewegungsmelders im Vorgarten ein Bild per Telegram-Messenger schickt, im Abstand von jeweils 3 Sekunden noch zwei weitere Bilder aufnimmt und auf Nachfrage ebenfalls zusendet.

Für dieses Tutorial habe ich das Script dann noch etwas verfeinert und die Möglichkeit zum Deaktivieren der Benachrichtigung und einen anpassbaren Zeitintervall für die Aufnahme der zusätzlichen Bilder hinzugefügt.

Im Folgenden will ich nun kurz beschreiben wie Ihr mein Script einsetzen könnt und die einzelnen Parameter konfiguriert. Zuerst klären wir aber mal die Vorraussetzungen.

Voraussetzungen

Ich werde versuchen das Tutorial nach Möglichkeit vollständig “copy-and-paste-fähig” zu schreiben, trotzdem solltet ihr nach Möglichkeit schon etwas ioBroker-Erfahrung mitbringen. Ich beziehe mich natürlich auch hier wieder auf meine eigene ioBroker-Umgebung (ioBroker unter Docker auf der Synology DiskStation), was allerdings nicht bedeutet, dass dieses Tutorial nicht 1:1 auch auf anderen Systemen umgesetzt werden kann. Außerdem setze ich folgendes voraus:

  • eingerichtete IP-Kamera und Pfad zum Kamerabild (Standbild)
  • Bewegungsmelder und/ oder anderer Auslöser
  • funktionsfähige ioBroker-Installation
  • installierter und konfigurierter Javascript-Adapter (mehr Infos)
  • installierter und konfigurierter Telegram-Adapter (inkl. Bot-Einrichtung!) (mehr Infos)
  • installierter und konfigurierter Text2command-Adapter (mehr Infos)

Konfiguration Telegram-Adapter

Wenn ihr bisher eventuell den Telegram-Adapter nur zum Senden von Benachrichtigungen genutzt habt, müsst ihr ggf. noch eine Einstellung anpassen. Dies ist die Verknüpfung des Adapters mit dem Text2command-Adapter.

Zu finden ist die Option in den Einstellungen des Telegram Adapters unter „NACHRICHTEN > Text2Command-Instanz“. Hier bitte die Text2Command-Instanz, die ihr verwenden wollt auswählen und speichern.

Javascript anlegen und konfigurieren

Als nächstes einfach ein neues Javascript unter “Scripte” anlegen und die folgenden Zeilen hineinkopieren.

// JavaScript zur Verwendung in ioBroker
//
// Das Script speichert bei Auslösung (z.B. durch einen Bewegungsmelder) drei Bilder einer Überwachungskamera in frei definierbaren Zeitabständen und versendet das erste Bild per telegram.
// Über telegram können dann bei Bedarf auch die weiteren zwei Bilder abgefragt werden. Natürlich ist auch eine manuelle Auslösung (ohne Bewegungsmelder) per telegram möglich.
// Der Automatische Versand der Bilder kann über telegram auch aktiviert/ deaktiviert werden. 
//
// Mehr Infos zum Script und dessen Einrichtung hier:  
 
// Hier können Einstellungen vorgenommen werden:

// Variablen
var cam_img = 'http://xxx:xx/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxx&pwd=xxx';	// Pfad zum Kamerabild (Im Beispiel eine Foscam)
var trigger_auto = 'hm-rpc.0.JEQXXXXXXX.1.MOTION';	// Datenpunkt zur autmatischen Auslösung (Status des Bewegungsmelders, Fenster-/ Türkontakt oder der Türklingel)
var trigger_manu = 'javascript.0.notify.telegram.cam.trigger_manu';	// Datenpunkt zur manuellen Auslösung (wird bei Bedarf automatisch angelegt)
var trigger_more_img = 'javascript.0.notify.telegram.cam.trigger_more_img';	// Datenpunkt zur Abfrage weiterer Bilder (wird bei Bedarf automatisch angelegt)
var disable = 'javascript.0.notify.telegram.cam.disable';	// Aktivierung/Deaktivierung des Versands per telegram (wird bei Bedarf automatisch angelegt)
var interval = '3000';	// Verzögerung der weiteren Aufnahmen in Millisekunden
var img_path = '/opt/iobroker/temp/cam/';	// Pfad zum lokalen Speicherort der aufgenommenen Bilder. Bilder werden bei jeder Auslösung überschrieben. Pfad muss schon vorhanden sein!


// -------------------------------------------
// Ab hier braucht in der Regel nichts mehr geändert zu werden. Also Finger weg wenn du nicht weißt was du tust. 🙂 
// -------------------------------------------

// Datenpunkte anlegen (Kann unter Umständen auskommentiert werden, wenn die Datenpunkte manuell angelegt wurden.)
createState( trigger_auto, false, {name: 'Datenpunkt zur autmatischen Auslösung'});
createState( trigger_manu, false, {name: 'Datenpunkt zur manuellen Auslösung'});
createState( trigger_more_img, false, {name: 'Datenpunkt zur Abfrage weiterer Bilder'});
createState( disable, false, {name: 'Aktivierung/Deaktivierung des Versands per telegram'});

// Variablendeklaration und Initialisierung bei Scriptstart
var stateTrigger_auto = getState(trigger_auto).val;
var stateTrigger_manu = getState(trigger_manu).val;
var stateTrigger_more_img = getState(trigger_more_img).val;
var stateDisable = getState(disable).val;
var request = require('request');
var fs      = require('fs');
var timer;


// Funktionen
// -------------------------------------------

// Funktion Bilder versenden
function sendImage (pfad) {
    setTimeout(function() {
        sendTo('telegram.0', {
    text:   pfad,
    reply_markup: {
        keyboard: [
            ['Mehr Bilder', 'Danke']
        ],
        resize_keyboard:   true,
        one_time_keyboard: true
    }
});
        log('Webcam Bild per telegram verschickt.');
    }, 2000);
}

// Funktion Bilder speichern
function saveImage() {
    request.get({url: cam_img, encoding: 'binary'}, function (err, response, body) {
        fs.writeFile(img_path + 'cam1_1.jpg', body, 'binary', function(err) {
        if (err) {
            log('Fehler beim Speichern von Bild 1: ' + err, 'warn');
        } else {
            log('Bild 1 gespeichert.');
            sendImage(img_path + 'cam1_1.jpg');
        }
      }); 
    });
    
    if (timer) {
        clearTimeout(timer);
        timer = null;
    } 
    timer = setTimeout(function () {
        request.get({url: cam_img, encoding: 'binary'}, function (err, response, body) {
            fs.writeFile(img_path + 'cam1_2.jpg', body, 'binary', function(err) {
            if (err) {
                log('Fehler beim Speichern von Bild 2: ' + err, 'warn');
            } else {
                log('Bild 2 gespeichert.');
        }
      }); 
    });
        }, interval);
    timer = setTimeout(function () {
        request.get({url: cam_img, encoding: 'binary'}, function (err, response, body) {
            fs.writeFile(img_path + 'cam1_3.jpg', body, 'binary', function(err) {
            if (err) {
                log('Fehler beim Speichern von Bild 3: ' + err, 'warn');
            } else {
                log('Bild 3 gespeichert.');        }
      }); 
    });
        }, 2 * interval);
}


// Trigger für die verschiedenen Aktionen
// -------------------------------------------

// trigger_auto
on(trigger_auto, function(dp) {
    stateTrigger_auto = dp.newState.val;
	stateDisable = getState(disable).val;
    if (stateTrigger_auto === true && stateDisable === false) {
        saveImage();
        // setState(trigger_auto, false);     // Option zum Zurücksetzen des Triggers. Standardmäßig auskommentiert, da sich der Bewegungsmelder automatisch zurück setzt. Bei Bedarf "//" am Zeilenafang entfernen.
    }
});

// trigger_more_img
on(trigger_more_img, function(dp) {
    stateTrigger_more_img = dp.newState.val;
    if (stateTrigger_more_img === true) {
        sendImage(img_path + 'cam1_2.jpg');
        sendImage(img_path + 'cam1_3.jpg');
        setState(trigger_more_img, false);
    }
});

// trigger_manu
on(trigger_manu, function(dp) {
    stateTrigger_manu = dp.newState.val;
    if (stateTrigger_manu === true) {
        saveImage();
        setState(trigger_manu, false);
    }
});

Die zu konfigurierenden Parameter im Script sollten eigentlich ausreichend kommentiert sein, sodass ich darauf hier wohl nicht weiter eingehen muss.

Hinweis: Solltet ihr das Verzeichnis für die Speicherung der Kameraaufnahmen übernehmen, so müsst ihr den Ordner vor der Inbetriebnahme noch anlegen. Dies geht am einfachsten über die Konsole (im Docker-Container) über den Befehl:

mkdir -p /opt/iobroker/temp/cam/

Konfiguration der Steuerbefehle im Text2Command-Adapter

Wenn ihr soweit alles richtig gemacht habt, dann sollte das Script euch nun bereits bei automatischer Auslösung das erste aufgenommene Bild zusenden. Damit Ihr aber z.B. weitere Bilder abfragen könnt, müssen noch ein paar Schlüsselworte und Aktionen im Text2Command-Adapter konfigurieren.

Dazu öffnet einfach die Adapter-Website und konfiguriert folgende Aktionen:

Im Einzelnen bildet das dann folgende Funktionen ab:

Mehr Bilder

Triggerworte: mehr bilder
Variablen-ID: javascript.0.notify.telegram.cam.trigger_more_img
Wert: true
Antwort: Geht los./Kommen sofort./OK.

Benachrichtigungen aktivieren

Triggerworte: kamera benachrichtigung einschalten/kamera benachrichtigung ein/kamera benachrichtigung aktivieren
Variablen-ID: javascript.0.notify.telegram.cam.disable
Wert: false
Antwort: Kamera Haustür: Benachrichtigung aktiv!

Benachrichtigungen deaktivieren

Triggerworte: kamera benachrichtigung ausschalten/kamera benachrichtigung aus/kamera benachrichtigung deaktivieren
Variablen-ID: javascript.0.notify.telegram.cam.disable
Wert: true
Antwort: Kamera Haustür: Benachrichtigung inaktiv!

Manuelle Auslösung

Triggerworte: kamera
Variablen-ID: javascript.0.notify.telegram.cam.trigger_manu
Wert: true
Antwort: Geht los./Kommt sofort./OK.

Von nun an sollte euch das Script bei jeder Auslösung ein Bild zusenden. Mit “Mehr Bilder” könnt ihr die anderen beiden Bilder abrufen. Mit dem Schlüsselwort “Kamera” löst ihr das Script manuell aus.
Über das Senden von z.B. “Kamera Benachrichtigung aus” oder “Kamera Benachrichtigung ein” könnt ihr das automatische zusenden ein- und ausschalten.
Natürlich könnt ihr die Schlüsselworte/ -phrasen nach Belieben gestalten. 🙂

Ich hoffe ihr könnt mit meinem kurzen Tutorial etwas anfangen. Bei Fragen und Anregungen zum Tutorial freue ich mich auf eure Kommentare. Bitte berücksichtigt, dass ich keinen individuellen Support per E-Mail leisten kann. Nutzt also bitte die öffentlichen Kanäle wie Kommentare, Foren oder Social Media. Gerne könnt ihr mich bei Bedarf auch per E-Mail oder Direktnachricht auf einen Post/ Thread/ Kommentar aufmerksam machen. Danke.

MfG,
André

About the author: André

André
Familienvater und bekennender Technik-Nerd. Beruflich unterwegs als Fachinformatiker für Systemintegration bei einem deutschen IT-Dienstleister. In der Freizeit begeisterter "Home-Automatisierer" bzw. "Smarthome-Bastler" und (zumindest bei schönem Wetter) gerne mit der Familie in verschiedenen Outdooraktivitäten unterwegs.

7
Hinterlasse einen Kommentar

avatar
10000
3 Kommentare
4 Antworten
0 Abonnenten
 
Meiste Antworten
Beliebtester Kommentar
5 Kommentatoren
ThomasLucasdvb2kAndréAlex Letzte Kommentatoren
  Abonnieren  
Benachrichtige mich zu:
Thomas
Gast
Thomas

Vielen Dank für das Script! Bei mir (Dahua IP Cam’s) wurden leere Dateien angelegt. Per URL im Browser ging es zwar mit user und pw in der URL aber offensichtlich in request.get nicht. Meine Lösung (Fehlerbehandlung fehlt), vielleicht nützt es ja noch jemandem:

var USER = ‚admin‘;
var PASS = ’secretpassword‘;

request(cam_img , function (error, response, body) {
if ((error) || (response.statusCode !== 200)) {
// self.emit(„error“, ‚ERROR ON SNAPSHOT‘);
}
})
.auth(USER,PASS,false).pipe(fs.createWriteStream(img_path + ‚cam1_1.jpg‘));

Gruss, Thomas

Lucas
Gast
Lucas

Hey,
vielen dank für die Anleitung.
Leider bin ich mit google und probieren nicht so wirklich weiter gekommen, aber gibt es auch eine Möglichkeit als Pfad die Raspberry Cam direkt zu integrieren?
Vielen Dank für eine Antwort.
Gruß Lucas

Alex
Gast
Alex

Nabend, habe mal etwas rumexperimentiert und ich benötigte beim auto trigger noch eine funktion die true wieder auf false setzt. habe es so gelöst: // trigger_auto
on(trigger_auto, function(dp) {
stateTrigger_auto = dp.newState.val;
stateDisable = getState(disable).val;
if (stateTrigger_auto === true && stateDisable === false) {
saveImage();
setStateDelayed( trigger_auto, false, true, parseInt(15000, 10), false);
}
});

Hoffe ist alles richtig funzt auf jeden fall