My CC2531 arrived today, and I flashed it and ran https://www.zigbee2mqtt.io/ - and while the ZBT-CCTSwitch-D0001 is unsupported out of the box, that looks to be merely a formality. The messages come across fine and zigbee2mqtt knows what they mean.
The top three buttons (power, brightness, color temp) all generate very usable messages and a single message per button press.
power button twice in a row:
zigbee2mqtt:debug 2019-12-17 00:46:37: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandOn', cluster 'genOnOff', data '{}' from endpoint 1 with groupID 16387
zigbee2mqtt:debug 2019-12-17 00:46:39: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandOff', cluster 'genOnOff', data '{}' from endpoint 1 with groupID 16387
brightness (one press):
zigbee-herdsman:controller:log Skipping command 'moveToLevel' because it is missing from the lookup +1ms
color temp (two presses):
zigbee2mqtt:debug 2019-12-17 00:51:16: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToColorTemp', cluster 'lightingColorCtrl', data '{"colortemp":181,"transtime":3}' from endpoint 1 with groupID 16387
zigbee2mqtt:debug 2019-12-17 00:51:36: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToColorTemp', cluster 'lightingColorCtrl', data '{"colortemp":222,"transtime":3}' from endpoint 1 with groupID 16387
The challenging one is the bottom button "revert to scene" - this one generates two messages per button press:
change scene press 1:
debug 2019-12-17 00:53:31: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToLevelWithOnOff', cluster 'genLevelCtrl', data '{"level":254,"transtime":0}' from endpoint 1 with groupID 16387
debug 2019-12-17 00:53:31: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToColorTemp', cluster 'lightingColorCtrl', data '{"colortemp":153,"transtime":3}' from endpoint 1 with groupID 16387
chang scene pres 2:
debug 2019-12-17 00:53:32: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToLevelWithOnOff', cluster 'genLevelCtrl', data '{"level":254,"transtime":0}' from endpoint 1 with groupID 16387
debug 2019-12-17 00:53:32: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToColorTemp', cluster 'lightingColorCtrl', data '{"colortemp":370,"transtime":3}' from endpoint 1 with groupID 16387
change scene press 3:
debug 2019-12-17 00:53:33: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToLevelWithOnOff', cluster 'genLevelCtrl', data '{"level":254,"transtime":0}' from endpoint 1 with groupID 16387
debug 2019-12-17 00:53:33: Received Zigbee message from '0xccccccfffea9cdd3', type 'commandMoveToColorTemp', cluster 'lightingColorCtrl', data '{"colortemp":222,"transtime":3}' from endpoint 1 with groupID 16387
So the change scene button just generates two commands - brightness and color.
For the top 3 buttons, we could just listen for the single button and rewrite it - either in zigbee2mqtt or elsewhere to do what we want. For the bottom button we'll have to recognize two successive commands and map them to a single command.
I'm sure that's doable, and it looks like we'll have to do it outside of Hubitat, so Zigbee2mqtt looks like a great choice if you're comfortable with the hardware aspect.
The responsiveness of zigbee2mqtt (at least the log messages) is immediate. This could be a really nice remote to scatter around the house (and I have plenty to scatter).