iOS - Using ST Notifications to give you option to run/abort SmartApp code

If you have a jailbroken iOS device, here’s a way to give you physical control over whether to cause an action in a SmartApp to run – or whether to abort an action that your SmartApp is scheduled to run.

It requires a little bit of setting up – both on your iOS device and in the ST IDE.

The below is an example of how I set up a way to Allow / Abort turning off lights when my iOS device receives a ST notification that my motion sensors detected “No Motion” for X amount of time. Basically, I set up a virtual on/off momentary button, get the endpoint url for that button, and link that endpoint url to an Activator action. In my SmartApp, when it detects the required “No Motion” event from my motion sensor, I send a unique ST Notification, NotiAction will listen for that unique Notification, and will cause Activator to present me with an Activator Menu of (i) sending endpoint url to cause Abort button to be pushed and (ii) doing nothing. The SmartApp is subscribed to the Abort button, and, if the SmartApp detects that the Abort button was pushed within a desired timeframe, then the SmartApp will cancel the turning off the lights.

I’ve had it up and running for a couple days now. Works great. Now I (or Significant Other!!!) can override the lights going off automatically. SAF increased!!! Happy happy jo


  1. Here are the apps that you’ll need on your jailbroken iOS device:
  • Activator ( the 1.9.3 beta 1 version - you will need to add rpetrich’s repo: http://rpetri.ch/repo/ )
  • Activate Command
  • NotiAction
  1. From the SmartThings’ IDE: set up 1 (or more) virtual on/off momentary button. For now, call it something like “Abort”.

  2. From the SmartThings’ IDE: add/create endpoints for the virtual button(s) from Step #2 above. Get the https url for the toggle command.

  3. On your iOS device: in the settings for Activate Command, add a command (you can name it anything you want) using the command of

    curl -k -s https://xxxxxxx.x.x.x.x.xxxxx/xxxx/xx/x

(using the endpoint url of the toggle command after curl -k -s).

  1. In ST’s IDE: Choose a SmartApp that contains an action that you want to be able to control. Add the following to the preferences section of that SmartApp:

    section(“User Abort Options”, hideable:true, hidden: true) {
    input “abortToggle”, title: “Identify the Abort Toggle”, “capability.momentary”, multiple: false, required: false
    input “abortTime”, “number”, title: “Specify length of Abort Window (minutes):”, multiple: false, required: true, defaultValue: 2
    }

The “abortTime” number is the number of minutes before you will run an action.

Then subscribe to the abortToggle thing, for example:

if (abortToggle) {
	subscribe(abortToggle, "momentary.pushed", abortHandler)       
}

Then create the abortHandler() routine:

def abortHandler(evt) {

	log.trace "abortHandler:  abortToggle pushed. "
    log.debug "Receieved evt is ${evt} & evt.value is ${evt.value}."
    
    if (state.abortWindow == "Valid") {
    
    	unschedule("turningOff")
		state.abortWindow = null
		sendNotificationEvent("Abort command received.  No Motion event cancelled.")         
        log.trace "abortHandler:  Received abort command within the abortWindow.  Unscheduling turningOff()."
    
    } else {
    
        log.trace "abortHandler:  Received abort command, but not within the abortWindow."
    }    
    
}

Then, before the code that would cause an action to run – in the example below, the function turningOff() – simply add logic to check for abortToggle, and, if found, send out a push Notification and wait the abortWindow amount of minutes before running (and if not found, then run as normal). IMPORTANT – start the notification with some unique, readily identfiable code/phrase (like ST123TrigAbort). As explained below, this code/phrase will be used by NotiAction to filter out these Notifications to ask you for input. For example:

    if (abortToggle) {

       	sendPush("ST123TrigAbort: No motion from ${motions.label}.")                 
	state.abortWindow = "Valid"        
            
            unschedule("turningOff")
            def abortWindow = abortTime as Number
            abortWindow = abortWindow * 60
            			    
           	runIn (abortWindow, "turningOff")                            
                   
        } else if (!abortToggle) {
        
        	log.debug "scheduleCheck:  no abortToggle, so running turningOff() now."
        	turningOff()
    
      }    

Last bit of code to add is to reset the state.abortWindow. For example:

def turningOff () {
    
   	log.trace "Executing turningOff() / resetting state.abortWindow. "
    
        state.abortWindow = false

                        if (hues) {
                hues?.each {
    	         	it.off()
	        }
            }       
}
  1. On your iOS device: in the settings for NotiAction, enter the Notification code/phrase you want it to listen for (e.g. “ST123TrigAbort”).

  2. On your iOS device: in Activator. First, create a Menu. Call it something like “No Motion Alert”. Then add an action linking the Activate Command command you set up in Step #4 above. Then add an action that does nothing or returns to first Springboard page.

  3. On your iOS device: in Activator, link all of this together. Go to “Anywhere” --> NotiAction Match (the one you set up in Step #6 above) --> No Motion Alert Menu (the one you set up in Step #7 above).

-Tony

3 Likes