How to get a return value from a child driver function back to a parent app - OR - Why doesn't this code work

Seems like it's always the easy things. This question has been asked before but never a clear answer.

Parent app calls a function in a child device. Child device executes the command and creates a map of results (visible on the child) and returns to the parent. However, parent sees the return value as null.

def getUnusedTiles(){
myDevice = getStorageDevice()
log.info ("myDevice: ${myDevice}")
if (myDevice == null) return [1:"tile1",2:"tile2",3:"tile3"]

def freeTileMap = [:]
freeTileMap = myDevice.getUnusedTiles()
log.info ("freeTileMap: ${freeTileMap}") //This is null  

}

Someone must know the answer.

Thanks.

1 Like

Try doing a getChildDevice() to get a handle to the device, and use that to do your call to the device's method.

1 Like

This function is doing that part. I know I'm connecting to the child device because the command "getUnusedTiles()" is getting executed as witnessed by the logs.

def getStorageDevice(){
myDevice = getChildDevice(storageDevice)
return myDevice
}

I've gone through the docs but I don't see anything regarding return value. But I do notice a getState in "To be Documented Section" so I can try that.

1 Like

I just tested calling a method on a child device from a parent device, and it worked for me:

Child method:

Map childMethod() {
    log.trace "childMethod()"
    return [myVal: 555]
}

Parent code, called to test this:

void testChildMethod() {
    log.trace "testChildMethod()"
    def childDev = getChildDevice("${device.deviceNetworkId}/1")
    def retVal = childDev.childMethod()
    log.debug "retVal = $retVal"
}

Log output demonstrating success:

Screenshot of myVal: 455 map returned

Something else must be going on in your code. I'd suggest paring it down to a minimal, non-working example for yourself (perhaps in a new set of drivers you create to test this), which may help you discover whatever the problem is on your own, or sharing more of your code and pointing to the relevant parts in case anyone feels like wading through it.

1 Like

I think your test for "myDevice == null" is flawed and causing the problem, what are you returning if it's not null???

Thanks for taking a look. As far as I can tell this is the biggest difference. I'm using the DNI as a string. The parent already knows the DNI because they created the child device by that name. You have a /1 which I'm assuming indicated the first child?

image

I will create a total bare bones config and see what I can figure out. thanks for your help.

I omitted the remainder of the code (the other return) as once freeTileMap is null anything subsequent wasn't really relevant.

Even if I boil down the code to three lines I'm still getting null as the retVal code.

def childDev = getChildDevice("X")
def retVal = childDev.childMethod()
log.debug "retVal = $retVal"

And yet the childMethod in the driver runs.
image

It's a mystery.

That was just the DNI I know I created for this child device (I probably should have used the device ID and not the DNI, but as long as it matches, it works).

What does the called method in the children device code look like?

I don't if this is the same case or will help but i communicate
Back to parent by calling a function
These are parent child devices not an app.

Parent code

Child code

I just used the child function you had posted for a like comparison.

Is it also defined as a command in the child device? In my example, it was not. This could affect outcome; I've never tested and don't recall, but from a platform-level perspective, commands don't return values (they just...run, executing the Groovy method of the same name), so I'm not sure what their in-driver behavior would do.

1 Like

I just tried it out at home and your educated guess was correct. After removing it as a command defined in the metadata section it began to behave as expected and I'm able to see the return values.

Sort of makes sense as many of the commands defined are used to interact with the devices and those responses are all returned to 39501 and make their way back to the driver via that route. So it makes sense that the commands are stateless.

Thank you for your persistence.

1 Like

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.