Smart Doorbell – openhab / Türklingel mit IP-CAM

7. Januar 2018 at 18:49
Print Friendly, PDF & Email

Klingel mit Openhab verbinden

Wenn jemand klingelt, erscheint auf dem HABPanel das Bild der IP-CAM.

Die Klingel ist mit einem raspberry verdrahtet. Ein shellscript wartet auf einen Interrupt und ruft dann ein weiteres Shell-Script auf. Dort wird dann ein Nachricht an den MQTT Server geschickt.

In OpenHAB gibt es ein item, welches auf diese MQTT-Nachricht wartet. In der entsprechenden Regel wird das HABPanel umgeschaltet (pDashboard). Danach werden mit Verzögerung 2 Bilder von der Kamera geholt. Diese werden separat angezeigt. Wenn jemand aus Spaß klingelt und sofort wegläuft oder sich umdreht, ist er auf den beiden gesicherten Bildern immer noch zu erkennen. Ich habe eine foscam C1 montiert. Dies ist sehr klein und unauffällig. Leider kann ich keinen Live-stream zeigen, so dass in dem frame lediglich jede Sekunde das Bild aktualisiert wird. Ist nicht sehr schön, aber ausreichend.

Bei mir habe ich tatsächlich 3 Raspberries verwendet. Die ersten beiden haben noch andere Aufgaben. Grundsätzlich kann aber alles auf einem Raspberry installiert werden.

Man kann dies natürlich auch ohne MQTT umsetzen. Da bei mir darüber bereits die homie Module, 1wire Auswertung und die 433MHz Anbindung darüber läuft, was es für mich logisch die Kingel auch so anzubinden.

Mittlerweile habe ich im Eingangsbereich einen MagicMirror, der acuh sehr leicht über MQTT angebunden wurde und nun den live-stream via RTSP darstellen kann:

MagicMirror mit MQTT-Anbindung

 

raspberry

crontab -e

[codesyntax lang=”bash”]

@reboot sudo /home/pi/doorbell/doorbell.py 2>&1

[/codesyntax]

doorbell.py

[codesyntax lang=”bash”]

#!/usr/bin/env python
# -*- coding: utf-8 -*-
#
#
# crontab -e
# @reboot sudo /home/pi/doorbell/doorbell.py 2>&1

#
import RPi.GPIO as GPIO
import time
import subprocess
 
GPIO.setmode(GPIO.BOARD) # use the pin number as on the raspi board
Button_GPIOPin = 5 # s/b 5 for boot / shutdown
LED_GPIOPin    = 11  # LED showing status
 
time_stamp = time.time()
 
GPIO.setup  (Button_GPIOPin, GPIO.IN ) # set pin 5 is input
GPIO.setup  (LED_GPIOPin   , GPIO.OUT) # set pin 7 as output
GPIO.output (LED_GPIOPin   , False    )# set pin 7 Low
 
Counter = 0
CounterPrior = 0


# ----------------------------------------------------------
def Button_Interrupt(channel):
	global time_stamp       # put in to debounce
	time_now = time.time()
	global Counter
	Counter = Counter + 1
	print "---------------------------------------- Button interrupt -> Counter :" + str(Counter)
	return
 
# ----------------------------------------------------------
def myBlink(ledpin, sleeptime, repeat):
	i = 0
	curlevel = 0
	curlevel = GPIO.input(ledpin)
 
	for i in range(0,repeat): 
		print "myblink - " + str(i)
		GPIO.output(ledpin, not curlevel)
		time.sleep(sleeptime) # wait 100ms
		GPIO.output(ledpin, curlevel)
		time.sleep(sleeptime) # wait 100ms
	return
#---------------------------------------------------------
# main function
def main():
 
	global Counter
	global CounterPrior
 
	print "-----------------------  Polling on PIN 5 started ...(LED 11)"
	myBlink(LED_GPIOPin,0.1,4);
	GPIO.add_event_detect(Button_GPIOPin, GPIO.RISING, callback = Button_Interrupt, bouncetime = 200)
 
	while True:
		# increment value if button is pressed
		if Counter > CounterPrior:
			print "> Counter > 1 :" + str(Counter)
			myBlink(LED_GPIOPin,0.2,2);
			subprocess.call('echo doorbell pressed | wall -n ', shell=True)

			print "> mqtt pub"
			subprocess.call('/home/pi/mqttpub.sh -t house/Door_EG_ESP1/switchDoor/on true', shell=True)

			Counter = 0
			CounterPrior = Counter
			myBlink(LED_GPIOPin,0.2,1);
			print "> ------------------- wait for next push....."
		# end if Counter
 
		time.sleep(0.5) # wait 500ms
 
		# 
	return 0
 
if __name__ == '__main__':
 
	 # call main function
	 main()

[/codesyntax]

mqttpub.sh

[codesyntax lang=”bash”]

#!/bin/bash
MQTT_SERVER="192.168.xxx.xxx"
MQTT_PORT="1883"
MQTT_USER="myuser"
MQTT_PW="mypassword"

MQTT_TOPIC="garage/Door_Garage_ESP1/switchDoor/on/set"
# MQTT_MSG="true"


ERR_NONE=0

# error handler
printUsage() {
   echo "Usage: mqttpub.sh [-t|--topic <topic>|] <message> "
   echo "examples"
   echo "./mqttpub.sh false"
   echo "./mqttpub.sh -t garage/Door_Garage_ESP1/switchDoor/on/set false"
   exit ${ERR_NONE}
}

# check if parameter has been provided
case $1 in
-t|--topic)
	case $2 in
	"")
		printUsage
		;;
	*)
		MQTT_TOPIC=$2
		echo "topic set:" $MQTT_TOPIC
		shift
		shift
		;;
	esac
	;;
esac

# read next paramater from commend line
case $1 in
*)
	case $1 in
	"")
		printUsage
		;;
	*)
		MQTT_MSG="$1"
		;;
	esac
	;;
esac


echo mosquitto_pub -t $MQTT_TOPIC -m $MQTT_MSG -q 1 -r -h $MQTT_SERVER -p $MQTT_PORT -u $MQTT_USER -P $MQTT_PW
mosquitto_pub -t $MQTT_TOPIC -m $MQTT_MSG -q 1 -r -h $MQTT_SERVER -p $MQTT_PORT -u $MQTT_USER -P $MQTT_PW


echo "message send:" $MQTT_TOPIC " <" $MQTT_MSG

[/codesyntax]

OpenHAB

doorbell.items

[codesyntax lang=”bash”]

// listen to status conveyed via MQTT
Switch 		door_EG_msg 		"MQTT switch status: [%s]" 	(gHomie2Setup,gPersist)	{ mqtt="<[mosquitto:house/Door_EG_ESP1/switchDoor/on:state:MAP(trueonfalseoff.map)" }
DateTime 	door_EG_time									(gHomie2Setup,gPersist)
String		AlarmPic1	"Picture from IPCM1 at door"

[/codesyntax]

doorbell.rules

[codesyntax lang=”bash”]

rule "DoorEGMessageChanged -> On"
when
  Item door_EG_msg changed from OFF to ON
then
    // logInfo("homie:DoorEGMessage", "Door EG Message to ON")
    
    val DateTime GetTime = now
    door_EG_time.postUpdate(new DateTimeType(GetTime.toString))
    
    // this change the cintent of a fram define in HabPanel
    postUpdate(pFrameIPCam,"http://192.168.xxx.xxx:88/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxxx&pwd=xxxxx")
    postUpdate(nFrameIPCam, 1) // [1="live", 1="Archiv 1", 2="Archiv 2"]
    postUpdate(pDashboard, "IP Cam")
    
	postUpdate(door_EG_switch,ON)
	
    // get single image and store as people will move out of the visible area
    val url = "http://192.168.xxx.xxx:88/cgi-bin/CGIProxy.fcgi?cmd=snapPicture2&usr=xxxxx&pwd=xxxxx"
  	// val outputFile = "/home/openhab/snaps/" + now.toString.replaceAll("[:\\/ ]+", "_") + ".jpg"
  	val outputFile = "/srv/openhab2-conf/html/alarm/alertpic.jpg"
  	logInfo("homie:Exec", "get \n" + outputFile)
	var cmd = "curl -m 10 -o " + outputFile + " " + url
	// logInfo("homie:Exec", "curl:\n" + cmd)  
	var String cmdRet1=executeCommandLine(cmd,1000)
    logInfo("homie:Exec", "Results from curl:\n" + cmdRet1)    
  	postUpdate   (AlarmPic1, outputFile)
  
    var String cmdExe="/home/openhabian/pushbullet.sh "
    var String cmdMsg="doorbell ON"
    var String cmdAll=cmdExe + " \"" + cmdMsg + "\""
    var String cmdRet=executeCommandLine(cmdAll,1000)
    logInfo("homie:Exec:pushbullet.sh", "Results from script:\n" + cmdRet)  

 // get second single image and store as people will move out of the visible area      
    timerDoorPic2 = createTimer(now.plusMinutes(1)) [| 
    	val outputFile2 = "/srv/openhab2-conf/html/alarm/alertpic2.jpg"
    	logInfo("homie:Exec", "get \n" + outputFile2)
    	var cmd2 = "curl -m 10 -o " + outputFile2 + " " + url
    	// logInfo("homie:Exec", "curl:\n" + cmd2)
    	var String cmdRet2=executeCommandLine(cmd2,1000)
    	logInfo("homie:Exec", "Results from curl:\n" + cmdRet2) 
    	timerDoorPic2 = null
    	postUpdate(door_EG_msg,OFF)
    	postUpdate(door_EG_switch,OFF)
    ]
    timerDoorPanel = createTimer(now.plusMinutes(5)) [|
    	postUpdate(pDashboard, "HOME")
    	timerDoorPanel = null
    ]
end


rule DoorEGMessageChanged_Off
when
  Item door_EG_msg changed from ON to OFF
then
    postUpdate(door_EG_switch,OFF)
end

[/codesyntax]

 

pushbullet.sh

[codesyntax lang=”bash”]

#!/bin/bash
API_KEY="mysecretapikey"
MSG_TITLE="Alert"
MSG_BODY="hallo Welt"

ERR_NONE=0

# error handler
printUsage() {
   echo "Usage: pushbullet.sh [-t|--title <title>|] <message> "
   echo "examples"
   echo './pushbullet.sh "Hallo Welt"'
   echo './pushbullet.sh -t "my Script" "Hallo Welt"'
   exit ${ERR_NONE}
}

# check if parameter has been provided
case $1 in
-t|--title)
	case $2 in
	"")
		printUsage
		;;
	*)
		MSG_TITLE=$2
		echo "title set:" $MSG_TITLE
		shift
		shift
		;;
	esac
	;;
esac

# read next paramater from commend line
case $1 in
*)
	case $1 in
	"")
		printUsage
		;;
	*)
		MSG_BODY="$1"
		;;
	esac
	;;
esac

curl -u $API_KEY: https://api.pushbullet.com/v2/pushes -d type=note -d title=$MSG_TITLE -d body="$MSG_BODY" > curl.log 2>&1
echo "message send :" $MSG_BODY

[/codesyntax]

 

Beschaltung

Die Klingel wird mit einem Optokoppler angebunden