Digital Unlock as trigger

I want to run an action when my lock is unlocked digitally. I found an older thread asking this question but It didn’t have any responses.

The situation I am trying to remedy is when I unlock the door from the car while my wife is walking up. It never fails that she will try her code and end up locking the door, frustrating while carrying a baby. If I can trigger off a digital unlock rather than a code I will flash my entryway bulb for a few seconds as an indicator. I am open to other solutions as well.

1 Like

I'm not sure I understand what you are asking. Why can't you just setup a rule where the trigger is LockDevice UNLOCKED and then perform some action?

If someone’s at the door and puts their code in I don’t need an indicator that it’s recently been unlocked.

I only want to trigger if it’s been unlocked digitally(with zwave).

Right. If you unlock it 'remotely' an UNLOCKED event should be generated. Is that not happening?

I'm not sure what threads you read, but there are a few that discuss this issue. Rule Machine (assuming that's what you're using) doesn't have a direct way to access the physical vs. digital status of locks/unlocks, perhaps a decision they made due to the fact that not all locks support this (it is supported for switches and dimmers; I guess that is more common).

One workaround for a specific lock is here:

This can likely be adapted, if even needed, to work for other types of locks. That being said, the implementation seems a bit odd to me since an app should be able to just access the physical/digital status, if supplied, directly rather than hunting through the description text for it (which alone might be a workaround without this in RM if your lock consistently reports something that could be used there).

However, you may wish to consider other things people have recommended instead. For example, a physical unlock is highly likely to also trigger motion in the area (by definition, a person should be there doing it). Do you have a motion sensor (or more) that you could use and check as a condition in your rule/app instead (you can still trigger based on the lock)? Or is there another workaround like presence you haven't considered? Explaining your actual desired outcome might give other people ideas to share that you'll also like.

Correct but it is also generated when it’s unlocked with a code. I’m trying to distinguish between the two.

There’s a nest cam on the patio that is integrated. Maybe I can use that motion to filter out the manual and code unlocks.

Here some code I was adapting for something very similar. I not mine originally.

It loaded as an app. And you have to create virtual switches for each type of event which can then be used in rules. This reads the event log for the lock. I have not fully tested the digital lock/unlock section so its commented out.

    name: "Kwikset Lock Events",
    namespace: "kuzenkohome",
    author: "Mike Kuzenko",
    description: "Tracks when a lock is manually or keypad controlled and updates virtual switches",
    category: "Convenience",
	iconUrl: "",
    iconX2Url: "",
    iconX3Url: "")


def lock = [
    name: "lock",
    type: "capability.lock",
    title: "Lock",
    description: "Select the lock to monitor.",
    required: true,
    multiple: false
]

def virtualManLockedSwitch = [
    name: "virtualManLockedSwitch",
    type: "capability.switch",
    title: "Virtual Manual Lock Switch",
    description: "Virtual switch that should be turned on when lock is manually locked.",
    required: true,
    multiple: false
]

def virtualManUnlockedSwitch = [
    name: "virtualManUnlockedSwitch",
    type: "capability.switch",
    title: "Virtual Manual Unlock Switch",
    description: "Virtual switch that should be turned on when lock is manually unlocked.",
    required: true,
    multiple: false
]

def virtualKeypadLockedSwitch = [
    name: "virtualKeypadLockedSwitch",
    type: "capability.switch",
    title: "Virtual Keypad Lock Switch",
    description: "Virtual switch that should be turned on when lock is locked by Keypad.",
    required: true,
    multiple: false
]

def virtualKeypadUnLockedSwitch = [
    name: "virtualKeypadUnLockedSwitch",
    type: "capability.switch",
    title: "Virtual Keypad Unlock Switch",
    description: "Virtual switch that should be turned on when lock is unlocked by Keypad.",
    required: true,
    multiple: false
]


def enableLogging = [
    name:				"enableLogging",
    type:				"bool",
    title:				"Enable debug Logging?",
    defaultValue:		false,
    required:			true
]

preferences {
	page(name: "mainPage", title: "<b>Lock to monitor:</b>", install: true, uninstall: true) {
		section("") {
			input lock
			input virtualManLockedSwitch
			input virtualManUnlockedSwitch
			input virtualKeypadLockedSwitch
			input virtualKeypadUnLockedSwitch
			label title: "Assign an app name", required: false
		}
		section ("<b>Advanced Settings</b>") {
			input enableLogging
		}
	}
}

def installed() {
	log.info "Installed with settings: ${settings}"
	initialize()
}

def updated() {
	log.info "Updated with settings: ${settings}"
	unsubscribe()
	initialize()
}

def initialize() {
    log "Lock status: ${lock.displayName} " + lockStatus()
	subscribe(lock, "lock.locked", manualLockHandler)
	subscribe(lock, "lock.locked", keypadLockHandler)
	subscribe(lock, "lock.unlocked", manualUnlockHandler)
	subscribe(lock, "lock.unlocked", keypadUnlockHandler)
	//subscribe(lock, "lock.unlocked", digitalUnlockHandler)
	//subscribe(lock, "lock.locked", digitalLockHandler)
}

def lockStatus() {
	return lock.currentValue("lock")
}

def keypadLockHandler(evt) {
	log("Lock event: ${evt.name} : ${evt.descriptionText}")
	if (evt.type == 'physical' && evt.descriptionText.endsWith('locked by keypad')) {
		log "${lock.displayName} was locked by keypad"
		virtualManLockedSwitch.off()
        virtualManUnlockedSwitch.off()
        virtualKeypadLockedSwitch.on()
        virtualKeypadUnLockedSwitch.off()
	} else {
		log "${lock.displayName} was locked"
	}
}

def keypadUnlockHandler(evt) {
	log("Unlock event: ${evt.name} : ${evt.descriptionText}")
	if (evt.type == 'physical' && evt.descriptionText.contains('unlocked by code')) {
		log "${lock.displayName} was unlocked by keypad code"
		virtualManLockedSwitch.off()
        virtualManUnlockedSwitch.off()
        virtualKeypadLockedSwitch.off()
        virtualKeypadUnLockedSwitch.on()
	} else {
		log "${lock.displayName} was unlocked"
	}
}

def manualLockHandler(evt) {
	log("Lock event: ${evt.name} : ${evt.descriptionText}")
	if (evt.type == 'physical' && evt.descriptionText.endsWith('locked by manual')) {
		log "${lock.displayName} was locked manually"
		virtualManLockedSwitch.on()
        virtualManUnlockedSwitch.off()
        virtualKeypadLockedSwitch.off()
        virtualKeypadUnLockedSwitch.off()
	} else {
		log "${lock.displayName} was locked"
	}
}

def manualUnlockHandler(evt) {
	log("Unlock event: ${evt.name} : ${evt.descriptionText}")
	if (evt.type == 'physical' && evt.descriptionText.endsWith('unlocked by manual')) {
		log "${lock.displayName} was unlocked manually"
		virtualManLockedSwitch.off()
        virtualManUnlockedSwitch.on()
        virtualKeypadLockedSwitch.off()
        virtualKeypadUnLockedSwitch.off()
	} else {
		log "${lock.displayName} was unlocked"
	}
}

/*
def digitalLockHandler(evt) {
	log("Lock event: ${evt.name} : ${evt.descriptionText}")
	if (evt.type == 'digital' && evt.descriptionText.endsWith('locked by digital command')) {
		log "${lock.displayName} was locked digitally"
		virtualLockedSwitch.on()
        virtualUnlockedSwitch.off()
        virtualKeypadLockedSwitch.off()
	} else {
		log "${lock.displayName} was locked"
	}
}

def digitalUnlockHandler(evt) {
	log("Unlock event: ${evt.name} : ${evt.descriptionText}")
	if (evt.type == 'digital' && evt.descriptionText.endsWith('unlocked by digital command')) {
		log "${lock.displayName} was unlocked digitally"
		virtualLockedSwitch.off()
        virtualUnlockedSwitch.on()
        virtualKeypadLockedSwitch.off()
	} else {
		log "${lock.displayName} was unlocked"
	}
}
*/

def log(msg) {
    if (enableLogging) {
        log.debug msg
    }
}

Hope this helps

Mike

That is interesting. I’ll try and play around with it.