[OBSOLETE] ZWN-SC7 Enerwave 7 Button Scene Controller

The various “state” variables aren’t updated in time — smart things is perhaps spawning multiple instances? threads? to deal with the function being called and they don’t all agree on what the state.repeatStart is.

I’m reworking this whole chunk of code and another chunk in the button controller app that tries to catch the multiple button presses getting thru due to the disagreement on state.repeatStart

1 Like

I don’t think that Device Handlers are multi-threaded… There is only one process running per Device Instance (i.e., per physical Button Controller thing…).

More investigation reveals that

def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) {

is always called twice — the devise always sends a button press twice. Sometimes, SmartThings starts processing each even within the same millisecond, sometime’s it’s off by 23 - 1500. When it starts at the exact same millisecond, the checking fails and the button press is called twice which causes two events that the button controller is subscribed to to be registered.

Then the code in the button controller smart app looks up the number of events in the last three seconds and if it’s been idling, finds that there have been a number of events and it should ignore the press.

There is a lot of code that is unneeded and redundant in both the device and the app which I’ve been stripping out. Stripping out this code has increased execution times which has progressively increased the likelihood that the two events are handled within the same millisecond.

This won’t be clear, but I’ve assigned ‘serial numbers’ to each time def zwaveEvent(physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet cmd) { is called, and when it starts, it increments it by one for each run. When they start at the same time, they each show the same serial number in the log.

4 Likes

@codytruscott & @tgauchat, thanks for your time, hopefully you’ll make this a healthy ST device…

2 Likes

Currently waiting for an answer from SmartThings about whether or not Device Handler Instances are reentrant or not.

I say they shouldn’t be, unlike (SmartApps).

SmartApps support atomicState variable, but, though documentation is not 100% clear, Device Type Handlers do not support it. My theory: because it should never be required.

But Cody is observing reentrant behavior, and I believe him, but don’t like it, and want to know the architecture or documentation answers from SmartThings; @slagle

Currently implementing a parse locking & message queue of sorts that’s gotten me to ~99% capture — which is about a 90% reduction. My poor index finger is sick of all this button pushing — I’m at at least two thousand. I need a solenoid set up.

Also interesting is that my idea for turning the bottom button into a ‘shift-key’ is totally easy and workable. Each zwn-sc7 can support upto 255 different button messages.

3 Likes

tongue in cheek: “Yes, dear, to turn on your closet it’s the bottom button and then the third on the right, and to turn them off again it’s… wait a minute, let me look that up…” :heart_eyes:

2 Likes

@tguachat: internal undocumented buggy voodoo from SmartThings — the Enerwave Device works just fine, but as soon as you start to involve the included assortment of zwave command and event parsing functions, the number of redundant hits started to escalate.

I had a massive post written up about my findings, and my solution that seemed to reliably work, but sometime late this afternoon, the results were no longer consistently reproducible. It seems that they might be changing the code on the backend to try to debounce before it reaches the device handler. However, this has lead to a massive increase in missed catches, yet without actually solving the problem.

If someone is working on this at SmartThings, your approach is wrong — the error is elsewhere, and your debounce code is making the problem worse for certain use cases. Get in touch.

2 Likes

Yup… This is very difficult impossible to do “blind” … i.e., without some substantially more detailed view into Device Handler (and Z-Wave methods) architecture and defined deterministic behaviors with release change notes.

Tagging @slagle, etc., hasn’t helped.

That or I previously didn’t notice how many presses were going handled, but I really think someone is in the machine tweaking a behind the scenes debounce because my perceived change in the way it was handled started shifting over the course of a few hours from ‘always the old way’ to ‘sometimes the old way and sometimes the new way’ to ‘nearly never the old way and almost always the new way’

This is the problem:

physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet

called

parse()

every Xms (I forget the exact/rough value) until it returns an event.

If you ran this

def parse(String description) {
log.debug description
return

and did not create an event, the system would log a description roughly 2/3rds of the time and not log the description at all 1/3 of the time, my assumption is that the function returned an ‘all done’ message before it had finished writing a ‘start work’ state somewhere which resulted in really erratic behavior.

Adding in a simple createEvent

def parse(String description) {
log.debug description
createEvent(name: "button", value: 1)
return}

results in 90% of the time the system calls parse() once, and 10% calls it twice. Using sendEvent() in my custom locking code seemed to get this down further. Basically, if I could get an event fired off ASAP, the chances that parse() would run again would drop significantly.

If we start calling all sorts of zwave event and parse functions, we start to increase the number of times parse() runs as it keeps firing them off until it reaches 6, or an event fires.

For instance, the normal barebones example containing several function calls resulted in a significant number of 2 parse() calls and occasional situations of a 3rd.

def parse(String description) {
log.debug description
def result = null
def cmd = zwave.parse(description)
if (cmd) {
    result = zwaveEvent(cmd)
} else {
    log.debug "Non-parsed event: ${description}"
}
return}

Then at around 3:30PST, some new debounce code prior to parse() being called started propagating and it now almost never fires off more than one parse(). Which, is nice and all, but it precludes using some really quick code I wrote that prevented multiple runs of parse() and thus enabled an app I’m writing that allowed the button to be pressed numerous times to dim lights or change hue colors. There now seems to be debounce code that makes me wait ~2 seconds between button presses containing the same sceneID.

@tgauchat I’m sure you can ask some questions to help me clarify — I’m not as single-mindedly engineering detail oriented.

1 Like

Here are my thoughts on a fix.
It seems that currently,

physicalgraph.zwave.commands.sceneactivationv1.SceneActivationSet

calls

parse(description)

upto six times every 25ms(? or was it 250ms? or? I lot my log) until it receives notice that it’s been handled.

Instead of trying to debounce based on the incoming zwave message, why not just increase the time before new attempts at parse() are sent?

That’s what I’m hoping @slagle can dig up for us.

I figured parse would be called solidly once per Device message and all messages would be queued up and there would be no duplication nor deduping (debouncing) done in lower levels of the Platform.

Of course, if there is filtering of any sort, then I hope it is documented and consistent… And hopefully easy to understand as to what method is doing it.

I believe this behavior is specific to ZWN-SC7 (a firmware bug maybe?). I have written device handler for a different remote that also uses SceneActivation command class and I don’t observe multiple invocations, i.e. parse() is called only once per button press.

1 Like

I do notice that the blue LED next to the pressed button flashes repeatedly very rapidly upon each press (ummm… Not 100% sure it does this every time?.. Or only when it’s having trouble reaching the hub?).

Now it seems each blink of the LED is a message!?

LED flashing pattern does not necessarily correlate with RF transmission. The only way to verify it is with Z-Wave sniffer. In theory, SCENE_ACTIVATION_SET command is sent in broadcast mode first, followed by the unicast to each node associated with the group. Assuming that the hub is the only member of the group, there should only be two messages sent - one broadcast and one unicast.

1 Like

Thank you. I wondered about that.

1 Like

And … back to the previous behavior. Maybe the reason we like developing for SmartThings is that it’s a bit of a mystery wrapped in an enigma hidden in a private class.

My current theory is that there wasn’t a backend change, but a response time change due to increased global load starting around 6 eastern time.

For me, Hub 2.0 is all about eliminating the weird behavior during peak times with local processing.

2 Likes

My thought on this LED was that it was the device indicating to the user that the action is in progress (flashing), then once it is confirmed, it stops flashing, indicating that it’s okay to press another button. Though no guess on what is the difference between the brief fast flashing and the slow flashing.

So, I know I’m really late to this party;

Got the ZWN-SC7 in the mail, got it connected to power and joined to the network, however

I cannot control the smart bulb in the socket controlled by the physical switch I’ve just replaced. Please direct me on how to power on the device physically connected to this switch circuit?

Also, I’ve been reading the comments as much as I can, does the custom device/smartapp only still control buttons 1-4?