PHP cURL script to control Roku box not working

I was reading here about the RESTful service accessed via the http protocol on port 8060. They provide command line curl examples, like:

$ curl -d '' http://192.168.1.134:8060/keypress/home

I need to write this as a PHP script that will execute a series of actions (all require just a POST request): keypress/home, launch/appid, keypress/select, keypress/right, keypress/right, keypress/select.

See below for what I came up with for one command. Two questions:

1) My Roku is not responding to this, so what am I doing wrong?
2) What’s the best way to send multiple POST requests one after the other?

<?php
$ch = curl_init('http://192.168.1.134:8060/keypress/home');
$data = '';

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, '$data');
curl_setopt($curl, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
?>

You shouldn’t have quotes around your $data variable. And you have a wrong variable name in one of your setopt calls, $curl instead of $ch.

<?php
$ch = curl_init('http://192.168.1.157:8060/keypress/home');
$data = '';

curl_setopt($ch, CURLOPT_POST, 1);
curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);

$response = curl_exec($ch);
curl_close($ch);
?>

Thanks, those were some dumb mistakes. However, even with those corrections, my Roku is not responding when I run the script.

Takes a long time for the script to run too, like 1.5 minutes.

Chris’ code works for me. It kind of sounds like you’re using the wrong IP address if it’s taking 1.5 minutes to complete.

-JT

Would it matter if I’m running the script on a remote web server? As long as the computer/browser that I’m executing it from is on the same network, shouldn’t it work?

“bryanharley” wrote:
Would it matter if I’m running the script on a remote web server? As long as the computer/browser that I’m executing it from is on the same network, shouldn’t it work?
If you’re using php, the code is running on the server, so it’ll only work if the server is on the same network as your Roku.

Oh duh. I need to use a public IP and port forward.

Alright, well now that I’m past that dumb mistake…

Is there a more efficient way of doing these multiple calls or is this OK?


<?php
$ch1 = curl_init('http://192.168.1.130:8060/keypress/home');
curl_setopt($ch1, CURLOPT_POST, 1);
curl_setopt($ch1, CURLOPT_POSTFIELDS, '');
curl_setopt($ch1, CURLOPT_RETURNTRANSFER, true);
 
$response1 = curl_exec($ch1);
curl_close($ch1);

$ch2 = curl_init('http://192.168.1.130:8060/launch/20802_6415');
curl_setopt($ch2, CURLOPT_POST, 1);
curl_setopt($ch2, CURLOPT_POSTFIELDS, '');
curl_setopt($ch2, CURLOPT_RETURNTRANSFER, true);
 
$response2 = curl_exec($ch2);
curl_close($ch2);

sleep(3);

$ch3 = curl_init('http://192.168.1.130:8060/keypress/select');
curl_setopt($ch3, CURLOPT_POST, 1);
curl_setopt($ch3, CURLOPT_POSTFIELDS, '');
curl_setopt($ch3, CURLOPT_RETURNTRANSFER, true);
 
$response3 = curl_exec($ch3);
curl_close($ch3);

$ch4 = curl_init('http://192.168.1.130:8060/keypress/select');
curl_setopt($ch4, CURLOPT_POST, 1);
curl_setopt($ch4, CURLOPT_POSTFIELDS, '');
curl_setopt($ch4, CURLOPT_RETURNTRANSFER, true);
 
$response4 = curl_exec($ch4);
curl_close($ch4);

$ch5 = curl_init('http://192.168.1.130:8060/keypress/select');
curl_setopt($ch5, CURLOPT_POST, 1);
curl_setopt($ch5, CURLOPT_POSTFIELDS, '');
curl_setopt($ch5, CURLOPT_RETURNTRANSFER, true);
 
$response5 = curl_exec($ch5);
curl_close($ch5);
?>

I am not a PHP witch doctor :face_with_tongue: but seems to me would be good to put all that stuff from curl_init to curl_close in a procedure/function and then call it repeatedly something like

post_roku_cmd('192.168.1.130', '/keypress/home')
post_roku_cmd('192.168.1.130', '/launch/20802_6415')

And you don’t need to hit Home before launching a channel (except maybe with screen saver, dont remember). Btw, if this is to be invoked from browser, best will be to so that without a server and server-side scripting - see how remoku.tv does it. Opening public port to home Roku is not something i’d recommend.

I agree it would be better to do this without a server.

Someone else wrote this javascript, but I was not able to get it to work client-side in a browser. Any idea why?

<script>
function post1() {
xdr = new XDomainRequest(); 
xdr.onload=function()
{
    alert(xdr.responseText);
}
xdr.open("POST", "http://192.168.110.100:8060/keypress/home");
xdr.send(); 
postdelay1();
}
function postdelay1() {
setTimeout("post2()",1000);
}
function post2() {
xdr = new XDomainRequest(); 
xdr.onload=function()
{
    alert(xdr.responseText);
}
xdr.open("POST", "http://192.168.110.100:8060/launch/12333");
xdr.send(); 
postdelay2();
}
function postdelay2() {
setTimeout("post3()",1000);
}
function post3() {
xdr = new XDomainRequest(); 
xdr.onload=function()
{
    alert(xdr.responseText);
}
xdr.open("POST", "http://192.168.110.100:8060/keypress/right");
xdr.send(); 
postdelay3();
}
function postdelay3() {
setTimeout("post4()",1000);
}
function post4() {
xdr = new XDomainRequest(); 
xdr.onload=function()
{
    alert(xdr.responseText);
}
xdr.open("POST", "http://192.168.110.100:8060/keypress/select");
xdr.send(); 
postdelay4();
}
function postdelay4() {
setTimeout("post5()",1000);
}
function post5() {
xdr = new XDomainRequest(); 
xdr.onload=function()
{
    alert(xdr.responseText);
}
xdr.open("POST", "http://192.168.110.100:8060/keypress/select");
xdr.send(); 
postdelay5();
}
function postdelay5() {
setTimeout("post6()",1000);
}
function post6() {
xdr = new XDomainRequest(); 
xdr.onload=function()
{
    alert(xdr.responseText);
}
xdr.open("POST", "http://192.168.110.100:8060/keypress/select");
xdr.send(); 
}
</script>
<body onload="post1()">

“bryanharley” wrote:
Someone else wrote this javascript, but I was not able to get it to work client-side in a browser. Any idea why?
I believe XDomainRequest is a IE only object, so that script will only work in Internet Explorer.

Right, and I’ve been testing it in IE 11 on a computer on the same network as my Roku. Can’t get it to work though.

Ah, looks like XDomainRequest is depreciated in IE 11, need to use XMLHttpRequest instead.