ZigBee Temperature reporting question for Cluster 0x402

Yep your dead on my friend!! Kind of blows my mind why they would do something like this I have to be missing something?? Oh and that is the “raw” message!!

1 Like

So that does confirm my suspicision that ST is “preparsing” messages before reaching the parse function.

Only raw or catchall or un “preparsed” messages make it completely through.

Grrrr… Hopefully there is someone at ST that might be able to shed some light on the preparsing of messages of zigbee devices.

Running into something similar with a Card Access device that has multiple temp endpoints. On poll I can get the messages for both, but on subscribe to the report, I don’t get anything usable.

3 Likes

If they did it hear for the temperature device I wonder what other device reports are going to be intercepted and changed. Also makes me wonder if they are going to add more down the road breaking what people have working today. Or maybe the rule is if the cluster is tied to one of their official device types it will always be intercepted. But I don’t think that is the case??

I don’t want to go all negative on this I know I have to be missing something!!. I went back to double check I’m dumping the raw input. Here is my parse method:

def parse(String description) {
log.debug “description: $description”

Map map = [:]
if (description?.startsWith(‘catchall:’)) {
map = parseCatchAllMessage(description)
}
else if (description?.startsWith(‘read attr -’)) {
map = parseReportAttributeMessage(description)
}
else if (description?.startsWith('temperature: ') || description?.startsWith('humidity: ')) {
map = parseCustomMessage(description)
}

log.debug "Parse returned $map"
return map ? createEvent(map) : null
}

It sure looks like the parse method just gets passed a string not an object. So if I log.debug the string that should be all the data I have to work with right?

1 Like

I wonder if the parent object of the description is accessible?

I’m mobile right now and can’t remember the groovy to access it but also try removing the string from the message in the function parse and see if a map is returned. Maybe forcing it to string removes the map in parse?

Gave it a try and get the exact same text when I dump the description with debug log.

Heading down to the boat to get her cleaned up for the weekend. Have a good weekend up there!!

Hi @JohnR, Do you mind sharing your code? How does your configuration looks like? Are you binding before asking for send-me-a-report?

"zdo bind 0x${device.deviceNetworkId} **1 ${endpointId}** 0x20 {${device.zigbeeId}} {}", "delay 400",
"zcl global send-me-a-report 1 0x20 0x20 600 3600 {01}", "delay 200",
"send 0x${device.deviceNetworkId} **1 ${endpointId}** ", "delay 1500",

private getEndpointId() 
{
	new BigInteger(device.endpointId, 16).toString()
}

Are you hardcoding the device endpointId in the configure() method?

1 Like

I’m using the default report configuration of the device which sends a new temperature report any time the temperature value changes. As I said above I’m getting the reports from the device its just they are being intercepted and the source end point is getting stripped out before it is handed to my parse method.

Here is my configure method:

def configure() {
log.debug "Binding SEP 0x38 DEP 0x01 Cluster 0x0101 Lock cluster to hub"
log.debug "Binding SEP 0x39 DEP 0x01 Cluster 0x0402 Temperature cluster to hub"
log.debug “Binding SEP 0x40 DEP 0x01 Cluster 0x0402 Temperature cluster to hub”

def cmd = []
cmd << "zdo bind 0x${device.deviceNetworkId} 0x38 0x01 0x0101 {${device.zigbeeId}} {}"			// Bind to end point 0x38 and the lock cluster
cmd << "delay 150"
cmd << "zdo bind 0x${device.deviceNetworkId} 0x39 0x01 0x0402 {${device.zigbeeId}} {}"    		// Bind to end point 0x39 and the temperature cluster
cmd << "delay 150"
cmd << "zdo bind 0x${device.deviceNetworkId} 0x40 0x01 0x0402 {${device.zigbeeId}} {}"    		// Bind to end point 0x40 and the temperature cluster
cmd << "delay 1500"    

log.info "Sending ZigBee Configuration Commands to Coop Control"
return cmd + refresh()
}

As you can see I’m not sending any send-me-a-report commands because I’m using the device’s default configuration. I don’t think the problem is in the configure method as I’m getting the reports just fine so these bind commands are being received and understood.

Thanks

Hi @JohnR:
Can you please try this in your code?

def configure() {
    "zdo bind 0x${device.deviceNetworkId} ${sourceEndPoint} ${destinationEndpointId} cluster {${device.zigbeeId}} {}"
}

It seems you are binding only in cluster 1.

Thanks

Yaima, I’m not following your suggestion. I’m binding to three end points. The first endpoint is 0x38 for the door cluster 0x0101, the next two endpoints are 0x39 and 0x40 both with the same cluster number 0x0402 Temperature. Those endpoints are being bound to your hubs 0x01 endpoint. Do I need to send them to different end points on your hub?? I have always used 0x01 as my destination endpoint when talking to your hub.

Did you mean to say “It seems you are binding only to destination end point 1”??

Can you please try this:

def cmd = []
cmd << "zdo bind 0x${device.deviceNetworkId}  0x01 0x38 0x0101 {${device.zigbeeId}} {}"			// Bind to end point 0x38 and the lock cluster
cmd << "delay 150"
cmd << "zdo bind 0x${device.deviceNetworkId} 0x01 0x39 0x0402 {${device.zigbeeId}} {}"    		// Bind to end point 0x39 and the temperature cluster
cmd << "delay 150"
cmd << "zdo bind 0x${device.deviceNetworkId}  0x01 0x40 0x0402 {${device.zigbeeId}} {}"    		// Bind to end point 0x40 and the temperature cluster
cmd << "delay 1500"    

log.info "Sending ZigBee Configuration Commands to Coop Control"
return cmd + refresh()
}

Bind from the hub to the device endpoint and cluster.

@JohnR, is your device in this list: http://www.zigbee.org/zigbee-products-2/#zigbeecertifiedproducts/?view_30_filters=[{"field"%3A"field_41"%2C"operator"%3A"is"%2C"value"%3A"551c72aa37b6dfa00fb984a5"}]&view_30_page=1
so I can take a look at the specs?

So your saying I should set my Source Endpoint to 0x1 and my destination endpoint to 0x38, 0x39, or 0x40? I think one of us has got this backwards. I’m binding my device’s Source Endpoint to your hub’s Destination Endpoint right? If I do as you suggest wont that be backwards? At least according to your documentation http://docs.smartthings.com/en/latest/device-type-developers-guide/building-zigbee-device-handlers.html#zdo-bind

Again I think my binding commands are fine I’m getting the reports from my device. I see the temperature reports come in as the temperature changes. I wouldn’t get those reports if the bind command wasn’t being understood and processed by my device.

I don’t mean to be hardheaded its just if I screw up the device’s binding table I will have to reinstall it and I have it outside in a test jig right now.

It will be a couple of weeks before I can give your suggestion a try. Thanks for the help!

1 Like

This is a new device its not on the certification list. Thanks again for your help!

That’s exactly what I am saying and this knowledge comes from Silicon Labs.
We have sniffers available that could use to trace the activity coming from your device, but it seems you are not willing to provide any additional information. I am here to help if you need anything else, it is always my pleasure.

Well then I bet I have it backwards. What makes me scratch my head is why it works and other device types I have written with the same order of source and destination work just fine. But anyway I will give it a try and see what happens. Thanks!

Any update on this? Sure seemed to go in circles in the above conversation…

But did you conclude and confirm that Source Endpoint and Destination Endpoint(s) should be reversed in your example?

The “Docs” link you gave no longer has any references to “zdo-bind”. :confused:
http://docs.smartthings.com/en/latest/device-type-developers-guide/building-zigbee-device-handlers.html#zdo-bind

The problem wasn’t with my binding order. Her input pretty much hijacked my thread so I just dropped it. Since this post I have seen other cases where the binding order is backwards in some of the sample device types. Take a look at this post from @rpress where he points this out. So I think she was basing her argument on these incorrect examples.

The state of ZigBee with attribute reporting

@JohnR… I hate to dig this thread out of the grave … well… it’s only been 13 days, so body isn’t cold yet.

I’ve run into a fundamental question that is confusing me:

  • As per the thread, which end is “Source” and which is “Dest”…

  • Can “Source” and “Dest” be swapped per @yaimavaldivia’s examples?

  • If so, does that also affect the definition of “Input Cluster” vs “Output Cluster?


Here’s my example Desc (and I have the source code for this Firmware which is consistent … ):

SensorTag
        Endpoint HA   DevType ?? #InClusters cluster cluster cluster #OutClusters cluster cluster
- desc: 08       0104 0000    00 02          0000    0003            01           0006
- desc: 09       0104 0302    00 03          0000    0003    0402    01           0003

Firmware Source: (sw = Switch Endpoint, ts = Temperature Sensor Endpoint)

// Cluster lists for the simple descriptor
static uint_least16_t swInputClusters[SENSORTAGAPP_SW_MAX_INCLUSTERS] =
{
  ZCL_CLUSTER_ID_GEN_BASIC,
  ZCL_CLUSTER_ID_GEN_IDENTIFY
};
static uint_least16_t swOutputClusters[SENSORTAGAPP_SW_MAX_OUTCLUSTERS] =
{
  ZCL_CLUSTER_ID_GEN_ON_OFF
};

static uint16_t tsInputClusters[SENSORTAGAPP_TS_MAX_INCLUSTERS] =
{
  ZCL_CLUSTER_ID_GEN_BASIC,
  ZCL_CLUSTER_ID_GEN_IDENTIFY,
  ZCL_CLUSTER_ID_MS_TEMPERATURE_MEASUREMENT
};
static uint16_t tsOutputClusters[SENSORTAGAPP_TS_MAX_OUTCLUSTERS] =
{
  ZCL_CLUSTER_ID_GEN_IDENTIFY
};

So let’s consider Endpoint 09 for a moment…
What is Temperature (0x0402) an InputCluster instead of an OutputCluster???

(For reference sake, this Device EndPoint 08 is a momentary button (0x0006 = on/off/toggle), and the Device properly sends Toggle messages to SmartThings, but the Device only sends back a default response when I send it an on/off from SmartThings. So the “Desc” for EndPoint 08 seems logically correct … i.e., the Device Outputs on/off/toggles to SmartThings).

But for Temperature; that’s backwards. The Device has a thermo sensor and Sends (outputs?) this to SmartThings correctly. So again … what is it called an “InCluster”.

For reference; here are my bindings (the binding of 0x09 EP to 0x0006 cluster is not meaningful, I know, but it shouldn’t hurt).

    log.debug "Binding SEP 0x08 and 0x09; DEP 0x01; Cluster 0x0006 (On/Off cluster) to hub"     
    cmd << "zdo bind 0x${device.deviceNetworkId} 0x08 0x01 0x0006 {${device.zigbeeId}} {}"	// Bind on/off output to SmartThings hub for end point 1
    cmd << "delay 150"
    cmd << "zdo bind 0x${device.deviceNetworkId} 0x09 0x01 0x0006 {${device.zigbeeId}} {}" 	// Bind on/off output to SmartThings hub for end point 2
    cmd << "delay 150"
    cmd << "zdo bind 0x${device.deviceNetworkId} 0x09 0x01 0x0402 {${device.zigbeeId}} {}" 	// Bind on/off output to SmartThings hub for end point 2
    cmd

Refresh:

def refresh() {
	log.debug "sending refresh command; Read Attribute(s)."
    def cmd = []
    cmd << "st rattr 0x${device.deviceNetworkId} 0x08 0x0006 0x0000"	// Read on / off value at End point 0x01 
    cmd << "delay 150"
    cmd << "st rattr 0x${device.deviceNetworkId} 0x09 0x0006 0x0000"	// Read on / off value at End point 0x02 
    cmd
}

And Log Output (from newest to oldest) when I press the Device’s “Button”:

Description As Map: [raw:0104 0006 08 01 0100 00 8719 01 00 0000 02 00 , profileId:0104, clusterId:0006, clusterInt:6, sourceEndpoint:08, destinationEndpoint:01, options:0100, messageType:00, dni:8719, isClusterSpecific:true, isManufacturerSpecific:false, manufacturerId:0000, command:02, direction:00, data:[]]
getEvent: [:]
debug getKnownDescription: [:]
debug Parse(): Description is catchall: 0104 0006 08 01 0100 00 8719 01 00 0000 02 00 .

And, FYI, I do get the Temperature Reports, but that just shows that, well, In is Out and Out is In, or is it?

Parse(): Description is temperature: 30.06.

##Edit:
Tagging @workmonk, @tpmanley, and @Tyler due to their ZigBee related roles at SmartThings (and @jody.albritton, 'cuz I’m a confused Developer who keeps coming back to the same few posts on the correct format of the ZCL, ZDO, ST RATTR, etc. “raw” ZigBee stuff and have yet to find a Topic that resolves the confusion).

NB: I am currently not interested in the wonderful new ZigBee abstraction methods, because it is not sufficient (for my project) to only have support for a single Endpoint in a Device Type.

And… as discussed in related posts, the whole “pre-parsing” of Raw Temperature Description is very concerning and adds to the confusion. :cold_sweat:

Take a look at the ZCL client server model description on page 6 of the ZigBee Spec. The last sentence brings it all together and calls out several key items, it says: “In the simple descriptor, the application input cluster list shall contain the list of server clusters supported on the device and the application output cluster list shall contain the list of client clusters supported on the device .

Input cluster = list of server clusters supported by the device.
Output cluster = list of client clusters supported by the device.

It’s all from your device’s point of view. Your device’s temperature is an input cluster because it gets the temperature from a temperature probe directly connected to it (input). It is a server for that cluster since it holds all the attributes for that cluster (temperature value, Min, Max values etc…). As for the on/off cluster your device is a client, it sends commands to a server’s on/off cluster to control the remote light.

It helps me to keep in mind its all from the device’s point of a view. If I’m a device and I collect data directly from the environment then I’m a server (input) for that cluster, and respond to input cluster commands. If I happen to also control a remote device wirelessly than I’m a client (output), and send client cluster commands to control that device remotely.

Binding is a completely different beast form your in and out clusters, it happens down at the ZDO layer. However, a hub can use a device’s in and out clusters to determine who can be bound together. If your device’s binding is backwards the device will not properly send reports to the bound device. An improperly bound device will still communicate and respond to read attribute request. That is why (when you poll a device) the binding can be backwards and the device still appears to work okay. But if you stop polling the device you will stop receiving data as the reports that rely on binding won’t get through.

3 Likes

Great answer… Concept is still fuzzy, but you’ve given my brain the data it needs to grasp it while I take a nap… Thanks!

1 Like