Forked from mckeed/ridiculously-automated-zwave-garage-door.groovy
Last active
September 21, 2015 00:18
-
-
Save schwark/07ea63bbe1a1a8318d83 to your computer and use it in GitHub Desktop.
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
/** | |
* Ridiculously Automated Garage Door | |
* | |
* Author: SmartThings | |
* | |
* Monitors arrival and departure of car(s) and | |
* | |
* 1) opens door when car arrives, | |
* 2) closes door after car has departed (for N minutes), | |
* 3) opens door when car door motion is detected, | |
* 4) closes door when door was opened due to arrival and interior door is closed. | |
* 5) closes door if found open at a specific time of day | |
*/ | |
definition( | |
name: "Enhanced Ridiculously Automated Garage Door for GD00Z", | |
namespace: "smartthings", | |
author: "SmartThings (modified by Schwark Satyavolu for scheduled closing)", | |
description: "Monitors arrival and departure of car(s) and 1) opens door when car arrives, 2) closes door after car has departed (for N minutes), 3) opens door when car door motion is detected, 4) closes door when door was opened due to arrival and interior door is closed, 5) closes door if left open at a certain time of day. Based on Ridiculously Automated Garage Door by SmartThings and modified for scheduled closing.", | |
category: "SmartThings Labs", | |
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/garage_contact.png", | |
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/[email protected]" | |
) | |
preferences { | |
section("Garage door") { | |
input "door", "capability.doorControl", title: "Which garage door controller?" | |
input "openThreshold", "number", title: "Warn when open longer than (optional)",description: "Number of minutes", required: false | |
input "phone", "phone", title: "Warn with text message (optional)", description: "Phone Number", required: false | |
input "closetime", "time", title: "Time to close if open (optional)", description: "Time", required: false | |
} | |
section("Car(s) using this garage door") { | |
input "cars", "capability.presenceSensor", title: "Presence sensor", description: "Which car(s)?", multiple: true, required: false | |
input "carDoorSensors", "capability.accelerationSensor", title: "Car door sensor(s)", description: "Which car(s)?", multiple: true, required: false | |
} | |
section("Interior door (optional)") { | |
input "interiorDoorSensor", "capability.contactSensor", title: "Contact sensor?", required: false | |
} | |
section("False alarm threshold (defaults to 10 min)") { | |
input "falseAlarmThreshold", "number", title: "Number of minutes", required: false | |
} | |
} | |
def installed() { | |
log.trace "installed()" | |
subscribe() | |
initialize() | |
} | |
def updated() { | |
log.trace "updated()" | |
unsubscribe() | |
subscribe() | |
unschedule(ensureDoorClosed) | |
initialize() | |
} | |
def initialize() { | |
log.trace "initialize" | |
if(closetime) { | |
log.debug "scheduling since closetime is set to ${closetime}" | |
schedule(closetime, "ensureDoorClosed") | |
} | |
} | |
def verifyDoorClosed() { | |
ensureDoorClosed() | |
} | |
def ensureDoorClosed() { | |
log.debug("refreshing door state") | |
door.refresh() | |
def currentState = door.doorState | |
if(currentState?.value != "closed") { | |
log.debug "closing door since it is currently not closed" | |
closeDoor() | |
def nxt = now()+2*60*1000 | |
log.debug "scheduling verification for ${nxt}" | |
schedule(nxt, "verifyDoorClosed") | |
} else { | |
log.debug "disabling further checks since door is closed" | |
unschedule("verifyDoorClosed") | |
} | |
} | |
def subscribe() { | |
log.debug "present: ${cars.collect{it.displayName + ': ' + it.currentPresence}}" | |
subscribe(door, "door", garageDoorState) | |
subscribe(cars, "presence", carPresence) | |
subscribe(carDoorSensors, "acceleration", accelerationActive) | |
if (interiorDoorSensor) { | |
subscribe(interiorDoorSensor, "contact.closed", interiorDoorClosed) | |
} | |
} | |
def doorOpenCheck() | |
{ | |
final thresholdMinutes = openThreshold | |
if (thresholdMinutes) { | |
def currentState = door.doorState | |
log.debug "doorOpenCheck" | |
if (currentState?.value == "open") { | |
log.debug "open for ${now() - currentState.date.time}, openDoorNotificationSent: ${state.openDoorNotificationSent}" | |
if (!state.openDoorNotificationSent && now() - currentState.date.time > thresholdMinutes * 60 *1000) { | |
def msg = "${door.displayName} was been open for ${thresholdMinutes} minutes" | |
log.info msg | |
sendPush msg | |
if (phone) { | |
sendSms phone, msg | |
} | |
state.openDoorNotificationSent = true | |
} | |
} | |
else { | |
state.openDoorNotificationSent = false | |
} | |
} | |
} | |
def carPresence(evt) | |
{ | |
log.info "$evt.name: $evt.value" | |
// time in which there must be no "not present" events in order to open the door | |
final openDoorAwayInterval = falseAlarmThreshold ? falseAlarmThreshold * 60 : 600 | |
if (evt.value == "present") { | |
// A car comes home | |
def car = getCar(evt) | |
def t0 = new Date(now() - (openDoorAwayInterval * 1000)) | |
def states = car.statesSince("presence", t0) | |
def recentNotPresentState = states.find{it.value == "not present"} | |
if (recentNotPresentState) { | |
log.debug "Not opening ${door.displayName} since car was not present at ${recentNotPresentState.date}, less than ${openDoorAwayInterval} sec ago" | |
} | |
else { | |
if (door.currentDoor == "closed") { | |
openDoor() | |
sendPush "Opening garage door due to arrival of ${car.displayName}" | |
state.appOpenedDoor = now() | |
} | |
else { | |
log.debug "door already open" | |
} | |
} | |
} | |
else { | |
// A car departs | |
if (door.currentDoor == "open") { | |
closeDoor() | |
log.debug "Closing ${door.displayName} after departure" | |
sendPush("Closing ${door.displayName} after departure") | |
} | |
else { | |
log.debug "Not closing ${door.displayName} because its already closed" | |
} | |
} | |
} | |
def garageDoorState(evt) | |
{ | |
log.info "garageDoorState, $evt.name: $evt.value" | |
if (evt.value == "open") { | |
schedule("0 * * * * ?", "doorOpenCheck") | |
} | |
else { | |
unschedule("doorOpenCheck") | |
} | |
} | |
def interiorDoorClosed(evt) | |
{ | |
log.info "interiorContact, $evt.name: $evt.value" | |
// time during which closing the interior door will shut the garage door, if the app opened it | |
final threshold = 15 * 60 * 1000 | |
if (state.appOpenedDoor && now() - state.appOpenedDoor < threshold) { | |
state.appOpenedDoor = 0 | |
closeDoor() | |
} | |
else { | |
log.debug "app didn't open door" | |
} | |
} | |
def accelerationActive(evt) | |
{ | |
log.info "$evt.name: $evt.value" | |
if (door.currentDoor == "closed") { | |
log.debug "opening door when car door opened" | |
openDoor() | |
} | |
} | |
private openDoor() | |
{ | |
door.open() | |
} | |
private closeDoor() | |
{ | |
door.close() | |
} | |
private getCar(evt) | |
{ | |
cars.find{it.id == evt.deviceId} | |
} |
Oops.. here's the error..
groovy.lang.MissingMethodException: No signature of method: script1421954200050857002520.section() is applicable for argument types: (java.lang.String, script1421954200050857002520$_run_closure1_closure5) values: [Garage door, script1421954200050857002520$_run_closure1_closure5@692ec0ec]
Possible solutions: getLog(), setLog(java.lang.Object) @ line 27
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Hello Schwark,
Wonder if you can help? .. I get this error on save, with the code above (device type).
Appreciate any assist. Thx.