Last active
November 2, 2016 19:06
-
-
Save lyons189/e5b30109fdaec805d474 to your computer and use it in GitHub Desktop.
These 3 files are used to get ADT integration working
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* ADT Device Handler | |
* | |
* Copyright 2014 craig Lyons | |
* | |
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except | |
* in compliance with the License. You may obtain a copy of the License at: | |
* | |
* http://www.apache.org/licenses/LICENSE-2.0 | |
* | |
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed | |
* on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License | |
* for the specific language governing permissions and limitations under the License. | |
* | |
*/ | |
// Automatically generated. Make future change here. | |
definition( | |
name: "ADT Device Handler", | |
namespace: "", | |
author: "craig Lyons", | |
description: "Handles my fake devices based off of ADT", | |
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("Which Shield are you using") { | |
input "shield", "capability.alarm", title: "Which Shield?" | |
} | |
section("Front Door"){ | |
input "zone2", "capability.contactSensor", title: "Which Door?" | |
} | |
section("Back Door"){ | |
input "zone5", "capability.contactSensor", title: "Which Door?" | |
} | |
section("Garage Door"){ | |
input "zone3", "capability.contactSensor", title: "Which Door?" | |
} | |
section("Basement Door"){ | |
input "zone6", "capability.contactSensor", title: "Which Door?" | |
} | |
section("Hall Motion"){ | |
input "zone4", "capability.motionSensor", title: "Which Motion?" | |
} | |
section("Number of Seconds motion stays active") { | |
input "motionDelay", "number", description: "Number of seconds", required: true | |
} | |
} | |
def installed() { | |
log.debug "Installed with settings: ${settings}" | |
initialize() | |
} | |
def updated() { | |
log.debug "Updated with settings: ${settings}" | |
unsubscribe() | |
initialize() | |
} | |
def initialize() { | |
// TODO: subscribe to attributes, devices, locations, etc. | |
subscribe(shield, "hallMotion", hallMotion) | |
subscribe(shield, "frontDoor", frontDoor) | |
subscribe(shield, "backDoor", backDoor) | |
subscribe(shield, "garageDoor", garageDoor) | |
subscribe(shield, "basementDoor", basementDoor) | |
} | |
def hallMotion(evt) { | |
//log.debug "${shield.label ?: shield.name} has motion" | |
//log.debug shield.latestValue("hallMotion") | |
//log.debug zone4.latestValue("motionSensor") | |
if (evt.value == "Active") { | |
//log.info "Motion Active" | |
zone4.Active() | |
} | |
else if (evt.value == "inActive") { | |
//log.info "delay ${motionDelay}" | |
//zone4.semiActive() | |
runIn ( motionDelay, motionInActive, overwrite: true) // Schedule to change motion state | |
} | |
} | |
def motionInActive() | |
{ | |
//log.info "Function inActive"; | |
zone4.inActive() | |
} | |
def frontDoor(evt) { | |
log.debug "${shield.label ?: shield.name} is open" | |
log.debug shield.latestValue("frontDoor") | |
log.debug zone2.latestValue("contact") | |
if (evt.value == "open") { | |
log.info "frontDoor open" | |
zone2.open() | |
} else if (evt.value == "closed") { | |
log.info "frontDoor closed" | |
zone2.close() | |
} | |
} | |
def backDoor(evt) { | |
log.debug "${shield.label ?: shield.name} is open" | |
log.debug shield.latestValue("backDoor") | |
log.debug zone2.latestValue("backDoor") | |
if (evt.value == "open") { | |
log.info "backDoor open" | |
zone5.open() | |
} else if (evt.value == "closed") { | |
log.info "backDoor closed" | |
zone5.close() | |
} | |
} | |
def garageDoor(evt) { | |
log.debug "${shield.label ?: shield.name} is open" | |
log.debug shield.latestValue("garageDoor") | |
log.debug zone2.latestValue("garageDoor") | |
if (evt.value == "open") { | |
log.info "garageDoor open" | |
zone3.open() | |
} else if (evt.value == "closed") { | |
log.info "garageDoor closed" | |
zone3.close() | |
} | |
} | |
def basementDoor(evt) { | |
log.debug "${shield.label ?: shield.name} is open" | |
log.debug shield.latestValue("basementDoor") | |
log.debug zone2.latestValue("basementDoor") | |
if (evt.value == "open") { | |
log.info "basementDoor open" | |
zone6.open() | |
} else if (evt.value == "closed") { | |
log.info "basementDoor closed" | |
zone6.close() | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#include <SmartThingsMega.h> //special library for Arduino Mega card | |
#include <Timer.h> | |
// PASSCODE = your personal code. It's hard coded here so you don't need to post it within Smartthings app. | |
String PASSCODE = "####"; | |
#define PIN_THING_LED 13 | |
#define BUFFER_SIZE 300 // max message length from ADT | |
#define ARDUINO_CHECK_IN 30000 | |
#define UPDATE_PERIOD_ARM 25283 | |
#define UPDATE_PERIOD_ALARM 30123 | |
#define UPDATE_PERIOD_ZONE 50234 | |
SmartThingsCallout_t messageCallout; // call out function forward decalaration | |
SmartThingsMega smartthing(&Serial2, messageCallout); // constructor | |
Timer timer; | |
char buffer[BUFFER_SIZE]; | |
boolean DEBUG = false; | |
boolean LIVE = false; | |
int bufferIdx; | |
void setup() | |
{ | |
pinMode(PIN_THING_LED, OUTPUT); // define PIN_LED as an output | |
Serial1.begin(115200); // intialize ADT serial stream | |
Serial.begin(115200); // intialize DEBUG or LIVE serial stream | |
bufferIdx = 0; | |
//timer.every(ARDUINO_CHECK_IN, checkIn); | |
//timer.every(UPDATE_PERIOD_ARM, sendArmStatus); | |
//timer.every(UPDATE_PERIOD_ALARM, sendAlarmStatus); | |
//timer.every(UPDATE_PERIOD_ZONE, sendZoneStatus); | |
digitalWrite(PIN_THING_LED, HIGH); // Turn Smartthings LED on. | |
smartthing.shieldSetLED(0, 1, 0); // Turn LED "green" to show startup | |
delay(250); | |
if (DEBUG || LIVE) | |
{ | |
if (DEBUG) | |
{ | |
smartthing.shieldSetLED(1, 0, 0); // Turn LED "Red" for DEBUG mode | |
delay(250); | |
} | |
if (LIVE) | |
{ | |
smartthing.shieldSetLED(0, 0, 1); // Turn LED "Blue" for LIVE mode | |
delay(250); | |
} | |
Serial.println("Ready"); | |
} | |
smartthing.shieldSetLED(0, 0, 0); | |
digitalWrite(PIN_THING_LED, LOW); // Turn of LED | |
} | |
void loop() | |
{ | |
char data, arduino_input; | |
timer.update(); // update periodic events | |
smartthing.run(); // run smartthing logic | |
if (DEBUG || LIVE) | |
{ | |
if (Serial.available() > 0) | |
{ | |
arduino_input = Serial.read(); | |
String command = "X"; | |
command.setCharAt(0,arduino_input); | |
Serial1.print(command); | |
if(DEBUG) | |
{ | |
Serial.print("type Code: <"); | |
Serial.print(arduino_input); | |
Serial.println(">"); | |
Serial.println(command); | |
delay (250); | |
smartthing.send(command); | |
} | |
} | |
} | |
if (Serial1.available() > 0) | |
{ | |
data = Serial1.read(); | |
if (DEBUG || LIVE) | |
{ | |
Serial.print(data); | |
} | |
if (data == '\r' && bufferIdx > 0) | |
{ | |
// if line is completed, review command | |
buffer[bufferIdx] = '\0'; | |
bufferIdx = 0; | |
String str(buffer); | |
int quoteIndex = str.indexOf('"'); | |
String cmd = str.substring(quoteIndex, str.length()); | |
if(cmd.length() > 0) | |
{ | |
smartthing.send(cmd); | |
} | |
else if (str.equals("!Sending.done") || str.indexOf("!RFX:") >=0) | |
{ | |
} | |
else | |
{ | |
smartthing.send(str); | |
} | |
if (DEBUG) | |
{ | |
Serial.println(""); | |
Serial.print("str Code: <"); | |
Serial.println(str); | |
} | |
if (LIVE) | |
{ | |
Serial.println(""); | |
Serial.print("cmd Code: "); | |
Serial.println(cmd); | |
} | |
} | |
// otherwise append to buffer (ignore \n) | |
else if (data != '\n') | |
{ | |
buffer[bufferIdx] = data; | |
bufferIdx++; | |
if (bufferIdx >= BUFFER_SIZE) | |
{ | |
smartthing.send("ER:Buffer overrun"); | |
bufferIdx = 0; | |
} | |
} | |
} | |
} | |
void debug() | |
{ | |
DEBUG = true; | |
smartthing.send("MODE: Debug"); | |
digitalWrite(PIN_THING_LED, HIGH); // turn LED on | |
smartthing.shieldSetLED(1, 0, 0); // turn LED Red for DEBUG | |
delay(250); | |
smartthing.shieldSetLED(0, 0, 0); | |
digitalWrite(PIN_THING_LED, LOW); // turn LED off | |
} | |
void Live() | |
{ | |
LIVE = true; | |
smartthing.send("MODE: Live"); | |
digitalWrite(PIN_THING_LED, HIGH); // turn LED on | |
smartthing.shieldSetLED(0, 0, 1); // turn LED Blue for LIVE | |
delay(250); | |
smartthing.shieldSetLED(0, 0, 0); | |
digitalWrite(PIN_THING_LED, LOW); // turn LED off | |
} | |
void noDebug() | |
{ | |
DEBUG = false; | |
LIVE = false; | |
smartthing.send("MODE: noDebug"); | |
digitalWrite(PIN_THING_LED, HIGH); // turn LED on | |
smartthing.shieldSetLED(0, 1, 0); // turn LED Green for no DEBUG or LIVE | |
delay(250); | |
smartthing.shieldSetLED(0, 0, 0); | |
digitalWrite(PIN_THING_LED, LOW); // turn LED off | |
} | |
void checkIn () | |
{ | |
smartthing.send("ADT Check-in"); | |
} | |
void messageCallout(String message) | |
{ | |
String code = message.substring(0,6); | |
String cmd = message.substring(6); | |
if(message.length()>0) | |
{ | |
String code = message.substring(0,6); | |
Serial.print("Smart-things sent: <"); | |
Serial.print(message); | |
Serial.println(">"); | |
if (DEBUG || LIVE) | |
{ | |
Serial.print("Smart-things sent: <"); | |
Serial.print(message); | |
Serial.println(">"); | |
delay(250); | |
smartthing.send(message); | |
} | |
if (message.equals("MODE: debug")) | |
{ | |
debug(); | |
} | |
else if (message.equals("MODE: Live")) | |
{ | |
Live(); | |
} | |
else if (message.equals("MODE: both")) | |
{ | |
debug(); | |
Live(); | |
} | |
else if (message.equals("MODE: noDebug")) | |
{ | |
noDebug(); | |
} | |
else if(code.equals("[CODE]")) | |
{ | |
Serial1.println(PASSCODE + cmd); | |
if(DEBUG || LIVE) | |
{ | |
Serial.print(PASSCODE); | |
Serial.print("+"); | |
Serial.println(cmd); | |
Serial.print("Sent Alarm: "); | |
Serial.println(PASSCODE + cmd); | |
delay(250); | |
smartthing.send(PASSCODE + cmd); | |
} | |
} | |
} | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
// | |
// In device configuration select the following capabilities: switch, contact and alarm | |
// | |
metadata { | |
// Automatically generated. Make future change here. | |
definition (name: "ADT", author: "craig Lyons") { | |
capability "Alarm" | |
capability "Contact Sensor" | |
capability "Switch" | |
capability "Motion Sensor" | |
attribute "backDoor", "string" | |
attribute "frontDoor", "string" | |
attribute "garageDoor", "string" | |
attribute "basementDoor", "string" | |
attribute "hallMotion", "string" | |
attribute "debug", "string" | |
attribute "chime", "string" | |
attribute "secs", "string" | |
attribute "msg", "string" | |
command "disarm" | |
command "armStay" | |
command "armAway" | |
command "noDebug" | |
command "live" | |
command "debug" | |
command "both" | |
command "chime" | |
command "status" | |
} | |
// Simulator metadata | |
simulator { | |
} | |
// UI tile definitions | |
tiles { | |
standardTile("alarm", "device.alarm", width: 1, height: 1) { | |
state "Disarmed", label:'${name}', action:"armStay", icon:"st.Home.home2", backgroundColor:"#ffffff" | |
state "Away", label:'${name}', action:"disarm", icon:"st.Home.home3", backgroundColor:"#79b821" | |
state "Stay", label:'${name}', action:"disarm", icon:"st.Home.home4", backgroundColor:"#79b821" | |
state "aWarning", label:'Warning', action:"disarm", icon:"st.Home.home3", backgroundColor:"#FF3333" | |
state "sWarning", label:'Warning', action:"disarm", icon:"st.Home.home4", backgroundColor:"#FF3333" | |
state "armingAway", label:'Away', action:"disarm", icon:"st.Home.home3", backgroundColor:"#ffa81e" | |
state "armingStay", label:'Stay', action:"disarm", icon:"st.Home.home4", backgroundColor:"#ffa81e" | |
} | |
standardTile("Stay", "device.alarm", width: 1, height: 1, decoration: "flat"){ | |
state "Stay", label:'${name}', action: "armStay", icon:"st.Home.home4", nextState: "Pressed" | |
state "Pressed", label:'Armed', action: "armStay", icon:"st.Home.home4" | |
} | |
standardTile("Away", "device.alarm", width: 1, height: 1, decoration: "flat"){ | |
state "Away", label:'${name}', action: "armAway", icon:"st.Home.home3", nextState: "Pressed" | |
state "Pressed", label:'Armed', action: "armStay", icon:"st.Home.home3" | |
} | |
standardTile("backDoor", "device.backDoor", width: 1, height:1) { | |
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e" | |
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821" | |
} | |
standardTile("frontDoor", "device.frontDoor", width: 1, height:1) { | |
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e" | |
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821" | |
} | |
standardTile("garageDoor", "device.garageDoor", width: 1, height:1) { | |
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e" | |
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821" | |
} | |
standardTile("basementDoor", "device.basementDoor", width: 1, height:1) { | |
state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#ffa81e" | |
state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#79b821" | |
} | |
standardTile("hallMotion", "device.hallMotion", width: 1, height:1) { | |
state "inActive", label: 'No Motion', icon: "st.motion.motion.inactive", backgroundColor: "#ffffff" | |
state "Active", label: 'Motion', icon: "st.motion.motion.active", backgroundColor: "#53a7c0" | |
} | |
standardTile("chime", "chime", width: 1, height: 1, inactiveLabel: false, decoration: "flat"){ | |
state "on", label: 'Chime On', action: "chime", icon: "st.custom.sonos.unmuted", backgroundColor: "#ffffff", nextState: "unk" | |
state "off", label: 'Chime Off', action: "chime", icon: "st.custom.sonos.muted", backgroundColor: "#ffffff", nextState: "unk" | |
state "unk", label: 'Changing', icon: "st.custom.sonos.unmuted", backgroundColor: "#ffffff" | |
} | |
standardTile("debug", "debug", width: 1, height: 1){ | |
state "none", label: '', action: "live", icon: "st.secondary.configure", backgroundColor: "#ffffff" | |
state "live", label: '', action: "debug", icon: "st.secondary.test", backgroundColor: "#53a7c0", nextState: "debug" | |
state "debug", label: '', action: "noDebug", icon: "st.secondary.test", backgroundColor: "#FF3333" | |
} | |
standardTile("Disarm", "device.alarm", width: 1, height: 1, decoration: "flat"){ | |
state "da", label:'Disarm', action: "disarm", icon:"st.Home.home2" | |
} | |
valueTile("secs", "device.secs") { | |
state "default", label:'${currentValue}' | |
} | |
valueTile("msg", "device.msg", width: 3, height:1, inactiveLabel: false, decoration: "flat") { | |
state "default", label:'${currentValue}' | |
} | |
main(["alarm"]) | |
details(["alarm","Stay","Away","frontDoor","garageDoor","chime","backDoor","basementDoor","Disarm","hallMotion","debug","secs", | |
"msg"]) | |
} | |
} | |
// Parse incoming device messages to generate events | |
def parse(String description) { | |
def result = [] | |
//log.info "Parsing: < ${description} >" | |
def msg = zigbee.parse(description)?.text | |
log.debug "Raw MSG : < ${msg} >" | |
if (msg.contains("ping")) {} | |
else {result << createEvent(name: "msg", value: msg)} | |
if (msg.contains("Hit") && msg.contains(" for faults")) | |
{ | |
status() | |
} | |
if (msg.contains("DISARMED")) | |
{ | |
result << createEvent(name: "alarm", value: "Disarmed") | |
result << createEvent(name: "Away", value: "Away") | |
result << createEvent(name: "Stay", value: "Stay") | |
result << createEvent(name: "secs", value: "-") | |
if (msg.contains("CHIME")) | |
{ | |
result << createEvent(name: "chime", value: "on") | |
} | |
else | |
{ | |
result << createEvent(name: "chime", value: "off") | |
} | |
} | |
if (msg.contains("DISARM SYSTEM")) | |
{ | |
if (device.currentValue("alarm").contains("Away")) | |
{ | |
result << createEvent(name: "alarm", value: "sWarning") | |
} | |
else if (device.currentValue("alarm").contains("Stay")) | |
{ | |
result << createEvent(name: "alarm", value: "aWarning") | |
} | |
else | |
{ | |
result << createEvent(name: "alarm", value: "sWarning") | |
} | |
result << createEvent(name: "alarm", value: "Warning") | |
} | |
if (msg.contains("Ready to Arm")) | |
{ | |
result << createEvent(name: "hallMotion", value: "inActive") | |
result << createEvent(name: "frontDoor", value: "closed") | |
result << createEvent(name: "garageDoor", value: "closed") | |
result << createEvent(name: "basementDoor", value: "closed") | |
result << createEvent(name: "backDoor", value: "closed") | |
} | |
if (msg.contains("ARMED")) | |
{ | |
if (msg.contains("STAY")) | |
{ | |
if (msg.contains("May Exit Now")) | |
{ | |
result << createEvent(name: "alarm", value: "armingStay") | |
result << createEvent(name: "secs", value: msg.substring(msg.length()-3,msg.length()-1)) | |
} | |
else | |
{ | |
result << createEvent(name: "alarm", value: "Stay") | |
result << createEvent(name: "secs", value: "-") | |
} | |
} | |
else if (msg.contains("AWAY")) | |
{ | |
if (msg.contains("May Exit Now")) | |
{ | |
result << createEvent(name: "alarm", value: "armingAway") | |
result << createEvent(name: "secs", value: msg.substring(msg.length()-3,msg.length()-1)) | |
} | |
else | |
{ | |
result << createEvent(name: "alarm", value: "Away") | |
result << createEvent(name: "secs", value: "-") | |
} | |
} | |
} | |
if (msg.contains("FAULT")) | |
{ | |
log.info "fault" | |
if (msg.contains("01")) | |
{ | |
log.info "01" | |
result << createEvent(name: "backDoor", value: "open") | |
} | |
else if (msg.contains("02")) | |
{ | |
log.info "02" | |
result << createEvent(name: "frontDoor", value: "open") | |
} | |
else if (msg.contains("03")) | |
{ | |
log.info "03" | |
result << createEvent(name: "garageDoor", value: "open") | |
} | |
else if (msg.contains("04")) | |
{ | |
log.info "04" | |
result << createEvent(name: "hallMotion", value: "Active") | |
} | |
else if (msg.contains("05")) | |
{ | |
log.info "05" | |
result << createEvent(name: "backDoor", value: "open") | |
} | |
else if (msg.contains("06")) | |
{ | |
log.info "06" | |
result << createEvent(name: "basementDoor", value: "open") | |
} | |
} | |
if (msg.contains("MODE")) | |
{ | |
if (msg.contains("Live")) | |
{ | |
result << createEvent(name: "debug", value: "live") | |
} | |
if (msg.contains("debug")) | |
{ | |
result << createEvent(name: "debug", value: "debug") | |
} | |
if (msg.contains("noDebug")) | |
{ | |
result << createEvent(name: "debug", value: "none") | |
} | |
} | |
//log.debug "Parse returned ${result?.descriptionText}" | |
return result | |
} | |
// Commands sent to the device | |
def on() { | |
log.debug "Trying to arm alarm" | |
} | |
def armAway(){ | |
zigbee.smartShield(text: "[CODE]2").format() | |
} | |
def disarm() { | |
zigbee.smartShield(text: "[CODE]1***").format() | |
} | |
def armStay() { | |
zigbee.smartShield(text: "[CODE]3").format() | |
} | |
def chime() { | |
zigbee.smartShield(text: "[CODE]9").format() | |
} | |
def debug() { | |
zigbee.smartShield(text: "Mode: debug").format() | |
} | |
def live() { | |
zigbee.smartShield(text: "MODE: Live").format() | |
} | |
def noDebug() { | |
zigbee.smartShield(text: "MODE: noDebug").format() | |
} | |
def status() { | |
//disarm() | |
log.trace "here" | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment