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

It was an extra comma in the test Aqara motion sensor DTH that wasn’t supposed to be there, and has been fixed.

For anyone trying these soon-to-be-released updates, please remember they are still being tested, so although the code is considered “ready to test”, we’re making adjustments here and there, and so should be considered as “beta”.

The links I’ve been sharing to the grab the updated test DTH code are to what’s called a “Pull Request” which is how to manage an update to a repository before it has been tested. It is temporary, however, and when it’s decided the code is good to use by everyone, it gets “merged” (overwrites) into the main repository.

So when the new versions are ready for release we will definitely replace the bspranger/Xiaomi collection of device handlers with the updated code on GitHub, and make an announcement with a description of all fixes / improvements.

After that, the links to test code will not work anymore.

Fix worked for me. Thanks!

1 Like

I keep my house at 18 in the day and 19 at night. I guess British Columbia is like Scotland. We are all perfectly comfy :wink:

On the Aqara motion detector is there a way to set the sensitivity, it seems vary sensitive.

My house is kept at 20.556 C or 69 F during the day and 17.778 c or 64 F at night.

Announcing: Update to v1.0 for all Xiaomi device handlers (except ZigBee Outlet)

Available now from the bspranger/Xiaomi repository on GitHub.

Change & Fixes:

All Xiaomi device handlers
Preferences Page
• Now standardized across all device handlers
• Reorganized preference settings into groups with headings
• Added notes to clarify some settings

• Battery reporting now standardized across all device handlers
• Improved code to avoid incorrect reported values
• Battery Changed date automatically set when device is paired

• Removed display of Last Checkin events from “Recently” tab of mobile app
• Removed unnecessary debug log messages displayed to Live Logging in IDE
• Added new informative debug log messages to some DTHs

• Centered smaller tiles displayed in user interface
• Renamed “Last Checkin” tile to “Last Event”
• All preference setting defaults are handled correctly
• Fixed / removed all code known to cause errors
• Cleaned up / organized code
• Code is better documented with comments to help others understand how it works
• Removed outdated change log in header section (refer to GitHub for history of all changes)

Button device handlers
• “Held” button mode now called “Momentary”
• Unused time setting removed from “original” Xiaomi button preferences

Door / Window sensor device handlers
• Improved responsiveness of open/close events
• Last Opened date no longer displays time of close events

Motion Detector sensor device handlers
• The motion detected preference setting now works correctly

Temperature / Humidity sensor device handlers
• Added option to record and display temperature in main tile as integer (takes effect on next temp report)
• Added daily high/low temperature & humidity tracking
• Added preferences to display daily high/low temp and/or humidity in main tile
• Changed temperature offset preference to allow decimal values to 0.1 precision


Last Checkin
Prior to this update, whenever sensor sent any report, at the same time Last Checkin date/time event was also recorded and displayed in the events log / Recently tab of the mobile app. However Xiaomi devices never actually “check in”, and so the lastCheckin events are basically redundant and cluttering up the Recently tab.

The best and only way to know if your idle Xiaomi device is still connected is battery reports. All Xiaomi devices send a battery report roughly every 50-60 minutes. I have seen single missed battery reports a few times with my dozen Xiaomi sensors, so I’d say if there hasn’t been any battery reports for 2 hours, then check whether the sensor is still connected by a short-press of its reset button. That will send a message that will show up in the SmartThings IDE Live Logging page, if the sensor is still connected.

Despite the removal of lastCheckin events being displayed, they are still logged as a state change and can be viewed in IDE > Devices > your device and click lastCheckin in the Current States section of the page. Also, lastCheckin is still used for the renamed “Last Event” tile displayed in the UI for any Xiaomi device in the ST mobile app. So a quick look at that tile will tell you when the device last sent any report to the hub.

Button modes
On both the “original” Xiaomi and Aqara buttons, two modes are available: Momentary and Toggle. Toggle works the same with both buttons - every time the button is pressed, the device handler alternates between pushed & released.

However, the Momentary mode works differently on each of the two types of buttons. The “original” Xiaomi button sends a pushed message to the hub when the button is pressed, and when the button is released, it sends a released message. So the Momentary mode in the “original” Xiaomi button device handler just passes on that information to SmartThings, and then either the devices you control or SmartApps can be set to do different actions based on how long the button is held for.

On the other hand, the Aqara button only sends a pushed message to the hub when it is pressed. So there is no way to know how long an Aqara button is held, because it does not send a released message. Because of this, the Momentary mode in the Aqara button device handler has to emulate a hold and release action by using a customizable timer. The length of time until the released message is sent to the hub by the device handler can be set in the preference setting called “Minimum time in seconds for a press to clear”. If Momentary mode is selected, and the “Minimum time…” preference is set to 5 seconds, when the button is pressed, SmartThings will see that it remains pushed for 5 seconds, and then released.

Motion Sensors
In normal operation both types of Xiaomi Motion Sensors are “blind” for 60 seconds after they detect motion, in order to save on battery usage. After 60 seconds, the hardware resets and is ready to detect motion again. This 60 second reset delay cannot be changed. However, in the device handler, there is a preference setting to change how long the “motion detected” state remains active, called MOTION RESET. The default is the same as the hardware delay, but it can be changed to any length of time, longer or shorter. Just remember that this setting only affects how long Motion Detected is reported to SmartThings.

NOTE: When first paired to a hub, both types of Motion Sensors run in test mode, for about 2 hours. During the test mode, the sensor can detect motion every 3-5 seconds, which can be useful for deciding the best placement of the sensor. During test mode, we recommend setting the MOTION RESET setting to 6-8 seconds to make it easier to determine whether the sensor is working well at the location you have chosen. After finishing with testing, then the MOTION RESET setting can be changed to a different length of time, according to your preference. Finally, the Aqara motion sensor can also be manually put into test mode for about 2 hours, by a short-press of the hardware reset button.

Temperature / Humidity sensors
The standard method of SmartThings temperature sensor device handlers is to display temperatures as integers, so we have added this capability as an option. The default is the same as before, displaying the reported temperature with 0.1 precision. When the “display as integer” option is changed, it will take effect on the next temperature report from the sensor.

The new daily high/low temperature and humidity feature allows the display of one, both, or neither sets of high/low temperatures and humidity percentages at the bottom of the main tile. The high/low temperatures are only displayed as integers because when displayed with the high/low humidity, there isn’t enough room to keep all the information on one line. The device handler resets both sets of high/low between midnight and 1:00 in the morning every day, and will update all values even if the display isn’t active. Note that the high/low display is designed for convenience. For long-term recording of changes in temperature and humidity, its recommended to use a SmartApp such as Simple Event Logger.

As with any major update of software, there is a good chance that something was missed, so please feel free to post any questions or feedback.


Excellent work and your write up is brilliant.
Great job and thanks.

Great work!

For the original Xiaomi button, would it be possible to reproduce the “held” action from a4refillpads old handler?

I’m thinking something like for the momentary mode, if time between pushed and released is greater then x (user variable), then report held. I can see the problem with the current implementation though, as pushed is reported instantly and not at release.

Anyway, a nice to have! I can always use the old handler, or emulate the behaviour in Webcore to some extent. :slight_smile:

Excellent work!
Thank you to all for the hard work.


I still use the old DTH as I have always had functionality on the HELD event. I miss that on the new Aqara buttons.

That code could be used, yes, but I’m looking at it now, and don’t see how it would work properly.

When the button is pressed, a function is called immediately that checks the time difference between when the button was pressed and the current time. Because the code runs almost instantly, it would see that the time difference is just some milliseconds, and set the status to “pushed”.

But then the function doesn’t get called again. There’s no loop to keep checking how long since the button was pressed.

Also, are there other button device handers with this feature? Why can’t WebCoRE handler the timer to decide when to consider the button as “held” instead of “pushed”?

Sorry for the questions, but I only have the Xiaomi 2-switch zigbee wall-mounted button, which works the same as the Aqara button (so it never sends a “released” message) and can’t do any testing.

You are missing some capability in your DTH:
capability "Holdable Button"
capability "Actuator"
capability “Switch”

also, the check routine is called when the button is released (not pressed) so it will check how long it was held since the last press; if it was more than defined value value, it will send the held event.

If I read the code correctly, “createButtonEvent” is called at release while “createPressEvent” is called at press. “createButtonEvent” then uses the timestamp set by “createPressEvent” (in lastPress) to determine the duration between push and release.

You are right, this could proably be solved in Webcore by looking for “pushed” and “released”, and then using timers to decide between different actions. For me, it’s mostly that I then have to rewrite a lot of pistons, and that the inherent delay in Webcore probably will make it a bit extra complex.

But, it’s really not a big issue. The old handler mostly works fine, it’s just a bit rough without all bells and whistles, and tends to miss events sometimes - something I dont experience with the new one.

Just to be clear: These DTH (device handlers) are the product of a group effort, with @ArstenA having started the work of updating the a4refillpad Xiaomi DTH code and expanding to create new DTHs for the Aqara series of sensors.

Personally, I focused on helping improve the temperature / humidity sensor and motion sensor DTHs as part of this update. I don’t have an “original” Xiaomi button, and until this morning had not looked closely at the original a4refillpad DTH code for it.

I’d love to help return the “held” button functionality from the a4refillpad “original” Xiaomi button DTH to the new one that is in the bspranger/Xiaomi GitHub repository, but I need to understand what behaviors users are expecting or hoping for.

As I understand it from reading the Developer Docs and many Community Forum posts, the Switch capability is for devices that directly control something (not through the hub.) Most often they are mains-powered, for example socket switched, or mount-in-wall mains-powered light switches/dimmers. A Switch can both receive on/off commands from the hub, and send messages about it’s on/off state so it could also be used to control devices via the hub.

As for the other two capabilities, sure, they can be added.

Okay, I can see this now that I have had more time to look through the code.

What doesn’t make sense to me is that the “held” message is only sent when the button is released. If the preference is set to 1 second, and I hold the button for 10 seconds, nothing based on a “held” message happens for 10 seconds, until I release the button.

It would be much better to send a “held” message right at the number of seconds the user has set in preferences and then send a “release” message when the button is released.

Then actions such as
• short press = turn on light, and
• long press = raise the brightness, until button release
could be performed.

However, if users just want to put the a4refillpad functionality back in, then okay. I can have a look at how to make sure it works without missing events as @emilakered mentioned.


The mijia buttons natively support multipress action too, a4 never had this implimented though. I think they work all the way up to 4 clicking. I have some of these If you want any help. The aqara buttons are kinda featureless in comparison to the originals.

Unfortunately although both Xiaomi buttons support multi-press in hardware, the SmartThings ZigBee parser strips out the information that the device handler can use to know the number of presses.

All the device handler receives from SmartThings is “On/Off: 0” (pressed) and “On/Off: 1” (released) for the “original” Xiaomi button, and from the Aqara button, only “On/Off: 1” (pressed).

Any multi-press functionality would have be simulated in the device handler code.

1 Like

We can’t access a known value on a known attribute for a known cluster? Smarthings isn’t helping here.

1 Like

Well, I’m happy with and grateful for any solution! :slight_smile:

I don’t know the language that DTH:s are written in, and I haven’t really programmed for a decade. So, I’m not much of a help, although I can read the code and understand most of the intended function.

I guess the reason for the wait until “released” in the original handler is that it is a “quick and easy” way to always send the right command. On release, just check if it is a “push” or a “hold” according to the parameters, then send it.

Your solutions sounds great as well! The only thing I can think of is that, as the DTH works now, it would send a “pushed”, followed by a “held” after the specified waiting time? As I use the buttons now, I control two lights with the same one - for example, a push cycles one lamp between on and off, and a hold cycles another lamp. I also use push for cycling lamps in a room, and hold for turning on night mode (at my bedside).

Maybe we need a third “Pushed/Held” mode, where the actual command is always sent att either release or when the specified pushed timer has passed? So to avoid sending “double” commands.

I’m happy for everything you guys can do! I believe that there are many more out that that, like me, has set up routines and actions based on the original pushed/held behaviour that would be very grateful for a more polished DTH in line with the other ones. :slight_smile:

The data that is being filtered out is the source endpoint data. A number of Xiaomi devices send reports from the same cluster/attribute but on multiple endpoints.

Not necessarily. I can use a runIn() function to set a countdown timer instead of the method of comparing “pressed” versus “released” time used in the a4refillpad DTH.

So if the device handler receives a “pressed” message from the button, it starts the runIn() countdown based on the user-set preference. At this time, no message is sent to the hub.

If the button is released before the runIn() countdown is finished, then the device handler tells the hub the button was “pressed.” So that would tell your Piston to toggle Lamp A on or off.

If the button hasn’t yet been released when the runIn() countdown is finished, then the device handler would tell the hub the button was “held.” That tells your Piston to toggle Lamp B on or off.

Then… (additional feature), when you finally release the button, a “released” message is sent to the hub. In your situation, you just ignore the message, but for other people it could be used to set up a piston to start dimming a light on “held”, and stop dimming on “released”. So the button could be used for setting the brightness of a light/group of lights.

Make sense?