Implementing capability.lockCodes - need guidance on a couple commands

I’ve done some searching in the docs, community, git & the greater Googles, but it seems that there just isn’t a lot of info on the lockCodes capability yet. Most of the actions are pretty self-explanatory, but a couple of them seem to overlap, and I’m wondering what the intention behind them is so that I implement what ST had in mind.

Specifically, the actions I’m unsure of are updateCodes(string) and reloadAllCodes().

Taking a stab, I’d say that updateCodes will change the codes for multiple slots as designated by the string arg. But what is the string arg? Some kind of delimited structure of slot #/code pairs?

I’ll guess, then, that reloadAllCodes will set all slots on the lock to the vales held in a local structure so the lock is back to a known state for all slots.

Also, what are the return values intended? For requestCode, I have a fairly good idea what the return might be. Or do they all typically return void & then an event is handled with an async return?

As I’m new to ST, I’m trying to wrap my head around conventions and whatnot. I’m a big fan of being able to fish for myself, so if there are resources I’ve missed, a pointer is much appreciated :slight_smile:

1 Like

So, I found the implementation of capability.LockCodes in the Z-Wave Lock device type example. It wouldn’t be so embarrassing that I asked my question before finding this, but I’d already brought this device type example into my IDE and had been looking thru the code.

sigh - It’s been a long week…

It takes a bit to figure out where things are, as they are spread out between the forums, github, and the IDE development area. The IDE is a common share point, but many of us do not fully share until we are confident the code works properly. So you will find many examples that are “in progress”.

I am still learning groovy, not use to the syntax yet. But, I believe that I have the basics down.

Just keep up the good work and share what you develope so that we all here in the community can enjoy your work here.

1 Like

Sorry about the lack of documentation on lockCodes. The capability isn’t finished, so it will likely still change, but here’s the run down:

lock.setCode(2, "0486") to set code #2 to 0486

You need to subscribe to “codeReport” to get the result of that, same with lock.requestCode(). The actual code is in the event data, accessed as evt.jsonData.code.

Subscribe to “codeChanged” to get notified when codes are deleted or changed manually, if you use lock.deleteCode(3) you should get a “codeReport” with blank code.

updateCodes takes JSON format like so:

lock.updateCodes('{"code2":"0486","code4":"2626","code5":""}')

Note the empty string to delete code 5.

lock.reloadAllCodes() will go through and getCode each code in order. You’ll get a big bunch of events so use it sparingly. It’s basically a stopgap since our system currently doesn’t support returning values from device methods.

There may be bugs, so let me know if you run into issues.

4 Likes

@duncan
I noticed that the device type for Z-Wave lock has changed significantly and new capabilities have been added. Is there any new official apps that are taking advantage of the new capabilities?

Is SmartThings actually using the code that is listed in Device Type Examples?

Was it announced somewhere that new commands are now available? I stumbled upon this information accidentally. It would be great if this type of updates are more advertised so that we could take advantage of the new capabilities.

Thanks

1 Like

The capability is there because official support for lock codes was being worked on a while ago, but it got delayed. The code in the device type examples almost always matches the code we are using for the device types.

We didn’t announce it because it’s not complete and we can’t guarantee forward support of those commands yet.

@duncan where is the documentation on this subcription for codeReport, codeChanged etc? I even looked at the Z-Wave lock source code and can’t find anything. Am I missing something here?

@duncan, I use the following code to subscribe to code reports

subscribe(lock, “lock.codeReport”, lockEvent)

Let me know if I’m doing this correct because I’m not seeing my smart app being called when I make a call to lock.getCode(user) to get notified if the user has a code set or not, but there is no call back to the event handler.
Code:

preferences {
    section("Select Lock") {
        input "lock","capability.lock", title: "Lock"
    }
    section("User Information") {
        input "user", "number", title: "User slot number, leave blank to get all active user slots", description: "This is the user slot number on the lock", required: false
    }
}

def installed()
{
	appTouch()
}

def updated()
{
	appTouch()
}

def lockEvent(evt) {
    log.debug "$evt.value: $evt.data, $evt.jsonData.code, $settings"
}

def appTouch() {
	unsubscribe()
	subscribe(lock, "lock.codeReport", lockEvent)

	if (user) {
	    lock.requestCode(user)
	} else {
		lock.reloadAllCodes()
	}
}

Here is what I see in the logging:

665492b7-bc61-43d0-8207-e798c9c8a883 2:14:32 AM: trace lock.codeReport from Deck Door Lock was provided with lockEvent…creating subscription
665492b7-bc61-43d0-8207-e798c9c8a883 2:14:32 AM: trace Lock Active User Slots is attempting to unsubscribe from all events

and from the door lock:

858fa556-f2a8-40ad-b68f-6223f9beee97 2:14:32 AM: error groovy.lang.MissingMethodException: No signature of method: static java.lang.Integer.toString() is applicable for argument types: (null, java.lang.Integer) values: [null, 16]
Possible solutions: toString(), toString(), toString(), toString(int), toString(int, int), toHexString(int) @ line 501
858fa556-f2a8-40ad-b68f-6223f9beee97 2:14:08 AM: debug "zw device: 1B, command: 9881, payload: 00 63 03 01 01 2A 2A 2A 2A 2A 2A 2A 2A 2A 2A " parsed to [[‘name’:‘codeReport’, ‘value’:1, ‘data’:[‘code’:‘**********’], ‘descriptionText’:Deck Door Lock code 1 is set, ‘displayed’:true, ‘isStateChange’:false, ‘linkText’:‘Deck Door Lock’]]

So the door lock is getting the command parsing it (reloadAllCodes is breaking but getUserCode() is working) but it isn’t calling the smartapp event handler. Something amiss here?

Unless I’m missing something, it should be subscribe(lock, "codeReport", lockEvent). The syntax for the subscription is “name” or “name.value” – if you look at the event, the name is “codeReport”.

Thanks, I tried that still not call back to the event handler. I can see the door device parsing the information but the callback to the handler is not taking place.

665492b7-bc61-43d0-8207-e798c9c8a883 7:10:58 PM: trace codeReport from Deck Door Lock was provided with lockEvent…creating subscription
665492b7-bc61-43d0-8207-e798c9c8a883 7:10:57 PM: trace Lock Active User Slots is attempting to unsubscribe from all events
665492b7-bc61-43d0-8207-e798c9c8a883 7:10:41 PM: trace codeReport from Deck Door Lock was provided with lockEvent…creating subscription
665492b7-bc61-43d0-8207-e798c9c8a883 7:10:40 PM: trace Lock Active User Slots is attempting to unsubscribe from all events

@duncan any thoughts on this please? I’m kinda stuck here without getting notifications from the lock I can’t proceed any further. If you have some sample code that works please share it so I can use that to build the next steps.

@duncan can you verify if you’re able to get this work on your end with your test/device?

thanks

I ran a few tests and it looks like the codeReport event always fires after change events or when no changes are made so isStateChange is always false. That seems to be combined with an issue with filterEvents = false on the subscription, which looks like it has no effect.

I haven’t had a chance to test filterEvents across other subscriptions/events, but the most recent docs say that when isStateChange is false, the event does not propagate through the system.

I used a custom device type that set isStateChange to true no matter what and all subscriptions/handlers on the codeReport event are called correctly.

@duncan, do you have any thoughts on what we are seeing? It seems like the best fix would be to figure out why filterEvents is not working. It does make sense that on the code report, there are no state changes as it is just a status report.