Making a PUT request with arduino ethernet

I'm trying to send a JSON string via PUT from an arduino in order to control a philips Hue smart light. I've googled and found a lot about POST and GET, but not much on PUT. I'm attempting to PUT "{"on":false}" to my local Hue bridge (/api/hueuser/lights/1/state), but don't now how to format it. Can anyone help me out? Here's what I'm trying:

if (client.connect("192.168.1.8",80))
  {

   client.print("PUT /api/hueuser/lights/1/state HTTP/1.1");

   client.print("Host: 192.168.1.8\n");                          
    client.print("Connection: close\n");
 
    client.print("Content-Type: text/plain; charset=UTF-8\n");
    client.print("Content-Length: 12 \n ");

    client.print("{\"on\":false}\n");}

I haven't tried it, but this should work according to the protocol.

IPAddress server(192,168,1,8);

if (client.connect(server,80))
{
   client.println("PUT /api/hueuser/lights/1/state HTTP/1.1");
   client.println("Host: 192.168.1.8");                          
    client.println("Connection: close");
    client.println("Content-Type: application/x-www-form-urlencoded");
    client.println("Content-Length: 10\r\n");
    client.print("\"on\":false");
}

edit: Added missing semicolon in code.

Thanks for replying. I didn't have any success with your code, so I looked at the console of the Hue API tool, and here is the header info it uses:
Accept text/html,application/xhtml+xml,application/xml;q=0.9,/;q=0.8
Accept-Encoding gzip, deflate
Accept-Language en-us,en;q=0.5
Connection keep-alive
Content-Length 12
Content-Type text/plain; charset=UTF-8
Host 192.168.1.8
Referer http://192.168.1.8/debug/clip.html
User-Agent Mozilla/5.0 (Macintosh; Intel Mac OS X 10.9; rv:12.0) Gecko/20100101 Firefox/12.0

So I changed the code to this, but still had no luck:

#include <SPI.h>
#include <Ethernet.h>


byte mac[]     = { 0x90, 0xA2, 0xDA, 0x0D, 0x83, 0x9D };

byte ip[]      = { 192, 168,   1,  199 }; 
byte gateway[] = { 192, 168,   1,  1 };   
byte subnet[]  = { 255, 255, 255,   0 };   



void setup()
{
  Ethernet.begin(mac, ip); 
 Serial.begin(9600); 
 delay(1000);
}
void loop()
{ 

 EthernetClient client;



IPAddress server(192,168,1,8);

if (client.connect(server,80))
{
   client.println("PUT /api/hueuser/lights/1/state HTTP/1.1");
   client.println("Host: 192.168.1.8");                          
    client.println("Connection: keep-alive");
    client.println("Content-Type: text/plain; charset=UTF-8");
    client.println("Content-Length: 12\r\n");
    client.print("\"on\":false");
    client.print("Referer: http://192.168.1.8/debug/clip.html");
}
  else
  {
    Serial.println("Connection Failed.");  
   Serial.println();
  }
 delay(5000); 
}

Does it use port 80?

It looks like you need to be sending a username and devicename too.

The following link seems to have some useful information on the API

You must complete the request by reading the response, then closing the connection. Maybe what the server sends will help you troubleshoot it.

if (client.connect(server,80))
{
   client.println("PUT /api/hueuser/lights/1/state HTTP/1.1");
   client.println("Host: 192.168.1.8");                          
    client.println("Connection: keep-alive");
    client.println("Content-Type: text/plain; charset=UTF-8");
    client.println("Content-Length: 12\r\n");
    client.print("\"on\":false");
    client.print("Referer: http://192.168.1.8/debug/clip.html");

    // read the server response
    while(client.connected()) {
        while(client.available()) {
            char ch = client.read();
            Serial.write(ch);
        }
    }

    // close the connection
    client.stop();      
    Serial.println("disconnected");
}

Hi,

I've been playing with this for some time because I wanted physical switches to control a few Hue lights. The current setup uses HT6P20B garage door remote controls and a 433.92MHz receiver to send commands to the Hue hub from an Arduino UNO with W5100 shield.

The 3 remote buttons can turn lights on/off and cycle through brightness and hue. You can see how it works at Hue_W5100_HT6P20B - YouTube.

The code is too large to post here, I saved it to github at oguime/Hue_W5100_HT6P20B

By the way, thanks Afonso for the HT6P20B code!

Regards,
Gilson

Old topic but it still helped me:

The only thing that was missing was

client.println("Content-Length: 12\r\n");
client.print("{\"on\":false}");

Notice the {}

if (client.connect(server,80))
{
  client.println("PUT /api/hueuser/lights/1/state HTTP/1.1");
  client.println("Host: 192.168.1.8");                          
  client.println("Connection: close");
  client.println("Content-Type: application/x-www-form-urlencoded");
  client.println("Content-Length: 10\r\n");
  client.print("{\"on\":false}");  
}

delay(10);

// Read all the lines of the reply from server and print them to Serial
while (client.available()) {
	String line = client.readStringUntil('\r');
    Serial.print(line);
}

Serial.println();
Serial.println("closing connection");

I came across this topic on my way of looking for a solution to turn on/off my DeConz controlled ZigBee lights via Arduino. After a lot of trial and error, this is the simplest solution I have found:

#include <ArduinoHttpClient.h>
char httpserverAddress[] = "192.168.0.2";  // server address
HttpClient httpclient = HttpClient(ethClient, httpserverAddress, port);

boolean ok=false;
unsigned long timestart=millis(); // save for 15 seconds timeout
while ( ok != true && (millis()-timestart) < 15000)
{
  delay(1000);
  Serial.println("Sending");
  httpclient.put("/api/BD0AB797F7/lights/32/state", "Content-Type: application/json", "{\"on\": true}");
  delay(20);
  Serial.println(F("CHECK Response"));
  String str = httpclient.readString();
  Serial.print(str);
  if (strstr(str.c_str(), "success") != NULL)
  {
    Serial.println("Success");
    ok=true;
  }
  else
  {
    delay(5000);
  }
}