Local Network HTTP/s Or Internet HTTPS with Authentication


(Eric M) #1

Hi, I am trying to write a SmartApp that can communicate on a local network to another device via HTTP. I read that it isn’t possible (in another forum posting), but SmartThings seems to communicate with my Philips Hue Hub by local IP (at least Smart Things found it by its local IP). I tried writing an app, but it times out when trying to reach the device (ie. 192.168.10.10). So, is there a way to reach this device without piping data through the web?

If not, can I talk to the device via HTTPS and use standard HTTP based authentication? Any tips on how to setup the HTTP post or get using those two things?


[RELEASE] Absolute Simplest ESP8266 Smart Blinds, no mqtt, rest, bridge, or broker, just your board and your hub
(Troy Kelly) #2

Have you looked at the link below @erocm1231 ?

https://graph.api.smartthings.com/ide/doc/smartApp

There are http commands there - but I am not quite sure what you are trying to achieve, so I don’t know if that is what you are looking for.

If you are talking to a device - would it be prudent to create a device driver for it? (rather than a SmartApp)

http://docs.smartthings.com/en/latest/cloud-and-lan-connected-device-types-developers-guide/building-lan-connected-device-types/building-the-device-type.html?highlight=http

Are you trying to use UPnP to discover the device, or are you setting the IP yourself?


(Eric M) #3

I have actually found a few posts that are directly related to what I am trying to do. I have a local server that will launch scripts based on events in SmartThings. I was using the http post and http get methods listed in the doc link you posted, but they do not work for local LAN addresses. For that I am trying to use:

sendHubCommand(new physicalgraph.device.HubAction(""“GET / HTTP/1.1\r\nHOST: $ip\r\n\r\n”"", physicalgraph.device.Protocol.LAN, “${deviceNetworkId}”))

as described in:

I haven’t had much time to work on it, but I will probably be able to get it to work.

FYI, thanks for the link to the ide docs. I didn’t know that existed and it has been extremely helpful.


(Troy Kelly) #4

Yeah, they are quite well hidden. I can’t actually recall how I found them in the first place.

I will have a bit of a play when I get a moment, my understanding however is that a SmartApp is not able to directly access the network on which a hub sits. Only a device would be able to do that.

If he is still around @Ben should be able to clarify, but he’s been very quiet.


(Convinced ST will never be unbroken…) #5

Not entirely true. I have no problem sending GETs from a SmartApp, but I have yet to successfully do a POST. Below is an example of one of several apps I use to do GETs:

definition(
    name: "Send HAM Bridge Command When…",
    namespace: "soletc.com",
    author: "Scottin Pollock",
    description: "Sends a command to your HAM Bridge server when SmartThings are activated.",
    category: "Convenience",
    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("Choose one or more, when..."){
		input "motion", "capability.motionSensor", title: "Motion Here", required: false, multiple: true
		input "contact", "capability.contactSensor", title: "Contact Opens", required: false, multiple: true
		input "contactClosed", "capability.contactSensor", title: "Contact Closes", required: false, multiple: true
		input "acceleration", "capability.accelerationSensor", title: "Acceleration Detected", required: false, multiple: true
		input "mySwitch", "capability.switch", title: "Switch Turned On", required: false, multiple: true
		input "mySwitchOff", "capability.switch", title: "Switch Turned Off", required: false, multiple: true
		input "arrivalPresence", "capability.presenceSensor", title: "Arrival Of", required: false, multiple: true
		input "departurePresence", "capability.presenceSensor", title: "Departure Of", required: false, multiple: true
		input "smoke", "capability.smokeDetector", title: "Smoke Detected", required: false, multiple: true
		input "water", "capability.waterSensor", title: "Water Sensor Wet", required: false, multiple: true
	}
	section("Send this command to HAM Bridge"){
		input "HAMBcommand", "text", title: "Command to send", required: true
	}
	section("Server address and port number"){
		input "server", "text", title: "Server IP", description: "Your HAM Bridger Server IP", required: true
		input "port", "number", title: "Port", description: "Port Number", required: true
	}
}

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

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

def subscribeToEvents() {
	subscribe(contact, "contact.open", eventHandler)
	subscribe(contactClosed, "contact.closed", eventHandler)
	subscribe(acceleration, "acceleration.active", eventHandler)
	subscribe(motion, "motion.active", eventHandler)
	subscribe(mySwitch, "switch.on", eventHandler)
	subscribe(mySwitchOff, "switch.off", eventHandler)
	subscribe(arrivalPresence, "presence.present", eventHandler)
	subscribe(departurePresence, "presence.not present", eventHandler)
	subscribe(smoke, "smoke.detected", eventHandler)
	subscribe(smoke, "smoke.tested", eventHandler)
	subscribe(smoke, "carbonMonoxide.detected", eventHandler)
	subscribe(water, "water.wet", eventHandler)
}

def eventHandler(evt) {
	sendHttp()
}

def sendHttp() {
def ip = "${settings.server}:${settings.port}"
def deviceNetworkId = "1234"
sendHubCommand(new physicalgraph.device.HubAction("""GET /?${settings.params} HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))
}

(Patrick Stuart [@pstuart]) #6

I don’t have a local device to test a POST to, but you might find this site helpful on building the headers for a POST / GET request:

POST /foo.php HTTP/1.1
Host: localhost
User-Agent: Mozilla/5.0 (Windows; U; Windows NT 6.1; en-US; rv:1.9.1.5) Gecko/20091102 Firefox/3.5.5 (.NET CLR 3.5.30729)
Accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8
Accept-Language: en-us,en;q=0.5
Accept-Encoding: gzip,deflate
Accept-Charset: ISO-8859-1,utf-8;q=0.7,*;q=0.7
Keep-Alive: 300
Connection: keep-alive
Referer: http://localhost/test.php
Content-Type: application/x-www-form-urlencoded
Content-Length: 43

first_name=John&last_name=Doe&action=Submit

This is an example of what the string in the HubAction should look like with the name / value pairs at the end.

Remember to make sure to HEX convert your ip at the end of the sendHubCommand action.


(Eric M) #7

Thanks guys, I was able to accomplish what I was looking for (although I still need to fine tune it). When a motion or contact is tripped, a GET request is sent to an apache webserver with a “deviceId” parameter to identify what device it is. The server executes a script with the deviceId information that it receives. Here is the code. It hasn’t been tested very well so it may have some bugs:

def eventHandler(evt) {
  def deviceNetworkId = "xxxxxxxx:0050" // "xx.xx.xx.xx:80"
  def ip = "xx.xx.xx.xx:80"
  def eventDeviceID = evt.deviceId
  
  if ( evt.value == "open" || evt.value == "active" ) {
    
     log.debug "The device ${eventDeviceID} (${evt.displayName}) is reporting ${evt.value}."

     sendHubCommand(new physicalgraph.device.HubAction("""GET /?deviceId=${eventDeviceID} HTTP/1.1\r\nHOST: $ip\r\n\r\n""", physicalgraph.device.Protocol.LAN, "${deviceNetworkId}"))

  }
}

(Convinced ST will never be unbroken…) #8

@pstuart Yeah… I am not sure what the problem is; it certainly isn’t my POST construct as it works just fine from my device-type using hubaction, just not from a smartapp using sendhubcommand. Of course as you probably recall, I am not getting a response to my GETs either with that command (where you are). So I have no idea what the deal is.


(Patrick Stuart [@pstuart]) #9

Have you tried any other servers to send to / get response from? Since I wrote both ends of the process I’m using, I have total control over it.

I wonder whatever server you are connecting to is sending a properly formatted response back? Can you access fiddler or anything to test the command / response on a web browser outside the ST hub?


(Convinced ST will never be unbroken…) #10

Well I’m using two devices, the first being the RESTful interface of a Venstar thermostat (which is really what I wanted to communicate with); the second is a simple http server that I wrote for issuing commands on my Mac from GET requests, that I have been using for testing (can’t really get my fingers between the fan blades with the thermostat without getting a response from it).

I ended up creating a device-type for the Venstar that does indeed respond to the same GET and POST requests via hubaction, so this is just an exercise in discovery as to why the same requests via sendhubcommand don’t work.

Not sure if fiddler is it, but think there’s a Chrome plug-in for examination of headers from the browser. I’ll look into it tomorrow.

But what’s driving me crazy at the moment, is that I’m getting responses from hubaction within my device-type, but not from the exact same requests sent from sendhubcommand within a SmartApp.


(Patrick Stuart [@pstuart]) #11

Ok, then stupid question as I just ran into it. Did you publish (for me) the smartapp before trying it out? I didn’t the first time and nothing worked, published locally for me and the send / response started showing up.


(Patrick Stuart [@pstuart]) #12

Scott, ironically I’m now trying to get a response from a device (camera) and can’t seem to find any working code on how to get the response from a GET via hubaction in a device?


(Kristopher Kubicki) #13

I’ve been looking forever for a way to get the Hub to ping a machine on the LAN. I am going to test this later today.


(Convinced ST will never be unbroken…) #14

I thought I had. Just went back to make sure… still no joy.


(Convinced ST will never be unbroken…) #15


Welcome to my nightmare…

I have yet to get a response from a camera locally. Dunno exactly why. This code seems to work, but you have to go out and come back in again i.e. the IP address must be your router’s WAN address, and you need an open port forwarded to the camera.

Here is the code for my thermostat, which is working locally with both get and post.


Can SmartThings generate a https request?
(Tony Gutierrez) #16

Am I correct in thinking that this still hasn’t been addressed? There is still no way to do reliable get/post traffic to local addresses with responses?


(sidjohn1) #17

No, you are not correct. There are several devices that reliably get/post http traffic. They are all hiding under the search button. Foscam, generic camera, Roomba, wifi thermostat just to name a few portential searches.


(Tony Gutierrez) #18

I’ve seen all of those. Those are possible because the apis are so simple. None of them require chainable LOCAL http requests (local requests are only possible in device types).


(sidjohn1) #19

Not close enough then, my Roomba devicetype chains an “on” command with a poll, no it’s not required but I do it anyway.


(Tony Gutierrez) #20

Chaining commands is not the same as chaining http calls to a local ip. The problem is that the function that handles the response is divorced from the function making the request…so you cant do more complex actions that require multiple synchronous calls.