Bug in "Notify If Left Unlocked”?

(Kevin) #1

I am trying to use the Notify if Unlocked code and it works, with the exception of sending the optional SMS message…and I can’t figure out what the issue is. The error message being logged is as follows.

c0ba4b58-d68c-49f3-9085-242f2e847050 10:50:45 AM CST: error groovy.lang.MissingMethodException: No signature of method: script14177118442451333570032.sendSMS() is applicable for argument types: (java.lang.String, org.codehaus.groovy.runtime.GStringImpl) values: [(999) 999-9999, Breezeway Door is left unlocked and closed for more than 1 minutes.]
Possible solutions: sendSms(java.lang.String, java.lang.String), sendSms(java.lang.String, java.lang.String, java.util.Map), sendPush(java.lang.String), sendPush(java.lang.String, java.util.Map) @ line 108
c0ba4b58-d68c-49f3-9085-242f2e847050 10:50:45 AM CST: debug Sending text message.Breezeway Door is left unlocked and closed for more than 1 minutes.
c0ba4b58-d68c-49f3-9085-242f2e847050 10:50:44 AM CST: trace Sending the notification: Breezeway Door is left unlocked and closed for more than 1 minutes…
c0ba4b58-d68c-49f3-9085-242f2e847050 10:49:51 AM CST: trace Scheduling ‘notifyUnlocked’ for InstalledSmartApp: c0ba4b58-d68c-49f3-9085-242f2e847050
c0ba4b58-d68c-49f3-9085-242f2e847050 10:49:49 AM CST: trace Deleting scheduled job ‘notifyUnlocked’ for InstalledSmartApp: c0ba4b58-d68c-49f3-9085-242f2e847050
c0ba4b58-d68c-49f3-9085-242f2e847050 10:49:49 AM CST: debug Starting the countdown for 1 minutes…

Anyone have any recommendations/thoughts on what the issue is here?

I’ve copied the code below for reference. Any help is appreciated.

Thanks in advance. - Kevin


  • Notify If Left Unlocked
  • Copyright 2014 George Sudarkoff
  • 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.


name: “Notify If Left Unlocked”,
namespace: “com.sudarkoff”,
author: “George Sudarkoff”,
description: “Send a push or SMS notification (and lock, if it’s closed) if a door is left unlocked for a period of time.”,
category: “Safety & Security”,
iconUrl: “http://www.kevinwestby.com/smartthings/securehome1-120.png”,
iconX2Url: “http://www.kevinwestby.com/smartthings/securehome1-120.png”,
iconX3Url: “http://www.kevinwestby.com/smartthings/securehome1-120.png”)

preferences {
section(“If this lock…”) {
input “aLock”, “capability.lock”, multiple: false, required: true
input “openSensor”, “capability.contactSensor”, title: “Open/close sensor (optional)”, multiple: false, required: false
section(“Left unlocked for…”) {
input “duration”, “number”, title: “How many minutes?”, required: true
section(“Notify me…”) {
input “pushNotification”, “bool”, title: "Push notification"
input “phoneNumber”, “phone”, title: “Phone number (optional)”, required: false
input “lockIfClosed”, “bool”, title: “Lock the door if it’s closed?”

def installed()

def updated()

def initialize()
log.trace "Initializing with: ${settings}"
subscribe(aLock, “lock”, lockHandler)

def lockHandler(evt)
log.trace "${evt.name} is ${evt.value}."
if (evt.value == “locked”) {
log.debug "Canceling lock check because the door is locked…"
else {
log.debug "Starting the countdown for ${duration} minutes…"
state.retries = 0
runIn(duration * 60, notifyUnlocked)

def notifyUnlocked()
// if no open/close sensor specified, assume the door is closed
def open = openSensor?.latestValue(“contact”) ?: “closed”

def message = "${aLock.displayName} is left unlocked and ${open} for more than ${duration} minutes."
log.trace "Sending the notification: ${message}."

if (lockIfClosed) {
    if (open == "closed") {
        log.trace "And locking the door."
        sendMessage("Locking the ${aLock.displayName} as prescribed.")
    else {
        if (state.retries++ < 3) {
            log.trace "Door is open, can't lock. Rescheduling the check."
            sendMessage("Can't lock the ${aLock.displayName} because the door is open. Will try again in ${duration} minutes.")
            runIn(duration * 60, notifyUnlocked)
        else {
            log.trace "The door is still open after ${state.retries} retries, giving up."
            sendMessage("Unable to lock the ${aLock.displayName} after ${state.retries} retries, giving up.")


def sendMessage(msg) {
if (pushNotification) {
if (phoneNumber) {
sendSMS(phoneNumber, msg)

(Matt) #2

Check this app

(Kevin) #3

Thanks Matt! I’ll give it a try.

(Kevin) #4

Loaded it up but am getting the following error…and no notifications.

7a078942-e32a-40cc-98b0-bc1e132d1745 8:01:24 AM CST: error java.lang.NullPointerException: Cannot execute null+null @ line 186

(Matt) #5

Please see this thread

I hadn’t actually loaded this either and now that I did. I get the same error. I’m sure he’ll fix it.

(Kevin) #6

Fixed it with the following updated runNotifyAt function.

private def runNotifyAt(timeMs) {

def currentTime = now()
def date = new Date(currentTime + state.repeatMs)

runOnce(date, taskNotify)
log.trace "taskNotify scheduled to run at ${date}"


(Kevin) #7

New version 1.0.2 is available…working great!