Fibaro FGBS-001

all done @deanturner39 if you take the latest from my branch it should work the only thing i need to do is create a virtual temperature driver as they dont have one in the stock drivers yet. But it should still work then you can change the driver to your prefered one.

Oh great work @BorrisTheCat I will have a look when I can :+1: cheers.

@BorrisTheCat help cant get it to create childs just says no temps but it is reading 2 lots in current states.
Tried reversing what you changed but still no joy.

dev:2892018-09-09 20:35:28.294:debugNo temperature received for temperature4 so no child will be created

dev:2892018-09-09 20:35:28.290:debugNo temperature received for temperature3 so no child will be created

dev:2892018-09-09 20:35:28.286:debugNo temperature received for temperature2 so no child will be created

dev:2892018-09-09 20:35:28.282:debugNo temperature received for temperature1 so no child will be created

dev:2892018-09-09 20:35:28.273:debugCreating Temperature children

Not actually tested this myself, so I will try setting one up tomorrow. Have you, set the settings and done configure?

Yes set all parameters to default and sent config, all confirmed in logs seeing contacts and child's were created. See temps 1&2 but it will not create child for for them. Log also shows temps 1&2 updating.

I am also having some issues with this one. I have connected 4 temp probes to it and set parameters 10 & 11, but I am not able to create the child devices. This is the error I get: No temperature received for temperature4 so no child will be created (same for 1,2,3).

Also tried reversing the temp wires, removed and re-added the device etc.

Any idea what to try next ?

It's because I still have to fix the driver, I'm waiting on some help with it. I have a hack to get it working but it's not right and your then need bro deleted the extra temperature probs it creates.

One thing you do need to check though, is to make sure your receiving temperature messages in the log. Your see stuff like input changed from X to Y

Ah, ok. I actually use my FGBS with all 4 probes, so perhaps the hack could work for me ? Would you be willing to share that, as I don´t mind having to tinker a bit.

However, I don´t seen any input changed messages, so probably the temp is not coming in ?

I do get an error when I try to update the current Params: java.lang.NullPointerException: Cannot get property 'value' on null object on line 411 (updateCurrentParams)

I don't mind sharing it as long as you know its not perfect :wink:

did you connect the probes after you included the device to the network?

You know what they say, Perfect is the enemy of good :slight_smile:

No, they were connected before. That is the way I have done it on the Vera. Is it different on the Hubitat ?

It's not even good :joy:

No that is correct, so you have them connected the same as you did on Vera. If that's the case you're need to fill in all the parameters and click send to device then configure.

You can do that before then in a second once I boot up my laptop I'll post the code.

When you say, all the parameters, do you mean I need to add an entry to the ones I won't use as well?

Yeah just fill in the defaults if you don't use them.

/**
 *  Device Type Definition File
 *
 *  Device Type:		Fibaro UBS - Dual Contact and Temperature Sensor
 *  File Name:			Fibaro UBS - Dual Contact and Temperature Sensor.groovy
 *	Initial Release:	2017-11-07
 *	Author:				Chris Charles modified by Borristhecat for hubitat
 *
 *  Copyright 2017 Chris Charles, based on original code by carlos.ir33, modified
 *  by Stuart Buchanan and Paul Crookes. Testing thanks to borristhecat.
 *
 ***************************************************************************************
 */
 
metadata {
	definition (name: "Fibaro UBS", namespace: "cjcharles0", author: "Chris Charles") {
    
    capability "Contact Sensor"
 	capability "Motion Sensor"
    capability "Sensor"
	capability "Temperature Measurement"
    capability "Configuration"
    
    command "removeChildDevices"
    command "createChildDevices"
    command "createChildTempDevices"
    command "updateCurrentParams"
    command "listCurrentParams"
    command "open1"
    command "open2"
    command "close1"
    command "close2"
    
    attribute "contact1","enum",["open1","close1"]
    attribute "contact2","enum",["open2","close2"]
	
	fingerprint type: "2001", cc: "30 60 85 8E 72 70 86 7A", ccOut: "2B"
}

main(["temperature1"]) //, "contact1"
details(["contact1","contact2",
		"temp1text", "temperature1", "temp2text", "temperature2",
        "temp3text", "temperature3", "temp4text", "temperature4",
        "configure", "report", "createchildren", "createtempchildren", "removechildren"])

preferences {
        input name: "Info", type: "paragraph", title:"Device Handler by @cjcharles", description: "Parameter Settings:", displayDuringSetup: false

    	input name: "Temps", type: "number", range: "0..4", required: true, //defaultValue: "0",
            title: "Temperature probes number. \n" +
                   "Default value: 0."
    
        input name: "param1", type: "number", range: "0..65535", required: true, //defaultValue: "0",
            title: "Parameter No. 1 - Input 1 Alarm Cancellation Delay. \n" +
                   "Additional delay after an alarm from input 1 has ceased.\n" +
                   "Time in seconds to delay the ceasing event.\n" +
                   "Default value: 0."
       
        input name: "param2", type: "number", range: "0..65535", required: true, //defaultValue: "0",
            title: "Parameter No. 2 - Input 2 Alarm Cancellation Delay. \n" +
                   "Additional delay after an alarm from input 2 has ceased.\n" +
                   "Time in seconds to delay the ceasing event.\n" +
                   "Default value: 0."
       
        input name: "param3", type: "number", range: "0..3", required: true, //defaultValue: "1",
            title: "Parameter No. 3 - Type of Input No 1." +
                   "Available settings:\n" +
                   "0 – INPUT_NO (Normal Open)\n" +
				   "1 – INPUT_NC (Normal Close)\n" +
				   "2 – INPUT_MONOSTABLE\n" +
				   "3 – INPUT_BISTABLE\n" +
                   "Default value: 1."

		input name: "param4", type: "number", range: "0..3", required: true, //defaultValue: "1",
            title: "Parameter No. 4 - Type of Input No 2." +
                   "Available settings:\n" +
                   "0 – INPUT_NO (Normal Open)\n" +
				   "1 – INPUT_NC (Normal Close)\n" +
				   "2 – INPUT_MONOSTABLE\n" +
				   "3 – INPUT_BISTABLE\n" +
                   "Default value: 1."

		input name: "param5", type: "number", range: "0..255", required: true, //defaultValue: "255",
            title: "Parameter No. 5 - Type of transmitted control or alarm frame for association group 1." +
                   "Available settings:\n" +
				   "0 – Frame ALARM GENERIC\n" +
				   "1 – Frame ALARM SMOKE\n" +
				   "2 – Frame ALARM CO\n" +
				   "3 – Frame ALARM CO2\n" +
				   "4 – Frame ALARM HEAT\n" +
				   "5 – Frame ALARM WATER\n" +
				   "255 – Control frame BASIC_SET\n" +
                   "Default value: 255."

		input name: "param6", type: "number", range: "0..255", required: true, //defaultValue: "255",
            title: "Parameter No. 6 - Type of transmitted control or alarm frame for association group 2." +
                   "Available settings:\n" +
				   "0 – Frame ALARM GENERIC\n" +
				   "1 – Frame ALARM SMOKE\n" +
				   "2 – Frame ALARM CO\n" +
				   "3 – Frame ALARM CO2\n" +
				   "4 – Frame ALARM HEAT\n" +
				   "5 – Frame ALARM WATER\n" +
				   "255 – Control frame BASIC_SET\n" +
                   "Default value: 255."

		input name: "param7", type: "number", range: "0..255", required: true, //defaultValue: "255",
            title: "Parameter No. 7 - Value of the parameter specifying the forced level of dimming / opening sun blinds when " +
            	   "sent a “switch on” / ”open” command from association group no. 1.\n" +
                   "Available settings:\n" +
                   "0-99 - Dimming or Opening Percentage\n" +
                   "255 - Last set percentage\n" +
                   "Default value: 255."

		input name: "param8", type: "number", range: "0..255", required: true, //defaultValue: "255",
            title: "Parameter No. 8 - Value of the parameter specifying the forced level of dimming / opening sun blinds when " +
            	   "sent a “switch on” / ”open” command from association group no. 2.\n" +
                   "Available settings:\n" +
                   "0-99 - Dimming or Opening Percentage\n" +
                   "255 - Last set percentage\n" +
                   "Default value: 255."

		input name: "param9", type: "number", range: "0..3", required: true, //defaultValue: "0",
            title: "Parameter No. 9 - Deactivating transmission of the frame cancelling the alarm or the " +
				   "control frame deactivating the device (Basic). Disable the alarm cancellation function.\n" +
                   "Available settings:\n" +
                   "0 – Cancellation sent for association group 1 and 2\n" +
				   "1 – Cancellation sent for association group 1 only\n" +
				   "2 – Cancellation sent for association group 2 only\n" +
				   "3 - Not sent for association group 1 or 2\n" +
                   "Default value: 0."

		input name: "param10", type: "number", range: "1..255", required: true, //defaultValue: "20",
            title: "Parameter No. 10 - Interval between successive readings of temperature from all " +
				   "sensors connected to the device. (A reading does not result in sending to ST)\n" +
                   "Available settings:\n" +
                   "1-255 - Seconds between readings\n" +
                   "Default value: 20."

		input name: "param11", type: "number", range: "0..255", required: true, //defaultValue: "200",
            title: "Parameter No. 11 - Interval between forcing to send report of the temperature. " +
				   "The forced report is sent immediately after the next temperature reading, " +
				   "irrespective of parameter 12. Advised to be 200 unless rapid temperature changes are expected.\n" +
                   "Available settings:\n" +
                   "0 - Deactivate temperature sending\n" +
                   "1-255 - Seconds between sends\n" +
                   "Default value: 200."

		input name: "param12", type: "number", range: "0..255", required: true, //defaultValue: "8",
            title: "Parameter No. 12 - Insensitiveness to temperature changes. This is the maximum " +
				   "difference between the last reported temperature and the current temperature. " +
				   "If they differ by more than this then a report is sent.\n" +
                   "Available settings:\n" +
                   "0-255 - x/16 = temp diff in C\n" +
                   "x/80*9 = temp diff in F\n" +
                   "Default value: 8 (0.5oC)."

		input name: "param13", type: "number", range: "0..3", required: true, //defaultValue: "0",
            title: "Parameter No. 13 - Transmitting the alarm or control frame in “broadcast” mode (i.e. to " +
				   "all devices within range), this information is not repeated by the mesh network." +
                   "Available settings:\n" +
                   "0 - IN1 and IN2 broadcast inactive,\n" +
                   "1 - IN1 broadcast mode active only,\n" +
                   "2 - IN2 broadcast mode active only,\n" +
                   "3 - INI and IN2 broadcast mode active.\n" +
                   "Default value: 0."

		input name: "param14", type: "number", range: "0..1", required: true, //defaultValue: "0",
            title: "Parameter No. 14 - Scene activation functionality." +
                   "Available settings:\n" +
                   "0 - Deactivated functionality,\n" +
                   "1 - Activated functionality.\n" +
                   "Default value: 0."
	}
}

def installed() {
	log.debug "installed()"
}
def updated() {
	log.debug "updated()"
	log.debug "Dont forget to press the button to send config to the device"
    //configure()
    //createChildDevices()
}
def uninstalled() {
    log.debug "uninstalled()"
    removeChildDevices()
}

def configure() {
	log.debug "configure()"
    updateCurrentParams()
}

def createChildDevices(){
	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("hubitat", "Virtual Contact Sensor", "${device.deviceNetworkId}-ep${i}", [name: "${device.displayName} (Contact${i})", isComponent: false])
			//	addChildDevice("hubitat", "Virtual Contact Sensor", "${device.deviceNetworkId}-ep${i}", device.hub.id,
             //   	[completedSetup: true, name: "${device.displayName} (Contact${i})", isComponent: false]) //, label: "${device.displayName} (Contact${i})"
                /*addChildDevice(deviceHandlerName, "${device.deviceNetworkId}-${deviceName}${deviceNumber}", null,
         			[completedSetup: true, label: "${device.displayName} (${deviceName}${deviceNumber})", 
                	isComponent: false, componentName: "${deviceName}${deviceNumber}", componentLabel: "${deviceName} ${deviceNumber}"])*/
            }
        } catch (e) {
            log.debug "Error adding child ${i}: ${e}"
        }
    }
}
def createChildTempDevices() {
    log.debug "Creating Temperature children"
    for (i in 1..4) {
    	try {
        	//If we have a temperature reading from this sensor (1 to 4) then try to create a child for it
        	if (Temps >=1) {
            	log.debug "Have received temperature readings for termperature${i} so creating a child for it if not already there"
                def currentchild = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-temperature${i}"}
                if (currentchild == null) {
                    addChildDevice("hubitat", "Virtual Temperature Sensor", "${device.deviceNetworkId}-temperature${i}", [name: "${device.displayName} (Temp${i})", isComponent: false])
                  //  addChildDevice("smartthings", "Temperature Sensor", "${device.deviceNetworkId}-temperature${i}", device.hub.id,
                   //     [completedSetup: true, name: "${device.displayName} (Temp${i})", isComponent: false]) //, label: "${device.displayName} (Temp${i})"
                }
            }
            else {
            	log.debug "No temperature received for temperature${i} so no child will be created" 
            }
        } catch (e) {
            log.debug "Error adding Temperature # ${i} child: ${e}"
        }
    }
}
private removeChildDevices() {
	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 parse(String description) {
	def result = null
	def cmd = zwave.parse(description, [ 0x60: 3])
	if (cmd) {
		result = zwaveEvent(cmd)
	}
	log.debug "parsed '$description' to result: ${result}"
	return result
}

def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv1.ManufacturerSpecificReport cmd) {
	log.debug("ManufacturerSpecificReport ${cmd.inspect()}")
}

def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
	log.debug("ConfigurationReport ${cmd.inspect()}")
}

def createEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, Map item1) { 
	log.debug "manufacturerId:   ${cmd.manufacturerId}"
    log.debug "manufacturerName: ${cmd.manufacturerName}"
    log.debug "productId:        ${cmd.productId}"
    log.debug "productTypeId:    ${cmd.productTypeId}"

}

def createEvent(hubitat.zwave.commands.versionv1.VersionReport cmd, Map item1) {	
    updateDataValue("applicationVersion", "${cmd.applicationVersion}")
    log.debug "applicationVersion:      ${cmd.applicationVersion}"
    log.debug "applicationSubVersion:   ${cmd.applicationSubVersion}"
    log.debug "zWaveLibraryType:        ${cmd.zWaveLibraryType}"
    log.debug "zWaveProtocolVersion:    ${cmd.zWaveProtocolVersion}"
    log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
}

def zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet cmd) {
	log.debug "BasicSet V1 ${cmd.inspect()}"
    def currentstate
    def motionstate
	if (cmd.value) {
		currentstate = "open"
        motionstate = "inactive"
	} else {
    	currentstate = "closed"
        motionstate = "active"
	}
    createEvent(name: "contact1", value: currentstate, descriptionText: "${device.displayName} is ${currentstate}")
    try {
        def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep1"}
        if (childDevice)
        	childDevice.sendEvent(name: "motion", value: motionstate)
            childDevice.sendEvent(name: "contact", value: currentstate)
            log.debug "Fibaro is ${motionstate} and ${currentstate}"
    } catch (e) {
        log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
    }
}

def zwaveEvent(hubitat.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
	log.debug "ZWaveEvent V3 ${cmd.inspect()}"
	def result
	if (cmd.commandClass == 32) {
        def currentstate
        def motionstate
		if (cmd.parameter == [0]) {
        	currentstate = "closed"
            motionstate = "active"
		}
		if (cmd.parameter == [255]) {
        	currentstate = "open"
            motionstate = "inactive"
		}
        log.debug "ep${cmd.sourceEndPoint} is ${currentstate}"
        //First update tile on this device
        sendEvent(name: "contact${cmd.sourceEndPoint}", value: currentstate, descriptionText: "$device.displayName - ep${cmd.sourceEndPoint} is ${currentstate}")
		//If not null then we have found either ep1 or ep2, hence try to send to the child device aswell
        try {
            def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep${cmd.sourceEndPoint}"}
            if (childDevice)
                childDevice.sendEvent(name: "motion", value: motionstate)
                childDevice.sendEvent(name: "contact", value: currentstate)
        } catch (e) {
            log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
        }
    }
	else if (cmd.commandClass == 49) {
		if ((cmd.sourceEndPoint >= 3) && (cmd.sourceEndPoint <= 6)) {
            
			def tempsensorid = cmd.sourceEndPoint - 2
			def tempendpoint = "temperature" + tempsensorid.toString()
			
            def tempval = ((cmd.parameter[4] * 256) + cmd.parameter[5])
            if (tempval > 32767) {
            	//Here we deal with negative values
            	tempval = tempval - 65536
            }
            //Finally round the temperature
            def tempprocessed = (tempval / 100).toDouble().round(1)
            
			//def cmdScale = cmd.scale == 1 ? "F" : "C"
			//def tempval = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision).toDouble().round(1)
            
            log.debug "${tempendpoint} has changed to ${tempprocessed}"
            
            sendEvent(name: tempendpoint, value: tempprocessed, displayed: true) //unit: getTemperatureScale()
            
			//If not null then we have found either contact1 or contact2, hence try to send to the child
            try {
                def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-${tempendpoint}"}
                if (childDevice)
                	//We found a child device that matches so send it the new temperature
                    childDevice.sendEvent(name: "temperature", value: tempprocessed)
            } catch (e) {
            	//Not an error message here as people may not want child temperature devices
                log.debug "Couldn't find child ${tempendpoint} device, probably doesn't exist...? Error: ${e}"
            }
        }
	}
	else {
		//Send them here just in case we want to do more complicated processing (not doing it as need to have endpoint passed and that makes it a bit messy)
		def encapsulatedCommand = cmd.encapsulatedCommand([0x31: 2, 0x60: 3, 0x85: 2, 0x8E: 2, 0x72: 1, 0x70: 1, 0x86: 1, 0x7A: 1, 0xEF: 1, 0x2B: 1]) // can specify command class versions here like in zwave.parse
		log.debug ("Command from endpoint ${cmd.sourceEndPoint}: ${encapsulatedCommand}")
		if (encapsulatedCommand) {
			result = zwaveEvent(encapsulatedCommand)
		}
	}
    return result
}

def zwaveEvent(hubitat.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd)
{
	//This is no longer used as caught in an earlier event, but kept here in case the code is useful
	log.debug "Sensor MultiLevel Report - Sensor Type = ${cmd.sensorType}"
	switch (cmd.sensorType) {
		case 1:
			// temperature
			def cmdScale = cmd.scale == 1 ? "F" : "C"
			def tempval = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision).toDouble().round(1)
            sendEvent(name: "temperature1", value: tempval, displayed: false) //unit: getTemperatureScale()
			break;
	}
    log.debug map
	createEvent(map)
}

def zwaveEvent(hubitat.zwave.commands.sensormultilevelv1.SensorMultilevelReport cmd) {
    log.debug "SensorMultilevelReport $cmd"
}

def zwaveEvent(hubitat.zwave.Command cmd) {
	// This will capture any commands not handled by other instances of zwaveEvent
	// and is recommended for development so you can see every command the device sends
	log.debug "Catchall reached for cmd: ${cmd.toString()}}"
	return createEvent(descriptionText: "${device.displayName}: ${cmd}")
}

def updateCurrentParams() {
	log.debug "Sending configuration parameters to device"
    def cmds = []
	cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
	cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
	cmds << zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 1, configurationValue:[param1.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 2, configurationValue:[param2.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 3, configurationValue:[param3.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 4, configurationValue:[param4.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 5, configurationValue:[param5.value]).format()
    cmds << zwave.configurationV1.configurationSet(parameterNumber: 6, configurationValue:[param6.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 7, configurationValue:[param7.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 8, configurationValue:[param8.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 9, configurationValue:[param9.value]).format()
    cmds << zwave.configurationV1.configurationSet(parameterNumber: 10, configurationValue:[param10.value]).format()
    cmds << zwave.configurationV1.configurationSet(parameterNumber: 11, configurationValue:[param11.value]).format()
    cmds << zwave.configurationV1.configurationSet(parameterNumber: 12, configurationValue:[param12.value]).format()
	cmds << zwave.configurationV1.configurationSet(parameterNumber: 13, configurationValue:[param13.value]).format()
    cmds << zwave.configurationV1.configurationSet(parameterNumber: 14, configurationValue:[param14.value]).format()
	delayBetween(cmds, 500)
}
def listCurrentParams() {
	log.debug "Listing of current parameter settings of ${device.displayName}"
    def cmds = []
	cmds << zwave.multiChannelAssociationV2.multiChannelAssociationGet(groupingIdentifier:2).format()
	cmds << zwave.associationV2.associationGet(groupingIdentifier: 3).format()
	cmds << zwave.associationV1.associationGet(groupingIdentifier: 1).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
   	cmds << zwave.configurationV1.configurationGet(parameterNumber: 3).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 4).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 5).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 6).format()
    cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 8).format()
   	cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 11).format()
   	cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 13).format()
	cmds << zwave.configurationV1.configurationGet(parameterNumber: 14).format()
	delayBetween(cmds, 500)
}

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: "motion", value: "inactive")
            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: "motion", value: "active")
            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: "motion", value: "inactive")
            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: "motion", value: "active")
			childDevice.sendEvent(name: "contact", value: "closed")
    } catch (e) {
        log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
    }
}

what i have been trying to do is create a variable and use that to select how many child devices are made (currently if you put in a number more that 0 it greats 4 :smile:) but i've been distracted by the new baby so if you have any ideas then fire away :wink:

so you need to put in the new parameter "temperature probes number" 1 or more.Then save that and hit the create button.

Now that changed a lot. I entered 4 in the child devices and it immediately created my 4 sensors. However, they all came in at 72°F, which according to my knowledge is around 22,2°C, but a nearby sensor reports 24,9°C (~77°F). Not sure what that is about.

But aside from this initial temperature it is not reporting anything more and I have set parameter 10&11 at 5 and 20 seconds, respectively.

I will tinker away and see if I see any changes. At least it is a step in the right direction :slight_smile:

And congratulations on your baby :smiley:

Thanks :slight_smile:

Mine does degrees, I think you select what you want I the parameters. If you hold them do they change their value?

It also only updates them if there is one correctly attached to the device, so sometimes your need to exclude (make sure you then do a factory reset on the device) and re add it in. I've had some problems with them when they haven't been fully reset.

Mine is still working well @BorrisTheCat , bit of messing as we know to get the childs to show but hopefully someone will tidy code up at some point. I can't get dashboard to display the C for centigrade had a play around with code but never got it right lol. Had some weird thing going on with contacts showing motion some times but just commented out all the motion stuff and it's been spot on since. Also if contacts are opened closed quickly it looses sync with hubitat so i added in the code for refresh and put in rule machine refresh and seems to do the trick. I still need to get my other fgbs out its box and put it to good use...

this is driver code i'm using

> /**
>  *  Device Type Definition File
>  *
>  *  Device Type:		Fibaro UBS - Dual Contact and Temperature Sensor
>  *  File Name:			Fibaro UBS - Dual Contact and Temperature Sensor.groovy
>  *	Initial Release:	2017-11-07
>  *	Author:				Chris Charles modified by Borristhecat for hubitat and bit more mods by Dean Turner
>  *
>  *  Copyright 2017 Chris Charles, based on original code by carlos.ir33, modified
>  *  by Stuart Buchanan and Paul Crookes. Testing thanks to borristhecat.
>  *
>  ***************************************************************************************
>  */
>  
> metadata {
> 	definition (name: "Fibaro UBS", namespace: "cjcharles0", author: "Chris Charles") {
>     
>     capability "Contact Sensor"
>  	//capability "Motion Sensor"
>     capability "Sensor"
> 	capability "Temperature Measurement"
>     capability "Configuration"
> 	//capability "Polling"
> 	capability "Refresh"
>     
>     command "removeChildDevices"
>     command "createChildDevices"
>     command "createChildTempDevices"
>     command "updateCurrentParams"
>     command "listCurrentParams"
>     command "open1"
>     command "open2"
>     command "close1"
>     command "close2"
>     
>     attribute "contact1","enum",["open1","close1"]
>     attribute "contact2","enum",["open2","close2"]
> 	
> 	fingerprint type: "2001", cc: "30 60 85 8E 72 70 86 7A", ccOut: "2B"
> }
> 
> main(["temperature1"]) //, "contact1"
> details(["contact1","contact2",
> 		"temp1text", "temperature1", "temp2text", "temperature2",
>         "temp3text", "temperature3", "temp4text", "temperature4",
>         "configure", "report", "createchildren", "createtempchildren", "removechildren"])
> 
> preferences {
>         input name: "Info", type: "paragraph", title:"Device Handler by @cjcharles", description: "Parameter Settings:", displayDuringSetup: false
> 
>         input name: "param1", type: "number", range: "0..65535", required: true, //defaultValue: "0",
>             title: "Parameter No. 1 - Input 1 Alarm Cancellation Delay. \n" +
>                    "Additional delay after an alarm from input 1 has ceased.\n" +
>                    "Time in seconds to delay the ceasing event.\n" +
>                    "Default value: 0."
>        
>         input name: "param2", type: "number", range: "0..65535", required: true, //defaultValue: "0",
>             title: "Parameter No. 2 - Input 2 Alarm Cancellation Delay. \n" +
>                    "Additional delay after an alarm from input 2 has ceased.\n" +
>                    "Time in seconds to delay the ceasing event.\n" +
>                    "Default value: 0."
>        
>         input name: "param3", type: "number", range: "0..3", required: true, //defaultValue: "1",
>             title: "Parameter No. 3 - Type of Input No 1." +
>                    "Available settings:\n" +
>                    "0 – INPUT_NO (Normal Open)\n" +
> 				   "1 – INPUT_NC (Normal Close)\n" +
> 				   "2 – INPUT_MONOSTABLE\n" +
> 				   "3 – INPUT_BISTABLE\n" +
>                    "Default value: 1."
> 
> 		input name: "param4", type: "number", range: "0..3", required: true, //defaultValue: "1",
>             title: "Parameter No. 4 - Type of Input No 2." +
>                    "Available settings:\n" +
>                    "0 – INPUT_NO (Normal Open)\n" +
> 				   "1 – INPUT_NC (Normal Close)\n" +
> 				   "2 – INPUT_MONOSTABLE\n" +
> 				   "3 – INPUT_BISTABLE\n" +
>                    "Default value: 1."
> 
> 		input name: "param5", type: "number", range: "0..255", required: true, //defaultValue: "255",
>             title: "Parameter No. 5 - Type of transmitted control or alarm frame for association group 1." +
>                    "Available settings:\n" +
> 				   "0 – Frame ALARM GENERIC\n" +
> 				   "1 – Frame ALARM SMOKE\n" +
> 				   "2 – Frame ALARM CO\n" +
> 				   "3 – Frame ALARM CO2\n" +
> 				   "4 – Frame ALARM HEAT\n" +
> 				   "5 – Frame ALARM WATER\n" +
> 				   "255 – Control frame BASIC_SET\n" +
>                    "Default value: 255."
> 
> 		input name: "param6", type: "number", range: "0..255", required: true, //defaultValue: "255",
>             title: "Parameter No. 6 - Type of transmitted control or alarm frame for association group 2." +
>                    "Available settings:\n" +
> 				   "0 – Frame ALARM GENERIC\n" +
> 				   "1 – Frame ALARM SMOKE\n" +
> 				   "2 – Frame ALARM CO\n" +
> 				   "3 – Frame ALARM CO2\n" +
> 				   "4 – Frame ALARM HEAT\n" +
> 				   "5 – Frame ALARM WATER\n" +
> 				   "255 – Control frame BASIC_SET\n" +
>                    "Default value: 255."
> 
> 		input name: "param7", type: "number", range: "0..255", required: true, //defaultValue: "255",
>             title: "Parameter No. 7 - Value of the parameter specifying the forced level of dimming / opening sun blinds when " +
>             	   "sent a “switch on” / ”open” command from association group no. 1.\n" +
>                    "Available settings:\n" +
>                    "0-99 - Dimming or Opening Percentage\n" +
>                    "255 - Last set percentage\n" +
>                    "Default value: 255."
> 
> 		input name: "param8", type: "number", range: "0..255", required: true, //defaultValue: "255",
>             title: "Parameter No. 8 - Value of the parameter specifying the forced level of dimming / opening sun blinds when " +
>             	   "sent a “switch on” / ”open” command from association group no. 2.\n" +
>                    "Available settings:\n" +
>                    "0-99 - Dimming or Opening Percentage\n" +
>                    "255 - Last set percentage\n" +
>                    "Default value: 255."
> 
> 		input name: "param9", type: "number", range: "0..3", required: true, //defaultValue: "0",
>             title: "Parameter No. 9 - Deactivating transmission of the frame cancelling the alarm or the " +
> 				   "control frame deactivating the device (Basic). Disable the alarm cancellation function.\n" +
>                    "Available settings:\n" +
>                    "0 – Cancellation sent for association group 1 and 2\n" +
> 				   "1 – Cancellation sent for association group 1 only\n" +
> 				   "2 – Cancellation sent for association group 2 only\n" +
> 				   "3 - Not sent for association group 1 or 2\n" +
>                    "Default value: 0."
> 
> 		input name: "param10", type: "number", range: "1..255", required: true, //defaultValue: "20",
>             title: "Parameter No. 10 - Interval between successive readings of temperature from all " +
> 				   "sensors connected to the device. (A reading does not result in sending to ST)\n" +
>                    "Available settings:\n" +
>                    "1-255 - Seconds between readings\n" +
>                    "Default value: 20."
> 
> 		input name: "param11", type: "number", range: "0..255", required: true, //defaultValue: "200",
>             title: "Parameter No. 11 - Interval between forcing to send report of the temperature. " +
> 				   "The forced report is sent immediately after the next temperature reading, " +
> 				   "irrespective of parameter 12. Advised to be 200 unless rapid temperature changes are expected.\n" +
>                    "Available settings:\n" +
>                    "0 - Deactivate temperature sending\n" +
>                    "1-255 - Seconds between sends\n" +
>                    "Default value: 200."
> 
> 		input name: "param12", type: "number", range: "0..255", required: true, //defaultValue: "8",
>             title: "Parameter No. 12 - Insensitiveness to temperature changes. This is the maximum " +
> 				   "difference between the last reported temperature and the current temperature. " +
> 				   "If they differ by more than this then a report is sent.\n" +
>                    "Available settings:\n" +
>                    "0-255 - x/16 = temp diff in C\n" +
>                    "x/80*9 = temp diff in F\n" +
>                    "Default value: 8 (0.5oC)."
> 
> 		input name: "param13", type: "number", range: "0..3", required: true, //defaultValue: "0",
>             title: "Parameter No. 13 - Transmitting the alarm or control frame in “broadcast” mode (i.e. to " +
> 				   "all devices within range), this information is not repeated by the mesh network." +
>                    "Available settings:\n" +
>                    "0 - IN1 and IN2 broadcast inactive,\n" +
>                    "1 - IN1 broadcast mode active only,\n" +
>                    "2 - IN2 broadcast mode active only,\n" +
>                    "3 - INI and IN2 broadcast mode active.\n" +
>                    "Default value: 0."
> 
> 		input name: "param14", type: "number", range: "0..1", required: true, //defaultValue: "0",
>             title: "Parameter No. 14 - Scene activation functionality." +
>                    "Available settings:\n" +
>                    "0 - Deactivated functionality,\n" +
>                    "1 - Activated functionality.\n" +
>                    "Default value: 0."
> 	}
> }
> 
> def refresh() {
> 	def cmds = []
> 	
> 	cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:1, destinationEndPoint:1, commandClass:32, command:2).format()
>     cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:2, destinationEndPoint:2, commandClass:32, command:2).format()
> 	//cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:3, destinationEndPoint:3, commandClass:49, command:5).format()
> 	//cmds << zwave.multiChannelV3.multiChannelCmdEncap(sourceEndPoint:3, destinationEndPoint:4, commandClass:49, command:5).format()
> 	delayBetween(cmds, 1500)
> 	
> }
> 
> def installed() {
> 	log.debug "installed()"
> }
> def updated() {
> 	log.debug "updated()"
> 	log.debug "Dont forget to press the button to send config to the device"
>     //configure()
>     //createChildDevices()
> }
> def uninstalled() {
>     log.debug "uninstalled()"
>     removeChildDevices()
> }
> 
> def configure() {
> 	log.debug "configure()"
>     updateCurrentParams()
> }
> 
> def createChildDevices(){
> 	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("hubitat", "Virtual Contact Sensor", "${device.deviceNetworkId}-ep${i}", [name: "${device.displayName} (Contact${i})", isComponent: false])
> 			//	addChildDevice("hubitat", "Virtual Contact Sensor", "${device.deviceNetworkId}-ep${i}", device.hub.id,
>              //   	[completedSetup: true, name: "${device.displayName} (Contact${i})", isComponent: false]) //, label: "${device.displayName} (Contact${i})"
>                 /*addChildDevice(deviceHandlerName, "${device.deviceNetworkId}-${deviceName}${deviceNumber}", null,
>          			[completedSetup: true, label: "${device.displayName} (${deviceName}${deviceNumber})", 
>                 	isComponent: false, componentName: "${deviceName}${deviceNumber}", componentLabel: "${deviceName} ${deviceNumber}"])*/
>             }
>         } catch (e) {
>             log.debug "Error adding child ${i}: ${e}"
>         }
>     }
> }
> def createChildTempDevices() {
>     log.debug "Creating Temperature children"
>     for (i in 1..4) {
>     	try {
>         	//If we have a temperature reading from this sensor (1 to 4) then try to create a child for it
>         	if (device.currentValue("temperature${i}") !=null) {
>             	log.debug "Have received temperature readings for termperature${i} so creating a child for it if not already there"
>                 def currentchild = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-temperature${i}"}
>                 if (currentchild == null) {
>                  //   addChildDevice("hubitat", "Virtual Thermostat", "${device.deviceNetworkId}-temperature${i}", [name: "${device.displayName} (Temp${i})", isComponent: false])
>                       addChildDevice("hubitat", "Virtual Thermostat", "${device.deviceNetworkId}-temperature${i}", device.hub.id,
>                       [completedSetup: true, name: "${device.displayName} (Temp${i})", isComponent: false]) //, label: "${device.displayName} (Temp${i})"
>                 }
>             }
>             else {
>             	log.debug "No temperature received for temperature${i} so no child will be created" 
>             }
>         } catch (e) {
>             log.debug "Error adding Temperature # ${i} child: ${e}"
>         }
>     }
> }
> private removeChildDevices() {
> 	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 parse(String description) {
> 	def result = null
> 	def cmd = zwave.parse(description, [ 0x60: 3])
> 	if (cmd) {
> 		result = zwaveEvent(cmd)
> 	}
> 	log.debug "parsed '$description' to result: ${result}"
> 	return result
> }
> 
> def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv1.ManufacturerSpecificReport cmd) {
> 	log.debug("ManufacturerSpecificReport ${cmd.inspect()}")
> }
> 
> def zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) {
> 	log.debug("ConfigurationReport ${cmd.inspect()}")
> }
> 
> def createEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd, Map item1) { 
> 	log.debug "manufacturerId:   ${cmd.manufacturerId}"
>     log.debug "manufacturerName: ${cmd.manufacturerName}"
>     log.debug "productId:        ${cmd.productId}"
>     log.debug "productTypeId:    ${cmd.productTypeId}"
> 
> }
> 
> def createEvent(hubitat.zwave.commands.versionv1.VersionReport cmd, Map item1) {	
>     updateDataValue("applicationVersion", "${cmd.applicationVersion}")
>     log.debug "applicationVersion:      ${cmd.applicationVersion}"
>     log.debug "applicationSubVersion:   ${cmd.applicationSubVersion}"
>     log.debug "zWaveLibraryType:        ${cmd.zWaveLibraryType}"
>     log.debug "zWaveProtocolVersion:    ${cmd.zWaveProtocolVersion}"
>     log.debug "zWaveProtocolSubVersion: ${cmd.zWaveProtocolSubVersion}"
> }
> 
> def zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet cmd) {
> 	log.debug "BasicSet V1 ${cmd.inspect()}"
>     def currentstate
>     //def motionstate
> 	if (cmd.value) {
> 		currentstate = "open"
>         //motionstate = "inactive"
> 	} else {
>     	currentstate = "closed"
>         //motionstate = "active"
> 	}
>     createEvent(name: "contact1", value: currentstate, descriptionText: "${device.displayName} is ${currentstate}")
>     try {
>         def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep1"}
>         if (childDevice)
>         	//childDevice.sendEvent(name: "motion", value: motionstate)
>             childDevice.sendEvent(name: "contact", value: currentstate)
>             log.debug "Fibaro is ${currentstate}"
>     } catch (e) {
>         log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
>     }
> }
> 
> def zwaveEvent(hubitat.zwave.commands.multichannelv3.MultiChannelCmdEncap cmd) {
> 	log.debug "ZWaveEvent V3 ${cmd.inspect()}"
> 	def result
> 	if (cmd.commandClass == 32) {
>         def currentstate
>         //def motionstate
> 		if (cmd.parameter == [0]) {
>         	currentstate = "closed"
>             //motionstate = "active"
> 		}
> 		if (cmd.parameter == [255]) {
>         	currentstate = "open"
>             //motionstate = "inactive"
> 		}
>         log.debug "ep${cmd.sourceEndPoint} is ${currentstate}"
>         //First update tile on this device
>         sendEvent(name: "contact${cmd.sourceEndPoint}", value: currentstate, descriptionText: "$device.displayName - ep${cmd.sourceEndPoint} is ${currentstate}")
> 		//If not null then we have found either ep1 or ep2, hence try to send to the child device aswell
>         try {
>             def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-ep${cmd.sourceEndPoint}"}
>             if (childDevice)
>                 //childDevice.sendEvent(name: "motion", value: motionstate)
>                 childDevice.sendEvent(name: "contact", value: currentstate)
>         } catch (e) {
>             log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
>         }
>     }
> 	else if (cmd.commandClass == 49) {
> 		if ((cmd.sourceEndPoint >= 3) && (cmd.sourceEndPoint <= 6)) { 
> 			def tempsensorid = cmd.sourceEndPoint - 2
> 			def tempendpoint = "temperature" + tempsensorid.toString()
>             def tempval = ((cmd.parameter[4] * 256) + cmd.parameter[5])
>             if (tempval > 32767) {
>             	//Here we deal with negative values
>             	tempval = tempval - 65536
>             }
>             //Finally round the temperature
>             
>             def tempprocessed = (tempval / 100).toDouble().round(1)
>             
>             def units = getTemperatureScale()
> 			//def cmdScale = cmd.scale == 1 ? "F" : "C"
> 			//def tempval = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision).toDouble().round(1)
>             
>             log.debug "${tempendpoint} has changed to ${tempprocessed}${units}"
>             
>             sendEvent(name: tempendpoint, value: tempprocessed, displayed: true, unit: getTemperatureScale)
>             
> 			//If not null then we have found either contact1 or contact2, hence try to send to the child
>             try {
>                 def childDevice = getChildDevices()?.find { it.deviceNetworkId == "${device.deviceNetworkId}-${tempendpoint}"}
>                 if (childDevice)
>                 	//We found a child device that matches so send it the new temperature
>                     childDevice.sendEvent(name: "temperature", value: tempprocessed)
>             } catch (e) {
>             	//Not an error message here as people may not want child temperature devices
>                 log.debug "Couldn't find child ${tempendpoint} device, probably doesn't exist...? Error: ${e}"
>             }
>         }
> 	}
> 	else {
> 		//Send them here just in case we want to do more complicated processing (not doing it as need to have endpoint passed and that makes it a bit messy)
> 		def encapsulatedCommand = cmd.encapsulatedCommand([0x31: 2, 0x60: 3, 0x85: 2, 0x8E: 2, 0x72: 1, 0x70: 1, 0x86: 1, 0x7A: 1, 0xEF: 1, 0x2B: 1]) // can specify command class versions here like in zwave.parse
> 		log.debug ("Command from endpoint ${cmd.sourceEndPoint}: ${encapsulatedCommand}")
> 		if (encapsulatedCommand) {
> 			result = zwaveEvent(encapsulatedCommand)
> 		}
> 	}
>     return result
> }
> 
> def zwaveEvent(hubitat.zwave.commands.sensormultilevelv2.SensorMultilevelReport cmd)
> {
> 	//This is no longer used as caught in an earlier event, but kept here in case the code is useful
> 	log.debug "Sensor MultiLevel Report - Sensor Type = ${cmd.sensorType}"
> 	switch (cmd.sensorType) {
> 		case 1:
> 			// temperature
> 			def cmdScale = cmd.scale == 1 ? "F" : "C"
> 			def tempval = convertTemperatureIfNeeded(cmd.scaledSensorValue, cmdScale, cmd.precision).toDouble().round(1)
>             sendEvent(name: "temperature1", value: tempval, displayed: false) //unit: getTemperatureScale()
> 			break;
> 	}
>     log.debug map
> 	createEvent(map)
> }
> 
> def zwaveEvent(hubitat.zwave.commands.sensormultilevelv1.SensorMultilevelReport cmd) {
>     log.debug "SensorMultilevelReport $cmd"
> }
> 
> def zwaveEvent(hubitat.zwave.Command cmd) {
> 	// This will capture any commands not handled by other instances of zwaveEvent
> 	// and is recommended for development so you can see every command the device sends
> 	log.debug "Catchall reached for cmd: ${cmd.toString()}}"
> 	return createEvent(descriptionText: "${device.displayName}: ${cmd}")
> }
> 
> def updateCurrentParams() {
> 	log.debug "Sending configuration parameters to device"
>     def cmds = []
> 	cmds << zwave.multiChannelAssociationV2.multiChannelAssociationSet(groupingIdentifier:2, nodeId:[zwaveHubNodeId]).format()
> 	cmds << zwave.associationV2.associationSet(groupingIdentifier:3, nodeId:[zwaveHubNodeId]).format()
> 	cmds << zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 1, configurationValue:[param1.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 2, configurationValue:[param2.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 3, configurationValue:[param3.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 4, configurationValue:[param4.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 5, configurationValue:[param5.value]).format()
>     cmds << zwave.configurationV1.configurationSet(parameterNumber: 6, configurationValue:[param6.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 7, configurationValue:[param7.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 8, configurationValue:[param8.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 9, configurationValue:[param9.value]).format()
>     cmds << zwave.configurationV1.configurationSet(parameterNumber: 10, configurationValue:[param10.value]).format()
>     cmds << zwave.configurationV1.configurationSet(parameterNumber: 11, configurationValue:[param11.value]).format()
>     cmds << zwave.configurationV1.configurationSet(parameterNumber: 12, configurationValue:[param12.value]).format()
> 	cmds << zwave.configurationV1.configurationSet(parameterNumber: 13, configurationValue:[param13.value]).format()
>     cmds << zwave.configurationV1.configurationSet(parameterNumber: 14, configurationValue:[param14.value]).format()
> 	delayBetween(cmds, 500)
> }
> def listCurrentParams() {
> 	log.debug "Listing of current parameter settings of ${device.displayName}"
>     def cmds = []
> 	cmds << zwave.multiChannelAssociationV2.multiChannelAssociationGet(groupingIdentifier:2).format()
> 	cmds << zwave.associationV2.associationGet(groupingIdentifier: 3).format()
> 	cmds << zwave.associationV1.associationGet(groupingIdentifier: 1).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 1).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 2).format()
>    	cmds << zwave.configurationV1.configurationGet(parameterNumber: 3).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 4).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 5).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 6).format()
>     cmds << zwave.configurationV1.configurationGet(parameterNumber: 7).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 8).format()
>    	cmds << zwave.configurationV1.configurationGet(parameterNumber: 9).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 10).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 11).format()
>    	cmds << zwave.configurationV1.configurationGet(parameterNumber: 12).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 13).format()
> 	cmds << zwave.configurationV1.configurationGet(parameterNumber: 14).format()
> 	delayBetween(cmds, 500)
> }
> 
> 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: "motion", value: "inactive")
>             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: "motion", value: "active")
>             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: "motion", value: "inactive")
>             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: "motion", value: "active")
> 			childDevice.sendEvent(name: "contact", value: "closed")
>     } catch (e) {
>         log.error "Couldn't find child device, probably doesn't exist...? Error: ${e}"
>     }
> }

Glad to see my code is still helping some people, even if it isnt working great....

Im now past my wedding so have a bit more time to tinker if any assistance is needed. Sadly I dont have Hubitat yet so testing is hard, but from what I can tell from a quick scan of the above thread - the motion contact differences are causing the most drama. I can totally imagine this being a problem, since I used a quirk of ST in order to get this device handler doing what I wanted (or was requested), I imagine there are some different quirks in Hubitat so possibly worth having a look at....!

The other thing I picked up was that it isnt very good at creating the children devices? I could modify the code so that there is a specific "Create Children" button. That might help fix some of the issues people are facing...?

what is it set as in your main settings?

This is correct the device is designed to go in a security PIR. So it was set up to give you both then depending on the child device driver it will populate the correct setting. Most of mine are just contacts but one is also triggered from a PIR so I have a motion child used for that.

This was never a problem until the last update but im now seeing this also, so I may try and take that bit.

The original creator was looking into cleaning it up for me on HE, ill contact him and see how he's doing.

edit: looks like he's here! welcome @cjcharles to HE