Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 11 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save jamesabruce/8bc9faf3c06e30c3f6fc to your computer and use it in GitHub Desktop.
Save jamesabruce/8bc9faf3c06e30c3f6fc to your computer and use it in GitHub Desktop.
Example of using an Arduino with Ethernet shield to control Philips Hue, with PIR motion sensor on i/o pin 2.
/*
Talking to Hue from an Arduino
By James Bruce (MakeUseOf.com)
Adapted from code by Gilson Oguime. https://github.com/oguime/Hue_W5100_HT6P20B/blob/master/Hue_W5100_HT6P20B.ino
*/
#include <SPI.h>
#include <Ethernet.h>
// Hue constants
const char hueHubIP[] = "192.168.1.216"; // Hue hub IP
const char hueUsername[] = "newdeveloper"; // Hue username
const int hueHubPort = 80;
// PIR
int pir = 2;
boolean activated = false;
// Hue variables
boolean hueOn; // on/off
int hueBri; // brightness value
long hueHue; // hue value
String hueCmd; // Hue command
unsigned long buffer=0; //buffer for received data storage
unsigned long addr;
// Ethernet
byte mac[] = { 0x74,0x69,0x69,0x2D,0x30,0x31 }; // W5100 MAC address
IPAddress ip(192,168,1,2); // Arduino IP
EthernetClient client;
/*
Setup
*/
void setup()
{
Serial.begin(9600);
Ethernet.begin(mac,ip);
pinMode(pir,INPUT);
delay(2000);
Serial.println("Ready.");
}
void loop()
{
if(digitalRead(pir) == 1){
Serial.println("activated");
// A series of four sample commands, which colour fades two lights between red and pink. Read up on the Hue API
// documentation for more details on the exact commands to be used, but note that quote marks must be escaped.
String command = "{\"on\": true,\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
setHue(1,command);
command = "{\"on\": true,\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
setHue(2,command);
command = "{\"hue\": 65280,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
setHue(1,command);
command = "{\"hue\": 50100,\"sat\":255,\"bri\":255,\"transitiontime\":"+String(random(15,25))+"}";
setHue(2,command);
// so we can track state
activated = true;
}
else{
activated = false;
Serial.println("deactivated");
//was activated, so send a single off command
String command = "{\"on\": false}";
setHue(1,command);
setHue(2,command);
}
}
/* setHue() is our main command function, which needs to be passed a light number and a
* properly formatted command string in JSON format (basically a Javascript style array of variables
* and values. It then makes a simple HTTP PUT request to the Bridge at the IP specified at the start.
*/
boolean setHue(int lightNum,String command)
{
if (client.connect(hueHubIP, hueHubPort))
{
while (client.connected())
{
client.print("PUT /api/");
client.print(hueUsername);
client.print("/lights/");
client.print(lightNum); // hueLight zero based, add 1
client.println("/state HTTP/1.1");
client.println("keep-alive");
client.print("Host: ");
client.println(hueHubIP);
client.print("Content-Length: ");
client.println(command.length());
client.println("Content-Type: text/plain;charset=UTF-8");
client.println(); // blank line before body
client.println(command); // Hue command
}
client.stop();
return true; // command executed
}
else
return false; // command failed
}
/* A helper function in case your logic depends on the current state of the light.
* This sets a number of global variables which you can check to find out if a light is currently on or not
* and the hue etc. Not needed just to send out commands
*/
boolean getHue(int lightNum)
{
if (client.connect(hueHubIP, hueHubPort))
{
client.print("GET /api/");
client.print(hueUsername);
client.print("/lights/");
client.print(lightNum);
client.println(" HTTP/1.1");
client.print("Host: ");
client.println(hueHubIP);
client.println("Content-type: application/json");
client.println("keep-alive");
client.println();
while (client.connected())
{
if (client.available())
{
client.findUntil("\"on\":", "\0");
hueOn = (client.readStringUntil(',') == "true"); // if light is on, set variable to true
client.findUntil("\"bri\":", "\0");
hueBri = client.readStringUntil(',').toInt(); // set variable to brightness value
client.findUntil("\"hue\":", "\0");
hueHue = client.readStringUntil(',').toInt(); // set variable to hue value
break; // not capturing other light attributes yet
}
}
client.stop();
return true; // captured on,bri,hue
}
else
return false; // error reading on,bri,hue
}
@awrebels
Copy link

Is getHue working for you? In the current code I’m getting just 0s for hue, on, and Bri

@rob2791
Copy link

rob2791 commented Oct 3, 2021

The reason your code takes so long to run and update the change of input is because of the while loop on line 90. You don't need that while loop. You should also only be calling setHue when the switch input changes from off to on, or on to off. Your current code continuously calls upon setHue even if the state is the same.
I suggest changing line 51 to:
if((digitalRead(pir) == 1) && (activated == false) ){
and line 68 to:
if((digitalRead(pir) == 0) && (activated == true) ){

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment