Remote Update of Endpoint Devices Fails without Error

I have a Windows-based Java program that calls a PHP file passing to it several parameters. This same PHP file takes the parameters and generates the appropriate URL to send to a ST endpoint device to turn it on/off. The created URL is logged (for debugging purposes) then sent such as "http://graph.api.smartthings.com/api/smartapps/installations/…"
The state of this ST device never changes when called via the Java program, however, I can take the same URL from the log, plunk it into the browser address bar and the device state changes accordingly. In fact I can manually call the PHP files with the appropriate parameters identical to that passed by the Java program and the ST device responds accordingly.

My first reaction was to assume that the problem lies with the Java program even though I confirmed that the URL generated through this method is working properly when passed via browser. However, to confirm there was a problem using the Java program method, instead of calling “http://graph.api.smartthings.com/api/smartapps/installations/…” I changed the URL to several different sites (i.e. http://homeAppache.server.com/event/OfficeOff) and noticed that each of these worked as expected.

After several days of trying everything under the sun to get this to work I have come to the conclusion that the “problem” (maybe some security thing?) lies at the ST end. I base this conclusion on my work over the past week AND some very similar behaviour I found using Alex ActiON Dashboard". In the case of the latter, the Dashboard will not load the video of 2 of my cameras showing the typical “broken link” icon. If I right click either of these and “Inspect the element”, copy the URL found inside the source file, paste it into a browser address bar then refresh ActiON Dashboard, it will now display the video for that camera. Like in my case with the Java–>PHP problem, ActiON Dashboard file generated the correct URL but ST does not respond accordingly. That same URL can be copy and pasted into a browser address bar and the end result is as expected.

This one problem is the only obstacle in my way of totally integrating Wemo device into ST. I am lost at what to do next. Anyone have any idea where I can look for a solution to this or who I can contact regarding this issue.

What other information do you have in the logs for the Java app? How are you making the HTTP call to the PHP server in Java? Are you logging other information including response codes (or other response header/body information)?

1 Like

The Java program is WemoServer written by MikeP. I create a rule that when any wemo state changes the WemoServer does a sendHTTP to the URL I specified in the rule.

The Java log shows what call (the URL) was made (from Java) and the value of each parameter passed. It also showed what happened within the PHP routines (i.e the URL to ST) and that, yes, ST was called with the correct URL but nothing else is shown, not even an error. This output I see in the log file is identical to what I see if I execute the PHP file with the same parameters from a browser except the latter results in the ST switch being turned on/off.

I have tried several ways to call ST from within PHP. For instance:

echo “iframe src=‘$url’>/iframe>”;
OR
header(‘Location: " . $url’);

Each of the methods tried worked fine when loading the PHP from a browser. It did not work when called from the java program. I cant emphasize this enough but one of the first thing the php file does is record the URL and parameters that were used to load it. Regardless of whether I used the Java approach or browser, this URL is identical.

So, as a last ditch effort I installed “curl” on my PC and this time I called ST with the following
shell_exec('C:\curl\cURL\bin\curl ’ . $url);

IT WORKED!!!

Still baffled though why any other approach did not work when called from java but did did work from within a browser.
To summarize:
To make it work from Java, I changed

echo ‘iframe src=’$url’>/iframe’
TO
$output = shell_exec('C:\curl\cURL\bin\curl ’ . $url);

Nothing less, nothing more :flushed:

Thanks for the additional commentary as it provides some insights. Keep in mind that when you open up a URL in your browser, the browser actually renders the content and may make an additional web requests based on the rendered content. For example, if you are echoing out an IFrame in PHP (which calls an ST URL), then that call via the IFrame will only be made in a client that actively renders the DOM.

So when you open your browser and hit a PHP page that has an IFrame in it, the browser will render the HTML and realize there is an IFrame and will then attempt the request for the SRC URL of the IFrame. If the Java application is just making an httpclient or httpurlconnection or something similar, then it isn’t actually rendering the content that gets returned from the PHP page, so it just gets the content which has <html><head></head><body><iframe src='STURL'></iframe></body></html> but the request is never made to STURL.

This is where having the Java app make the call directly to ST -or- having the Java app call the PHP app which makes the call directly to the STURL would work.

To summarize, the change from “echo iframe” to “shellexec curl” effectively changed the responsibility of which client was making the request to STURL. In the “echo iframe” example, the PHP app was expecting the calling client to ultimately make the request to SmartThings (which didn’t happen in the Java app). In the “shellexec curl” example, the PHP app is making the request directly to SmartThings.

Edit:
You should also be able to get PHP to make a direct HTTP GET call to the ST URL by using the function file_get_contents() - this is a built in PHP function so you wouldn’t need to install CURL or call shell_exec which isn’t allowed in some PHP instances.

1 Like

Thank you very much for such a clear and descriptive response. Makes total sense.
As for the file_get_contents(), I had give that (albeit half heartedly) a try without much success. Will need to look into this a bit more as adding yet another layer (curl for Windows) into this mix is not any too appealing :smile: