[OBSOLETE] Original & Aqara Xiaomi Zigbee Sensors (contact, temp, motion, button, outlet, leak, etc)

I recently purchased 3 Aqara temp/humidity sensors and installed the custom DH before attempting to pair. The pairing process went pretty smoothly, but one of the devices keeps dropping off. They are all currently in the same location, about 10’ from my hub, for testing purposes. I’ve tried some of the tips from this thread:

  • Go to scan for new device mode in the app and press the “wake-up” button on the sensor until the status light indicates it’s back on network. This did cause the sensor to become online again, only to drop off after a couple of hours.
  • Reset the sensor but do not remove the device from ST, then scan for new devices. This caused ST to discover the device and automatically associate it with the existing device name (i.e., I didn’t have to rename it). Same results–offline after a couple of hours.
  • Reset the sensor and remove the device from ST, then scan for new devices. This caused ST to discover the device as completely new (i.e., I had to rename it). Same results–offline after a couple of hours.

In the IDE, they all show a route of This Device (ID) ↔ Home Hub; so nothing looks suspicious there. So are there any other tricks to try? Or should I assume this is a bad sensor and send it back? I don’t have any ZigBee repeaters on my network at the moment, and I’m nowhere near any neighbors for stray WiFi/ZigBee. I’ve got a couple Ikea plugs on order to help other issues, but it’ll be a while before they’re delivered. I could also go with the Centralite 3310 sensors, though they are more expensive than the Aqara. Any thoughts from those who have had experience with these devices? As always, thanks in advance.

You have checked the next hop and that’s the important key, Home Hub.
I have many of these and while most are solid there have been ones that I have had to re-add a few time before they “stick”. Just go into + Add a new device and scan, then press the reset until the blue led flashes 3 times or so. Sometime you have to wait for a minute or even retry a few times but it will find itself again and come back online.
I am just thankful ST has made provisions for Sleepy End Devices.

Thanks, @daven, I’ll try re-adding a few more times. These will be in attic crawlspaces to monitor humidity, so I certainly don’t want to keep having to physically get at the sensors to get them to re-join. When you re-added them, did you first delete the device from ST, or just leave it and re-pair? Thanks.

Also, interesting to note, is that the two sensors that have stayed joined are able to report battery. The one that keeps dropping offline reports no battery events in the hour or so it is online.

Just leave them in ST and press the reset in the sensor and search for them in ST, they will retain all the info and pair again. Do you have any zigbee outlet or some repeaters nearby? Xiaomi sensors don’t like some zigbee repeaters, I know Ikea ones work fine with them.

hi

I have successfully used the original A4refillpad for the Xiaomi Button. Pairing, i have used the Catchall method by lifting the 7th block as the ID and creating a device manually. However i noticed that the 7th block ID in the catch all changes everytime you reset the button ?

also the button drops off the network after a while and only way to fix it is to reset and re-add again… any thoughts?

i have now updated DTH to your version above… but lost the button press functionality in ST classic mobile app ?

I am dealing with that issue for buttons as well right now. Here’s what a quick google search comes up with: Help with Xiaomi Aqara door sensor disconnects

“… the standard requires that a zigbee Device check in with the hub every 60 minutes or it will be marked as missing. The Xiaomi devices Report right on the edge of that time period, so they are more vulnerable to being dropped.”

I only have one of the temperature sensors, but my tuppence worth is …

By ‘dropping off’, do you mean the sensor is no longer sending any readings, or that it is marked as ‘offline’ when you look at it in the SmartThings app? If the latter, does it also say ‘offline’ in the IDE? Although it isn’t usefully documented, and indeed barely documented at all, one interpretation of what ‘offline’ might actually mean it that it hasn’t seen any attribute updates from the device handler for a while.

The battery readings on these Aqara sensors usually take a few hours to start appearing, but after that they usually appear roughly every 50 to 60 minutes, which should be frequent enough to make SmartThings consider the device is online as long as Health Check is suitably configured (the device handler in the set described this thread looks OK in that regard),

Do you get temperature and humidity readings before the device ‘drops off’? Mine can go literally hours between them, and even longer for atmospheric pressure changes. From the Health Check perspective it is always worth making sure they do report something now and again before the battery reporting comes on stream. A huff of breath or a cupped hand to warm them up should suffice. Now and again would just mean less than every two hours.

Of course sometimes they just seem to stop communicating for no obvious reason, but I always found they seem to take a bit longer to do that as they like you to think they are working fine. The repeaters will certainly help. When it comes to interference don’t forget about the possibility of own goals from you own wi-fi, and don’t be surprised how little seems to be required to change the quality of Zigbee reception, even in what seems to be clear line of sight.

Thanks for all the great info. I’ve decided, though, that they seem to be more trouble than saving a few bucks is worth. So they’re currently awaiting the ride back to Amazon, and I’m going to give the Centralite 3310 a try. In case it helps others, though, here are answers to your questions:

By “offline”, I mean that the app shows it as offline, the IDE shows it as offline, there have been no events reported in 1+ hours, and when I press the little button on the top of the device, I get a single blink meaning it is no longer registered to the network. I might chalk this up to needing a repeater, but this occurred with the devices sitting within 15’ of my hub.

And, yes, I did get temp and humidity readings before the device dropped. If memory serves, probably about 20-30 minutes of readings. Then nothing. And, FWIW, the pressure sensitivity seemed to cause events quite frequently for me. Certainly not hours with stable temp, humidity, and pressure.

Hopefully the Centralites will do better, since they’ll be in not-so-easily-accessible attic space. But thanks again for trying to help.

I’ve not been able to get the old device handler for the two-button wireless switches to work with the new app. It will only register as a single button regardless of which button you press. Any idea how I might fix that?

Hi,

I have a issue since the release of the new app. As mentioned before no new DTH since the release but I can from the app virtual switch on and off the light but not from the actual switch although it flashes blue underneath. Came across a thread where this was solved but no solution was mentioned and no response.

Somebody with the same issue and possibly a solution?

Finaly the Aqara temp sensor to work. One worked right out of the box with the custom handler from bspranger. The second sensor took a bit more doing as it attached it self to the samsung smartthings outlet. Once I got it to connect directly to the hub it seems to be stable.

Even got pressure to “work” with action tiles. Added pressure atribute to bsrpangers code. This way I can get webcore to read the temperature. And send it to a virtual device in smarthings which in turn can be read by action tiles. Unfortunatly it has to be read as something else, I chose temperature as it just ads a little degree sign after the pressure. Sent a request to smartthings to add pressure as a capability, while being very friendly stating he forwarded my request to the design team Im not too hopefull this will be added any time soon.


/**************************************************************/
/* Temp test                                                  */
/**************************************************************/
/* Author     : Akidon                                        */
/* Created    : 3.5.2020, 13:05:02                            */
/* Modified   : 15.5.2020, 13:28:41                           */
/* Build      : 7                                             */
/* UI version : v0.3.110.20191009                             */
/**************************************************************/
 
+0msstart
/* Trace started on 18.5.2020, 11:10:41 (about 1 minute ago) */
 
define
dynamic Pressure1; /* 1006.1 */
end define;
 
execute
+145mspending
every minute /* #5 */
do
+149ms10ms
with /* #3 */
Temperatur Balkong
do
+151ms8ms
Set variable {Pressure1} = Temperatur Balkong's pressure; /* #4 */
end with;
+160ms30ms
with /* #1 */
{:a32b225724d35e949ee3371fdf3812bc:}
do
+162ms28ms
setTemperature({Pressure1}); /* #2 */
end with;
end every;
end execute;
 
+203msstop
/* Trace ended on 18.5.2020, 11:10:41 */
/**
 *  Xiaomi Aqara Temperature Humidity Sensor
 *  Version 1.3
 *
 *
 *  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.
 *
 *  Original device handler code by a4refillpad, adapted for use with Aqara model by bspranger
 *  Additional contributions to code by alecm, alixjg, bspranger, cscheiene, gn0st1c, foz333, jmagnuson, rinkek, ronvandegraaf, snalee, tmleafs, twonk, & veeceeoh 
 * 
 *  Known issues:
 *  Xiaomi sensors do not seem to respond to refresh requests
 *  Inconsistent rendering of user interface text/graphics between iOS and Android devices - This is due to SmartThings, not this device handler
 *  Pairing Xiaomi sensors can be difficult as they were not designed to use with a SmartThings hub. See 
 *
 */

metadata {
	definition (name: "Xiaomi Aqara Temperature Humidity Sensor", namespace: "bspranger", author: "bspranger") {
	capability "Temperature Measurement"
	capability "Relative Humidity Measurement"
	capability "Sensor"
	capability "Battery"
	capability "Health Check"

    
	attribute "lastCheckin", "String"
	attribute "lastCheckinDate", "String"
	attribute "maxTemp", "number"
	attribute "minTemp", "number"
	attribute "maxHumidity", "number"
	attribute "minHumidity", "number"
	attribute "multiAttributesReport", "String"
	attribute "currentDay", "String"
	attribute "batteryRuntime", "String"
   	attribute "pressure", "number"
    

	fingerprint profileId: "0104", deviceId: "5F01", inClusters: "0000, 0003, FFFF, 0402, 0403, 0405", outClusters: "0000, 0004, FFFF", manufacturer: "LUMI", model: "lumi.weather", deviceJoinName: "Xiaomi Aqara Temp Sensor"

	command "resetBatteryRuntime"
	}

    // simulator metadata
    simulator {
        for (int i = 0; i <= 100; i += 10) {
            status "${i}F": "temperature: $i F"
        }

        for (int i = 0; i <= 100; i += 10) {
            status "${i}%": "humidity: ${i}%"
        }
    }

    tiles(scale: 2) {
        multiAttributeTile(name:"temperature", type:"generic", width:6, height:4) {
            tileAttribute("device.temperature", key: "PRIMARY_CONTROL") {
                attributeState("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"]
 				]
                )
            }
            tileAttribute("device.multiAttributesReport", key: "SECONDARY_CONTROL") {
                attributeState("multiAttributesReport", label:'${currentValue}' //icon:"st.Weather.weather12",
                )
            }
        }
        valueTile("temperature2", "device.temperature", inactiveLabel: false) {
            state "temperature", label:'${currentValue}°', icon:"st.Weather.weather2",
                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("humidity", "device.humidity", inactiveLabel: false, width: 2, height: 2) {
            state "humidity", label:'${currentValue}%', unit:"%", icon:"https://raw.githubusercontent.com/bspranger/Xiaomi/master/images/XiaomiHumidity.png",
            backgroundColors:[
                [value: 0, color: "#FFFCDF"],
                [value: 4, color: "#FDF789"],
                [value: 20, color: "#A5CF63"],
                [value: 23, color: "#6FBD7F"],
                [value: 56, color: "#4CA98C"],
                [value: 59, color: "#0072BB"],
                [value: 76, color: "#085396"]
            ]
        }
        standardTile("pressure", "device.pressure", inactiveLabel: false, decoration:"flat", width: 2, height: 2) {
            state "pressure", label:'${currentValue}', icon:"https://raw.githubusercontent.com/bspranger/Xiaomi/master/images/XiaomiPressure.png"
        }
        valueTile("battery", "device.battery", inactiveLabel: false, width: 2, height: 2) {
            state "battery", label:'${currentValue}%', unit:"%", icon:"https://raw.githubusercontent.com/bspranger/Xiaomi/master/images/XiaomiBattery.png",
            backgroundColors:[
                [value: 10, color: "#bc2323"],
                [value: 26, color: "#f1d801"],
                [value: 51, color: "#44b621"]
            ]
        }
        valueTile("spacer", "spacer", decoration: "flat", inactiveLabel: false, width: 1, height: 1) {
	    state "default", label:''
        }
        valueTile("lastcheckin", "device.lastCheckin", inactiveLabel: false, decoration:"flat", width: 4, height: 1) {
            state "lastcheckin", label:'Last Event:\n ${currentValue}'
        }
        valueTile("batteryRuntime", "device.batteryRuntime", inactiveLabel: false, decoration:"flat", width: 4, height: 1) {
            state "batteryRuntime", label:'Battery Changed: ${currentValue}'
        }

        main("temperature2")
        details(["temperature", "battery", "pressure", "humidity", "spacer", "lastcheckin", "spacer", "spacer", "batteryRuntime", "spacer"])
    }
	preferences {
		//Button Config
		input description: "The settings below customize additional infomation displayed in the main tile.", type: "paragraph", element: "paragraph", title: "MAIN TILE DISPLAY"
		input name: "displayTempInteger", type: "bool", title: "Display temperature as integer?", description:"NOTE: Takes effect on the next temperature report. High/Low temperatures are always displayed as integers."
		input name: "displayTempHighLow", type: "bool", title: "Display high/low temperature?"
		input name: "displayHumidHighLow", type: "bool", title: "Display high/low humidity?"
		//Temp, Humidity, and Pressure Offsets and Pressure Units
		input description: "The settings below allow correction of variations in temperature, humidity, and pressure by setting an offset. Examples: If the sensor consistently reports temperature 5 degrees too warm, enter '-5' for the Temperature Offset. If it reports humidity 3% too low, enter ‘3' for the Humidity Offset. NOTE: Changes will take effect on the NEXT temperature / humidity / pressure report.", type: "paragraph", element: "paragraph", title: "OFFSETS & UNITS"
		input "tempOffset", "decimal", title:"Temperature Offset", description:"Adjust temperature by this many degrees", range:"*..*"
		input "humidOffset", "number", title:"Humidity Offset", description:"Adjust humidity by this many percent", range: "*..*"
		input "pressOffset", "number", title:"Pressure Offset", description:"Adjust pressure by this many units", range: "*..*"
		input name:"PressureUnits", type:"enum", title:"Pressure Units", options:["mbar", "kPa", "inHg", "mmHg"], description:"Sets the unit in which pressure will be reported"
		input description: "NOTE: The temperature unit (C / F) can be changed in the location settings for your hub.", type: "paragraph", element: "paragraph", title: ""
		//Date & Time Config
		input description: "", type: "paragraph", element: "paragraph", title: "DATE & CLOCK"    
		input name: "dateformat", type: "enum", title: "Set Date Format\nUS (MDY) - UK (DMY) - Other (YMD)", description: "Date Format", options:["US","UK","Other"]
		input name: "clockformat", type: "bool", title: "Use 24 hour clock?"
		//Battery Reset Config
		input description: "If you have installed a new battery, the toggle below will reset the Changed Battery date to help remember when it was changed.", type: "paragraph", element: "paragraph", title: "CHANGED BATTERY DATE RESET"
		input name: "battReset", type: "bool", title: "Battery Changed?", description: ""
		//Battery Voltage Offset
		input description: "Only change the settings below if you know what you're doing.", type: "paragraph", element: "paragraph", title: "ADVANCED SETTINGS"
		input name: "voltsmax", title: "Max Volts\nA battery is at 100% at __ volts.\nRange 2.8 to 3.4", type: "decimal", range: "2.8..3.4", defaultValue: 3
		input name: "voltsmin", title: "Min Volts\nA battery is at 0% (needs replacing)\nat __ volts.  Range 2.0 to 2.7", type: "decimal", range: "2..2.7", defaultValue: 2.5
	}
}

// Parse incoming device messages to generate events
def parse(String description) {
    log.debug "${device.displayName}: Parsing description: ${description}"

    // Determine current time and date in the user-selected date format and clock style
    def now = formatDate()    
    def nowDate = new Date(now).getTime()

	// Any report - temp, humidity, pressure, & battery - results in a lastCheckin event and update to Last Checkin tile
	// However, only a non-parseable report results in lastCheckin being displayed in events log
    sendEvent(name: "lastCheckin", value: now, displayed: false)
    sendEvent(name: "lastCheckinDate", value: nowDate, displayed: false)

	// Check if the min/max temp and min/max humidity should be reset
    checkNewDay(now)

	// getEvent automatically retrieves temp and humidity in correct unit as integer
	Map map = zigbee.getEvent(description)

	// Send message data to appropriate parsing function based on the type of report
	if (map.name == "temperature") {
        def temp = parseTemperature(description)
		map.value = displayTempInteger ? (int) temp : temp
		map.descriptionText = "${device.displayName} temperature is ${map.value}°${temperatureScale}"
		map.translatable = true
		updateMinMaxTemps(map.value)
	} else if (map.name == "humidity") {
		map.value = humidOffset ? (int) map.value + (int) humidOffset : (int) map.value
		updateMinMaxHumidity(map.value)
	} else if (description?.startsWith('catchall:')) {
		map = parseCatchAllMessage(description)
	} else if (description?.startsWith('read attr - raw:')) {
		map = parseReadAttr(description)
	} else {
		log.debug "${device.displayName}: was unable to parse ${description}"
        sendEvent(name: "lastCheckin", value: now) 
	}

	if (map) {
		log.debug "${device.displayName}: Parse returned ${map}"
		return createEvent(map)
	} else
		return [:]
}

// Calculate temperature with 0.1 precision in C or F unit as set by hub location settings
private parseTemperature(String description) {
	def temp = ((description - "temperature: ").trim()) as Float
	def offset = tempOffset ? tempOffset : 0
	temp = (temp > 100) ? (100 - temp) : temp
    temp = (temperatureScale == "F") ? ((temp * 1.8) + 32) + offset : temp + offset
	return temp.round(1)
}

// Check catchall for battery voltage data to pass to getBatteryResult for conversion to percentage report
private Map parseCatchAllMessage(String description) {
	Map resultMap = [:]
	def catchall = zigbee.parse(description)
	log.debug catchall

	if (catchall.clusterId == 0x0000) {
		def MsgLength = catchall.data.size()
		// Original Xiaomi CatchAll does not have identifiers, first UINT16 is Battery
		if ((catchall.data.get(0) == 0x01 || catchall.data.get(0) == 0x02) && (catchall.data.get(1) == 0xFF)) {
			for (int i = 4; i < (MsgLength-3); i++) {
				if (catchall.data.get(i) == 0x21) { // check the data ID and data type
					// next two bytes are the battery voltage
					resultMap = getBatteryResult((catchall.data.get(i+2)<<8) + catchall.data.get(i+1))
					break
				}
			}
		}
	}
	return resultMap
}

// Parse pressure report or battery report on reset button press
private Map parseReadAttr(String description) {
	Map resultMap = [:]

	def cluster = description.split(",").find {it.split(":")[0].trim() == "cluster"}?.split(":")[1].trim()
	def attrId = description.split(",").find {it.split(":")[0].trim() == "attrId"}?.split(":")[1].trim()
	def value = description.split(",").find {it.split(":")[0].trim() == "value"}?.split(":")[1].trim()

	// log.debug "${device.displayName}: Parsing read attr: cluster: ${cluster}, attrId: ${attrId}, value: ${value}"

	if ((cluster == "0403") && (attrId == "0000")) {
		def result = value[0..3]
		float pressureval = Integer.parseInt(result, 16)

		if (!(settings.PressureUnits)){
			settings.PressureUnits = "mbar"
		}
		// log.debug "${device.displayName}: Converting ${pressureval} to ${PressureUnits}"
	
		switch (PressureUnits) {
			case "mbar":
				pressureval = (pressureval/10) as Float
				pressureval = pressureval.round(1);
				break;

			case "kPa":
				pressureval = (pressureval/100) as Float
				pressureval = pressureval.round(2);
				break;

			case "inHg":
				pressureval = (((pressureval/10) as Float) * 0.0295300)
				pressureval = pressureval.round(2);
				break;

			case "mmHg":
				pressureval = (((pressureval/10) as Float) * 0.750062)
				pressureval = pressureval.round(2);
				break;
		}
		// log.debug "${device.displayName}: Pressure is ${pressureval} ${PressureUnits} before applying the pressure offset."

		if (settings.pressOffset) {
			pressureval = (pressureval + settings.pressOffset)
		}

		pressureval = pressureval.round(2);

		resultMap = [
			name: 'pressure',
			value: pressureval,
			unit: "${PressureUnits}",
			isStateChange: true,
			descriptionText : "${device.displayName} Pressure is ${pressureval} ${PressureUnits}"
		]
	} else if (cluster == "0000" && attrId == "0005")  {
		def modelName = ""
	
		// Parsing the model name
		for (int i = 0; i < value.length(); i+=2) {
			def str = value.substring(i, i+2);
			def NextChar = (char)Integer.parseInt(str, 16);
			modelName = modelName + NextChar
		}
		log.debug "${device.displayName}: Reported model: ${modelName}"
	}
	return resultMap
}

// Convert raw 4 digit integer voltage value into percentage based on minVolts/maxVolts range
private Map getBatteryResult(rawValue) {
    // raw voltage is normally supplied as a 4 digit integer that needs to be divided by 1000
    // but in the case the final zero is dropped then divide by 100 to get actual voltage value 
    def rawVolts = rawValue / 1000
    def minVolts
    def maxVolts

    if(voltsmin == null || voltsmin == "")
    	minVolts = 2.5
    else
   	minVolts = voltsmin
    
    if(voltsmax == null || voltsmax == "")
    	maxVolts = 3.0
    else
	maxVolts = voltsmax
    
    def pct = (rawVolts - minVolts) / (maxVolts - minVolts)
    def roundedPct = Math.min(100, Math.round(pct * 100))

    def result = [
        name: 'battery',
        value: roundedPct,
        unit: "%",
        isStateChange: true,
        descriptionText : "${device.displayName} Battery at ${roundedPct}% (${rawVolts} Volts)"
    ]

    return result
}

// If the day of month has changed from that of previous event, reset the daily min/max temp values
def checkNewDay(now) {
	def oldDay = ((device.currentValue("currentDay")) == null) ? "32" : (device.currentValue("currentDay"))
	def newDay = new Date(now).format("dd")
	if (newDay != oldDay) {
		resetMinMax()
		sendEvent(name: "currentDay", value: newDay, displayed: false)
	}
}

// Reset daily min/max temp and humidity values to the current temp/humidity values
def resetMinMax() {
	def currentTemp = device.currentValue('temperature')
	def currentHumidity = device.currentValue('humidity')
    currentTemp = currentTemp ? (int) currentTemp : currentTemp
	log.debug "${device.displayName}: Resetting daily min/max values to current temperature of ${currentTemp}° and humidity of ${currentHumidity}%"
    sendEvent(name: "maxTemp", value: currentTemp, displayed: false)
    sendEvent(name: "minTemp", value: currentTemp, displayed: false)
    sendEvent(name: "maxHumidity", value: currentHumidity, displayed: false)
    sendEvent(name: "minHumidity", value: currentHumidity, displayed: false)
    refreshMultiAttributes()
}

// Check new min or max temp for the day
def updateMinMaxTemps(temp) {
	temp = temp ? (int) temp : temp
	if ((temp > device.currentValue('maxTemp')) || (device.currentValue('maxTemp') == null))
		sendEvent(name: "maxTemp", value: temp, displayed: false)	
	if ((temp < device.currentValue('minTemp')) || (device.currentValue('minTemp') == null))
		sendEvent(name: "minTemp", value: temp, displayed: false)
	refreshMultiAttributes()
}

// Check new min or max humidity for the day
def updateMinMaxHumidity(humidity) {
	if ((humidity > device.currentValue('maxHumidity')) || (device.currentValue('maxHumidity') == null))
		sendEvent(name: "maxHumidity", value: humidity, displayed: false)
	if ((humidity < device.currentValue('minHumidity')) || (device.currentValue('minHumidity') == null))
		sendEvent(name: "minHumidity", value: humidity, displayed: false)
	refreshMultiAttributes()
}

// Update display of multiattributes in main tile
def refreshMultiAttributes() {
	def temphiloAttributes = displayTempHighLow ? (displayHumidHighLow ? "Today's High/Low:  ${device.currentState('maxTemp')?.value}° / ${device.currentState('minTemp')?.value}°" : "Today's High: ${device.currentState('maxTemp')?.value}°  /  Low: ${device.currentState('minTemp')?.value}°") : ""
	def humidhiloAttributes = displayHumidHighLow ? (displayTempHighLow ? "    ${device.currentState('maxHumidity')?.value}% / ${device.currentState('minHumidity')?.value}%" : "Today's High: ${device.currentState('maxHumidity')?.value}%  /  Low: ${device.currentState('minHumidity')?.value}%") : ""
	sendEvent(name: "multiAttributesReport", value: "${temphiloAttributes}${humidhiloAttributes}", displayed: false)
}

//Reset the date displayed in Battery Changed tile to current date
def resetBatteryRuntime(paired) {
	def now = formatDate(true)
	def newlyPaired = paired ? " for newly paired sensor" : ""
	sendEvent(name: "batteryRuntime", value: now)
	log.debug "${device.displayName}: Setting Battery Changed to current date${newlyPaired}"
}

// installed() runs just after a sensor is paired using the "Add a Thing" method in the SmartThings mobile app
def installed() {
	state.battery = 0
	if (!batteryRuntime) resetBatteryRuntime(true)
	checkIntervalEvent("installed")
}

// configure() runs after installed() when a sensor is paired
def configure() {
	log.debug "${device.displayName}: configuring"
		state.battery = 0
	if (!batteryRuntime) resetBatteryRuntime(true)
	checkIntervalEvent("configured")
	return
}

// updated() will run twice every time user presses save in preference settings page
def updated() {
		checkIntervalEvent("updated")
		if(battReset) {
			resetBatteryRuntime()
			device.updateSetting("battReset", false)
		}
}

private checkIntervalEvent(text) {
    // Device wakes up every 1 hours, this interval allows us to miss one wakeup notification before marking offline
    log.debug "${device.displayName}: Configured health checkInterval when ${text}()"
    sendEvent(name: "checkInterval", value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: "zigbee", hubHardwareId: device.hub.hardwareID])
}

def formatDate(batteryReset) {
    def correctedTimezone = ""
    def timeString = clockformat ? "HH:mm:ss" : "h:mm:ss aa"

	// If user's hub timezone is not set, display error messages in log and events log, and set timezone to GMT to avoid errors
    if (!(location.timeZone)) {
        correctedTimezone = TimeZone.getTimeZone("GMT")
        log.error "${device.displayName}: Time Zone not set, so GMT was used. Please set up your location in the SmartThings mobile app."
        sendEvent(name: "error", value: "", descriptionText: "ERROR: Time Zone not set, so GMT was used. Please set up your location in the SmartThings mobile app.")
    } 
    else {
        correctedTimezone = location.timeZone
    }

    if (dateformat == "US" || dateformat == "" || dateformat == null) {
        if (batteryReset)
            return new Date().format("MMM dd yyyy", correctedTimezone)
        else
            return new Date().format("EEE MMM dd yyyy ${timeString}", correctedTimezone)
    }
    else if (dateformat == "UK") {
        if (batteryReset)
            return new Date().format("dd MMM yyyy", correctedTimezone)
        else
            return new Date().format("EEE dd MMM yyyy ${timeString}", correctedTimezone)
        }
    else {
        if (batteryReset)
            return new Date().format("yyyy MMM dd", correctedTimezone)
        else
            return new Date().format("EEE yyyy MMM dd ${timeString}", correctedTimezone)
    }
}
2 Likes

When will this work with the new app?

For anyone who is interested this method works a treat. I have had my V3 Hub for a couple of hours and now all my Xiaomi / Aqara sensors added and working.

The pairing method does need a few tries to get things going. I also went to Device / Add / Scan Nearby before pairing the sensors.

For that to happen I suppose somone will have to pick it up from bsrpanger as he doesnt seem to be using smartthings anymore. As long as it works in the old app Im happy. Was never very into the new app anyway. With the old app I get it to work with action tiles and webcore. If they discontinue the old app I suppose I would look into it. Not that Im that great at coding, but how hard can it be.

Atmospheric Pressure Measurement is already a capability, but not everything supports it yet. I use it in my stripped down, revamped, new app only, version of the bspranger driver.

https://github.com/orangebucket/Anidea-for-SmartThings/blob/master/devicetypes/orangebucket/anidea-for-aqara-temperature.src/anidea-for-aqara-temperature.groovy?ts=4

And yes that driver has some friends but only tested on the sensors I have.

2 Likes

I agree, i started with smartthings this year so i was trying to keep things in the new app as the old one will shut down at some time. But more and more i keep falling back to the old one :confused:

Aha, I couldnt find that in the list of capabilities in the documentation. I will have a go and see if I can get it to work. Would be awesome to have it straight like that.

It certainly appears in the Device Details but to most other things it is a custom attribute at the moment. I simply can’t remember where I found it listed though.

Doesn’t seem like it pops up in action tiles or webcore for the aqara temp sensor device. Oh well I guess I will just have to stick to my workaround.
Attributes will always work, the problem is having it as a true capability so its availalbe throughout the system.

It is certainly a true capability, albeit a ‘proposed’ one. I tracked down the details from the SmartThings API:

{
  "id": "atmosphericPressureMeasurement",
  "version": 1,
  "status": "proposed",
  "name": "Atmospheric Pressure Measurement",
  "attributes": {
    "atmosphericPressure": {
      "schema": {
        "type": "object",
        "properties": {
          "value": {
            "type": "number",
            "minimum": 0,
            "maximum": 110
          },
          "unit": {
            "type": "string",
            "enum": [
              "kPa"
            ],
            "default": "kPa"
          }
        },
        "additionalProperties": false,
        "required": [
          "value"
        ]
      },
      "enumCommands": []
    }
  },
  "commands": {}
}

I actually use it with mbar as the unit as that is what the Aqara device uses, and it doesn’t seem to mind. As it only seems to like displaying integers in the app, kPa seems like rather a crude measurement (for reference, 1 kPa == 10 mbar == 7.5 mmHg). So I think the capability needs some refinement.

Have you tried removing the device from webCoRE and authorising it again? Only …

Clipboard01