I'm responsible for a commercial buildings that, as you would expect, have monitored alarms, access control and such like.

However, commercial alarm monitoring is horrendously expensive, and most of them are stuck in the dark ages; I want to be able to monitor the condition of my alarm remotely, and get notifications in a useful way.

Piece of cake pi

My usual solution to these sorts of problems - Raspberry Pi. I've found use for this £30 mini Linux box in lighting control, information displays, presentations, video servers, phone systems and more...

Connecting to the alarm

Most alarms have a contact for an external 'dialler', traditionally a box that would dial out to a predefined number (or monitoring centre) and notify them - you need to connect this to the Pi, in my case it's a much higher voltage than the 3.3V the Pi would expect on GPIO, so a simple relay is used across to GPIO pins on the Pi.

Yes, I am well aware there are better ways and circuits to do this, but at the time we had a box of small relays from the access control system, and no spare components and breadboards to make a 'proper' interface between them!

Code on the Pi

Basically, all we need to do is generate an HTTP request when the relay is triggered, this could then go to a service like Pushover or to your own HTTP server.

We also want to generate an alert if the connection fails for any reason (this is better than a traditional dialler, as if the phone line is cut it couldn't make a call) – this relies on some server-side code which behaves much like a 'dead man's switch' and generates an alarm if a heartbeat is not received every 10s.

The actual code has a bit more to it but is effectively the below

import time
import pprint
import json
import signal, os, sys
import RPi.GPIO as GPIO
import httplib, urllib

## initialise
GPIO.setmode(GPIO.BOARD)
GPIO.setup(8, GPIO.IN, pull_up_down=GPIO.PUD_UP)
GPIO.setwarnings(True)
value = GPIO.input(8)

## called when the state changes
def state_change(channel):
    time.sleep(0.5)
    value = GPIO.input(channel)
    
    ## alarm has been activated
    if value == 0:
       print("ALARM ACTIVATED")
       try:
          conn = httplib.HTTPSConnection("example.com:443")
          conn.request("POST", "/alarm",
             urllib.urlencode({
               "message": "ALARM ACTIVATION",
             }), { "Content-type": "application/x-www-form-urlencoded" })
       except Exception:
             sys.exc_clear()

GPIO.add_event_detect(8, GPIO.BOTH, callback=state_change)

## heartbeat loop
while True:
    time.sleep(10)
    value = GPIO.input(8)
    try:
       conn = httplib.HTTPSConnection("example.com:443")
       conn.request("POST", "/alarm_heartbeat/?s="+str(value),
             urllib.urlencode({
               "s": value, "timestamp": int(time.time()),
             }), { "Content-type": "application/x-www-form-urlencoded" })
    except Exception:
       sys.exc_clear()

Server-side Implementation

You can handle this request in whatever way you like, I'm not going to share my implementation here but effectively;

  • If the alarm is activated, notify several people by several annoying means;
  • If there are missing heartbeats, notify in a more subtle way at first, if more than two go missing - notify as above.
  • If any of the heartbeats have the wrong signature - alarm immediately (in the off-chance someone figures out how to spoof them)

It also triggers a backup of the most recent ZoneMinder events, and includes them with the messages above.

The point is you can do virtually anything with it, and it's every bit as robust as the 'proper' solution.

Commercial Monitoring

If any monitoring company can send me a push notification to my phone, send me photos from the CCTV, alert me by API driven clocks in my home etc... then I'll consider it until then I like the flexibility the Raspberry Pi give me :)

Ideal Solutions

Whilst there are numerous home security products (e.g. Canary) that have apps and cloud-based services (which I'm not 100% confident on!) I'm surprised no-one yet makes a simple replacement for a commercial alarm panel that has a network interface, API and ideally a nicer way of configuring it than a completely unintuitive two line LCD and numeric keypad (or worse, a series of coloured LEDs!)