Your Universal Remote Control Center
RemoteCentral.com
Philips Pronto Professional Forum - View Post
Previous section Next section Previous page Next page Up level
Up level
The following page was printed from RemoteCentral.com:

Login:
Pass:
 
 

Page 1 of 3
Topic:
Philips HUE controls
This thread has 44 replies. Displaying posts 1 through 15.
Post 1 made on Sunday September 22, 2013 at 10:05
bibi-12
Long Time Member
Joined:
Posts:
February 2008
16
Hi,

I'm trying to control my philips hue bulbs with Pronto. It uses en http protocol
(see: [Link: developers.meethue.com])

Here is my code for now:
var socket = new TCPSocket(false);
var chaine=""
var JSON_Test = '{"devicetype":"test user","username":"newdeveloper"}';
System.print("call connect");

socket.connect('192.168.0.158', 80, 3000);




function getInfos()
{
socket.write("POST /api HTTP/1.1 \r\n\r\n"+JSON_Test);


}

socket.onConnect = function()
{
getInfos();
};

socket.onData = function()
{

result += socket.read();


};

socket.onClose = function()
{

var resultStartIndex =result.indexOf("\r\n\r\n");
var jsonData = result.substring(resultStartIndex+4);

System.print("resultas: "+jsonData);

}




When I use that, the response is:
[{"error":{"type":5,"address":"/","description":"invalid/missing parameters in body"}}]

I am probably wrong with the JSON object i tried to sent, but i don't know how to solve that.

Can anyone please help me ?
OP | Post 2 made on Sunday September 22, 2013 at 14:52
bibi-12
Long Time Member
Joined:
Posts:
February 2008
16
Ok I found my mistake.

I forgot the Content-Length:
Post 3 made on Saturday September 28, 2013 at 03:04
brentwoods
Lurking Member
Joined:
Posts:
May 2008
4
Hi bibi-12

I am trying to create some code to control my Hue lights using a Pronto TSU9400.

I am completely new to using Pronto for Network (TCP) communications.

Can you show an example of your code which is working to control Hue?

Thanks
Brent
OP | Post 4 made on Saturday September 28, 2013 at 05:15
bibi-12
Long Time Member
Joined:
Posts:
February 2008
16
Hi

Here is my code that turn on the light:


var socket = new TCPSocket(false);
var result="";

socket.connect('192.168.0.158', 80, 3000);
var JSON_on='{"on": true,"bri":144,"hue":13122,"sat":211,"ct":467,"xy": [0.5119,0.4147]}';

function getInfos(commands)
{
socket.write('PUT /api/newdeveloper/groups/all/action HTTP/1.1\r\nContent-Length: '+commands.length+'\r\n\r\n'+commands);

}

socket.onConnect = function()
{
getInfos(JSON_on);
};

socket.onData = function()
{

};

socket.onClose = function()
{
socket = null
}

socket.onIOerror = function() {
System.print("error");
try {
socket.close()
socket = null
} catch(e) {}
}


You have to create a new user before :


var socket = new TCPSocket(false);

socket.connect('192.168.0.158', 80, 3000);

function setUser()
{
socket.write('POST /api HTTP/1.1\r\nContent-Length: 64\r\n\r\n{"devicetype":"test user","username":"newdeveloper"}');
}

socket.onConnect = function()
{
setUser();
};

socket.onData = function()
{
result += socket.read();
};

socket.onClose = function()
{
var resultStartIndex =result.indexOf("\r\n\r\n");
var jsonData = result.substring(resultStartIndex+4);
}
Post 5 made on Saturday September 28, 2013 at 10:43
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,985
Make sure this is the last line that is executed.

socket.connect('192.168.0.158', 80, 3000);

Your connect is likely occurring prior to you defining all your callback functions.
Lyndel McGee
Philips Pronto Addict/Beta Tester
Post 6 made on Saturday September 28, 2013 at 11:16
brentwoods
Lurking Member
Joined:
Posts:
May 2008
4
Thanks so much! That is working.

Where should I place the code to create the new user (newdeveloper)?

Also, if I need to execute several commands in a row, do I need to repeat the entire code every time, or can I put multiple socket.write lines inside the function.getInfos part?

eg.:
function getInfos(commands)
{
socket.write(1st command);
socket.write(2nd command);
socket.write(3rd command);
}


Thanks again for your help!
Brent
Post 7 made on Saturday September 28, 2013 at 16:25
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,985
The answer depends on the protocol and whether HTTP socket is being closed by the server. If server closes the socket on you, you have no choice but to open another. In theory, you could write as many commands as you like by calling getInfos() multiple times from onConnect. Note that this only works as long as the socket remains open.
Lyndel McGee
Philips Pronto Addict/Beta Tester
OP | Post 8 made on Saturday September 28, 2013 at 18:04
bibi-12
Long Time Member
Joined:
Posts:
February 2008
16
I have un problem with socket.The error is " Maximum active socket count reached" but I close the socket I don't understand why the maximum socket count is reached.

Have I missed something in my code?


var brightness=0;

onRotary = function(clicks)
{

if (socket_bri && socket_bri.connected)
{
try
{ socket_bri.close();
}
catch (e)
{
Diagnostics.log('close error! e: ' + e);
}
finally
{
socket_bri = null;
}
}

if (clicks >= 3)
{
socket_bri=null;
var socket_bri = new TCPSocket(false);
brightness=parseInt(brightness)+5*clicks<=255?parseInt(brightness)+5*clicks:255;
var JSON_commande='{"bri":'+brightness+'}';
socket_bri.connect('192.168.0.158', 80, 3000);

function setBright(commands)
{
socket_bri.write('PUT /api/newdeveloper/groups/all/action HTTP/1.1\r\nContent-Length: '+commands.length+'\r\n\r\n'+commands);

}
socket_bri.onConnect = function()
{
setBright(JSON_commande);

};
socket_bri.onClose = function()
{
socket_bri = null;

}
socket_bri.onIOerror = function()
{
System.print("error");
try {
socket_bri.close()
socket_bri = null
} catch(e) {}



}


}}
Post 9 made on Sunday September 29, 2013 at 00:30
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,985
I am having trouble gathering all my thoughts on your issue tonight so apologies if this is confusing. There are quite a few issues happening here.

Here is one issue you should be aware of but it is not the cause of your root problem.

try{
socket.close();
socket = null;
}
catch(e)
{
}

The above code will NOT set the socket to null if the close fails (an error is thrown).


My recommendation for debugging and better understanding what is going on is to robustly issue system.prints whenever you are referencing a socket variable for write, close, connect, create, or set to null. However, there is no 'identifier' on a socket that tells you which one it is. But you can overcome this with a little extra work.

Create an integer counter varibble that starts at 0 that can be used to indicate the number of times you have created a socket. As the 'socket' is a Javascript object, you can add fields to it. Set a counter field on your socket that you can use for debugging. For example, socket_bri.myCounter = ++currCounterValue;

Then, in all places where you are referencing a non-null socket, do a System.print(socket_bri.myCounter);

This will help you better understand the asynchronous socket events and lifecycle and also help you isolate and understand the issue.

I strongly suspect is happening is that you are doing a quick OnRotary turn and generating lots of occurrences where clicks > 3. As your code calls out, your connect timeout is 3000ms. So, on previous click iteration, you created a socket and requested a connect. When the next click iteration comes through, the following condition does not hold true.

if (socket_bri && socket_bri.connected)
{
// the close in here will never take place because not connected. A System.print() will confirm this. :-)
}

socket_bri = null; // Releases the refrence to the variable but the socket is still trying to connect and is never closed... :-)

Once connected, your code is issuing a write to socket_bri which may NOT be the socket that was connected in the OnConnected callback. That is, you might have already reassigned another socket to the variable as OnRotary might be occurring many times within the time it takes for the socket to connect. I might suggest using the 'this' keyword to get the real socket on which the callback is occurring and pass that to your write function as a parameter.

socket_bri.onConnect = function()
{
setBright(this,JSON_commande);
// new code to force the current socket to be closed (note use of 'this' keyword)
if (this.connected)
{
try{this.close()}catch(e){}
}
if (socket_bri === this)
{
// if what is happening is what I believe, this line will rarely be executed. System.print() will confirm.
socket_bri = null;
}
};

I would also change setBright to accept 2 parameters to be sure that you are always writing to the socket that was just connected. The way you have the function defined, it could be writing to an instance of a socket that has not yet fully connected as you are cleared and reset socket_bri in the OnRotary callback.

function setBright(sock, command)
{
if (sock.connected)
sock.write(command);
}


The above suggestions should help to if not almost completely eliminate your maximum socket issue. However, if you turn that scroll wheel very fast, you can still have issues.

All of this will better help you understand the issue. The most robust solution is a code rework once this all sinks in.

Please make these changes and see if my assumptions are correct. At that point, we can discuss how to make this code more bulletproof with some reorganization.

Lyndel

Last edited by Lyndel McGee on September 29, 2013 01:12.
Lyndel McGee
Philips Pronto Addict/Beta Tester
OP | Post 10 made on Sunday September 29, 2013 at 05:17
bibi-12
Long Time Member
Joined:
Posts:
February 2008
16
Thanks for your help.
I still have the same isues.

...if (socket_bri === this)
{
// if what is happening is what I believe, this line will rarely be executed. System.print() will confirm.
socket_bri = null;
}

This line is executed very often (each time I scroll the wheel it seems).

The counter of socket is always increasing. It seems the socket_bri.onClose function is never executed and maybe that is the main problem. But I don't understand why it's not executed.
Post 11 made on Monday September 30, 2013 at 18:36
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,985
0) The counter was suggested so you can see which instance of the socket is the one with which you are working.

1) Quote: This line is executed very often (each time I scroll the wheel it seems).

Which line is executed very often, the check to seeif socket_bri == this or the actual set to null for socket_bri?

2) Did these lines execute - these were immediately before set to 'null'?

if (this.connected)
{
try{this.close()}catch(e){}
}


3) OnClose is not executed because you used HTTP1.1 instead of HTTP1.0 where the server will close the socket. Change HTTP1.1 to HTTP1.0 and see if they start closing. Note that this will still not resolve your issue as you are scrolling the wheel too much prior to when socket can connect, send the command, and clean up. Also note that you only get OnClose() notifications when the remote side closes the socket. Not when you close the socket. (That's why I suggested HTTP1.0 instead of HTTP1.1).

Try with HTTP1.0 and see if results are better. Note that this will still not fix your issue.

Please post the complete updated code that you are using, including the declaration of your variable socket_bri. This will allow me to see just how far you have gotten and will also serve to self-document what you have done.
Lyndel McGee
Philips Pronto Addict/Beta Tester
OP | Post 12 made on Tuesday October 1, 2013 at 07:56
bibi-12
Long Time Member
Joined:
Posts:
February 2008
16
here is the code:

var brightness=0;
currCounterValue=0;

onRotary = function(clicks)
{


if (clicks >= 3)
{
socket_bri=null;
var socket_bri = new TCPSocket(false);
socket_bri.myCounter = ++currCounterValue;
System.print("counter: " +socket_bri.myCounter);
brightness=parseInt(brightness)+5*clicks<=255?parseInt(brightness)+5*clicks:255;
var JSON_commande='{"bri":'+brightness+'}';
socket_bri.connect('192.168.0.158', 80, 500);

function setBright(sock,commands)
{
if (sock.connected)
socket_bri.write('PUT /api/newdeveloper/groups/all/action HTTP/1.1\r\nConnection: close\r\nContent-Length: '+commands.length+'\r\n\r\n'+commands);
System.print("counter_f: " +socket_bri.myCounter);

}
socket_bri.onConnect = function()
{
setBright(this,JSON_commande);
if (this.connected)
{
try{this.close()}catch(e){}
}
if (socket_bri === this)
{
// if what is happening is what I believe, this line will rarely be executed. System.print() will confirm.
System.print("It is happening");
System.print(socket_bri.myCounter);
socket_bri = null;
}

};
socket_bri.onClose = function()
{
System.print("count_close: "+socket_bri.myCounter);
socket_bri = null;


}
socket_bri.onIOerror = function()
{
System.print("error");
try {
socket_bri.close()
socket_bri = null
} catch(e) {}



}


}

};

It seems to work quite well with HTTP 1.0
Post 13 made on Tuesday October 1, 2013 at 19:24
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,985
Well, if you want to leave at HTTP1.0, that is fine by me. If you run into further issues, this code could use a good restructuring.
Lyndel McGee
Philips Pronto Addict/Beta Tester
Post 14 made on Saturday November 16, 2013 at 21:17
brentwoods
Lurking Member
Joined:
Posts:
May 2008
4
Hi

I'm trying to add an off timer for my Hue lights as part of my "Go To Bed" macro which will turn off all AV equipment, as well as turning on the Hue lights in the bedroom. I would also like it to turn on the living area lights, and then set a timer to switch them off after 5 minutes.

I initially didn't know the command to set a timer in the Hue bridge, but Leonmeijer on the everyhue forum kindly provided me with the following code to help out:


{
"name": "some name",
"description": "Fade light/group to bri = 0 in 5 minutes.",
"command": {
"address": "/api/key/groups/1/state",
"body": {
"transitiontime": 3000,
"bri": 0
},
"method": "PUT"
},
"time": "PT00:00:01",
}

(here's the link to the actual discussion: [Link: everyhue.com])

The syntax for sending the commands using Pronto Script is a little different (thanks to bibi-12 and Lyndell for your help so far!)

Where in the Pronto Script should I include the "time" command which sets the timer in the Hue bridge?

I've tried adding it to the variable JSON_on, but this doesn't work.


My 2nd question relates to issuing several commands in a row. To achieve what I want with the timers, I actually need to set two timers (as per the advice from Leonmeijer). One timer runs after one second and begins the slow fade to minimum brightness. The second timer runs after 4:59 and turns the lights off completely.

I have not managed to figure out how to send multiple commands in a single button press. Any ideas how I should be approaching that? I've tried using HTTP 1.1 and 1.0 but without success.

Thanks for any help!
Brent
Post 15 made on Sunday November 17, 2013 at 17:03
Lyndel McGee
RC Moderator
Joined:
Posts:
August 2001
12,985
Have a look at Activity.scheduleAfter in conjunction with Widget.scheduleActions. Note that if you leave the current activity, the task you submitted with scheduleAfter will not occur. Also, if the remote is asleep (not docked), your task may not run.
Lyndel McGee
Philips Pronto Addict/Beta Tester
Page 1 of 3


Jump to


Protected Feature Before you can reply to a message...
You must first register for a Remote Central user account - it's fast and free! Or, if you already have an account, please login now.

Please read the following: Unsolicited commercial advertisements are absolutely not permitted on this forum. Other private buy & sell messages should be posted to our Marketplace. For information on how to advertise your service or product click here. Remote Central reserves the right to remove or modify any post that is deemed inappropriate.

Hosting Services by ipHouse