Manufacturer Proprietary Z-Wave command worked on C3, but is broken on C8-Pro with Z-Wave JS

Hi all,

I've been trying to troubleshoot a manufacturer-proprietary (and zealously undocumented) Leviton command string that used to work from a custom device driver on my C3, but doesn't work anymore on my new C8-Pro.

Initially, I couldn't operate any of Z-Wave devices at all after migrating to the C8-Pro, but @bcopeland had me switch over to Z-Wave JS, and then (after some remote log analysis) disable watchdog to overcome a known firmware bug:

http:///hub/zwave2/watchdog/disable

This indeed brought back all of my other Z-Wave devices, except for the fact that my Leviton VRCZ4-M04 Zone Controllers were still not getting their on-switch LEDs set properly. (This is something I'd noticed post-migration to the C8-Pro, but had initially attributed to the general Z-Wave failure.)

I then thought this might be due to the switch to Z-Wave JS -- especially after I saw @bertabcd1234's comment (here) that the erstwhile Advanced "Send Z-Wave Command" on the device page (which I'd just come across, and had hoped to experiment with) "wouldn't work on Z-Wave JS nowadays anyway."

I'm still curious why that is, in case it's still somehow related to my issue?

I reverted my C8-Pro to legacy Z-Wave, which did indeed re-break all of my other Z-Wave commands without restoring VRCZ4 LED control (of course, since it's now clear that nothing is receiving any Z-Wave commands from my C8-Pro under legacy Z-Wave). And switching back to Z-Wave JS again brought back all of the (other) Z-Wave functionality (without having to re-disable watchdog, which I'd also tried to do in legacy mode) except for the VRCZ4 LEDs.

So apparently something else in the C3-to-C8-Pro upgrade has broken (only?) my Manufacturer Proprietary Z-Wave command for controlling the VRCZ4s' on-switch LED indicators. (All my other outgoing Z-Wave commands are switch bindings for non-proprietary devices, and they're all fine under Z-Wave JS with watchdog disabled.)

Does this ring any bells or otherwise suggest any possible issues to anyone?

FWIW, this is concerning setLightStatus() in my Leviton VRCZ4-M04 Zone Controller driver at lines 391-414. Specifically, line 413:

sendHubCommand(new hubitat.device.HubAction("${start.join()}${String.format("%02X",light)}${end.join()}${String.format("%02X",checksum)}", hubitat.device.Protocol.ZWAVE))

sends (for example):

91001D0D01FFBB00000A28

to turn the button 2 and 4 LEDs to amber and the button 1 and 3 LEDs off for node id 05. All of these bytes are hard-wired (fixed) except for the last two bolded bytes (BB and 28). I inherited the command construction from a prior VRCS4 controller, but just now found confirmation of the first bolded bit here; the un-bolded (and hard-wired) bit in the middle remains unexplained. The BB is a hex encoding of the LED statuses and colors, while the 28 comprises a checksum that XORs all of the other bytes plus four more "hidden" bytes -- three of which are also hard-coded, and the last of which is the target node ID.

I'm wondering if it's possible that the sendHubCommand((new HubAction()) syntax above was somehow good enough for legacy Z-Wave on the C3, but not for Z-Wave JS on the C8-Pro?

Thanks,
Michael

That is because that option required the use of "raw" hex (command class ID, command ID, payload) in a format tightly coupled with the hub's underlying Z-Wave implementation, while Z-Wave JS works differently ("JS" is the "rawest" you can get at this level :slight_smile: ).

I can't speak to the rest, but ... a quick look shows you might be using raw hex somewhere there, too? If so, that won't work for the same reasons. If it's not a "standard" command class, that will pose challenges, but you might be able to manually construct a JSON string (instead of a raw hex string, both instead of using Hubitat's standard Z-Wave Groovy classes and format() to make a string from that). A quick web search shows this post on the Home Assistant forums that might help: Send Manufacturer Proprietary command - Z-Wave - Home Assistant Community (I haven't explored the format JS uses for "outbound" commands, so this might not actually be what you need...)

4 Likes

That's exactly what's happening here -- and I'm not sure how you managed to find that Home Assistant Community link (which is describing the exact command I'm trying to send) almost instantly, when I couldn't find it at all!

Will have a deeper look through, and let you know how it goes.

Thanks so much, Robert!!!

So...it looks like Z-Wave JS does support Manufacturer Proprietary commands (with raw-bitmap payloads), no?

And Robert's link above includes this Home Assistant yaml script snippet:

image

Is there no way I can get to the sendData() method on the Z-Wave JS Manufacturer Proprietary command class from my Driver code?

I think a regular sendHubCommand() would be what you need -- not needing to go that deep into ZWJS yourself -- if you can figure out the JSON the command needs. That I don't know. Something like:

sendHubCommand(new hubitat.device.HubAction("your JSON", hubitat.device.Protocol.ZWAVE))

If you ever see commands like these coming in (or inspect the "formatted" result of others you send going out), you may be able to figure it out. But I won't be much help beyond that. :smiley: The trick, of course, would be figuring out that string, like you (or someone you may have copied the code from) did with legacy and the raw hex string instead of ZWJS-style JSON. Logging from JS in HASS might even show you this if you can get it working there, though I don't know how their logging works.

Just curious, is it possible to hub mesh the C3 to the new c8 Pro? If yes, maybe a work-around for the moment.

I think a regular sendHubCommand() would be what you need -- not needing to go that deep into ZWJS yourself -- if you can figure out the JSON the command needs. That I don't know. Something like:

sendHubCommand(new hubitat.device.HubAction("your JSON", hubitat.device.Protocol.ZWAVE))

If you ever see commands like these coming in (or inspect the "formatted" result of others you send going out), you may be able to figure it out. But I won't be much help beyond that. :smiley: The trick, of course, would be figuring out that string, like you (or someone you may have copied the code from) did with legacy and the raw hex string instead of ZWJS-style JSON. Logging from JS in HASS might even show you this if you can get it working there, though I don't know how their logging works.

Well...a regular sendHubCommand() is what I'm already using:

sendHubCommand(new hubitat.device.HubAction("91001D0D01FFBB00000A28", hubitat.device.Protocol.ZWAVE))

but I've no idea what sort of JSON I'd need to replace that hex string representation with? (Maybe @Hubitat_Staff can help here?) And unfortunately, this is a command I need to send to the device, so there's nowhere else to see them coming in from (and I'm unable to send them out successfully, so there's nothing I can inspect there either).

Meanwhile, the underlying zwave-js sendData() command takes a number and a Uint8Array:

async sendData(
    manufacturerId: number,
    data?: Uint8Array,
): Promise<void>;

both of which I could readily supply, if I could get them to zwave-js. Does Hubitat not have some equivalent of the HA zwave_js.invoke_cc_api service?