Return to Tricks with Google Home

Web interface to ipDatatel security alarm

As soon as I started connecting things to Google Home (either directly or through IFTTT), one of the first things I wanted to do was connect my security alarm to Google Home so that I could say “OK Google, goodnight” and get Google home to arm the alarm (and of course the corresponding “OK Google, Good-morning ” to disarm the security alarm.

Much to my frustration when I went to Google and IFTTT looking for a defined interface to my AlarmRelay.com alarm, I found nothing!  This started me digging some more, the alarm interface was an ipDatatel device and AlarmRelay was providing a web interface to the ipDatatel device via AlarmDealer.com.  Certainly in all this I could find a way to interface with the alarm and get tied into Google Home.

The AlarmDealer.com web interface to the alarm panel was the place to start.  There had to be something there I could use.  After some digging, it turned out that most of the AlarmDealer interface was simple java script using websockets.  The AlarmDealer web interface runs just like the alarm panel does by sending button presses just like you would on the alarm panel.  The only feedback mechanism is then the text that gets displayed on the LCD on the alarm panel.  So the interface is simply press some buttons, wait until the virtual ‘LCD’ has the correct text displayed, then press some more keys.

Roughly the code to arm the alarm then looks like:

Wait for the LCD to display “READY TO ARM”

‘press’ the buttons for the numeric 4 key pin

Wait for the LCD to display “Exit Delay in Progress” or “System Armed in Away Mode” or “Armed With No Entry Delay” to know that the alarm successfully armed.

The interface isn’t 100% foolproof, it looks like there are probably timing issues in the back-end.  Most likely because this is a websocket interface to another interface that actually communicates with the alarm over cell towers.  It appears the websocket interface is operating as expected, but it doesn’t always get the actual alarm data in time.    Ultimately I had to code in time delay and repeat on failure on some of the commands.

My whole back-end is built as PHP code on a web server, so the goal was to figure out how to run the AlarmDealer websocket interface from PHP rather than Java.  I found a PHP web socket implementation over here.

My PHP interface looks like this:

$client = Alarm_Login();
if($client->isConnected() == true) {
	if(Alarm_Arm($client)) {
		IFTTT_say("Alarm is armed");
	} else {
		error_log(basename(__FILE__)."[".__LINE__."]\t failed to arm alarm");
	}
} else {
	error_log(basename(__FILE__)."[".__LINE__."]\t failed to connect to alarm");
}

Alarm_Login() connects to the AlarmRelay web site using your credentials (which right now much be embedded in the PHP script, yeah should be passed as parameter or something, that’s for v2)

Once the websocket connection is made, then Alarm_Arm sends the key codes you would normally press on the local keypad to arm the alarm (again, hard-coded right now in the PHP script)

// Routines:
//	Alarm_Login() - log into the alarmdealer interface, has embedded path, username, and password
//		returns the WebSocket client
//  Alarm_Ping($client) - ping the alarm, it's a NOP to keep the link active
//		returns json decode of the return string
//  Alarm_Arm($client) - uses the embedded key code to arm the alarm.  verifies that the alarm
//              is in Arm-able state, enters the keys, then verifies it arms
//		returns false if the arm fails and true if it succeeds
//  Alarm_Disarm($client) - embedded key code, effectively same as Arm except looking for 
//              different start/stop conditions returns false on fail and true on success
//  Alarm_NoEntryDelay($client) - enters the keycode *9 to disable all zone delay, 
//              good for going to bed at night use before Alarm_Arm to disable the delay, 
//              returns true/false
//  Alarm_ArmAway($client) - keycode a to "arm in away mode", returns true/false
//  Alarm_ArmStay($client) - keycode s to "arm in stay mode", returns true/false
//  Alarm_WaitForLCD($client, $str, $cnt) - loops every 1 sec looking for $str to show 
//              up on the alarm LCD loops for a maximum of $cnt times.   If there are 
//              several potential LCD strings that are "OK" append them together with 
//              a | inbetween.  returns true if one of the specified strings shows up 
//              on the LCD within the iteration limits, false if none of them ever turn up.
//  AlarmLCD($client) - returns the current LCD string, Line 1 and Line 2 concatenated with 
//              a space between no verification happens so sometimes this returns blank, 
//              sometimes it even errors, so use Alarm_WaitForLCD to wait for specific strings.
//  AlarmStatus($client) - returns the full Alarm status, tries to ignore blank and null returns.  
//              returns the full status, LEDs and such (that's don't ever seem to get set!)

You can find my code for the php2ipdatatel interface here.