Update DeviceTamperAlarm.groovy
[smartapps.git] / third-party / NotifyIfLeftUnlocked.groovy
1 /**
2  *  Notify If Left Unlocked
3  *
4  *  Copyright 2014 George Sudarkoff
5  *
6  *  Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7  *  in compliance with the License. You may obtain a copy of the License at:
8  *
9  *      http://www.apache.org/licenses/LICENSE-2.0
10  *
11  *  Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
12  *  on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
13  *  for the specific language governing permissions and limitations under the License.
14  *
15  */
16
17 definition(
18     name: "Notify If Left Unlocked",
19     namespace: "com.sudarkoff",
20     author: "George Sudarkoff",
21     description: "Send a push or SMS notification (and lock, if it's closed) if a door is left unlocked for a period of time.",
22     category: "Safety & Security",
23     iconUrl: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience.png",
24     iconX2Url: "https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png")
25
26
27 preferences {
28     section("If this lock...") {
29         input "aLock", "capability.lock", multiple: false, required: true
30         input "openSensor", "capability.contactSensor", title: "Open/close sensor (optional)", multiple: false, required: false
31     }
32     section("Left unlocked for...") {
33         input "duration", "number", title: "How many minutes?", required: true
34     }
35     section("Notify me...") {
36         input "pushNotification", "bool", title: "Push notification"
37         input "phoneNumber", "phone", title: "Phone number (optional)", required: false
38         input "lockIfClosed", "bool", title: "Lock the door if it's closed?"
39     }
40 }
41
42 def installed()
43 {
44     initialize()
45 }
46
47 def updated()
48 {
49     unsubscribe()
50     initialize()
51 }
52
53 def initialize()
54 {
55     log.trace "Initializing with: ${settings}"
56     subscribe(aLock, "lock", lockHandler)
57 }
58
59 def lockHandler(evt)
60 {
61     log.trace "${evt.name} is ${evt.value}."
62     if (evt.value == "locked") {
63         log.debug "Canceling lock check because the door is locked..."
64         unschedule(notifyUnlocked)
65     }
66     else {
67         log.debug "Starting the countdown for ${duration} minutes..."
68         state.retries = 0
69         runIn(duration * 60, notifyUnlocked)
70     }
71 }
72
73 def notifyUnlocked()
74 {
75     // if no open/close sensor specified, assume the door is closed
76     def open = openSensor?.latestValue("contact") ?: "closed"
77
78     def message = "${aLock.displayName} is left unlocked and ${open} for more than ${duration} minutes."
79     log.trace "Sending the notification: ${message}."
80     sendMessage(message)
81
82     if (lockIfClosed) {
83         if (open == "closed") {
84             log.trace "And locking the door."
85             sendMessage("Locking the ${aLock.displayName} as prescribed.")
86             aLock.lock()
87         }
88         else {
89             if (state.retries++ < 3) {
90                 log.trace "Door is open, can't lock. Rescheduling the check."
91                 sendMessage("Can't lock the ${aLock.displayName} because the door is open. Will try again in ${duration} minutes.")
92                 runIn(duration * 60, notifyUnlocked)
93             }
94             else {
95                 log.trace "The door is still open after ${state.retries} retries, giving up."
96                 sendMessage("Unable to lock the ${aLock.displayName} after ${state.retries} retries, giving up.")
97             }
98         }
99     }
100 }
101
102 def sendMessage(msg) {
103     if (pushNotification) {
104         sendPush(msg)
105     }
106     if (phoneNumber) {
107         sendSMS(phoneNumber, msg)
108     }
109 }
110