import groovy.transform.Field /* * Inteset Door / Window Sensor * * Modified from Bryan Copeland's * Wink Door / Window Sensor * v1.0 */ metadata { definition (name: "Inteset Door/Window Sensor", namespace: "elgreen99", author: "Bryan Copeland, Eric Green", importUrl: "https://raw.githubusercontent.com/elgreen99/hubitat/master/Drivers/Inteset/door-window-sensor.groovy") { capability "Actuator" capability "Sensor" capability "Configuration" capability "Battery" capability "ContactSensor" capability "Configuration" fingerprint mfr:"039A", prod:"0003", deviceId:"0101", inClusters:"0x5E,0x86,0x72,0x5A,0x73,0x80,0x71,0x30,0x85,0x59,0x84,0x70", deviceJoinName: "Inteset Door/Window Sensor" } preferences { input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: true input name: "txtEnable", type: "bool", title: "Enable descriptionText logging", defaultValue: true } } @Field static Map CMD_CLASS_VERS=[0x86:2,0x70:1,0x20:1,0x71:4] @Field static Map ZWAVE_NOTIFICATION_TYPES=[0:"Reserverd", 1:"Smoke", 2:"CO", 3:"CO2", 4:"Heat", 5:"Water", 6:"Access Control", 7:"Home Security", 8:"Power Management", 9:"System", 10:"Emergency", 11:"Clock", 12:"First"] void logsOff(){ log.warn "debug logging disabled..." device.updateSetting("logEnable",[value:"false",type:"bool"]) } void updated() { log.info "updated..." log.warn "debug logging is: ${logEnable == true}" log.warn "description logging is: ${txtEnable == true}" unschedule() if (logEnable) runIn(1800,logsOff) } void installed() { initializeVars() } void uninstalled() { } void initializeVars() { // first run only sendEvent(name:"battery", value:100) state.initialized=true } void configure() { if (!state.initialized) initializeVars() runIn(5,pollDeviceData) } void refresh() { } void pollDeviceData() { List cmds = [] cmds.add(zwave.versionV2.versionGet()) cmds.add(zwave.batteryV1.batteryGet()) cmds.add(zwave.notificationV4.notificationGet(notificationType: 6, event: 0)) cmds.add(zwave.wakeUpV1.wakeUpIntervalSet(seconds: 43200, nodeid:getZwaveHubNodeId())) cmds.add(zwave.wakeUpV1.wakeUpIntervalGet()) state.gotPoll=true sendToDevice(cmds) } void zwaveEvent(hubitat.zwave.commands.wakeupv2.WakeUpIntervalReport cmd) { state.wakeInterval=cmd.seconds } void eventProcess(Map evt) { if (device.currentValue(evt.name).toString() != evt.value.toString() || !eventFilter) { if (txtEnable && evt.descriptionText) log.info evt.descriptionText evt.isStateChange=true sendEvent(evt) } } void zwaveEvent(hubitat.zwave.commands.wakeupv2.WakeUpNotification cmd) { log.info "${device.displayName} Device wakeup notification" if (!state.gotPoll) pollDeviceData() List cmds=[] cmds.add(zwave.batteryV1.batteryGet()) cmds.add(zwave.wakeUpV2.wakeUpNoMoreInformation()) sendToDevice(cmds) } void zwaveEvent(hubitat.zwave.commands.basicv1.BasicReport cmd) { if(logEnable) log.debug "Basic report: ${cmd.value}" // this is redundant/ambiguous and I don't care what happens here } void zwaveEvent(hubitat.zwave.commands.configurationv1.ConfigurationReport cmd) { if(configParams[cmd.parameterNumber.toInteger()]) { Map configParam=configParams[cmd.parameterNumber.toInteger()] int scaledValue cmd.configurationValue.reverse().eachWithIndex { v, index -> scaledValue=scaledValue | v << (8*index) } device.updateSetting(configParam.input.name, [value: "${scaledValue}", type: configParam.input.type]) } } void parse(String description) { if (logEnable) log.debug "parse:${description}" hubitat.zwave.Command cmd = zwave.parse(description, CMD_CLASS_VERS) if (cmd) { zwaveEvent(cmd) } } void zwaveEvent(hubitat.zwave.Command cmd) { if (logEnable) log.debug "skip:${cmd}" } void zwaveEvent(hubitat.zwave.commands.securityv1.SecurityMessageEncapsulation cmd) { hubitat.zwave.Command encapsulatedCommand = cmd.encapsulatedCommand(CMD_CLASS_VERS) if (encapsulatedCommand) { zwaveEvent(encapsulatedCommand) } } void zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd) { if (logEnable) log.debug "Supervision get: ${cmd}" if (cmd.commandClassIdentifier == 0x6F) { parseEntryControl(cmd.commandIdentifier, cmd.commandByte) } else { hubitat.zwave.Command encapsulatedCommand = cmd.encapsulatedCommand(CMD_CLASS_VERS) if (encapsulatedCommand) { zwaveEvent(encapsulatedCommand) } } sendToDevice(new hubitat.zwave.commands.supervisionv1.SupervisionReport(sessionID: cmd.sessionID, reserved: 0, moreStatusUpdates: false, status: 0xFF, duration: 0)) } void zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport cmd) { Map evt = [name: "battery", unit: "%"] if (cmd.batteryLevel == 0xFF) { evt.descriptionText = "${device.displayName} has a low battery" evt.value = "1" } else { evt.descriptionText = "${device.displayName} battery is ${cmd.batteryLevel}%" evt.value = "${cmd.batteryLevel}" } eventProcess(evt) } void zwaveEvent(hubitat.zwave.commands.versionv2.VersionReport cmd) { if (logEnable) log.debug "version3 report: ${cmd}" device.updateDataValue("firmwareVersion", "${cmd.firmware0Version}.${cmd.firmware0SubVersion}") device.updateDataValue("protocolVersion", "${cmd.zWaveProtocolVersion}.${cmd.zWaveProtocolSubVersion}") device.updateDataValue("hardwareVersion", "${cmd.hardwareVersion}") } void zwaveEvent(hubitat.zwave.commands.notificationv4.NotificationReport cmd) { Map evt = [:] log.info "Notification: " + ZWAVE_NOTIFICATION_TYPES[cmd.notificationType] if (cmd.notificationType==6) { // access control switch (cmd.event) { case 0: // state idle break case 22: // Window / door is open evt.name="contact" evt.value="open" evt.descriptionText="${device.displayName} is ${evt.value}" eventProcess(evt) break case 23: // Window / door is closed evt.name="contact" evt.value="closed" evt.descriptionText="${device.displayName} is ${evt.value}" eventProcess(evt) break } } } void sendToDevice(List cmds) { sendHubCommand(new hubitat.device.HubMultiAction(commands(cmds), hubitat.device.Protocol.ZWAVE)) } void sendToDevice(hubitat.zwave.Command cmd) { sendHubCommand(new hubitat.device.HubAction(secureCommand(cmd), hubitat.device.Protocol.ZWAVE)) } void sendToDevice(String cmd) { sendHubCommand(new hubitat.device.HubAction(secureCommand(cmd), hubitat.device.Protocol.ZWAVE)) } List commands(List cmds, Long delay=200) { return delayBetween(cmds.collect{ secureCommand(it) }, delay) } String secureCommand(hubitat.zwave.Command cmd) { secureCommand(cmd.format()) } String secureCommand(String cmd) { String encap="" if (getDataValue("zwaveSecurePairingComplete") != "true") { return cmd } else { encap = "988100" } return "${encap}${cmd}" }