Help a newbie write a Device Handler for a Zigbee Multi-Button Scene Controller


(Bradlee S.) #1

I have a few Orvibo 7 button Zigbee controllers that I’m trying to get working from scratch. I can’t find any multi-button Zigbee DH examples to start from.

I’m able to log some catchall commands that recognize the 7 buttons being pressed, held, released.

  • 1 pressed ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 010000’
  • 2 pressed ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 020000’
  • 3 pressed ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 030000’
  • 4 pressed ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 040000’
  • 5 pressed ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 050000’
  • 6 pressed ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 060000’
  • 7 pressed ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 070000’
  • 7 held ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 070002’
  • 7 released ‘catchall: 0104 0017 01 0A 0100 00 4348 01 00 0000 08 01 070003’

I’d like to have 7 tiles that toggle ON/OFF when each of the buttons are pressed, and have each of the 7 buttons recognized as individual buttons through other smart apps.

This device also has an indicator light for each of the 7 buttons the momentarily lights up when pressed. I’m at a total loss as to how I might figure out how to set status of these programmatically. There must be some attribute for each? Anyway to discover these?


(Tony Fleisher) #2

You can Look at the hue dimmer switch (zha), or one of the lightify dimmer dth (both found searching this community) for some examples of zigbee button controllers.


(Bradlee S.) #3

Happen to know any DH’s using Scene cluster 0x0005?


(Bradlee S.) #4

Still in search of some cluster 0005 examples…


(Bradlee S.) #5

Here is my device:

	fingerprint profileId: "0104",
		deviceId: "000C",
		inClusters: "0000, 0005",
		outClusters: "0000, 0005, 0017",
		manufacturer: "欧瑞博",
		model: "75d430d66c164c26ac8601c05932dc94",
		deviceJoinName: "7 Button Scene Controller"

I started with a very basic handler having only a configure and refresh sections (with buttons to invoke each) that I add/remove pieces of code from/to to piecemeal test.

Here’s my config:

def configure() {
log.debug "Setting numberOfButtons to 7"
sendEvent(name: "numberOfButtons", value: 7, displayed: false)

log.debug "Configuring Reporting and Bindings."
def configCmds = [
	"zcl global send-me-a-report 0 0 0x00 0 3600 {01}", "delay 500",
    "send 0x${device.deviceNetworkId} ${endpointId} 1", "delay 1000",
    "zcl global send-me-a-report 5 0 0x00 0 3600 {01}", "delay 500",
    "send 0x${device.deviceNetworkId} ${endpointId} 1", "delay 1000",
    
    "zdo bind 0x${device.deviceNetworkId} 1 1 0 {${device.zigbeeId}} {}", "delay 2000",
    "zdo bind 0x${device.deviceNetworkId} 1 1 5 {${devicezigbeeId}} {}", "delay 2000"
]
return configCmds + refresh()
}

And my refresh:

def refresh() {

log.debug "Starting Refresh"

log.debug "Get Clusters Called"
["zdo active 0x${device.deviceNetworkId}", "delay 2000"]
}

My parse:

def parse(String description) {
log.debug "Parsing '${description}'"  
def event = zigbee.parse(description)    
log.debug "$event"
log.debug "EventData: '${event.data}'"

if (event) {
	sendEvent(event)
}
else {
	log.warn "DID NOT PARSE MESSAGE for description : $description"
	log.debug zigbee.parseDescriptionAsMap(description)
}
}

This is what that returns:

	Parsing 'catchall: 0000 8021 00 00 0100 00 4AB3 00 00 0000 00 00 6700'
	SmartShield(
		clusterId: 0x8021, command: 0x00,
        data: [0x67, 0x00], //increments - see below
        destinationEndpoint: 0x00, direction: 0x00,
        isClusterSpecific: false, isManufacturerSpecific: false,
        manufacturerId: 0x0000,
        messageType: 0x00,
        number: null, options: 0x0100, profileId: 0x0000,
        senderShortId: 0x4ab3, sourceEndpoint: 0x00,
        text: null
	)
    EventData: '[103, 0]'  //increments by some amount each run. resets at about 126

When I try to read attributes from cluster 5:

[
"st rattr 0x${device.deviceNetworkId} 1 5 0", "delay 200",
"st rattr 0x${device.deviceNetworkId} 1 5 1", "delay 200",
"st rattr 0x${device.deviceNetworkId} 1 5 2", "delay 200",
"st rattr 0x${device.deviceNetworkId} 1 5 3", "delay 200",
"st rattr 0x${device.deviceNetworkId} 1 5 4", "delay 200",
"st rattr 0x${device.deviceNetworkId} 1 5 5", "delay 200"
]

For each attribute, I get back:

Parsing 'read attr - raw: 4AB301000506000086, dni: 4AB3, endpoint: 01, cluster: 0005, size: 06, attrId: 0000, result: unsupported attr'

I am able to read a few results back from cluster 0

I then try adding a few scenes, and reading back scene count and current scene attributes:

log.debug "Attemping to Add some Scenes"    
delayBetween([
	zigbee.command(0x0005, 0x00, "0000", "01", "1111", "Test1"),
	zigbee.command(0x0005, 0x00, "0000", "02", "2112", "Test2"),
	zigbee.command(0x0005, 0x00, "0000", "03", "3113", "Test3"),
	zigbee.command(0x0005, 0x00, "0001", "04", "4114", "Test4"),
	zigbee.command(0x0005, 0x00, "0001", "05", "5115", "Test5"),
	zigbee.command(0x0005, 0x00, "0001", "06", "6116", "Test6")
], 1000)
 
log.debug "Attempting to Read Attributes"
[
"st rattr 0x${device.deviceNetworkId} 1 5 0", "delay 200", //scene count
"st rattr 0x${device.deviceNetworkId} 1 5 1", "delay 200"  //current scene
]

I get no response from the add scene commands, and the same unsupported attr results as above. I can similarly send view/remove scene commands with equal success. Not sure what to try next.

If configured for buttons, I am able to log pressed/held/released events from the device. So I could use this as a plain vanilla button controller. But I want to be able to utilize the LED’s to display the active scenes. And I can only assume that is controlled solely by the device in this case.


Zigbee.[something] Commands Reference?
#6

You may have run into an issue where the SmartThings platform (not zigbee itself) doesn’t pass along the endpoints for multi endpoint devices. This is just the way the platform was designed, but it can make working with multi endpoint devices quite challenging.

Because I rely on text to speech software, I can’t read your code, but hopefully someone else will be able to help.

@veeceeoh has done a lot of investigation of this type of zigbee device and might be able to say more.


(Tom Manley) #7

We recommend using zigbee.configureReporting to configure reporting of attributes. It requires less code and sets up the binding before the report configuration which is often important. Also the data types in the report configuration need to be correct for the specified attributes. In the case of attribute 0x0000 on cluster 0x0000 and 0x0005 they are unsigned 8-bit integers which has a data type value of 0x20. This comes from section 2.6.2 of the ZCL spec.

def configCmds = zigbee.configureReporting(0x0000, 0x0000, 0x20, 0, 3600, 0x01) +
    zigbee.configureReporting(0x0005, 0x0000, 0x20, 0, 3600, 0x01)

^ This should configure reporting of those two attributes every hour.

Since we use the Active Endpoint Request/Response for device discovery the response to this message will be consumed by the platform and doesn’t make it back to the DTH. I assume this was just for testing because typically refresh would be used to read some attributes which is what I’d recommend doing here.

This code should work but we recommend using zigbee.readAttribute. For example the above code can be replaced with:

zigbee.readAttribute(0x0005, 0x0000) +
zigbee.readAttribute(0x0005, 0x0001) +
zigbee.readAttribute(0x0005, 0x0002) +
zigbee.readAttribute(0x0005, 0x0003) +
zigbee.readAttribute(0x0005, 0x0004) +
zigbee.readAttribute(0x0005, 0x0005)

The ZCL spec I’m looking at says that attributes 0x0000-0x0004 are required so it is odd that the device is responding to those reads with an unsupported attribute status. I wonder if this device is actually not fully Zigbee compliant because the ZCL spec says that any device that implements the Scenes server cluster like this device does shall also implement the Groups server cluster which this device does not do.

The delayBetween shouldn’t be necessary because zigbee.command calls automatically add a delay after each one. The commands themselves look OK but I suggest making the 5th parameter (transition time) smaller. For example if you want it to be 5 seconds use a value of “0500”. Also it wasn’t clear from the code snippet but make sure this value is being returned from the function. Otherwise it won’t be sent to the hub.

This ended up being a long post but I hope this helps you get at least a little farther. If you’re still having trouble it will probably be helpful to see the entire DTH.


(Bradlee S.) #8

Thanks for the tips! As I’m sure you can tell, I’m completely new to this and diving headfirst! I’ll make your changes and report back.

I’ve also had some (albeit minimal) contact with the manufacturer. I purchased the items directly from them to test. I’ll see if I can get them to share more info. They’ve been quite hesitant to this point.


(Keith G) #9

Not surprising at all. They are in the business of selling their own hub solution, after all.

It’s a shame that only button #7 supports sending “held” & “released” reports.

Despite what @JDRoberts said, I only have done a bunch of reading on the limitations of ST in receiving messages from multiple endpoints on the same cluster/attribute.

In case you do find you need to access endpoints other than 01, the workaround is to add it as an additional parameter to your zigbee.readAttribute and zigbee.command commands, like this:

zigbee.readAttribute(0x0005, 0x0000, [destEndpoint: 0x02])

I found that information posted in a thread starting with this post by the ever helpful @tpmanley.

I have zero experience with the scenes cluster, but if for some reason non-default endpoints are used, then it seems you could experiment with readAttribute commands at different endpoints to see what happens.

I’m very interested to see what you find, because this looks like a nicely priced product for what it does.