Adding DoorSense To Z-Wave Yale Driver

Yeah, I'm also using that driver on my Assure 1 locks that don't have Doorsense. My plan was to use the native Doorsense functionality rather than a separate Zwave contact sensor. I'd like to cut down on the complexity, and having the contact sensor and lock integrated into one driver was ideal.

Turn on debug logging to see if that shows anything in the logs.

Did you try recalibrating the Door Sense?

I had a look in the app, and it doesn't appear to offer Doorsense recalibration. I can unenroll Doorsense and then possibly re-enroll it. The Calibration option in the app, only refers to handing. Perhaps there has been an update and the Doorsense recalibration was removed? I can try removing the Doorsense from the app and see if lets me re-add it.

DoorSense events are showing in the event log, but I can't find a DoorSense state attribute in the device pages? Is there supposed to be a child contact sensor created?

It should be a contact state in the current states.

Post a screenshot of the logs. I looked at the driver code and it should be producing an ungodly amount of debug and trace logs all the time. I don't see any way to turn them on or off. I should be able to see whats going wrong with the logs.

Thanks for your help. I've attached a screenshot of the logfile before and after I closed and locked the door this morning.

I've also attached a screenshot of the state variables that I see on the device page.

OK I see the issue. When @joemc91 converted it to use the contact state, one section was missed which is where the reports from your device are landing.

Try this code, you can just overwrite the existing driver with it. I only changed a few lines.

/**
 * 	Z-Wave Lock
 *
 *  Derivative Work Copyright 2025 Joe McNamee
 *  (Previous: Derivative Work Copyright 2019 Hans Andersson, Copyright 2024 William Siggson)
 *
 *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
 *  in compliance with the License. You may obtain a copy of the License at:
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
 *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
 *  for the specific language governing permissions and limitations under the License.
 *
 */

/**
  *  Joe McNamee modified code to work properly with doorsense and enable contact sensor
  *  Also brought event handling to current standard (sendevent vs createevent percolation), corrected lock code support for lock code manager
  *  
  *
  */

metadata {
	definition (name: "Yale Assure Z-Wave Lock", namespace: "Mrjoemac", author: "Joe McNamee") {
        
		capability "Actuator"
		capability "Lock"
		capability "Polling"
		capability "Refresh"
		capability "ContactSensor"
		capability "Lock Codes"
		capability "Battery"
		capability "Health Check"
		capability "Configuration"
		
		command "reloadCodes", [
			[name: "positions", type: "STRING", description: "Comma separated list: individual positions or ranges (e.g. 1,3,5-7). Also ALL for all positions."]
			]

		fingerprint mfr:"0129", prod:"8002", model:"0600", deviceJoinName: "Yale Assure Lock" //YRD416, YRD426, YRD446
		fingerprint mfr:"0129", prod:"8004", model:"0600", deviceJoinName: "Yale Assure Lock Push Button Deadbolt" //YRD216
		fingerprint mfr:"0129", prod:"800B", model:"0F00", deviceJoinName: "Yale Assure Keypad Lever Door Lock" // YRL216-ZW2
		fingerprint mfr:"0129", prod:"800C", model:"0F00", deviceJoinName: "Yale Assure Touchscreen Lever Door Lock" // YRL226-ZW2
		fingerprint mfr:"0129", prod:"8002", model:"1000", deviceJoinName: "Yale Assure Lock" //YRD-ZWM-1
		fingerprint mfr:"0129", prod:"8107", model:"1000", deviceJoinName: "Yale Assure Lock 2 Touch" //YRD450-F-ZW3-619
	}
}

import hubitat.zwave.commands.doorlockv1.*
import hubitat.zwave.commands.usercodev1.*
    
/**
 * Called on app installed
 */
def installed() {
	// Device-Watch pings if no device events received for 1 hour (checkInterval)
	sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])
	scheduleInstalledCheck()
}

/**
 * Verify that we have actually received the lock's initial states.
 * If not, verify that we have at least requested them or request them,
 * and check again.
 */
def scheduleInstalledCheck() {
	runIn(120, installedCheck)
}

def installedCheck() {
	if (device.currentState("lock") && device.currentState("battery")) {
		unschedule("installedCheck")
	} else {
		// We might have called updated() or configure() at some point but not have received a reply, so don't flood the network
		if (!state.lastLockDetailsQuery || secondsPast(state.lastLockDetailsQuery, 2 * 60)) {
			def actions = updated()

			if (actions) {
				sendHubCommand(actions.toHubAction())
			}
		}

		scheduleInstalledCheck()
	}
}

/**
 * Called on app uninstalled
 */
def uninstalled() {
	def deviceName = device.displayName
	log.trace "[DTH] Executing 'uninstalled()' for device $deviceName"
	sendEvent(name: "lockRemoved", value: device.id, isStateChange: true, displayed: false)
}

/**
 * Executed when the user taps on the 'Done' button on the device settings screen. Sends the values to lock.
 *
 * @return hubAction: The commands to be executed
 */
def updated() {
	// Device-Watch pings if no device events received for 1 hour (checkInterval)
	sendEvent(name: "checkInterval", value: 1 * 60 * 60, displayed: false, data: [protocol: "zwave", hubHardwareId: device.hub.hardwareID, offlinePingable: "1"])

	def hubAction = null
	try {
		def cmds = []
		if (!device.currentState("lock") || !device.currentState("battery") || !state.configured) {
			log.debug "Returning commands for lock operation get and battery get"
			if (!state.configured) {
				doConfigure()
			}
			refresh()
			cmds << secure(zwave.userCodeV1.usersNumberGet())
			if (!state.MSR) {
				cmds << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
			}
			if (!state.fw) {
				cmds << zwave.versionV1.versionGet().format()
			}
			executeCommands(delayBetween(cmds, 30*1000))
		}
	} catch (e) {
		log.warn "updated() threw $e"
	}
}

/**
 * Configures the device to settings needed by SmarthThings at device discovery time
 *
 */
def configure() {
	log.trace "[DTH] Executing 'configure()' for device ${device.displayName}"
	doConfigure()
}

/**
 * Returns the list of commands to be executed when the device is being configured/paired
 *
 */
def doConfigure() {
	log.trace "[DTH] Executing 'doConfigure()' for device ${device.displayName}"
	state.configured = true
	def cmds = []
	cmds << secure(zwave.doorLockV1.doorLockOperationGet())
	cmds << secure(zwave.batteryV1.batteryGet())
	cmds = delayBetween(cmds, 30*1000)
	executeCommands(cmds)		// run configuration commands

	state.lastLockDetailsQuery = now()

	log.debug "Do configure returning with commands := $cmds"
}

def zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd) {
    log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = $cmd"
    hubitat.zwave.Command encapCmd = cmd.encapsulatedCommand(commandClassVersions) // we defined commandClassVersions above
    if (encapCmd) {
        zwaveEvent(encapCmd)
    }
    sendHubCommand(new hubitat.device.HubAction(zwaveSecureEncap(zwave.supervisionV1.supervisionReport(sessionID: cmd.sessionID, reserved: 0, moreStatusUpdates: false, status: 0xFF, duration: 0).format()), hubitat.device.Protocol.ZWAVE))
} 

/**
 * Responsible for parsing incoming device messages to generate events
 *
 * @param description: The incoming description from the device
 *
 * @return result: The list of events to be sent out
 *
 */
def parse(String description) {
	log.trace "[DTH] Executing 'parse(String description)' for device ${device.displayName} with description = $description"

	def result = null
	if (description.startsWith("Err")) {
//        log.debug "********************** Err "
		if (state.sec) {
			sendEvent(descriptionText:description, isStateChange:true, displayed:false)
		} else {
			sendEvent(
					descriptionText: "This lock failed to complete the network security key exchange. If you are unable to control it via SmartThings, you must remove it from your network and add it again.",
					eventType: "ALERT",
					name: "secureInclusion",
					value: "failed",
					displayed: true,
			)
		}
	} else {
//        log.debug "*** description *** = " + description
		def cmd = zwave.parse(description, [ 0x98: 1, 0x62: 1, 0x63: 1, 0x71: 2, 0x72: 2, 0x80: 1, 0x85: 2, 0x86: 1 ])
//        log.debug "*** cmd *** = " + cmd
		if (cmd) {
			result = zwaveEvent(cmd)
            log.debug "Parsed ${cmd} to ${result.inspect()}"
		}
	}
	log.info "[DTH] parse() - returning result=$result"
	return result
}

/**
 * Responsible for parsing ConfigurationReport command
 *
 * @param cmd: The ConfigurationReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.configurationv2.ConfigurationReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.configurationv2.ConfigurationReport cmd)' with cmd = $cmd"
	return null
}

/**
 * Responsible for parsing SecurityMessageEncapsulation command
 *
 * @param cmd: The SecurityMessageEncapsulation command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.securityv1.SecurityMessageEncapsulation)' with cmd = $cmd"
	def encapsulatedCommand = cmd.encapsulatedCommand([0x62: 1, 0x71: 2, 0x80: 1, 0x85: 2, 0x63: 1, 0x98: 1, 0x86: 1])
	if (encapsulatedCommand) {
		zwaveEvent(encapsulatedCommand)
	}
}

/**
 * Responsible for parsing NetworkKeyVerify command
 *
 * @param cmd: The NetworkKeyVerify command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.securityv1.NetworkKeyVerify cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.securityv1.NetworkKeyVerify)' with cmd = $cmd"
	sendEvent(name:"secureInclusion", value:"success", descriptionText:"Secure inclusion was successful", isStateChange: true)
}

/**
 * Responsible for parsing SecurityCommandsSupportedReport command
 *
 * @param cmd: The SecurityCommandsSupportedReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.securityv1.SecurityCommandsSupportedReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.securityv1.SecurityCommandsSupportedReport)' with cmd = $cmd"
	state.sec = cmd.commandClassSupport.collect { String.format("%02X ", it) }.join()
	if (cmd.commandClassControl) {
		state.secCon = cmd.commandClassControl.collect { String.format("%02X ", it) }.join()
	}
	sendEvent(name:"secureInclusion", value:"success", descriptionText:"Lock is securely included", isStateChange: true)
}

/**
 * Responsible for parsing DoorLockOperationReport command
 *
 * @param cmd: The DoorLockOperationReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(DoorLockOperationReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = $cmd"

	unschedule("followupStateCheck")
	unschedule("stateCheck")

	// DoorLockOperationReport is called when trying to read the lock state or when the lock is locked/unlocked from the DTH or the smart app
//log.debug "****** cmd ****** = " + cmd
	def map = [ name: "lock" ]
	map.data = [ lockName: device.displayName ]
	if (cmd.doorLockMode == 0xFF) {
		map.value = "locked"
		map.descriptionText = "Locked"
	} else if (cmd.doorLockMode >= 0x40) {
		map.value = "unknown"
		map.descriptionText = "Unknown state"
	} else if (cmd.doorLockMode == 0x01) {
		map.value = "unlocked with timeout"
		map.descriptionText = "Unlocked with timeout"
	}  else {
		map.value = "unlocked"
		map.descriptionText = "Unlocked"
		if (state.assoc != zwaveHubNodeId) {
			def cmds = []
			cmds << secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId))
			cmds << zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId)
			cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1))
			executeCommands(cmds)
		}
	}

	sendEvent(map)
}

def delayLockEvent(data) {
	log.debug "Sending cached lock operation: $data.map"
	sendEvent(data.map)
}

/**
 * Responsible for parsing AlarmReport command
 *
 * @param cmd: The AlarmReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.alarmv2.AlarmReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.alarmv2.AlarmReport)' with cmd = $cmd"

	if (cmd.zwaveAlarmType == 6) {
		handleAccessAlarmReport(cmd)
	} else if (cmd.zwaveAlarmType == 7) {
		handleBurglarAlarmReport(cmd)
	} else if(cmd.zwaveAlarmType == 8) {
		handleBatteryAlarmReport(cmd)
	} else {
		handleAlarmReportUsingAlarmType(cmd)
	}

	log.debug "[DTH] zwaveEvent(hubitat.zwave.commands.alarmv2.AlarmReport) returning with result = $result"
}

/**
 * Responsible for handling Access AlarmReport command
 *
 * @param cmd: The AlarmReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
private def handleAccessAlarmReport(cmd) {
	log.trace "[DTH] Executing 'handleAccessAlarmReport' with cmd = $cmd"
	def result = []
	def map = null
	def codeID, changeType, lockCodes, codeName
	def deviceName = device.displayName
	lockCodes = loadLockCodes()
	if (1 <= cmd.zwaveAlarmEvent && cmd.zwaveAlarmEvent < 10) {
		map = [ name: "lock", value: (cmd.zwaveAlarmEvent & 1) ? "locked" : "unlocked" ]
	}
	switch(cmd.zwaveAlarmEvent) {
		case 1: // Manually locked
			map.descriptionText = "Locked manually"
			map.data = [ method: (cmd.alarmLevel == 2) ? "keypad" : "manual" ]
            sendEvent(name: "lock", value: "locked", descriptionText: "Locked manually", isStateChange: true)
			break
		case 2: // Manually unlocked
			map.descriptionText = "Unlocked manually"
			map.data = [ method: "manual" ]
            sendEvent(name: "lock", value: "unlocked", descriptionText: "Unlocked manually", isStateChange: true)
			break
		case 3: // Locked by command
			map.descriptionText = "Locked"
			map.data = [ method: "command" ]
            sendEvent(name: "lock", value: "locked", descriptionText: "Locked by command", isStateChange: true)
			break
		case 4: // Unlocked by command
			map.descriptionText = "Unlocked"
			map.data = [ method: "command" ]
            sendEvent(name: "lock", value: "unlocked", descriptionText: "Unlocked by command", isStateChange: true)
			break
		case 5: // Locked with keypad
			if (cmd.eventParameter || cmd.alarmLevel) {
				codeID = readCodeSlotId(cmd)
				codeName = getCodeName(lockCodes, codeID)
				map.descriptionText = "$deviceName locked by \"$codeName\""
				map.data = [ codeId: codeID as String, usedCode: codeID, codeName: codeName, method: "keypad" ]
                sendEvent(name: "lock", value: "locked", descriptionText: "Locked by $codeName", isStateChange: true)
			} else {
				map.descriptionText = "Locked manually"
				map.data = [ method: "keypad" ]
                sendEvent(name: "lock", value: "locked", descriptionText: "Locked by keypad", isStateChange: true)
			}
			break
		case 6: // Unlocked with keypad
			if (cmd.eventParameter || cmd.alarmLevel) {
				codeID = readCodeSlotId(cmd)
				codeName = getCodeName(lockCodes, codeID)
				map.descriptionText = "Unlocked by \"$codeName\""
				map.data = [ codeId: codeID as String, usedCode: codeID, codeName: codeName, method: "keypad" ]
                sendEvent(name: "lock", value: "unlocked", descriptionText: "Unlocked by $codeName", isStateChange: true)
			}
			break
		case 7:
			map = [ name: "lock", value: "unknown", descriptionText: "Unknown state" ]
			map.data = [ method: "manual" ]
			break
		case 8:
			map = [ name: "lock", value: "unknown", descriptionText: "Unknown state" ]
			map.data = [ method: "command" ]
			break
		case 9: // Auto locked
			map = [ name: "lock", value: "locked", data: [ method: "auto" ] ]
			map.descriptionText = "Auto locked"
            sendEvent(name: "lock", value: "locked", descriptionText: "Auto locked", isStateChange: true)
			break    
		case 0xA:
			map = [ name: "lock", value: "unknown", descriptionText: "Unknown state" ]
			map.data = [ method: "auto" ]
			break
		case 0xB:
			map = [ name: "lock", value: "unknown", descriptionText: "Unknown state" ]
			break
		case 0xC: // All user codes deleted
			map = [ name: "codeChanged", value: "all deleted", descriptionText: "Deleted all user codes", isStateChange: true ]
			map.data = [notify: true, notificationText: "Deleted all user codes in $deviceName at ${location.name}"]
			sendLockCodesEvent([:])
			break
		case 0xD: // User code deleted
			if (cmd.eventParameter || cmd.alarmLevel) {
				codePosition = readCodeSlotId(cmd)
				return handleUserCodeDeleted(codePosition)
			}
			break
		case 0xE: // Master or user code changed/set
			if (cmd.eventParameter || cmd.alarmLevel) {
				codePosition = readCodeSlotId(cmd)
				log.debug("code changed from 0xE position $codePosition")
				return handleUserCodeChanged(codePosition)
			}
			break
		case 0xF: // Duplicate Pin-code error
			if (cmd.eventParameter || cmd.alarmLevel) {
				codePosition = readCodeSlotId(cmd)
				return handleUserCodeDuplicate(codePosition)
			}
			break
		case 0x10: // Tamper Alarm
		case 0x13:
			map = [ name: "tamper", value: "detected", descriptionText: "Keypad attempts exceed code entry limit", isStateChange: true, displayed: true ]
			break
		case 0x11: // Keypad busy
			map = [ descriptionText: "Keypad is busy" ]
			break
		case 0x12: // Master code changed
			map = [ name: "codeChanged", value: "0 set", descriptionText: "master code changed", isStateChange: true ]
			map.data = [ notify: true, notificationText: "master code changed in $deviceName at ${location.name}" ]
			break
        case 22:
        case 23:
            return handleDoorSenseReport(cmd)
		case 0xFE:		// delegating it to handleAlarmReportUsingAlarmType
		default:
			// delegating it to handleAlarmReportUsingAlarmType
			return handleAlarmReportUsingAlarmType(cmd)
	}

	if (map) {
		if (map.data) {
			map.data.lockName = deviceName
		} else {
			map.data = [ lockName: deviceName ]
		}
		sendEvent(map)
	}
}

/**
 *
 */
private def handleAllUserCodesDeleted() {
	log.trace "[DTH] Executing 'handleAllUserCodesDeleted' for device ${device.displayName}"
}

/**
 *
 */
private def handleUserCodeDeleted(codePosition) {
	log.trace "[DTH] Executing 'handleUserCodeDeleted' for device ${device.displayName}"
	lockCodes = loadLockCodes()
	name = lockCodes[codePosition.toString()].name

	def map = [ name: "codeChanged", value: "$codePosition deleted", descriptionText: "User code for $name at $codePosition deleted", isStateChange: true, data: [isCodeDuplicate: true] ]

	lockCodes.remove(codePosition.toString())
	sendLockCodesEvent(lockCodes)
	sendEvent(map)
}

/**
 *
 */
private def handleUserCodeChanged(codePosition) {
	log.trace "[DTH] Executing 'handleUserCodeChanged' for device ${device.displayName}"
	lockCodes = loadLockCodes()
	log.debug("codes: $lockCodes")
	log.debug("codePosition: $codePosition")
	name = lockCodes[codePosition.toString()].name

	def map = [ name: "codeChanged", isStateChange: true, value: "$codePosition changed", descriptionText: "Code for $name at position $codePosition changed" ]
	if(!isMasterCode(codeID)) {
		validateLockCode(codePosition)
	} else {
		map.descriptionText = "${getStatusForDescription('set')} \"$codeName\""
		map.data.notificationText = "${getStatusForDescription('set')} \"$codeName\" in $deviceName at ${location.name}"
	}
	sendEvent(map)
}

/**
 *
 */
private def handleUserCodeDuplicate(codePosition) {
	log.trace "[DTH] Executing 'handleUserCodeDuplicate' for device ${device.displayName}"
	def map = [ name: "codeChanged", value: "$codePosition failed, duplicate pin", descriptionText: "User code is duplicate and not added", isStateChange: true, data: [isCodeDuplicate: true] ]
	lockCodes = loadLockCodes()
	def duplicateCode = lockCodes[codePosition.toString()].code
	def positionToDelete = null
	lockCodes.each{ k, v -> if (v.code == duplicateCode) {positionToDelete = k} }

	if (positionToDelete) {
		name = lockCodes[positionToDelete].name
		map.value = "$positionToDelete failed, duplicate pin"
		map.descriptionText = "code for $name at position $positionToDelete failed, duplicate pin"
		lockCodes.remove(positionToDelete)
	}
	sendLockCodesEvent(lockCodes)
	sendEvent(map)
}


/**
 * Responsible for handling DoorSense events
 *
 * @param cmd: The AlarmReport command to be parsed
 *
 * @return: does not return data
 */
private def handleDoorSenseReport(cmd) {
    log.trace "[DTH] Executing 'handleDoorSenseReport' with cmd = $cmd"
	def deviceName = device.displayName
    
    def map = [ name: "contact", value: "open", descriptionText: "", isStateChange: true ]
    map.data = [ lockName: deviceName ]
    
    switch (cmd.alarmLevel) {
        case 0:  // Door is open
            map.value = "open"
            map.descriptionText = "Door opened"
            sendEvent(map)
            break;
        
        case 1:  // Door is closed
            map.value = "closed"
            map.descriptionText = "Door closed"
            sendEvent(map)
            break;

        case 2:  // Door Propped (door open for longer than configurable door propped open)
            map.value = "open"
            map.descriptionText = "Door propped opened"
            sendEvent(map)
            break;

        default:
            log.trace "NotificationReport Error (Received non supported DoorSense alarmLevel from lock)"
            break;
    }
}


/**
 * Responsible for handling Burglar AlarmReport command
 *
 * @param cmd: The AlarmReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
private def handleBurglarAlarmReport(cmd) {
	log.trace "[DTH] Executing 'handleBurglarAlarmReport' with cmd = $cmd"

	def map = [name: "tamper", isStateChange: true, data: [ lockName: device.displayName ] ]
	switch (cmd.zwaveAlarmEvent) {
		case 0:
			map.value = "clear"
			map.descriptionText = "Tamper alert cleared"
			break
		case 1:
		case 2:
			map.value = "detected"
			map.descriptionText = "Intrusion attempt etected"
			break
		case 3:
			map.value = "detected"
			map.descriptionText = "Covering removed"
			break
		case 4:
			map.value = "detected"
			map.descriptionText = "Invalid code"
			break
		default:
			// delegating it to handleAlarmReportUsingAlarmType
			return handleAlarmReportUsingAlarmType(cmd)
	}
	sendEvent(map)
}

/**
 * Responsible for handling Battery AlarmReport command
 *
 * @param cmd: The AlarmReport command to be parsed
 *
 * @return The event(s) to be sent out
 */
private def handleBatteryAlarmReport(cmd) {
	log.trace "[DTH] Executing 'handleBatteryAlarmReport' with cmd = $cmd"
	def deviceName = device.displayName
	switch(cmd.zwaveAlarmEvent) {
		case 0x01: //power has been applied, check if the battery level updated
			executeCommand(secure(zwave.batteryV1.batteryGet()))
			break;
		case 0x0A:
			sendEvent(name: "battery", value: 1, descriptionText: "Battery level critical", displayed: true, data: [ lockName: deviceName ])
			break
		case 0x0B:
			sendEvent(name: "battery", value: 0, descriptionText: "Battery too low to operate lock", isStateChange: true, displayed: true, data: [ lockName: deviceName ])
			break
		default:
			// delegating it to handleAlarmReportUsingAlarmType
			handleAlarmReportUsingAlarmType(cmd)
	}
}

/**
 * Responsible for handling AlarmReport commands which are ignored by Access & Burglar handlers
 *
 * @param cmd: The AlarmReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
private def handleAlarmReportUsingAlarmType(cmd) {
	log.trace "[DTH] Executing 'handleAlarmReportUsingAlarmType' with cmd = $cmd"
	def result = []
	def map = null
	def codeID, lockCodes, codeName
	def deviceName = device.displayName
	lockCodes = loadLockCodes()
	switch(cmd.alarmType) {
		case 9:
		case 17:
			map = [ name: "lock", value: "unknown", descriptionText: "Unknown state" ]
			break
		case 16: // Note: for levers this means it's unlocked, for non-motorized deadbolt, it's just unsecured and might not get unlocked
		case 19: // Unlocked with keypad
			map = [ name: "lock", value: "unlocked" ]
			if (cmd.alarmLevel != null) {
				codeID = readCodeSlotId(cmd)
				codeName = getCodeName(lockCodes, codeID)
				map.isStateChange = true // Non motorized locks, mark state changed since it can be unlocked multiple times
				map.descriptionText = "Unlocked by \"$codeName\""
				map.data = [ codeId: codeID as String, usedCode: codeID, codeName: codeName, method: "keypad" ]
			}
			break
		case 18: // Locked with keypad
			codeID = readCodeSlotId(cmd)
			map = [ name: "lock", value: "locked" ]
			codeName = getCodeName(lockCodes, codeID)
			map.descriptionText = "Locked by \"$codeName\""
			map.data = [ codeId: codeID as String, usedCode: codeID, codeName: codeName, method: "keypad" ]
			break
		case 21: // Manually locked
			map = [ name: "lock", value: "locked", data: [ method: (cmd.alarmLevel == 2) ? "keypad" : "manual" ] ]
			map.descriptionText = "Locked manually"
			break
		case 22: // Manually unlocked
			map = [ name: "lock", value: "unlocked", data: [ method: "manual" ] ]
			map.descriptionText = "Unlocked manually"
			break
		case 23:
			map = [ name: "lock", value: "unknown", descriptionText: "Unknown state" ]
			map.data = [ method: "command" ]
			break
		case 24: // Locked by command
			map = [ name: "lock", value: "locked", data: [ method: "command" ] ]
			map.descriptionText = "Locked"
			break
		case 25: // Unlocked by command
			map = [ name: "lock", value: "unlocked", data: [ method: "command" ] ]
			map.descriptionText = "Unlocked"
			break
		case 26:
			map = [ name: "lock", value: "unknown", descriptionText: "Unknown state" ]
			map.data = [ method: "auto" ]
			break
		case 27: // Auto locked
			map = [ name: "lock", value: "locked", data: [ method: "auto" ] ]
			map.descriptionText = "Auto locked"
			break
		case 32: // All user codes deleted
			map = [ name: "codeChanged", value: "all deleted", descriptionText: "Deleted all user codes", isStateChange: true ]
			map.data = [notify: true, notificationText: "Deleted all user codes in $deviceName at ${location.name}"]
			sendLockCodesEvent([:])
			break
		case 33: // User code deleted
			codePosition = readCodeSlotId(cmd)
			return handleUserCodeDeleted(codePosition)
			break
		case 38: // Non Access
			map = [ descriptionText: "A Non Access Code was entered at the lock", isStateChange: true ]
			break
		case 13:
		case 112: // Master or user code changed/set
			codePosition = readCodeSlotId(cmd)
			log.debug("code changed from 112 position $codePosition")
			return handleUserCodeChanged(codePosition)
			break
		case 34:
		case 113: // Duplicate Pin-code error
			codePosition = readCodeSlotId(cmd)
			return handleDuplicateUserCode(codePosition)
			break
		case 130:  // Batteries replaced
			map = [ descriptionText: "Batteries replaced", isStateChange: true ]
			break
		case 131: // Disabled user entered at keypad
			map = [ descriptionText: "Code ${cmd.alarmLevel} is disabled", isStateChange: false ]
			break
		case 161: // Tamper Alarm
			if (cmd.alarmLevel == 2) {
				map = [ name: "tamper", value: "detected", descriptionText: "Front escutcheon removed", isStateChange: true ]
			} else {
				map = [ name: "tamper", value: "detected", descriptionText: "Keypad attempts exceed code entry limit", isStateChange: true, displayed: true ]
			}
			break
		case 167: // Low Battery Alarm
			if (!state.lastbatt || now() - state.lastbatt > 12*60*60*1000) {
				map = [ descriptionText: "Battery low", isStateChange: true ]
				executeCommand(secure(zwave.batteryV1.batteryGet()))
			} else {
				map = [ name: "battery", value: device.currentValue("battery"), descriptionText: "Battery low", isStateChange: true ]
			}
			break
		case 168: // Critical Battery Alarms
			map = [ name: "battery", value: 1, descriptionText: "Battery level critical", displayed: true ]
			break
		case 169: // Battery too low to operate
			map = [ name: "battery", value: 0, descriptionText: "Battery too low to operate lock", isStateChange: true, displayed: true ]
			break
		default:
			map = [ displayed: false, descriptionText: "Alarm event ${cmd.alarmType} level ${cmd.alarmLevel}" ]
			break
	}

	if (map) {
		if (map.data) {
			map.data.lockName = deviceName
		} else {
			map.data = [ lockName: deviceName ]
		}
		sendEvent(map)
	}
}

/**
 * refactoring
 * Responsible for parsing UserCodeReport command
 *
 * @param cmd: The UserCodeReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(UserCodeReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(UserCodeReport)' with userIdentifier: ${cmd.userIdentifier} and status: ${cmd.userIdStatus} and full cmd $cmd"
	def result = []
	// cmd.userIdentifier seems to be an int primitive type
	def codePosition = cmd.userIdentifier.toString()
	def lockCodes = loadLockCodes()
	def map = [ name: "codeChanged", isStateChange: true ]
	def deviceName = device.displayName
	def userIdStatus = cmd.userIdStatus

	if (userIdStatus == UserCodeReport.USER_ID_STATUS_OCCUPIED ||
			(userIdStatus == UserCodeReport.USER_ID_STATUS_STATUS_NOT_AVAILABLE && cmd.user)) {
		log.trace("User code for position $codePosition is occupied")
		if (!lockCodes.containsKey(codePosition) || lockCodes[codePosition].code != cmd.userCode.toString()) {
			log.trace("User code for position $codePosition is different or non-existent")
			lockCodes[codePosition].code = cmd.userCode.toString()
			map.value = "code updated for $codePosition"
			map.descriptionText = "Code for ${lockCodes[codePosition].name} at position $codePosition updated"
		}
		
		// code is already set
	} else {
		// We are using userIdStatus here because codeID = 0 is reported when user tries to set programming code as the user code
		// code is not set
		log.trace("User code for position $codePosition is not set, removing from lockCodes")
		lockCodes.remove(codePosition)
	}

	sendLockCodesEvent(lockCodes)

	if (state.checkCode == codePosition.toInteger()) {
		reloadList = state.codeReloadList
		if (codePosition.toInteger() == reloadList.first()) {
			reloadList = reloadList.drop(1)
			state.codeReloadList = reloadList
		}
		if (reloadList.size() > 0) {
			state.checkCode = reloadList.first()
			executeCommand(secure(zwave.userCodeV1.userCodeGet(userIdentifier:state.checkCode.toInteger())))
		} else {
			state.checkCode = null
			state.codeReloadList = null
			sendEvent(name: "reloadCodes", value: "reloading complete", descriptionText: "Code reload complete")
			log.trace("Code reload complete")
		}
	}
}

/**
 * Responsible for parsing UsersNumberReport command
 *
 * @param cmd: The UsersNumberReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(UsersNumberReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(UsersNumberReport)' with cmd = $cmd"
	sendEvent(name: "maxCodes", value: cmd.supportedUsers, displayed: false)
}

/**
 * Responsible for parsing AssociationReport command
 *
 * @param cmd: The AssociationReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.associationv2.AssociationReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.associationv2.AssociationReport)' with cmd = $cmd"
	if (cmd.nodeId.any { it == zwaveHubNodeId }) {
		state.remove("associationQuery")
		state["associationQuery"] = null
		sendEvent(descriptionText: "Is associated")
		state.assoc = zwaveHubNodeId
		if (cmd.groupingIdentifier == 2) {
			executeCommand(secure(zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId)))
		}
	} else if (cmd.groupingIdentifier == 1) {
		executeCommand(secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId)))
	} else if (cmd.groupingIdentifier == 2) {
		executeCommand(secure(zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId)))
	}
}

/**
 * Responsible for parsing TimeGet command
 *
 * @param cmd: The TimeGet command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.timev1.TimeGet cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.timev1.TimeGet)' with cmd = $cmd"
	def result = []
	def now = new Date().toCalendar()
	if(location.timeZone) now.timeZone = location.timeZone
	sendEvent(descriptionText: "Requested time update", displayed: false)
	executeCommand(secure(zwave.timeV1.timeReport(
			hourLocalTime: now.get(Calendar.HOUR_OF_DAY),
			minuteLocalTime: now.get(Calendar.MINUTE),
			secondLocalTime: now.get(Calendar.SECOND)))
	)
}

/**
 * Responsible for parsing BasicSet command
 *
 * @param cmd: The BasicSet command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.basicv1.BasicSet)' with cmd = $cmd"
	// DEPRECATED: The old Schlage locks use group 1 for basic control - we don't want that, so unsubscribe from group 1
	sendEvent(name: "lock", value: cmd.value ? "unlocked" : "locked")
	def cmds = [
			zwave.associationV1.associationRemove(groupingIdentifier:1, nodeId:zwaveHubNodeId).format(),
			"delay 1200",
			zwave.associationV1.associationGet(groupingIdentifier:2).format()
	]
	executeCommands(cmds)
}

/**
 * Responsible for parsing BatteryReport command
 *
 * @param cmd: The BatteryReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport)' with cmd = $cmd"
	def map = [ name: "battery", unit: "%" ]
	if (cmd.batteryLevel == 0xFF) {
		map.value = 1
		map.descriptionText = "Has a low battery"
	} else {
		map.value = cmd.batteryLevel
		map.descriptionText = "Battery is at ${cmd.batteryLevel}%"
	}
	state.lastbatt = now()
	sendEvent(map)
}

/**
 * Responsible for parsing ManufacturerSpecificReport command
 *
 * @param cmd: The ManufacturerSpecificReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.ManufacturerSpecificReport)' with cmd = $cmd"
	def msr = String.format("%04X-%04X-%04X", cmd.manufacturerId, cmd.productTypeId, cmd.productId)
	updateDataValue("MSR", msr)
	sendEvent(descriptionText: "MSR: $msr", isStateChange: false)
}

/**
 * Responsible for parsing VersionReport command
 *
 * @param cmd: The VersionReport command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.versionv1.VersionReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.versionv1.VersionReport)' with cmd = $cmd"
	def fw = "${cmd.applicationVersion}.${cmd.applicationSubVersion}"
	updateDataValue("fw", fw)
	if (getDataValue("MSR") == "003B-6341-5044") {
		updateDataValue("ver", "${cmd.applicationVersion >> 4}.${cmd.applicationVersion & 0xF}")
	}
	def text = "${device.displayName}: firmware version: $fw, Z-Wave version: ${cmd.zWaveProtocolVersion}.${cmd.zWaveProtocolSubVersion}"
	sendEvent(descriptionText: text, isStateChange: false)
}

/**
 * Responsible for parsing ApplicationBusy command
 *
 * @param cmd: The ApplicationBusy command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.applicationstatusv1.ApplicationBusy cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.applicationstatusv1.ApplicationBusy)' with cmd = $cmd"
	def msg = cmd.status == 0 ? "try again later" :
			cmd.status == 1 ? "try again in ${cmd.waitTime} seconds" :
					cmd.status == 2 ? "request queued" : "sorry"
	sendEvent(displayed: true, descriptionText: "Is busy, $msg")
}

/**
 * Responsible for parsing ApplicationRejectedRequest command
 *
 * @param cmd: The ApplicationRejectedRequest command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.commands.applicationstatusv1.ApplicationRejectedRequest cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.applicationstatusv1.ApplicationRejectedRequest)' with cmd = $cmd"
	sendEvent(displayed: true, descriptionText: "Rejected the last request")
}

def zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = $cmd"    
    
    // is this v1AlarmType = 0x2b  (DoorState/DoorSense)
    if (cmd.v1AlarmType == 43) {
        // what is the state of DoorSense
        log.trace "got v1AlarmType = 43"
            
        switch (cmd.v1AlarmLevel) {
            case 0:  // Door is open
                log.trace "got v1AlarmLevel = 0  (Door Open)"
                sendEvent(name: "contact", value: "open", isStateChange: true)
                break;
                
            case 1:  // Door is closed
                log.trace "got v1AlarmLevel = 1  (Door Closed)"
                sendEvent(name: "contact", value: "closed", isStateChange: true)
                break;
                
            case 2:  // Door Propped (door open for longer than configurable door propped open)
                log.trace "got v1AlarmLevel = 2  (Door Propped)"
                sendEvent(name: "contact", value: "Propped", isStateChange: true)
                break;
                
            default:
                log.trace "NotificationReport Error (Received non supported v1AlarmLevel from lock)"
                break;
        }
    }
}

def zwaveEvent(hubitat.zwave.commands.alarmv1.AlarmReport cmd) {
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.alarmv1.AlarmReport cmd)' with cmd = $cmd"    
    sendEvent(displayed: false, descriptionText: "$cmd")
}

/**
 * Responsible for parsing zwave command
 *
 * @param cmd: The zwave command to be parsed
 *
 * @return The event(s) to be sent out
 *
 */
def zwaveEvent(hubitat.zwave.Command cmd) {
//    log.debug "***********************************************************************************"
	log.trace "[DTH] Executing 'zwaveEvent(hubitat.zwave.Command)' with cmd = $cmd"
    sendEvent(displayed: false, descriptionText: "$cmd")
}

/**
 * Executes lock and then check command with a delay on a lock
 */
def lockAndCheck(doorLockMode) {

	def cmds = secureSequence([
			zwave.doorLockV1.doorLockOperationSet(doorLockMode: doorLockMode),
			zwave.doorLockV1.doorLockOperationGet()
	], 4200)

	executeCommands(cmds)
}

/**
 * Executes lock command on a lock
 */
def lock() {
	log.trace "[DTH] Executing lock() for device ${device.displayName}"
	lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_SECURED)
}

/**
 * Executes unlock command on a lock
 */
def unlock() {
	log.trace "[DTH] Executing unlock() for device ${device.displayName}"
	lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_UNSECURED)
}

/**
 * Executes unlock with timeout command on a lock
 */
def unlockWithTimeout() {
	log.trace "[DTH] Executing unlockWithTimeout() for device ${device.displayName}"
	lockAndCheck(DoorLockOperationSet.DOOR_LOCK_MODE_DOOR_UNSECURED_WITH_TIMEOUT)
}

/**
 * PING is used by Device-Watch in attempt to reach the Device
 */
def ping() {
	log.trace "[DTH] Executing ping() for device ${device.displayName}"
	runIn(30, followupStateCheck)
	secure(zwave.doorLockV1.doorLockOperationGet())
}

/**
 * Checks the door lock state. Also, schedules checking of door lock state every one hour.
 */
def followupStateCheck() {
	runEvery1Hour(stateCheck)
	stateCheck()
}

/**
 * Checks the door lock state
 */
def stateCheck() {
	sendHubCommand(new hubitat.device.HubAction(secure(zwave.doorLockV1.doorLockOperationGet())))
}

/**
 * Called when the user taps on the refresh button
 */
def refresh() {
	log.trace "[DTH] Executing refresh() for device ${device.displayName}"

	def cmds = secureSequence([zwave.doorLockV1.doorLockOperationGet(), zwave.batteryV1.batteryGet()])
	if (!state.associationQuery) {
		cmds << "delay 4200"
		cmds << zwave.associationV1.associationGet(groupingIdentifier:2).format()  // old Schlage locks use group 2 and don't secure the Association CC
		cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1))
		state.associationQuery = now()
	} else if (now() - state.associationQuery.toLong() > 9000) {
		cmds << "delay 6000"
		cmds << zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId).format()
		cmds << secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId))
		cmds << zwave.associationV1.associationGet(groupingIdentifier:2).format()
		cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1))
		state.associationQuery = now()
	}
	state.lastLockDetailsQuery = now()

	executeCommands(cmds)
}

/**
 * Called by the Smart Things platform in case Polling capability is added to the device type
 */
def poll() {
	log.trace "[DTH] Executing poll() for device ${device.displayName}"
	def cmds = []
	// Only check lock state if it changed recently or we haven't had an update in an hour
	def latest = device.currentState("lock")?.date?.time
	if (!latest || !secondsPast(latest, 6 * 60) || secondsPast(state.lastPoll, 55 * 60)) {
		log.trace "poll is sending doorLockOperationGet"
		cmds << secure(zwave.doorLockV1.doorLockOperationGet())
		state.lastPoll = now()
	} else if (!state.lastbatt || now() - state.lastbatt > 53*60*60*1000) {
		cmds << secure(zwave.batteryV1.batteryGet())
		state.lastbatt = now()  //inside-214
	}
	if (state.assoc != zwaveHubNodeId && secondsPast(state.associationQuery, 19 * 60)) {
		cmds << zwave.associationV1.associationSet(groupingIdentifier:2, nodeId:zwaveHubNodeId).format()
		cmds << secure(zwave.associationV1.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId))
		cmds << zwave.associationV1.associationGet(groupingIdentifier:2).format()
		cmds << "delay 6000"
		cmds << secure(zwave.associationV1.associationGet(groupingIdentifier:1))
		cmds << "delay 6000"
		state.associationQuery = now()
	} else {
		// Only check lock state once per hour
		if (secondsPast(state.lastPoll, 55 * 60)) {
			cmds << secure(zwave.doorLockV1.doorLockOperationGet())
			state.lastPoll = now()
		} else if (!state.MSR) {
			cmds << zwave.manufacturerSpecificV1.manufacturerSpecificGet().format()
		} else if (!state.fw) {
			cmds << zwave.versionV1.versionGet().format()
		} else if (!device.currentValue("maxCodes")) {
			state.pollCode = 1
			cmds << secure(zwave.userCodeV1.usersNumberGet())
		} else if (state.pollCode && state.pollCode <= state.codes) {
			cmds << requestCode(state.pollCode)
		} else if (!state.lastbatt || now() - state.lastbatt > 53*60*60*1000) {
			cmds << secure(zwave.batteryV1.batteryGet())
		}
	}

	if (cmds) {
		log.debug "poll is sending ${cmds.inspect()}"
		executeCommands(cmds)
	} else {
		// workaround to keep polling from stopping due to lack of activity
		sendEvent(descriptionText: "skipping poll", isStateChange: true, displayed: false)
		return null
	}
}

/**
 * Returns the command for user code get
 *
 * @param codeID: The code slot number
 *
 * @return The command for user code get
 */
def requestCode(codeID) {
	executeCommand(secure(zwave.userCodeV1.userCodeGet(userIdentifier: codeID)))
}

/**
 * API endpoint for server smart app to populate the attributes. Called only when the attributes are not populated.
 *
 * @return The command(s) fired for reading attributes
 */
def reloadAllCodes() {
	log.trace "[DTH] Executing 'reloadAllCodes()' by ${device.displayName}"
	sendEvent(name: "scanCodes", value: "Scanning", descriptionText: "Code scan in progress", displayed: false)
	state.checkCode = state.checkCode ?: 1

	def cmds = []
	// Not calling validateAttributes() here because userNumberGet command will be added twice
	if (!state.codes) {
		// BUG: There might be a bug where Schlage does not return the below number of codes
		executeCommand(secure(zwave.userCodeV1.usersNumberGet()))
	} else {
		sendEvent(name: "maxCodes", value: state.codes, displayed: false)
		cmds << requestCode(state.checkCode)
	}
	if(cmds.size() > 1) {
		cmds = delayBetween(cmds, 4200)
	}
	
	executeCommands(cmds)
}

def reloadCodes(positions) {
	log.trace("Executing 'reloadCodes' by ${device.displayName} with $positions")

	if (state.codeReloadList?.size() > 0 || state.checkCode != null) {
		log.warn("Code reload already in progress")
		return
	}

	def positionList = []
	def validPositions = (1..device.currentValue("maxCodes"))

	if (positions == "ALL") {
		positionList = validPositions
	} else {
		def textList = positions.tokenize(",")
		textList.each { v ->
			p = v.trim().tokenize("-")
			if (p.size() == 1) {
				positionList.add(p[0].toInteger())
			} else if (p.size() == 2) {
				(p[0].toInteger()..p[1].toInteger()).each { positionList.add(it.toInteger()) }
			}
		}
		validPositions = validPositions.toSet()
		positionList = positionList.toSet()
		positionList = positionList.intersect(validPositions)
		positionList = positionList.toList().sort()
	}

	if (positionList.size() > 0) {
		sendEvent(name: "reloadCodes", value: "reloading began", descriptionText: "Reloading codes beginning with positions: $positions" )
		state.codeReloadList = (new groovy.json.JsonOutput()).toJson(positionList)
		state.codeReloadList = positionList
		state.checkCode = positionList.first()
		log.trace("Beginning code reload for positions: $positionList")
		executeCommand(secure(zwave.userCodeV1.userCodeGet(userIdentifier:state.checkCode.toInteger())))
	} else {
		log.warn("Invalid code positions: $positions")
	}

}

def getCodes() {
    return loadLockCodes()
}

/**
 * API endpoint for setting the user code length on a lock. This is specific to Schlage locks.
 *
 * @param length: The user code length
 *
 * @returns The command fired for writing the code length attribute
 */
def setCodeLength(length) {
	return null
}

/**
 * API endpoint for setting a user code on a lock
 *
 * @param codeID: The code slot number
 *
 * @param code: The code PIN
 *
 * @param codeName: The name of the code
 *
 * @returns cmds: The commands fired for creation and checking of a lock code
 */
def setCode(codePosition, pin, codeName = null) {
    log.trace("calling set code")
//    log.debug "code = " + code
//    log.debug "!code = " + !code
	if (!pin) {
		log.trace "[DTH] Executing 'nameSlot()' by ${this.device.displayName}"
		// update later Joe
		//nameSlot(codeID, codeName)
		return
	}

	log.trace "[DTH] Executing 'setCode()' by ${this.device.displayName} with codeid $codePosition, code $pin, name $codeName"

	validateAttributes()

	if (addCodeToLockCodes(codePosition, pin, codeName)) {
		executeCommand(secure(zwave.userCodeV1.userCodeSet(userIdentifier:codePosition, userIdStatus:1, userCode:pin)))	
	} else {
		log.warn "[DTH] setCode: Invalid pin: $pin"
	}
}

private def isPinValid(pin) {
	if (pin instanceof List) {
		pin = pin.collect{ it as Character }.join()
	}

	if (pin instanceof String) {
		// trim pin
		pin = pin.trim()
	} else {
		// pin was not a string
		pin = pin.toString()
	}

	if (!(pin =~ /^\d+$/)) {
		// pin was not only numeric digits
		return false
	}

	return pin
}

/**
 */
def boolean addCodeToLockCodes(codePosition, pin, codeName=null, validated=false) {
	lockCodes = loadLockCodes()

	if (!codeName) { codeName = "Code $codePosition" }

	pin = isPinValid(pin)
	if (!pin) { return false }

	lockCodes[codePosition.toString()] = ["name": codeName, "code": pin.toString(), "status": "contingent"]

	sendLockCodesEvent(lockCodes)

	return true
}

def validateLockCode(codePosition, validated=true) {
	lockCades = loadLockCodes()

	lockCodes[codePosition.toString()].status = "active"

	sendLockCodesEvent(lockCodes)
}



/**
 * Validates attributes and if attributes are not populated, adds the command maps to list of commands
 * @return List of commands or empty list
 */
def validateAttributes() {
	if(!device.currentValue("maxCodes")) {
		executeCommand(secure(zwave.userCodeV1.usersNumberGet()))
	}
	log.trace "validateAttributes returning commands list: " + cmds
}

/**
 * API endpoint for deleting a user code on a lock
 *
 * @param codeID: The code slot number
 *
 * @returns cmds: The command fired for deletion of a lock code
 */
def deleteCode(codePosition) {
	log.trace "[DTH] Executing 'deleteCode()' by ${this.device.displayName}"
	// AlarmReport when a code is deleted manually on the lock
	def cmd = secureSequence([
			zwave.userCodeV1.userCodeSet(userIdentifier:codePosition, userIdStatus:0),
			zwave.userCodeV1.userCodeGet(userIdentifier:codePosition)
	], 4200)

	executeCommands(cmd)
}

/**
 * Encapsulates a command
 *
 * @param cmd: The command to be encapsulated
 *
 * @returns ret: The encapsulated command
 */
private secure(hubitat.zwave.Command cmd) {
//	zwave.securityV1.securityMessageEncapsulation().encapsulate(cmd).format()
    zwaveSecureEncap(cmd)    
}

/**
 * Encapsulates list of command and adds a delay
 *
 * @param commands: The list of command to be encapsulated
 *
 * @param delay: The delay between commands
 *
 * @returns The encapsulated commands
 */
private secureSequence(commands, delay=4200) {
	delayBetween(commands.collect{ secure(it) }, delay)
}

/**
 * Sends the queued commands
 */
private executeCommands(commands) {
	for (cmd in commands) {
		executeCommand(cmd)
	}
}

/**
 * Sends the command to the hub
 */
private executeCommand(command, callback=null) {
	def hubAction = new hubitat.device.HubAction(command, hubitat.device.Protocol.ZWAVE)
	sendHubCommand(hubAction)
}

/**
 * Checks if the time elapsed from the provided timestamp is greater than the number of senconds provided
 *
 * @param timestamp: The timestamp
 *
 * @param seconds: The number of seconds
 *
 * @returns true if elapsed time is greater than number of seconds provided, else false
 */
private Boolean secondsPast(timestamp, seconds) {
	if (!(timestamp instanceof Number)) {
		if (timestamp instanceof Date) {
			timestamp = timestamp.time
		} else if ((timestamp instanceof String) && timestamp.isNumber()) {
			timestamp = timestamp.toLong()
		} else {
			return true
		}
	}
	return (now() - timestamp) > (seconds * 1000)
}

/**
 * Reads the code name from the 'lockCodes' map
 *
 * @param lockCodes: map with lock code names
 *
 * @param codeID: The code slot number
 *
 * @returns The code name
 */
private String getCodeName(codeID) {
	lockCodes = loadLockCodes()
	if (isMasterCode(codeID)) {
		return "Master Code"
	}
	return lockCodes[codeID.toString()].name
}

/**
 * Check if a user code is present in the 'lockCodes' map
 *
 * @param codeID: The code slot number
 *
 * @returns true if code is present, else false
 */
private Boolean isCodeSet(codeID) {
	// BUG: Needed to add loadLockCodes to resolve null pointer when using schlage?
	def lockCodes = loadLockCodes()
	lockCodes[codeID.toString()] ? true : false
}

/**
 * Reads the 'lockCodes' attribute and parses the same
 *
 * @returns Map: The lockCodes map
 */
private Map loadLockCodes() {
    def stuff = device.currentValue("lockCodes")
    def stuff2 = decrypt(stuff)?:stuff
	parseJson(stuff2 ?: "{}") ?: [:]
}

/**
 * Populates the 'lockCodes' attribute by calling create event
 *
 * @param lockCodes The user codes in a lock
 */
private def sendLockCodesEvent(lockCodes) {
	sendEvent(name: "lockCodes", value: (new groovy.json.JsonOutput()).toJson(lockCodes), displayed: false,
			descriptionText: "'lockCodes' attribute updated")
}

/**
 * Utility function to figure out if code id pertains to master code or not
 *
 * @param codeID - The slot number in which code is set
 * @return - true if slot is for master code, false otherwise
 */
private boolean isMasterCode(codeID) {
	if(codeID instanceof String) {
		codeID = codeID.toInteger()
	}
	(codeID == 0) ? true : false
}

/**
 * Generic function for reading code Slot ID from AlarmReport command
 * @param cmd: The AlarmReport command
 * @return user code slot id
 */
def readCodeSlotId(hubitat.zwave.commands.alarmv2.AlarmReport cmd) {
	if(cmd.numberOfEventParameters == 1) {
		return cmd.eventParameter[0]
	} else if(cmd.numberOfEventParameters >= 3) {
		return cmd.eventParameter[2]
	}
	return cmd.alarmLevel
}

def logsOff(){
    log.warn "debug logging disabled..."
}
1 Like

I've loaded the new driver but the DoorSense status is still not showing up in the states list. The DoorSense events show in the events list. Is there something else I should try? Thank you for your help with this.

Contact just showed up. I guess it needed more time. I'm going to add it to my dashboard. I'll update with further testing. Thanks for your help.

1 Like

With the new driver, it's been working great. Thanks again for your help @jtp10181.

2 Likes

@jtp10181 @joemc91 @Hubi

Would it be possible to update this driver to support the newer Yale Assure 2 lock with touch and key? I tried the updated driver above that @jtp10181 posted. It locks and unlocks my door and the contact updates for door open/close, but it is throwing an error in my logs and the door lock/unlock status is not updating, nor is the "Last Code Name" field under 'Current States'. The lock that I purchased has the new Z-Wave Plus v2.40.0 smart module with S2 security (model AYR-MOD-ZW3-USA).

Here are my logs:

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:05.441 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:05.408 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 2, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:05.402 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 02 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:04.546 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@120e553[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:04.542 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:24, commandLength: 19, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[19, 6, 0, 255, 6, 6, 10, 99, 3, 6, 1, 57, 53, 54, 56, 50, 52] to java.util.concurrent.FutureTask@120e553[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@142c48[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@14ca516]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:04.535 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 19, v1AlarmLevel: 6, notificationStatus: 255, notificationType: 6, event: 6, sequence: false, eventParametersLength: 10, eventParameter: [99, 3, 6, 1, 57, 53, 54, 56, 50, 52], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:04.528 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:24, commandLength: 19, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[19, 6, 0, 255, 6, 6, 10, 99, 3, 6, 1, 57, 53, 54, 56, 50, 52]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:40:04.522 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 18 13 71 05 13 06 00 FF 06 06 0A 63 03 06 01 39 35 36 38 32 34 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:39.829 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:39.827 AM

debug

Parsed DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 0, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:39.776 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 0, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:39.771 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: FF 00 00 FE FE FF 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:38.853 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@62757c[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:38.850 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:23, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 2, 0, 255, 6, 1, 0] to java.util.concurrent.FutureTask@62757c[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@1d02e66[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@4830fc]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:38.845 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 21, v1AlarmLevel: 2, notificationStatus: 255, notificationType: 6, event: 1, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:38.840 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:23, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 2, 0, 255, 6, 1, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:38.836 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 17 09 71 05 15 02 00 FF 06 01 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:18.862 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:18.830 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 2, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:18.826 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 02 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:17.909 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@512832[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:17.906 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:22, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[22, 1, 0, 255, 6, 2, 0] to java.util.concurrent.FutureTask@512832[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@c96987[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@160c97]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:17.901 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 22, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 2, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:17.896 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:22, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[22, 1, 0, 255, 6, 2, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:39:17.892 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 16 09 71 05 16 01 00 FF 06 02 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:08.186 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:08.184 AM

debug

Parsed DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 0, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:08.167 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 0, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:08.163 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: FF 00 00 FE FE FF 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:07.258 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@962061[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:07.255 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:21, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 1, 0, 255, 6, 1, 0] to java.util.concurrent.FutureTask@962061[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@14fd5bd[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@1564700]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:07.250 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 21, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 1, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:07.234 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:21, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 1, 0, 255, 6, 1, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:38:07.230 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 15 09 71 05 15 01 00 FF 06 01 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:34.739 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:34.706 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 2, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:34.702 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 02 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:33.784 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@16f66c5[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:33.782 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:20, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[22, 1, 0, 255, 6, 2, 0] to java.util.concurrent.FutureTask@16f66c5[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@1d3cfa[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@181d00a]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:33.776 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 22, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 2, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:33.772 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:20, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[22, 1, 0, 255, 6, 2, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:33.768 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 14 09 71 05 16 01 00 FF 06 02 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:21.795 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:21.793 AM

debug

Parsed DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 0, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:21.763 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 0, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:21.758 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: FF 00 00 FE FE FF 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:20.844 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@3e52ef[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:20.840 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:19, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 1, 0, 255, 6, 1, 0] to java.util.concurrent.FutureTask@3e52ef[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@17af9ca[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@fb5550]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:20.835 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 21, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 1, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:20.830 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:19, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 1, 0, 255, 6, 1, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:37:20.826 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 13 09 71 05 15 01 00 FF 06 01 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:07.446 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:07.411 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 2, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:07.407 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 02 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:06.601 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@21b90f[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:06.598 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:18, commandLength: 19, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[145, 1, 0, 255, 6, 6, 10, 99, 3, 1, 1, 49, 48, 52, 51, 50, 52] to java.util.concurrent.FutureTask@21b90f[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@5ead16[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@167ac49]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:06.592 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 145, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 6, sequence: false, eventParametersLength: 10, eventParameter: [99, 3, 1, 1, 49, 48, 52, 51, 50, 52], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:06.586 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:18, commandLength: 19, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[145, 1, 0, 255, 6, 6, 10, 99, 3, 1, 1, 49, 48, 52, 51, 50, 52]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:36:06.525 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 12 13 71 05 91 01 00 FF 06 06 0A 63 03 01 01 31 30 34 33 32 34 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:57.454 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@139cca5[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:57.451 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:17, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 0, 0, 255, 6, 22, 0] to java.util.concurrent.FutureTask@139cca5[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:57.443 AM

trace

got v1AlarmLevel = 0 (Door Open)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:57.442 AM

trace

got v1AlarmType = 43

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:57.439 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 43, v1AlarmLevel: 0, notificationStatus: 255, notificationType: 6, event: 22, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:57.432 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:17, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 0, 0, 255, 6, 22, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:57.429 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 11 09 71 05 2B 00 00 FF 06 16 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:47.583 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:47.562 AM

debug

Parsed DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:47.524 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:47.520 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: FF 00 01 FE FE FF 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:46.602 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@15cf4e7[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:46.600 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:16, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 1, 0, 255, 6, 1, 0] to java.util.concurrent.FutureTask@15cf4e7[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@17da91a[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@3ea8aa]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:46.595 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 21, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 1, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:46.590 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:16, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[21, 1, 0, 255, 6, 1, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:46.586 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 10 09 71 05 15 01 00 FF 06 01 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:28.401 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@1a9c180[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:28.398 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:15, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 1, 0, 255, 6, 23, 0] to java.util.concurrent.FutureTask@1a9c180[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@1b21b3f[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@eb0f7b]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:28.392 AM

trace

got v1AlarmLevel = 1 (Door Closed)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:28.391 AM

trace

got v1AlarmType = 43

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:28.311 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 43, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 23, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:28.306 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:15, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 1, 0, 255, 6, 23, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:28.301 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 0F 09 71 05 2B 01 00 FF 06 17 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:06.325 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@54f484[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:06.324 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:14, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 0, 0, 255, 6, 22, 0] to java.util.concurrent.FutureTask@54f484[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:06.316 AM

trace

got v1AlarmLevel = 0 (Door Open)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:06.315 AM

trace

got v1AlarmType = 43

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:06.313 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 43, v1AlarmLevel: 0, notificationStatus: 255, notificationType: 6, event: 22, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:06.308 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:14, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 0, 0, 255, 6, 22, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:35:06.305 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 0E 09 71 05 2B 00 00 FF 06 16 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:55.330 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@151b776[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:55.327 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:13, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 1, 0, 255, 6, 23, 0] to java.util.concurrent.FutureTask@151b776[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:55.317 AM

trace

got v1AlarmLevel = 1 (Door Closed)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:55.316 AM

trace

got v1AlarmType = 43

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:55.312 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 43, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 23, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:55.307 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:13, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 1, 0, 255, 6, 23, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:55.303 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 0D 09 71 05 2B 01 00 FF 06 17 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:00.283 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@1f5abf5[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:00.280 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:12, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 0, 0, 255, 6, 22, 0] to java.util.concurrent.FutureTask@1f5abf5[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@c8a1ce[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@f73d0f]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:00.273 AM

trace

got v1AlarmLevel = 0 (Door Open)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:00.272 AM

trace

got v1AlarmType = 43

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:00.265 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 43, v1AlarmLevel: 0, notificationStatus: 255, notificationType: 6, event: 22, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:00.259 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:12, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[43, 0, 0, 255, 6, 22, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:34:00.255 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 0C 09 71 05 2B 00 00 FF 06 16 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:50.374 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:50.302 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:50.295 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:49.378 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@b4e1e4[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:49.375 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:11, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[22, 1, 0, 255, 6, 2, 0] to java.util.concurrent.FutureTask@b4e1e4[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@f8307[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@10d0a62]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:49.370 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 22, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 2, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:49.363 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:11, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[22, 1, 0, 255, 6, 2, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:33:49.360 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 0B 09 71 05 16 01 00 FF 06 02 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:07.836 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:07.834 AM

debug

Parsed DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:07.816 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:07.812 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: FF 00 01 FE FE FF 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:06.976 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@156600a[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:06.905 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:10, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[24, 1, 0, 255, 6, 3, 0] to java.util.concurrent.FutureTask@156600a[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@1ae0b7a[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@169febf]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:06.898 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 24, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 3, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:06.887 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:10, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[24, 1, 0, 255, 6, 3, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:06.881 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 0A 09 71 05 18 01 00 FF 06 03 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:04.292 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:04.263 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:04.260 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE FF 03 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:03.820 AM

trace

[DTH] Executing lock() for device 2nd - Lock - Front Door (New)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:01.915 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:01.884 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:01.880 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.965 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@1155cec[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.962 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:9, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[25, 1, 0, 255, 6, 4, 0] to java.util.concurrent.FutureTask@1155cec[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@1ed379c[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@12ad191]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.956 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 25, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 4, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.951 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:9, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[25, 1, 0, 255, 6, 4, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.947 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 09 09 71 05 19 01 00 FF 06 04 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.785 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.751 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.748 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE 00 03 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.264 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.230 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.226 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:31:00.136 AM

trace

[DTH] Executing unlock() for device 2nd - Lock - Front Door (New)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:59.332 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@11fbd3d[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:59.329 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:8, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[25, 1, 0, 255, 6, 4, 0] to java.util.concurrent.FutureTask@11fbd3d[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@1e7d64d[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@12036c1]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:59.251 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 25, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 4, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:59.246 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:8, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[25, 1, 0, 255, 6, 4, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:59.243 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 08 09 71 05 19 01 00 FF 06 04 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:56.563 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:56.561 AM

debug

Parsed DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:56.524 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:56.520 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: FF 00 01 FE FE 00 03 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:30:54.959 AM

trace

[DTH] Executing unlock() for device 2nd - Lock - Front Door (New)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:11.693 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:11.691 AM

debug

Parsed DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:11.689 AM

info

2nd - Lock - Front Door (New) command "lock" succeeded on retry: 1.

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:11.668 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 255, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 1, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:11.664 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: FF 00 01 FE FE FF 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:10.750 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@cc0d74[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:10.747 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:7, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[24, 1, 0, 255, 6, 3, 0] to java.util.concurrent.FutureTask@cc0d74[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@eddbde[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@1ef4727]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:10.741 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 24, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 3, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:10.736 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:7, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[24, 1, 0, 255, 6, 3, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:10.732 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 07 09 71 05 18 01 00 FF 06 03 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.910 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.881 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.877 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE FF 03 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.529 AM

trace

[DTH] Executing lock() for device 2nd - Lock - Front Door (New)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.152 AM

info

[DTH] parse() - returning result=java.util.concurrent.FutureTask@1619ac2[Completed normally]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.148 AM

debug

Parsed SupervisionGet(statusUpdates:false, sessionID:6, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[24, 1, 0, 255, 6, 3, 0] to java.util.concurrent.FutureTask@1619ac2[Not completed, task = java.util.concurrent.Executors$RunnableAdapter@40a61a[Wrapped task = com.hubitat.hub.executor.DeviceDelegatingScript$_sendHubCommand_closure1@1f91621]]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.142 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport' with cmd = NotificationReport(v1AlarmType: 24, v1AlarmLevel: 1, notificationStatus: 255, notificationType: 6, event: 3, sequence: false, eventParametersLength: 0, eventParameter: [], sequenceNumber: 0)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.030 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd)' with cmd = SupervisionGet(statusUpdates:false, sessionID:6, commandLength: 9, commandClassIdentifier: 113, commandIdentifier:5, commandByte:[24, 1, 0, 255, 6, 3, 0]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:08.021 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6C01, payload: 06 09 71 05 18 01 00 FF 06 03 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:05.328 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:05.296 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:05.292 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE FF 03 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:28:03.476 AM

trace

[DTH] Executing lock() for device 2nd - Lock - Front Door (New)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:28.124 AM

info

[DTH] parse() - returning result=null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:28.121 AM

debug

Parsed BatteryReport(batteryLevel:92) to null

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:28.109 AM

trace

[DTH] Executing 'zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport)' with cmd = BatteryReport(batteryLevel:92)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:28.098 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 8003, payload: 5C , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:27.975 AM

error

groovy.lang.GroovyRuntimeException: Could not find matching constructor for: hubitat.device.HubAction(hubitat.zwave.commands.associationv1.AssociationSet, hubitat.device.Protocol) on line 1419 (method parse)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:27.866 AM

trace

[DTH] Executing 'zwaveEvent(DoorLockOperationReport)' with cmd = DoorLockOperationReport(doorLockMode: 0, outsideDoorHandlesMode: 0, insideDoorHandlesMode: 0, doorCondition: 3, lockTimeoutMinutes: 254, lockTimeoutSeconds: 254)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:27.856 AM

trace

[DTH] Executing 'parse(String description)' for device 2nd - Lock - Front Door (New) with description = zw device: 57, command: 6203, payload: 00 00 03 FE FE 00 00 , isMulticast: false

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:26.122 AM

debug

Do configure returning with commands := [9F03046202, delay 30000, 9F03048002]

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:26.077 AM

trace

[DTH] Executing 'doConfigure()' for device 2nd - Lock - Front Door (New)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:27:26.075 AM

trace

[DTH] Executing 'configure()' for device 2nd - Lock - Front Door (New)

[dev:451](http://192.168.11.4/device/list#)2025-07-08 11:25:10.140 AM

info

2nd - Lock - Front Door (New) battery is 91%

FYI - a screenshot of logs is usually much easier to read than text which is cut & paste.

Thanks. I was concerned that the screenshot wouldn't capture all of the details that are needed. I have modified the post to put the logs in a pre-formatted code box and I will add a screenshot.

1 Like

Try commenting out 293-299.
TBH this code is sort of a mess, and I am not sure why it is trying to set associations right here. Also not sure why this would be tossing an error, it looks fine. But I am pretty sure it is not liking one of these commands.

I will give that a try. Thanks!