How to connect your ESP or Arduino with Philips Hue bridge using RESTfull API and HTTP requests.

In this tutorial, I'm going to show you how to connect your ESP or Arduino with Philips Hue bridge using RESTfull API and HTTP requests.

I would like to continue with the idea of using a microcontroller with the Philips Hue system. I will do this by extending the light control capabilities with IR remote control (e.g., a simple remote control from a television) or make an interactive switch with TFT shield for ESP32 Lolin D32 with simple power consumption monitoring.

The ideas above are a few basic concepts and several other details need to be solved for real use (location of IR sensor, detection of the current state of the bulb by API getter, etc.)

Required Hardware

Required Libraries

Project Code

/*************************************************************
Hue @ D1 mini Pro (ESP8266)
Basic demo of switch based on IR sensor to demonstrate
communication between ESP and Hue gateway
Version: 1.00
by Petr Lukas
Functionality:
Identify IR signal and switch light on and off using IR remote control.
*************************************************************/
#include <IRremoteESP8266.h>
#include <IRrecv.h>
#include <IRutils.h>
#include <ESP8266HTTPClient.h>
#include <ESP8266WiFi.h>
// Wifi network SSID
const char* ssid = "YOUR_SSID";
// Wifi network password
const char* password = "YOUR_PASSWORD";
// IP of Hue gateway
String ip = "YOUR_HUE_BRIDGE_IP";
// Set IR signal number (copy it from serial output) to switch light on and off
int switch_on = 0xE0E048B7;
int switch_off = 0xE0E008F7;
// Hue gateway user name
String user_name = "YOUR_HUE_AUTHORIZED_USER";
#define RECV_PIN D4
#define MIN_UNKNOWN_SIZE 20
IRrecv irrecv(RECV_PIN);
decode_results results;
bool state = false;
void setup() {
Serial.begin(115200);
WiFi.begin(ssid, password);
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Connected to the WiFi network");
irrecv.enableIRIn(); // Start the receiver
while (!Serial) // Wait for the serial connection to be establised.
delay(50);
Serial.println();
Serial.print("IR receiver is now running and waiting for IR message on Pin ");
Serial.println(RECV_PIN);
irrecv.setUnknownThreshold(MIN_UNKNOWN_SIZE);
}
void loop() {
if (irrecv.decode(&results)) {
// print() & println() can't handle printing long longs. (uint64_t)
serialPrintUint64(results.value, HEX);
Serial.println("");
if(results.value == switch_on){
switchLight(1,true);
delay(500);
}
if(results.value == switch_off){
switchLight(1,false);
delay(500);
}
irrecv.resume(); // Receive the next value
}
delay(100);
}
void switchLight(byte room, bool current_state){
state = current_state;
HTTPClient http;
String req_string;
req_string = "http://";
req_string += ip;
req_string += "/api/";
req_string += user_name;
req_string += "/lights/";
req_string += room;
req_string += "/state";
Serial.println(req_string);
http.begin(req_string);
http.addHeader("Content-Type", "text/plain");
String put_string;
put_string = "{\"on\":";
put_string += (current_state)? "true" : "false";
put_string += "}";
int httpResponseCode = http.PUT(put_string);
if(httpResponseCode > 0){
String response = http.getString();
Serial.println(httpResponseCode);
Serial.println(response);
} else {
Serial.print("Error on sending PUT Request: ");
Serial.println(httpResponseCode);
}
http.end();
}
view raw philips_hue_ir.ino hosted with ❤ by GitHub
/*************************************************************
Hue @ Lolin D32 Pro (ESP32)
Basic demo of switch based on touch TFT display to demonstrate
communication between ESP and Hue gateway
Version: 1.00
by Petr Lukas
Functionality:
Touch a button on TFT to switch on and off the lights.
*************************************************************/
#include <WiFi.h>
#include <HTTPClient.h>
#include <Adafruit_GFX.h>
#include <Adafruit_ImageReader.h>
#include <Adafruit_ILI9341.h>
#include <SPI.h>
#include <SD.h>
// Touchscreen library
#include <XPT2046_Touchscreen.h>
// Fonts
#include <Fonts/FreeMono9pt7b.h>
#include <Fonts/FreeSansBold9pt7b.h>
#include <Fonts/FreeSansBold12pt7b.h>
// Default pin numbers for D32 Pro
#define TFT_CS 14
#define TFT_DC 27
#define TFT_RST 33
#define TS_CS 12
// SD card pin
#define SD_CS 4
// IP of Hue gateway
String ip = "YOUR_HUE_BRIDGE_IP";
// Hue gateway user name
String user_name = "YOUR_HUE_AUTHORIZED_USER";
// Wifi network SSID
const char* ssid = "YOUR_SSID";
// Wifi network password
const char* password = "YOUR_PASSWORD";
// Power consumtion per bulb
float consumption = 8.5; // Let's assume consumption of bulb in full light is 8.5 W
unsigned long previousMillis = 0;
bool state1 = false;
bool state2 = false;
bool state3 = false;
float total_consumption = 0;
int runtime = 0;
Adafruit_ILI9341 tft = Adafruit_ILI9341(TFT_CS, TFT_DC, TFT_RST);
Adafruit_ImageReader reader;
XPT2046_Touchscreen ts(TS_CS);
void setup() {
// put your setup code here, to run once:
Serial.begin(115200);
tft.begin();
tft.setFont(&FreeMono9pt7b);
tft.fillScreen(ILI9341_BLACK);
tft.setCursor(0, 15);
tft.println("Init SD card...");
if (!SD.begin(SD_CS)) {
tft.setTextColor(ILI9341_RED);
Serial.println("SD card failed");
tft.println("Failed!");
delay(999999);
return;
}
WiFi.begin(ssid, password);
tft.println("Connecting to WiFi");
Serial.print("Connecting to WiFi");
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.print(".");
}
Serial.println("Connected to the WiFi network");
tft.println("Success");
delay(500);
tft.println("Init touchscreen...");
ts.begin();
tft.println("Setup complete");
tft.println("Starting loop...");
delay(500);
tft.fillScreen(ILI9341_BLACK);
drawButtons();
}
void switchLight(byte light_id, bool current_state, int x, int y){
HTTPClient http;
String req_string;
req_string = "http://";
req_string += ip;
req_string += "/api/";
req_string += user_name;
req_string += "/lights/";
req_string += light_id;
req_string += "/state";
Serial.println(req_string);
http.begin(req_string);
http.addHeader("Content-Type", "text/plain");
String put_string;
put_string = "{\"on\":";
put_string += (current_state)? "true" : "false";
put_string += "}";
int httpResponseCode = http.PUT(put_string);
// Change button only in case the operation is successfull
if(httpResponseCode == 200){
toggleButton(x,y,current_state);
}
if(httpResponseCode > 0){
String response = http.getString();
Serial.println(httpResponseCode);
Serial.println(response);
} else {
Serial.print("Error on sending PUT Request: ");
Serial.println(httpResponseCode);
}
http.end();
}
void drawButtons(){
int y = 115;
int y_space = 60;
reader.drawBMP("/wemos.bmp", tft, 10, 20);
reader.drawBMP("/hue.bmp", tft, 180, 20);
reader.drawBMP("/off.bmp", tft, 130, y);
reader.drawBMP("/off.bmp", tft, 130, y + y_space);
reader.drawBMP("/off.bmp", tft, 130, y + y_space*2);
tft.setFont(&FreeSansBold12pt7b);
y = y + 22;
tft.setCursor(3, y);
tft.println("Hall:");
tft.setCursor(3, y + y_space);
tft.println("Bedroom:");
tft.setCursor(3, y + y_space*2);
tft.println("Bathroom:");
tft.setFont(&FreeSansBold9pt7b);
tft.setCursor(50, 310);
tft.println("0.00 Wh | 0 min");
}
void toggleButton(int x, int y, bool state){
if(state){
reader.drawBMP("/on.bmp", tft, x, y);
} else {
reader.drawBMP("/off.bmp", tft, x, y);
}
}
void loop() {
unsigned long currentMillis = millis();
if (currentMillis - previousMillis >= 1000){
if(state1)total_consumption += consumption/3600;
if(state2)total_consumption += consumption/3600;
if(state3)total_consumption += consumption/3600;
runtime++;
tft.setFont(&FreeSansBold9pt7b);
tft.setCursor(50, 310);
tft.fillRect(0,285,240,320,ILI9341_BLACK);
tft.print(total_consumption,2);
tft.print(" Wh | ");
tft.print(runtime/60);
tft.print(" min");
previousMillis = currentMillis;
}
if (ts.touched()) {
TS_Point p = ts.getPoint();
// You need to test coordinates (in this case landscape oriented)
/*
tft.setCursor(0,50);
tft.fillRect(0,30,100,50,ILI9341_BLACK);
tft.println(p.x);
tft.println(p.y);
*/
if((p.x < 2500 && p.x > 2000) && (p.y < 1800 && p.y > 300)){
state1 = !state1;
switchLight(1, state1, 130, 115);
}
if((p.x < 2000 && p.x > 1500) && (p.y < 1800 && p.y > 300)){
state2 = !state2;
switchLight(2, state2, 130, 175);
}
if((p.x < 1500 && p.x > 1000) && (p.y < 1800 && p.y > 300)){
state3 = !state3;
switchLight(3, state3, 130, 235);
}
delay(500);
}
}
view raw philips_hue_tft.ino hosted with ❤ by GitHub

Watch the video below to see how I do!

Petr Lukáš
Application Software Developer, Performance and capacity reporting for IBM zSeries team, experimenting with home automation, sensors, Arduino and ESP