SmartThings Community

Yale Smartphone Alarm System integration

yale
dth_security
project_security

(Daniel McDougall) #1

Hello all,

IM new to coding and new to smartthings and groovy.

I’ve just got smart things and I wondered if I could integrate it with my existing security system.
Its a wireless smartphone controlled alarm system.

There is no API for it. but it can be accessed via web page

I’m thinking to add these I will have to write something that periodically fetches the state of the devices.

https://www.yalehomesystem.co.uk

and the status of individual sensors can be seen here

MY thoughts to integrate initially went to selenium to arm and disarm but im not sure if that’s possible from within Smart things.

and even if I could get that working I don’t know how Id capture the status’ of the sensors or if I could.

So im looking for advice and similar projects if they exist so I can work through this.


UK Alarm / Security System that is ST Compatible--advice needed (2018 build)
Pre Sale questions
(Daniel McDougall) #2

So browsing the forum I think the thread comes closes to what I’m after and it’s done in a similar way to I was thinking.

New App: Integration with HoneyWell TotalConnect Alarm & Monitoring System


(Daniel McDougall) #3

Ahh So my journey has got further than i would have expected.
I can successfully log in and i can return the state of the devices.

What im struggling to do is Parse (not sure if right word) into something i can play with.

this is what the response looks like

{“result”:“1”,“message”:[{“area”:“1”,“no”:“1”,“rf”:null,“address”:“RF:a6a40210”,“type”:“device_type.door_contact”,“attr”:“device_attribute.burglar”,“latch”:“1”,“name”:“Bay centre window”,“status1”:"",“status2”:null,“status_switch”:null,“status_power”:null,“status_temp”:null,“status_humi”:null,“status_dim_level”:null,“status_lux”:"",“status_hue”:null,“status_saturation”:null,“rssi”:“8”,“scene_trigger”:“0”,“pss_group”:“00”,“status_total_energy”:"",“device_id2”:"",“bypass”:“0”,“always_on”:“0”,“normal_open”:“0”,“reserved_bit0”:“1”,“reserved_bit3”:“0”,“reserved_bit4”:“0”,“device_chime”:“1”},{“area”:“1”,“no”:“9”,“rf”:null,“address”:“RF:df220210”,“type”:“device_type.door_contact”,“attr”:“device_attribute.home_omit”,“latch”:“1”,“name”:“Master bed R”,“status1”:“device_status.dc_open”,“status2”:null,“status_switch”:null,“status_power”:null,“status_temp”:null,“status_humi”:null,“status_dim_level”:null,“status_lux”:"",“status_hue”:null,“status_saturation”:null,“rssi”:“4”,“scene_trigger”:“0”,“pss_group”:“00”,“status_total_energy”:"",“device_id2”:"",“bypass”:“0”,“always_on”:“0”,“normal_open”:“0”,“reserved_bit0”:“1”,“reserved_bit3”:“0”,“reserved_bit4”:“0”,“device_chime”:“1”}]}

So that means all the details about a device are in one line rather than cascading.

if anyone knows what to do id be grateful.
still wrapping my head around it all.

below is where i am up to with everything else btw.

definition(
name: "Post Tester",
namespace: "dmc",
author: "dmc",
description: "Test Post to yaler",
category: "My Apps",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png"
)

preferences {
section("Monitor This Switch") {	
         input "theSwitch", "capability.switch", title: "Which switch?", multiple: false
  } 
}
def installed() {
log.debug "Installed with settings: ${settings}"
initialize()
}
def updated() {
log.debug "Updated with settings: ${settings}"    
initialize()
}
def initialize() {
subscribe(theSwitch,"switch",poster)
}

 def poster(evt){
def token ="i18next=en-US; PHPSESSID=dj48drc5c62hln2vb6; language=en-US; is_remember=1"
def url1 = "https://www.yalehomesystem.co.uk/homeportal/api/login/check_login/"
def param = [
	uri: url1,
    body: [id:thisisaUserName,password:"AVeryPasswordyPassword"]]

def url2 = "https://www.yalehomesystem.co.uk/homeportal/api/panel/get_devices/"             
	def params2 = [
	uri: url2,
    body: [id:thisisaUserName,password:"AVeryPasswordyPassword"],
	headers: ['Cookie' : "${token}"]
	         ]

try {
	httpPost(param)     
    { resp1 ->
    	resp1.headers.'Set-Cookie'.split(";")?.getAt(0)
		resp1.data.each {
			log.debug "Header ${it.value} "
            }
  		log.debug "token"
        }

	httpPost(params2) 
     { resp2 ->
    	resp2.headers.each {
			log.debug "Header ${it.name} : ${it.value}"
           }
           // this is just for me so i can see that its returing something
           resp2.data.message.each{ log.debug "${it.no.value}:${it.name.value}:${it.status1.value}"}
          
          
          // this is the heart of it i want only the  ..message.name.value   where the message.no.value is 1
          resp2.data.message.each {if(it.no == "1"){
		   log.debug "${resp2.data.message.name.value}"}
            					 }
       }

			

} catch (e) {
	log.debug "something went wrong: $e"
}
}

(Daniel McDougall) #4

Additionally i am having to hardcode in a cookie from a different session

presently i sign in on a browser take the cookie from that session and literally paste it into this.

if i try and capture the cookie here it has literally never worked.


Z-Wave and UK Alarm/Security systems
(Daniel McDougall) #5

HI Guys, just to let you know i have finished writing a device handler for the alarm.

It arms disarms and sets to home. it works with smartthings routines.

Next on my list is to write something that takes that status of the sensors and allows me to use those in routines also.

I’ll be posting the code later on this evening but seen as i’m the only one in the world with this system it seems it will just be for the curious.

next step after that is to see if i can do the opposite and use wave sensors to trigger the yale system.


(Daniel McDougall) #6
/**
*  Version 0.1 - First version arms/home/disarm the alarm
*/
preferences {

input("userName", "text", title: "Username", description: "Your username for Yale Home System")
input("password", "password", title: "Password", description: "Your Password for Yale Home System")


}
metadata {
definition (name: "YALE ALARM SWITCH", namespace: "Tapion1ives", author: "Tapion1ives") {

capability "Refresh"
capability "Switch"
attribute "status", "string"
capability "lock"
}


// UI tile definitions
tiles {
	standardTile("toggle", "device.status", width: 2, height: 2) {
		state("unknown", label:'${name}', action:"device.refresh", icon:"st.Office.office9", backgroundColor:"#ffa81e")
		state("Armed Stay", label:'${name}', action:"switch.off", icon:"st.Home.home4", backgroundColor:"#79b821", nextState:"Disarmed")
		state("Disarmed", label:'${name}', action:"lock.lock", icon:"st.Home.home2", backgroundColor:"#a8a8a8", nextState:"Armed Away")
		state("Armed Away", label:'${name}', action:"switch.off", icon:"st.Home.home3", backgroundColor:"#79b821", nextState:"Disarmed")
        state("Arming", label:'${name}', icon:"st.Home.home4", backgroundColor:"#ffa81e")
		state("Disarming", label:'${name}', icon:"st.Home.home2", backgroundColor:"#ffa81e")
     	}
	standardTile("statusstay", "device.status", inactiveLabel: false, decoration: "flat") {
		state "default", label:'Arm Stay', action:"switch.on", icon:"st.Home.home4"
	}
	standardTile("statusaway", "device.status", inactiveLabel: false, decoration: "flat") {
		state "default", label:'Arm Away', action:"lock.lock", icon:"st.Home.home3"
	}
	standardTile("statusdisarm", "device.status", inactiveLabel: false, decoration: "flat") {
		state "default", label:'Disarm', action:"switch.off", icon:"st.Home.home2"
	}
	standardTile("refresh", "device.status", inactiveLabel: false, decoration: "flat") {
		state "default", label:'', action:"refresh.refresh", icon:"st.secondary.refresh"
	}

	main "toggle"
	details(["toggle", "statusaway", "statusstay", "statusdisarm", "refresh"])
}
}



 // Login Function. Returns cookie for rest of the functions
 def login(token) {
log.debug "Executed login"
def paramsLogin = [
	uri: "https://www.yalehomesystem.co.uk/homeportal/api/login/check_login/",
	body: [id:settings.userName , password: settings.password]
]
httpPost(paramsLogin) { responseLogin ->
	token = responseLogin.headers?.'Set-Cookie'?.split(";")?.getAt(0)
} 
return token
 } // Returns cookie as token		

 // Logout Function. Called after every mutational command. Ensures the current user is always       logged Out.
def logout(token) {
//log.debug "During logout - ${token}"
def paramsLogout = [
	uri: "https://www.yalehomesystem.co.uk/homeportal/api/logout/",
	headers: ['Cookie' : "${token}"]
]
httpPost(paramsLogout) { responseLogout ->
	log.debug "Smart Things has successfully logged out"
}  
 }

//Should get the panel mode so we know what its current status is

def refresh(YaleAlarmState) {		   
def token = login(token)
def getPanelMetaDataAndFullStatus = [
	uri: "https://www.yalehomesystem.co.uk/homeportal/api/panel/get_panel_mode",
	body: [id:settings.userName , password: settings.password],
	headers: ['Cookie' : "${token}"]
]
httpPost(getPanelMetaDataAndFullStatus) {	response -> 
    YaleAlarmState = response.data.message
    }
 // Gets Information
if (YaleAlarmState.mode.contains("arm")) {
	log.debug "Alarm is ${YaleAlarmState.mode}ed"
    sendEvent(name: "status", value: "Armed Away", displayed: "true", description: "Refresh: Alarm is Armed Away")
} else if (YaleAlarmState.mode.contains("home")) {
	log.debug "Alarm is set to ${YaleAlarmState.mode}"
   sendEvent(name: "status", value: "Armed Stay", displayed: "true", description: "Refresh: Alarm is Armed Stay") 
} else if (YaleAlarmState.mode.contains("disarm")) {
	log.debug "Alarm is ${YaleAlarmState.mode}ed"
	sendEvent(name: "status", value: "Disarmed", displayed: "true", description: "Refresh: Alarm is Disarmed") 
 } 
  logout(token)
sendEvent(name: "refresh", value: "true", displayed: "true", description: "Refresh Successful") 
  return YaleAlarmState
}

// Arm Function. Performs arming function
def armAway() {		   
def token = login(token)
def paramsArm = [
	uri: "https://www.yalehomesystem.co.uk/homeportal/api/panel/set_panel_mode?area=1&mode=arm",
	body: [id:settings.userName , password: settings.password],
	headers: ['Cookie' : "${token}"]
]
//httpPost(paramsArm) // Arming Function in away mode
def metaData = refresh(YaleAlarmState) // Get AlarmCode
  if (metaData.mode.contains("arm")) {
	log.debug "Status is: Already Armed Away"
	sendEvent(name: "status", value: "Armed Away", displayed: "true", description: "Refresh: Alarm is Armed Away") 
} else if (metaData.mode.contains("home")) {
	log.debug "Status is: Armed Stay - Please Disarm First"
	sendEvent(name: "status", value: "Armed Stay", displayed: "true", description: "Refresh: Alarm is Armed Stay") 
} else {
	log.debug "Status is: Arming ${metaData.mode}"
    httpPost(paramsArm) // Arming Function in away mode
}


 }

def armStay() {		   
def token = login(token)
def paramsArm = [
	uri: "https://www.yalehomesystem.co.uk/homeportal/api/panel/set_panel_mode?area=1&mode=home",
	body: [id:settings.userName , password: settings.password],
	headers: ['Cookie' : "${token}"]
]
//httpPost(paramsArm) // Arming function in stay mode
def metaData = refresh(YaleAlarmState) // Gets AlarmCode
  if (metaData.mode.contains("arm")) {
	log.debug "Status is: Already Armed Away"
	sendEvent(name: "status", value: "Armed Away", displayed: "true", description: "Refresh: Alarm is Armed Away") 
} else if (metaData.mode.contains("home")) {
	log.debug "Status is: Armed Stay - Please Disarm First"
	sendEvent(name: "status", value: "Armed Stay", displayed: "true", description: "Refresh: Alarm is Armed Stay") 
} else {
	log.debug "Status is: Arming"
    httpPost(paramsArm) // Arming function in stay mode
  }

   }

 def disarm() {
def token = login(token)
def paramsDisarm = [
	uri: "https://www.yalehomesystem.co.uk/homeportal/api/panel/set_panel_mode?area=1&mode=disarm",
			body: [id:settings.userName , password: settings.password],
	headers: ['Cookie' : "${token}"]
]
//httpPost(paramsDisarm)	
def metaData = refresh(YaleAlarmState) // Gets AlarmCode
if (metaData.mode.contains("disarm")) {
	log.debug "Status is: Already Disarmed"
	sendEvent(name: "status", value: "Disarmed", displayed: "true", description: "Refresh: Alarm is Disarmed") 
} else {
	log.debug "Status is: Disarming"
	httpPost(paramsDisarm)	
} 

}


  // parse events into attributes
 def parse(String description) {
   log.debug "Parsing '${description}'"
 }

// handle commands
def lock() {
log.debug "Executing 'Arm Stay'"
armStay()
sendEvent(name: "lock", value: "lock", displayed: "true", description: "Arming Stay") 
sendEvent(name: "status", value: "Arming", displayed: "true", description: "Updating Status: Arming System")
runIn(10,refresh)
  }

def unlock() {
log.debug "Executing 'Disarm'"
disarm()
sendEvent(name: "unlock", value: "unlock", displayed: "true", description: "Disarming") 
sendEvent(name: "status", value: "Disarming", displayed: "true", description: "Updating Status: Disarming System") 
runIn(10,refresh)
   }

 def on() {
log.debug "Executing 'Arm Away'"
armAway()
sendEvent(name: "switch", value: "on", displayed: "true", description: "Arming Away") 
sendEvent(name: "status", value: "Arming", displayed: "true", description: "Updating Status: Arming System") 
runIn(10,refresh)
  }

  def off() {
log.debug "Executing 'Disarm'"
disarm()
sendEvent(name: "switch", value: "off", displayed: "true", description: "Disarming") 
sendEvent(name: "status", value: "Disarmed", displayed: "true", description: "Updating Status: Disarming System") 
runIn(10,refresh)
 }


(Daniel McDougall) #7

I used @QCCowboy s Device handler for total connect as my basis for this.so much thanks to them.


(John Lockwood) #8

@tapion1ives

Thanks for creating this. I am thanks to it currently planning to buy a Yale alarm and use this.

Did you get anywhere with supporting the Yale PIR cameras?

Also, for your next challenge :slight_smile: how about adding IFTTT support?


(Daniel McDougall) #9

IFTTT should be compatible already. you get an email when the alarm changes state so you can use that to fire triggers in IFTTT and once the sensors are in Smartthings then again IFTTT is already there.


(John Lockwood) #10

@tapion1ives

I have not yet played with IFTTT I am still in the very early stages of getting home automation products for my house. I was not sure whether IFTTT had to directly talk to the device. If I understand you correctly you are saying it can talk to a Smartthings entry representing the (Yale) device and therefore there is no need to do anything more.

Since you already have all the items, could you try a few simple IFTTT tests, e.g. ‘If’ motion detected by Yale Sensor A, ‘then’ do send message.


(Daniel McDougall) #11

Yeah thats spot on.

Ive not got the individual sensors integrated yet.
thats what im doing next. but once ive done that it should work exactly as you’ve described.

Right now we can just arm/disarm the system.

the photoPIR stuff should be really really easy to be honest. but i dont know about the video pir i think thats out of my reach (also i dont own one)


(Daniel McDougall) #12

added photos of the device in smartthings under the code


(Daniel McDougall) #13

I have the door and window contact sensors working. At the minute i have to manually refresh the statuses. Need to find a way to automate this.


Yale Conexis l1
(Daniel McDougall) #14

So it seems i need to create a smart app which is a Service Manager.

Service Managers can create ‘child devices’ and manage the refresh process etc…
this seems like the easiest way handling the refreshing everything.
might allow us to go to near real time.

lots of good information here
http://docs.smartthings.com/en/latest/cloud-and-lan-connected-device-types-developers-guide/building-cloud-connected-device-types/building-the-service-manager.html#discovery


(Daniel McDougall) #15

Progress update:

Control Panel - arming/disarming etc… - Done
Contact Sensors - Done - working towards real time updates
Normal PIRs - Doubtful - im becoming convinced this will remain out of reach. unless the system is armed the PIRs send no signal to the panel ( unless its in walk test mode) i think i may be able to force this mode but will need testing.

Photos PIR - Hopeful - getting the photos and trigging the camera are 100% in reach. using it as a PIR has the same issue as the above, the thing is i have a feeling the the photo PIR is actually a Zigbee device. and i think i could do something with that. for now though mark as OOR

Smartthings sensors used by Yale alarm system - Will need more testing but i think i can trigger the alarm if any other sensor in smartthings changes state. Will need loads more testing and i think i might have to buy a panic button device to actually do this but i’m hopeful.


(John Lockwood) #16

Smartthings sensors used by Yale alarm system - Will need more testing but i think i can trigger the alarm if any other sensor in smartthings changes state. Will need loads more testing and i think i might have to buy a panic button device to actually do this but i’m hopeful.

It would be cool if you could get Smartthings to send the status of Nest Protect smoke detectors to the Yale such that if the Nest reports an alarm it is passed to the Yale and treated as if it was a native alarm trigger.


(Daniel McDougall) #17

so if your fire alarm goes off you want your house alarm siren to trigger?

if I was your neighbour I could find that quite annoying. my fire alarm goes off every time I cook lol


(Daniel McDougall) #18

I should say that if I can find a way to trigger the alarm for one thing I can do it for anything.


(John Lockwood) #19

LOL.

I would only have this trigger a DSC alarm if the panel was armed. If one was at home and setting fire to the lunch then this would only trigger the Nest to reprimand you. :grin:


(Daniel McDougall) #20

Oh yeah - duh sorry its been a long week. If I can get external devices to trigger it shouldn’t matter what those devices are really.