War irgendwann klar dass ich mir einen Raspberry Pi hole, fand auch (natürlich erst nach dem Kauf) einen Anwendungsfall >>> unsere Türklingel.
Funktion JETZT:
Klingel ist an ISDN-Anlage (ohne sonstige Funktion) angeschlossen. Telefon klingelt wenn jemand an der Tür leutet.
Funktion SOLL:
Jemand klingelt, Audio wird abgespielt, Bild wird vom Besucher gemacht, Upload per SFTP auf Webserver, Pushmessage auf iPhone/iPad/Android
Die Schaltung ist überschaubar. Verwende einen Pullup / Pulldown Resistor (muss noch testen was besser funktioniert, da ich gemerkt habe dass statische Aufladung den Eingang setzt). Eine LED für die Anzeige dass das Python-Script läuft und eine LED für Aktivierung der Doorbell-Funktion.
Hab es jetzt zum testen auf eine Steckplatine aufgebaut, funktioniert soweit. Werde es aber noch auf eine Platine löten, damit dass schön kompakt wird.
Zuerst wollte ich das ganze mit Mono programmieren, da ich Mono noch eine Chance geben wollte. Aber da es an einigen Ecken zu beginn schon zum knarzen begann, habe ich auf Python zurückgegriffen.
Finde Python keine schöne Sprache, aber mächtig. Naja, mein Anwendungsfall ist überschaubar, somit auch die paar Zeilen Programmcode.
Ich gehe hier nicht auf die Standard-Funktionen des Raspberrys ein, da es viele gute Anleitungen im Internet gibt.
Initialisierung
Alle benötigten Abhängigkeiten + Eventhandler (ausschalten der Status-LED) + Logging Methode. Wichtig ist hier auch noch das Audio auf 100% zu stellen. Da ich das Signal per Funk an Boxen weitergebe, ist hier wichtig dass der AUX Anschluss auf Maximum ist. Als letztes werden die IOs konfiguriert.
from time import gmtime, strftime, sleep
from datetime import datetime
import RPi.GPIO as GPIO
import os
import subprocess
import os.path
import httplib, urllib
import pysftp
import atexit
import traceback
import logging
import time
# On exit
def exit_handler():
GPIO.output(22, False)
atexit.register(exit_handler)
# Logging
logger = logging.getLogger('doorbell')
hdlr = logging.FileHandler('/home/pi/Desktop/doorbell/web/doorbell.txt')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)
# Start
print(strftime("%Y-%m-%d %H:%M:%S", gmtime()) + " Doorbell started")
logger.info("Doorbell started")
# Volume
cmdVolume='amixer set PCM -- 1000'
subprocess.call(cmdVolume, shell=True)
# Pins
GPIO.setmode(GPIO.BOARD)
GPIO.setup(15, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
GPIO.output(15, False)
GPIO.output(22, True)
GPIO.setup(11, GPIO.IN)
Alles eingepackt in eine While-Dauerschleife für ich folgenden Code nacheinander aus:
# Setup
now=strftime("%Y-%m-%d %H:%M:%S", gmtime())
filename=strftime("%Y-%m-%d_%H.%M.%S", gmtime()) + '.jpg'
print(now + " Button pressed")
logger.info("Button pressed")
GPIO.output( 15, True)
Hier wird einfach nur geloggt, wenn der Button gedrückt wurde (Datum, Uhrzeit) und zusätzlich die LED für den Programmablauf eingeschaltet. Ich speichere mir gleich das Datum in eine Variable um es später für die Bilddatei zu verwenden.
# Audio
print("--> Audio")
logger.info("--> Audio")
subprocess.Popen(['aplay', '/home/pi/Desktop/doorbell/ringtone.wav'])
Nun spielen wir das Audiofile (in meinem Fall eine WAV-Datei) ab. Hier ist die Besonderheit dass es parallel zum Ablauf des Scripts passiert. Dass heißt hier wird ein separater Thread gestartet. Achja, TIP: nehmt am besten einen nervigen Sound (habe mich für Super Mario 1 Theme entschieden) dass kommt in der Frauenwelt sehr gut an :^)
# Camera
print("--> Camera")
logger.info("--> Camera")
cmdCam='raspistill -o ' + '/home/pi/Desktop/doorbell/web/photos/' + filename
subprocess.call(cmdCam, shell=True)
Der Kamera Aufruf ist denkbar einfach. Hier habe ich versucht auch im separaten Thread das Bild zu speichern, hatte aber bei jedem 10. Bild ein Problem, welches ich (noch) nicht nachvollziehen konnte. Ihr seht schon dass sich die Bilder in einem Ordner web befinden. Ich habe mich im Nachhinein dafür entschieden einen Webserver auf dem Pi laufen zu lassen. Dadurch hab ich mehr Kontrolle und kann von außen auch z.B. einen Livestream der Cam anschauen sowie die Logdatei oder einfach per SSH verbinden.
Wie oben erwähnt habe ich angedacht per SFTP das Bild auf meinen Webserver bei Uberspace zu laden. Habe ich auch getestet und das wäre der Code dafür (auskommentiert):
# Upload Foto
#print("--> Upload")
#logger.info("--> Upload")
#srv = pysftp.Connection(host="MeinServer.de", username="MyUsername",
# password="MyPassword", log="True")
#srv.chdir("/Mein/Ordner/Mit/Photos/Auf/Server")
#srv.put('/Mein/Ordner/Mit/Photos/Lokal/' + filename)
#srv.close()
Nun zum Teil der mir am meisten Spaß gemacht hat. Funktion ist genial und einfach zu implementieren. Der Dienst nennt sich Pushover, ist für meine Anwendung kostenlos da ich unter 7500 Pushes im Monat bleibe (außer ich bekomme sehr viel Besucher). Die API ist sehr gut dokumentiert und es gibt Beispiele für viele Sprachen.
# Pushover
print("--> Pushover")
logger.info("--> Pushover")
conn = httplib.HTTPSConnection("api.pushover.net:443")
conn.request("POST", "/1/messages.json",
urllib.urlencode({
"token": "app-token",
"user": "user-token",
"title": "Doorbell",
"message": "KNOCK KNOCK",
"url": "http://irgendwo.de/photos/" + filename,
"url_title": "Image",
}),
{ "Content-type": "application/x-www-form-urlencoded" })
conn.getresponse()
Das ganze wird bei mir wie erwähnt auf Android, iPad und iPhone gepusht und dauert ca. 1-3 Sekunden nach drücken der Klingel, was mehr als ausreicht.
Lockscreen > Pushover App Übersicht > Detail
Mit einem Tap auf Image wird mir dann auch das Bild des Besuchers angezeigt. Die Farben sind Tagsüber OK. In der nacht wird das ganze schwarz/weiß, aber die Qualität und Erkennbarkeit ist durchgehend gut.
Hier sei erwähnt dass ich nicht die Standard Raspberry Pi Camera gekauft habe sondern die IR-Version.
Zusätzlich habe ich mir einen HTTP-Livestream gebaut, damit ich per iPhone/iPad die Kamera live betrachten kann (diente nur zum einstellen).
Anbei das ganze Script:
from time import gmtime, strftime, sleep
from datetime import datetime
import RPi.GPIO as GPIO
import os
import subprocess
import os.path
import httplib, urllib
import pysftp
import atexit
import traceback
import logging
import time
# On exit
def exit_handler():
GPIO.output(22, False)
atexit.register(exit_handler)
# Logging
logger = logging.getLogger('doorbell')
hdlr = logging.FileHandler('/home/pi/Desktop/doorbell/web/doorbell.txt')
formatter = logging.Formatter('%(asctime)s %(levelname)s %(message)s')
hdlr.setFormatter(formatter)
logger.addHandler(hdlr)
logger.setLevel(logging.INFO)
# Start
print(strftime("%Y-%m-%d %H:%M:%S", gmtime()) + " Doorbell started")
logger.info("Doorbell started")
# Volume
cmdVolume='amixer set PCM -- 1000'
subprocess.call(cmdVolume, shell=True)
# Pins
GPIO.setmode(GPIO.BOARD)
GPIO.setup(15, GPIO.OUT)
GPIO.setup(22, GPIO.OUT)
GPIO.output(15, False)
GPIO.output(22, True)
GPIO.setup(11, GPIO.IN)
# Loop
while 1:
if GPIO.input(11):
try:
# Setup
now=strftime("%Y-%m-%d %H:%M:%S", gmtime())
filename=strftime("%Y-%m-%d_%H.%M.%S", gmtime()) + '.jpg'
print(now + " Button pressed")
logger.info("Button pressed")
GPIO.output( 15, True)
# Audio
print("--> Audio")
logger.info("--> Audio")
subprocess.Popen(['aplay', '/home/pi/Desktop/doorbell/ringtone.wav'])
# Camera
print("--> Camera")
logger.info("--> Camera")
cmdCam='raspistill -o ' + '/home/pi/Desktop/doorbell/web/photos/' + filename
subprocess.call(cmdCam, shell=True)
# Pushover
print("--> Pushover")
logger.info("--> Pushover")
conn = httplib.HTTPSConnection("api.pushover.net:443")
conn.request("POST", "/1/messages.json",
urllib.urlencode({
"token": "app-token",
"user": "user-token",
"title": "Doorbell",
"message": "KNOCK KNOCK",
"url": "http://irgendwo.de/photos/" + filename,
"url_title": "Image",
}),
{ "Content-type": "application/x-www-form-urlencoded" })
conn.getresponse()
# Finished
print("--> Finished")
logger.info("--> Finished")
time.sleep(2)
except Exception, e:
traceback.print_exc()
logging.exception("!!!")
else:
GPIO.output( 15, False)
Hi,
erstmal muss ich sagen gute Anleitung! Will mich nun auch daran versuchen unsere Klingel per Raspi zu “erweitern”. Leider habe ich mit python noch nicht viel am Hut… Wenn ich den Skyipt nehem und dies dann ausführen möchte bekomme ich folgenden fehler:
pi@raspberrypi:~$ sudo python doorbell.py
Traceback (most recent call last):
File “doorbell.py”, line 8, in
import pysftp
ImportError: No module named pysftp
Ach und ist es auch möglich eine IP Cam einzubinden? Wir haben eine und ich kann diese auch über eine URL http://192.168.178.25/snapshot.cgi mir ein Bild anzeigen lassen…
@pysftp: mit PIP kannst du es schnell und einfach installieren (das kannst du über apt-get beziehen). Hier noch eine kleine Anleitung:
http://www.pythonforbeginners.com/modules-in-python/python-secure-ftp-module
Danach müsste es compilieren.
@IP-Cam: Normal schon, wo werden denn die Daten dann gespeichert? Kenne es so dass du den Speicherort für das Bild angeben kannst und es auch ein Network-Share sein kann… Somit einfach auf dem Pi einen “Freigabe-Ordner” einstellen und dort speichern.
Hallo,
Ich habe ihre Webseite gefunden da ich auch ein RaspiDoor Projekt gestartet habe.
Ich habe mir mal ihr script kopiert und habe dazu einige fragen.
Da ich zzt NUR den Klingelknopf überwachen will, benötige ich ja nur Pin11 (GPIO17), kann ich im Script die anderen Ausdokumentieren ? ( bin Elektroniker kein Programmierer :( )
z.b. So # Pins
GPIO.setmode(GPIO.BOARD)
# GPIO.setup(15, GPIO.OUT)
# GPIO.setup(22, GPIO.OUT)
# GPIO.output(15, False)
# GPIO.output(22, True)
GPIO.setup(11, GPIO.IN) # =gpio 17
ebenso für die Audioausgabe und Webcam funktion ? da ich diese ( noch nicht ) nutzen möchte, ggf. später mal.
Ist der Bereich für das Senden der Nachricht mit ihrem, da Script der API “Pushover” mit einer andern einfach zu tauschen ? ich sag mal ja, ich würde gern “Puchbullet” nuzen
dazu, unter welchen Namen muss ich das Script speichern und Wohin damit es 100% funktioniert
Hardware Technisch funktioniert meine Schaltung.
Wäre über eine Mail mit Antworten von ihnen sehr dankbar
MFG
Leif
Ich verstehe bei “app-token, user: user-token” in Pushover nicht, welches app-token man hier einsetzt (user-token ist klar – das dürfte mein token sein)?
User-Token: Startseite auf Pushover
App-Token: Startseite > Applikation (neu anlegen) > API Token/Key
@Leif: kannst weglassen sind nur die Status-LEDs
Tausch des pushes müsste klappen… habs auch schon mit Email probiert.
Hallo zusammen, ich habe mir jetzt auch endlich einen RasPi besorgt, da es mich nervt die Klingel nicht im ganzen Haus zu hören. Genau so etwas wie dieses Projekt habe ich als Vorlage für mein erstes Projekt gesucht, da ich anfangs nicht viel Schnickschnack will. Sehe ich das in der Schaltung richtig, dass die Spannung des Pi über den Klingeltaster geschleift wird, um den Eingang zu schalten? Da ich meinen bestehenden Türgong behalten möchte, müsste ich diesen doch über eine Schaltung parallel zum Eingang des Pi schalten können, bzw. ist der Pi auch in der Lage einen potentialfreien Kontakt am Eingang zu erkennen? Mein Pi ist noch nicht bei mir eingetroffen, daher die ein oder andere vielleicht überflüssige Frage ;)
Merci und viele Grüße
Sascha
Hallo Sascha,
schau dir mal den zweiten Teil an… hier schalte ich nur die Masse: https://suplanus.de/doorbell-stoerungen-umgehen/
Wenn du einen potenzialfreien Kontakt hast, geht das natürlich :)
Hallo Johann,
vielen Dank für die schnelle Reaktion, die Pause habe ich direkt übernommen und etwas mit der Zeit gespielt. Jedoch habe ich noch ein anderes Problem, bei dem mir auch Google noch nicht helfen konnte. Du hast das ganze doch in Python 3 geschrieben? Ich habe mir die Teile genommen, die ich brauche und entsprechend angepasst, allerdings bekomme ich die Meldung, dass es das Modul “httplib” nicht gibt. Scheinbar gibt es das in Python2, aber das muss doch für 3 irgendwie funktionieren. Ich habe testweise httplib2 für Python 3 installiert, aber natürlich gibt es da andere Argumente. Kannst du mir einen Tipp geben, wie ich das in den Griff bekomme?
Wurde wohl unbenannt, siehe hier: https://docs.python.org/2.6/library/httplib.html