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

15. November 2015 at 11:05

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,

 

[codesyntax lang=”c”]

/* 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");
}

[/codesyntax]

 

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