Zigbee Device Type question about "enrollResponse" and the function "configure"

First off, I’m not sure if this is the right category for this question, since Device Types are NOT SmartApps, but I didn’t see another better category, so I apologize ahead of time if that’s incorrect.

I have two questions about Zigbee device types at the moment.

My first question is about the SmartSense Motion/Temp Sensor Device type that’s published by SmartThings and is the default one used for the Smart Things starter kit motion sensor. Its a zigbee sensor, and in the device type, there is the following:

metadata {
	definition (name: "SmartSense Motion/Temp Sensor", namespace: "smartthings", author: "SmartThings") {
		capability "Motion Sensor"
		capability "Configuration"
		capability "Battery"
        capability "Temperature Measurement"
		capability "Refresh"
        command "enrollResponse"

		fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305-S"
        fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3305"
        fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05", outClusters: "0019", manufacturer: "CentraLite", model: "3325"


What is that enrollResponse command doing? I couldn’t find anything describing it in the documentation. The command is define later on as the following, but that’s not helping me much either.

def enrollResponse() {
	log.debug "Sending enroll response"
	"raw 0x500 {01 23 00 00 00}", "delay 200",
    "send 0x${device.deviceNetworkId} 1 1"

Is the 0x500 referring to the IAS Zone cluster I presume? Where is the best document to decode the other numbers? This is proprietary to ST or can I find that somehow in the ZCL documentation?

My second question is about the configure function. How often does this function run? What triggers it? I only saw one indirect mention of this function in the documentation under the ZDO bind section here:


The code is here:

def configure() {

	String zigbeeId = swapEndianHex(device.hub.zigbeeId)
	log.debug "Confuguring Reporting, IAS CIE, and Bindings."
	def configCmds = [
    	"zcl global write 0x500 0x10 0xf0 {${zigbeeId}}", "delay 200",
		"send 0x${device.deviceNetworkId} 1 1", "delay 1500",
        "zcl global send-me-a-report 1 0x20 0x20 300 3600 {01}", "delay 200",
        "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
        "zcl global send-me-a-report 0x402 0 0x29 300 3600 {6400}", "delay 200",
        "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
		"zdo bind 0x${device.deviceNetworkId} 1 1 0x402 {${device.zigbeeId}} {}", "delay 200",
		"zdo bind 0x${device.deviceNetworkId} 1 1 0x001 {${device.zigbeeId}} {}", "delay 1500",
        "raw 0x500 {01 23 00 00 00}", "delay 200",
        "send 0x${device.deviceNetworkId} 1 1", "delay 1500",
    return configCmds + refresh() // send refresh cmds as part of config

enrollResponse() is indeed referring to the IAS Zone. When IAS Security devices join they request to be enrolled into the IAS Server. So you’ll notice in parse() there is a listener for that request, which follows up with this response. The message exist in the configure() block as sort of a “spray and pray” where during pairing that enroll message usually gets the device in, but sometimes it doesn’t. Which is why it also will be called anytime the device requests it.

configure() gets called once when the device pairs. It can also sometimes be called when the device rejoins.

The best documentation is the ZCL doc provided by ZigBee. The chip is also Ember based, so there is some more info that can be found in the Ember Application Framework.


Thanks Andrew, this is some great info. You might consider having the documentation owner add something on configure in the “Building ZigBee Device-Type” documentation section. Thanks for pointing out the enroll is also in the parse() function. That makes a lot of sense now.

So I have tried adding binding in the configure() function, just for my Occupancy Sensor (0x406) cluster. But this gave me a few other questions:

  • If configure() is only called once at pairing then how will my zdo bind commands ever get called if the device doesn’t have a fingerprint that is found properly by ST? Can I force configure() to get called again somehow? Or should I add the zdo bind commands to something I can force call like refresh()?
  • I have a log message in my refresh() function, and I see the tile on the main UX and it allows me to press it like a button. All great. But I never see the log.debug message happen in “live logging”. I do see my device in the “my devices” area, and it even shows “ACTIVE” when I power up the zigbee NXP module. So I think that all means good things about ST communicating with my NXP module. And anyway even if the module isn’t configured totally right for binding etc, shouldn’t I see the log.debug fire in the refresh() function since that’s all just ST smart app and hub side of things?

Let me know if you want me to paste my device type code here.

Thanks in advance for any info/ideas you can share.

NOTE: I tried the refresh() command that’s part of the original SmartSense Motion/Temp Sensor I used as reference for a ZigBee device type, and it’s log.debug works great to live to “live logging” every time I press it.

NOTE2: Some of my reply here is specific to my other thread Trying to use NXP(Jennic) zigbee module (JN5168-001-M00) as a basic sensor:


Hopefully Andrew will chime back in because no one knows this better, but here’s some info from other threads and issues that relates to your questions.

  1. If you need configure to be called, you can add the configure tile to the device UI (just like refresh), then it can be triggered with a tap. I forget what device type has this as an example. Useful if configure is needed after a loss of power for instance.

  2. Is your log statement at the beginning of refresh()? Could the other code in refresh be getting stalled or erroring such that your log statement is never reached properly? I’ve seen instances where the code looks pretty straightforward, but doesn’t run as expecting.

1 Like

Thanks Scott, I’ve posted my device type here just for reference as I work out the issues. I don’t see any reason why the refresh logging wouldn’t work. I also tried adding a standard tile for configuration but that logging doesn’t come out either. The tile showed up fine though.

I just noticed it, a simple fix. Just adding the refresh and configure capability will get you to be able to execute those functions.

Great call Andrew, thanks! I finally got my first data from the NXP device!!!

10:29:32 PM: debug JDE: description: read attr - raw: 43440104060A0000001800, dni: 4344, endpoint: 01, cluster: 0406, size: 0A, attrId: 0000, result: success, encoding: 18, value: 00
10:29:31 PM: debug JDE: Refresh called

1 Like

looks like that means unoccupied !

:slight_smile: Yea, I know how to simulate “occupied” on this module. They actually wrote their demo code for a test device they make with a few buttons on the DIO’s. If you press the first button 5 times within 10 seconds, it goes to occupied. This refresh() command worked a few times to do a rattr command, but I it was very flaky. I believe that’s because the module usually is sleeping. Anyway, the answer is I’m thinking getting the “bind” to work. But I noticed that my configure() function was totally wrong. It wasn’t logging my message even though refresh() was.

So I’ve since fixed it based on “Aeon Home Energy Meter” as an example of doing a tile for “configuration”. Thanks Scott G for the tip on finding an example of this. See github above for the latest device type groovy code.

Andrew, I would recommend that the documentation could use a bit of an update on the fields in the standard tile declarations.


Is there somewhere else than the above link that explains in detail each element of the following:

	standardTile("configure", "device.power", inactiveLabel: false, decoration: "flat") {
		state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"

For example, I was using state of “default” rather than “configure”. And I had action:“configure.configure”. And at first I had “device.configure” as the second item trying to emulate what I saw in the refresh example.

Is there a manual that goes into a lot more detail on device type coding by any chance?

Thanks! I really appreciate all the help and I can’t test till I get home tonight, but I think now I should have a chance that my binding will work!


The documentation is in the process of being rewritten/improved. They just added a dedicated documentation leader. @Jim do you have a timeline for updating/expanding the device type documentation?

Thanks Scott for the update.

@urman, just FYI binding worked too now.

5:41:08 PM: debug JDE: description: read attr - raw: 74510104060800001801, dni: 7451, endpoint: 01, cluster: 0406, size: 08, attrId: 0000, encoding: 18, value: 01


There is only whats available on the docs site right now. @Jim is tearing through though! Getting better every day.

Were you ever able to decode the rest of the enroll response raw message? @urman do you know what the the 01 23 00 00 00 represent?

I’m trying to understand the format of raw messages because I think we will use them to send group commands. I found in the Ember framework a command “send_multicast [groupID] [source_endpoint]” that would be used to send a pre-buffered command like the enroll response out to a group.

I don’t know if ST supports that command, but I will need to figure out how to address the raw command in order to test it.

(sorry for hijacking your thread a bit)


I can’t say I have a specific timeline for an updated device-type documentation… obviously, it’s something that’s on my list, and I’m taking note of questions like these.

1 Like