Smart Doorbell – openhab / Türklingel mit IP-CAM
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
@reboot sudo /home/pi/doorbell/doorbell.py 2>&1
doorbell.py
#!/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()
mqttpub.sh
#!/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
OpenHAB
doorbell.items
// 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"
doorbell.rules
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
pushbullet.sh
#!/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
Beschaltung
Die Klingel wird mit einem Optokoppler angebunden
Hallo Herr Höser,
ihre Seiten haben mir sehr bei der Einrichtung eines MM2 geholfen.
Noch zwei Fragen:
Müssen MQTT-Server und OpenHAB auf getrennter Hardware laufen?
Wird das MMM.mqtt mudule im MM2 bei Ihrer Anwendung gebraucht oder läuft das über die Scripte?
Viele Grüsse
Andreas Engelmann
Hallo Herr Engelmann,
Der MQTT-Server/Broker kann auf der gleichen Hardware laufen.
Neben OpenHAB verwende ich MQTT auch fuer NodeRed, daher habe ich dies getrennt.
Bei mir ist MMM.mqtt ein reines Anzeigemodul fuer Temperaturen meiner 1/Wire Sensoren bzw. Daten der SONOFF POW Module.
Wenn keine Anzeige erfolgen soll, muss man dies auch nicht installieren.
Viele Gruesse,
Thomas Hoeser
Hallo Herr Höser,
ich mache gerade meine ersten Erfahrungen mit OpenHAB auf einem Raspberry und versuche Ihr Beispiel für eine Türstation Anbindung umzusetzen.
Sie schreiben das Sie einen Taster zur Signalisierung verwenden welches am pin5 angeschlossen wird. Kann ich das auch mit einem Relais machen? Ich verwende eine Mobotix Türstation und über die IO Box kann ich ein Relais (potentialfrei) ansprechen.
Gruß
Marc Hanselmann
Hallo Herr Hanselmann,
ich habe den Schaltplan für den Eingang hinzugefügt.
Der Taster S1, und die LED sind nur für Testzwecke eingefügt worden.
Viele Grüße,
Thomas Höser
Hallo,
ich kämpfe mich so langsam durch die Scripts,
können Sie mir vielleicht noch ein paar Info’s bzw. Erklärungen zu den beiden folgenden Befehlen geben?
mqtt=”<[mosquitto:house/Door_EG_ESP1/switchDoor/on:state:MAP(trueonfalseoff.map)" }
und
subprocess.call('/home/pi/ -t house/Door_EG_ESP1/switchDoor/on true', shell=True)
bei den subprocess bekomme ich ein access denied
Sie können mir auch gerne per Email antworten.
Gruß
Marc
Hallo,
hier noch einmal die Meldung welche ich bekomme:
***********************************************************
—————————————- Button interrupt -> Counter :1
> Counter > 1 :1
myblink – 0
myblink – 1
wall: –nobanner is available only for root
Broadcast message from openhabian@openhab (pts/0) (Mon Jan 6 20:38:19 2020):
doorbell pressed
> mqtt pub
/bin/sh: 1: /home/openhabian/: Permission denied
myblink – 0
> ——————- wait for next push…..
*****************************************************************
Gruß
Marc
PS: noch etwas anders, hast du den integrierten MQTT Broker in openHab dafür benutzt?
Hallo Marc,
Keine Ahnung wie das passiert ist, aber da ist ein Fehler im script.
ALT: subprocess.call(‘/home/pi/ -t house/Door_EG_ESP1/switchDoor/on true’, shell=True)
NEU: subprocess.call(‘/home/pi/mqttpub.sh -t house/Door_EG_ESP1/switchDoor/on true’, shell=True)
Ich verwende einen MagicMirror für die Anzeige, daher habe ich das alte Setup nicht in Verwendung.
Mit dem integriertem MQTT Broker hatte ich so meine Probleme. Lag aber wahrscheinlich an der Umstellung in OH auf die neue Version des MQTT plugins.
Der MQTT Broker läuft bei mir auf dem MagicMirror mit.
Das ist die alte Version in OH MQTT einzubinden:
mqtt=”<[mosquitto:house/Door_EG_ESP1/switchDoor/on:state:MAP(trueonfalseoff.map)" } Mittlerweile wird das aber anders gelöst. Gruß, Thomas