Skip to content

Instantly share code, notes, and snippets.

@grafuls
Created December 6, 2024 08:12
Show Gist options
  • Save grafuls/465c0f3c30ac2d7262f41df9a1304a39 to your computer and use it in GitHub Desktop.
Save grafuls/465c0f3c30ac2d7262f41df9a1304a39 to your computer and use it in GitHub Desktop.
Controlling HUE lights via D1 mini
#define POTENTIOMETER_PIN A0
#define CHANGE_THRESHOLD 2
#include <ESP8266WiFi.h>
#include <WiFiClientSecure.h>
#include <ArduinoJson.h>
#include <ESP8266HTTPClient.h>
// Replace with your network credentials
const char* ssid = "{SSID}";
const char* password = "{PASSWORD_HERE}";
const char* token = "{HUE_API_TOKEN}";
const char* bridge = "{BRIDGE_IP}";
const char* resource = "{RESOURCE_ID}";
char apiEndpoint[200];
// Pin connected to the latch button (change to your actual pin)
const int buttonPin = D1;
// Variables to handle button state
bool lastButtonState = HIGH; // Assume the button is not pressed initially
bool buttonPressed = false;
int lastSentValue = -1;
WiFiClientSecure wifiClient; // Create a WiFi client
void setup() {
Serial.begin(115200);
snprintf(apiEndpoint, sizeof(apiEndpoint), "https://%s/clip/v2/resource/grouped_light/%s", bridge, resource);
// Initialize button pin
pinMode(buttonPin, INPUT_PULLUP); // Using internal pull-up resistor
// Connect to Wi-Fi
Serial.println("Connecting to Wi-Fi...");
WiFi.begin(ssid, password);
while (WiFi.status() != WL_CONNECTED) {
delay(1000);
Serial.println("Connecting...");
}
Serial.println("Connected to Wi-Fi.");
// Optional: Disable SSL certificate validation (for testing purposes)
wifiClient.setInsecure();
}
void loop() {
// Read potentiometer value and scale it
int potValue = analogRead(POTENTIOMETER_PIN);
int scaledValue = scalePotentiometerValue(potValue);
// Check if the value has changed
if (lastSentValue == -1 || abs(scaledValue - lastSentValue) > CHANGE_THRESHOLD) {
Serial.printf("Value changed significantly: %d -> %d\n", lastSentValue, scaledValue);
lastSentValue = scaledValue; // Update the last sent value
sendValueToServer(scaledValue); // Send the new value
}
// Read the current state of the button
bool currentButtonState = digitalRead(buttonPin);
// If button state changes (from HIGH to LOW), toggle action
if (lastButtonState == HIGH && currentButtonState == LOW) {
buttonPressed = !buttonPressed; // Toggle the latch state
delay(50); // Debounce delay (adjust as necessary)
if (buttonPressed) {
toggleState(); // Call the HTTP request function
}
}
delay(10); // Short delay to avoid excessive CPU usage
}
void toggleState() {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
// First, send a GET request to check the current state
Serial.println("Checking current state...");
http.begin(wifiClient, apiEndpoint);
// Add the authentication header
http.addHeader("hue-application-key", token);
int httpCode = http.GET(); // Send the GET request
if (httpCode > 0) {
String response = http.getString();
Serial.println("Current state response:");
Serial.println(response);
// Parse the JSON response to check the current state
StaticJsonDocument<200> doc;
deserializeJson(doc, response);
bool currentOnState = doc["data"][0]["on"]["on"];
// Toggle the state (if false, make it true, and if true, make it false)
bool newState = !currentOnState;
Serial.printf("Current state: %s, setting new state to: %s\n", currentOnState ? "true" : "false", newState ? "true" : "false");
// Prepare JSON payload
String payload = createJsonPayload(newState);
// Start the HTTP GET request
Serial.println("Sending POST request...");
http.begin(wifiClient, apiEndpoint);
http.addHeader("hue-application-key", token);
int httpCode = http.PUT(payload);
// Check the response code
if (httpCode > 0) {
Serial.printf("HTTP Response code: %d\n", httpCode);
String payload = http.getString();
Serial.println("Response payload:");
Serial.println(payload);
} else {
Serial.printf("PUT request failed, error: %s\n", http.errorToString(httpCode).c_str());
}
}
http.end(); // Free resources
} else {
Serial.println("Wi-Fi disconnected, retrying...");
WiFi.begin(ssid, password);
}
}
void sendValueToServer(int value) {
if (WiFi.status() == WL_CONNECTED) {
HTTPClient http;
String payload = createDimmingPayload(value);
// Send POST request
http.begin(wifiClient, apiEndpoint);
http.addHeader("hue-application-key", token);
int httpCode = http.PUT(payload);
if (httpCode > 0) {
Serial.printf("PUT response code: %d\n", httpCode);
String response = http.getString();
Serial.println("Response:");
Serial.println(response);
} else {
Serial.printf("POST failed, error: %s\n", http.errorToString(httpCode).c_str());
}
http.end();
} else {
Serial.println("Wi-Fi disconnected!");
}
}
// Function to create JSON payload with dynamic state
String createJsonPayload(bool newState) {
StaticJsonDocument<200> doc;
// Create a nested object with the required structure
JsonObject on = doc.createNestedObject("on");
on["on"] = newState; // Set the value of the inner "on" key to the new state (true or false)
// Serialize JSON to string
String payload;
serializeJson(doc, payload);
return payload;
}
// Function to create JSON payload with dynamic state
String createDimmingPayload(int inputValue) {
StaticJsonDocument<200> doc;
// Create a nested object with the required structure
JsonObject dimming = doc.createNestedObject("dimming");
dimming["brightness"] = inputValue;
// Serialize JSON to string
String payload;
serializeJson(doc, payload);
return payload;
}
int scalePotentiometerValue(int inputValue) {
// Map inputValue from 60–1024 to 0–100
int scaledValue = map(inputValue, 60, 1024, 0, 100);
// Constrain the value to ensure it's within bounds (0–100)
return constrain(scaledValue, 0, 100);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment