SmartThings Community

Notify if lock opened with a particular code


(Morgan) #10

Ah the device type examples has some good code in it. I’ll see if I can hack up my app to get it to work to send a notification when a particular user code is used to unlock the lock.


(Rikard Lundqvist) #11

I have a Schlage lock and the number of the code used to unlock the lock can be extracted from both evt.data and evt.descriptionText.

BTW: Can somebody explain why it appears that the format of evt.data have changed in the last month? Had to go through all SmartApps to change the parsing. Also, is there a better way to parse {“userCode”:3} than to simply compare the whole string or parse out the number? Both methods are quite crude and gives “ugly” code that is prone to stop working as soon as anything is changed. Is there a parser “function” that already takes care of this?


(Tod) #12

@rikard - I agree, it is ugly, and I hope ST creates a better way to obtain the userCode.

For reference to anyone else looking to do the same - first I did just a compare with the evt.descriptionText - but I ended up switching it to a little more dynamic method.

My app changes the mode based on a specific usedCode, triggered by a lock event on an assigned lock. In my case, 2 is the usedCode that is assigned to security code that is used to unlock the door. I set that as a number, which entered in with the preferences on install (along with the lock and the newMode).


def LockHandler(evt) {
if (evt.value == “unlocked”) {
if (evt.data == ‘{“usedCode”:’+code1+’}’ && location.mode != newMode)
{
setLocationMode(newMode)
}
}

Painful, yes - but it gets the job done.


(Florian Z) #13

No need to reinvent the wheel. The data is formatted as a JSON string, and Groovy comes with a json parser:

def data = new JsonSlurper().parseText(evt.data)
log.debug data.usedCode

Make sure to import the JsonSlurper. This line should come before the metadata section:

import groovy.json.JsonSlurper

(Morgan) #14

Has anyone got this to work with the Kwik 910 z-wave lock?


(Tod) #15

@thrash99er - yep, mine is a Kwikset lock, same model as yours. I got it working with the code I wrote and provided above. If you need more detail let me know. I have not revised it to use @FlorianZ’s approach though, I figured it was working, but if I modify it in the future, I’ll use it.


(Alex) #16

@todbrock, @florianz

How do I access “data” property of an event?

When I call evt.data, I get an error “No such property data for class Event”.


(Greg) #17

can anyone post the entire code for this? want to use it with a Schlage Camelot Touchscreen


(Chris Cooney) #18

At one point with this logic I was able to get a notification, but when I tried to also change the mode, I messed something up. Now this doesn’t seem to work, but I imagine it’s something very small because it does compile properly. You can use this as a guide, but it doesn’t appear to do anything in its current form, and I’ve had it…

definition(
name: “Notify Me When Cleaners Open Door”,
namespace: “”,
author: “CCooney”,
description: “Notifies when a specific user code is used on door.”,
category: “Safety & Security”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience%402x.png”)

preferences
{
section(“When a door unlocks…”) {
input “lock1”, “capability.lock”
}
section(“And this user opened the door:”){
input “User1”, “enum”, title: “User Code”, metadata:[values:[“1”,“2”,“3”,“4”,“5”]]
}
section(“Send this message (optional, sends standard status message if not specified)”){
input “messageText”, “text”, title: “Message Text”, required: false
}
section( “Notifications” ) {
input “sendPushMessage”, “enum”, title: “Send a push notification?”, metadata:[values:[“Yes”,“No”]], required:false
input “phone”, “phone”, title: “Send a Text Message?”, required: false
}
section(“And change to this mode”) {
input “newMode”, “mode”, title: “Mode?”, required: false
}

}

def installed() {
log.debug "Installed with settings: ${settings}"
subscribeToEvents()
}

def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribeToEvents()
}

def subscribeToEvents() {

log.debug "Settings: ${settings}"
subscribe(lock1, "lock", eventHandler)

}

def eventHandler(evt) {
if (evt.value == “unlocked”) {
if (evt.data == ‘{“usedCode”:’+User1+’}’)
{ send(evt) }

}}
private send(evt) {
if ( sendPushMessage != “No” ) {
log.debug( “sending push message” )
sendPush( msg )
}

if ( phone ) {
	log.debug( "sending text message" )
	sendSms( phone, msg )
}

log.debug msg

}


(Barry) #19

This might be of interest:


#20

Thanks, chriscooney, that’s just what I needed. I think the reason your version isn’t working is that you store the text of the message in messageText, and then call sendPush or sendSms with msg instead.


(Chris Cooney) #21

Ah, thanks. That did the trick. I appreciate the feedback. So here’s my pretty brute-force solution to my specific need. I tried the Unlock Too program from Barry, but it was doing some odd behaviors - setting then re-setting the mode. So this just sends a message and sets your mode when a specific lock code is used.

I have an open/close sensor on my door as well, and I was pleased to see the mode change occurs in the proper sequence so the alarm doesn’t go off because of the open/close sensor… that would be an unwelcome surprise for the cleaners.

/**

  • Cleaners have arrived
  • Copyright 2014 Chris Cooney
  • 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.

*/
definition(
name: “Cleaners have arrived”,
namespace: "cooney.christopher@gmail.com",
author: “Chris Cooney”,
description: “Sends a message and sets status when a particular user code is used on a door lock”,
category: “My Apps”,
iconUrl: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png”,
iconX2Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”)

preferences
{
section(“When a door unlocks…”) {
input “lock1”, “capability.lock”
}
section(“And this user opened the door:”){
input “User1”, “enum”, title: “User Code”, metadata:[values:[“1”,“2”,“3”,“4”,“5”]]
}
section(“Send this message (optional, sends standard status message if not specified)”){
input “msg”, “text”, title: “Message Text”, required: false
}
section( “Notifications” ) {
input “sendPushMessage”, “enum”, title: “Send a push notification?”, metadata:[values:[“Yes”,“No”]], required:false
input “phone”, “phone”, title: “Send a Text Message?”, required: false
}
section(“And change to this mode”) {
input “newMode”, “mode”, title: “Mode?”, required: false
}

}

def installed() {
log.debug "Installed with settings: ${settings}"
subscribeToEvents()
}

def updated() {
log.debug "Updated with settings: ${settings}"
unsubscribe()
subscribeToEvents()
}

def subscribeToEvents() {

log.debug "Settings: ${settings}"
subscribe(lock1, “lock”, eventHandler)
}

def eventHandler(evt) {
if (evt.value == “unlocked”) {
if (evt.data == ‘{“usedCode”:’+User1+’}’)
{
setLocationMode(newMode)
send(evt)}

}}
private send(evt) {
if ( sendPushMessage != “No” ) {
log.debug( “sending push message” )
sendPush( msg )
}

if ( phone ) {
log.debug( “sending text message” )
sendSms( phone, msg )
}
log.debug msg
}


#22

Was anyone able to get this to work with a Schlage deadbolt (using custom device type)? It appears that the evt.data isn’t populated?

Is there a way to trigger this using the descriptionText?

Appreciate the help!


(Fast, Good, Cheap...pick two.) #23

I too am interested for Schlage locks


(Barry) #24

The potential problem in this above code is that the method for identifying the usedCode depends on the lock sending EXACTLY {“usedCode”:1} for code 1. If the lock sends {“usedCode”:01} instead, you won’t get a match.

The more general approach is the one used in my Home on Code Unlock Too, which converts the code into an Integer for the comparison rather than depending upon specific hard strings.

I’m interested to hear more about the problems you may have had with my SmartApp - I’m happy to fix things if htey’re broken, especially since it was EXACTLY this use case that led me to create Home on Code Unlock in the first place.

http://community.smartthings.com/t/new-home-on-code-unlock-too/4451/51#

FWIW, my backlog for this SmartApp includes a “NotifyOnly” mode (for those that don’t want to change modes), an added BatteryLevel warning before the lock actually dies out, and possibly multiple failed-attempt Notifications. There is also a request to implement code scheduling, which would add/delete codes based on a schedule…this one is a major undertaking, but it is intriguing for those who want to make sure that their cleaning people only come on Thursday afternoons, for example.


(ChrisN) #25

Hi all,

Thanks for the great discussion so far. Barry - I took a look at your app, but it didn’t quite fit my scenario. I have several different door codes, and I want 2 of them to change to different unique modes when entered (In my case, Pet Sitting and House Cleaning), but I don’t want other codes to trigger modes. I didn’t see a way to accomplish that in the app.

I tried using the above code for my scenario, but it didn’t work with my lock due to extended metadata. Thanks to both of you I modified the code above and mashed it up a bit with Home Mode on Code Unlock Too. So far it is working great for my needs:

/**
 * Door Codes Mode or Alert
 *
 * Based on code from Chris Cooney's Cleaners have arrived and Barry A. Burke's Home Mode on Code Unlock Too
 *
 * 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.
 *
 */
definition(
    name: "Door Codes Mode or Alert",
    namespace: "",
    author: "cninsd",
    description: "Alert and/or change mode when a specific unlock code is used. Based on code from Chris Cooney's Cleaners have arrived and Barry A. Burke's Home Mode on Code Unlock Too",
    category: "My Apps",
    iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
    iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")

/*
Need json capability to parse data for unlock as it can contain more than just usedCode data. Example from kwikset:
{
    "usedCode": 2,
    "microDeviceTile": {
        "type": "standard",
        "icon": "st.locks.lock.unlocked",
        "backgroundColor": "#ffffff"
    }
}
*/
import groovy.json.JsonSlurper

preferences {
    section("Select a door lock...") {
        input "lock1", "capability.lock"
    }
    section("Select user code:") {
        input "user1", "enum", title: "User Code", metadata: [values: ["1", "2", "3", "4", "5", "6", "7", "8", "9", "10"]]
    }
    section("Notification:") {
        input "alertmsg", "text", title: "Message Text", required: false
        input "sendPushMessage", "enum", title: "Send a push notification?", metadata: [values: ["Yes", "No"]], required: false
        input "phone", "phone", title: "Send a Text Message?", required: false
    }
    section("Change Mode:") {
        input "newMode", "mode", title: "Mode?", required: false
    }
}

def installed() {
    log.debug "Installed with settings: ${settings}"
    subscribeToEvents()
}

def updated() {
    log.debug "Updated with settings: ${settings}"
    unsubscribe()
    subscribeToEvents()
}

def subscribeToEvents() {
    log.debug "Settings: ${settings}"
    subscribe(lock1, "lock", eventHandler)
}

def eventHandler(evt) {
    def data = []

    if (evt.value == "unlocked") {
        def isManual = false
        if ((evt.data == "") || (evt.data == null)) { // No extended data, must be a manual/keyed unlock
            isManual = true
        } else { // We have extended data, should be a coded unlock
            data = new JsonSlurper().parseText(evt.data) //Parse the event data
            if ((data.usedCode == "") || (data.usedCode == null)) { // If no usedCode data, treat as manual unlock
                log.debug "Unknown extended data (${data}), treating as manual unlock"
                isManual = true
            }
        }

        if (!isManual) {
            // Wasn't manual and we have a usedCode	

            Integer i = data.usedCode as Integer
            log.debug "Unlocked with code ${i}"
            log.debug "Listening for ${settings.user1}"

            if (i == settings.user1.toInteger()) {
                log.debug "Unlocked code ${i} matches user code"
                setLocationMode(newMode)
                log.debug "Setting mode to ${settings.newMode}"
                send(evt)
            }
        }

    }
}

private send(evt) {
    if (sendPushMessage != "No") {
        log.debug("Sending push message: ${settings.alertmsg}")
        sendPush(alertmsg)
    }

    if (phone) {
        log.debug("Sending text message: ${settings.alertmsg}")
        sendSms(phone, alertmsg)
    }

}

(Patrick Haughton) #26

So i tried to use the above code and received the following error

7:54:05 PM:
error
groovy.lang.GroovyRuntimeException: Ambiguous method overloading for method script14393408446811259192727#setLocationMode.
Cannot resolve which method to invoke for [null] due to overlapping prototypes between:
[class java.lang.String]
[class physicalgraph.app.ModeWrapper] @ line 95


#27

Here’s my decent solution

import groovy.json.JsonSlurper

def code = new JsonSlurper().parseText(evt.data).usedCode
if(code == null) code = 0
def codes = [‘Manually’, ‘User1’, ‘User2’, ‘User3’, ‘User4’]
log.debug “Door Unlocked${code > 0 ?” by":""} ${codes[code]}"


(Christine Waters) #28

ok call me stupid but I am trying to figure out how to figure this all out. I am new to the smart anything devices and have the kwikset zwave 910 touchpad locks. I just setup a samsung smart things hub and this is my only item. While its great that it tells me if the door is locked or unlocked I more wanted to know when my youngest gets home from school and uses his code to unlock the door. As far as i can tell this thing is an app on my phone to control the hub so not sure where this code is suppose to even go. Can someone please dumb this down for me?


#29

Welcome! You are replying to a thread which is in the archive section of the forum and is more than a year old, so most of the information in this thread isn’t really relevant anymore. Also, this was a section for people who wanted to write their own code, which I don’t think is what you’re asking about. So let’s see if we can get you to the right section of the forum where you can get an answer to your question. :sunglasses:

From what you’re describing, you’ve run into the fact that the official SmartThings integration with locks does not at present do anything with user codes.

Fortunately, there is a very popular smart app called lock manager created by one of the community members which will let you do all of this and more.

If you haven’t used custom code before, it’s pretty straightforward. Basically you just copy the author’s code and paste it into your own account. Here’s the FAQ that describes that process:

If that sounds like something you’d like to pursue, then here is the thread where you can read about the lock manager smart app and talk to the author if you have any questions:

In the future, if you are looking for functionality and you can’t figure out whether it exists in SmartThings or not, Just start a new thread in the following section of the forum and someone will help you.

https://community.smartthings.com/c/smartapps/smartapp-ideas

If you’d just like to explore what other custom code is already available, check out the quick browse lists in the community – created wiki:

http://thingsthataresmart.wiki/index.php?title=How_to_Quick_Browse_the_Community-Created_SmartApps_Forum_Section

But for now, I think Lock Manager Will give you everything you need. Just ask any follow-up questions in the author’s thread linked to above.