Hey Folks,
I had an issue with the built in driver not having the attribute acceleration, and it was missing config button, and a few other things. The attribute shock was there but it is not recognized by some of the apps I used, they needed acceleration. Here is a driver I found on GitHub for Smarthings that I made an attempt to bring over to Hubitat. I went through it using some of the guides posted in the forums and kept at it until the errors went away. I never wrote this code and I am not a code writer by any stretch, but it did fix my problem. Hope I never buggered it up too much. So thanks to Mr. LaFramboise, not sure if he is here in these forums and I hope I didn't violate anything by doing this. If I did, someone please let me know, I am not up on the code thing and have read some post where people get pretty upset. I just want to help others like myself,
Edit, pulled the original and went with something different. Thanks @JasonJoel for the code to use to get this one going (again, lol). Lot of changes, but the layout I like. Again, I am just tinkering and trying to learn. I wonder if anyone has these to test it with me? Also, I added a battery install state, but not sure how that's going to work out, will the .state keep it in memory during shutdown's and software rev's? Please give me your thoughts on that as well @jtp10181.
/**
*
* Zooz ZSE43 Tilt Shock XS Sensor v0.1.0
*
* 0.1.0 (08/16/2021) - Initial Version - C. Andrews
*/
import groovy.transform.Field
@Field static Map commandClassVersions =
[
0x30: 2 //Sensor Binary
,0x55: 1 //Transport Service
,0x59: 3 //Association Group Info
,0x5A: 1 //Device Reset Locally
,0x5E: 2 //Z-Wave Plus Info
,0x6C: 1 //Supervision
,0x70: 2 //Configuration
,0x71: 3 //Notification
,0x72: 2 //Manufacturer Specific
,0x73: 1 //Powerlevel
,0x7A: 5 //Firmware Update MD
,0x80: 1 //Battery
,0x84: 2 //Wakeup
,0x85: 3 //Association
,0x86: 2 //Version
,0x87: 3 //Indicator
,0x8E: 2 //Multi Channel Association
,0x9F: 1 //Security
]
metadata {
definition (name: "Zooz ZSE43 Tilt Shock XS Sensor v0.1.0",
namespace: "C. Andrews",
author: "C. Andrews",
)
{
capability "AccelerationSensor"
capability "Battery"
capability "Sensor"
capability "ContactSensor"
command "DebugLogging", [[name:"Debug Logging",type:"ENUM", description:"Turn Debug Logging OFF/ON", constraints:["-", "OFF", "30m", "1h", "3h", "6h", "12h", "24h", "ON"]]]
command "BatteryInstallation", [[name:"Battery Install Date YYYY-MM-DD",type:"STRING"]]
// zw:Ss2a type:0701 mfr:027A prod:7000 model:E003 ver:1.10 zwv:7.13 lib:03 cc:5E,55,9F,6C sec:86,85,8E,59,72,5A,87,73,80,71,30,70,84,7A
fingerprint mfr:"027A", prod:"7000", model:"E003", deviceJoinName: "Zooz ZSE43 Tilt Shock XS Sensor"
}
preferences {
input name: "paramLEDIndicatorMode", type: "enum", title: "LED Indicator Mode", multiple: false, defaultValue: "3", options: ["0" : "No LED blink on status change", "1" : "LED blink on vibration only", "2" : "LED blink on open/close only", "3" : "LED blink for any change [DEFAULT]"], required: false, displayDuringSetup: true
input name: "paramBatteryReportTime", type: "number", title: "Battery Report Time (in %), Default 5", multiple: false, defaultValue: "5 [DEFAULT]", range: "1..50", required: false, displayDuringSetup: true
input name: "paramLowBatteryAlertThreshold", type: "number", title: "Low Battery Alert Threshold (in %), Default 20", multiple: false, defaultValue: "20", range: "10..50", required: false, displayDuringSetup: true
input name: "paramVibrationSensitivity", type: "enum", title: "Vibration Sensitivity", multiple: false, defaultValue: "0", options: ["0" : "High [DEFAULT]", "1" : "Medium", "2" : "Low"], required: false, displayDuringSetup: true
input name: "paramGroup2OnDelay", type: "number", title: "Delay before sending ON to Assoc Group2 Devices (in seconds)", multiple: false, defaultValue: "0", range: "0..3600", required: false, displayDuringSetup: true
input name: "paramGroup2OffDelay", type: "number", title: "Delay before sending OFF to Assoc Group2 Devices (in seconds)", multiple: false, defaultValue: "0", range: "0..3600", required: false, displayDuringSetup: true
input name: "paramSensorReports", type: "enum", title: "Sensor Reports", multiple: false, defaultValue: "2", options: ["0" : "Only tilt sensor enabled", "1" : "Only vibration sensor enabled", "2" : "Both tilt and vibration enabled [DEFAULT]"], required: false, displayDuringSetup: true
input name: "requestedGroup2", title: "Association Group 2 Members (Max of 5):", type: "text", required: false
input name: "requestedGroup3", title: "Association Group 3 Members (Max of 4):", type: "text", required: false
input name: "logEnable", type: "bool", title: "Enable debug logging", defaultValue: false
input name: "logDesc", type: "bool", title: "Enable descriptionText logging", defaultValue: true
}
}
// Parse //
void parse(String description){
if (logEnable) log.debug "parse description: ${description}"
hubitat.zwave.Command cmd = zwave.parse(description,commandClassVersions)
if (cmd) {
zwaveEvent(cmd)
}
}
// Z-Wave Messages //
String secure(String cmd){
return zwaveSecureEncap(cmd)
}
String secure(hubitat.zwave.Command cmd){
return zwaveSecureEncap(cmd)
}
void zwaveEvent(hubitat.zwave.commands.supervisionv1.SupervisionGet cmd){
hubitat.zwave.Command encapCmd = cmd.encapsulatedCommand(commandClassVersions)
if (encapCmd) {
zwaveEvent(encapCmd)
}
sendHubCommand(new hubitat.device.HubAction(secure(zwave.supervisionV1.supervisionReport(sessionID: cmd.sessionID, reserved: 0, moreStatusUpdates: false, status: 0xFF, duration: 0)), hubitat.device.Protocol.ZWAVE))
}
def zwaveEvent(hubitat.zwave.commands.associationv3.AssociationReport cmd) {
log.info "---ASSOCIATION REPORT V3--- ${device.displayName} sent groupingIdentifier: ${cmd.groupingIdentifier} maxNodesSupported: ${cmd.maxNodesSupported} nodeId: ${cmd.nodeId} reportsToFollow: ${cmd.reportsToFollow}"
}
def zwaveEvent(hubitat.zwave.commands.sensorbinaryv2.SensorBinaryReport cmd) {
if (logEnable) log.debug "---SensorBinaryReport--- ${device.displayName} sent ${cmd}"
}
def zwaveEvent(hubitat.zwave.commands.notificationv3.NotificationReport cmd)
{
if (logEnable) log.debug "---NOTIFICATION REPORT V3--- ${device.displayName} sent ${cmd}"
if (cmd.notificationType == 0x06) {
if ((cmd.event == 0x16)) {
if (logDesc) log.info "$device.displayName is open"
sendEvent(name: "contact", value: "open", descriptionText: "$device.displayName is open", type: "physical")
} else if (cmd.event == 0x17) {
if (logDesc) log.info "$device.displayName is closed"
sendEvent(name: "contact", value: "closed", descriptionText: "$device.displayName is closed", type: "physical")
}
}
if (cmd.notificationType == 0x07) {
if ((cmd.event == 0x03)) {
if (logDesc) log.info "$device.displayName is active"
sendEvent(name: "acceleration", value: "active", descriptionText: "$device.displayName is active", type: "physical")
} else if (cmd.event == 0x00) {
if (logDesc) log.info "$device.displayName is inactive"
sendEvent(name: "acceleration", value: "inactive", descriptionText: "$device.displayName is inactive", type: "physical")
} else {
log.debug "Unhandled notification: Type ${cmd.notificationType}, Event ${cmd.event}"
}
}
}
def zwaveEvent(hubitat.zwave.commands.indicatorv3.IndicatorReport cmd) {
if (logEnable) log.debug "---IndicatorReport REPORT V3--- ${device.displayName} sent ${cmd}"
}
def zwaveEvent(hubitat.zwave.commands.batteryv1.BatteryReport cmd) {
if (logEnable) log.debug "---BatteryReport REPORT V1--- ${device.displayName} sent ${cmd}"
def result = []
if (cmd.batteryLevel == 0xFF) {
if (logDesc) log.info "$device.displayName battery is low"
sendEvent(name: "battery", value: 1, descriptionText: "$device.displayName battery is low", type: "physical", isStateChange: true)
} else {
if (logDesc) log.info "$device.displayName battery is ${cmd.batteryLevel}%"
sendEvent(name: "battery", value: cmd.batteryLevel, descriptionText: "$device.displayName battery is ${cmd.batteryLevel}%",type: "physical", isStateChange: true)
}
}
def zwaveEvent(hubitat.zwave.commands.deviceresetlocallyv1.DeviceResetLocallyNotification cmd) {
if (logEnable) log.debug "---DeviceResetLocallyNotification--- ${device.displayName} sent ${cmd}"
log.info ("$device.displayName has reset.")
}
def zwaveEvent(hubitat.zwave.commands.configurationv2.ConfigurationReport cmd) {
if (logEnable) log.debug "---CONFIGURATION REPORT V2--- ${device.displayName} sent ${cmd}"
}
def zwaveEvent(hubitat.zwave.commands.manufacturerspecificv2.DeviceSpecificReport cmd) {
if (logEnable) log.debug "---Device Specific Report: ${cmd}---"
switch (cmd.deviceIdType) {
case 1:
// serial number
def serialNumber=""
if (cmd.deviceIdDataFormat==1) {
cmd.deviceIdData.each { serialNumber += hubitat.helper.HexUtils.integerToHexString(it & 0xff,1).padLeft(2, '0')}
} else {
cmd.deviceIdData.each { serialNumber += (char) it }
}
device.updateDataValue("serialNumber", serialNumber)
break
}
}
void zwaveEvent(hubitat.zwave.commands.wakeupv2.WakeUpIntervalReport cmd) {
if (logEnable) log.debug "---WakeUpIntervalReport: ${cmd}---"
}
void zwaveEvent(hubitat.zwave.commands.wakeupv2.WakeUpIntervalCapabilitiesReport cmd) {
if (logEnable) log.debug "---WakeUpIntervalCapabilitiesReport: ${cmd}---"
}
void zwaveEvent(hubitat.zwave.commands.wakeupv2.WakeUpNotification cmd) {
if (logEnable) log.debug "---WakeUpNotification: ${cmd}---"
if (state.queuedConfig) {
state.queuedConfig = false
updateConfig()
} else {
sendToDevice(zwave.batteryV1.batteryGet().format())
}
}
void zwaveEvent(hubitat.zwave.commands.versionv2.VersionReport cmd) {
if (logEnable) log.debug "---Version Report: ${cmd}"
device.updateDataValue("firmwareVersion", "${cmd.firmware0Version}.${cmd.firmware0SubVersion}")
device.updateDataValue("protocolVersion", "${cmd.zWaveProtocolVersion}.${cmd.zWaveProtocolSubVersion}")
device.updateDataValue("hardwareVersion", "${cmd.hardwareVersion}")
}
def zwaveEvent(hubitat.zwave.Command cmd) {
log.warn "${device.displayName} received unhandled command: ${cmd}"
}
// Driver Commands / Functions //
def BatteryInstallation (value) {
state.BatteryInstallationDate = (value)
log.info "$device.displayName Battery Installation Date is ${value}"
}
void sendToDevice(List<String> cmds, Long delay = 300) {
sendHubCommand(new hubitat.device.HubMultiAction(commands(cmds, delay), hubitat.device.Protocol.ZWAVE))
}
void sendToDevice(String cmd, Long delay = 300) {
sendHubCommand(new hubitat.device.HubAction(zwaveSecureEncap(cmd), hubitat.device.Protocol.ZWAVE))
}
List<String> commands(List<String> cmds, Long delay = 300) {
return delayBetween(cmds.collect { zwaveSecureEncap(it) }, delay)
}
def installed() {
state.queuedConfig = false
updated()
}
def updateConfig() {
log.info "Updating Configuration..."
List<String> cmds = []
// Associations
// Group1
cmds.add(zwave.associationV3.associationSet(groupingIdentifier:1, nodeId:zwaveHubNodeId).format())
// Group2
def nodes = []
if (settings.requestedGroup2 != state.currentGroup2) {
nodes = parseAssocGroupList(settings.requestedGroup2, 2)
cmds.add(zwave.associationV3.associationRemove(groupingIdentifier: 2, nodeId: []).format())
cmds.add(zwave.associationV3.associationSet(groupingIdentifier: 2, nodeId: nodes).format())
cmds.add(zwave.associationV3.associationGet(groupingIdentifier: 2).format())
state.currentGroup2 = settings.requestedGroup2
}
// Group3
if (settings.requestedGroup3 != state.currentGroup3) {
nodes = parseAssocGroupList(settings.requestedGroup3, 3)
cmds.add(zwave.associationV3.associationRemove(groupingIdentifier: 3, nodeId: []).format())
cmds.add(zwave.associationV3.associationSet(groupingIdentifier: 3, nodeId: nodes).format())
cmds.add(zwave.associationV3.associationGet(groupingIdentifier: 3).format())
state.currentGroup3 = settings.requestedGroup3
}
// Set LED Indicator param
if (paramLEDIndicatorMode==null) {
paramLEDIndicatorMode = 3
}
cmds.add(zwave.configurationV2.configurationSet(scaledConfigurationValue: paramLEDIndicatorMode.toInteger(), parameterNumber: 1, size: 1).format())
cmds.add(zwave.configurationV2.configurationGet(parameterNumber: 1).format())
// Set Battery Report Time param
if (paramBatteryReportTime==null) {
paramBatteryReportTime = 5
}
cmds.add(zwave.configurationV2.configurationSet(scaledConfigurationValue: paramBatteryReportTime.toInteger(), parameterNumber: 2, size: 1).format())
cmds.add(zwave.configurationV2.configurationGet(parameterNumber: 2).format())
// Set Low Battery Alert Threshold param
if (paramLowBatteryAlertThreshold==null) {
paramLowBatteryAlertThreshold = 20
}
cmds.add(zwave.configurationV2.configurationSet(scaledConfigurationValue: paramLowBatteryAlertThreshold.toInteger(), parameterNumber: 3, size: 1).format())
cmds.add(zwave.configurationV2.configurationGet(parameterNumber: 3).format())
// Set Vibration Sensitivity param
if (paramBatteryVibrationSensitivity==null) {
paramBatteryVibrationSensitivity = 0
}
cmds.add(zwave.configurationV2.configurationSet(scaledConfigurationValue: paramVibrationSensitivity.toInteger(), parameterNumber: 4, size: 1).format())
cmds.add(zwave.configurationV2.configurationGet(parameterNumber: 4).format())
// Set Group 2 ON Delay
if (paramGroup2OnDelay==null) {
paramGroup2OnDelay = 0
}
cmds.add(zwave.configurationV2.configurationSet(scaledConfigurationValue: paramGroup2OnDelay.toInteger(), parameterNumber: 5, size: 4).format())
cmds.add(zwave.configurationV2.configurationGet(parameterNumber: 5).format())
// Set Group 2 OFF Delay
if (paramGroup2OffDelay==null) {
paramGroup2OffDelay = 0
}
cmds.add(zwave.configurationV2.configurationSet(scaledConfigurationValue: paramGroup2OffDelay.toInteger(), parameterNumber: 6, size: 4).format())
cmds.add(zwave.configurationV2.configurationGet(parameterNumber: 6).format())
// Set Sensor Reports param
if (paramSensorReports==null) {
paramSensorReports = 2
}
cmds.add(zwave.configurationV2.configurationSet(scaledConfigurationValue: paramSensorReports.toInteger(), parameterNumber: 7, size: 1).format())
cmds.add(zwave.configurationV2.configurationGet(parameterNumber: 7).format())
// Get current sensor state
// Get a battery Update
cmds.add(zwave.batteryV1.batteryGet().format())
// Get version info
cmds.add(new hubitat.zwave.commands.versionv3.VersionGet().format())
// Wakeup Interval
cmds.add(zwave.wakeUpV2.wakeUpIntervalSet(seconds: 43200, nodeid:zwaveHubNodeId).format())
// Send No More Information
cmds.add(zwave.wakeUpV2.wakeUpNoMoreInformation().format())
// Send Commands
log.info "Sending configuration parameters to the device..."
sendToDevice(cmds,500)
}
def updated() {
log.info "updated..."
log.warn "debug logging is: ${logEnable == true}"
log.warn "description logging is: ${txtEnable == true}"
if (logEnable) runIn(1800,logsOff)
if (state.lastUpdated && now() <= state.lastUpdated + 3000) return
state.lastUpdated = now()
if (getDataValue("inClusters").contains("0x80") || getDataValue("secureInClusters").contains("0x80")) {
state.queuedConfig = true
} else {
state.queuedConfig = false
updateConfig()
}
}
private parseAssocGroupList(list, group) {
def nodes = group == 2 ? [] : [zwaveHubNodeId]
if (list) {
def nodeList = list.split(',')
def max = group == 2 ? 5 : 4
def count = 0
nodeList.each { node ->
node = node.trim()
if ( count >= max) {
log.warn "Association Group ${group}: Too many members. Greater than ${max}! This one was discarded: ${node}"
}
else if (node.matches("\\p{XDigit}+")) {
def nodeId = Integer.parseInt(node,16)
if (nodeId <= 5) {
log.warn "Association Group ${group}: Adding the hub id as an association is not allowed."
}
else if ( (nodeId > 5) & (nodeId < 256) ) {
nodes << nodeId
count++
}
else {
log.warn "Association Group ${group}: Invalid member: ${node}"
}
}
else {
log.warn "Association Group ${group}: Invalid member: ${node}"
}
}
}
return nodes
}
void DebugLogging(value) {
if (value=="OFF") {
unschedule(logsOff)
logsOff()
} else
if (value=="30m") {
unschedule(logsOff)
log.debug "debug logging is enabled."
device.updateSetting("logEnable",[value:"true",type:"bool"])
runIn(1800,logsOff)
} else
if (value=="1h") {
unschedule(logsOff)
log.debug "debug logging is enabled."
device.updateSetting("logEnable",[value:"true",type:"bool"])
runIn(3600,logsOff)
} else
if (value=="3h") {
unschedule(logsOff)
log.debug "debug logging is enabled."
device.updateSetting("logEnable",[value:"true",type:"bool"])
runIn(10800,logsOff)
} else
if (value=="6h") {
unschedule(logsOff)
log.debug "debug logging is enabled."
device.updateSetting("logEnable",[value:"true",type:"bool"])
runIn(21699,logsOff)
} else
if (value=="12h") {
unschedule(logsOff)
log.debug "debug logging is enabled."
device.updateSetting("logEnable",[value:"true",type:"bool"])
runIn(43200,logsOff)
} else
if (value=="24h") {
unschedule(logsOff)
log.debug "debug logging is enabled."
device.updateSetting("logEnable",[value:"true",type:"bool"])
runIn(86400,logsOff)
} else
if (value=="ON") {
unschedule(logsOff)
log.debug "debug logging is enabled."
device.updateSetting("logEnable",[value:"true",type:"bool"])
}
}
def logsOff(){
log.warn "debug logging disabled..."
device.updateSetting("logEnable",[value:"false",type:"bool"])
}