Eliminate multiple notifications from mailbox


(Lindsey Fowler) #1

I’ve been using the mailbox app and we have a mailbox that is linked to other mailboxes. Is there any way to not send a notification if the motion has been triggered in the last X minutes? I’m happy to modify the code.


(Chrisb) #2

Yes, there’s ways to do that where it checks the current time and verifies that the program hasn’t been run which a specified number of minutes. Unfortunately I’m not well versed in how the code would work for that.

I’d end up tackling it up a bit more of a clumsy way. I’d add a virtual on/off tile to my setup. Then I’d modify this program to also ask for a on/off switch when it installs. Obviously you’d pick this on/off tile you made.

Then in the code, you have something like this (translated into plain English):

When there is movement: {
     Send a notificastion
}

We’re going to change it so it looks like this:

When there is movement: {
     If (The on/off tile is OFF) then do this: {
          Send the notification.
          Turn on the tile.
          runIn("turn off procedure", 5 minutes)
     }
}

Okay, so what does this do? When there is movement before a notification is send, the program checks to see if this virtual tile is turned on or off. If it is ON, then nothing else happens. If it’s OFF, then the program sends the notification. Next it turns on the tile. And finally it schedules a procedure to run in five minutes that will turn off the tile.

So for the next five minutes while that on/off tile is turned on whenever the sensor is bumped no new notification will be sent.

Like I said, it’s more clumsy than using the time constraints, but it does have one nice advantage: Let’s say you go on vacation… even if you put a hold on your mail with the post office, you’re sensor is still gonna get bumped when the neighbor’s get their mail delivered, right? So when you leave, simply go into the MobileApp and then on this button tile. Now the program is effectively disabled. You’ll never get a notification. And because the “turn me off in five minutes” procedure only gets scheduled if the tile was first off, it’ll never automatically reset.

When you come home, open the mobile app again, tap the tile to turn if off and you’re back in business.


(Tim Slagle) #3

Here ya go. Modified the original code to allow for minimum time between alerts and you can turn on and off alerts. Should be good to go now :smile: Let me know if it doesn’t work for some reason.

/**
 *  Mail Has Arrive Push with minimum time requirements
 *
 *  Copyright 2014 Tim Slagle
 *
 *  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: "Mail Has Arrive (Push) with minimum time requirements)",
    namespace: "tslagle13",
    author: "Tim Slagle",
    description: "Mail Has Arrived with Push Notifications and frequency minumum times.",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/mail_contact.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/mail_contact@2x.png"
)

preferences {
    section("When mail arrives...") {
        input "accelerationSensor", "capability.accelerationSensor", title: "Where?"
    }
    section("Notifications") {
        input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
      }
    
    section("Minimum time between actions (defaults to every event)") {
        input "frequency", "decimal", title: "Minimum time between actions (defaults to every event)", description: "Minutes", required: false
      }
}

def installed() {
    subscribe(accelerationSensor, "acceleration.active", accelerationActiveHandler)
}

def updated() {
    unsubscribe()
    subscribe(accelerationSensor, "acceleration.active", accelerationActiveHandler)
}

def accelerationActiveHandler(evt) {
    log.trace "$evt.value: $evt, $settings"

    // Don't send a continuous stream of text messages
    def deltaSeconds = 5
    def timeAgo = new Date(now() - (1000 * deltaSeconds))
    def recentEvents = accelerationSensor.eventsSince(timeAgo)
    log.trace "Found ${recentEvents?.size() ?: 0} events in the last $deltaSeconds seconds"
    def alreadySentNotification = recentEvents.count { it.value && it.value == "active" } > 1

    if (alreadySentNotification) {
        log.debug "Notification already sent within the last $deltaSeconds seconds"
    } else {
        log.debug "$accelerationSensor has moved, notifying via push"
        send("Mail has arrived!")
    }
}

private send(msg) {
    if (sendPushMessage != "no"){
        def lastTimePressure = state[frequencyKeyPressure(evt)]
        if (lastTimePressure == null || now() - lastTimeTemp >= frequency * 60000) {
            log.debug( "sending push message" )
            sendPush( msg )
            log.debug msg
            state[frequencyKey(evt)] = now()
        }    
    }
}

private frequencyKey(evt) {
    "lastActionTimeStamp"
}

(Edward Pope) #4

Just a word of thanks @tslagle13. Your code is helping me learn how to make some custom applications for my house :smile:


(Lindsey Fowler) #5

Awesome, thanks all! I’ll try these out ASAP!


(Tim Slagle) #6

Much appreciated sir! I love helping the community! Glad I can lend my knowledge, albeit limited. :smile:


(Brad B.) #7

Thanks again for posting this!

I’m looking to use this with an Ecotech door sensor. Would I have to edit your code to allow for an open/close sensor or could I edit the device type on the door sensor? (I don’t have experience doing either).


(Tim Slagle) #8

Yes. You’ll need to edit it to use the contact variable instead.


(Brad B.) #9

Thank you for yours help! I used to write html pages in notepad, so I think I can get a hang of this. I hope you don’t mind me throwing in a few coding questions here…

I went through your code and changed the references from the Accelerator Sensor to a Contact Sensor. Seemed easy enough. However, I’m stuck at the last part of your code that refers to pressure (frequencyKeyPressure and lastTimePressure). These didn’t look like they were defined within the SmartApp itself, so I’m guessing that these are preset variables that ST is looking for. Do I use something like “OpenThreshold” that I see in the “Left It Open” SmartApp?

Finally, comparing your code to the original one by Smartthings, I don’t see “sendSMS” in yours. Does yours have sms or just push? Frankly, I don’t think I’d enable sms anyway, just curious.

Thank you!


(Tim Slagle) #10

Sloppy code at its finest lol. I copy and pasted frm another app of mine and didn’t rewritre it to make sense lol. I could re write when I have time. But for now just know it’s needed to work lol.

Just didn’t add it. I never use SMS anyways so I didn’t add it. I can though.


(Brad B.) #11

Don’t look to add SMS on my behalf, I like to save it for the important stuff like water leaks or smoke alarms!

So, no need to modify the “Pressure” entries to work with a contact sensor? It’s 5 degrees outside right now, so I haven’t been able to install or test the thing on the mailbox yet.


(Tim Slagle) #12

heat wave!!! i’m sitting in -7 real temp. lol


(Brad B.) #13

I finally had time to test my modified SmartApp and nothing seems to be happening… no notifications at all… This must be just a bit beyond my experience level. Maybe I’ll try to modify the standard Smartthings one and work from there.


(Brad B.) #15

Thank you! I’ll test it out tonight. :slight_smile: After the “//Don’t send a continuous stream of text messages” line, there is the code: “$accelerationSensor has moved, notifying via push” Will that work with a contact sensor?


(Tim Slagle) #16

yeah thats just a log. i maidified this in like 3 seconds. its a little sloppy lol.


(Tim Slagle) #17

Cleaned it up.

/**
 *  Mail Has Arrive Push with minimum time requirements
 *
 *  Copyright 2014 Tim Slagle
 *
 *  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: "Mail Has Arrived (Push) with minimum time requirement (contact))",
    namespace: "tslagle13",
    author: "Tim Slagle",
    description: "Mail Has Arrived with Push Notifications and frequency minumum times.",
    category: "My Apps",
	iconUrl: "https://s3.amazonaws.com/smartapp-icons/Meta/mail_contact.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Meta/mail_contact@2x.png"
)

preferences {
	section("When mail arrives...") {
		input "contactSensor", "capability.contactSensor", title: "Where?"
	}
    section("Notifications") {
        input "sendPushMessage", "enum", title: "Send a push notification?", metadata:[values:["Yes","No"]], required:false
  	}
    
    section("Minimum time between actions (defaults to every event)") {
        input "frequency", "decimal", title: "Minimum time between actions (defaults to every event)", description: "Minutes", required: false
  	}
    section("Settings") {
    	label title: "Assign a name", required: false
  	}
}

def installed() {
	subscribe(contactSensor, "contact.open",contactActiveHandler)
}

def updated() {
	unsubscribe()
	subscribe(contactSensor, "contact.open", contactActiveHandler)
}

def contactActiveHandler(evt) {
	log.trace "$evt.value: $evt, $settings"

	// Don't send a continuous stream of text messages
	def deltaSeconds = 5
	def timeAgo = new Date(now() - (1000 * deltaSeconds))
	def recentEvents = contactSensor.eventsSince(timeAgo)
	log.trace "Found ${recentEvents?.size() ?: 0} events in the last $deltaSeconds seconds"
	def alreadySentNotification = recentEvents.count { it.value && it.value == "active" } > 1

	if (alreadySentNotification) {
		log.debug "Notification already sent within the last $deltaSeconds seconds"
	} else {
		log.debug "$contactSensor has moved, notifying via push"
		send("Mail has arrived!")
	}
}

private send(msg) {
	if (sendPushMessage != "no"){
    	def lastTime = state[frequencyKey(evt)]
		if (lastTime == null || now() - lastTime >= frequency * 60000) {
			log.debug( "sending push message" )
			sendPush( msg )
			log.debug msg
            state[frequencyKey(evt)] = now()
        }    
    }
}

private frequencyKey(evt) {
	"lastActionTimeStamp"
}

#19

Thanks for the code. FYI you left an extra “name the app” box in there. The first one is the one that works.