Howdy, Stranger!

It looks like you're new here. If you want to get involved, click one of these buttons!

Sign In with Google Sign In with OpenID

Categories

In this Discussion

DEV CON NEWS. The dev con has been postponed until a couple weeks later in the year (exact date to be announced). We would like the event to coincide with a larger hacker / developers event and that way reach more enthusiasts. I will post updates on the dev con page!
To get support, first browse what's already here. Can't find what you're looking for? Start a new discussion (on the right) and choose "question" in the next screen. You will be notified of answers and you can vote the best answer. Good luck!
Simple PHP Gateway
  • I ran into issues trying to do HTTP PUT requests with various software I use regularly (like tasker for Android). I have a server always in my house so I made a simple gateway that will send commands to the lights. You can make a request like this:

    http://x.x.x.x?bulb=1&hue=12555&bri=50

    This just makes things a bit more accessible so you don't need to mess with the rest stuff to control lights. Development is a breeze.

    So here's the PHP code I'm using. It's not great but it works. Don't expose this to the outside. Only use it on your local network.

    $data = "{";

    $bulb = $_GET["bulb"];
    $comma = 0;

    if ($hue = $_GET["hue"]) {
    $data = $data . "\"hue\":" . $hue;
    $comma = 1;
    echo "what?";
    }

    if ($sat = $_GET["sat"]) {
    if ($comma == 1) {$data = $data . ",";} else {$comma = 1;};
    $data = $data . "\"sat\":" . $sat;
    }
    if ($trans = $_GET["trans"]) {
    if ($comma == 1) {$data = $data . ",";} else {$comma = 1;};
    $data = $data . "\"transitiontime\":" . $trans;
    //Transition time in 1/10ths of a second. 0 = snap.
    }

    if ($bri = $_GET["bri"]) {
    if ($comma == 1) {$data = $data . ",";} else {$comma = 1;};
    $data = $data . "\"bri\":" . $bri;
    }

    if ($on = $_GET["on"]) {
    if ($comma == 1) {$data = $data . ",";} else {$comma = 1;};
    $data = $data . "\"on\":" . $on;

    }

    $data = $data . "}";

    $url = 'http://localhost/api/YOURHASH/lights/'.$bulb.'/state';

    //$data = "{\"hue\": ".$hue.",\"sat\": ".$sat.",\"transitiontime\": ".$trans.",\"bri\":".$bri.",\"on\":".$on."}";

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
    $response1 = curl_exec($ch);
    if(!$response1) {
    return false;
    }

    echo $data . '
    ';

    echo $response1;
  • It's not a *big* risk, but you do realize it also makes it easier for others to control your lights? The only unknown parameter (for forum readers) is the ip/hostname of your php server (which probably is easy to find by trying).
    A simple picture on a website using your url as source could trigger an action on your bulbs as soon as you visit that site.

    More info on: http://en.wikipedia.org/wiki/Cross-site_request_forgery
  • Even simpler;

    $bulb = $_GET["bulb"];

    if (isset($_GET['hue'])) $arrData['hue'] = (int)$_GET['hue'];
    if (isset($_GET['sat'])) $arrData['sat'] = (int)$_GET['sat'];
    if (isset($_GET['trans'])) $arrData['transitiontime'] = (int)$_GET['trans']
    if (isset($_GET['bri'])) $arrData['bri'] = (int)$_GET['bri'];
    if (isset($_GET['on'])) $arrData['on'] = (bool)$_GET['on'];

    $data = json_encode($arrData);

    $url = 'http://10.0.0.0/api/YOURHASH/lights/'.$bulb.'/state';

    $ch = curl_init($url);
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, $data);
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
    $response = curl_exec($ch);
    echo $response;
  • I have rewritten your PHP gateway to take multiple lights in a single request and now it is able to restore the previous state of the light. Now you can make the lights blink to a color and return to it's previous state. At my android Phone I'm using tasker the fade the light for two seconds to a color on receiving a notification:
    Gmail blinks red,
    Facebook Blue,
    WhatsApp Green,
    ...

    And I have used tasker with the AutoAlarm plugin to create a wakeup light with the main lighting in my bedroom. 15 minutes befor my android alarm goes of tasker sends a command via the php gateway with a transition time of 9000. The 9000 is calculated from the amount of minutes to the next alarm multiplied by 600.

    This is more of a proof of concept before creating a proper app.

  • Very nice Juicie,
    I've enjoyed your vid, but can you share the code please?
    Chears,
    Arjo
  • Guys--I have written up an increasingly complete PHP library and put it on Github. Maybe we ought to join efforts?

    http://github.com/danray0424/phpHue

    My thing in particular would benefit from being turned into a proper OO class, and from having its REST interface rebuilt (for quickness of build I used a library called PEST, but I'd rather bring the fairly simple CURL code into the class itself).
  • Juicie, can you post the code that supports multiple lights? this may be a temp solution for my NFC needs.
  • Request is something like:

    http://server/hue.php?bulb=1,3,12&hue=45000&blinktime=2&trans=5

    This lights up lamps 1, 3 and 12 blue for two seconds with a transition time of 500ms.

    <?php<br />$HUE_BRIDGE_ADRESS = 'address';
    $HUE_API_KEY = 'key';

    $url = ''.$HUE_BRIDGE_ADRESS.'/api/'.$HUE_API_KEY.'/lights';

    $bulbs = $_GET["bulb"];
    $bulblist = explode(',', $bulbs);

    foreach($bulblist as $bulb)
    {
    $previousState[$bulb] = getState($bulb);

    $newState = createData();

    $response = sendData($newState, $bulb);
    echo $response;
    }

    if ($blinktime = $_GET["blinktime"]){
    sleep($blinktime);
    foreach($bulblist as $bulb)
    {
    print_r($previousState[$bulb]);

    $response = sendData($previousState[$bulb], $bulb);
    echo $response;
    }
    }

    function getState($bulb){
    global $url;
    echo(''.$url.'/'.$bulb.'');
    $cf = curl_init(''.$url.'/'.$bulb.'');
    curl_setopt($cf, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($cf, CURLOPT_CUSTOMREQUEST, "GET");
    $response = curl_exec($cf);
    $lightstate = json_decode($response);
    if(!$response) {
    return false;
    }

    return $lightstate->state;
    }

    function createData(){
    if (isset($_GET['hue'])) $arrData['hue'] = (int)$_GET['hue'];
    else $arrData['hue'] = 100;

    if (isset($_GET['sat'])) $arrData['sat'] = (int)$_GET['sat'];
    else $arrData['sat'] = 254;

    if (isset($_GET['trans'])) $arrData['transitiontime'] = (int)$_GET['trans'];
    else $arrData['transitiontime'] = 10;

    if (isset($_GET['bri'])) $arrData['bri'] = (int)$_GET['bri'];
    else $arrData['bri'] = 240;

    if (isset($_GET['on'])) $arrData['on'] = (bool)$_GET['on'];
    else $arrData['on'] = true;

    return $arrData;
    }

    function sendData($data, $bulb){
    global $url;
    $ch = curl_init(''.$url.'/'.$bulb.'/state');
    curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
    curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
    curl_setopt($ch, CURLOPT_CUSTOMREQUEST, "PUT");
    $response1 = curl_exec($ch);

    if(!$response1) {
    return false;
    }
    return response1;
    }
    ?>
  • Omg, that's perfect! I wonder if you can put that request into tasker (android)... That would solve my issue entirely!
  • Hey i noticed something with your php code. When you change colors or brightness, there is a period where the lights turn red regardless of what url you use... is there something in the code i dont see?
  • Yes you can, I'm using it to blink some lights when I get a notification from Facebook, Gmail, Whatsapp or Google Talk. And I'm using it to create a wakeuplight with Tasker and my bedroom lighting. I'm using HTTP Post in tasker.

    I've seen the same thing but was going to check it this weekend. But when I look at it now, I see that if you don't set HUE in your URL it default takes red. Remove this line: else $arrData['hue'] = 100; Maybe this helps. I've also seen some weird things when restoring the previous state.
  • whats the formatting of your http post command in tasker?
  • I've added my tasker configuration below:
    tasker.txt
    4K
  • The one I'm using with my original script is a task that looks like this:

    For
    -Variable %bulb Items: 1,2,3,4,5
    | HTTP Get
    Server: Port http://xxx.xxx.xxx.xxx/?bulb=%bulb&amp;on=true

    You can add whatever other options you want to set hue, brightness, etc.
  • awesome. I actually just have the script set up behind some authentication, so only my phone works with it at the moment (for security reasons). but i got some nfc tags in the mail, so i have them set up as my on and off switches.. :) now i just need to find a way to add a party mode to that php script. I'd love to have a party mode tag lol. :-p
  • Guys, there's a question:

    I don't have a server at home, but a server at a provider outside my own network. I tried port forwarding the "10.1...." ip of my bridge to some random port and contacting my bridge through myexternalip:port but it doesn't work. Does on of your scripts up there do that?

    Can you give me advice how I can access my bridge? What I want to do is, to write an objective-C application to access my lights. Since there is no objective-C API I'm aware of, I thought of calling a PHP script...

    What do you think?

    Thanks!
  • Hm, I made it via objective-C directly... so thanks anyway
  • I updated Juicie's code in the CreateData section. It adds KevinToms' RGB to xy calculations (although not fully, yet), as well as some other commands:
    rgb - Hex representation of a color translated to xy values (ie. rgb=FF00FF will give you purple)
    color - Use a named color instead of RGB (ie. color=red) Valid values: green, red, blue, coolwhite, warmwhite, purple, reading (Presets mostly from DanRay's presets, I added "reading" from Phillips preset and can be easily added with your own presets)
    effect - Used to put bulb in an effect mode. Valid Values: colorloop - cycles bulb though all colors, none - turns off effects
    alert - Used to blink bulb. Valid values: select - Blink bulb once, lselect - Blink bulb continuously.
    bri - While not new, can be used to override the brightness from a rgb or color command value. (can be useful as a work around for the RGB conversion not being perfect)

    so xxx.php?bulb=3,4&color=reading will give you reading light
    xxx.php?bulb=3,4&rgb=FFFF00 will give you yellow light at full brightness
    xxx.php?bulb=3,4&rgb=FFFF00&bri=254 will give you yellow light at full brightness
    etc.

    Just replace the CreateData function above with this below:

    function createData(){

    if (isset($_GET['rgb'])){
    $rgb=$_GET['rgb'];
    if (strlen($rgb)==6) {
    $r=hexdec(substr($rgb,0,2))/255;
    $g=hexdec(substr($rgb,2,2))/255;
    $b=hexdec(substr($rgb,4,2))/255;

    if ($r>0.04045)
    {$rf=pow(($r + 0.055) / (1.0 + 0.055), 2.4);} else {$rf=$r/12.92;};
    if ($r>0.04045) {$gf=pow(($g + 0.055) / (1.0 + 0.055), 2.4);} else {$gf=$g/12.92;};
    if ($r>0.04045) {$bf=pow(($b + 0.055) / (1.0 + 0.055), 2.4);} else {$bf=$b/12.92;};

    $x = $rf * 0.649926 + $gf * 0.103455 + $bf * 0.197109;
    $y = $rf * 0.234327 + $gf * 0.743075 + $bf * 0.022598;
    $z = $rf * 0.000000 + $gf * 0.053077 + $bf * 1.035763;

    $cx = $x / ($x + $y + $z);
    $cy = $y / ($x + $y + $z);

    if (is_nan($cx)) {$cx=0;};
    if (is_nan($cy)) {$cy=0;};

    $xy[0]=$cx;
    $xy[1]=$cy;
    $arrData['bri'] = intval($y*254); //This isn't quite right
    $arrData['xy']=$xy;
    } else {
    $arrData['ct'] = 150;
    $arrData['bri'] = 254;
    };

    } else {
    if (isset($_GET['color'])){
    switch ($_GET['color']) {
    case "green":
    $arrData['hue'] = 182 * 140;
    $arrData['sat'] = 254;
    $arrData['bri'] = 254;
    break;
    case "red":
    $arrData['hue'] = 0;
    $arrData['sat'] = 254;
    $arrData['bri'] = 254;
    break;
    case "blue":
    $arrData['hue'] = 182 * 250;
    $arrData['sat'] = 254;
    $arrData['bri'] = 254;
    break;
    case "coolwhite":
    $arrData['ct'] = 150;
    $arrData['bri'] = 254;
    break;
    case "warmwhite":
    $arrData['ct'] = 500;
    $arrData['bri'] = 254;
    break;
    case "purple":
    $arrData['hue'] = 182 * 270;
    $arrData['sat'] = 254;
    $arrData['bri'] = 254;
    break;
    case "reading":
    $arrData['ct'] = 343;
    $arrData['bri'] = 240;
    break;
    };
    } else {

    if (isset($_GET['hue'])) $arrData['hue'] = (int)$_GET['hue'];
    //else $arrData['hue'] = 100;

    if (isset($_GET['sat'])) $arrData['sat'] = (int)$_GET['sat'];
    else $arrData['sat'] = 254;

    if (isset($_GET['bri'])) $arrData['bri'] = (int)$_GET['bri'];
    else $arrData['bri'] = 240;
    };
    };

    //I'm allowing an override on brightness
    if (isset($_GET['bri'])) $arrData['bri'] = (int)$_GET['bri'];

    if (isset($_GET['trans'])) $arrData['transitiontime'] = (int)$_GET['trans'];
    else $arrData['transitiontime'] = 10;

    if (isset($_GET['on'])) $arrData['on'] = (bool)$_GET['on'];
    else $arrData['on'] = true;

    if (isset($_GET['effect'])) $arrData['effect'] = $_GET['effect'];

    if (isset($_GET['alert'])) $arrData['alert'] = $_GET['alert'];


    return $arrData;
    }


    Have fun with it!
  • Hello.Can someone help me on how to create a simple php just to get the status of an specific light and do something like make the light turn green or red for few seconds and then put it back the way it was?
    thank You.