Programming for Humidity Sensors (not % issue)

I am trying to create a custom smartapp to control a switch based on a temperature and humidity sensors, however I am having difficulties pulling the humidity value from the sensor (this is not related to the “%” issue).

I can pull the current readings from a virtual sensor using:

    ...
def updated() {
    	unsubscribe()
        subscribe(humiditySensor, "humidity", "humidityHandler")
    }
def humidityHandler(evt) {
    	def test = evt.value
    	log.debug "current humidity is $test"
    }

but not using something along the lines of:

    ...
def humidityHandler() {
    	def test = humiditySensor.latestValue("humidity")
    	log.debug "current humidity is $test"
    }

The IDE is providing me with an error groovy.lang.MissingMethodException: No signature of method… Can someone help me understand what I am missing?

Thank you in advance for the help!

Since you are in a event handler, try doing it this way (not sure why your .latestValue doesn’t work and mine does):

definition(
    name: "Virtual Dehumidifier",
    namespace: "My Apps",
    author: "Barry Burke",
    category: "Green Living",
    description: "Turns on a humidifier when humidity gets too high, back off when it reaches the target again.",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png"
)
preferences {
    section("Humidity") {
        input "humiditySensor", "capability.relativeHumidityMeasurement", title: "Which Sensor?"
        input "desiredHumidity", "number", title: "Desired Humidity?"
        input "dehumidifierSwitch", "capability.switch", title: "Which Switch?"
    }
}
def installed() {
    initialize()
}
def updated() {
    unsubscribe()
    initialize()
}
def initialize() {
    subscribe(humiditySensor, "humidity", humidityHandler)
    log.debug "Initialized... current humidity is ${humiditySensor.latestValue("humidity")}%, max humidity is ${desiredHumidity*1.05}, dehumidifier is ${dehumidifierSwitch.latestValue( "switch" )}"
    dehumidifierSwitch.poll()             // Update power display
}
def humidityHandler(evt) {
    log.debug "Humidity: $evt.value, $evt"
    if (Double.parseDouble(evt.value.replace("%", "")) <= desiredHumidity) {
        if ( dehumidifierSwitch.latestValue( "switch" ) != "off" ) {
            log.debug "Turning dehumidifier off"
            dehumidifierSwitch.off()
        }
    }
    else if (Double.parseDouble(evt.value.replace("%", "")) > desiredHumidity ) {
        if ( dehumidifierSwitch.latestValue( "switch" ) != "on" ) {
            log.debug "Turning dehumidifier on"
            dehumidifierSwitch.on()
        }  
    }
    else {
        log.debug "Current humidity is ${evt.value}"
    }
    dehumidifierSwitch.poll()                // every time the humidity changes, poll the switch for power updates
}

In your second block, you need the “evt” parameter. That could be what the MissingMethodException is trying to tell you.

The .latestValue should work as you have it, but I’m guessing it is not even getting into that method.

Thanks for the responses. I am not sure if I am wording this correctly, but my ultimate goal is to compare a current versus targeted temperature AND a current versus targeted humidity to activate a switch(es).

Is there a way to compare values from two different types of sensors in one event handler? Using an evt parameter seems to limit the number of things I can get data from. Alternatively, is there a way to pass values from one event handler into another?

...

def updated() {
	unsubscribe()
	eventSubscriptions()
        //compareToTargets() 
}
 
def eventSubscriptions() {
	subscribe(humiditySensor, "humidity", "humidityHandler")
	subscribe(tempSensor, "temperature", "temperatureHandler")
}
    
def humidityHandler(evt) {
	def currentHumidity = Double.parseDouble(evt.value.replace("%", ""))
	log.debug "current event handler humidity is $currentHumidity"
}

def temperatureHandler(evt) {
	def currentTemperature = tempSensor.latestValue("temperature")
	log.debug "current event handler temperature is $currentTemperature"
}

def compareToTargets() {
	
    //compare (current and target TEMP) with (current and target HUMIDITY) 
	
}

Simple:

...
subscribe( humiditySensor, "humidity", "eventHandler")
subscribe(tempSensor, "temperature", "eventHandler")
...
}
def eventHandler(evt) {
    compareToTargets( humiditySensor.latestValue("humidity"), tempSensor.latestValue("temperature"))
    ....
}
def compareToTargets( humidity, temperature) {
...
     if ((humidity > settings.targetHumidity) && (temperature>settings.targetTemp)) {
         do_whatever()
     }
}

New here as well, have you looked at other smart apps to see how they pulled that data?

I looked the SmartApp examples and code on the community boards and GitHub but could not find anything that used humidity in parallel with another sensor’s data. All of the implementations of humidity sensors I found used an evt.value to pull the humidity data.

For example, I get a NumberFormatException error on the humidity line of this code…

...
def eventHandler(evt) {

    def currentHumidity = humiditySensor.latestValue("humidity")	
    def currentTemperature = tempSensor.latestValue("temperature")	
   
	log.debug "humidity:$currentHumidity  temperature: $currentTemperature"
    
}

…but it will run and provide me with a temperature when I comment out the humidity.

Truly baffling, because the log.debug statement below works in my “Smart Dehumidifier” SmartApp - it shows the humidity at the time of installation/preferences changes.

    def initialize() {
        subscribe(humiditySensor, "humidity", humidityHandler)
        log.debug "Initialized... current humidity is ${humiditySensor.latestValue("humidity")}%, max humidity is ${desiredHumidity*1.05}, dehumidifier is ${dehumidifierSwitch.latestValue( "switch" )}"
        dehumidifierSwitch.poll()             // Update power display
    }

Suggestion: change the pseudo-code I posted above to this:

compareToTargets( ${humiditySensor.latestValue("humidity")}, tempSensor.latestValue("temperature"))

and see if it works.

I appreciate the help, but still no luck - I think my IDE is cursed! Maybe I am missing something else…here is the code I am running (sorry the tabs didn’t copy/paste totall correct):

preferences {

	section("Select humidity sensor...") {
    	input "humiditySensor", "capability.relativeHumidityMeasurement"
    }
    section("Select humidity sensor...") {
    	input "tempSensor", "capability.temperatureMeasurement"
    }
	section("Turn on/off this switch...") {
    	input "switch1", "capability.switch"
    }
}
 
def installed() {
	log.debug "Installed with settings: ${settings}"
 	subscribe(humiditySensor, "humidity", "eventHandler")
    subscribe(tempSensor, "temperature", "eventHandler")    
}
 
def updated() {
	unsubscribe()
 	subscribe(humiditySensor, "humidity", "eventHandler")
    subscribe(tempSensor, "temperature", "eventHandler")    
}

def eventHandler(evt) {
	
    def currentHumidity = {humiditySensor.latestValue("humidity")}
    def currentTemperature = tempSensor.latestValue("temperature")	
	
    log.debug "temperature: $currentTemperature"
    log.debug "humidity: $currentHumidity"
    
}

Debugging Notes:

  • Commenting out references to humidity works (i.e., temperature will
    output to console).
  • Commenting out references to temperature does not work (i.e., humidity will not display…with or without curly brackets). The error is a NumberFormatException.
  • Using evt.value with the temperature references commenting out does work (i.e., humidity will display).

I’m wondering if you NumberFormatException is due to a bug with the virtual humidity device where it is returning the ‘%’ character instead of just a number. Earlier it looks like you had that:

I’m hoping to get that bug fixed today so it returns only the number value.

I just fixed the % issue. Let me know if that fixes your app.

Thank Matt - it works! Apparently my subject was incorrect…it was the percent issue :smile:

preferences {

	section("Select humidity sensor...") {
    	input "humiditySensor", "capability.relativeHumidityMeasurement"
    }
    section("Select humidity sensor...") {
    	input "tempSensor", "capability.temperatureMeasurement"
    }
	section("Turn on/off this switch...") {
    	input "switch1", "capability.switch"
    }
}
 
def installed() {
	log.debug "Installed with settings: ${settings}"
 	subscribe(humiditySensor, "humidity", "eventHandler")
    subscribe(tempSensor, "temperature", "eventHandler")    
}
 
def updated() {
	unsubscribe()
 	subscribe(humiditySensor, "humidity", "eventHandler")
    subscribe(tempSensor, "temperature", "eventHandler")    
}

def eventHandler(evt) {
	
    def currentHumidity = humiditySensor.latestValue("humidity")
   	def currentTemperature = tempSensor.latestValue("temperature")	
	
    log.debug "temperature: $currentTemperature"
    log.debug "humidity: $currentHumidity"
    
    compareto(currentHumidity, currentTemperature)
}

def compareto(temp, humid) {

	def test = temp + humid
    log.debug "test: $test"
}

Results:
1:20:40 PM: debug test: 80
1:20:40 PM: debug humidity: 50
1:20:40 PM: debug temperature: 30

This is exactly what I am trying to accomplish, but am unable to decide on a humidity sensor. Does anyone have any recommendations. I was looking at the Everspring ST814 with mixed reviews, and ZOOZ 4 in 1 without any.

2 Likes

The zooZ 4-1 ZSE-40 is pretty good. I have a couple of them now as well as different models from Aeon Labs. I like the simplicity and accuracy of the zooZ unit and the price is good. I wrote a device handler for it that handles all functionality and configuration options through preferences. Sending configuration is also handled seamlessly now. ( I need to revisit my Aeon sensor code)

Code repository is here https://github.com/robertvandervoort/SmartThings

Hi! I am a novice user and believe I am trying to do the same thing as you were with this app.

I have a dehumidifier in an outbuilding that I would like to turn on only above a certain temperature and then only if the humidity if above a certain %. If your app does that, would you mind sharing the complete code?

Thanks! Eric