[GUIDE] Writing Z-Wave Drivers for S2

Agreed. Its unlikely (1 in 64) and only for the first command.

I had thought about random, but realized that can clash too. The way I currently address this is I use an Initialize routine where, during driver startup, it reads the devices current attributes and send that to the device twice (on two sequential sessionIDs). This both ensures the device is at the value that Hubitat thinks it is (just in case a device was turned on / off or something else happened to it during the reboot), and, by sending twice, it ensures the sessionID that is used will work (if the first attempt clashes with a prior sessionID, the second succeeds; if the first is fine, the second will be too, but no harm). I suspect this is as good a method as any.

Anyway, thanks for the info. you provided this morning. It helped to clear up a few misunderstandings that I had about this feature.

Out of curiosity... Would this mean that the Z-wave trafic is doubled? Can this become a problem on a mesh with many devices, especially if many drivers do the same thing?

I'd say the increase in traffic is miniscule compared to the available bandwidth and the time period over which startup occurs. I'm doing this with about 75 devices right now and it isn't noticeable. The reason it isn't a problem is it only happens on a hub reboot and it is only done once. Assuming each driver takes 1 second to start up (and some of mine take longer), you're talking about each driver adding only a couple of short command / acknowledgement sequences on a channel that can handle many commands per second during a period where performance isn't a significant issue.

1 Like

Awesome post. Love the indepth explanation.

Time to update my drivers with proper s2 encapsulation.

2 Likes

Question - I noticed the inclusion of the supervisionCheck function which seems to perform a retransmission if you don't get a "success" response. I don't have anything like this in my code since I thought it was the job of the SDK to perform the application-level retransmission and the driver doesn't have to worry about it. Did I get this wrong - i.e., Is this another misunderstanding I have and do I need to do this (or are you being extra cautious)?

I do do something that I guess is a bit on the flip-side of this which is, if I get a "failure" code back in return to a supervision message, I put the command code (cmd.CMD) into a failure table (which is stored @Field static based on the manufacturer / deviceType / deviceID code of the device so any failure of a similar device is marked for all similar devices ) and never try to supervise that same command again for the same device type (I had found some devices seemed to always respond with a "failure" even when they were supposed to succeed, so I made it so my code "learns" this and adapts). I'm revisiting all this based on your sample (checking to make sure my "failures" weren't coding problems).

The SDK doesn’t perform this application layer re-transmit. The SDK already got it’s ACK and has cleared this packet out of it’s queue..

1 Like

yep, I had that wrong. Thanks for clarifying.

1 Like

Anytime

1 Like

Forgive my intrusion (my only experience w/"ACK" is below, and I'm not a SW engineer)...

image

When will this thread and it's excellent/useful info be moved into the fully accessible/non-beta part of the forum so all developers have access to it? I'm not sure why it's in the 2.2.7 beta section (Security Encapsulation is new in 2.2.7?) but that's above my pay grade.

From the responses of the developers to this info, seems like the more developers see this, the better for them and their drivers and for HE/HE users. :slight_smile:

It will be moved out to public soon..

2 Likes

It’s public now.

3 Likes

Ok.. Just noticed a couple of places in the example code is using a method of mine to simplify things.. sendToDevice ..

This just packages the commands into a HubAction or HubMultiAction and sends it out immediately:

void sendToDevice(List<String> cmds, Long delay = 300) {
    sendHubCommand(new hubitat.device.HubMultiAction(commands(cmds, delay), hubitat.device.Protocol.ZWAVE))
}

void sendToDevice(String cmd, Long delay = 300) {
    sendHubCommand(new hubitat.device.HubAction(zwaveSecureEncap(cmd), hubitat.device.Protocol.ZWAVE))
}

List<String> commands(List<String> cmds, Long delay = 300) {
    return delayBetween(cmds.collect { zwaveSecureEncap(it) }, delay)
}

Weird Behavior . . .

Brian, I have supervision code that is similar to yours. However, in my SupervisionReport handler code, I make use of the cmd.status value of the SupervisionReport to log whether the command was supported, succeeded, etc.

The issue - it seems I always get a cmd.status == 0 (that is a "No Support") even though the devices are seeming to respond.

I tried switching to your built-in "Plus" drivers and logging. Here is an example of the log message I get:

dev:452021-04-29 07:13:56.628 am debugsupervision report for session: 3
dev:452021-04-29 07:13:56.624 am debugparse:zw device: 22, command: 6C02, payload: 03 00 00 , isMulticast: false
dev:452021-04-29 07:13:56.536 am debugnew supervised packet for session: 3

Notice the second line -- the Supervision Report -- it shows 6C02 03 00 00

As the last two bytes are 00 00. According to the Z-wave standard, SDS13783, Section 3.7.4, this means "No Support" even though your command succeeded. I would have expected 6C02 03 FF 00 meaning "Success"

This is for a HomeSeer WD200. I get the same results on a WD100 (both devices are included as S2).

It occurs to me there may be a problem at the Hubitat side with how the message is received from the device. Or maybe the devices implement supervision incorrectly? In any case, are you seeing similar behavior, or am I not understanding the message?

Thanks,

1 Like

Checking

1 Like

Not sure if it matters, but there were some supervision errors and workarounds noted in the Zwave 700 series SDK release notes 7.14.3.0. Maybe nothing to do with this issue, but maybe it helps. https://www.silabs.com/documents/public/release-notes/SRN14667-4.0.0.0.pdf

I am not able to reproduce this on my devices:

SupervisionReport(moreStatusUpdates:false, sessionID:1, status:255, duration:0)

:point_up_2:

What command did you send to the device? And.. did the device execute the command properly even though it reported not supported?

Switch MultiLevel Set from my own driver.
Also tried BasicSet

Also whatever the built-in "Plus" dimmer driver would use for an On/Off and setLevel.

And, yes, my recollection is that the devices did respond correctly even though they reported the "No Support" status.

Do you have either of the HomeSeer devices I mentioned (WD200 or WD100)? Maybe give those a try if you can.

Ha.. that sounds like a firmware bug