Need help converting ST Zigbee DTH to HE

I'm attempting to port the ST Mitch Pond Keypad DTH to HE. I use my keypads for things other than arming, and AFAIK that is not supported on HE. I want to finish converting from ST, and keypads are my last devices to cut over. I plan using the keypads with a remnant of my ST SHM Delay smartapp.

My ZigBee hardware message understanding is about 0. I found HE examples on Github and followed them, but nada. The commands look the same but the device does not respond.

Perhaps someone who understands this more than me can give me a clue about what I'm doing wrong. Tagging: @mike.maxwell

Aside from the getting rid of tiles, I changed the message sending as follows:

def results = cmds?.collect{ new physicalgraph.device.HubAction(it)};


def results = cmds?.collect{ new hubitat.device.HubAction(it,hubitat.device.Protocol.ZIGBEE) };

He Code

private sendRawStatus(status, secs = 00) {
def seconds=secs as Integer
logdebug "sendRawStatus info ${zigbee.convertToHexString(status,2)}${zigbee.convertToHexString(seconds,2)} to device..."

// Seems to require frame control 9, which indicates a "Server to client" cluster specific command (which seems backward? I thought the keypad was the server)
List cmds = ["raw 0x501 {09 01 04 ${zigbee.convertToHexString(status,2)}${zigbee.convertToHexString(seconds,2)}}",
			 "send 0x${device.deviceNetworkId} 1 1", 'delay 100']
def results = cmds?.collect{ new hubitat.device.HubAction(it,hubitat.device.Protocol.ZIGBEE) };
logdebug "sendRawStatus results"+results
return results


ST Code

private sendRawStatus(status, seconds = 00) {
log.debug "sendRawStatus info ${zigbee.convertToHexString(status)}${zigbee.convertToHexString(seconds)} to device..."

// Seems to require frame control 9, which indicates a "Server to client" cluster specific command (which seems backward? I thought the keypad was the server)
List cmds = ["raw 0x501 {09 01 04 ${zigbee.convertToHexString(status)}${zigbee.convertToHexString(seconds)}}",
			 "send 0x${device.deviceNetworkId} 1 1", 'delay 100']
def results = cmds?.collect { new physicalgraph.device.HubAction(it) };
log.debug "sendRawStatus results"+results

return results

HE trace
2019-04-10 07:49:45.189 debugParsing 'catchall: 0104 0501 01 01 0040 00 0B85 01 00 0000 07 00 '
2019-04-10 07:49:30.508 debugsendRawStatus results[raw 0x501 {09 01 04 0000}, send 0x0B85 1 1, delay 100]
2019-04-10 07:49:30.501 debugsendRawStatus info 0000 to device...

ST trace of similar device
8:01:18 AM: debug Parsing 'catchall: 0104 0501 01 01 0000 00 7397 01 00 0000 07 00'
8:01:14 AM: debug sendRawStatus results[raw 0x501 {09 01 04 0000}, send 0x7397 1 1, delay 100]
8:01:14 AM: debug sendRawStatus info 0000 to device...

you'll want to replace the ST raw and send cmds with the HE consolidated version of the same:

ST raw zigbee frame	
List cmds = ["raw 0x501 {09 01 00 04}","send 0x${device.deviceNetworkId} 1 1"]

HE raw zigbee frame (for the same command)
List cmds = ["he raw 0x${device.deviceNetworkId} 1 1 0x0501 {09 01 00 04}"]
he raw 
0x${device.deviceNetworkId} 16 bit hex address 
1							source endpoint, always one				 
1 							destination endpoint, device dependent
0x0501 						zigbee cluster id
{09 						frame control
	01 						sequence, always 01
		00 					command
			04}				command parameter(s)

I'm going to be honest, writing a driver using raw commands (and in this case you have no other options), is extremely difficult, even if you know what you're doing and have a sniffer online.

I should note, I have no idea if that will allow that driver to port correctly or not, there may be other issues. I built our drivers from scratch for these devices.


I'm surprised I managed to get as far as I did with that DTH without a sniffer, just poring over ZB docs...

@arnb apologies for the poorly documented code. I wish refactoring my code on no one :grimacing:

1 Like

This is totally crazy but I just got most of the DTH working without using the HE Raw.

Just before receiving your response I was testing the various commands on the Devices page, I almost jumped out of my chair when the Beep command worked. I reviewed your code, but decided to find out why beep worked and nothing else did. Simple: it used a cmds statement vs the
cmds?.collect{ new hubitat.device.HubAction(it,hubitat.device.Protocol.ZIGBEE) };

So I changed the rest of the code to cmds. I have not tested everything, but setArmedNight/Away/Stay, set Disarmed, set Exit/Entry Delay work! I don't understand why but it's working!:grin:


It's sometimes amazing what a bit of perseverance, determination, and ignorance can do! (I'm referring to me on the ignorance)

Thank you for that DTH I suggest it to folks on ST with the SHM Delay app and it's held quite nicely, with a couple of minor changes.

yeah, we support the legacy ST commands, but not forever...

How long is "not forever"

once you post complete success migrating this driver using the st commands, then we'll remove support for them...

LOL, there is no current time line, but it would be best to not use them, then you have nothing to worry about.


You folks must be learning something from ST!


Let's hope not!


@mike.maxwell Is there a variant or a different command to send the data to a group address instead of a device specific one?

currently group commands are implemented via our groups and scenes application.

Is there a way to do this outside of that application? I'm experimenting with zigbee commands with a low level driver, and want to send a message with a group delivery mode and group id:



"he grp cmd 0x${groupAddress} 0x01 0x${cluster} 0x${command} { ${hexData} }"

Download the Hubitat app