What state does Smartthings retrieve when no device is selected?

Hello everyone,

I’m sorry if this is the wrong place to post this question.

What state does Smartthings retrieve when no device is selected?

For example, if I use the following code to get the state of a switch, def switch1check = switch1.currentState(“switch”), but I have not selected a switch in my setup, what state does Smartthings retrieve?

I have written some code that will turn on 2 switches when a motion sensor senses motion and then set a sleep timer to turn the switches off. The sleep timer will not activate for switches that were already on when the motion was detected.

It all works great as long as I select 2 switches but I want the second switch to be optional. The problem is that if I don’t select the second switch, nothing happens. This is because my program checks the state of both switches before determining which switches to turn on and set the sleep timer for. So if I don’t have the second switch selected, it isn’t grabbing an “on” or “off” state. So what does it retrieve?

Thanks

You didn’t include your code, so i can’t say for sure, but It probably is dying with an error like null pointer exception. If the configured device is optional, Your code should check that it is a valid device before trying to dereference it.

1 Like

Live logging in the IDE should help you see what is happening.

Sorry, but how do I do that?

I ran the simulator, got his error: c97f8c5e-0736-425c-a466-845c6d375db4 9:40:15 AM: error java.lang.NullPointerException: Cannot invoke method currentState() on null object @line 71 (doorOpenedHandler

Line 71: def switch2check = switch2.currentState(“switch”) //get switch2 state

This makes sense, it just causes an error when it tries to grab the state of the unselected switch. But as you can see in my code, I have made the second switch not required. Anyway around this?

Posting code is great, but please use a code block to do so. Some of our community members, including me, depend on text to speech software. When you use a code block we can just skip the whole thing. But still hear any additional comments you might have at the end. :sunglasses:

Sorry, I don’t know how to do that. Any link to explain it or is it something simple?

Edit: Never mind, google helped me figure out the code block. Thanks for letting me know though.

1 Like

Here is the code. Sorry if its sloppy, I haven’t coded in a long time.

preferences {
    section("Turn on when Door Opened:") {
        input "thecontact", "capability.contactSensor", required: true, title: "Multi Sensor?"
    }
    section("Turn off after...") {
        input "minutes", "number", required: true, title: "Minutes?"
    }
    section("Select a light") {
        input "switch1", "capability.switchLevel", required: true
		input "brightness1", "number", title: "Brightness"
    }
    section("Select another light") {
        input "switch2", "capability.switchLevel", required: false
        input "brightness2", "number", title: "Brightness", required: false
    }
    section("Program active between these hours") {
    	input "fromTime", "time", title:"From"
        input "toTime", "time", title: "To"
	}
    section("Program active on these days") {
        input "days", "enum", title: "Select Days of the Week", required: true, multiple: true, options: ["Monday": "Monday", "Tuesday": "Tuesday", "Wednesday": "Wednesday", "Thursday": "Thursday", "Friday": "Friday", "Saturday": "Saturday", "Sunday": "Sunday"]
    }
}

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

	initialize()
}

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

	unsubscribe()
	initialize()
}

def initialize() {
    subscribe(thecontact, "contact.open", doorOpenedHandler)
}

def doorOpenedHandler(evt) {
    log.debug "doorOpenedHandler called: $evt"
  	def switch1check = switch1.currentState("switch") //get switch1 state
    def switch2check = switch2.currentState("switch") //get switch2 state
    def df = new java.text.SimpleDateFormat("EEEE")
        // Ensure the new date object is set to local time zone
        df.setTimeZone(location.timeZone)
        def day = df.format(new Date())
        def dayCheck = days.contains(day)
        if (dayCheck){
            def between = timeOfDayIsBetween(fromTime, toTime, new Date(), location.timeZone)
            if (between){
    			if(switch1check.value != "on" && switch2check.value != "on"){ //if switch1 and switch2 are not on, continue
                    switch1.on()
                    switch1.setLevel(brightness1)
                    switch2.on()
                    switch2.setLevel(brightness2)
                    runIn(60 * minutes, lightsOff)
             	}
            	else if(switch1check.value != "on" && switch2check.value == "on"){ //if switch1 is not on and switch2 is on, continue
                    switch1.on()
                    switch1.setLevel(brightness1)
                    runIn(60 * minutes, light1Off)
				}
                else if(switch1check.value == "on" && switch2check.value != "on"){ //if switch1 is on and switch2 is not on, continue
                    switch2.on()
                    switch2.setLevel(brightness2)
                    runIn(60 * minutes, light2Off)
				}else { //switch1 and switch2 are on, do nothing
        		}
			}
    	}
}

def lightsOff() {
	switch1.off()
	switch2.off()
}

def light1Off() {
	switch1.off()
}

def light2Off() {
	switch2.off()
}
preferences {
    section("Turn on when Door Opened:") {
        input "thecontact", "capability.contactSensor", required: true, title: "Multi Sensor?"
    }
    section("Turn off after...") {
        input "minutes", "number", required: true, title: "Minutes?"
    }
    section("Select a light") {
        input "switch1", "capability.switchLevel", required: true
		input "brightness1", "number", title: "Brightness"
    }
    section("Select another light") {
        input "switch2", "capability.switchLevel", required: false
        input "brightness2", "number", title: "Brightness", required: false
    }
    section("Program active between these hours") {
    	input "fromTime", "time", title:"From"
        input "toTime", "time", title: "To"
	}
    section("Program active on these days") {
        input "days", "enum", title: "Select Days of the Week", required: true, multiple: true, options: ["Monday": "Monday", "Tuesday": "Tuesday", "Wednesday": "Wednesday", "Thursday": "Thursday", "Friday": "Friday", "Saturday": "Saturday", "Sunday": "Sunday"]
    }
}

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

	initialize()
}

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

	unsubscribe()
	initialize()
}

def initialize() {
    subscribe(thecontact, "contact.open", doorOpenedHandler)
}

def doorOpenedHandler(evt) {
    log.debug "doorOpenedHandler called: $evt"
  	def switch1check = switch1.currentState("switch") //get switch1 state
    def switch2check = switch2.currentState("switch") //get switch2 state
    def df = new java.text.SimpleDateFormat("EEEE")
        // Ensure the new date object is set to local time zone
        df.setTimeZone(location.timeZone)
        def day = df.format(new Date())
        def dayCheck = days.contains(day)
        if (dayCheck){
            def between = timeOfDayIsBetween(fromTime, toTime, new Date(), location.timeZone)
            if (between){
    			if(switch1check.value != "on" && switch2check.value != "on"){ //if switch1 and switch2 are not on, continue
                    switch1.on()
                    switch1.setLevel(brightness1)
                    switch2.on()
                    switch2.setLevel(brightness2)
                    runIn(60 * minutes, lightsOff)
             	}
            	else if(switch1check.value != "on" && switch2check.value == "on"){ //if switch1 is not on and switch2 is on, continue
                    switch1.on()
                    switch1.setLevel(brightness1)
                    runIn(60 * minutes, light1Off)
				}
                else if(switch1check.value == "on" && switch2check.value != "on"){ //if switch1 is on and switch2 is not on, continue
                    switch2.on()
                    switch2.setLevel(brightness2)
                    runIn(60 * minutes, light2Off)
				}else { //switch1 and switch2 are on, do nothing
        		}
			}
    	}
}

def lightsOff() {
	switch1.off()
	switch2.off()
}

def light1Off() {
	switch1.off()
}

def light2Off() {
	switch2.off()
}
1 Like

Does anyone know a way around this?

I think I need to prevent the program from checking the state of switch2 if the user has not selected a device for switch2 during the setup. I thought adding “required:false” would do that but that’s not working. Any ideas?

One option would be using a try/catch block. See the Exception Handling section of the Groovy Basics reference

You can also have a single input line accept multiple devices by setting “multiple: true”. See the Subscribe to Multiple Devices section of the Smartapp reference. You could then loop through all of the selected switches (you would need to rethink the flow of your logic) no matter how many you choose.

Also, “if(switch2)” will evaluate to false if switch2 is null, letting you bypass any code in the if block.

1 Like

Awesome! Thank You