Push Notification from smartthings REST application?

I am writing a HTML5 app to access and control smartthings sensors using smartthing REST application.

Is it possible to get push notification from smartthing REST app to HTML5 application?

For example - to get status of motion sensor, I like to send event from REST app to HTML5 app rather then polling for the motion sensor status using REST endpoints. Polling creates delay in case I like to take some action as soon as motion is detected.

Example will be really helpful.

Thanks

Ashish

Yes, this is what I am doing. I have a SmartApp that responds to events and sends the data to a web service (actually just a web handler).

/**

  • Data Publisher
  • Copyright 2015 Jeff May
  • 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: “Data Publisher”,
namespace: “”,
author: “Jeff May”,
description: “Pushes data to the Server”,
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”,
iconX3Url: “https://s3.amazonaws.com/smartapp-icons/Convenience/Cat-Convenience@2x.png”)

preferences {
section(“Door Sensors”) {
input “labDoor”, “capability.contactSensor”, title:"Where ?"
input “serverDoor”, “capability.contactSensor”, title:“Where ?”
}
section(“Switches”) {
input “labLamp”, “capability.switch”, title:“Where ?”
}
section(“Moisture”) {
input “shower1”, “capability.waterSensor”, title:“Where ?”
}
section(“Motion & Presence”) {
input “jeffOfficeMotion”, “capability.motionSensor”, title:"Where ?"
input “presenceTag”, “capability.presenceSensor”, title:"Where ?"
input “outsideTemp”, “capability.temperatureMeasurement”, title:“Where ?”
}
section(“Power Outlets”) {
input “JeffOfficePower”, “capability.powerMeter”, title:“Where ?”
}
}

def installed() {
log.debug “Installed with settings: ${settings}”

initialize()

}

def updated() {
log.debug “Updated with settings: ${settings}”

unsubscribe()
initialize()

}

def initialize() {
subscribe(labDoor,“contact”,dataChangeHandler)
subscribe(serverDoor,“contact”,dataChangeHandler)
subscribe(labLamp,“switch”,dataChangeHandler)
subscribe(Shower1,“water”,dataChangeHandler)
subscribe(jeffOfficeMotion,“motion”,dataChangeHandler)
subscribe(presenceTag,“presence”,dataChangeHandler)
subscribe(outsideTemp,“temperature”,dataChangeHandler)
subscribe(JeffOfficePower,“power”,dataChangeHandler)
}

def dataChangeHandler(evt){
log.debug “$location: $evt.date - $evt.id : $evt.displayName - $evt.stringValue”

def params = [
	uri: "http://www.dummy.org",
	path: "/handlers/SmartThingsHandler.ashx",
    query:[sensor:evt.displayName,value:evt.stringValue,area:location] 
]

try {
	httpGet(params) { resp ->
		if (resp.data) {
        
            log.debug "Response Status = ${resp.status}"
    		log.debug "Response Data = ${resp.data}"
    		

            //resp.headers.each {
				//log.debug "header: ${it.name}: ${it.value}"
			//}
    	}
    	//if(resp.status == 200) {
        //	log.debug "Request was OK"
		//}
    	//else {
    	//	log.error "Request got http status ${resp.status}"
    	//}
    }
} catch(e)
{
	log.debug e
}

}

1 Like

Check out my project. It does what you want, less push notifications.

If you figure out an elegant/effective way to send push notifications to a web app, please let me know.

Thanks for nice sample code and idea of calling REST call from smartthing web service. My server is going to be behind router and won’t have public IP. If this is the only way then I have to think about accessing server from public IP.

Do let me know if there is any other approach.

Thanks for help.

Nice project. I will look at your project and let you know if I get any idea regarding push notifications.

Thanks

You may be able to create a custom LAN Device Type and then write to that Device. Currently that requires setting up a LAN discovery mechanism like UPnP, but after discovery, you can use REST against your server.

There’s a good section in the Developer Documentation…

I use firebase as an intermediary between ST and my webapp for realtime events. Very easy to set up and their free tier will work fine for a single house application.

Your server behind the firewall would subscribe to the firebase events and your smartapp would push events to the firebase instance. Is this what you are looking for?

I will look at firebase and see if it works for my environment. Thanks

There is no “free and unlimited” service out there, is there?

I will look at LAN device type but not sure how smartthing REST app can access server behind NAT using LAN Device mechanism. Will look at samples and try to understand idea of LAN device.

So you might want to at least consider hosting your web app. Gives you a lot of flexibility and capability when you are not at home, it solves problems like this (especially if you want to tie in other APIs)

If you notice I have a siteID in my code. The reason is because then you could use your app for multiple homes and they could all use your app (if you publicly hosted it)

The other way is to use a dynamic dns service. I have not used one (or it least not that I cna remember) but the jist is that you have a domain name and it resolves your IP behind the scenes.

Using site id is really good idea. Thanks. I will try your approach and see if it works for me. Will post feedback.

Thanks

By hosting I meant on a public server where you pay like $10/ month

The SmartApp runs in the Cloud which also runs your custom LAN Device Type. The SmartThings Platform relays the REST calls from the SmartApp in the Cloud to and through your Smart Hub on your LAN to your server.

It should work fine if you don’t require UDP or Websockets, etc. (ie, there are some protocol and transfer size restrictions).

So the SmartThings Cloud <-> SmartThings Hub which is already doing the NAT translation for itself is used as a proxy / tunnel.

1 Like

Essentially, yes!

That’s a powerful feature of LAN device types.

Not that I am aware, but if you only use firebase for real time eventing and delete the messages once they are stored in your own local database, you should not ever have to pay for firebase.

Event triggered —> SmartApp —> Firbase ← Local app subscribes to firebase → Store event in local DB

I have to look into it. I have no need to store anything.

I now wonder, isn’t SAMI also providing this functionality? Maybe this will be more transparent with tight ST/SAMI integration.

1 Like

Maybe. I looked into it and they do support web sockets. I don’t know how tightly the integration with ST is at this point and I want to experiment with it as well. I can have ST shooting realtime events to a browser with a few lines of code and have it done in about 10 minutes on Firebase. SAMI seems to be a much more complex beast.

2 Likes

Do you have any sample code?

I looked at the documentation, but I am not sure if I understand using UPnP to connect to device. If you look at my code example above, I still want to do that, but I would rather use an IP like 192.168.1.2 (from hub on my home intranet) instead of http://www.dummy.org (which is a dynamic IP in a new project I am working on.)