Child SmartApp installs but gives error


(Joe Angell) #1

I’m putting together a simple(?) SmartApp for controlling my water heater. The parent app lets you pick heaters (currently using a slightly modified version of Justin Huff’s Rheem bridge), toggle vacation mode, and add schedules. The schedules are child apps that will turn the heater on/off and set the temperature at specific times and on specific days of the week.

There are still a few things to do to make it completely work, but I’m ready to start testing. My problem is related to actually instantiating the child SmartApp. After setting the options for new child and tapping “done”, I get the expected message that the app is “installed and automating”, but this is immediately followed by “There was an error, please try again”. The SmartThings iOS app never leave the preferences page that I tapped “done” on. If I hit “back” to return to the parent, I see my schedule there, but if I tap the child and then tap “back” to got to the parent again, it disappears.

There is no information in the live log. It says it the child has initialized, but there’s nothing about the error, so I’m not sure how to proceed.

So, what am I doing wrong? I’ve put the source in GitHub. I’m reasonably certain I’m doing everything correctly, but apparently, not, since the app won’t instal.

Thanks!

– Joe


(Eric) #2

When you say installed and initialized, do you mean in the IDE or you mean after to first use the child app it runs the installed() and initialize() methods?


(Joe Angell) #3

I"m publishing it, rather than using the simulator (I publish the child app too, although I don’t think I have to). I see that it’s being installed, in that my installed() method is being called and is outputting to the log (i.e.: “Installed with settings: …”).

In the iOS SmartThings app though, it won’t leave the child app’s Preferences page. If you hit “done” you get the “Installed and automating” green notification in the iOS app, and my debug output shows up in the log (“Installed with settings”), but I then get the “An error occurred, please try again” red notification in the iOS app, and I’m still in the Preferences page of my child app.

Which implies something went wrong after the child app was launched. Since it does (temporarily) show up in the parent app, I’m thinking the connection is at least there, but not necessarily working properly.

Thanks.

– Joe


(Eric) #4

Start by commenting out this line…

If that fixes the error you know there some something going wrong there.

Also, try just doing this inside initialize.

if(parent.getVacationMode() == null) {
log.error “Vacation Mode is null!!!”
}


(Joe Angell) #5

That was the trick! I changed getVacationMode() to return false when NULL to work around the problem.

Now I just have to figure out why the name shown for the child app in the parent list is just the default name instead of the name I specified, but I can probably figure that one out. Thanks!

– Joe


(Eric) #6

I don’t see you asking for a name of the child app… You need this in the child app…

label(title: "Assign a name", required: false)


(Joe Angell) #7

Ah, I must have removed that from the parent/child sample I was using as a reference when I was tinkering around.

It seems I’m still having trouble with calling a method on the parent, though. To further debug this, I updated my initialize() function to:

def initialize() {
    	log.debug "initialize() called"
        if (!overrideLabel) {
            app.updateLabel(defaultLabel())
        }

    	log.debug "Ready to test parent"
    	if( parent == NULL ) {
    		log.debug "no parent"
        	return
        }

    	if( parent.getVacationMode() == NULL ) {
    		log.debug "Update for vacation mode (NULL)"
        	updateForVacationMode( false )
        }


	log.debug "Update for vacation mode (normal)"
    updateForVacationMode( parent.getVacationMode() )
}

But in the debug output, I only see these two lines:

>     initialize() called
>     Ready to test parent

It gets no further. This implies that it’s failing on this line:

if( parent == NULL ) {

And I still get the error message when I try to install the app. As before, there is no other error information in the log. I’m starting to wonder if it’s illegal to access parent from the installed() method. I can work around that if that’s the case, but it does seem a bit odd.

Thanks again

– Joe


(Eric) #8

Try something like this to figure out what is going on…

def initialize() {

	log.debug "initialize() called"
    if (!overrideLabel) {
        app.updateLabel(defaultLabel())
    }


	log.debug "Ready to test parent"
    
    try {
	     if( parent == NULL ) {
		     log.debug "no parent"
    	     return
         }
    } catch (Exception e) {
           log.debug "Exception ${e}"
    }

    try {
	      if( parent.getVacationMode() == NULL ) {
	        	log.debug "Update for vacation mode (NULL)"
            	updateForVacationMode( false )
           }
    } catch (Exception e) {
           log.debug "Exception ${e}"
    }


log.debug "Update for vacation mode (normal)"
updateForVacationMode( parent.getVacationMode() )

}


(Joe Angell) #9

Hmmm… I gave that a shot, and there was no change at all in the debug output, and I still got the same red notification from the iOS app. It seems like the exception isn’t being thrown.

– Joe