Leaksmart Water Sensor

I have it working again, however you have to use the simulator to configure it. Still debugging.

1 Like

Here’s what I have updated for my device handler. I don’t have a new device to add to test with, but I’ve included the configure as part of the refresh, instead of the reverse as before.

/*

  • Copyright 2016 SmartThings
  • Licensed under the Apache License, Version 2.0 (the “License”); you may not
  • use this file except in compliance with the License. You may obtain a copy
  • of the License at:
  •  http://www.apache.org/licenses/LICENSE-2.0
    
  • Unless required by applicable law or agreed to in writing, software
  • distributed under the License is distributed on an “AS IS” BASIS, WITHOUT
  • WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  • License for the specific language governing permissions and limitations
  • under the License.
    */

metadata {
definition (name: “leakSmart Moisture Sensor”,namespace: “smartthings”, author: “SmartThings”, category: “C2”) {
capability "Configuration"
capability "Battery"
capability "Refresh"
capability "Temperature Measurement"
capability “Water Sensor”

    fingerprint profileId: "0104", inClusters: "0000,0001,0003,0020,0402,0B02,FC02", outClusters: "0003,0019", manufacturer: "WAXMAN", model: "leakSMART Water Sensor V2", deviceJoinName: "leakSmart Water Sensor"
}

simulator {

}

preferences {
    section {
        image(name: 'educationalcontent', multiple: true, images: [
			"http://cdn.device-gse.smartthings.com/Moisture/Moisture1.png",
			"http://cdn.device-gse.smartthings.com/Moisture/Moisture2.png",
			"http://cdn.device-gse.smartthings.com/Moisture/Moisture3.png"
        ])
    }
    section {
        input title: "Temperature Offset", description: "This feature allows you to correct any temperature variations by selecting an offset. Ex: If your sensor consistently reports a temp that's 5 degrees too warm, you'd enter '-5'. If 3 degrees too cold, enter '+3'.", displayDuringSetup: false, type: "paragraph", element: "paragraph"
        input "tempOffset", "number", title: "Degrees", description: "Adjust temperature by this many degrees", range: "*..*", displayDuringSetup: false
    }
}

tiles(scale: 2) {
    multiAttributeTile(name:"water", type: "generic", width: 6, height: 4){
        tileAttribute ("device.water", key: "PRIMARY_CONTROL") {
            attributeState "dry", label: "Dry", icon:"st.alarm.water.dry", backgroundColor:"#ffffff"
            attributeState "wet", label: "Wet", icon:"st.alarm.water.wet", backgroundColor:"#53a7c0"
        }
    }
    valueTile("temperature", "device.temperature", inactiveLabel: false, width: 2, height: 2) {
        state "temperature", label:'${currentValue}°',
        backgroundColors:[
            [value: 31, color: "#153591"],
        [value: 44, color: "#1e9cbb"],
        [value: 59, color: "#90d2a7"],
        [value: 74, color: "#44b621"],
        [value: 84, color: "#f1d801"],
        [value: 95, color: "#d04e00"],
        [value: 96, color: "#bc2323"]
    ]
    }
    valueTile("battery", "device.battery", decoration: "flat", inactiveLabel: false, width: 2, height: 2) {
        state "battery", label:'${currentValue}% battery', unit:""
    }
    standardTile("refresh", "device.refresh", inactiveLabel: false, decoration: "flat", width: 2, height: 2) {
        state "default", action:"refresh.refresh", icon:"st.secondary.refresh"
    }

    main (["water", "temperature"])
    details(["water", "temperature", "battery", "refresh"])
}

}

def parse(String description) {
log.debug “description: $description”

Map map = [:]

if (description?.startsWith(‘catchall:’)) {
map = parseCatchAllMessage(description)
}
else if (description?.startsWith(‘read attr -’)) {
map = parseReportAttributeMessage(description)
}
else if (description?.startsWith('temperature: ')) {
map = parseCustomMessage(description)
}

    log.debug "Parse returned $map"

def result = map ? createEvent(map) : null

if (description?.startsWith(‘enroll request’)) {
List cmds = enrollResponse()
log.debug "enroll response: ${cmds}"
result = cmds?.collect { new physicalgraph.device.HubAction(it) }
}
return result
}

private Map parseCatchAllMessage(String description) {
Map resultMap = [:]
def cluster = zigbee.parse(description)
if (shouldProcessMessage(cluster)) {
switch(cluster.clusterId) {
case 0x0001:
log.debug "001 Cluster Data: ${cluster.data}"
resultMap = getBatteryResult(cluster.data.last())
break

    case 0x0402:
       // temp is last 2 data values. reverse to swap endian
    	log.debug "402 Cluster Data: ${cluster.data}"
        String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join()
       def value = getTemperature(temp)
        resultMap = getTemperatureResult(value)
        break
    case 0x0B02:
    	log.debug "B02 Cluster Data: ${cluster.data}"
        String temp = cluster.data[2];
        log.debug "B02 temp data ${temp}"
        return parseAlarmCode(temp)
		break
   }
}

else {
log.debug “Did not process message ${cluster}”
}
return resultMap
}

private boolean shouldProcessMessage(cluster) {
// 0x0B is default response indicating message got through
// 0x07 is bind message
boolean ignoredMessage = cluster.profileId != 0x0104 ||
cluster.command == 0x0B ||
cluster.command == 0x07 ||
(cluster.data.size() > 0 && cluster.data.first() == 0x3e)
return !ignoredMessage
}

private Map parseReportAttributeMessage(String description) {
Map descMap = (description - “read attr - “).split(”,”).inject([:]) { map, param ->
def nameAndValue = param.split(":")
map += [(nameAndValue[0].trim()):nameAndValue[1].trim()]
}
log.debug “Desc Map: $descMap”

Map resultMap = [:]
if (descMap.cluster == “0402” && descMap.attrId == “0000”) {
def value = getTemperature(descMap.value)
resultMap = getTemperatureResult(value)
}
else if (descMap.cluster == “0001” && descMap.attrId == “0020”) {
resultMap = getBatteryResult(Integer.parseInt(descMap.value, 16))
}
else if (descMap.cluster == “0b02” && descMap.attrId == “0000”) {
log.debug “Parsing cluster B02 data”
//resultMap =
}

return resultMap
}

private Map parseCustomMessage(String description) {
Map resultMap = [:]
if (description?.startsWith('temperature: ')) {
def value = zigbee.parseHATemperatureValue(description, "temperature: ", getTemperatureScale())
resultMap = getTemperatureResult(value)
}
return resultMap
}

def getTemperature(value) {
def celsius = Integer.parseInt(value, 16).shortValue() / 100
if(getTemperatureScale() == “C”){
return celsius
} else {
return celsiusToFahrenheit(celsius) as Integer
}
}

private Map getBatteryResult(rawValue) {
log.debug "Battery rawValue = ${rawValue}"
def linkText = getLinkText(device)

def result = [
    name: 'battery',
value: '--',
translatable: true

]

def volts = rawValue / 10

if (rawValue == 0 || rawValue == 255) {}
else {
    if (volts > 4.5) {
        result.value = 100
        result.descriptionText = "{{ device.displayName }} battery has too much power: (> 3.5) volts."
    }
    else {
        if (device.getDataValue("manufacturer") == "SmartThings") {
            volts = rawValue // For the batteryMap to work the key needs to be an int
            def batteryMap = [28:100, 27:100, 26:100, 25:90, 24:90, 23:70,
							  22:70, 21:50, 20:50, 19:30, 18:30, 17:15, 16:1, 15:0]
            def minVolts = 15
            def maxVolts = 28

            if (volts < minVolts)
                volts = minVolts
            else if (volts > maxVolts)
                volts = maxVolts
            def pct = batteryMap[volts]
            if (pct != null) {
                result.value = pct
                result.descriptionText = "{{ device.displayName }} battery was {{ value }}%"
            }
        }
        else {
            def minVolts = 2.1
            def maxVolts = 4.5
            def pct = (volts - minVolts) / (maxVolts - minVolts)
            result.value = Math.min(100, (int) pct * 100)
            result.descriptionText = "{{ device.displayName }} battery was {{ value }}%"
        }
    }
}

return result

}

private Map getTemperatureResult(value) {
log.debug 'TEMP’
if (tempOffset) {
def offset = tempOffset as int
def v = value as int
value = v + offset
}
def descriptionText
if ( temperatureScale == ‘C’ )
descriptionText = '{{ device.displayName }} was {{ value }}°C’
else
descriptionText = ‘{{ device.displayName }} was {{ value }}°F’

return [
    name: 'temperature',
value: value,
descriptionText: descriptionText,
translatable: true

]
}

private Map getMoistureResult(value) {
log.debug "water"
def descriptionText
if ( value == “wet” )
descriptionText = '{{ device.displayName }} is wet’
else
descriptionText = '{{ device.displayName }} is dry’
return [
name: ‘water’,
value: value,
descriptionText: descriptionText,
translatable: true
]
}

private Map parseAlarmCode(value) {
log.debug “parse alarm code ${value}”

Map resultMap = [:]

switch(value) {
    case "1": // Closed/No Motion/Dry
    	log.debug "dry"
        resultMap = getMoistureResult('dry')
        break

    case "17": // Open/Motion/Wet
    	log.debug "wet"
        resultMap = getMoistureResult('wet')
        break
        }

return resultMap

}

def refresh() {
log.debug "Refreshing"
def refreshCmds = [
zigbee.readAttribute(0x0402, 0x0000), “delay 200”,
zigbee.readAttribute(0x0001, 0x0020), “delay 200”

    //for mfg and model
    //"str rattr 0x${zigbee.deviceNetworkId} 0x${zigbee.endpointId} 0 4", "delay 200",
	//"str rattr 0x${zigbee.deviceNetworkId} 0x${zigbee.endpointId} 0 5"
   
]

return refreshCmds + configure() //send config as part of the refresh

}

def configure() {
def configCmds = [

	zigbee.configureReporting(0x0001, 0x0020, 0x20, 30, 21600, 0x01), "delay 500",
  	zigbee.configureReporting(0x0402, 0x0000, 0x29, 30, 3600, 0x0064), "delay 500",
    zigbee.configureReporting(0x0b02, 0x0000, 0x10, 0, 3600, null), "delay 500"

]
log.debug "Sending config commands"
return configCmds
}

private getEndpointId() {
new BigInteger(device.endpointId, 16).toString()
}

private hex(value) {
new BigInteger(Math.round(value).toString()).toString(16)
}

private String swapEndianHex(String hex) {
reverseArray(hex.decodeHex()).encodeHex()
}

private byte[] reverseArray(byte[] array) {
int i = 0;
int j = array.length - 1;
byte tmp;
while (j > i) {
tmp = array[j];
array[j] = array[i];
array[i] = tmp;
j–;
i++;
}
return array
}

1 Like

This works for me now. Tested it on 6 sensors. Pain in the ass, but it works.

Post Installation Configuration

  1. Navigate to the device on your SmartThings app.
  2. Press the gear icons.
  3. Press done (or update the log level and done).
  4. Wait about 10 - 15 seconds.
  5. Press the “refresh” button.
  6. Wait about 10 - 15 seconds.
  7. Press the “configure” button.
  8. Wait about 10 - 15 seconds.
  9. Temperature and battery level should begin to appear.
  10. If they don’t begin to appear, do another cycle of 2-8.

Just tested with one sensor that i got and it worked as described! Great work!

I can’t figure out why the configure command doesn’t finish during the regular setup process which is why you need the post installation steps. I’m glad it worked.

Found that removing one battery from the sensor for a few seconds and then putting it back in works much better than steps 2-8 :slight_smile:

THANK YOU for the DTH.

Thanks. I cant figure out what is going on during the standard install / update process. During both procedures the updated()/installed() method gets called with then calls initialize() which then call configure(). Configure seems to start but never finish. I’ve try surrounding everything with try / catch’s but no dice.

I tried your code but it has that same Java.Lang exception error, so I reverted back to dhelm2’s code I posted since it works despite the need for setup via the simulator. Looking forward to working code that doesn’t need extra configuration steps outside the app.

I’m still having trouble getting the Dry/Wet status to update. Below is the log data that I think is showing the change in status as it correlates with me shorting the sensing pins at 5:22:14 and then removing the short at 5:22:34. Any idea why I’m seeing different results?

FYI, pairing and temperature/battery refreshing all went smoothly.

58e27323-c02a-4845-b3a7-42517d5290d2 5:22:34 PM: debug leakSmart – map = [:].
58e27323-c02a-4845-b3a7-42517d5290d2 5:22:34 PM: debug leakSmart – Desc Map: [raw:9E0E010B020801810100, dni:9E0E, endpoint:01, cluster:0B02, size:08, attrId:8101, encoding:01, value:00].
58e27323-c02a-4845-b3a7-42517d5290d2 5:22:34 PM: debug leakSmart – parse(read attr - raw: 9E0E010B020801810100, dni: 9E0E, endpoint: 01, cluster: 0B02, size: 08, attrId: 8101, encoding: 01, value: 00.
58e27323-c02a-4845-b3a7-42517d5290d2 5:22:14 PM: debug leakSmart – map = [:].
58e27323-c02a-4845-b3a7-42517d5290d2 5:22:14 PM: debug leakSmart – Desc Map: [raw:9E0E010B020801811100, dni:9E0E, endpoint:01, cluster:0B02, size:08, attrId:8101, encoding:11, value:00].
58e27323-c02a-4845-b3a7-42517d5290d2 5:22:14 PM: debug leakSmart – parse(read attr - raw: 9E0E010B020801811100, dni: 9E0E, endpoint: 01, cluster: 0B02, size: 08, attrId: 8101, encoding: 11, value: 00.

I’m also including the log section from when I asked the device to configure in case that reveals anything:

Configuration Log

58e27323-c02a-4845-b3a7-42517d5290d2 5:21:40 PM: debug leakSmart – map = [:].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:40 PM: debug leakSmart – Desc Map: [raw:9E0E010B0206000086, dni:9E0E, endpoint:01, cluster:0B02, size:06, attrId:0000, result:unsupported attr].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:40 PM: debug leakSmart – parse(read attr - raw: 9E0E010B0206000086, dni: 9E0E, endpoint: 01, cluster: 0B02, size: 06, attrId: 0000, result: unsupported attr.
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:40 PM: debug leakSmart – map = [name:battery, value:91, translatable:true, descriptionText:{{ device.displayName }} battery was {{ value }}%].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:40 PM: debug leakSmart – Battery rawValue = 43.
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:40 PM: debug leakSmart – Desc Map: [raw:9E0E0100010A200000202B, dni:9E0E, endpoint:01, cluster:0001, size:0A, attrId:0020, result:success, encoding:20, value:2b].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:39 PM: debug leakSmart – parse(read attr - raw: 9E0E0100010A200000202B, dni: 9E0E, endpoint: 01, cluster: 0001, size: 0A, attrId: 0020, result: success, encoding: 20, value: 2b.
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:39 PM: debug leakSmart – map = [name:temperature, value:82, descriptionText:{{ device.displayName }} was {{ value }}°F, translatable:true].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:39 PM: debug leakSmart – Begin getTemperatureResult(82).
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:39 PM: debug leakSmart – 402 Cluster Data: [0, 0, 0, 41, 17, 11].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:39 PM: debug leakSmart – parse(catchall: 0104 0402 01 01 0140 00 9E0E 00 00 0000 01 01 00000029110B.
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:38 PM: debug leakSmart – map = [:].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:38 PM: debug leakSmart – Did not process message SmartShield(clusterId: 0x0b02, command: 0x07, data: [0x86, 0x00, 0x00, 0x00], destinationEndpoint: 0x01, direction: 0x01, isClusterSpecific: false, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0140, profileId: 0x0104, senderShortId: 0x9e0e, sourceEndpoint: 0x01, text: null).
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:38 PM: debug leakSmart – parse(catchall: 0104 0B02 01 01 0140 00 9E0E 00 00 0000 07 01 86000000.
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:37 PM: debug leakSmart – map = [:].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:37 PM: debug leakSmart – Did not process message SmartShield(clusterId: 0x0402, command: 0x07, data: [0x00], destinationEndpoint: 0x01, direction: 0x01, isClusterSpecific: false, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0140, profileId: 0x0104, senderShortId: 0x9e0e, sourceEndpoint: 0x01, text: null).
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:37 PM: debug leakSmart – parse(catchall: 0104 0402 01 01 0140 00 9E0E 00 00 0000 07 01 00.
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:36 PM: debug leakSmart – map = [:].
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:36 PM: debug leakSmart – Did not process message SmartShield(clusterId: 0x0001, command: 0x07, data: [0x00], destinationEndpoint: 0x01, direction: 0x01, isClusterSpecific: false, isManufacturerSpecific: false, manufacturerId: 0x0000, messageType: 0x00, number: null, options: 0x0140, profileId: 0x0104, senderShortId: 0x9e0e, sourceEndpoint: 0x01, text: null).
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:36 PM: debug leakSmart – parse(catchall: 0104 0001 01 01 0140 00 9E0E 00 00 0000 07 01 00.
58e27323-c02a-4845-b3a7-42517d5290d2 5:21:34 PM: debug Configuring Reporting, IAS CIE, and Bindings.

Which error, can you post the logs? Off what event? Refresh or wet?

Updated the code by removing un-needed lines of code. I believe I fixed the unsupported attr issue.

Paired and tested 2 devices.

I still had to do the strange post installation steps, removing the battery did not work or at least I didn’t wait long enough.

Yeah, you have to wait until the device sends something - it will flash blue when it does.

5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎30‎:‎02‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690430019401132315953.$() is applicable for argument types: (script14690430019401132315953$_log_closure2) values: [script14690430019401132315953$_log_closure2@5ae7fafe]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), use([Ljava.lang.Object;) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎30‎:‎02‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690430019271132315953.$() is applicable for argument types: (script14690430019271132315953$_log_closure2) values: [script14690430019271132315953$_log_closure2@188e7ed9]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), any(groovy.lang.Closure) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎52‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429916621132315953.$() is applicable for argument types: (script14690429916621132315953$_log_closure2) values: [script14690429916621132315953$_log_closure2@6d5e8963]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), use([Ljava.lang.Object;) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎51‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429916131132315953.$() is applicable for argument types: (script14690429916131132315953$_log_closure2) values: [script14690429916131132315953$_log_closure2@736346b6]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), use([Ljava.lang.Object;) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎51‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429915681132315953.$() is applicable for argument types: (script14690429915681132315953$_log_closure2) values: [script14690429915681132315953$_log_closure2@57129799]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), any(groovy.lang.Closure) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎51‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429915131132315953.$() is applicable for argument types: (script14690429915131132315953$_log_closure2) values: [script14690429915131132315953$_log_closure2@30dc77b4]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), use([Ljava.lang.Object;) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎51‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429914071132315953.$() is applicable for argument types: (script14690429914071132315953$_log_closure2) values: [script14690429914071132315953$_log_closure2@39e86bf5]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), any(groovy.lang.Closure) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎51‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429914071132315953.$() is applicable for argument types: (script14690429914071132315953$_log_closure2) values: [script14690429914071132315953$_log_closure2@4a07bf86]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), any(groovy.lang.Closure) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎51‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429913431132315953.$() is applicable for argument types: (script14690429913431132315953$_log_closure2) values: [script14690429913431132315953$_log_closure2@479747cb]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), use([Ljava.lang.Object;) 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎51‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script14690429912641132315953.$() is applicable for argument types: (script14690429912641132315953$_log_closure2) values: [script14690429912641132315953$_log_closure2@417766f4]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), use([Ljava.lang.Object;)
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎48‎ ‎PM: debug refresh() -- retVal = [st rattr 0x75F1 1 1026 0, delay 500, st rattr 0x75F1 1 1 32, delay 500] 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎48‎ ‎PM: debug Refreshing 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎45‎ ‎PM: debug Ending configure(), returning retVal = [zdo bind 0x75F1 1 0x01 1 {0022A3000013AD64} {}, delay 500, zcl global send-me-a-report 1 32 32 30 21600 {01}, delay 200, send 0x75F1 0x01 1, delay 500, zdo bind 0x75F1 1 0x01 1026 {0022A3000013AD64} {}, delay 500, zcl global send-me-a-report 1026 0 41 30 3600 {6400}, delay 200, send 0x75F1 0x01 1, delay 500, zdo bind 0x75F1 1 0x01 2818 {0022A3000013AD64} {}, delay 500, zcl global send-me-a-report 2818 0 0 30 3600 {}, delay 200, send 0x75F1 0x01 1, delay 500, st rattr 0x75F1 1 1026 0, delay 500, st rattr 0x75F1 1 1 32, delay 500]. 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎45‎ ‎PM: debug Configuring Reporting, IAS CIE, and Bindings. 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎45‎ ‎PM: debug Begin configure(). 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎40‎ ‎PM: debug refresh() -- retVal = [st rattr 0x75F1 1 1026 0, delay 500, st rattr 0x75F1 1 1 32, delay 500] 
5dc47a34-07f8-4c50-afc8-2eb4000d70d4 ‎3‎:‎29‎:‎40‎ ‎PM: debug Refreshing 

That’s what I get from your latest code. Sorry it took me so long to post.

Update from github and try now…

Also, can you tell me when you try the new code if you got this error on install of the device? Hitting refresh? Hitting configure & done?

Updated from GitHub, hit configure, says “Begin Configure()”, hit poll, no output, hit refresh, no output, wet contacts get:

 ‎5‎:‎09‎:‎06‎ ‎PM: error groovy.lang.MissingMethodException: No signature of method: script1469048945977111945188.$() is applicable for argument types: (script1469048945977111945188$_log_closure2) values: [script1469048945977111945188$_log_closure2@78c88457]
Possible solutions: is(java.lang.Object), now(), run(), any(), app(java.util.Map), use([Ljava.lang.Object;)

Looking into it now. Unfortunately when I do a wet contact I get…

50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:16 PM: debug leakSmart -- map = [name:water, value:dry, descriptionText:leakSmart Sensor is dry, translatable:true].
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:16 PM: debug leakSmart -- Begin getMoistureResult(dry).
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:16 PM: debug leakSmart -- Sensor is dry.
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:16 PM: debug leakSmart -- Parse alarm code 1.
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:16 PM: debug leakSmart -- B02 temp data 1.
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:16 PM: debug leakSmart -- B02 Cluster Data: [1, 129, 1, 0].
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:16 PM: debug leakSmart -- parse(catchall: 0104 0B02 01 01 0140 00 F8F0 01 00 0000 01 01 01810100.
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:06 PM: debug leakSmart -- map = [name:water, value:wet, descriptionText:leakSmart Sensor is wet, translatable:true].
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:06 PM: debug leakSmart -- Begin getMoistureResult(wet).
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:06 PM: info leakSmart -- Sensor is wet!
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:06 PM: debug leakSmart -- Parse alarm code 17.
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:06 PM: debug leakSmart -- B02 temp data 17.
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:06 PM: debug leakSmart -- B02 Cluster Data: [1, 129, 17, 0].
50e39cc9-4ba6-46f5-b49e-eb485550f2ac  6:19:06 PM: debug leakSmart -- parse(catchall: 0104 0B02 01 01 0140 00 F8F0 01 00 0000 01 01 01811100.

By the way, I pushed new code. I don’t think it will resolve your issue but worth a try. Can you try removing the device, excluding it and re-adding it?

Whats the latest on what it takes to get wet/dry to report correctly? I got mine paired and battery and temp showing correctly, but tripped the moisture sensor for 30 seconds and it beeped a bunch, but never showed wet in SmartThings.

Try removing the batteries for a few seconds. That’s how I got all 6 of mine to work

Getting them to start communicating is kind of a pain. @ady624 method also worked for me. BTW - I have an update coming to this DH later today. Likely won’t make this process any easier, but I had one of my devices go “INACTIVE” this week.

1 Like

I wish I had more time to test your code Eric. Right now I’m still using the dhelm2 code I reformatted. Everything is working.