Trouble triggering def someEvent(evt) function


(Camden Krupala) #1

New to the forums and SmartThings. I’ve had some programing experience in Java, but I am an Electrical Engineer by Major (Junior). This might be something ridiculously obvious that I am missing but I figured it didn’t hurt to post and introduce myself too! Basically trying to use the subscribe command to gather humidity readings in the future. I have typed it as shown below:

subscribe(humidity, “humidity”, showerEvent)

I go on to add:

def showerEvent(evt) {
//CODE HERE
}

For some reason I never get to the actually showerEvent function and it presumably hangs. I added a couple log.trace calls to figure out where my code starts and stops.

Any help would be greatly appreciated! And feel free to correct my vocabulary if I am naming/describing something wrong.

Thanks guys!


(Camden Krupala) #2
/**
 *  In the Shower
 *
 *  Copyright 2015 Camden Krupala
 *
 *  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.
 *
 */
definition(
    name: "In the Shower",
    namespace: "",
    author: "Camden Krupala",
    description: "Takes the difference in humidity from 10 minutes ago and texts I'm taking a shower if it has increased by 10%",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")


preferences {
	section("Humidity sensor to monitor") {
		
        input "humiditySensor", "capability.relativeHumidityMeasurement", //Select sensor
        	title: "Humidity sensors", multiple: false 
	}
    section("Percent difference between measurements") {
    	
        input "percentDif", "integer", title: "Enter a positive integer value", required: true
    }
    section("Time difference between measurements") {
    	
        input "timeDif", "integer", title: "Enter a positive integer value", required: true
    }
    section("Notifications") {
    	input "enablePushMessage", "enum", title: "Send push notification?", metadata:[values:["Yes","No"]], required:false
        input "phoneNum", "phone", title: "Send a text message?", required: false
        
        
    }
}

def installed() {

	initialize()
}

def updated() {

	unsubscribe()
    initialize()
	
}

def initialize() {

	subscribe(humiditySensor, "humidity", humidityEvent)
    state.currentHumidity = 0
    state.pastHumidity = 0
    state.percentComp = 0
    state.percentDif = 0
    
}

def humidityEvent(evt) {
    def isTakingShower = "false"
    def deltaMinutes = 30
    log.info "Variables initialized"
    while (true) {
    	state.pastHumidity = Double.parseDouble(evt.value.replace("%", ""))
        log.info "1st humidity value saved: ${state.pastHumidity}. Waiting for next value"
        wait (1000 * 60 * timeDif)
        state.currentHumidity = Double.parseDouble(evt.value.replace("%", ""))
    	log.info "2nd humidity value saved: ${state.pastHumidity}"
        state.percentComp = ( ( ( state.currentHumidity - state.pastHumidity ) / state.pastHumidity ) * 100 )
        if (state.percentComp >= state.percentDif){
        	log.info "Percent difference between readings is ${state.percentComp}. Proceeding to notification"
    		if (alreadySentSms) {
            	log.info "Notification already sent within the last ${deltaMinutes} minutes"
            } else {
            	log.info "Sending SMS to phone."
                send("User is in the shower")
            }
    	}
    }
}

private send(msg) {
	if (enablePushMessage != "No") {
    	log.info "Sending push message"
        sendPush(msg)
    }
    if (phoneNum) {
    	log.info "Sending text message"
        sendSms(phoneNum,msg)
    }
    log.debug msg
}

(Gary D) #3

First, you said you added some tracing, but never mentioned what the live logging showed. Many would help you, but don’t have a device to measure humidity - so we are dependent on your logs to take educated guesses.

Second, when posting code in the forum, PLEASE surround it with [code] [/code] tags. For example:

[code]
your code pasted here
[/code]

(When you do it without the escaping I used, it’ll format it like this:

your code pasted here

)


(Camden Krupala) #4

Thanks! Made that change to my code post. I have to run errands real quick but I will post the logs as soon as I am back. I probably need to add more tracers to pinpoint the issue so I’ll do that too before I post.


(Patrick Stuart [@pstuart]) #5

the capability “humidity” doesn’t exist that is why nothing fires.

replace “humidity” with “capability.relativeHumidityMeasurement” and it should work.


(Camden Krupala) #6

I forgot to state the purpose the code. Using a humidity sensor in the shower room I would like to take a humidity reading followed by another one after some delta time. I want to compare this delta humidity to a set value and if it is greater by a significant amount I want to send a push notification or sms.

Made those changes to the code:

definition(
    name: "In the Shower",
    namespace: "grilledpeaches",
    author: "Camden Krupala",
    description: "Takes the difference in humidity from X minutes ago and texts I'm taking a shower if it has increased by Z%",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png",
    iconX3Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")


preferences {
	section("Humidity sensor to monitor") {
		
        input "humiditySensor", "capability.relativeHumidityMeasurement", //Select sensor
        	title: "Humidity sensors", multiple: false 
	}
    section("Percent difference between measurements") {
    	
        input "percentDif", "integer", title: "Enter a positive integer value", required: true
    }
    section("Time difference between measurements") {
    	
        input "timeDif", "integer", title: "Enter a positive integer value", required: true
    }
    section("Notifications") {
    	input "enablePushMessage", "enum", title: "Send push notification?", metadata:[values:["Yes","No"]], required:false
        input "phoneNum", "phone", title: "Send a text message?", required: false
        
        
    }
    log.info "Preference() DONE"
}

def installed() {

	initialize()
    log.info "Installed() DONE"
}

def updated() {

	unsubscribe()
    initialize()
	log.info "Updated() DONE"
}

def initialize() {

	subscribe(humiditySensor, "capability.relativeHumidityMeasurement", humidityEvent)
    state.currentHumidity = 0
    state.pastHumidity = 0
    state.percentComp = 0
    state.percentDif = 0
    log.info "Initialize() DONE"
    
}

def humidityEvent(evt) {
	log.info "Begin humidityEvent"
    def isTakingShower = "false"
    def deltaMinutes = 30
    log.info "Variables initialized"
    while (true) {
    	state.pastHumidity = Double.parseDouble(evt.value.replace("%", ""))
        log.info "1st humidity value saved: ${state.pastHumidity}. Waiting for next value"
        wait (1000 * 60 * timeDif)
        state.currentHumidity = Double.parseDouble(evt.value.replace("%", ""))
    	log.info "2nd humidity value saved: ${state.pastHumidity}"
        state.percentComp = ( ( ( state.currentHumidity - state.pastHumidity ) / state.pastHumidity ) * 100 )
        if (state.percentComp >= state.percentDif){
        	log.info "Percent difference between readings is ${state.percentComp}. Proceeding to notification"
    		if (alreadySentSms) {
            	log.info "Notification already sent within the last ${deltaMinutes} minutes"
            } else {
            	log.info "Sending SMS to phone."
                send("User is in the shower")
            }
    	}
    }
}

private send(msg) {
	if (enablePushMessage != "No") {
    	log.info "Sending push message"
        sendPush(msg)
    }
    if (phoneNum) {
    	log.info "Sending text message"
        sendSms(phoneNum,msg)
    }
    log.debug msg
}

I’m not sure how the code is supposed to proceed but it seems to get hung up in Preference()
Here is the log:

‎4‎:‎09‎:‎30‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Updated() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Initialize() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: trace capability.relativeHumidityMeasurement from Bathroom was provided with humidityEvent...creating subscription 

‎4‎:‎09‎:‎29‎ ‎PM: trace In the Shower is attempting to unsubscribe from all events 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎29‎ ‎PM: info Preference() DONE 

‎4‎:‎09‎:‎24‎ ‎PM: info Preference() DONE 

(Patrick Stuart [@pstuart]) #7

what device are you using for humidity? How often does it poll / parse humidity changes?

What happens when you test in the simulator to a virtual humidity device? does anything log for the humidityevent?


(Mike Maxwell) #8

Just a thought, as I’m dinking with a smart app looking at humidity sensors in the shower as well.
The potential issue with waiting x amount of time and trying to get a previous sample is just that, you are at the mercy of the reporting interval of the device…
Maybe consider using another humidity sensor in the house as your base line?, in my case I’m using the one in my thermostat as it’s not subject to localized changes.
Then I set a delta above the baseline humidity so once the shower humidity exceeds that threshold we fire the “do something” stuff…
This method doesn’t rely on calculating a rate of rise over time. if (currentShowerHumidity > (currentBaselineHumidity + triggerOffset)) makeItGobaby(), that type of thing.


Rooms Manager: Smarter Rooms: Personalized home automation with Occupancy
(Camden Krupala) #9

Gotcha, I had a feeling there might be limitations like that. Thankfully, I have another temp/humidity sensor that I can use as a baseline. I’ll incorporate those changes see if that helps.

Nothing logs for the humidityevent when I use the virtual device unfortunately.


(Patrick Stuart [@pstuart]) #10

Your subscribe line needs to subscribe to the “Humidity” state not the capability

subscribe(humiditySensor, “humidity”, humidityEvent)


#11

@rayzurbock has a custom smartapp that uses a humidity sensor to track trends so it can guess whether someone is taking a shower. Might be of interest.


(Camden Krupala) #12

Should be fairly easy to repurpose and add a sms/pushnotification event. I do have a question regarding the use of multiple sensors (if I wanted to go the simple compare the humidity of two sensors and take an action route): If I wanted to compare the humidity of one sensor to another can I simply subscribe them to the same event like so:

subscribe(humiditySensor1, "humidity1", humidityEvent)
subscribe(humiditySensor2, "humidity2", humidityEvent)

(Mike Maxwell) #13

You don’t really need to.
You can use one deviceList/subscription then do this to get a maximum from all of them in one shot.

 def maxCrnt = activeHumidityDevices.currentValue("humidity").max()

I know groovy is annoying, but it does have some very powerful features.