According to my conversation with @slagle when a SmartApp calls a DH the DH should be able to return a value to the SmartApp (when using Parent Child relationships). Funnily it works and doesn’t work for me.
What I specify a return type for the function in the DH it does NOT work, however when I don’t specify a return type for the function it does work.
I’ve whipped up some code to replicate the issue, can someone try it out and let me know what results they get. Install the SmartApp and Device Handler. Open Live Logging, goto your phone and install the SmartApp and see what you get in Live Logging:
DH CODE:
metadata {
definition (name: "Test Device", namespace: "rboy", author: "RBoy") {
capability "Polling"
capability "Refresh"
// Calls from Parent to Child
command "saveStuff", ["string"]
command "readStuff"
command "readStuffA"
}
tiles(scale: 2) {
standardTile("refresh", "device.status", width: 2, height: 2, inactiveLabel: false, decoration: "flat") {
state "refresh", action:"refresh.refresh", icon:"st.secondary.refresh"
}
main "refresh"
details(["refresh"])
}
}
def initialize() {
log.trace "Initialize called settings: $settings"
try {
if (!state.init) {
state.init = true
}
response(refresh()) // Get the updates
} catch (e) {
log.warn "updated() threw $e"
}
}
def updated() {
log.trace "Update called settings: $settings"
try {
if (!state.init) {
state.init = true
}
response(refresh()) // Get the updates
} catch (e) {
log.warn "updated() threw $e"
}
}
def refresh() {
log.trace "Refresh called"
}
// PARENT CHILD INTERFACES
def void saveStuff(def stuff) {
log.debug "SaveStuff called with: $stuff"
state.stuff = stuff as String
}
def String readStuff() {
log.debug "ReadStuff called, returning: ${state.stuff}"
return state.stuff as String
}
def readStuffA() {
log.debug "ReadStuffA called, returning: ${state.stuff}"
return state.stuff as String
}
SMARTAPP
definition(
name: "Test Device Parent",
namespace: "rboy",
author: "RBoy",
description: "Test Parent Child app",
category: "Safety & Security",
iconUrl: "https://s3.amazonaws.com/smartapp-icons/Developers/whole-house-fan.png",
iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Developers/whole-house-fan@2x.png",
singleInstance: false)
preferences {
page(name: "mainPage")
}
def mainPage() {
dynamicPage(name: "mainPage", title: "Test Parent Child Device App", install: true, uninstall: true) {
// Let the user know the current status
section("Status") {
def devices = getChildDevices().each { device ->
log.trace "Found child ${device.displayName}"
def stuff = device.readStuff()
paragraph "${device.displayName}: $stuff"
}
}
def physicalHubs = location.hubs.findAll { it.type == physicalgraph.device.HubType.PHYSICAL } // Ignore Virtual hubs
if (physicalHubs.size() > 1) { // If there is more than one hub then select the hub otherwise we'll the default hub
section("Hub Selection") {
paragraph title: "", "Multiple SmartThings Hubs have been detected at this location. Please select the Hub."
input name: "installHub", type: "hub", title: "Select the Hub", required: true
}
}
}
}
def installed()
{
log.debug "Installed: $settings"
initialize()
}
def updated()
{
log.debug "Updated: $settings"
unsubscribe()
unschedule()
initialize()
}
def uninstalled() {
log.trace "Uninstalled called"
getChildDevices().each {device ->
log.info "Deleting Device $device.displayName"
deleteChildDevice(device.deviceNetworkId)
}
}
def initialize() {
def physicalHubs = location.hubs.findAll { it.type == physicalgraph.device.HubType.PHYSICAL } // Ignore Virtual hubs
log.trace "Selected Hub ID ${installHub?.id}, All Hubs Types: ${location.hubs*.type}, Names: ${location.hubs*.name}, IDs: ${location.hubs*.id}, IPs: ${location.hubs*.localIP}, Total Hubs Found: ${location.hubs.size()}, Physical Hubs Found: ${physicalHubs.size()}"
try {
def existingDevices = getChildDevices()
log.trace "Found devices $existingDevices"
if(!existingDevices) {
if ((physicalHubs.size() > 1) && !installHub) {
log.error "Found more than one physical hub and user has NOT selected a hub in the SmartApp settings"
throw new RuntimeException("Select Hub in SmartApp settings") // Lets not continue with out this settings
}
if (physicalHubs.size() < 1) {
log.error "NO Physical hubs found at this location, please contact SmartThings support!"
throw new RuntimeException("No physical hubs found") // Lets not continue with out this settings
}
(1..5).each {
def id = 3000 + it
log.info "Creating Device ID $id on Hub Id ${physicalHubs.size() > 1 ? installHub.id : physicalHubs[0].id}"
def childDevice = addChildDevice("rboy", "Test Device", id.toString(), (physicalHubs.size() > 1 ? installHub.id : physicalHubs[0].id), [name: "Test Device $id", label: "Test Device $id", completedSetup: true])
}
existingDevices = getChildDevices()
}
log.trace "Working with devices $existingDevices"
existingDevices.each { device ->
def stuff = "DeviceID" + device.deviceNetworkId.toString()
log.trace "Saving stuff to ${device.displayName}: $stuff"
device.saveStuff(stuff)
stuff = device.readStuff()
log.debug "Read stuff from ${device.displayName}: $stuff"
stuff = device.readStuffA()
log.debug "Read stuff without return type from ${device.displayName}: $stuff"
}
} catch (e) {
log.error "Error creating device: ${e}"
throw e // Don't lose the exception here
}
}