ST Multi-Sensor battery reporting issues

My multi sensors haven’t gone offline but they all show 100% battery even though some have been in for a year now. They are all SmartSense Multi Sensor, same as @rhoffer, model 3321-S also running 0x1F015310.

My one motion sensor also shows 100% battery and I put in a new battery about 5 or 6 months ago. It’s in my kitchen and gets almost constant activity so I know that can’t be right. It’s also the same one as above, model 3325-S running 0x1F015310.

Just a FYI if it helps my SmartSense Humidity/Temp Sensor, model 3310-S, also running firmware 0x1F075310, do not have this issue. They are all reporting different battery statuses including one in my refrigerator at 44% which is the lowest (and with the cold that makes sense).

Also not sure if this is related but I’ve been having issues with some of my leak sensors lately (about the last month). All are SmartSense Moisture Sensor M/N: STS-WTR-250, Model moisturev4, current and target firmware are both 0x00000019. The will be marked offline and but at 100% battery. Here is on doing it right now:

image

So I pull the cover, press the button, it starts a couple blue/green blinks, click the X in the app and hit refresh. Magically its back online and still shows 100% battery. It’s been in for at least 4 months now. This is the second one to do this and same thing on the other…100% battery. The other after doing this has stayed online so far (about a week) so IDK. Just hitting X and refresh doesn’t fix it…have to press the button inside.

-Allan

I’ve replaced several batteries that were still reporting 100%. I knew they were nearly dead because they kept going online/offline several times a day, each time triggering a false event.

I just had another muilti drop from my system this morning. The battery was showing 100% but read 2.532 volts. I will be contacting support again tomorrow.

I have been trouble shooting since support was of no help. I have 3 test case DTHs reporting percentages, each differently. The least modified version has me scratcbing my head. Can anybody tell me it this line is correct.

def curValVolts = Integer.parseInt(device.currentState(“battery”)?.value ?: “100”) / 100.0

This is line 278 of the DTH for the Smartsense Multi Sensor. If I remove the ?: “100” to where it looks like this:

def curValVolts = Integer.parseInt(device.currentState(“battery”)?.value ) / 100.0

The Centralite sensor begins to report what looks to be correct values in the app instead of 100% all the time. I also played with the min and max voltage. Original max was 2.7 volts. Min voltage was 2.1. I changed this to 2.5 because i know at 2.5 volts the device no longer reports open/close.

I know they will all run in the cloud now, just trying to get a battery percentage to keep from having the device drop from the system without any warning.

If anyone could help explain if that original line is correct I would be greatful.

So this is still a issue here too but I’ve found some differences in exactly what devices have the issue. Example - I have 6 leak sensors. 5 are reporting 100% battery and one is reporting 78%. So I looked into it further:

5x manufacturer: SmartThings model: moisturev4 - All Show 100% (firmware 0x00000019)
1x manufacturer: CentraLite model: 3315-S - Shows 78% (firmware 0x10015100)

So same with the SmartSense Multi Sensor but the opposite of above:

5x manufacturer: CentraLite model: 3321-S - All Show 100% (firmware 0x1F015310)
1x manufacturer: SmartThings model: multiv4 - Shows 90% (firmware 0x00000019)

@posborne - You CC’d @Zach_Varberg and @tpmanley before. Has any progress been made on this to fix it? My motion sensor also is showing 100% and not changing and its been in for 8 months with daily use…I know its not 100%. Its listed as manufacturer: CentraLite model: 3325-S.

Should there be a different device type for the different manufactures? They are the “same” device but obviously they are not being treated as such.

-Allan

In the DTH, there is a split when it comes to battery reporting for the Multi Sensors (IF SmartThings then X else Y). ST manuractured ones have one way of calculating and the CentraLites have another. I haven’t looked at the leak or motion detectors to see if they different methods of calculating/reporting for each manufacturer.

I started post in the developer device handler section to see if anyone of the pros could answer the question above about the parseInt format. No takers/replys yet.

So far the modified version is holding.

Update: My scheduled daily 10 am battery check correctly reported that 2 multis were below the old magic threshold of 68% battery.

Whats weird is the fact that I have “SmartThings” listed devices that only show 100% while the CentraLite ones show correct then for other devices it’s the opposite.

Either way the devs need to look at this and fix it in the DTH’s especially since their changes seemed to break things.

I looked at the moister sensor DTH. For the SmartSense Moisture Sensor DTH, the ST section is calculated the same as the ST in the multi. The Max Volt on it is 2.8 volts (100%)

For the CentraLite section they did not add in any of the curValVolts calculations/formulas. That is why it is working for the CentraLite moisture sensors. The max volt for these is set at 3.0 volts.

If the ST batteries in the moisture sensor are 2.8 or over then they are reported at 100%. That same battery, if it fit in a CentraLite would be less than 100 of the voltave was under 3.0 volts

1 Like

Any update to this issue? I’m having the same problem

No change as far as word/fix from support other than working on it emails. The five I have on a modified DTH are going fine. I have two @ 60% and One @ 80%. The other ones had recent battery changes, one 21 days and the other 5 days ago. They are both @ 100%. Temperature and all other sensor functions are reporting fine also. The sixth one in a freezer has the temp not working properly on the modified DTH. I haven’t sorted through the code to see if I can find out why. This one has been modified with external batteries because The tab broke off during a battery change. The temp is fine with the stock DTH, just not battery % other than 100%.

Yes I notified support about this and they confirmed it is an issue. Their suggestions was to change the battery 2-3 times a year.

Thats BS. I would reply and tell them thats not a answer and ask when it will be fixed. They made a change that broke it, they can figure out how to fix it.

Here is the modified DTH I am using on my CentraLite 3321-S sensors. Battery reporting seems to be working correctly. I added remarks to explain the changes made. It will not run locally, but it fixed the battery reporting for my 6 sensors. All other senor abilities are also working except for temperature for the one I have in a freezer.

The changes include addition of remarks and the follow:
1 - Name change to keep track of test version
2 - Changed minVolt from 2.1 to 2.5, as my sensors no longer report open/close when batteries get close to 2.5 volts.
3 - Changed maxVolt from 2.7 to 3 to get a more realistic battery percentage an to gain more steps in the battery reporting percentages.
4 - Changed defining line for curValVolt to correctly follow the parseInt(string, radix) by changing the “?:100” to “, 10” for the proper radix for decimal numeral

/*

  • 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.
    */
    // Rhoffer - Edited version to original SmartSense Multi Senesor. See comments at lines 22, 279-281, 283-284, 286-287 for the remarks on the changes made

import physicalgraph.zigbee.clusters.iaszone.ZoneStatus
import physicalgraph.zigbee.zcl.DataType

metadata {
//Rhoffer - Changed Name to reflect Test Version on Line 23
definition(name: “SmartSense Multi Sensor test3”, namespace: “smartthings”, author: “SmartThings”) {

	capability "Three Axis"
	capability "Battery"
	capability "Configuration"
	capability "Sensor"
	capability "Contact Sensor"
	capability "Acceleration Sensor"
	capability "Refresh"
	capability "Temperature Measurement"
	capability "Health Check"

	command "enrollResponse"
	fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3320"
	fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321"
	fingerprint inClusters: "0000,0001,0003,0402,0500,0020,0B05,FC02", outClusters: "0019", manufacturer: "CentraLite", model: "3321-S", deviceJoinName: "Multipurpose Sensor"
	fingerprint inClusters: "0000,0001,0003,000F,0020,0402,0500,FC02", outClusters: "0019", manufacturer: "SmartThings", model: "multiv4", deviceJoinName: "Multipurpose Sensor"

	attribute "status", "string"
}

simulator {
	status "open": "zone report :: type: 19 value: 0031"
	status "closed": "zone report :: type: 19 value: 0030"

	status "acceleration": "acceleration: 1"
	status "no acceleration": "acceleration: 0"

	for (int i = 10; i <= 50; i += 10) {
		status "temp ${i}C": "contactState: 0, accelerationState: 0, temp: $i C, battery: 100"
	}

	// kinda hacky because it depends on how it is installed
	status "x,y,z: 0,0,0": "x: 0, y: 0, z: 0"
	status "x,y,z: 1000,0,0": "x: 1000, y: 0, z: 0"
	status "x,y,z: 0,1000,0": "x: 0, y: 1000, z: 0"
	status "x,y,z: 0,0,1000": "x: 0, y: 0, z: 1000"
}
preferences {
	section {
		image(name: 'educationalcontent', multiple: true, images: [
				"http://cdn.device-gse.smartthings.com/Multi/Multi1.jpg",
				"http://cdn.device-gse.smartthings.com/Multi/Multi2.jpg",
				"http://cdn.device-gse.smartthings.com/Multi/Multi3.jpg",
				"http://cdn.device-gse.smartthings.com/Multi/Multi4.jpg"
		])
	}
	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
	}
	section {
		input("garageSensor", "enum", title: "Do you want to use this sensor on a garage door?", description: "Tap to set", options: ["Yes", "No"], defaultValue: "No", required: false, displayDuringSetup: false)
	}
}

tiles(scale: 2) {
	multiAttributeTile(name: "status", type: "generic", width: 6, height: 4) {
		tileAttribute("device.status", key: "PRIMARY_CONTROL") {
			attributeState "open", label: 'Open', icon: "st.contact.contact.open", backgroundColor: "#e86d13"
			attributeState "closed", label: 'Closed', icon: "st.contact.contact.closed", backgroundColor: "#00a0dc"
			attributeState "garage-open", label: 'Open', icon: "st.doors.garage.garage-open", backgroundColor: "#e86d13"
			attributeState "garage-closed", label: 'Closed', icon: "st.doors.garage.garage-closed", backgroundColor: "#00a0dc"
		}
	}
	standardTile("contact", "device.contact", width: 2, height: 2) {
		state("open", label: 'Open', icon: "st.contact.contact.open", backgroundColor: "#e86d13")
		state("closed", label: 'Closed', icon: "st.contact.contact.closed", backgroundColor: "#00a0dc")
	}
	standardTile("acceleration", "device.acceleration", width: 2, height: 2) {
		state("active", label: 'Active', icon: "st.motion.acceleration.active", backgroundColor: "#00a0dc")
		state("inactive", label: 'Inactive', icon: "st.motion.acceleration.inactive", backgroundColor: "#cccccc")
	}
	valueTile("temperature", "device.temperature", 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(["status", "acceleration", "temperature"])
	details(["status", "acceleration", "temperature", "battery", "refresh"])
}

}

def parse(String description) {
def maps = []
maps << zigbee.getEvent(description)
if (!maps[0]) {
maps = []
if (description?.startsWith(‘zone status’)) {
maps += parseIasMessage(description)
} else {
Map descMap = zigbee.parseDescriptionAsMap(description)
if (descMap?.clusterInt == 0x0001 && descMap.commandInt != 0x07 && descMap?.value) {
maps << getBatteryResult(Integer.parseInt(descMap.value, 16))
} else if (descMap?.clusterInt == zigbee.TEMPERATURE_MEASUREMENT_CLUSTER && descMap.commandInt == 0x07) {
if (descMap.data[0] == “00”) {
log.debug "TEMP REPORTING CONFIG RESPONSE: $descMap"
sendEvent(name: “checkInterval”, value: 60 * 12, displayed: false, data: [protocol: “zigbee”, hubHardwareId: device.hub.hardwareID])
} else {
log.warn “TEMP REPORTING CONFIG FAILED- error code: ${descMap.data[0]}”
}
} else if (descMap?.clusterInt == zigbee.IAS_ZONE_CLUSTER && descMap.attrInt == zigbee.ATTRIBUTE_IAS_ZONE_STATUS && descMap?.value) {
maps += translateZoneStatus(new ZoneStatus(zigbee.convertToInt(descMap?.value)))
} else {
maps += handleAcceleration(descMap)
}
}
} else if (maps[0].name == “temperature”) {
def map = maps[0]
if (tempOffset) {
map.value = (int) map.value + (int) tempOffset
}
map.descriptionText = temperatureScale == ‘C’ ? ‘{{ device.displayName }} was {{ value }}°C’ : '{{ device.displayName }} was {{ value }}°F’
map.translatable = true
}

def result = maps.inject([]) {acc, it ->
	if (it) {
		acc << createEvent(it)
	}
}
if (description?.startsWith('enroll request')) {
	List cmds = zigbee.enrollResponse()
	log.debug "enroll response: ${cmds}"
	result = cmds?.collect { new physicalgraph.device.HubAction(it) }
}
return result

}

private List handleAcceleration(descMap) {
def result = []
if (descMap.clusterInt == 0xFC02 && descMap.attrInt == 0x0010) {
def value = descMap.value == “01” ? “active” : "inactive"
log.debug "Acceleration $value"
result << [
name : “acceleration”,
value : value,
descriptionText: “{{ device.displayName }} was $value”,
isStateChange : isStateChange(device, “acceleration”, value),
translatable : true
]

	if (descMap.additionalAttrs) {
		result += parseAxis(descMap.additionalAttrs)
	}
} else if (descMap.clusterInt == 0xFC02 && descMap.attrInt == 0x0012) {
	def addAttrs = descMap.additionalAttrs ?: []
	addAttrs << ["attrInt": descMap.attrInt, "value": descMap.value]
	result += parseAxis(addAttrs)
}
return result

}

private List parseAxis(List attrData) {
def results = []
def x = hexToSignedInt(attrData.find { it.attrInt == 0x0012 }?.value)
def y = hexToSignedInt(attrData.find { it.attrInt == 0x0013 }?.value)
def z = hexToSignedInt(attrData.find { it.attrInt == 0x0014 }?.value)

if ([x, y ,z].any { it == null }) {
	return []
}

def xyzResults = [:]
if (device.getDataValue("manufacturer") == "SmartThings") {
	// This mapping matches the current behavior of the Device Handler for the Centralite sensors
	xyzResults.x = z
	xyzResults.y = y
	xyzResults.z = -x
} else {
	// The axises reported by the Device Handler differ from the axises reported by the sensor
	// This may change in the future
	xyzResults.x = z
	xyzResults.y = x
	xyzResults.z = y
}

log.debug "parseAxis -- ${xyzResults}"

if (garageSensor == "Yes")
	results += garageEvent(xyzResults.z)

def value = "${xyzResults.x},${xyzResults.y},${xyzResults.z}"
results << [
		name           : "threeAxis",
		value          : value,
		linkText       : getLinkText(device),
		descriptionText: "${getLinkText(device)} was ${value}",
		handlerName    : name,
		isStateChange  : isStateChange(device, "threeAxis", value),
		displayed      : false
]
results

}

private List parseIasMessage(String description) {
ZoneStatus zs = zigbee.parseZoneStatus(description)

translateZoneStatus(zs)

}

private List translateZoneStatus(ZoneStatus zs) {
List results = []

if (garageSensor != "Yes") {
	def value = zs.isAlarm1Set() ? 'open' : 'closed'
	log.debug "Contact: ${device.displayName} value = ${value}"
	def descriptionText = value == 'open' ? '{{ device.displayName }} was opened' : '{{ device.displayName }} was closed'
	results << [name: 'contact', value: value, descriptionText: descriptionText, displayed: false, translatable: true]
	results << [name: 'status', value: value, descriptionText: descriptionText, translatable: true]
}

return results

}

private Map getBatteryResult(rawValue) {
log.debug “Battery rawValue = ${rawValue}”

def result = [:]

def volts = rawValue / 10

if (!(rawValue == 0 || rawValue == 255)) {
	result.name = 'battery'
	result.translatable = true
	result.descriptionText = "{{ device.displayName }} battery was {{ value }}%"
	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]
		result.value = pct
	} else {
		// Rhoffer - Changed minVolts from 2.1 to 2.5 because my Multi sensors (3321-S Centralite) 
        // Rhoffer - would no longer report open/close around 2.5 but would still report temperature
        // Rhoffer - 2.5 volts = 0%
        def minVolts = 2.5
		// Rhoffer - Changed maxVolts from 2.7 to 3 because CR-2450 is a 3V battery. This gives a better
        // Rhoffer - scale of true percentage of batter.  3V =100%
        def maxVolts = 3.0
        // Rhoffer - Changed fomula to remove non-standard ?:"100" and replaced with 10, which is for decimal numeral system
        // Rhoffer - The original formula did not follow the parseInt(String, radix) standard where radix is an integer between 2 and 36
        // Get the current battery percentage as a multiplier 0 - 1
		def curValVolts = Integer.parseInt(device.currentState("battery")?.value, 10 ) / 100.0
		// Find the corresponding voltage from our range
		curValVolts = curValVolts * (maxVolts - minVolts) + minVolts
		// Round to the nearest 10th of a volt
		curValVolts = Math.round(10 * curValVolts) / 10.0
		// Only update the battery reading if we don't have a last reading,
		// OR we have received the same reading twice in a row
		// OR we don't currently have a battery reading
		// OR the value we just received is at least 2 steps off from the last reported value
		if(state?.lastVolts == null || state?.lastVolts == volts || device.currentState("battery")?.value == null || Math.abs(curValVolts - volts) > 0.1) {
			def pct = (volts - minVolts) / (maxVolts - minVolts)
			def roundedPct = Math.round(pct * 100)
			if (roundedPct <= 0)
				roundedPct = 1
			result.value = Math.min(100, roundedPct)
		} else {
			// Don't update as we want to smooth the battery values
			result = null
		}
		state.lastVolts = volts
	}
}

return result

}

List garageEvent(zValue) {
List results = []
def absValue = zValue.abs()
def contactValue = null
def garageValue = null
if (absValue > 900) {
contactValue = 'closed’
garageValue = ‘garage-closed’
} else if (absValue < 100) {
contactValue = 'open’
garageValue = ‘garage-open’
}
if (contactValue != null) {
def descriptionText = contactValue == ‘open’ ? ‘{{ device.displayName }} was opened’ : '{{ device.displayName }} was closed’
results << [name: ‘contact’, value: contactValue, descriptionText: descriptionText, displayed: false, translatable: true]
results << [name: ‘status’, value: garageValue, descriptionText: descriptionText, translatable: true]
}
results
}

/**

  • PING is used by Device-Watch in attempt to reach the Device
  • */
    def ping() {
    return zigbee.readAttribute(0x001, 0x0020) // Read the Battery Level
    }

def refresh() {
log.debug "Refreshing Values "

def refreshCmds = zigbee.readAttribute(zigbee.TEMPERATURE_MEASUREMENT_CLUSTER, 0x0000) +
		zigbee.readAttribute(zigbee.POWER_CONFIGURATION_CLUSTER, 0x0020) +
		zigbee.readAttribute(0xFC02, 0x0010, [mfgCode: manufacturerCode]) +
		zigbee.readAttribute(zigbee.IAS_ZONE_CLUSTER, zigbee.ATTRIBUTE_IAS_ZONE_STATUS) + zigbee.enrollResponse()

return refreshCmds

}

def configure() {
// Device-Watch allows 2 check-in misses from device + ping (plus 1 min lag time)
// enrolls with default periodic reporting until newer 5 min interval is confirmed
sendEvent(name: “checkInterval”, value: 2 * 60 * 60 + 1 * 60, displayed: false, data: [protocol: “zigbee”, hubHardwareId: device.hub.hardwareID])

log.debug "Configuring Reporting"
def configCmds = []

if (device.getDataValue("manufacturer") == "SmartThings") {
	log.debug "Refreshing Values for manufacturer: SmartThings "
	/* These values of Motion Threshold Multiplier(0x01) and Motion Threshold (0x0276)
        seem to be giving pretty accurate results for the XYZ co-ordinates for this manufacturer.
        Separating these out in a separate if-else because I do not want to touch Centralite part
        as of now.
    */
	configCmds += zigbee.writeAttribute(0xFC02, 0x0000, 0x20, 0x01, [mfgCode: manufacturerCode])
	configCmds += zigbee.writeAttribute(0xFC02, 0x0002, 0x21, 0x0276, [mfgCode: manufacturerCode])
} else {
	// Write a motion threshold of 2 * .063g = .126g
	// Currently due to a Centralite firmware issue, this will cause a read attribute response that
	// indicates acceleration even when there isn't.
	configCmds += zigbee.writeAttribute(0xFC02, 0x0000, 0x20, 0x02, [mfgCode: manufacturerCode])
}

// temperature minReportTime 30 seconds, maxReportTime 5 min. Reporting interval if no activity
// battery minReport 30 seconds, maxReportTime 6 hrs by default
configCmds += zigbee.batteryConfig() +
		zigbee.temperatureConfig(30, 300) +
		zigbee.configureReporting(0xFC02, 0x0010, DataType.BITMAP8, 10, 3600, 0x01, [mfgCode: manufacturerCode]) +
		zigbee.configureReporting(0xFC02, 0x0012, DataType.INT16, 1, 3600, 0x0001, [mfgCode: manufacturerCode]) +
		zigbee.configureReporting(0xFC02, 0x0013, DataType.INT16, 1, 3600, 0x0001, [mfgCode: manufacturerCode]) +
		zigbee.configureReporting(0xFC02, 0x0014, DataType.INT16, 1, 3600, 0x0001, [mfgCode: manufacturerCode])

return refresh() + configCmds

}

def updated() {
log.debug "updated called"
log.info "garage value : $garageSensor"
if (garageSensor == “Yes”) {
def descriptionText = "Updating device to garage sensor"
if (device.latestValue(“status”) == “open”) {
sendEvent(name: ‘status’, value: ‘garage-open’, descriptionText: descriptionText, translatable: true)
} else if (device.latestValue(“status”) == “closed”) {
sendEvent(name: ‘status’, value: ‘garage-closed’, descriptionText: descriptionText, translatable: true)
}
} else {
def descriptionText = "Updating device to open/close sensor"
if (device.latestValue(“status”) == “garage-open”) {
sendEvent(name: ‘status’, value: ‘open’, descriptionText: descriptionText, translatable: true)
} else if (device.latestValue(“status”) == “garage-closed”) {
sendEvent(name: ‘status’, value: ‘closed’, descriptionText: descriptionText, translatable: true)
}
}
}

private hexToSignedInt(hexVal) {
if (!hexVal) {
return null
}

def unsignedVal = hexToInt(hexVal)
unsignedVal > 32767 ? unsignedVal - 65536 : unsignedVal

}

private getManufacturerCode() {
if (device.getDataValue(“manufacturer”) == “SmartThings”) {
return “0x110A”
} else {
return “0x104E”
}
}

private hexToInt(value) {
new BigInteger(value, 16)
}

You should put in a Pull Request against the DTh in the smartthings repo. Maybe they can just use your changes or at the very least use it as a base for modifying theirs.

Still not sure why they would change something in firmware and not change the DTH to match. This seems like a wide spread issue…maybe most people arn’t noticing.

I will give it a try. I guess it is time to learn a little more on the Github side of things!

I’ve put in 25+ PRs on their repo, majority got committed. If you don’t have a GitHub account create one. Then go to https://github.com/SmartThingsCommunity/SmartThingsPublic and navigate to devicetypes -> smartthings and find the device. Click the sub directory, click the groovy file, click the Edit button. Make your changes, give a good description of why (I would also link back to this thread), and hit Propose File Change. On the next screen click Create Pull Request and submit it.

You can also open a new issue by starting at the root of the repo (link above) then clicking Issues and New Issue and listing what the problem seems to be and link your PR on how you think it should be fixed and ask for a review.

-Allan

2 Likes

Thanks, I think I did get one submitted. I could have used those instructions al little earlier :wink: . Just chalked up a little more knowledge figuring it out.

My 3 Multi Sensor are still reporting 100% battery. I have taken the battery out and back.
Still the same. I have asked ST support UK(by email) nothing back as yet.

I woke up to verification that the modified DTH worked for my CentraLite 3321-S multi sensors. The offender that started the original post has dropped from 100% to 80%. The battery raw value is 29 which is 2.9 volts, which is the 80% step in the 3.0-2.5 volt range. This took 28 days to change since the battery was replaced. The other steps should go quicker as new batteries are usually around 3.2 volts. Now to watch verificatiion of the change to the minimum voltage for open/close reporting.

1 Like

Hey ST.
Aren’t you working?
Why can’t you fix it?
I’m really angry about this issue.
This issue have been appeared lots of months ago.

Don’t think about your salary anymore.
I think you guys don’t work.

Check this line in the device handler code.
if (descMap?.clusterInt == 0x0001 && descMap.commandInt != 0x07 && descMap?.value)
clusterInt is 0x0001 -->> this signal can’t be generated anymore!
I’ve been watching the log again and again, but this signal doesn’t turn up!!

I think that you guys fix that 0x0001 signal to appear normally, then this issue will be done, ok?