Calculating Time Difference Between Two Device Events?

Having some trouble getting my first SmartApp to work…

Goal:
When bedroom door is closed, capture time of the event.
When bedroom motion sensor state changes to inactive, capture time of the event.
If the time difference between motion inactive and door closing is less than X seconds, turn off bedroom light.

Use Case:
My take at an occupancy sensor. We keep our bedroom door closed at all times to keep the dog from getting on our bed. If we enter the room and close the door behind us, there will be motion for at least X seconds after the door is closed - even if we go lay down on the bed. If we leave the room, motion will go inactive within just a few seconds after the door is closed. Obviously not perfect and has it’s loopholes, but this is the goal!

Problem:
It’s not working… And I don’t know what isn’t working because my live logging isn’t reporting ANY activity at all (open to any thoughts on why that might be as well!).

Code:

def contactHandler(evt) {
	if("closed" == evt.value){
    	log.debug "ContactHandler called: $evt"
   		def doorClosed = ${evt.date.time}
    }
    else {
        // Door Opened; just log it and do nothing
        log.debug "Door was opened."
    }
}

def motionStoppedHandler(evt) {
    log.debug "motionStoppedHandler called: $evt"
    def motionStopped = ${evt.date.time}
    def elapsed = motionStopped - doorClosed
    def threshold = 1000 * seconds
    
    if (elapsed <= threshold) {
    	log.debug "Time between door close and motion stop ($elapsed ms):  turning switch off"
        theswitch.off()
    }
    else {
        // Motion active; just log it and do nothing
        log.debug "Motion is active, do nothing."
    }       
}

I’m new to SmartThings and groovy, so I am guessing that I am just missing something simple? Any thoughts?

The

def motionStoppedHandler(evt) { ... }

will not have access to the variable defined in

def contactHandler(evt) { ... }

The scope of doorClosed is limited to the contactHandler method.

You need to use the state object to share the data…

def contactHandler(evt) {
	if("closed" == evt.value){
    	log.debug "ContactHandler called: $evt"
   		state.doorClosed = ${evt.date.time}
    }
    else {
        // Door Opened; just log it and do nothing
        log.debug "Door was opened."
    }
}

def motionStoppedHandler(evt) {
    log.debug "motionStoppedHandler called: $evt"

    if(state.doorClosed == null) {
          log.debug "state.doorClosed is null, exiting..."
          return
    }

    def motionStopped = ${evt.date.time}
    def elapsed = motionStopped - state.doorClosed
    def threshold = 1000 * seconds
    
    if (elapsed <= threshold) {
    	log.debug "Time between door close and motion stop ($elapsed ms):  turning switch off"
        theswitch.off()
    }
    else {
        // Motion active; just log it and do nothing
        log.debug "Motion is active, do nothing."
    }       
}

Thanks Eric - I had a feeling that was the issue but had no idea how to fix it…

Much appreciated!

1 Like