-
-
Save adamkempenich/1c102cc360c76fe783a88a899cdb54e6 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
metadata { | |
definition (name: "Binding Driver", namespace: "Inovelli", author: "AdamKempenich", importUrl: "") { | |
capability "Configuration" | |
command "bind", ["string"] | |
} | |
preferences { | |
section("Device Settings:") { | |
} | |
} | |
} | |
def configure(anything){ | |
} | |
void parse( data ){ | |
log.debug "Parse: ${data}" | |
} | |
def bind(cmds){ return cmds } |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
/** | |
* Zigbee Bindings | |
* | |
* Author: | |
* Adam Kempenich | |
* | |
* Add | |
* [X] Bind | |
* [X] Unbind | |
* [X] Allow multiple device selections | |
* [X] Make sure child device list doesn't include master device | |
* [X] Read device capabilities and only show possible outcomes | |
* [ ] Read binding Table | |
* [X] LogDebug | |
* | |
* Documentation: | |
* | |
* Changelog: | |
* 0.965 (Feb 23, 2022) | |
* - Requires the master device to use the binding driver | |
* - Doesn't validate master device capabilities | |
* - Works to bind/unbind | |
* 0.96 (Feb 2, 2022) | |
* - Initial build | |
ADD THE FOLLOWING LINE TO THE BOTTOM OF YOUR DRIVER (yes, it's so silly...) | |
def bind(cmds){ return cmds } | |
*/ | |
import hubitat.device.HubAction | |
import hubitat.device.HubMultiAction | |
definition( | |
name: "Zigbee Bindings", | |
namespace: "inovelli", | |
author: "Adam Kempenich", | |
importURL: "", | |
description: "", | |
category: "", | |
iconUrl: "", | |
iconX2Url: "" | |
) | |
preferences { | |
section("Options:") { | |
//Master | |
input "bindMaster", "capability.configuration", title: "Bind this device", multiple:false, required: false, submitOnChange: true | |
input "masterEndpoint", "string", title: "Use this endpoint from the master (0x__)", defaultValue: "0x01", required: true | |
// Get endpoint from master? | |
// Get outClusters and hide depending on what's available | |
if(bindMaster != null){ | |
// if(bindMaster.hasCapability("Switch")){ | |
input "bindPower", "bool", title: "Bind power", defaultValue: true | |
// } | |
// if(bindMaster.hasCapability("SwitchLevel")){ | |
input "bindLevel", "bool", title: "Bind level", defaultValue: true | |
// } | |
// if(bindMaster.hasCapability("ColorControl")){ | |
input "bindColor", "bool", title: "Bind color", defaultValue: true | |
//} | |
} | |
// Slave | |
input "bindSlave", "capability.configuration", title: "To these devieces...", multiple:true, required: false | |
input "slaveEndpoint", "string", title: "Use this endpoint for the slave (0x__)", defaultValue: "0x01", required: true | |
// Get endpoint from slaves, or multiple fields? | |
def unbindSelectedTrue = "<div class='ignoreRequired enclosure'><span class='left'>Bind</span><span class='right-selected'><b>Unbind</b></span></div>" | |
def unbindSelectedFalse = "<div class='ignoreRequired enclosure'><span class='left-selected'><b>Bind</b></span><span class='right'>Unbind</span></div>" | |
input "unbindSelected", "bool", title: "${unbindSelected && unbindSelected != null ? unbindSelectedTrue : unbindSelectedFalse}", submitOnChange: true, defaultValue: false | |
input(name:"logDebug", type:"bool", title: "Log debug information?", | |
description: "Logs data for debugging. (Default: On)", defaultValue: true, | |
required: true, displayDuringSetup: true) | |
label title: "<h2>Enter a name for this app (optional)</h2>", required: false | |
paragraph """<style> | |
#formApp > div > div:nth-child(9) > div.mdl-grid > div:nth-child(14) > label > div.mdl-switch__track, #formApp > div > div:nth-child(9) > div.mdl-grid > div:nth-child(14) > label > div.mdl-switch__thumb{ | |
display: none !important; | |
} | |
/**.mdl-switch__track, .mdl-switch__thumb, .mdl-switch__ripple-container{display:none;}**/ | |
.left-selected{ | |
background:#3498db; | |
border-top-left-radius:25px; | |
border-bottom-left-radius:25px; | |
padding: 1em; color:#ecf0f1 | |
} | |
.left{ | |
background:#ecf0f1; | |
border-top-left-radius:25px; | |
border-bottom-left-radius:25px; | |
padding: 1em; | |
color: #95a5a6; | |
} | |
.right-selected{ | |
background:#e74c3c; | |
border-top-right-radius:25px; | |
border-bottom-right-radius:25px; | |
padding: 1em; color:#ecf0f1; | |
} | |
.right{ | |
background:#ecf0f1; | |
border-top-right-radius:25px; | |
border-bottom-right-radius:25px; | |
padding: 1em; | |
color: #95a5a6; | |
} | |
.enclosure{ | |
margin: 1.5em -44px !important; | |
} | |
.ignoreRequired + span{ | |
display:none; | |
} | |
</style>""" | |
} | |
} | |
def installed() { | |
unsubscribe() | |
unschedule() | |
initialize() | |
} | |
def updated() { | |
unsubscribe() | |
unschedule() | |
initialize() | |
} | |
def initialize() { | |
unsubscribe() | |
unschedule() | |
List<String> cmds = [] | |
if(unbindSelected){ | |
bindText = 'unbind' | |
} else { | |
bindText = 'bind' | |
} | |
for(slaveDevice in bindSlave){ | |
// I definitely didn't cause an infinite loop by binding a device to itself... | |
if(bindMaster.zigbeeId != slaveDevice.zigbeeId){ | |
if(bindPower){ | |
cmds << "zdo ${bindText} 0x${bindMaster.deviceNetworkId} ${masterEndpoint} ${slaveEndpoint} 0x0006 {${bindMaster.zigbeeId}} {${slaveDevice.zigbeeId}}" | |
cmds << "delay 200" | |
} | |
if(bindLevel){ | |
cmds << "zdo ${bindText} 0x${bindMaster.deviceNetworkId} ${masterEndpoint} ${slaveEndpoint} 0x0008 {${bindMaster.zigbeeId}} {${slaveDevice.zigbeeId}}" | |
cmds << "delay 200" | |
} | |
if(bindColor){ | |
cmds << "zdo ${bindText} 0x${bindMaster.deviceNetworkId} ${masterEndpoint} ${slaveEndpoint} 0x0300 {${bindMaster.zigbeeId}} {${slaveDevice.zigbeeId}}" | |
cmds << "delay 200" | |
} | |
} else { | |
log.warn "BING BONG! You tried to bind a device to itself. Ignoring that device and moving along." | |
} | |
} | |
logDebug "Sending ${cmds}" | |
bindMaster.bind(cmds) // I hate having to rely on the device for now... | |
//def params = [request: "${cmds}", protocol: hubitat.device.Protocol.ZIGBEE ] | |
//sendHubCommand(new HubAction(params, "0x${bindMaster.deviceNetworkId}", [callback: parse])) | |
//sendHubCommand(new HubMultiAction(cmds, hubitat.device.Protocol.ZIGBEE, "0x${bindMaster.deviceNetworkId}")) | |
} | |
def parse(String description) { | |
log.debug "Parse description $description" | |
def descMap = zigbee.parseDescriptionAsMap(description) | |
log.info "map is ${descMap}" | |
} | |
def logDebug(text){ | |
if(settings.logDebug){ | |
log.debug(text) | |
} | |
} | |
///** | |
//* Zigbee Bindings | |
//* | |
//* Author: | |
//* Adam Kempenich | |
//* | |
//* Add | |
//* [X] Bind | |
//* [X] Unbind | |
//* [X] Allow multiple device selections | |
//* [X] Make sure child device list doesn't include master device | |
//* [X] Read device capabilities and only show possible outcomes | |
//* [ ] Read binding Table | |
//* [ ] LogDebug | |
//* [ ] LogDescriptionText | |
//* | |
//* Documentation: | |
//* | |
//* Changelog: | |
//* 0.96 (Feb 2, 2022) | |
//* - Initial build | |
//*/ | |
// | |
// | |
// | |
//import hubitat.device.HubAction | |
//import hubitat.device.HubMultiAction | |
//import hubitat.device.Protocol | |
// | |
// | |
//definition( | |
// name: "Zigbee Bindings", | |
// namespace: "inovelli", | |
// author: "Adam Kempenich", | |
// importURL: "", | |
// description: "", | |
// category: "", | |
// iconUrl: "", | |
// iconX2Url: "" | |
//) | |
// | |
//preferences { | |
// section("Options:") { | |
// | |
// //Master | |
// input "bindMaster", "capability.configuration", title: "Bind this device", multiple:false, required: false | |
// input "masterEndpoint", "string", title: "Use this endpoint from the master (0x__)", defaultValue: "0x01", required: true | |
// // Get endpoint from master? | |
// | |
// | |
// | |
// // Get outClusters and hide depending on what's available | |
// if(bindMaster != null){ | |
// | |
// if(bindMaster.hasCapability("Switch")){ | |
// input "bindPower", "bool", title: "Bind power", defaultValue: true | |
// } | |
// if(bindMaster.hasCapability("SwitchLevel")){ | |
// input "bindLevel", "bool", title: "Bind level", defaultValue: true | |
// } | |
// if(bindMaster.hasCapability("ColorControl")){ | |
// input "bindColor", "bool", title: "Bind color", defaultValue: true | |
// } | |
// } | |
// | |
// | |
// | |
// // Slave | |
// input "bindSlave", "capability.configuration", title: "To these devieces...", multiple:true, required: false | |
// input "slaveEndpoint", "string", title: "Use this endpoint for the slave (0x__)", defaultValue: "0x01", required: true | |
// // Get endpoint from slaves, or multiple fields? | |
// | |
// input "unbindSelected", "bool", title: "Enable this to <b>UNBIND</b> the above selected clusters/devices", defaultValue: false | |
// | |
// | |
// | |
// input(name:"logDebug", type:"bool", title: "Log debug information?", | |
// description: "Logs data for debugging. (Default: On)", defaultValue: true, | |
// required: true, displayDuringSetup: true) | |
// | |
// label title: "<h2>Enter a name for this app (optional)</h2>", required: false | |
// | |
// } | |
//} | |
// | |
//def installed() { | |
// unsubscribe() | |
// unschedule() | |
// initialize() | |
//} | |
// | |
//def updated() { | |
// unsubscribe() | |
// unschedule() | |
// initialize() | |
//} | |
// | |
//def initialize() { | |
// unsubscribe() | |
// unschedule() | |
// | |
// bind() | |
//} | |
// | |
// | |
//def bind(){ | |
// | |
// def cmds = [] | |
// | |
// if(unbindSelected){ | |
// bindText = 'unbind' | |
// } else { | |
// bindText = 'bind' | |
// } | |
// | |
// for(slaveDevice in bindSlave){ | |
// | |
// // I definitely didn't cause an infinite loop by binding a device to itself... | |
// if(bindMaster.zigbeeId != slaveDevice.zigbeeId){ | |
// if(bindPower){ | |
// cmds << "zdo ${bindText} 0x${bindMaster.deviceNetworkId} ${masterEndpoint} ${slaveEndpoint} 0x0006 {${bindMaster.zigbeeId}} {${slaveDevice.zigbeeId}}" | |
// cmds << "delay 200" | |
// } | |
// if(bindLevel){ | |
// cmds << "zdo ${bindText} 0x${bindMaster.deviceNetworkId} ${masterEndpoint} ${slaveEndpoint} 0x0008 {${bindMaster.zigbeeId}} {${slaveDevice.zigbeeId}}" | |
// cmds << "delay 200" | |
// } | |
// if(bindColor){ | |
// cmds << "zdo ${bindText} 0x${bindMaster.deviceNetworkId} ${masterEndpoint} ${slaveEndpoint} 0x0300 {${bindMaster.zigbeeId}} {${slaveDevice.zigbeeId}}" | |
// cmds << "delay 200" | |
// } | |
// } else { | |
// log.warn "BING BONG! You tried to bind a device to itself. Ignoring that device and moving along." | |
// } | |
// } | |
// | |
// logDebug "Sending ${cmds}" | |
// | |
// bindMaster.bind(cmds) | |
// //cmds << "he rattr 0x${bindMaster.deviceNetworkId} 0x${bindMaster.endpointId} 0x0006 0 {}" | |
// //"zdo bind 0x1D6E 0x02 0x01 0x0006 {000D6F000FC74D13} {000D6F00053AC67A}" | |
// //cmds << "zdo bind 0x${bindMaster.deviceNetworkId} 1 1 6 {${bindMaster.zigbeeId}} {}" | |
// // cmds << "zdo bind ${bindMaster.deviceNetworkId} 1 1 0x0006 {${bindMaster.zigbeeId}} {${bindSlave[0].zigbeeId}}" | |
// //bindMaster.refresh() | |
// //sendHubCommand(new HubMultiAction(cmds, hubitat.device.Protocol.ZIGBEE, "0x${bindMaster.deviceNetworkId}")) | |
// // def hubAction = new HubMultiAction(cmds, hubitat.device.Protocol.ZIGBEE, "0x${bindMaster.deviceNetworkId}") | |
// // log.warn "${bindMaster.hubAction}" | |
// //cmds << "he cmd 0x${bindMaster.deviceNetworkId} 1 0x0006 1 {}" | |
// //def hubAction = new hubitat.device.HubAction("zdo bind 0xCCD2 0x02 0x01 0x0006 {000D6F00053AC67A} {000D6F0003325A24}", hubitat.device.Protocol.ZIGBEE, bindMaster.deviceNetworkid) | |
// //log.trace "${hubAction}" | |
// //sendHubCommand(hubAction) | |
// //String cmd = "zdo bind 0x1D6E 0x01 0x01 0x0006 {000D6F000FC74D13} {000D6F00053AC67A}" | |
// //sendHubCommand(new HubAction(cmd, hubitat.device.Protocol.ZIGBEE, "0x${bindMaster.deviceNetworkId}")) | |
// | |
// //try{ | |
// // addChildDevice("Inovelli", "Zigbee Bindings", "ZigbeeBindingBuddy") | |
// // pauseExecution(1000) | |
// //} catch(gatewayCreationError){ | |
// // if($gatewayCreationError != "java.lang.IllegalArgumentException: A device with the same device network ID exists, Please use a different DNI"){ | |
// // logDebug "Something went wrong when creating a child gateway: ${gatewayCreationError}" | |
// // } | |
// //} | |
// //def childDevice = getChildDevice("ZigbeeBindingBuddy") | |
// //// | |
// //// | |
// //childDevice.bind(cmds) | |
// | |
// //log.trace "${unbindSelected ? 'Unbinding' : 'Binding'} with ${cmds} master DNI: 0x${bindMaster.deviceNetworkId}" | |
// | |
// | |
//} | |
// | |
// | |
//def parse(String description) { | |
// log.debug "Parse description $description" | |
// def descMap = zigbee.parseDescriptionAsMap(description) | |
// log.info "map is ${descMap}" | |
//} | |
// | |
//def logDebug(text){ | |
// if(settings.logDebug){ | |
// log.debug(text) | |
// } | |
//} | |
// | |
// | |
// | |
// |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment