My apartment complex currently has a phone-based doorbell system to let visitors enter the complex. Visitors find the resident’s name on a callbox, and then call the resident. The resident verifies friend of foe, and can press 9 to open the door.

I didn’t want my visitors to have to rely on me being able to answer the phone in order to enter. Especially if I have them “follow me in”, there is no reception in the parking garage, so they would be stuck in the garage for a few minutes. Or, if I did not hear my phone ring, I still want friends to be able to come directly to my apartment door. I also thought it would just be pretty cool and nerdy to have it automated.

After doing some reading online about various setups, I decided to go with Asterisk and combine it with a small Rails application that would send notifications using Growl and Prowl. My goal was that whenever a guest dialed my extension on the gate, all my computers (including my media center) would show a notification on screen alerting me of their entry. As a bonus, it also would send a notification to my iPhone so that even if I wasn’t at home, I would know if someone was over.

Setting up Asterisk

The first step with Asterisk was routing a phone number to the asterisk server. Since I did not have a landline in my apartment, I decided to get a SIP endpoint that I could connect to asterisk. After looking around online, I decided to go with sipgate. I was able to get a free number that would take inbound calls and could route them to asterisk. Perfect.

To connect with sipgate, you need to tell asterisk how it should connect to your VoIP provider. You need to edit (or create) a sip.conf folder that will let you configure any SIP settings. Below is the file from my server.

; sip.conf
;
; SipGate Info
; SIPGATE_USER - your sipgate username
; SIPGATE_PASS - your sipgate secret/password

[general]
tcpenable=no
srvlookup=yes
register=> SIPGATE_USER:SIPGATE_PASS@sipgate/SIPGATE_USER

[sipgate]
type=peer
secret=SIPGATE_PASS
insecure=invite
username=SIPGATE_USER
defaultuser=SIPGATE_USER
fromuser=SIPGATE_USER
context=sipgate_in
fromdomain=sipgate.com
host=sipgate.com
outboundproxy=proxy.live.sipgate.com
qualify=yes
disallow=all
allow=ulaw
dtmfmode=rfc2833

Next, I needed to setup a route for sipgate. I decided that I wanted to route all inbound calls from sipgate directly to the door program. You can add this configuration to the bottom of your extensions.conf file. In sip.conf I configured asterisk to use [sipgate_in] as the “context” for any calls from sipgate. (You can see above the context= setting).

The block below configures the actions that should be taken should a call be in the sipgate_in context. I decided that I wanted all calls to be routed directly to my extension called door-access. After opening the door, asterisk should immediately hang up the call.

[sipgate_in]
exten => SIPGATE_USER,1,Goto(door-access,s,1)
exten => SIPGATE_USER,n,Hangup

Next, you need to configure the door-access extension to perform the required actions to open the door. What I wanted the system to do was:

  1. Answer the call
  2. Say “Access Granted”
  3. Send a growl notification
  4. “Press” 9 to open the door

So I added the following script to my extensions.conf file:

[door-access]
exten => s,1,Answer(500)
exten => s,n,Playback(silence/1)
exten => s,n,Playback(access-granted)
exten => s,n,System(curl -s -d "callerid=${CALLERID(num)}" http://doorbell.mitchdempsey.net/asterisk >/dev/null)
exten => s,n,SendDTMF(99999)
exten => s,n,Hangup

A few things I added were the Playback(silence/1) line. This plays a second of silence, which allows the other system to enable the speakers or whatever. I found after testing that if I didn’t have that line, then the “Access Granted” phrase would be cut off in the beginning.

The System() line is what submits a POST request to the rails application. It also passes the caller’s phone number. I realized that each door at my apartment had a different telephone number, so I could easily tell exactly which door someone entered from just based on the phone number.

Rails Application

The Rails application side was relatively simple. I have a single page that accepts a POST request containing the callerid. It does a simple lookup to find out which door the specified number corresponds to. Once it has determined the location of the door, it fires off a Growl notification to all computers in the apartment, and then submits a notification to Prowl, which is then sent to my iPhone.

# POST /asterisk
def asterisk
  # the phone number of the door
  callerid = params[:callerid]
    
  # Search the gate code
  @gate_phone = GatePhone.find_or_create_by_phone_number(callerid)
  
  # Submit a request to Prowl
  Prowler.notify "Gate Entry", "Visitor entered from #{@gate_phone.location}"
  
  # Notify all the computers over Growl
  NotifyGrowlHost.where(:gate_entry => true).each do |growl_host|
    g = Growl.new growl_host.host, "mr-universe", ["gate-entry"], nil, growl_host.password
    g.notify "gate-entry", "Gate Entry Notification", "Visitor entered via #{@gate_phone.location}"  
  end
end

That’s about it! Not very complicated, but pretty useful.