SmartThings Community

Newbie - help with time delay


(Don England) #1

I am new with the smartapps as I have just recently purchased a hub and it has been quite a few years since I have done any coding.

Basically I am looking at getting a notification when the garage door is open and then the interior door to the garage is open for more than 1 minutes. This is so the dogs don’t get out, but I don’t want to get the notification if i just open and close the door. Later I will probably add a way to get a sound notification.

But what I am looking at doing is adding a delay to the following code that I am trying to modify to suit my needs. Any help in pointing me in the right direction would be great.

preferences {
section (“When this door opens/is open…”) {
input “door1”, “capability.contactSensor”, title: “Which garage door?”, required: true
}
section (“And this door opens/is open…”) {
input “door2”, “capability.contactSensor”, title: “Which interior door?”, required: true
}

section( "Notifications" ) {
    input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
    input "phone1", "phone", title: "Send a text message?", required: false
    input "msg", "text", title: "What is your message?", required: false
}

}

def installed() {
log.debug “Installed with settings: ${settings}”
initialize()
}

def updated() {
log.debug “Updated with settings: ${settings}”
unsubscribe()
initialize()
}

def initialize() {
subscribe(door1, “contact.open”, door1Handler)
subscribe(door2, “contact.open”, door2Handler)
}

def door1Handler(evt) {
def door2Current = door2.currentContact
log.debug “door2 current status is $door2Current”

if (door2.currentContact == "open") {
	send(msg)
}

}

def door2Handler(evt) {
def door1Current = door1.currentContact
log.debug “door1 current status is $door1Current”
if (door1.currentContact == “open”) {
send(msg)
}
}

private send(msg) {
if ( sendPushMessage != “No” ) {
log.debug( “sending push message” )
sendPush( msg )
}

if ( phone1 ) {
    log.debug( "sending text message" )
    sendSms( phone1, msg )
}

log.debug msg

}

Thank you in advance for any help!


(Bryan) #2

Can’t help you with your code but can offer another solution that’s pretty quick and easy. If you are writing the app to hone your coding skills, I get that.

I coded by “door open” alerts in webCore in about 15 lines. You’d just need to add the code for your interior door to it. I’m attaching mine in case you want a different solution. This one alerts immediately when the mode is armed away and the door is opened.


(Bryan) #3

This one notifies after the door as been open for a period of time.


(Tony Fleisher) #4

The typical approach to this would be to schedule a method to run after the delay time from within the event handler (and cancel the schedule if conditions change).

see: https://docs.smartthings.com/en/latest/smartapp-developers-guide/scheduling.html


(Don England) #5

@TonyFleisher
So something like this?

def door1Handler(evt) {
def door2Current = door2.currentContact
log.debug “door2 current status is $door2Current”

if (door2.currentContact == "open") {
	runIn(maxOpenTime * 60, send(msg))
}
    else if (door2.currentContact == "close") {
	unschedule(send(msg))
}

}

def door2Handler(evt) {
def door1Current = door1.currentContact
log.debug “door1 current status is $door1Current”
if (door1.currentContact == “open”) {
runIn(maxOpenTime * 60, send(msg))
}
else if (door1.currentContact == “close”) {
unschedule(send(msg))
}
}

I am not home right now, so I will have to try it later and let everyone know.

@Bry

If I can’t figure it out, I will go with the webCore. But definitely need to get back to coding, as it looks like I may be going back into an IT position again.


(Don England) #6

Ok. Tried it when I got home. It will still send out the message when both doors are open, but the delay didn’t work. So I must be missing something.

Also, I think I may be putting the delay on the wrong thing. I want the delay on one of the contact sensor. If the door2.currentContact is open for more than 2 minutes. Or is that the way the runIn works??


(Don England) #7

So I tried to go a different way and that didn’t work out either. So I am definitely missing something. Does anyone see what I am missing??

/**

  • Garage Open and Interior Garage Door Open?
  • Copyright 2018 D. England
  • 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.
  • Author: D. England
  • Date: 12.19.2018
    */
    definition(
    name: “Garage Open and Interior Garage Door Open?”,
    namespace: “englanddh2”,
    author: “D. England”,
    description: “Notifies you when you have left a garage door and interior door open longer that a specified amount of time. So the pets don’t get out!”,
    category: “Safety & Security”,
    iconUrl: “https://s3.amazonaws.com/smartapp-icons/Meta/garage_contact.png”,
    iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Meta/garage_contact@2x.png”,
    iconX3Url: “https://s3.amazonaws.com/smartapp-icons/Meta/garage_contact@3x.png
    )

preferences {

section(“Monitor this garage door”) {
input “contact1”, “capability.contactSensor”, title: “Which garage door?”, required: true
}

section(“Monitor this interior door”) {
input “contact2”, “capability.contactSensor”, title: “Which interior door?”, required: true
}

section(“And notify me if it’s open for more than this many minutes (default 5)”) {
input “openThreshold”, “number”, description: “Number of minutes”, required: false
}

section(“Delay between notifications (default 10 minutes”) {
input “frequency”, “number”, title: “Number of minutes”, description: “”, required: false
}

section(“Via text message at this number (or via push notification if not specified”) {
input(“recipients”, “contact”, title: “Send notifications to”) {
input “phone”, “phone”, title: “Phone number (optional)”, required: false
}
}
}

def installed() {
log.trace “installed()”
subscribe()
}

def updated() {
log.trace “updated()”
unsubscribe()
subscribe()
}

def subscribe() {
subscribe(contact1, “contact.open”, door1Open)
subscribe(contact1, “contact.closed”, door1Closed)
subscribe(contact2, “contact.open”, door2Open)
subscribe(contact2, “contact.closed”, door2Closed)
}

def door2Open(evt) {
log.trace “door2Open($evt.name: $evt.value)”
def delay = (openThreshold != null && openThreshold != “”) ? openThreshold * 60 : 600
runIn(delay, doorOpenTooLong, [overwrite: true])
}

def door2Closed(evt) {
log.trace “door2Closed($evt.name: $evt.value)”
unschedule(doorOpenTooLong)
}

def doorOpenTooLong() {
def contact1State = contact.currentState(“contact1”)
def contact2State = contact.currentState(“contact2”)
def freq = (frequency != null && frequency != “”) ? frequency * 60 : 600

if (contact1State.value == “open”) {
if (contact2State.value == “open”) {
def elapsed = now() - contact2State.rawDateCreated.time
def threshold = ((openThreshold != null && openThreshold != “”) ? openThreshold * 60000 : 60000) - 1000
if (elapsed >= threshold) {
log.debug “Contact has stayed open long enough since last check ($elapsed ms): calling sendMessage()”
sendMessage()
runIn(freq, doorOpenTooLong, [overwrite: false])
} else {
log.debug “Contact has not stayed open long enough since last check ($elapsed ms): doing nothing”
}
} else {
log.warn “doorOpenTooLong() called but contact is closed: doing nothing”
}
}
}

void sendMessage() {
def minutes = (openThreshold != null && openThreshold != “”) ? openThreshold : 5
def msg = “{contact2.displayName} has been left open for {minutes} minutes. The dogs can get out the garage door!”
log.info msg
if (location.contactBookEnabled) {
sendNotificationToContacts(msg, recipients)
} else {
if (phone) {
sendSms phone, msg
} else {
sendPush msg
}
}
}


(Tony Fleisher) #8

You will need to have another look at the “passing data to the handler” section of the scheduling docs.


(Tony Fleisher) #9

i think you want state of “contact” attribute here (and other similar lines).


(Don England) #10

Ok. Like this contact.currentState(“contact”)


(Tony Fleisher) #11

Yes, but i think the device is contact1…


(Don England) #12

So, it is actually device.currentState(“attribute”)?? contact1.currentState(“contact”).


(Don England) #13

@TonyFleisher
Thank you. I got it to work and it works perfectly. I posted it to GitHub and pasting the link below for anyone else that is looking for something like this.

Dogs Can Get Out Garage SmartApp