SmartThings Community

Problems with child creation at the moment?


(cjcharles) #1

Is anybody else having problems creating child devices at the moment? I find that they create fine, but they get diassociated from the parent upon creation, hence the parent can no longer send commands/updates to the children (and vice versa).

I have simplified the code to give the most simple implementation below and it still gives a problem. Can somebody verify this for me please? I have tried fiddling with tons of settings for hours but with no luck!

Basically if you press open/close on the parent then it should update the relevant child, however it seems to work on the first created child and not the second. If you look in live logging you will see the error that it cannot find the child (even though it exists), and if you press list children you will see it only finds one child.
To fix it: if you then hit remove devices (once) it will remove the working child (not the broken one - no idea why), but then you can press create devices again and it will re-create the working child and magically the broken child will start working (sometimes you need to do this a few times). - NOTE this fix only works if you have 2/3 children, if you have 4+ Ive never managed to get every child working!

/**
 *  Test children devices
 *
 ***************************************************************************************
 */
 
metadata {
    definition (name: "Test children", namespace: "cjcharles0", author: "Chris Charles") {
    
    capability "Contact Sensor"
    capability "Sensor"
    
    command "rmvChildDevices"
    command "crtChildDevices"
    command "lstChildDevices"
    command "open1"
    command "open2"
    command "close1"
    command "close2"
    
}

simulator {
}

tiles(scale: 2) {
    standardTile("contact1", "device.contact1", width: 3, height: 2) {
        state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13", action: "close1"
        state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00a0dc", action: "open1"
    }
    standardTile("contact2", "device.contact2", width: 3, height: 2) {
        state "open", label: '${name}', icon: "st.contact.contact.open", backgroundColor: "#e86d13", action: "close2"
        state "closed", label: '${name}', icon: "st.contact.contact.closed", backgroundColor: "#00a0dc", action: "open2"
    }
    
    standardTile("crtchildren", "crtchildren", inactiveLabel: false, decoration: "flat", width: 2, height: 1) {
        state "default", label:'Create Child Devices', action:"crtChildDevices"
    }
    standardTile("rmvchildren", "rmvchildren", inactiveLabel: false, decoration: "flat", width: 2, height: 1) {
        state "default", label:'Remove Child Devices', action:"rmvChildDevices"
    }
    standardTile("lstchildren", "lstchildren", inactiveLabel: false, decoration: "flat", width: 2, height: 1) {
        state "default", label:'List Child Devices', action:"lstChildDevices"
    }
}

main(["contact1"]) //, "temperature1"
details(["contact1","contact2","crtchildren", "rmvchildren", "lstchildren"])
}

def crtChildDevices(){
	log.debug "Adding Child Devices if not already added"
    for (i in 1..2) {
    	try {
        	log.debug "Trying to create child switch if it doesn't already exist ${i}"
            def currentchild = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep${i}"}
            if (currentchild == null) {
            	log.debug "Creating child for ep${i}"
				addChildDevice("smartthings/testing", "Simulated Contact Sensor", "${device.deviceNetworkId}-ep${i}", device.hub.id,
                	[completedSetup: true, name: "${device.displayName} (Contact${i})", isComponent: false])
            }
        } catch (e) {
            log.debug "Error adding child ${i}: ${e}"
        }
    }
}
def rmvChildDevices() {
    log.debug "Removing Child Devices"
    try {
        getChildDevices()?.each {
            try {
                deleteChildDevice(it.deviceNetworkId)
            } catch (e) {
                log.debug "Error deleting ${it.deviceNetworkId}, probably locked into a SmartApp: ${e}"
            }
        }
    } catch (err) {
        log.debug "Either no children exist or error finding child devices for some reason: ${err}"
    }
}
def lstChildDevices(){
	log.debug getChildDevices()
}

def open1() {
    sendEvent(name: "contact1", value: "open", descriptionText: "$device.displayName (1) is opened manually")
    try {
        def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep1"}
        log.debug "Changing child ${childDevice} to open/inactive"
        if (childDevice)
            childDevice.sendEvent(name: "contact", value: "open")
    } catch (e) {
        log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
    }
}

def close1() {
    sendEvent(name: "contact1", value: "closed", descriptionText: "$device.displayName (1) is closed manually")
    try {
        def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep1"}
        log.debug "Changing child ${childDevice} to closed/active"
        if (childDevice)
            childDevice.sendEvent(name: "contact", value: "closed")
    } catch (e) {
        log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
    }
}

def open2() {
    sendEvent(name: "contact2", value: "open", descriptionText: "$device.displayName (2) is opened manually")
    try {
        def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep2"}
        log.debug "Changing child ${childDevice} to open/inactive"
        if (childDevice)
            childDevice.sendEvent(name: "contact", value: "open")
    } catch (e) {
        log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
    }
}

def close2() {
    sendEvent(name: "contact2", value: "closed", descriptionText: "$device.displayName (2) is closed manually")
    try {
        def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep2"}
        log.debug "Changing child ${childDevice} to closed/active"
        if (childDevice)
            childDevice.sendEvent(name: "contact", value: "closed")
    } catch (e) {
        log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
    }
}

childDevice.sendEvent no longer works as of 4 days ago
(cjcharles) #2

Can somebody install this DTH and just confirm it gives you the same problems as I am seeing please?

Specifically that when creating child devices, quite often they are created but not accessible as they are not defined as child devices (see the list of child devices by pressing list and looking at live logging)


(Borristhecat) #3

Could you install this on a virtual device and get the same effect/ logging?


(cjcharles) #4

Yup, you don’t need any real hardware, just creating a virtual device exhibits the same bug


(Borristhecat) #5

im getting the same results as you. For me it is always contact 2 that is the issue. i have attached some logs if that helps?

125b5ff7-131f-444f-b5de-ba06aa667927 21:00:45: debug Changing child Child test (Contact1) to open/inactive
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:39: debug Changing child Child test (Contact2) to closed/active
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:38: debug Changing child Child test (Contact1) to closed/active
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:23: debug Trying to create child switch if it doesn’t already exist 2
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:20: debug Creating child for ep1
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:20: debug Trying to create child switch if it doesn’t already exist 1
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:19: debug Adding Child Devices if not already added
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:13: debug Removing Child Devices
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:04: debug Changing child Child test (Contact1) to open/inactive
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:03: debug Changing child null to open/inactive
125b5ff7-131f-444f-b5de-ba06aa667927 21:00:01: debug Changing child null to closed/active
125b5ff7-131f-444f-b5de-ba06aa667927 20:59:56: debug Changing child Child test (Contact1) to closed/active
125b5ff7-131f-444f-b5de-ba06aa667927 20:59:51: debug Error adding child 1: grails.validation.ValidationException: Validation Error(s) occurred during save():

  • Field error in object ‘physicalgraph.device.Device’ on field ‘deviceNetworkId’: rejected value [80-ep1]; codes [physicalgraph.device.Device.deviceNetworkId.unique.error.physicalgraph.device.Device.deviceNetworkId,physicalgraph.device.Device.deviceNetworkId.unique.error.deviceNetworkId,physicalgraph.device.Device.deviceNetworkId.unique.error.java.lang.String,physicalgraph.device.Device.deviceNetworkId.unique.error,device.deviceNetworkId.unique.error.physicalgraph.device.Device.deviceNetworkId,device.deviceNetworkId.unique.error.deviceNetworkId,device.deviceNetworkId.unique.error.java.lang.String,device.deviceNetworkId.unique.error,physicalgraph.device.Device.deviceNetworkId.unique.physicalgraph.device.Device.deviceNetworkId,physicalgraph.device.Device.deviceNetworkId.unique.deviceNetworkId,physicalgraph.device.Device.deviceNetworkId.unique.java.lang.String,physicalgraph.device.Device.deviceNetworkId.unique,device.deviceNetworkId.unique.physicalgraph.device.Device.deviceNetworkId,device.deviceNetworkId.unique.deviceNetworkId,device.deviceNetworkId.unique.java.lang.String,device.deviceNetworkId.unique,unique.physicalgraph.device.Device.deviceNetworkId,unique.deviceNetworkId,unique.java.lang.String,unique]; arguments [deviceNetworkId,class physicalgraph.device.Device,80-ep1]; default message [{0} must be unique]
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:51: debug Trying to create child switch if it doesn’t already exist 2
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:50: debug Creating child for ep1
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:50: debug Trying to create child switch if it doesn’t already exist 1
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:50: debug Adding Child Devices if not already added
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:44: debug Creating child for ep2
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:44: debug Trying to create child switch if it doesn’t already exist 2
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:41: debug Creating child for ep1
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:41: debug Trying to create child switch if it doesn’t already exist 1
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:41: debug Adding Child Devices if not already added
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:31: debug Removing Child Devices
    125b5ff7-131f-444f-b5de-ba06aa667927 20:59:00: debug Changing child null to open/inactive
    125b5ff7-131f-444f-b5de-ba06aa667927 20:58:58: debug Changing child null to open/inactive
    125b5ff7-131f-444f-b5de-ba06aa667927 20:58:57: debug Changing child null to closed/active
    125b5ff7-131f-444f-b5de-ba06aa667927 20:58:55: debug Changing child null to closed/active

(cjcharles) #6

Yup, and in fact it’s always the last child that it creates that is dodgy, I.e. If you change it so it creates 3 or 4 children then it is always the 3rd or 4th one that is broken!


(Borristhecat) #7

Have you got any further with finding out why this is happening?


(Tom Manley) #8

@cjcharles, can you try adding this to the DTH and update the DTH instead of pressing the Create Child Devices tile? I did some quick testing and it seemed to work. I’m not sure why it doesn’t work as is but I can report the issue to our cloud team.

def updated() {
	crtChildDevices()
}

(cjcharles) #9

@tpmanley Thanks for that, you’re right that the code does work fine when called in the updated function. I just found that the updated function was called multiple times in some cases and made it hard to control, plus it was more convenient to customise what Child devices are created. Please do report it, and if you hear anything back or they have any questions they can get in touch. Thanks


(Tom Manley) #10

You can try this so that the child devices only get created if none exist yet:

def updated() {
    if (!childDevices) {
        crtChildDevices()
    }
}

(cjcharles) #11

Yes sadly some of my device handlers use different types of children and with some customisation about which children are used and how many, so I dont think I can easily use that option.

Perhaps in the updated function I can do a bit more complicated checking of other variables, I just know that some functions dont work in the updated function (e.g. if sometimes doesnt evaluate, but if you move the same code out of updated it works fine)