Created
December 6, 2024 08:12
-
-
Save grafuls/465c0f3c30ac2d7262f41df9a1304a39 to your computer and use it in GitHub Desktop.
Controlling HUE lights via D1 mini
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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