Zigbee reporting on multi-endpoint devices

I have built the following driver that I am having some problems configuring reporting and refresh. Basically, the device is a multi-endpoint switch (a Mercator Ikuu Double GPO), basically a hardwired double power outlet. Everything works, with statuses updating as expected, except for updating the status of the secondary child switch when the physical button on the device is pressed. Button one reports using the standard power reporting on cluster 0x0006 with endpoint 0x01, but even hand-fabricating a command such as:

"zdo bind 0x${device.deviceNetworkId} 0x02 0x01 6 {${device.zigbeeId}} {}, delay 200, he cr 0x${device.deviceNetworkId} 0x02 6 0 16 0 900 {}, delay 200]"

which is identical to the reporting command created by

zigbee.onOffConfig(0, 900)

except for the endpoint being changed to 0x02 does not make the device report secondary switch state.

Does anyone have any ideas? Also, is there a better way to create these commands than hand-rolling them? The documentation is, of course, non-existent, and using a map to set the additional parameters does not seem to work, although this might be because I am using the wrong names since there is no documentation. Did I mention that there is no documentation yet?

I will also need to make similar changes to the refresh function, but once again, can't see how to create read attribute requests for secondary endpoints.

1 Like

What does the device respond with when you send that data?

It should respond with an 0x8021 ZDP bind response and then an 0x07 ZCL configure reporting response. Both should be "success" (0x00) if the device accepts both correctly, any other value should be matched against the respective lookup tables to see what the failure code means.

Not currently, most of the defined helper methods only target the first endpoint reported by the device. There's an "additionalParams" Map that can be passed to some of them, but the last time I checked it's not been implemented fully.

https://docs.hubitat.com/index.php?title=Zigbee_Object

As you mentioned, the documentation is lacking quite a lot and sometimes things get missed in the documention even though methods have been added. You can often poke around and discover as yet undocumented methods, e.g. by deliberately passing a bad argument type:

log.debug( zigbee.onOffConfig(10000) )

And then see what the logging says - obviously a method missing exception, but it will often suggest almost matching method signatures that you can then take a guess at.

So for that particular case try:

onOffConfig(String endpointId, Integer minRefreshInterval, Integer maxRefreshInterval)

But, as mentiond above, the response from the device still needs to indicate success for it to actually work .....

3 Likes

Interesting approach. I had noticed the tendency of the Groovy runtime to suggest stuff and had got some insights into how types were being handled for example.

I do note that Groovy does appear to support reflection through ".class" with things like methods available. I might take some time to reflect everything to start seeing what constants are available for example.

Back to the problem at hand. It seems that the instructions were all correct, it was the way that I was hand rolling the messages that was the problem. I though that the interpreter of these messages parsed the strings, but it actually only handles each message individually, so you can't return "zdo bind, delay 200", rather you have to return ["zdo bind", "delay 200"]. My confusion came from the way that lists are printed by the logging functions.

Anyway, I ended up with the following code snippet:

// On/Off reporting of 0 seconds, maximum of 15 minutes if the device does not report any on/off activity
for (endpoint = 1; endpoint <= 2; endpoint++)
{
    cmd += ["zdo bind ${device.deviceNetworkId} ${endpoint} 0x01 0x0006 {${device.zigbeeId}} {}", "delay 200", "he cr 0x${device.deviceNetworkId} ${endpoint} 6 0 16 0 900 {}", "delay 200"]
}

I decided that I would use the DIY code for both endpoints for consistency and then wrap it in a loop.

You might be interested in the delayBetween() method, which will take a list of strings (commands) and insert the delay between them for you, though what you're doing will certainly also work if you prefer: Driver Object - Hubitat Documentation (not much help since it isn't documented...but at least it's more self-explanatory than the rest, ha).

Sounds interesting.

On the topic of delays, the default is 2000ms, which is a long time. For mains powered devices, surely this can be a lot shorter? I have tried 200ms and things work perfectly still. I have been thinking about building a special device to do fast colour animations and this might be useful.

Interesting--I didn't know what the default value was, but 2000 ms does indeed seem a bit long! I normally see things like 200 ms or rarely something like 1000+ ms (if you're trying to read something after writing it, maybe) in drivers. I suppose this depends on the specific device (bulbs seem really sensitive to this for me...) and the general chattiness of your network. I don't do a lot with Zigbee driver development, but the Z-Wave side seems pretty similar to me.

In any case, I almost always specify a delay, a lot of times just a few hundred milliseconds, myself.

This topic was automatically closed 365 days after the last reply. New replies are no longer allowed.