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
[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
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