http://www.gearbest.com/aqara-_gear/
Aqara Temp. sensor $8.99
Aqara Contact $6.99
Aqara Button switch $6.99
Xiaomi motion sensor $9.99
Xiaomi contact sensor $7.99
Xiaomi button switch $6.99
Xiaomi temperature sensor $8.99
http://www.gearbest.com/aqara-_gear/
Aqara Temp. sensor $8.99
Aqara Contact $6.99
Aqara Button switch $6.99
Xiaomi motion sensor $9.99
Xiaomi contact sensor $7.99
Xiaomi button switch $6.99
Xiaomi temperature sensor $8.99
I’m assuming as they are zigbee they (the sensors) will work in the US even though the switches and plugs are for the UK… Correct?
Yes the battery powered zigbee devices work in the US.
I have a lot of door sensors, motion sensors and temp sensors.
They work well. I have 3 that do not like to stay online.
I have 3 of these Aqara buttons, but cannot get them to work in any useful fashion.
I managed to get the ST hub to find them, then had to associate them with a device handler, so used the a4refillpad : Xiaomi Zigbee Button found on this community site (I couldn’t find anything more suitable).
The only event I can get them to sometimes respond to is a 4 second hold, the normal press seems to send through nothing.
They also seem to eventually drop off and become inactive after a few hours and cannot be restarted without completely removing and re-pairing.
Anybody had more success with these buttons?
Has anyone reported that the Aqara motion sensors work?
fyi “TWITTER” coupon code will currently get you %8 off.
I would like to know if those work as well. The addition of the holder make them a better choice for mounting. They also have built in illuminance detection, which will work better for lighting applications than the other Xiaomi motion sensors I previously purchased.
I have not tried the aqara motion sensors but I do have the aqara temp and aqara door sensors working. I had to make new device handlers for them. I have them on got hub. I might try to pickup an aqara motion sensor. But it would be a while before I got one.
I have a few aqara door and temp sensors on order do you mind sharing your device handlers for them, if you haven’t already?
I also have a few Aqara motion sensors on the order, Ill post my experience with them when they arrive.
My code is on git hub.
Thanks @ArstenA for the DH.
I tested and it is working for the Aqara Motion sensor except the intensity feature.
Anyone has implemented it?
regards
I tried to merge with another DH…but still getting 0 for the illuminance:
/**
http://www.apache.org/licenses/LICENSE-2.0
*/
metadata {
definition (name: “Xiaomi Aqara Motion Sensor Teste”, namespace: “a4refillpad”, author: “a4refillpad”) {
capability "Motion Sensor"
capability "Configuration"
capability "Battery"
capability "Sensor"
capability "Refresh"
capability "Health Check"
capability “Illuminance Measurement”
attribute "lastCheckin", "String"
attribute "lastMotion", "String"
fingerprint profileId: "0104", deviceId: "0104", inClusters: "0000, 0003, FFFF, 0019", outClusters: "0000, 0004, 0003, 0006, 0008, 0005, 0019", manufacturer: "LUMI", model: "lumi.sensor_motion", deviceJoinName: "Xiaomi Motion"
command "reset"
command "Refresh"
}
// simulator metadata
simulator {
status "dark": "illuminance: 8"
status "light": "illuminance: 300"
status "bright": "illuminance: 1000"
}
preferences {
input "motionReset", "number", title: "Number of seconds after the last reported activity to report that motion is inactive (in seconds). \n\n(The device will always remain blind to motion for 60seconds following first detected motion. This value just clears the 'active' status after the number of seconds you set here but the device will still remain blind for 60seconds in normal operation.)", description: "", value:120, displayDuringSetup: false
}
tiles(scale: 2) {
multiAttributeTile(name:"motion", type: "generic", width: 6, height: 4){
tileAttribute ("device.motion", key: "PRIMARY_CONTROL") {
attributeState "active", label:'motion', icon:"st.motion.motion.active", backgroundColor:"#00a0dc"
attributeState "inactive", label:'no motion', icon:"st.motion.motion.inactive", backgroundColor:"#ffffff"
}
tileAttribute("device.lastCheckin", key: "SECONDARY_CONTROL") {
attributeState("default", label:'Last Update: ${currentValue}',icon: "st.Health & Wellness.health9")
}
}
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"
}
standardTile("configure", "device.configure", inactiveLabel: false, width: 2, height: 2, decoration: "flat") {
state "configure", label:'', action:"configuration.configure", icon:"st.secondary.configure"
}
standardTile("reset", "device.reset", inactiveLabel: false, decoration: "flat", width: 2, height: 1) {
state "default", action:"reset", label: "Reset Motion"
}
standardTile("icon", "device.refresh", inactiveLabel: false, decoration: "flat", width: 4, height: 1) {
state "default", label:'Last Motion:', icon:"st.Entertainment.entertainment15"
}
valueTile("lastmotion", "device.lastMotion", decoration: "flat", inactiveLabel: false, width: 4, height: 1) {
state "default", label:'${currentValue}'
}
standardTile("refresh", "command.refresh", inactiveLabel: false) {
state "default", label:'refresh', action:"refresh.refresh", icon:"st.secondary.refresh-icon"
}
valueTile("illuminance", "device.illuminance", width: 2, height: 2) {
state("illuminance", label:'${currentValue}', unit:"lux"
)
}
main(["motion"])
details(["motion", "battery", "icon", "lastmotion", "reset", "refresh","illuminance"])
}
}
def parse(String description) {
def linkText = getLinkText(device)
log.debug “${linkText} Parsing: $description”
Map map = [:]
if (description?.startsWith('catchall:')) {
map = parseCatchAllMessage(description)
}
else if (description?.startsWith('read attr -')) {
map = parseReportAttributeMessage(description)
}
log.debug "${linkText} Parse returned: $map"
def result = map ? createEvent(map) : null
// send event for heartbeat
def now = new Date().format(“yyyy MMM dd EEE h:mm:ss a”, location.timeZone)
sendEvent(name: “lastCheckin”, value: now)
if (description?.startsWith('enroll request')) {
List cmds = enrollResponse()
log.debug "${linkText} enroll response: ${cmds}"
result = cmds?.collect { new physicalgraph.device.HubAction(it) }
}
if (description?.startsWith("illuminance: ")) {
def raw = description - "illuminance: "
if (raw.isNumber()) {
result = createEvent(
name: "illuminance",
value: Math.round(zigbee.lux(raw as Integer)).toString(),
unit: "lux"
)
}
log.debug "Parse returned ${result?.descriptionText}"
}
return result
}
private Map getBatteryResult(rawValue) {
//log.debug 'Battery’
def linkText = getLinkText(device)
//log.debug rawValue
def result = [
name: 'battery',
value: '--'
]
def volts = rawValue / 1
def maxVolts = 100
if (volts > maxVolts) {
volts = maxVolts
}
result.value = volts
result.descriptionText = "${linkText} battery was ${result.value}%"
return result
}
private Map parseCatchAllMessage(String description) {
def linkText = getLinkText(device)
Map resultMap = [:]
def cluster = zigbee.parse(description)
log.debug cluster
if (shouldProcessMessage(cluster)) {
switch(cluster.clusterId) {
case 0x0000:
resultMap = getBatteryResult(cluster.data.get(30))
break
case 0xFC02:
log.debug '${linkText}: ACCELERATION'
break
case 0x0402:
log.debug '${linkText}: TEMP'
// temp is last 2 data values. reverse to swap endian
String temp = cluster.data[-2..-1].reverse().collect { cluster.hex1(it) }.join()
def value = getTemperature(temp)
resultMap = getTemperatureResult(value)
break
}
}
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
}
def configure() {
def linkText = getLinkText(device)
String zigbeeEui = swapEndianHex(device.hub.zigbeeEui)
log.debug "${linkText}: ${device.deviceNetworkId}"
def endpointId = 1
log.debug "${linkText}: ${device.zigbeeId}"
log.debug "${linkText}: ${zigbeeEui}“
def configCmds = [
//battery reporting and heartbeat
"zdo bind 0x${device.deviceNetworkId} 1 ${endpointId} 1 {${device.zigbeeId}} {}”, “delay 200”,
“zcl global send-me-a-report 1 0x20 0x20 600 3600 {01}”, “delay 200”,
“send 0x${device.deviceNetworkId} 1 ${endpointId}”, “delay 1500”,
// Writes CIE attribute on end device to direct reports to the hub's EUID
"zcl global write 0x500 0x10 0xf0 {${zigbeeEui}}", "delay 200",
"send 0x${device.deviceNetworkId} 1 1", "delay 500",
]
log.debug "${linkText} configure: Write IAS CIE"
return configCmds
}
def enrollResponse() {
def linkText = getLinkText(device)
log.debug “${linkText}: Enrolling device into the IAS Zone”
[
// Enrolling device into the IAS Zone
"raw 0x500 {01 23 00 00 00}", “delay 200”,
“send 0x${device.deviceNetworkId} 1 1”
]
}
def refresh() {
def linkText = getLinkText(device)
log.debug “${linkText}: Refreshing Battery”
// def endpointId = 0x01
// [
// “st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0000 0x0000”, “delay 200”
// “st rattr 0x${device.deviceNetworkId} ${endpointId} 0x0000”, “delay 200”
// ] //+ enrollResponse()
zigbee.configureReporting(0x0001, 0x0021, 0x20, 300, 600, 0x01)
}
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 = [:]
def now = new Date().format("yyyy MMM dd EEE h:mm:ss a", location.timeZone)
if (descMap.cluster == "0001" && descMap.attrId == "0020") {
resultMap = getBatteryResult(Integer.parseInt(descMap.value, 16))
}
else if (descMap.cluster == "0406" && descMap.attrId == "0000") {
def value = descMap.value.endsWith("01") ? "active" : "inactive"
sendEvent(name: "lastMotion", value: now)
if (settings.motionReset == null || settings.motionReset == "" ) settings.motionReset = 120
if (value == "active") runIn(settings.motionReset, stopMotion)
resultMap = getMotionResult(value)
}
return resultMap
}
private Map parseCustomMessage(String description) {
Map resultMap = [:]
return resultMap
}
private Map parseIasMessage(String description) {
def linkText = getLinkText(device)
List parsedMsg = description.split(’ ')
String msgCode = parsedMsg[2]
Map resultMap = [:]
switch(msgCode) {
case '0x0020': // Closed/No Motion/Dry
resultMap = getMotionResult('inactive')
break
case '0x0021': // Open/Motion/Wet
resultMap = getMotionResult('active')
break
case '0x0022': // Tamper Alarm
log.debug '${linkText}: motion with tamper alarm'
resultMap = getMotionResult('active')
break
case '0x0023': // Battery Alarm
break
case '0x0024': // Supervision Report
log.debug '${linkText}: no motion with tamper alarm'
resultMap = getMotionResult('inactive')
break
case '0x0025': // Restore Report
break
case '0x0026': // Trouble/Failure
log.debug '${linkText}: motion with failure alarm'
resultMap = getMotionResult('active')
break
case '0x0028': // Test Mode
break
}
return resultMap
}
private Map getMotionResult(value) {
def linkText = getLinkText(device)
//log.debug "${linkText}: motion"
String descriptionText = value == ‘active’ ? “${linkText} detected motion” : "${linkText} motion has stopped"
def commands = [
name: ‘motion’,
value: value,
descriptionText: descriptionText
]
return commands
}
private byte[] reverseArray(byte[] array) {
byte tmp;
tmp = array[1];
array[1] = array[0];
array[0] = tmp;
return array
}
private String swapEndianHex(String hex) {
reverseArray(hex.decodeHex()).encodeHex()
}
def stopMotion() {
sendEvent(name:“motion”, value:“inactive”)
}
def reset() {
sendEvent(name:“motion”, value:“inactive”)
}
def installed() {
// Device wakes up every 1 hour, this interval allows us to miss one wakeup notification before marking offline
def linkText = getLinkText(device)
log.debug "${linkText}: Configured health checkInterval when installed()"
sendEvent(name: “checkInterval”, value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: “zigbee”, hubHardwareId: device.hub.hardwareID])
}
def updated() {
// Device wakes up every 1 hours, this interval allows us to miss one wakeup notification before marking offline
def linkText = getLinkText(device)
log.debug "${linkText}: Configured health checkInterval when updated()"
sendEvent(name: “checkInterval”, value: 2 * 60 * 60 + 2 * 60, displayed: false, data: [protocol: “zigbee”, hubHardwareId: device.hub.hardwareID])
}