I am trying to write a device handler for my router to be able to enable/disable wifi and guest network from ST.
The router is Netgear and it has a soap api fortunately. I found the messages needed to pass to the router.
But I need to send 3 soap commands to the router to make one change.
So I put all of these in separate functions and I call them from one action bound to a device handler’s button tile.
They don’t run in the correct order and I need to get the response of each commands sent to the hub.
how can I do that ?
my sample code for 3 actions are below. GuestWirelessOff is the main function called when button is pressed.
Hi. I’m the creator of Konnected. Thanks for the mention, and glad you learned something from my code.
Yes, you can pass a [callback: "myFunctionName"] to hubAction to call a custom callback function. Keep in mind that hubAction is asynchronous, so if you need your three functions to be run in order, I would suggest that each hubAction call specifies the next in sequence as the callback. This will ensure that they’re run in order.
thanks. but I actually have some other problem right now.
parsing may wait. First I need to solve how to send envelope-header in soap request.
any idea on that ?
I bookmarked your code indeed as i want to improve my own porting with a lan discovery and you are the first one in this forum providing a clear way to do it. Million thanks!
Dude… it took me 5 sec to search “soap” in this forum an hit the below, I am not sure why you don’t find it.
There are many people writing things years before us (and better than us) so the first thing in this forum is to search a bit before posting. Another source of inspiration is to get the smartthings public GitHub on your laptop and grep/find in the hundreds of sources how people/smartthings team do stuff.
it seems like a solution. Now I just need to find how to calculate content-length.
how did you find this solution ?
since my problem is about hubsoapaction, I always searched with keyword “hubsoapaction”
and if I search with just the short keyword “soap” , there are lots of threads. (mostly unrelated)
well… the time you didn’t spend looking in is the same I spent to fibd it. I can tell you, not more than 5sec, that was the 3rd entry.
Anyway, since the solution is availAble, that would be great you click the notch box to indicate it, so others can get quicker to this post and solution. You can also reward people answering you by using the likes. That’s how it works here and allow everyone to progress in the forum activities.
well, I tried several formats but I could not succeed sending an http packet to the router (I get captures from its interface)
the packet does not reach the host. but if I use hubsoapaction all packets reach the router.
Note
A Device Handler’s parse() method can also return a HubAction object, in addition to the above-described usage by explicitly calling sendHubCommand.
See Building the Device Type for more information.
Normally, in ST, you create an event (like by createEvent and I guess this is also true for sendHubCommand) and you return the event if you are in a command (parse, on, off, etc…). If you are in private method, I think you have to send the hubcommand explicitly.
So try to sendHubCommand( turnOn ) at the end of your gwoff1()
or
just have a sendhHubCommand ( new physicalgraph.device.HubAction("""POST /soap/server_sa/ HTTP/1.0
SOAPAction: "urn:NETGEAR-ROUTER:service etc…)
Also in order to make sure your gwoff1 is called, add a log,debug “in gwoff1” so you can check in the live logging that it is called.
Thanks. I will try that. But I had read that HubSoapAction is just an extension of HubAction
And when I replace HubAction with HubSoapAction it sends the packet.
Actually, I don’t suspect the code but I suspect that something is missing to direct it to my router.
We just have the HOST: 192.168.254.1 header , is that enough ?
I tried adding the log.debug and it is showing up in logging.
In the example I gave you, the guy used getHostAddress() returned string
Please follow that too. We all convert our IPs and ports following this function.
private getHostAddress() {
def ip = getDataValue("ip")
def port = getDataValue("port")
if (!ip || !port) {
def parts = device.deviceNetworkId.split(":")
if (parts.length == 2) {
ip = parts[0]
port = parts[1]
} else {
log.warn "Can't figure out ip and port for device: ${device.id}"
}
}
log.debug "Using ip: ${ip} and port: ${port} for device: ${device.id}"
return convertHexToIP(ip) + ":" + convertHexToInt(port)
}
actually in the code you just posted, I see “$host:$port” is passed to the header HOST
That’s not the hex format. It’s just 192.168.1.49:80
so what am I missing ?
I have the network ID in device profile set as C0A8FE01:0050
But shall I have to put this somewhere also in my code ?
I don’t see it anywhere in code examples.
in other device handlers I see these 2 parameters:
String dni = null, // Remove this when using device.deviceNetworkId
[callback: callbackParse], // Remove this when using device.deviceNetworkId
as in
def hubAction = new physicalgraph.device.HubAction(
method: "GET",
path: uri,
headers: [HOST:getHostAddress(useIP)],
String dni = null, // Remove this when using device.deviceNetworkId
[callback: callbackParse], // Remove this when using device.deviceNetworkId
)
internal_ip contains the IP string like “192.168.1.49”
internal_port contains the port string like “80”
Then enter your device setting and save them so that the updated method is called. Then you should see the soap going to the IP. I just tested the below on my a device I use to hack and test and its parse function was called so it means the request went to the IP:port and got answered by my device.
If I don’t return the turnOn at the end of the method, nothing will happen