Multi-endpoint dimmer unsupported?

Hi,

I have a few issues connecting a multi-endpoint LED dimmer to HE.

Environment:
the device is an NXP5168-based device, hardware-wise it's basically not more than a bunch of wires now, but I can successfully pair it to ST, and the first endpoint works properly with it. This is the status I'm trying to reach right now. (as my 2 button Aqara switches cannot be used with ST, I gave up on ST here...)

Its firmware is an enhanced version of NXP's Application Note 1218, behaving as a router, I simply - okay, it wasn't THAT straightforward - added one more endpoint. Both endpoints are dimmable lights right now, and the firmware is based on NXP's own Zigbee 3.0 SDK, so AFAIK it is fully compliant to the standard.
I use the latest publicly available firmware in HE.

Network layer stuff (I can provide you with Wireshark capture files to help investigation in case it's not the way it should work):

  • The device successfully joins the PAN
  • HE discovers both endpoints, my device receives Simple Descriptor Requests for both of them, but the attributes (model ID, manufacturer, etc.) are requested only for EP #1. I'm fine with it, but strange, indicates some kind of anomaly that may or may not cause issues at upper sw layers.

Fun layer stuff:

  • With Generic Zigbee Dimmer driver attached, and a few clicks in Simple Lighting app, I can control the light attached to endpoint #1 with my Aqara switch. Yay, /me happy...
  • ...but not EP #2. It's as if it wasn't even there, I cannot even select the "dimmer" in Simple Lighting the same way I can select the "button".

Sad stuff:
As I have no access to the sources of neither the driver nor the app, I don't know where to start debugging. I BELEIVE my little thingy works properly, but right now I'm lost.

So my questions:

  • Will we ever have access to
    • built-in drivers?
    • built-in apps?
  • Do the built-in drivers/apps support multi-endpoint devices?
  • Is there something that might help me and I'm not aware of? I have to admit, I unboxed my HE 4 hours ago...

Thanks,
guyee

In both SmartThings and Hubitat, multi-endpoint devices that implement the same Capability (e.g. Switch) multiple times are best handled with a Composite Device Driver. This model has a Parent Driver that is actually paired with the physical device. The Parent Driver creates a Child Device for each endpoint (e.g. 2 switch devices.)

The Parent Device is responsible for all communications with the actual physical device.

The Child Devices get status updates from the Parent whenever new data comes in from the device. They also can send data to the physical device via the Parent Device.

The Child Devices are what other Apps use to interact with. The Parent Device usually is in the background handling network traffic duties.

Hope this helps!

1 Like

couple of things, the stock driver is only going to bind clusters 6 and 8 to the primary endpoint (1), leaving 2 in the weeds, and as Dan mentioned below you'll either need custom commands implemented in the driver for ep2 and or spin up a child device for ep 2.
We publish a few drivers, but not all of them, there's an example of a zigbee bulb driver that might get you started.

1 Like

Ah, okay, so the driver doesn't support multiple endpoints!

I thought it does (as multi-endpoint devices are part of the standard), and the odd behavior of pairing process caused the issue, but okay, I'm fine with it.

Btw do you plan to implement it in the built-in driver? Just for the sake of standard compliance, of course... :smile: And, well, yeah, because I'm lazy. :wink:
I will hack together a driver for my device using the parent-child logic, but as a noob in this scene I'm pretty sure it won't be as bulletproof as it should be...

And thanks for the quick responses!

Not following, what was odd about it?

Not at this time, this is the only device I'm aware of that contains two separate load controls in a single zigbee device.

1 Like

IMHO endpoints should be treated the same way, but there are some attributes that were not read on EP #2. I know, manufacturer and model are quite useless info (for an nth endpoint), but it made me suspicious... :slight_smile:

well, that's why I decided to build one for myself. :blush:

Okay, thanks for all the help, hopefully I'll be able to carry on by myself...

Here are some tips to help you get started

and you can refer to the ST Composite Device Handler docs for an overview...but be aware, the API is not exactly the same on Hubitat so refer to the above information from @chuck.schwer on how to use the Composite Driver API calls.

https://docs.smartthings.com/en/latest/composite-devices/

Good luck and let us know if you have any questions. Lots of helpful folks here in the community!

Dual zigbee relays are quite popular. It's just that smartthings doesn't handle them well.

https://www.zigbee.org/zigbee-products-2/#zigbeecertifiedproducts/productdetails3/5964caaf7f8dd44ecc879a36/

https://www.zigbee.org/zigbee-products-2/#zigbeecertifiedproducts/productdetails3/5553fef8f7f0b6063927b3ce/

https://www.zigbee.org/zigbee-products-2/#zigbeecertifiedproducts/productdetails3/5553fefaf7f0b6063927b3d7/

1 Like

Gentlemen,

with your help I managed to create a driver using the parent-child method, works pretty well given it's my first driver and first Groovy code... and I bashed a few bugs in my firware along the way as well :slight_smile:

My observation:

  • It was a one-time phenomenon, but maybe worth mentioning: Once during the discovery/join process, the hub somehow got stuck in a loop, and started flooding the network with... ehh, Active Endpoint or Simple Descriptor Requests, I don't remember, and of course I deleted the capture file. Stopping the discovery process stopped the flood. I couldn't reproduce it, however...

And 2 questions:

  • I see that in most drivers, binding and attribute reporting is configured in configure(). Okay, it's exactly what I planned to do. But then, when a (e.g. on/off, setlevel etc) command is sent to the device endpoint it is usually followed by a read attribute command sent to the corresponding attributes, even though there's attribute reporting configured for them. It's totally redundant, against the logic behind Zigbee, and eats resources/wastes time, mostly on larger networks. I removed all these rattrs, and obviously everything works properly. Is there a specific reason for this behavior?
  • How can I enumerate the endpoints discovered during the join process (in configure(), and without sending Active Endpoint Request, preferably)? I try to avoid hardcoding anything...

Thanks!

Yes, specifically in the case of cluster 0008 state reporting was disabled to prevent all the intermediate level reports that get generated during setlevel requests from generating useless HE system events, also frequently the last level attribute sent by the device won't match the requested level, sure this could be "fixed" by dinking with reportable change, however that would produce even more system events.

So which is worse, extra zigbee commands or the possibility of firing an app 10 times (unnecessarily) during a level transition when it's subscribed to setLevel...

For cluster 0006 I will at some point in the future flip that one around.

Oh, I see what you're saying, my awesome device does the same, I just thought it's my bug... :slight_smile:

Luckily in my case the last attribute sent matches the requested level (even in case of a switch off cmd), so it's not that annyoing, but you're right that it might waste resources elsewhere...

I think it's a great time to convince NXP to address this issue in their SDK, my IKEA and Xiaomi devices all use NXP SOCs... I'll try :wink:

Speaking of updates... do you plan to offer OTA updates for third-party devices? I know, it's not that straightforward, but maybe... later... it'd be a great feature even as a paid service, I'd rather pay than play the remove-pair-update-remove-pair-reconfigure game with every single device I have (after buying one more hub per manufacturer just because of OTA updates, of course)... :slight_smile:

at some point we'd like to have this, it's a ways out obviously.

Just a sidenote: I just found an "old" wall switch (3-gang relay, ZHA, KUDLED brand) on the shelf next to my ST hub... I bought it about a year ago, but couldn't use it with ST, so I forgot it.
Needless to say, it joined to HE successfully on the first try, and it's working flawlessly... I mean the first endpoint is working...

It's quite annoying to write a new device driver for all my devices, so I think I'll create two generic drivers for these multi-endpoint dimmers and switches, but due to the lack of (or availability of) documentation it's not that easy... could you please help me in:

  • How can I enumerate the endpoints of a device (for the creation of child devices)?
  • I'm quite confused by the large number of similar capabilities. "Actuator"/"Switch"? "Switch Level"/"Change Level"? Is there a documentation that describes the differences between them?
  • What (generic) commands must/should/can be supported by drivers with specific capabilities? I'd like to make the drivers compatible with every possible app you throw at it, but all I can use for help is the DTH code for other devices provided by fellow hobbyists, and the code quality... well, it varies. They can be very misleading and contradictory.

Thanks!

P.S: Sorry for the fuss, but I'm a software developer IRL, and while collecting the missing pieces of this puzzle can be fun, this way I'll never be confident enough in my code to release it...

I don't know, I imagine there's a zigbee command that could be run from the driver to fetch this, I don't know what it is.
Whatever that command was in ST, it should work here, how were you figuring this out before?

From a compatibility standpoint, we pretty much started off by mirroring the capabilities as documented in the smartthings developer documentation.
For simple things like dimmers switches and sensors, its a one to one match.

We know we're lacking on documentation overall, and we are working on this.

Of course I can issue an Active Endpoint Request to the device, process the response in parse(), and make the whole installation process asynchronous... Probably I will, I just though it's stored somewhere in the device object, as these steps were already performed during the join process... whatever.
Btw the reason for me to leave ST was its virtually non-existing support for endpoints, so I can imagine that these attributes are not accessible.

That's great, I'm fine with it... only one question remained: which documentation? They have two, with slight differences:

Thanks!

Classic.

Thanks.

In the meantime I tried to issue a zdo active 0x${device.deviceNetworkId} command to discover the endpoints (they're not stored in device object, I checked), but no trace of response... haven't sniffed the traffic yet, but should I receive the response in parse() - or anywhere else -, or am I just wasting my time?

everything comes in via parse

Hmmm,,, I think I found a bug then... :slight_smile:

I put zdo active 0x${device.deviceNetworkId} to the end of rattrs in refresh(), sniffed the network and... no trace of Active Endpoint Request.

The return value of refresh() is
[he rattr 0xCC58 17 0x0006 0 {}, delay 200, he rattr 0xCC58 18 0x0006 0 {}, delay 200, zdo active 0xCC58]
but after refreshing, only the 2 rattrs are sent to the network, no trace of anything that looks like an active endpoint request. :frowning:

Bump... :slight_smile:

@mike.maxwell does it work for you? No matter how I try, I see no egress Active Endpoint Requests (except the ones sent automatically during discovery).

Or what do I do wrong?

TIA.