Using PHP to switch outputs without showing the URL in the HTML source

This post describes using PHP with HTML on a web page to turn on/off three imp output pins.
There are two scripts you need to put into your website (as shown below). The only change you need to make is to enter YOUR imp URL … the codes from the HTTP IN box on your planner.

The point of this post is to describe how to use a web page to affect an imp output without anyone seeing your imp URL. The imp code itself is not described here. The imp code I used is a modified version of the “porch light button”.

As of now, for the HTTP IN, you use the URL like this: https://api.electricimp.com/v1/… ?value=1
Doing that on a webpage, using a form, anyone can see the URL for which you POST the form. Not very secure.

===================================================================
EDIT:
As I discovered, this can be done with one script as MikeyDK figured out.
http://forums.electricimp.com/discussion/comment/3365#Comment_3365

I’ll leave my post and scripts on here … but the “single script” method takes care of all my woes.
Thanks MikeyDK … I think this will help other people.

So, with PHP, you can use CURL to post the value to the imp http api. Nobody can see the URL. One problem with posting values to a URL is that fact that after the post is sent, the PHP script can’t redirect after the CURL (headers already sent error). You might notice the same thing happening with apps (like Android). The imp returns the “OK” and your website script is done. You can’t get back to your html form page without hitting your browser back button.

To get around this, you can reference the https://api.electricimp.com/v1/… ?value=1 URL as an image. The act of referencing that as an image performs the HTTP IN on the imp side, and is a part of the HTML on your webpage - the same webpage that has the form.

Example, putting this in your HTML webpage will post the value to your HTTP IN:

Two things will happen when you use the imp URL in the src tag:

  1. Again, people can see the imp URL when they view the HTML source. We don’t want people to see that URL.
  2. The image on the browser is a box with the [x] in it … it’s not a real image (appears as a broken image).

So, you create a webpage, we’ll call it “index.php”. You have a form which calls the same script as itself. When you select a radio button, it references another PHP script as the image. I don’t want the image to show (box with an [x] in it), so I use CSS to hide that on the screen.

Here is “index.php” …
I can turn on/off any of 3 output pins.
In my imp code, I look for the value and determine which pin to affect.

#image{ display:none; } <?php if($_POST['v']==="90" || $_POST['v']==="91" || $_POST['v']==="80" || $_POST['v']==="81" || $_POST['v']==="70" || $_POST['v']==="71"){ $v=$_POST['v']; $url = "send_imp.php?v=".$v; echo "
"; } ?> OUTPUT 7: ON OFF OUTPUT 8: ON OFF OUTPUT 9: ON OFF

============================================================================

Here is the PHP script called “send_imp.php” …
This does the PHP CURL to post the value to the imp URL and returns back the fake image without the “header already sent” problem.
It is accomplishing this by using PHP GD to create a “fake” or “garbage” JPG image using the imp URL.

=============================================================================

<?php if(strlen($_GET['v'])>1){ // put your imp URL reference (the URL from your HTTP IN box) on this next line. $rURL = "https://api.electricimp.com/v1/b451e3adsf1/15s5sdf4a7/?value=".$_GET['v']; $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "$rURL"); curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1); curl_setopt($ch, CURLOPT_HEADER, 0); $out = curl_exec($ch); curl_close($ch); $imgRes = imagecreatefromstring($out); header("Content-Type: image/jpg"); imagejpeg($imgRes, NULL, 70); imagedestroy($imgRes); exit(); } ?>

=========================================

Why not just do it all in the same php file? That could be done like this.

Script removed, see my next reply for the working one: http://forums.electricimp.com/discussion/comment/3365#Comment_3365

I just removed my first and linked to my second… Yours might be useful for some… maybe do the same, clearly link to my post with the single file working one, but keep the code you got too.

I’m glad now that I started this thread … that PHP issue was troubling me.

Now, as I had asked in a different thread, it would be nice to query the imp using PHP and find out ahead of time what the states are of the outputs. I want to be able to determine which radio button to mark as “selected”. Perhaps Hugo and them are working on an agent that will make this easier. I don’t see a way to find out what the current states are.

You could always save what you send to it last, or use “HTTP request” to have the imp report back what it just did, and maybe on a timer have it send the statuses back too, just to make sure it is in sync.

Did you try that to see if it works? I don’t think it will. If it does, then I must be doing something wrong, or my webhost has something configured differently. For me, that single script doesn’t change my imp outputs. (I just tried it)

EDIT:

So here’s what is happening …
That single script works on one site I have, but on a different site with a different webhost, it does not work. So, I guess shared webhosts have different configuration settings, or different PHP versions?

That sort of complicates things now (for me).

Oh well … now this thread shows different ways of doing it (which is a good thing).
For PHP newbies, it’s all with CURL.

.

I am sorry, I forgot something… Not sure how that original one would work, since it does not specify how to handle the SSL either… which is also the part I just forgot to include…

`<?php
$v = $_POST[‘v’];

if($v == “90” || $v == “91” || $v == “80” || $v == “81” || $v == “70” || $v == “71”)
{
$rURL = “https://api.electricimp.com/v1/b451e3adsf1/15s5sdf4a7/?value=” . $v;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $rURL);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_exec($ch);
curl_close($ch);

}
?>

OUTPUT 7: ON OFF
	<form action="<?=$_SERVER['php_self']?>" method="post">
		OUTPUT 8: 
		<input type="radio" name="v" onclick="javascript: submit()" value="81"> ON
		<input type="radio" name="v" onclick="javascript: submit()" value="80"> OFF
	</form>
	
	<form action="<?=$_SERVER['php_self']?>" method="post">
		OUTPUT 9: 
		<input type="radio" name="v" onclick="javascript: submit()" value="91"> ON
		<input type="radio" name="v" onclick="javascript: submit()" value="90"> OFF
	</form>
</body>
` Here it is, and working. Just tested it on my imp.

I’m looking at both webhosts I have (PHP info) and trying to see what might be different. It works fine on one website, but not the other. Might it have to do with PHP “safe mode” on or off?

What about the second one? That one should work.

Success! Now it works on BOTH webhosts (with the 2nd one).

That makes it easier now. Thanks.

Now, do I erase the first post I made, or leave it alone. This thread might help some people, but they may copy the wrong script. Or is this discussion OK with all of the script variations?

Thanks … that will be my next goal … to make something like that.
Since the website can be viewed from anywhere, I might have to do the “save last action” method. I also need to handle the refreshing of the browsers in case 3 people are viewing the webpage at the same time. All 3 people need to see the current state when they look at their browser. Do you have any inside information at imp about some up-coming agents or improvements that would make this easier?

Give me 10…

This is what I just made for mine… It might not be the world best way to do it, but this might help you further.

`<?php
$url = “https://api.electricimp.com/v1/xxxxxxxxxxxxx/xxxxxxx”;

if (!file_exists(“pin.states”))
{
$fh = fopen(“pin.states”, ‘w’) or die(“can’t open file”);
fwrite($fh, “0,0,0,0,0,0,0,0,0”);
fclose($fh);
}

$v = $_POST[‘v’];

if(isset($v))
{
$pinStates = explode(",", file_get_contents(‘pin.states’));

if(substr($v, 0, 4) == "pin,")
{
	$pin = substr($v, 4, 1);
	$state = substr($v, -1);
	
	$pinStates[$pin] = $state;
}

$fh = fopen("pin.states", 'w') or die("can't open file");
fwrite($fh, implode(",", $pinStates));
fclose($fh);

$url .= "?value=" . $v;

$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_CONNECTTIMEOUT, 1);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
curl_setopt($ch, CURLOPT_SSL_VERIFYPEER, FALSE);
curl_setopt($ch, CURLOPT_SSL_VERIFYHOST, 2);
curl_exec($ch);
curl_close($ch);

}

?>

Permanent state:

OUTPUT 1: > ON > OFF
	<form action="<?=$_SERVER['php_self']?>" method="post">
		OUTPUT 2: 
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,2|mode,s|state,1"<?php if($pinStates[2] == "1") { echo " checked"; } ?>> ON
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,2|mode,s|state,0"<?php if($pinStates[2] == "0") { echo " checked"; } ?>> OFF
	</form>
	
	<form action="<?=$_SERVER['php_self']?>" method="post">
		OUTPUT 5: 
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,5|mode,s|state,1"<?php if($pinStates[5] == "1") { echo " checked"; } ?>> ON
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,5|mode,s|state,0"<?php if($pinStates[5] == "0") { echo " checked"; } ?>> OFF
	</form>
	
	<form action="<?=$_SERVER['php_self']?>" method="post">
		OUTPUT 7: 
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,7|mode,s|state,1"<?php if($pinStates[7] == "1") { echo " checked"; } ?>> ON
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,7|mode,s|state,0"<?php if($pinStates[7] == "0") { echo " checked"; } ?>> OFF
	</form>
	
	<form action="<?=$_SERVER['php_self']?>" method="post">
		OUTPUT 8: 
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,8|mode,s|state,1"<?php if($pinStates[8] == "1") { echo " checked"; } ?>> ON
		<input type="radio" name="v" onclick="javascript: submit()" value="pin,8|mode,s|state,0"<?php if($pinStates[8] == "0") { echo " checked"; } ?>> OFF
	</form>
</body>
` This will work with: http://pastebin.com/sqZNALd0

Mikey …

What I ended up doing:

I added an output node and with every watchdog trigger (60 second interval), I post the pin states to a text file on my server. I also post the pin states if any of the pins are turned on or off. So I have the HTTP IN and an HTTP REQUEST (post) both working together. This is working great. As a good side-affect, I also save a timestamp whenever the text file is updated. If at any time, it hasn’t been updated within 60 seconds of my current time, I know that communication with the imp has been lost. That gets indicated on my web page. I left my browser up and disconnected the power to my imp. After a bit, the COMM LOST message appears on my browser. I could also have PHP do an SMS message to my cell phone letting me know the imp has died.

I’m now working on a good GUI that refreshes and keeps the states current, which in my case, keeps the correct radio buttons “checked”. This part is javascripting.

So, it’s all coming together. I really have no plans for what to use this for, but I’m new to the imp and this is a great learning experience for me.

Thanks for holding my hand through this.

Also … you seem to be very experienced at the imp and PHP. Maybe we should create some good PHP/imp scripting examples for others. I’m not finding many examples or tutorials pertaining to this. But then again, the imp is very new.

.

I have thought about doing so, but due to come changes at work, a lot of my energy is spend there. At some point I am planning on making an Imp category on my blog though :slight_smile:

http://captain-slow.dk/ so far it is mostly electronics and 3d printing on it…