Zcl global send-me-a-report and zdo bind


(Serge Sozonoff) #1

Hi All,

Could someone briefly explain the function of each of these calls ?

zcl global send-me-a-report …
zdo bind …

I understand that its for getting notifications on attribute changes but I dont know why both are required and what their respective role is ?

I read this
http://docs.smartthings.com/en/latest/device-type-developers-guide/building-zigbee-device-types/building-zigbee-device-types.html

And it seems to say that all I need is “zdo bind” …

Thanks,
Serge


(Scott G) #2

This may not help at all, but here’s a link to the Ember implementation of Zigbee. The ST Zigbee chip is Ember-based. Page 556 has the zcl global send-me-a-report and 594 has the zdo bind.

There’s not a whole lot of additional info and what is there is jibberish to me, but good luck!


(Serge Sozonoff) #3

Thanks, I have yet to find what these actually so …


(John Rucker) #4

There are two ways you can read the value of a cluster’s attribute one is to query it (Send it a ZigBee Read Attribute command 0x00) and the other is to have it report it’s attribute (command 0x0A). To get a device to report its attribute it has to be told who to send the report to. That is what the bind is for. If the receiving device’s address is in the reporting devices bind table it will get reports.

So when you write a device type for SmartThings it is a common practice to put the hub’s address in the binding table of the device. That is one of the things the zdo bind is used for.

In addition to receiving attribute reports from a device you can configure how often the attributes are reported things like only send an update if there is a change or every hour or both. I’m guessing report configuring is what the zcl global sen-me-a-report is for. I haven’t used that command in my device types yet.


(John Rucker) #5

One last thing. Not all devices report on their attributes. The Hue bulbs are one example that is why it is difficult to know when a device has changed the bulb’s color or turned it off. If the bulb supported attribute reporting it would let devices in its bind table know that its color has been changed. It would allow us to make a much better device type for the bulb.


(Serge Sozonoff) #6

Hello John,

Great stuff and thanks for taking the time to answer. I now understand things a lot better!!

With regards to “zdo bind”. Two endpoint are required, src and dst. In the case of the hub, how to know what endpoint to use for the binding ?

Also how are these reports reported in the parse() method of a Device Type ? Will it be a catchall ?

Thanks,
Serge


(John Rucker) #7

Great question on the end point, I use 0xFF on the hub and it works fine. I don’t think it matters what endpoint you use for the SmartThings hub (it should matter but I think they just pass on everything back to the cloud). 0xFF is like a broadcast for endpoints if you use 0xFF all endpoints get it.

Here is some code I used to read attributes from our backyard ZigBee Anemometer.

    // Parse incoming device messages to generate events
def parse(String description) {
    log.debug "Parse description $description"
    def name = null
    def value = null
    if (description?.startsWith("read attr -")) {
        def descMap = parseDescriptionAsMap(description)
        log.debug "Read attr: $description"
        if (descMap.cluster == "000C" && descMap.attrId == "0055") {
            name = "windSpeed"
            value = getFPoint(descMap.value)
        } else if (descMap.cluster == "000C" && descMap.attrId == "0045") { 
            name = "minWind"
            value = getFPoint(descMap.value)
        } else if (descMap.cluster == "000C" && descMap.attrId == "0041") { 
            name = "maxWind"
            value = getFPoint(descMap.value)
        } else if (descMap.cluster == "000C" && descMap.attrId == "0401") { 
            name = "offWindSpeed"
            value = getFPoint(descMap.value)
        } else if (descMap.cluster == "000C" && descMap.attrId == "0402") { 
            name = "onWindSpeed"
            value = getFPoint(descMap.value)
        } else if (descMap.cluster == "000C" && descMap.attrId == "0403") { 
            name = "minOnDelay"
            value = Integer.parseInt(descMap.value, 16)
        } else if (descMap.cluster == "000C" && descMap.attrId == "0404") { 
            name = "minOffDelay"
            value = Integer.parseInt(descMap.value, 16)    
        }
                   
    } else if (description?.startsWith("catchall: 0104 0006 38")) {
        log.debug "On/Off command received"
        name = "contact"
        value = description?.endsWith(" 01 00 0000") ? "open" : "closed"
    }
    
    def result = createEvent(name: name, value: value)
    log.debug "Parse returned ${result?.descriptionText}"
    return result
}


def parseDescriptionAsMap(description) {
    (description - "read attr - ").split(",").inject([:]) { map, param ->
        def nameAndValue = param.split(":")
        map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
    }
}