Here you go, this is based on my minimal skills and by hacking other peoples work, If I get the time I will try and package this into a plugin as much for the exercise of learning as anything else.
Initial Setup
I run a script that creates a dedicated web server in python that receives the three notifications that the DoorBird generates. This was based on the Roomba script that Karl posted that I modified for this purpose (many thanks to Karl). This was necessary as the doorbird API only supports simple authentication not digest and is my crude workaround. Note this allows the three events to be triggered without authentication, so be careful if you use any port forwarding and at your own risk. The triggering URL becomes, with your choice of port hard coded in the script.
Code: Select all
http://<indigo server ip address>:<port>/motion.html – when motion is triggered
http://<indigo server ip address>:<port>/doorbell.html – when the doorbell has been pushed
http://<indigo server ip address>:<port>/button.html – when the door open button has been pressed in the app
To set the notification URL on the DoorBird, you need to enter the following. (I needed to use Chrome as this failed in safari). I used one of the online url encoding tools to do the encoding for my specific URL’s
Code: Select all
http://<doorbird%20user>:<doorbird%20pass>@<doorbird%20ip>/bha-api/notification.cgi?url=<encoded%20url%20from%20above%20for%20the%20event>%20&user=&password=&event=<event%20%20-%20one%20of%20doorbell,%20motionsensor,%20dooropen>&subscribe=1
You can also check the configuration by opening the following url
http://<doorbird ip>/bha-api/notification.cgi?
I then created three action groups that run on the three events. The ID’s for the three groups need to be inserted into the forwarding server script.
The doorbell ring action group triggers the doorbell sound on a DLink Z Wave Siren (using raw Z wave commands). I also run a script that captures the doorbell image into a subdirectory of the user (under home as ~/doorbirdfwd/images). Each image is timestamped as well as maintaining a link to “currentdoorbellimage.jpg” that I expose on a control page. In my case I also do a Sonos group announcement of a doorbell sound mp3. After a 5 min delay another script runs that refreshes the 20 images that the doorbird stores of the last bell pushes (which I also show on a control page). The delay is to allow the intercom conversation to complete.
The motion action group is similar but this simply captures the current image (the doorbird API does not currently support the extraction of the motion triggered images even though the app does). This will be slightly delayed and will not be synchronised with the actual trigger of the motion detector but in my case it is close enough. It saves a timestamped image and maintains a symbolic link to “currentmotionimage.jpg” which is also shown on a control page.
I also created triggers to auto start the python web server on indigo startup as well as an action group to a modified version of Karls script that kills it if it has any problems.
I also have the RTSP stream from the doorbird recording into BlueIris and that works extremely well. I am sure it would also work with other tools like security spy, and that works with the url in the DoorBird API.
The delay from the doorbird for the Z wave siren is minimal, the Sonos announcement takes a second or two to work.
The API also has the ability to remotely trigger the doorlock relay that can be actuated by the doorbird itself simply by calling the appropriate URL.
DoorBird Fowarding Server Script – doorbirdserver.py
Code: Select all
# by Karl Wachs
# July 16
# modified for DoorBird by NeilK
##
import datetime, subprocess, os, time, urlparse
from BaseHTTPServer import BaseHTTPRequestHandler, HTTPServer
PORT = 8009 ## port number to be used by DoorBird on IndigoServer to GET url's defined in the API
# See DoorBird API at www.doorbird.com/api to set the URL to get based on the action for /motion.html , /doorbell.html , /button.html
class S(BaseHTTPRequestHandler):
def _set_headers(self):
self.send_response(200)
self.send_header('Content-type', 'text/html')
self.end_headers()
def do_GET(self):
self._set_headers()
self.wfile.write("<html><body><h1>Indigo DoorBird Forwarding</h1>"+str(self.path)+"</body>")
if self.path=="/motion.html":
indigo.server.log( "DoorBird sent motion command")
indigo.actionGroup.execute(1756507149) # "DoorBirdMotion" Action Group to run when DoorBird motion sensor triggered
if self.path=="/button.html":
indigo.server.log( "DoorBird sent Button command")
indigo.actionGroup.execute(1630756004) # "DoorBirdButton" Action Group to run when pressing the open button in the app
if self.path=="/doorbell.html":
indigo.server.log( "DoorBird sent doorbell command")
indigo.actionGroup.execute(1427726874) # "DoorBirdRing" Action Group to run on the DoorBird ring.
def do_HEAD(self):
self._set_headers()
def do_POST(self):
# Doesn't do anything with posted data
self._set_headers()
self.wfile.write("<html><body><h1>POST!</h1></body></html>")
def run(server_class=HTTPServer, handler_class=S, port=PORT):
server_address = ('', port)
httpd = server_class(server_address, handler_class)
indigo.server.log( "Starting DoorBird httpd..."+"Port...."+str(PORT))
httpd.serve_forever()
def killOldPgm(myPID,pgmToKill):
cmd= "ps -ef | grep "+pgmToKill+" | grep -v grep"
ret = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()[0]
lines=ret.split("\n")
for line in lines:
if len(line) < 10: continue
line=line.split()
pid=int(line[1])
if pid == int(myPID): continue
os.system("kill -9 "+str(pid))
indigo.server.log( "killed program: "+pgmToKill+" pid="+str(pid))
time.sleep(5)
if __name__ == "__main__":
myPID = str(os.getpid())
indigo.server.log(" PID of DoorBird server is:" +myPID )
print(myPID)
killOldPgm(myPID,"doorbirdserver.py")
# Create the server, binding on port xxx
#server = SocketServer.TCPServer((ipAddress, PORT), MyTCPHandler)
# Activate the server; this will keep running until you
# interrupt the program with Ctrl-C
#server.serve_forever()
run()
DoorBell Ring Image Capture Script (runs as part of the action group when the button is pushed), expects a directory under the indigo users home directory “~/doorbirdfwd/images”
Code: Select all
#!/usr/bin/python
userID="<doorbird user name>"
passWD="<doorbird password>"
ipNumber="<doorbird ip>"
import subprocess
import time
from os.path import expanduser
#homeDir=expanduser("~")
imagePath=expanduser("~")+"/doorbirdfwd/images"
timestr = time.strftime("%Y%m%d-%H%M%S")
ret = subprocess.Popen("curl -u "+userID+":"+passWD+" http://"+ipNumber+"/bha-api/history.cgi?index=1 -o "+imagePath+"/"+timestr+"doorbellimage"+".jpg", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
ret2 = subprocess.Popen("ln -f "+imagePath+"/"+timestr+"doorbellimage"+".jpg "+imagePath+"/currentdoorbellimage.jpg", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
indigo.server.log("DoorBird Image "+timestr+" Capture Done")
Motion Image Script (same as the doorbell version but uses a different URL to capture the current image). This is run by the action group from the motion trigger.
Code: Select all
#!/usr/bin/python
userID="<doorbird user name>"
passWD="<doorbird password>"
ipNumber="<doorbird ip>"
import subprocess
import time
from os.path import expanduser
imagePath=expanduser("~")+"/doorbirdfwd/images"
timestr = time.strftime("%Y%m%d-%H%M%S")
ret = subprocess.Popen("curl -u "+userID+":"+passWD+" http://"+ipNumber+"/bha-api/image.cgi -o "+imagePath+"/"+timestr+"motionimage"+".jpg", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
ret2 = subprocess.Popen("ln -f "+imagePath+"/"+timestr+"motionimage"+".jpg "+imagePath+"/currentmotionimage.jpg", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
indigo.server.log("DoorBird Image "+timestr+" Capture Done")
This script Captures all 20 doorbell images stored on the doorbird, run as a delayed action after the doorbell has rung in the doorbell action group. I haven’t tried but actually probably more elegant to get these directly from the control page using the url for each image, but I like having the local copy.
Code: Select all
#!/usr/bin/python
userID="<doorbird user name>"
passWD="<doorbird password>"
ipNumber="<doorbird ip>"
import subprocess
import time
from os.path import expanduser
imagePath=expanduser("~")+"/doorbirdfwd/images"
timestr = time.strftime("%Y%m%d-%H%M%S")
for x in range(1, 21):
ret = subprocess.Popen("curl -u "+userID+":"+passWD+" http://"+ipNumber+"/bha-api/history.cgi?index="+str(x)+" -o "+imagePath+"/historyimage"+str(x)+".jpg", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
#ret2 = subprocess.Popen("ln -f "+imagePath+"/"+timestr+"historyimage"+str(x)+".jpg "+imagePath+"/historyimage"+str(x)+".jpg", shell=True, stdout=subprocess.PIPE, stderr=subprocess.PIPE).communicate()
indigo.server.log("DoorBird Image "+str(x)+" Refresh Done")
indigo.server.log("DoorBird refresh "+timestr+" Done "+imagePath)
Finally the kill script that runs from an action group as embedded python. (again from Karl)
Code: Select all
import subprocess
pgmToKill="doorbirdserver.py"
cmd= "ps -ef | grep "+pgmToKill+" | grep -v grep"
ret = subprocess.Popen(cmd,shell=True,stdout=subprocess.PIPE,stderr=subprocess.PIPE).communicate()[0]
lines=ret.split("\n")
for line in lines:
if len(line) < 10: continue
line=line.split()
pid=int(line[1])
os.system("kill -9 "+str(pid))
indigo.server.log( "killed program: "+pgmToKill+" pid="+str(pid))
Anyway good luck and if it works great, and if I can help I will. I may have limited time online over the next week or so.
Thanks,
Neil