Compare commits

..

1 Commits

Author SHA1 Message Date
Aneep Tandel
ce02135b04 MSA-691: ZigBee Hub 2015-11-17 05:27:42 -06:00
2 changed files with 133 additions and 203 deletions

View File

@@ -0,0 +1,59 @@
/**
* My app
*
* Copyright 2015 Aneep Tandel
*
* 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.
*
*/
definition(
name: "My app",
namespace: "aneepct",
author: "Aneep Tandel",
description: "test app",
category: "SmartThings Labs",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
oauth: [displayName: "Aneep Tandel", displayLink: ""])
preferences {
section("Turn on when motion detected:") {
input "themotion", "capability.motionSensor", required: true, title: "Where?"
}
section("Turn on this door") {
input "theswitch", "capability.switch", 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(themotion, "motion.active", motionDetectedHandler)
}
// TODO: implement event handlers
def motionDetectedHandler(evt) {
log.debug "motionDetectedHandler called: $evt"
theswitch.on()
}

View File

@@ -10,7 +10,7 @@
* The timeout perid begins when the contact is closed, or motion stops, so leaving a door open won't start the timer until it's closed.
*
* Author: andersheie@gmail.com
* Date: 2015-10-30
* Date: 2014-08-31
*/
definition(
@@ -23,18 +23,12 @@ definition(
iconX2Url: "http://upload.wikimedia.org/wikipedia/commons/6/6a/Light_bulb_icon_tips.svg")
preferences {
section("Turn on when there is movement..."){
section("Turn on when there's movement..."){
input "motions", "capability.motionSensor", multiple: true, title: "Select motion detectors", required: false
}
section("Or, turn on when one of these contacts opened"){
input "contacts", "capability.contactSensor", multiple: true, title: "Select Contacts", required: false
}
section("Or, turn on when any of these people come home") {
input "peoplearrive", "capability.presenceSensor", multiple: true, required: false
}
section("Or, turn on when any of these people leave") {
input "peopleleave", "capability.presenceSensor", multiple: true, required: false
}
section("And off after no more triggers after..."){
input "minutes1", "number", title: "Minutes?", defaultValue: "5"
}
@@ -46,232 +40,109 @@ preferences {
def installed()
{
log.debug "installed()"
initialize()
subscribe(switches, "switch", switchChange)
subscribe(motions, "motion", motionHandler)
subscribe(contacts, "contact", contactHandler)
schedule("0 * * * * ?", "scheduleCheck")
state.myState = "ready"
}
def updated()
{
log.debug "updated()"
initialize()
}
def initialize()
{
log.debug "initialize()"
// Reset to new set of Switches, just in case.
unsubscribe()
state.switches = [:]
switches.each {
// log.debug "ID: $it.id"
// Set ready state for each switch
state.switches["$it.id"] = "ready"
}
logStates()
unsubscribe()
subscribe(motions, "motion", motionHandler)
subscribe(switches, "switch", switchChange)
subscribe(contacts, "contact", contactHandler)
subscribe(peoplearrive, "presence.present", presencePresentHandler)
subscribe(peopleleave, "presence.not present", presenceNotPresentHandler)
state.lastAction = null
schedule("0 * * * * ?", "scheduleCheck")
}
def logStates() {
if(state.switches == null) {
state.switches = [:]
}
state.switches.each {
log.debug "State: $it.key = $it.value"
}
}
def turnSwitchOn(id) {
for(S in switches) {
if(S.id == id) {
S.on()
}
}
}
def turnSwitchOff(id) {
for(S in switches) {
if(S.id == id) {
S.off()
}
}
}
def initState(deviceID) {
// Have to add this so existing apps that are neither updated nor initiated can slowly get 'reset' with states.
// Smartthings doesn't call any specifc method when new version is published.
if(state.switches == null) {
state.switches = [:]
}
if(state.switches[deviceID] == null) {
state.switches[deviceID] = "ready"
}
state.myState = "ready"
log.debug "state: " + state.myState
}
def switchChange(evt) {
def deviceID = evt.device.id
log.debug "SwitchChange: $evt.name: $evt.value $evt.device.id current state = " + state.switches[deviceID]
initState(deviceID)
log.debug "SwitchChange: $evt.name: $evt.value"
if(evt.value == "on") {
if(state.switches[deviceID] == "activating") {
// OK, probably an event from Activating something, and not the switch itself. Go to Active mode.
log.debug "$deviceID = " + state.switches[deviceID] + " -> active"
state.switches[deviceID] = "active"
} else if(state.switches[deviceID] != "active") {
log.debug "$deviceID = " + state.switches[deviceID] + " -> already on"
state.switches[deviceID] = "already on"
}
if(evt.value == "on") {
// Slight change of Race condition between motion or contact turning the switch on,
// versus user turning the switch on. Since we can't pass event parameters :-(, we rely
// on the state and hope the best.
if(state.myState == "activating") {
// OK, probably an event from Activating something, and not the switch itself. Go to Active mode.
state.myState = "active"
} else if(state.myState != "active") {
state.myState = "already on"
}
} else {
// If active and switch is turned of manually, then stop the schedule and go to ready state
state.switches[deviceID] = "ready"
// If active and switch is turned of manually, then stop the schedule and go to ready state
if(state.myState == "active" || state.myState == "activating") {
unschedule()
}
state.myState = "ready"
}
logStates()
log.debug "state: " + state.myState
}
def contactHandler(evt) {
log.debug "contactHandler: $evt.name: $evt.value"
state.switches.each { thisswitch ->
initState(thisswitch.key)
//log.debug "Looking for $thisswitch.key"
if (evt.value == "open") {
if(state.switches[thisswitch.key] == "ready") {
log.debug "Turning on lights by contact opening: $thisswitch"
log.debug "$thisswitch.key = " + state.switches[thisswitch.key] + " -> activating"
state.switches[thisswitch.key] = "activating"
turnSwitchOn(thisswitch.key)
setActiveAndSchedule()
}
} else if (evt.value == "closed") {
if (!state.lastAction && (state.switches[thisswitch.key] == "active"
|| state.switches[thisswitch.key] == "activating")) {
// When contact closes, we reset the timer if not already set
log.debug "$thisswitch.key = " + state.switches[thisswitch.key] + " -> active"
state.switches[thisswitch.key] = "active"
setActiveAndSchedule()
}
if (evt.value == "open") {
if(state.myState == "ready") {
log.debug "Turning on lights by contact opening"
switches.on()
state.inactiveAt = null
state.myState = "activating"
}
} else if (evt.value == "closed") {
if (!state.inactiveAt && state.myState == "active" || state.myState == "activating") {
// When contact closes, we reset the timer if not already set
setActiveAndSchedule()
}
}
logStates()
log.debug "state: " + state.myState
}
def scheduleCheck() {
log.debug "schedule check, ts = ${state.lastAction}"
boolean resetInactive = false
state.switches.each { thisswitch ->
initState(thisswitch.key)
if(state.switches[thisswitch.key] != "already on") {
if(state.lastAction != null) {
def elapsed = now() - state.lastAction
log.debug "${elapsed / 1000} sec since events stopped"
def threshold = 1000 * 60 * minutes1
if (elapsed >= threshold) {
if (state.switches[thisswitch.key] == "active"
|| state.switches[thisswitch.key] == "activating") {
state.switches[thisswitch.key] = "ready"
log.debug "Turning off lights by switch closing: $thisswitch"
turnSwitchOff(thisswitch.key)
}
resetInactive = true
}
}
}
}
if(resetInactive) {
state.lastAction = null
unschedule()
}
logStates()
}
/**********************************************************************/
def motionHandler(evt) {
log.debug "motionHandler: $evt.name: $evt.value (current state: " + state.myState + ")"
log.debug "motionHandler: $evt.name: $evt.value"
state.switches.each { thisswitch ->
initState(thisswitch.key)
if (evt.value == "active") {
if(state.switches[thisswitch.key] == "ready"
|| state.switches[thisswitch.key] == "active"
|| state.switches[thisswitch.key] == "activating" ) {
log.debug "$thisswitch.key = " + state.switches[thisswitch.key] + " -> activating"
state.switches[thisswitch.key] = "activating"
turnSwitchOn(thisswitch.key)
setActiveAndSchedule()
}
} else if (evt.value == "inactive") {
if (state.switches[thisswitch.key] == "active" || state.switches[thisswitch.key] == "activating") {
// When Motion ends, we reset the timer if not already set
log.debug "$thisswitch.key = " + state.switches[thisswitch.key] + " -> active"
state.switches[thisswitch.key] = "active"
setActiveAndSchedule()
}
if (evt.value == "active") {
if(state.myState == "ready" || state.myState == "active" || state.myState == "activating" ) {
log.debug "turning on lights"
switches.on()
state.inactiveAt = null
state.myState = "activating"
}
} else if (evt.value == "inactive") {
if (!state.inactiveAt && state.myState == "active" || state.myState == "activating") {
// When Motion ends, we reset the timer if not already set
setActiveAndSchedule()
}
}
logStates()
}
def presencePresentHandler(evt) {
log.debug "presence: $evt.linkText is now $evt.value"
state.switches.each { thisswitch ->
initState(thisswitch.key)
if (evt.value == "present") {
if(state.switches[thisswitch.key] == "ready"
|| state.switches[thisswitch.key] == "active"
|| state.switches[thisswitch.key] == "activating" ) {
log.debug "Presence turning on switch $thisswitch"
state.switches[thisswitch.key] = "active"
turnSwitchOn(thisswitch.key)
// We don't wait until the person leave, but instead start timer immediately.
setActiveAndSchedule()
}
}
}
logStates()
}
def presenceNotPresentHandler(evt) {
log.debug "presence: $evt.linkText is now $evt.value"
state.switches.each { thisswitch ->
initState(thisswitch.key)
if (evt.value == "not present") {
if(state.switches[thisswitch.key] == "ready"
|| state.switches[thisswitch.key] == "active"
|| state.switches[thisswitch.key] == "activating" ) {
log.debug "No Presence turning on lights $thisswitch"
state.switches[thisswitch.key] = "active"
turnSwitchOn(thisswitch.key)
// We don't wait until the person arrive back, but instead start timer immediately.
setActiveAndSchedule()
}
}
}
logStates()
log.debug "state: " + state.myState
}
def setActiveAndSchedule() {
unschedule()
state.lastAction = now()
state.myState = "active"
state.inactiveAt = now()
schedule("0 * * * * ?", "scheduleCheck")
log.debug "Scheduled new timer"
}
def scheduleCheck() {
log.debug "schedule check, ts = ${state.inactiveAt}"
if(state.myState != "already on") {
if(state.inactiveAt != null) {
def elapsed = now() - state.inactiveAt
log.debug "${elapsed / 1000} sec since motion stopped"
def threshold = 1000 * 60 * minutes1
if (elapsed >= threshold) {
if (state.myState == "active") {
log.debug "turning off lights"
switches.off()
}
state.inactiveAt = null
state.myState = "ready"
}
}
}
log.debug "state: " + state.myState
}