Delayed Notification

smartapp

(Pacman5633) #1

Hello,
I have two hydroponic gardens that get watered for a set number of minutes, normally 15, and then no water for a set number of minutes, normally 15. The water is pumped to the top of the gardens and then drips through holes onto the roots.

Anyway, I want to be able to use a water sensor to monitor the gardens and notify me if they haven’t been watered after a set number of minutes, which I enter while installing the app. I have attempted to use both schedule((now() + (waterTime600000)), sendMessage(evt)) and runIn(60waterTime, sendMessage()). The idea being that when water is detected it schedules the event to send the message during the next watering time. For example, if the cycle is 15 on/15 off, I schedule the event for 45 minutes from when water is detected. This means that the message should go out in the middle of the next water cycle. However, between scheduling the event and the time it should occur, there will be another wet event, which should overwrite the schedule and always keep it out in front, until, that is, something happens and the gardens are not watered and the even occurs.

However, the message is sent as soon as water is detected. Can you take a look at see if you can see what I am missing here. Do I need to change the sendMessage() method from private sendMessage() to def sendMessage()?

Thank you,
Jerry

definition(
name: “TowerGardens 1.26”,
namespace: “”,
author: “Gerald Mabrito”,
description: “Warns when the Tower Gardens have not been watered in a set number of minutes.”,
category: “Safety & Security”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Meta/water_moisture.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Meta/water_moisture@2x.png
)

preferences {
section(“Choose one or more, when…”){
input “water”, “capability.waterSensor”, title: “Water Sensor Wet”, required: false, multiple: true
}

    //Allows the user to determine the maximum number of minutes between watering before getting a notification.
section("Set the max number of minutes between watering..."){
	input "waterTime", "decimal", title: "Set Max Time Without Water"
}

section("Send this message (optional, sends standard status message if not specified)"){
	input "messageText", "text", title: "Message Text", required: false
}
section("Via a push notification and/or an SMS message"){
	input("recipients", "contact", title: "Send notifications to") {
		input "phone", "phone", title: "Phone Number (for SMS, optional)", required: false
		paragraph "If outside the US please make sure to enter the proper country code"
		input "pushAndPhone", "enum", title: "Both Push and SMS?", required: false, options: ["Yes", "No"]
	}
}

}

def installed() {
log.debug "Installed with settings: ${settings}"
subscribeToEvents()
}

def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribeToEvents()
}

def subscribeToEvents() {
subscribe(water, “water.wet”, eventHandler)
}

def eventHandler(evt) {
//schedule((now() + (waterTime600000)), sendMessage(evt))
runIn(60
waterTime, sendMessage())

}

private sendMessage() {
String msg = messageText
Map options = [:]

if (!messageText) {
	msg = "You had better check on this!!!!"
	options = [translatable: true, triggerEvent: evt]
}
log.debug "$evt.name:$evt.value, pushAndPhone:$pushAndPhone, '$msg'"

if (location.contactBookEnabled) {
	sendNotificationToContacts(msg, recipients, options)
} else {
	if (!phone || pushAndPhone != 'No') {
		log.debug 'sending push'
		options.method = 'push'
		//sendPush(msg)
	}
	if (phone) {
		options.phone = phone
		log.debug 'sending SMS'
		//sendSms(phone, msg)
	}
	sendNotification(msg, options)
}

}


( I hate Mondays) #2

Easy. When you give the second parameter sendMessage(), it gets evaluatedright away. Since you included the (), it will actually evaluate it aka run that function. You need to give a reference to the function itself, not its resulting value. Simply remove the () and pass sendMessage as the second parameter. Again, no () as that would evaluate the function on the fly and pass the returned value to runIn. That is not what you need :wink:


(Pacman5633) #3

Thank you for looking this over and your reply. Unfortunately, as soon as I take away the, “(evt)”, from runIn(60*waterTime, delaySendMessage(evt)), it stops working. I added this method in hopes of calling it without the “(evt)” and leaving that in the sendMessage(evt) method call. However, either way, without “(evt)”, it doesn’t send a message and with it, it sends the message right way.

Any thoughts?

Thanks again,
Jerry

PS - Here’s the current, code that sends a message but instantly.

preferences {
section(“Choose one or more, when…”){
input “water”, “capability.waterSensor”, title: “Water Sensor Wet”, required: false, multiple: true
}
section(“Send this message (optional, sends standard status message if not specified)”){
input “messageText”, “text”, title: “Message Text”, required: false
}
//Allows the user to determine the maximum number of minutes between watering before getting a notification.
section(“Set the max number of minutes between watering…”){
input “waterTime”, “decimal”, title: “Set Max Time Without Water”
}
section(“Via a push notification and/or an SMS message”){
input(“recipients”, “contact”, title: “Send notifications to”) {
input “phone”, “phone”, title: “Phone Number (for SMS, optional)”, required: false
paragraph "If outside the US please make sure to enter the proper country code"
input “pushAndPhone”, “enum”, title: “Both Push and SMS?”, required: false, options: [“Yes”, “No”]
}
}
section(“Minimum time between messages (optional, defaults to every message)”) {
input “frequency”, “decimal”, title: “Minutes”, required: false
}
}

def installed() {
log.debug "Installed with settings: ${settings}"
subscribeToEvents()
}

def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribeToEvents()
}

def subscribeToEvents() {
subscribe(water, “water.wet”, eventHandler)
}

def eventHandler(evt) {
log.debug “Notify got evt ${evt}”

//schedule((now() + (waterTime*600000)), delaySendMessage(evt))
runIn(60*waterTime, delaySendMessage)

}

def delaySendMessage(){
sendMessage(evt)
}

private sendMessage(evt) {
String msg = messageText
Map options = [:]

if (!messageText) {
	msg = "You had better check on this!!!!"
	options = [translatable: true, triggerEvent: evt]
}
log.debug "$evt.name:$evt.value, pushAndPhone:$pushAndPhone, '$msg'"

if (location.contactBookEnabled) {
	sendNotificationToContacts(msg, recipients, options)
} else {
	if (!phone || pushAndPhone != 'No') {
		log.debug 'sending push'
		options.method = 'push'
		//sendPush(msg)
	}
	if (phone) {
		options.phone = phone
		log.debug 'sending SMS'
		//sendSms(phone, msg)
	}
	sendNotification(msg, options)
}

if (frequency) {
	state[evt.deviceId] = now()
}

}