Implementing Http PUT ( not GET or POST ) for Phillips Hue Wifi Lightbulbs

Hi All !

I’ve really been wanting to do something fun the Phillips Hue lightbulbs :
http://developers.meethue.com/1-lightsapi.html- for all that don’t know they are these fun ( although expensive ~$60 each ) wifi addressable lightbulbs.

So far I’ve been able to use Arturo’s great ofxHttpUtils https://github.com/arturoc/ofxHttpUtils for all the GET methods. But in order to actually change the light colors I need to use HTTP PUT. Looking at Artutro’s code it looks like GET and POST were the only ones implemented. I don’t have that much expertise in HTTP but I was wondering how hard this might be to implement in Poco ? I found this Stack Exchange : http://stackoverflow.com/questions/10077126/httprequest-put-content-in-poco-library- which should put me on the right track. But I just wanted to check if there’s an easier way to do this, maybe a C++ way that’s already been implemented, or using python or some other scripting language ? Perhaps forcing this down OF’s throat isn’t the best way to move forward.

Any feedback would be awesome sauce. Thanks !

Any thoughts would be greatly appreciated :slight_smile:

Hi,

I had to do something similar last year. My solution was to modify the code of ofxHttpUtils.cpp to handle the PUT command. I’m not sure how it is content-wise (back then I was supposed to only send an empty put message), but I’m pretty sure it should be handled the same way as the post is, so just the HTML header should changed.

A quick and dirty fix for you might be to replace the line:

HTTPRequest req(HTTPRequest::HTTP_POST, path, HTTPMessage::HTTP_1_1);

by :

HTTPRequest req(HTTPRequest::HTTP_PUT, path, HTTPMessage::HTTP_1_1);

And see if it serves your purpose. If so you can make a proper implementation of it by distinguishing the two use cases instead of using this outrageous hack.

I hope what I’m saying makes sense.

ps. I edited my post to match the current version of the code.

Awesome ! I’ll give that a shot. I’ll update my progress here :slight_smile: So POST and PUT are that similar ? Interesting…

From my (quick) reading they seem to be similar on the client side. On the server side they have a different semantic.

PUT seems to be meant to replace existing content on the specified address without affecting anything else, while post has a broader range of action (but don’t quote me on that, it’s mainly paraphrasing what I understood from wikipedia)

It shouldn’t be too much work to see if it’s fine…

Sorry about my delay ! I’ve had to focus on a few other things for a week or so :slight_smile: But now I’m back !

I implemented your code like you said but I’m getting an interesting error.

Do you think the “Date” error is on the hue side ? or on the poco side ?

My two repos are up on git :
https://github.com/benMcChesney/ofxPhillipsHue
https://github.com/benMcChesney/ofxHttpUtils

Hey did you ever figure this out?

Also, I may be wrong, but “Date” might be a required header for the PUT.

Oh it looks like ofxHTTP (not ofxHttpUtils) includes a way to do PUT requests, I’m gonna try it out:

https://github.com/bakercp/ofxHTTP/blob/master/example_basic_client_put_request/src/ofApp.cpp

1 Like

Hey @dennyroberts – yeah, this is how we control the HUE in our courses – we started with this example.

e.g.

#include "ofApp.h"


void ofApp::setup()
{
    // Testing redirects and https.
    std::string url = "http://192.168.100.100/api/YOUR_USERNAME/lights/";

    ofx::HTTP::DefaultClient client;
    ofx::HTTP::Context context;

    ofx::HTTP::BaseResponse response;
    ofx::HTTP::GetRequest request(url);

    std::string putUrl = "http://192.168.100.100/api/YOUR_USERNAME/lights/1/state";

    ofx::HTTP::PutRequest putRequest(putUrl);

    Json::Value messageBody;
    messageBody["on"] = false;
    messageBody["effect"] = "colorloop";

    ofBuffer bodyBuffer = messageBody.toStyledString();

    cout << bodyBuffer.getText() << endl;

    putRequest.setPutBuffer(bodyBuffer);

    try
    {
        // Execute the request and get the response stream.
        std::istream& responseStream = client.execute(putRequest,
                                                      response,
                                                      context);

        // Request and response headers can be examined here.


        std::cout << "============" << endl;
        // Copy the output to the terminal.
        Poco::StreamCopier::copyStream(responseStream, std::cout);

        // Flush the input stream.
        std::cout << std::endl;

        std::cout << "============" << endl;


    }
    catch(const Poco::Exception& exc)
    {
        ofLogError("ofApp::setup") << "Got Exception " << exc.displayText() << " " << exc.code();
    }
    catch(...)
    {
        ofLogError("ofApp::setup") << "Got unknown exception.";
    }
}

There are lots of other ways to do this with ofxHTTP, but this is the simplest.

Can you use this method to upload files (the equivalent of the -T flag in curl)? Sorry if it’s an obvious answer.

Sure – if your server supports “PUT” to upload files. Alternatively you can upload files with a POST (see other examples in ofxHTTP).

btw, I’ve used the PUT methods to upload files to vimeo etc, so it should work.