Smart Doorbell – Türklingel mit Videoüberwachung und Pushingbox, basierend auf Arduino, Raspberry und HTML

15. November 2015 at 11:05
Print Friendly, PDF & Email

Wenn jemand an der Haustür klingelt werden zwei Ereignisse ausgelöst:

  • Über Pushingbox wird ein Pop-Up Fenster auf den gekoppelten Geräten angezeigt.
    Dies sind bei mir alle Computer im Haus sowie iPad.
  • Auf einer Web-Seite wird das Bild der IP-Kamera für 2 Minuten eingeblendet.
    Die Web-Seite kann auf jedem Gerät mit Browser  aufgerufen werden.
    Da ich im Eingangsbereich kein Computer montieren will, wurde hier ein Tablet installiert.
Update August 2017: Die Lösung wurde nun durch OpenHAB ersetzt.

Video-Überwachung

Door-Schema-webserver

Ruhemodus                                                                     Video der IP-Kamera an der Haustür

Door-Web-Uhr    Door-Web-Video

 

Der Arduino wurde mit einem Optokopler an die Türklingel angeschlossen. Wenn jemand klingelt, ruft der Web-Client des Arduinos einen Web-Server auf. Da bei mir ein Raspberry immer läuft, habe ich dort die HTML-Seiten hinterlegt. Man kann natürlich einen beliebigen anderen Web-Sever (z.B. auf einem NAS) verwenden.

Auf dem Web-Server liegt eine Seite, die im Ruhemodus eine Uhr anzeigt. Wenn der Arduino sein Signal sendet, wird der Video-Stream der IP-Kamera für 2 Minuten eingeblendet,

 

/* Doorbell.pde -- sample code for Doorbell  */
// Based on general code from http://www.pushingbox.com for Arduino + Ethernet Shield (official) v1.2
#include "Arduino.h"
#include <SPI.h>
#include <Ethernet.h>
 
void sendToWebServer(IPAddress myDoorMonitor, int iPort, char ipcamCode[]);
void sendToPushingBox(char serverName[],int iPort, char path[]);
 
/////////////////
 // MODIFY HERE //
/////////////////
 
//Your secret DevID from PushingBox.com. You can use multiple DevID  on multiple Pin if you want
char serverNamePushingbox[] = "api.pushingbox.com";
char path_pushingBox[] = "GET /pushingbox?devid=maintainyouridhere";
 
byte mac[] = { 0x00, 0xAA, 0xBB, 0xCC, 0xDE, 0x19 };   // Be sure this address is unique in your network
IPAddress myIP(192,168,xxx,xxx);
char myClientName[] =  "www.arduino-hoeser.de";
 
uint8_t pinDevid1 = 3; // Example : the doorbell switch is connect to the Pin 3
int     statusLED = 7; // LED connect to Pin 7
 
IPAddress myDoorMonitor_1(192,168,xxx,xxx); // Raspberry Wintergarten
IPAddress myDoorMonitor_2(192,168,xxx,xxx); // Raspberry Wohnzimmer
IPAddress myDoorMonitor_3(192,168,xxx,xxx); // Raspberry Speicher
int iPortRaspi = 80;
 
IPAddress myCamoFS_1(192,168,xxx,xxx); // Vu Plus SAT Receiver
int iPortVuPlus = 8080;
 
char path_htPlugin[]   = "/htPlugin/plugins/doorbell/doorbell.php?bell=secretid";
char path_htCamoFS_1[] = "/doorbell.php?bell=secretid&cam=cam1";
char path_htCamoFS_2[] = "/doorbell.php?bell=secretid&cam=cam2";
char path_upload_and_push[] = "/ftp/upload.php";
 
  //////////////
 //   End    //
//////////////
 
boolean pinDevid1State = false;                // Save the last state of the Pin for DEVID1
boolean lastConnected = false;                 // State of the connection last time through the main loop
EthernetClient webClient;// Initialize the Ethernet client library
 
#define BLINK_DURATION 10
 
// --------------------------------------------------------------- function()
void myBlink(int ledpin, int time, int repeat){
int i,cur_level;
 
	cur_level = digitalRead(ledpin); // read current level
	for(i=0; i<repeat;i++){
		digitalWrite(ledpin, ! cur_level); // invert initial level
		delay(time);
		digitalWrite(ledpin, cur_level); // set back to initial level
		delay(time);
	}
}
 
// ----------------------------------------------------------------------------------------------
void setup() {
 
  Serial.begin(9600);
  delay(200);
  Serial.println("\n\n+++++++++++++++++++++++++++++++++++++");
  Serial.println("++  Network Doorbell - 2016-01-17  ++");
  Serial.println("+++++++++++++++++++++++++++++++++++++");
 
  pinMode(pinDevid1, INPUT);
  pinMode(statusLED, OUTPUT);
 
  Ethernet.begin(mac, myIP);
  Serial.print("My IP address: ");    // print the Ethernet board/shield's IP address:
  Serial.println(Ethernet.localIP());
  delay(1000);// give the Ethernet shield a second to initialize
 
  myBlink(statusLED,200,3);
 
} // setup()
 
// ----------------------------------------------------------------------------------------------
void loop()
{
      ////
      // Listening for the pinDevid1 state
      ////
      if (digitalRead(pinDevid1) == HIGH && pinDevid1State == false) // switch on pinDevid1 is ON
      {
        Serial.println("pinDevid1 is HIGH");
        pinDevid1State = true;
 
        myBlink(statusLED,BLINK_DURATION,1);
        Serial.println("****************************************** doorbell pressed ");
 
        //Sending request to raspberries + PushingBox when the pin is HIGH
 
//        sendToWebServer(myDoorMonitor_1, iPortRaspi, path_htPlugin);
//        myBlink(statusLED,BLINK_DURATION,1);
 
        sendToWebServer(myDoorMonitor_2, iPortRaspi, path_htPlugin);
        myBlink(statusLED,BLINK_DURATION,1);
 
        sendToWebServer(myDoorMonitor_3, iPortRaspi, path_htPlugin);
        myBlink(statusLED,BLINK_DURATION,1);
 
        sendToWebServer(myCamoFS_1, iPortVuPlus, path_htCamoFS_2);
        myBlink(statusLED,BLINK_DURATION,1);
 
//        sendToPushingBox(serverNamePushingbox, 80, path_pushingBox);
//        myBlink(statusLED,BLINK_DURATION,1);
 
        sendToWebServer(myDoorMonitor_3, iPortRaspi, path_upload_and_push);
        myBlink(statusLED,BLINK_DURATION,1);
 
        Serial.println(">>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>> all messages send ");
        pinDevid1State = false;
      }
 
} // loop()
 
// ----------------------------------------------------------------------------------------------
//Function for sending the request to door monitor
void sendToWebServer(IPAddress myDoorMonitor,int iPort, char path[]){
int returnCode; // false = 0
 
	webClient.stop();
	Serial.print("----------------------- connecting to Web Server ... ");
	Serial.println(myDoorMonitor);
 
  	returnCode = webClient.connect(myDoorMonitor, iPort);
  	if (returnCode) {
  		Serial.print("connected, sending request to ");
  		Serial.println(myDoorMonitor);
  		Serial.println(path);
 
  		webClient.print("GET ");
  		webClient.print(path);
  		webClient.println(" HTTP/1.1");
 
  		webClient.print("Host: ");
  		webClient.println(myClientName);
  		webClient.println("User-Agent: Arduino");
  		webClient.println("Connection: close");
  		webClient.println();
 
        // this reads the response from Web Server.
        webClient.flush(); // waits until all outgoing characters in buffer have been sent.
  		delay(1);
        while (webClient.connected()) {
        	if ( webClient.available() ) {
        		char c = webClient.read();
        		Serial.print(c);
        	}
        }
 
        // if the server's disconnected, stop the webClient:
        if (!webClient.connected()) {
         Serial.println();
         Serial.println("disconnecting.");
         webClient.stop();
        }
  	}
  	else {
  		Serial.print("ERROR - connection to ");
  		Serial.print(myDoorMonitor);
  		Serial.println(" failed");
  	} // webClient.connect
 
  	Serial.println("sendToWebServer complete");
}
 
// ----------------------------------------------------------------------------------------------
//Function for sending the request to door monitor
void sendToPushingBox(char serverName[],int iPort, char path[]){
int returnCode; // false = 0
 
 
	webClient.stop();
	Serial.print("----------------------- connecting to Web Server ... ");
	Serial.println(serverName);
 
  	returnCode = webClient.connect(serverName,80);
  	if (returnCode) {
  		Serial.print("connected, sending request to ");
  		Serial.println(serverName);
  		Serial.println(path);
 
  		webClient.print(path);
  		webClient.println(" HTTP/1.1");
 
  		webClient.print("Host: ");
  		webClient.println(serverNamePushingbox);
  		webClient.println("User-Agent: Arduino");
  	    webClient.println("Connection: close");
  	    webClient.println();
 
        // this reads the response from Web Server.
        webClient.flush(); // waits until all outgoing characters in buffer have been sent.
  		delay(1);
        while (webClient.connected()) {
        	if ( webClient.available() ) {
        		char c = webClient.read();
        		Serial.print(c);
        	}
        }
 
        // if the server's disconnected, stop the webClient:
        if (!webClient.connected()) {
         Serial.println();
         Serial.println("disconnecting.");
         webClient.stop();
        }
  	}
  	else {
		Serial.print("ERROR - connection to ");
		Serial.print(serverName);
		Serial.println(" failed");
  	} // webClient.connect
 
  	Serial.println("sendToWebServer complete");
}

 

Benachrichtigung per Pushingbox

Der Arduino sendet parallel ein Nachricht an pushingbox. Der Client zeigt wenige Sekunden später ein po-up.
Somit kann man z.B. auf dem Computer die Web-Seite auf dem rasbperry aufrufen.

 

Door-Schema-pushingbox

Notifying Doorbell with PushingBox

Notifying Doorbell with PushingBox