bspranger / Xiaomi

my Xiaomi Device Handlers for Smartthings
Apache License 2.0
520 stars 1.36k forks source link

New BETA for Xiaomi Aqara Vibration sensor #124

Open veeceeoh opened 6 years ago

veeceeoh commented 6 years ago

I have uploaded the code for an initial beta release of a SmartThings device handler for the new Xiaomi Aqara Vibration Sensor (Model DJT11LM).

The new code can be viewed here.

I do not yet own an Aqara Vibration Sensor, so it is completely untested and needs beta testing by users who do own one. Please know that it will very likely generate errors in your log, and also not all planned features are implemented.

The initial features are as follows: • Vibration / Movement detections will generate a Motion - Active event • When the sensor is tilted, an Acceleration - Active event is generated • When the sensor is dropped, a Button 1 - pushed event is generated • The above three event types will be displayed as "Vibration Detected", "Tilt Detected", and "Drop Detected" in the main tile for the sensor in the SmartThings mobile app. If no other events occur within 61 seconds, the display will clear out with a grey background, meaning the sensor is motionless. • When the sensor is tilted, if the value of tilt angle change is reported, this will be displayed in the mobile app, and also in the events list and in live logging. It is not yet associated with any SmartThings capability so it cannot be used by any SmartApps other than WebCoRE. • After the sensor has moved, if a 3-axis value is reported, it will generate a Three-Axis event. The X, Y, Z values are the raw values given by the sensor in the range of -2048 to +2047. This feature needs more development to make it useful. • After vibration events, if the sensor reports the "level" of vibration, it will be displayed in small text at the bottom of the main tile for the sensor in the mobile app, as well as in the events list and in live logging. It is given as the raw reported value on a scale of 0-512. • The time/date of the most recent vibration, tilt, and drop events are displayed in smaller GUI tiles for the sensor in the mobile app • As with other bspranger/Xiaomi device handlers, the battery voltage and % level are reported and its replacement date is stored and displayed in a GUI tile for the sensor in the mobile app. • Preference Settings are similar to those in other bspranger/Xiaomi device handlers, but also include toggles for informational ("info") and debug log messages to be displayed in the Live Logging page of the IDE.

Any and all comments, suggestions, and bug reports are highly encouraged in order to improve this device handler and its functionality.

I'm tagging @oltman on this as he has also been working on device handler code. Hope you can take a look and see what may be improved, especially with regards to the 3-Axis Accelerometer data. Keep in mind I don't own one of these yet, so everything has been coded without any testing at all. Please go easy on me! :)

oltman commented 6 years ago

Thanks, Keith! 

I loaded the code and tried it--  One issue is that 'zigbee.getEvent(description)' does not return an event for the returns from this device.  So you never get into parseReadAttr() where all the action is for this device.  The bold line below (which I added in the code) returns the following two lines.  I assume this '[:]' means the result is empty...  Should the parseReadAttr() function be outside of the if (result) statement?  I'm a complete hacker and could make this work, by moving the parseReadAttr() outside of the if(result) function, but that may not make "good code".    I'll force the issue on my side and keep moving with testing. 

1be67764-59b9-4e66-9942-dc61b0fb1a1a 9:37:48 PM: debug Motion Sensor 2 parsing: read attr - raw: E9190101010E0505230000E400, dni: E919, endpoint: 01, cluster: 0101, size: 0E, attrId: 0505, encoding: 23, value: 00e40000 result = [:] 1be67764-59b9-4e66-9942-dc61b0fb1a1a 9:36:48 PM: debug Motion Sensor 2 parsing: read attr - raw: E9190101010E05052300009700, dni: E919, endpoint: 01, cluster: 0101, size: 0E, attrId: 0505, encoding: 23, value: 00970000 result = [:]

def parse(String description) {     displayDebugLog(": Parsing description: ${description}")     def result = zigbee.getEvent(description)     log.debug "${device.displayName} parsing: $description result = ${result)" //added by @oltman          // 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 - contact sensor & 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: "lastCheckinCoRE", value: nowDate, displayed: false)

    Map map = [:]

    // Send message data to appropriate parsing function based on the type of report     if (result) {         displayDebugLog(": Event = ${result}")         if (description?.startsWith('catchall:')) {             map = parseCatchAllMessage(description)         }         else if (description?.startsWith('read attr - raw:')) {             map = parseReadAttr(description)         }         displayDebugLog(": Parse returned ${map}")         def results = map ? createEvent(map) : null         return results     } }

Best Regards, Randy

Randy L. Oltman m:  732 513 1553

On Thursday, September 13, 2018, 8:47:45 PM EDT, Keith G <notifications@github.com> wrote:  

I have uploaded the code for an initial beta release of a SmartThings device handler for the new Xiaomi Aqara Vibration Sensor (Model DJT11LM).

I do not yet own one an Aqara Vibration Sensor, so it is completely untested and needs beta testing by users who do own one. Please know that it will very likely generate errors in your log, and also not all planned features are implemented.

The initial features are as follows: • Vibration / Movement detections will generate a Motion - Active event • When the sensor is tilted, an Acceleration - Active event is generated • When the sensor is dropped, a Button 1 - pushed event is generated • The above three event types will be displayed as "Vibration Detected", "Tilt Detected", and "Drop Detected" in the main tile for the sensor in the SmartThings mobile app. If no other events occur within 61 seconds, the display will clear out with a grey background, meaning the sensor is motionless. • When the sensor is tilted, if the value of tilt angle change is reported, this will be displayed in the mobile app, and also in the events list and in live logging. It is not yet associated with any SmartThings capability so it cannot be used by any SmartApps other than WebCoRE. • After the sensor has moved, if a 3-axis value is reported, it will generate a Three-Axis event. The X, Y, Z values are the raw values given by the sensor in the range of -2048 to +2047. This feature needs more development to make it useful. • After vibration events, if the sensor reports the "level" of vibration, it will be displayed in small text at the bottom of the main tile for the sensor in the mobile app, as well as in the events list and in live logging. It is given as the raw reported value on a scale of 0-512. • The time/date of the most recent vibration, tilt, and drop events are displayed in smaller GUI tiles for the sensor in the mobile app • As with other bspranger/Xiaomi device handlers, the battery voltage and % level are reported and its replacement date is stored and displayed in a GUI tile for the sensor in the mobile app. • Preference Settings are similar to those in other bspranger/Xiaomi device handlers, but also include toggles for informational ("info") and debug log messages to be displayed in the Live Logging page of the IDE.

Any and all comments, suggestions, and bug reports are highly encouraged in order to improve this device handler and its functionality.

I'm tagging @oltman on this as he has also been working on device handler code. Hope you can take a look and see what may be improved, especially with regards to the 3-Axis Accelerometer data. Keep in mind I don't own one of these yet, so everything has been coded without any testing at all. Please go easy on me! :)

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

veeceeoh commented 6 years ago

Hi Randy! Thanks for taking a look.

I was wondering about whether using zigbee.getEvent would work or not. I've removed it and the conditional based on it completely, following the format from the Aqara Button DTH I helped improved. That should get the attribute report messages recognized.

Also - By all means feel free to submit a pull request for any changes you think it really needs, and then we can go over it.

oltman commented 6 years ago

I just made if if(1) and moved on.  fix that later and work on the rest of the parsing...

Best Regards, Randy

On Thursday, September 13, 2018, 10:04:12 PM EDT, Keith G <notifications@github.com> wrote:  

Hi Randy! Thanks for taking a look.

I was wondering about whether using zigbee.getEvent would work or not. I've removed it and the conditional based on it completely, following the format from the Aqara Button DTH I helped improved. That should get the attribute report messages recognized.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

oltman commented 6 years ago

This code will parse the accelerometer values correctly.   (around line 226).  

                Integer x = Integer.parseInt(value.substring(8,11),16)  //@oltman                 Integer y = Integer.parseInt(value.substring(4,8),16)   //@oltman                 Integer z = Integer.parseInt(value.substring(0,4),16)   //@oltman                 if (x>=32768) x=x-65535   //converter twos complement negative numbers to negative integers @oltman                 if (y>=32768) y=y-65535   //converter twos complement negative numbers to negative integers @oltman                 if (z>=32768) z=z-65535   //converter twos complement negative numbers to negative integers @oltman

After making the above change and the previous one, I get g values on the UI. 

By the way, I am happy to send you my hacked code which actually creates angles out of the g sensor.  You can also store 'open' and 'close' positions and the DH will report whether the device is in the open or closed positions.  Unfortunately, this is all text and needs to be turned into proper switch code so that it can be used with other smartthings smartapps, etc.  I haven't done all that yet. 

See the attached, I'd rather not formally upload this because it doesn't respect proper copyright, authorship, etc. so please forgive the fact that this is a blatant adaptation of other bspraner/Xiaomi code.  I've never uploaded to GitHub and want to respect the prior authors work and have not taken the time to figure out the appropriate 'rules of the road'

Best Regards,

On Thursday, September 13, 2018, 10:04:12 PM EDT, Keith G <notifications@github.com> wrote:  

Hi Randy! Thanks for taking a look.

I was wondering about whether using zigbee.getEvent would work or not. I've removed it and the conditional based on it completely, following the format from the Aqara Button DTH I helped improved. That should get the attribute report messages recognized.

— You are receiving this because you were mentioned. Reply to this email directly, view it on GitHub, or mute the thread.

veeceeoh commented 6 years ago

This code will parse the accelerometer values correctly. (around line 226).

But those are 16-bit two's complements, and there's strong indications the X,Y,Z values are 12-bit 2's C. I haven't dug into what SmartThings' three-axis capability is expecting for a range on each axis, though. As an aside, there's the problem of three-axis not being on the list of supported capabilities for the new SmartThings App. It's not clear if using it to post events is that useful, especially if the capability is going to be depreciated.

By the way, I am happy to send you my hacked code which actually creates angles out of the g sensor. You can also store 'open' and 'close' positions and the DH will report whether the device is in the open or closed positions.

If the DTH takes care of all that using preference settings, for example, then it could be linked to the open/close contact capability. This is the main challenge - making the data useful in terms of events that the majority of SmartApps recognize, rather than custom attributes that can only be used in WebCoRE.

See the attached, I'd rather not formally upload this because it doesn't respect proper copyright, authorship, etc. so please forgive the fact that this is a blatant adaptation of other bspraner/Xiaomi code.

I didn't see any attachment. As for copyright, see the Apache License, which is pretty loose in its terms. Nobody receives ant other gain than to have better access to use of these devices by collaboration on the code. There's nothing groundbreaking being done here. My main goal besides opening up maximum functionality is that the DTH aesthetically and functionally similar to the other device handlers in the bspranger/Xiaomi collection.

EDIT:

You can also store 'open' and 'close' positions and the DH will report whether the device is in the open or closed positions. Unfortunately, this is all text and needs to be turned into proper switch code so that it can be used with other smartthings smartapps, etc. I haven't done all that yet.

Giving it some thought, the contact sensor capability is probably the best choice to link this to. But then the open / close position values would need to be set by the user in the preference settings, either by entering in a value for each, or possibly through temporary toggles ("Press this toggle to save sensor's Open position"). But doing this would leave the sensor's built-in tilt angle change value reporting feature without an suitable ST capability to link it to.

oltman commented 6 years ago

For string opps, .substring(a,b) is inclusive of 'a' but exclusive of 'b', so you get indexes in the range [a..b).  So it is three hex characters being passed to the parseInt function.  took me a while to figure that out. 

A couple other thoughts... I stopped using the three axis data type.  Once I put the three values into three axis, I couldn't find a way to access them individually for calculations without throwing java errors (even after heavy googling of java code, etc.  fully admit this should be possible).  I finally threw up my hands and just stored computed angle values instead. 

We might want to discuss use cases-- is it valuable to return the actual g values and/or tilt or is it more valuable to remember a position and tell the user what position the sensor is in.  Then the device handler would have 2-3 types of reports:  

I'm currently using the Door Control data type because it allows for open, closed, and unknown.  However, I am finding that the smartlighting doesn't seem to be integrated with door control.  Any suggestions? EDIT: just saw your edit that contact sensor might be better. agree. Then its almost as if you have to save the closed position and everything else is considered open.

veeceeoh commented 6 years ago

I have updated the code with some changes, now at v0.6b

Changes

I haven't yet changed the code that converts the Accelerometer XYZ axis value reports, while it's determined how to best make use of the data.

For string opps, .substring(a,b) is inclusive of 'a' but exclusive of 'b', so you get indexes in the range [a..b). So it is three hex characters being passed to the parseInt function. took me a while to figure that out.

Hmm, that's a bit non-intuitive, but very helpful to know, thanks! Since I still haven't actually received any attachment with your code-in-progress, I'm curious if it takes into account the different g ranges represented by the accelerometer XYZ axis values when the sensitivity level is changed?

A couple other thoughts... I stopped using the three axis data type. Once I put the three values into three axis, I couldn't find a way to access them individually for calculations without throwing java errors (even after heavy googling of java code, etc. fully admit this should be possible). I finally threw up my hands and just stored computed angle values instead.

To be honest, I haven't looked for any examples of SmartApps which make use of events from the three axis capability. And it's apparently being depreciated anyhow.

We might want to discuss use cases-- is it valuable to return the actual g values and/or tilt or is it more valuable to remember a position and tell the user what position the sensor is in.

I'm sure some nerdy people will love to see the g values in live logging, but it's much more useful if the DTH could be coded to store user-set "open" and "close" positions. I'm envisioning something as basic as pressing one of the GUI Tiles to set each of those, and then open / close events using the contact sensor capability would be sent when either position is reached (or within a certain range of that position because it won't be the exact same values every time.)

  • motion sensor (active / inactive)
    • motion type (drop, vibe, tilt)

The only choices I see of capabilities / data types that will continue to exist in the new mobile app are motion, acceleration, and button. Of there three functions, vibration/motion is the only one that can be continuous (or at least it generates repeated attribute reports) and drop / tilt are one-at-a-time events. The acceleration capability has active/inactive states, so as I've assigned it to tilt in my DTH code, I have to use runIn() to reset the state to inactive after about a minute. (The same is true for vibration events, but if they happen repeatedly, the motion active state will persist. For Drop, I used button because it just has the pressed state, and there's no "released" state. So it can be used as a trigger (as opposed to a condition) for HA logic in SmartApps.

  • Door Control?

I shy away from this capability because it allows both output (to control the door) and input (on the reported state of the door). So SmartApps will see this DTH as giving control over the sensor's position, and will present those options in the setup of said SmartApps which could confuse users.

oltman commented 6 years ago

@veeceeoh what is the simplest way to upload code? Apologies, but I was responding through email rather than the web interface of GitHub. (you really are dealing with a newbie). Anyway, attached is the working device handler code I am now using for my garage door vibration sensor.

I'm happy to keep testing yours and refining or switching to mine with your refinements. I am fully on board with making these all look like the ones from bspranger as those are already super-helpful and intuitive as a repository.

The file attached is a severe modification of other bspranger work. My name is on as author, but, again, have no need for ownership and want to respect all the work of people before this for which the following would not be possible. This is a fully working/tested device handler. although the UI could use some work. It uses the three-axis and door control and contact sensor data types. Choose which one works for you... You can store open and close positions. it will register open and closed when within 10 degrees of where the register open/close was registered (each axis needs to meet that threshold). I couldn;t figure out how to upload to bspranger/Xiaomi.

The attachment: Vibration_Sensor_rlo2.txt

veeceeoh commented 6 years ago

@oltman - Sorry, was out of town for a couple days. Uploading code is only possible to repositories you have access to, which at a minimum includes your own, of course. I've been using the GitHub Desktop app for managing a local mirror of repositories in conjunction with Atom as an editor (and it plays well with local GitHub repositories.) I imagine with the relative complexity of this particular Xiaomi device, there will be a number of different DTH offerings which work in different ways. So I'd say if interested in sharing the DTH you settle on for your personal, try creating a GitHub repository! Normally, though the way collaborations on code works is to create a Pull Request with suggested edits. This avoids the current code from being overwritten until everyone agrees on the changes, and Pull Requests have their own discussion threads for the purpose of talking about them.

That said, if I have your blessings, it would be wonderful to incorporate your Accelerometer output -> position code into whatever the final form of the bspranger/Xiaomi DTH for this sensor comes out to be.

This time around, I'm able to download the attachment, but I see that it's visible to anyone reading this discussion. I'm not sure if that's what you intended. I will have a look, but I think at this point I need to wait until my two sensors I ordered are actually in my hands so I can test it out.

The UI for these DTHs is something I enjoy working on, but this device presents so much data that it's going to be a challenge to find a balance between simplicity and present all information that people would like to have handy access to.

oltman commented 5 years ago

@veeceeoh feel free to use any of that code at will in the updated driver. My intention was to upload here. I will eventually delete that attachment from the comment and point to the final code on the bspranger/Xiaomi github location.

veeceeoh commented 5 years ago

@oltman - Great, thank you! I have just released a new beta DTH version which properly handles vibration/shock, tilt, and drop events, with built-in timers using runOnce() to reset motion to inactive (for vibration/tilt) and acceleration to inactive (for tilt) as well as clearing the main UI tile back to displaying "Stationary." It's all working quite well, and stable enough that my next step will be to incorporate your code to implement the open/close functionality in the DTH, though I still plan to link it to the contact sensor capability.

My SmartThings Community Forums post with more details about newest beta version of the DTH can be viewed here.

veeceeoh commented 5 years ago

Just in case anyone is actually reading this comment thread, I posted an updated version of the beta DTH a few days ago. Now at v0.9b, the code to convert the sensors raw 3-axis data to angles and store user-set open/closed positions by @oltman has been integrated and fully implemented. Also, I have reorganized and cleaned up the UI, and made other improvements and fixes. I feel it's all working quite well, and pretty close to being out of beta.

Detailed notes with screenshots can be viewed in this post on the SmartThings Community Forums.

Many thanks again to @oltman for the code contributions!

veeceeoh commented 5 years ago

I might finally get the vibration solution I need for my dryer

To be honest, I'm not sure it's a good solution for clothes washer / dryer load cycle detection. I have tried placing both of my sensors on my washer while in operation, and the only reports I saw were activity level values - and those are infrequent and inconsistent in their timing. No vibration detected reports were sent at all.

This might have to do with the sensitivity setting, but I still haven't been able to confirm that sending the command to change it from the device handler is actually working.

By the way, @alecm - it looks like you sent your reply via e-mail, and so your signature with cell number and e-mail are showing up in this publicly accessible comment thread. Just thought you might want to be aware of that.

alecm commented 5 years ago

@veeceeoh - thanks for the heads up both on using it for dryer and about my cell phone, etc..

harr2969 commented 4 years ago

@veeceeoh - I appreciate the info and your contributions – does setting the sensitivity work yet? or perhaps can it be changed manually? I would be willing to send $ your way to buy one from gearbest if that helps and you don't have one yet. (https://www.gearbest.com/smart-access-lock/pp_009824810051.html?wid=1433363)