if (client.connect(server,80))
{
client.println("PUT /api/newdeveloper/lights/3/state HTTP/1.1");
client.println("{\"on\":false}");
}
I get some type of response, but the light doesn’t actually change, running the same command through the philips gui works fine.
In addition, I’m wondering how to properly format my code to be able to update the PUT requests in the loop so I can begin to manipulate the lights through hardware buttons.
If anyone has any guidance on this it would be a huge help!
I don’t know much about requests, so if I wanted to make a new request after this would it just be a matter of making an empty client.println(""); or do I actually have to do something like client.println("Connection: keep-alive"); and then just send more requests with the PUT command.
Also, do I need to be changing the content length for every different command that is sent?
edit: sorry if this stuff is really basic, I’ve been trying to find a good intro to learning this stuff but haven’t been very successful.
I just noticed that the Host header is also required for all HTTP 1.1 requests, so you’ll want to make sure to include that as well.
PUT /api/newdeveloper/lights/3/state HTTP/1.1
Host: 192.168.1.10
Content-Type: application/json
Content-Length: 14
{\"on\":false}
To do multiple requests per connection, you specify the Connection: keep-alive header on the first request, then Connection: close on the last request like this:
PUT /api/newdeveloper/lights/3/state HTTP/1.1
Host: 192.168.1.10
Connection: keep-alive
Content-Type: application/json
Content-Length: 14
{\"on\":false}
PUT /api/newdeveloper/lights/3/state HTTP/1.1
Host: 192.168.1.10
Connection: close
Content-Type: application/json
Content-Length: 13
{\"on\":true}
And yes, you need to set the content-length for each request.
Thanks Hypno! I’ve made some progress. Able to turn on and off lights and set states so long as I know what I want. Now I’m attempting to hook up a pot value to the brightness. This is where I am:
TCPClient client;
byte server[] = { 192, 168, 1, 10 }; // Google
int potPin = A0;
int val = 0;
int prev = 0;
void setup()
{
Serial.begin(9600);
delay(1000);
if (client.connect(server, 80)){
Serial.println("connected");
}
else{
Serial.println("fail");
}
}
void loop(){
val = analogRead(potPin);
val = map(val, 2, 4093, 0, 255);
Serial.println(val);
if (val != prev){
if (client.connected()){
client.println("PUT /api/newdeveloper/lights/3/state HTTP/1.1");
client.println("Host: 192.168.1.10");
client.println("Connection: keep-alive");
client.println("Content-Type: application/json");
client.println("Content-Length: 51");
client.println();
client.print("{\"on\":true,\"sat\":255,\"bri\":");
client.print(val);
client.println(",\"hue\":10000}");
Serial.println("sent");
}
else{
Serial.println("not connected/sending");
}
}
if (client.available())
{
//char c = client.read();
//Serial.print(c);
//delay(1000);
}
delay(10);
prev = val;
}
The issue is that this works the first time through the loop but nothing after that.
some obvious problems:
I don’t know how to get my content length if the int can be from 0-255.
I am probably making too many PUT requests (dont know whats the limit or how to throttle)
As far as the keep-alive stuff, maybe try a slight delay in between requests? When I was trying it, I was using a bash script + telnet to send multiple requests. Perhaps I should try to do it on a core. It also might have to do with the particular server you’re working with. It’s possible the server doesn’t support keep-alive requests.
Hey guys,
Thanks for all your help so far, I’ve made a bit more progress but I’m still having that issue where any subsequent requests don’t have any effect despite the fact that the client is connected. It’s only the first time through the loop that does anything. Maybe there is something I have to do to terminate the requests?
The Arduino code you pointed us at does that as well. Might not matter–depends on the parser, but worth a quick shot.
The Arduino code does client.stop() since it reconnects every time with a client.connect(). You only connect in setup, so your code never reconnects after a stop and seems hung (really client.connected() is never true).
Thanks for the catch! I’ve finally got it working!!
Seems like something was blocking before, but changing the structure helped.
Again, thanks @bko and @Hypnopompia!
I’ll probably be back with more questions soon.
TCPClient client;
byte server[] = { 192, 168, 1, 10 }; // Local light server
int potPin = A0; // Potentiometer Pin
int val = 0;
int prev = 0;
String stringOne; // empty string to store val length
unsigned int len; // length of val
void setup()
{
Serial.begin(9600);
delay(1000);
client.connect(server, 80);
if (client.connected()){ //initiate connection
Serial.println("connected");
}
else{
Serial.println("failed");
}
}
void loop(){
if (client.connect(server, 80)) {
if(client.connected())
{
val = analogRead(potPin); //read potentiometer
val = map(val, 2, 4093, 0, 255); //map it
String stringOne = String(val); //convert to string
unsigned int len = stringOne.length(); //get length
if (val != prev ){ // if new reading is different than the old one
client.println("PUT /api/newdeveloper/lights/3/state HTTP/1.1");
client.println("Connection: keep-alive"); //
client.println("Host: 192.168.1.10"); //same as server
client.println("Content-Type: text/plain;charset=UTF-8"); //
client.print("Content-Length: "); //param
client.println(11+len); //brightness string + val length
client.println(); // blank line before body
client.print("{\"bri\": ");
client.print(val); //value of potentiometer
client.println("}");
Serial.print("sent"); // command executed
delay(100); // slight delay IMPORTANT
prev = val; //set prev
}
}
client.stop();
Serial.println("stopping");
}
delay(10);
}
I think moving the client.connect() call into the loop is what fixed it. I suspect that even though all their examples include the Connection: keep-alive header, that they don’t actually support keep-alive requests. By moving the client.connect() into the loop, you are initiating a new connection each time.
If you want to be pedantic, you could replace Connection: keep-alive with Connection: close, which was what I was originally going to suggest. However, I’m guessing that this won’t make any difference to anything, either.
@callil
Could you please share the code that you used to turn the philips hue lights on or off using telnet? I’ve been trying to do that very thing. Just the simple command of all lights on or all lights off using a telnet command string.