ZigBee attribute reporting is a great feature. It basically allows for “push” messages from devices when their state has changed. This eliminates the need for polling, reduces traffic on the network, and keeps SmartThings instantly in sync.
I’ve been hitting various roadblocks in this endeavor and I thought I’d document them in this thread. Feel free to add your own observations.
First up are the SmartThings devices. In nearly all the device type templates I’ve looked at, there is a bug in the report configuration. For example here’s a snip of the Cree device type:
def configure() {
log.debug "Configuring Reporting and Bindings."
def configCmds = [
//Switch Reporting
"zcl global send-me-a-report 6 0 0x10 0 3600 {01}", "delay 500",
"send 0x${device.deviceNetworkId} ${endpointId} 1", "delay 1000",
//Level Control Reporting
"zcl global send-me-a-report 8 0 0x20 5 3600 {0010}", "delay 200",
"send 0x${device.deviceNetworkId} ${endpointId} 1", "delay 1500",
"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 6 {${device.zigbeeId}} {}", "delay 1000",
"zdo bind 0x${device.deviceNetworkId} ${endpointId} 1 8 {${device.zigbeeId}} {}", "delay 500",
]
return configCmds + refresh() // send refresh cmds as part of config
On the “send” command, the source and destination endpoints are backward. The on/off reporting should not have any payload. Also the level reporting has too many digits. The max interval is way too long. It should be like so:
//Switch Reporting
"zcl global send-me-a-report 6 0 0x10 0 120 {}", "delay 500",
"send 0x${device.deviceNetworkId} 1 ${endpointId}", "delay 1000",
//Level Control Reporting
"zcl global send-me-a-report 8 0 0x20 5 120 {10}", "delay 200",
"send 0x${device.deviceNetworkId} 1 ${endpointId}", "delay 1500",
On the Cree bulbs this is particularly a problem because it uses endpoint 10, and not 1 like a lot of devices. Not a big deal in this case, because the code can be easily fixed.
So once that’s solved, the bulb now reports periodically (in the case of the code above, every 120 seconds). However, the bulb should also be reporting on change; in the case above any change of on/off or a level change > 10 should cause a attribute report to be sent to the coordinator. This doesn’t work. I’ve logged the packets with the Ubiqua analyzer and they all check out okay, so I can assume this is a bug in the Cree firmware.
The second problem with the Cree bulb is that these report configurations are volatile; if the light is powered off it loses it’s memory. This should not be the case. And don’t even get me started about the Cree bulb using the device ID of 0x0100 (“On/Off Light”) instead of 0x0101 (“Dimmable Light”). Ugh.
Next up is my Kwikset 914 deadbolt. I’ve been working on a device type for this and it too has problems with attribute reporting. In this case, the attribute report does not reflect the true state of the lock. What happens is as follows: If I refresh the device, the attribute report is correct. If I turn the lock by hand, I do not get a change report. The next attribute report (on max interval) reports the old state! No wonder I didn’t get a change report. If I then refresh, now I get the correct state, and subsequent attribute reports also report the correct state. It’s as if only a refresh (read attribute) will update the internal variable containing the state.
I think attribute reporting is an important feature. For example it will update the status in SmartThings when a smart bulb is power cycled. If SmartThings doesn’t see a report in the allotted time it can assume the bulb has dropped off the network (manually turned off). The state of devices with manual input (door locks, etc) can stay in sync with the SmartThings state. The alternative to attribute reporting is polling, which creates a lot more network traffic and also creates a delay in the status updates; not to mention that polling devices seems broken in SmartThings at this time.