Alexa Helper and Local URL's?


#1

So I just installed Alexa Helper and was very impressed with the installation “how to”. It all went very smoothly. I use a scripting/automation engine called Intelliremote (with built in Autoit Scripting) that allows remote control via HTTP commands. I created an Alexa Switch to trigger an HTTP command via the Alexa Helper Scenario with the ultimate goal of controlling it all via the Echo. The HTTP command is something like this “HTTP:\192.168.1.201:8080?button=CommandX”.
When I added that to the scenario all looked good however when I manually activated the Alexa Switch no joy, nothing was sent.

I suspect it has to do with the fact that Alexa Helper uses httpGet vs physicalgraph.device.HubAction. I was going to change the Alexa Helper-Scenario Smart App with something similar to the following:

> {
>   def ip = "192.168.1.201:8080"
>   def deviceNetworkId = "c0a801C9:1f90" //need the Hex ID for the Device Handler (doesnt like Ascii)
>   sendHubCommand(new physicalgraph.device.HubAction("""GET /?button=CommandX HTTP/1.1\r\nHOST: $ip\r\n\r\n""", 
>   				 physicalgraph.device.Protocol.LAN, 
>   				 "${deviceNetworkId}"))
>   
> }
> 

But figured I would ask if any of you knew of a better way. Thanks for any input you can provide on this. I think the Alexa Helper Smart App is terrific and will go a long way in helping me automate.

Regards All!


#2

Best to ask the author. :wink:

Tagging @MichaelS


(Micheal ) #3

You are correct…the app simply calls a blind http address and doesn’t look for a response. I have tested this with my own Cloud Interface app (which does create an end-point that can be accessed) along with IFTTT Maker HTTP addresses.

If I understand what you are attempting to accomplish, you have a separate server on your LAN that is listening on port 8080 for something? You aren’t trying to http out to the internet?


#4

Hi Michael,
First Nice Job on the app! Really ties a lot together in making the Echo a key component in an automated home.

Yes you are correct I have a server on my LAN (or any component that has a local web based interface for that matter - like a TV, or Receiver, etc…). Not trying to get out to the internet.

I have written a basic device handler that I know can send the LAN based HTTP commands using the HubAction commands but thought that perhaps you might have come across this already and found a better way. What I like about the Alexa Helper Scenario approach is that I don’t have to code a new device handler for each new HTTP command, just create a new scenario. I know its similar but it seems much more intuitive your way.

I can explain my findings with the HubAction command and the HubSoapAction commands if it helps any. A lot of others have been experimenting with those methods and I learned much by pouring over threads discussing smartthings control of LAN based devices (using HTTP Gets and Puts - unfortunately no native Socket API for lower level IP controls).

Anyway wanted to say thanks for the great App and if you could shed any light on this, otherwise I may just hack around with the Alexa Helper Scenario and see how far I can get.


#5

I realize that my original question is very specific and doesn’t talk to the general use case I am looking at…

That use case is this; I have a device on my LAN (TV, Receiver, HTPC, etc) that can be controlled via HTTP Gets/Puts. Smartthings has native support for LAN based web services through its HubAction (or HubSOAPAction) Method. Therefore I can create a Smartthings based remote control for the LAN based device. To take it a step further coupling the smartthings interface to Alexa/Echo via the Alexa Helper App (using Alexa Switches and Momentary PBs) allows voice control over those devices!

Hope that makes it a little clearer as to what my ultimate goal is (I’m sure others are also doing this already too)


(James) #6

Hello MichaelS,

Hope you don’t mind me asking directly.

I too want to be able to send to a local URL.
Reading between the lines. I installed Alexa Helper, Cloud Interface and Alexa switch as per your instructions.
I created an Alexa switch as per your instructions and then linked it to the cloud interface.
In the URL I changed both on /off as
http://192.168.0.200/sendIR?n=1&code=0x4bb6a05f&p=NEC

This works if I send this URL by any browser connected to my network iPhone, Ipad etc.

This will send a command to an IR blaster connected to a computer and Mute the television.

Should this work or have I got the wrong end of the stick?

Best wishes.

James.


(Micheal ) #7

The issue with this is that the 192.x.x.x is an internal, non-routable address within your network. The HTTPGet command that I use is actually issued remotely from SmartThings’ DC out to the internet. So, you will be unable to activate it internally. There are a couple things I have heard about that may work. First, you could use the “hub action” command to send (I think) internal commands within your network. This would require a code change within Alexa Helper to issue a different command, and unfortunately, I don’t have anything to test this with so you might have to do this yourself or with Community assistance. The other thing you could do it forward your port 80 on your firewall to whatever is at 192.168.0.200. Then the commands from ST will come from the internet and should work with no modification to the code. The danger of this is, of course, that once you open up that port then ANYONE can get through to possibly access that device. Port 80 is one of the most common ports scanned, but unless the device has a web interface you might be fine (use at your own risk).

I am curious what you used the Cloud Interface app for in this case…That is just for connecting SmartThings devices to an ‘endpoint’ that can be accessed through SmartThings…If your device isn’t connected to SmartThings I am not clear on how you would use Cloud Interface.


#8

Hi All,
The HubAction does work but the Alexa Helper-Scenario App has to change, here is the section of that code (it has to be modified to run the physicalgraph.device.HubAction command)…

   if (settings."${type}HTTP"){
        def httpAddr = settings."${type}HTTP"
        log.info "Attempting to run: ${httpAddr}"
        httpGet(httpAddr)
    }

The issue is that in order to setup the HubAction command the string passed to the helper-scenario has to be parsed and formatted with the HubAction syntax, so it is not so straight forward. I am trying to work through the nuances of Groovy to make that happen but so far no joy. I can hard code and see that the hubaction from my previous post works, but that makes the helper app interface for HTTP functions useless as only one command would be available.

The helper-scenario app needs to be able to parse the input string and break it down into chunks. For instance the example “HTTP://92.168.1.201:8080/?button=CommandX”, has to have the port and IP address broken down and then converted to hex. So in my previous post I have

>   def ip = "192.168.1.201:8080"
>   def deviceNetworkId = "c0a801C9:1f90" //need the Hex ID for the Device Handler (doesn't like text)

The ip variable needs the text version of the IP Address and the deviceNetworkId needs the hex version. I found a simple Hex conversion utility in another thread on HubAction that can do this but I have to put it all together.

The rest of the HTTP command (the part after the ip:port) then has to be saved into another variable…Finally the whole thing has to be put into the HubAction Syntax like this…

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

Where the part “/?button=CommandX” would be in some variable like $command…

I don’t want to break the helper-scenario interface because I may want both Local and Internet based HTTP calls so I am trying to figure out how to add the addition of a Local HTTP call to the interface.

Anyway I wanted to send this out if it gives anyone some additional insight…


(Micheal ) #9

Excellent post…If you guys can work through this and share your code I can make it part of the core app…Maybe with a ‘switch’ that will either allow for ‘external’ http or ‘internal’. Are you saying your top snippet DOES work as long as the receiving end (internally) can react to a http command? Are you saying if the choice is ‘internal’ that the app should have sections for ports and commands instead of just cramming them into the HTTP line? Again, if you guys work this out I have some interesting ideas of how this could be implemented.


#10

Michael
Yes the HubAction does work as long as the receiving internal device can react to a http command.
Yes I am saying that if (for local commands) there was a way to set the IP and Port and then the Command instead of just cramming them in we could build a more generic HubAction command interface.

Regards!


#11

Here is the Hex Conversion Utilities I found. Unfortunately I do not remember who to credit with the code…They were tested in a device handler that I was mucking around with to send local IP commands to various devices…

private setDeviceNetworkId(ip,port){  
  def iphex = convertIPtoHex(ip)  
  def porthex = convertPortToHex(port)  
  device.deviceNetworkId = "$iphex:$porthex"  
  log.debug "Device Network Id set to ${iphex}:${porthex}"  
} 
private String convertIPtoHex(ipAddress) {  
    String hex = ipAddress.tokenize( '.' ).collect {  String.format( '%02x', it.toInteger() ) }.join()  
    return hex  
}
private String convertPortToHex(port) {  
  String hexport = port.toString().format( '%04x', port.toInteger() )  
    return hexport  
}

#12

Guys,
I sent some additional code snippets but for some reason they were gobbled up by “slagle Akismet…” hopefully that will be reversed. Otherwise I will resend…
Regards!


(Micheal ) #13

Cool…I think first I will add the switch and the backend code for HubAction…that will solve half of the problem, and if you have a solution to the IP and port that is programmable I can add that as well (giving you full credit in the code, of course!).


#14

Hi Again,
No need for any credit as I borrowed from other posts and cant remember where I got most of the code anyway. here is the code snippet again. Hopefully this time it will go through!

private setDeviceNetworkId(ip,port){  
  def iphex = convertIPtoHex(ip)  
  def porthex = convertPortToHex(port)  
  device.deviceNetworkId = "$iphex:$porthex"  
  log.debug "Device Network Id set to ${iphex}:${porthex}"  
} 
private String convertIPtoHex(ipAddress) {  
    String hex = ipAddress.tokenize( '.' ).collect {  String.format( '%02x', it.toInteger() ) }.join()  
    return hex  
}
private String convertPortToHex(port) {  
  String hexport = port.toString().format( '%04x', port.toInteger() )  
    return hexport  
}

(Micheal ) #15

Excellent…you going to be around this week if I PM you to test the new scenario code once I get it together?


#16

Michael
I wont be back home until Thursday evening but would love to test anything you come up with! As I said earlier great work on the App to begin with. It makes Alexa integration so much easier! If we could only master the Alexa Skills and Voice API we could really make the smartthings to echo integration sweet. I hope the smartthings team finds a way to open the voice interface to this community.

Thanks Again for your efforts!


(Micheal ) #17

No problem…already worked out in my mind the interface…here is what I am thinking:

Instead of adding the http right to the mail page, there would be a new page just for the HTTP Request. Going to this page you would have the default “Run this HTTP request” in a single line. Below that would be a toggle (Internal/External-Defaults to External). If you choose internal, below that would be a toggle for “Advanced Options”. If that is chosen, you would be presented with the following:

IP Address
Port
Command (/? not require)

Sound right?


(James) #18

I think it is safe to say I got the wrong end of the stick.

The reason I was looking at the “Cloud Interface” was that it appeared to be a place where I could put a URL. However “Cloud” should have told me that it was not likely to be “Local”. I have just read the wiki again and your notes above. I can see that a URL can be entered in the Alexa Helper, even though it would still not have worked.

How ever it looks like you have a plan to move forward.

Clearly I am not a programmer, but if I can help with any testing. Please let me know.

Best wishes.


(Micheal ) #19

Correct…I already have the framework for the internal/external revision going, and will be finishing up the code probably today. Once tested I can add this. If we can get this to work it will be rather cool and another feature to tout for Alexa Helper.


#20

That sounds right! Looking forward to working on this. Thanks for taking the time.