diff --git a/src/Controls.h b/src/Controls.h index 19f7277..0bb4598 100644 --- a/src/Controls.h +++ b/src/Controls.h @@ -1,5 +1,7 @@ #pragma once +#include "config.h" + #include #define PIN_A 1 diff --git a/src/Hanglamp.cpp b/src/Hanglamp.cpp index 899d958..e4b1330 100644 --- a/src/Hanglamp.cpp +++ b/src/Hanglamp.cpp @@ -3,6 +3,7 @@ CRGB colorTable[] = { + CRGB(255, 142, 32), // "warm wit" // CRGB(255, 100, 4), // CRGB(255, 128, 4), // CRGB(255, 100, 32), @@ -14,20 +15,94 @@ CRGB colorTable[] = { CRGB::Yellow, CRGB::Turquoise, CRGB::Purple, - CRGB(255, 142, 32), // "warm wit" }; Hanglamp::Hanglamp(){ - turnOn(); + } +void parseHexColor(const String& hexColor, uint8_t& r, uint8_t& g, uint8_t& b) { + String cleanHex = hexColor; + + // Remove leading '#' if present + if (cleanHex.startsWith("#")) { + cleanHex = cleanHex.substring(1); + } + + // Make sure it's exactly 6 characters + if (cleanHex.length() != 6) { + r = g = b = 0; // default/fallback + return; + } + + // Parse the color components + r = strtoul(cleanHex.substring(0, 2).c_str(), NULL, 16); + g = strtoul(cleanHex.substring(2, 4).c_str(), NULL, 16); + b = strtoul(cleanHex.substring(4, 6).c_str(), NULL, 16); +} + + void Hanglamp::setup(){ + #ifdef ENABLE_MQTT + + MQTT_subscribe("hanglamp/CMD/brightness", [&](unsigned char* payload, unsigned int len){ + String input = String((const char*)payload).substring(0, len); + int brightness = constrain(input.toInt(), 0, 255); + setBrightness(brightness); + }); + + + MQTT_subscribe("hanglamp/CMD/color", [&](unsigned char* payload, unsigned int len){ + String input = String((const char*)payload).substring(0, len); + uint8_t r, g, b; + + parseHexColor(input, r, g, b); + + Serial.printf("input: %s, r: %d, g: %d, b: %d\n", input, r, g, b); + CRGB color(r, g, b); + setColor(color); + }); + + + MQTT_subscribe("hanglamp/CMD/power", [&](unsigned char* payload, unsigned int len){ + String input = String((const char*)payload).substring(0, len); + Serial.printf("Have power command: [%s]\n", input.c_str()); + if(input == "true" || input == "1" || input == "on" || input == "ON"){ + Serial.printf("Setting power to true\n"); + turnOn(); + }else{ + Serial.printf("Setting power to false\n"); + turnOff(); + } + }); + + #endif + + setColor(colorTable[this->colorIndex]); + turnOn(); } void Hanglamp::setColor(CRGB color){ - jumpTo(color); + currentColor = color; + jumpTo(currentColor); + changed(); +} + +void Hanglamp::changed(){ + #ifdef ENABLE_MQTT + char buff[128]; + snprintf(buff, sizeof(buff), + "{\"color\":\"%02X%02X%02X\",\"brightness\":%d,\"power\":%s}", + currentColor.r, + currentColor.g, + currentColor.b, + brightness, + on ? "true" : "false" + ); + MQTT_publish("hanglamp/status", buff); + #endif } void Hanglamp::nextColor(){ @@ -41,17 +116,15 @@ void Hanglamp::nextColor(){ } void Hanglamp::setBrightness(int brightness){ - uint8_t newBrightness = - brightness < 0 ? 0 : - brightness > 255 ? 255 : - brightness; + uint8_t newBrightness = constrain(brightness, 0, 255); + if(!isOn()){ + turnOn(); + } this->brightness = newBrightness; Serial.printf("new brightness: %d\n", newBrightness); FastLED.setBrightness(newBrightness); FastLED.show(); - #ifdef ENABLE_MQTT - MQTT_publish("hanglamp/brightness", String(newBrightness)); - #endif + changed(); } void Hanglamp::adjustBrightness(int add){ @@ -94,6 +167,10 @@ void Hanglamp::status(CRGB color){ void Hanglamp::setOn(bool on){ Serial.printf("Hanglamp::setOn(%d -> %d)\n", this->on, on); this->on = on; + if(currentColor == CRGB::Black){ + nextColor(); + } + changed(); } bool Hanglamp::isOn(){ diff --git a/src/Hanglamp.hpp b/src/Hanglamp.hpp index 53c0b94..5d01f39 100644 --- a/src/Hanglamp.hpp +++ b/src/Hanglamp.hpp @@ -1,9 +1,13 @@ #pragma once + +#include "config.h" + #include #include "Led.h" #include "Controls.h" +#include "MQTT.h" class Hanglamp { public: @@ -20,9 +24,13 @@ class Hanglamp { void turnOn(); void turnOff(); + // void receiveBrightnessFromMQTT(uint8_t * payload, unsigned int len); + private: + void changed(); char colorIndex = 0; + CRGB currentColor; int brightness = 128; bool on = false; void setOn(bool on); diff --git a/src/Led.cpp b/src/Led.cpp index c3411ce..8833bf6 100644 --- a/src/Led.cpp +++ b/src/Led.cpp @@ -123,8 +123,8 @@ void Led_setup(){ // analogWriteRange(255); #ifdef LED_FASTLED - FastLED.addLeds(strip2, NUM_LEDS).setRgbw(RgbwDefault()); - FastLED.addLeds(strip2, NUM_LEDS).setRgbw(RgbwDefault()); + FastLED.addLeds(strip2, NUM_LEDS).setRgbw(RgbwDefault()); + FastLED.addLeds(strip2, NUM_LEDS).setRgbw(RgbwDefault()); strip1[0] = CRGB::Black; strip2[0] = CRGB::Black; diff --git a/src/Led.h b/src/Led.h index 71cc419..64b107c 100644 --- a/src/Led.h +++ b/src/Led.h @@ -1,7 +1,10 @@ #pragma once + #include "stdint.h" #include + +#include "config.h" #include // #define LED_NEOPIXEL_BUS diff --git a/src/MQTT.cpp b/src/MQTT.cpp index 864f735..6e177bc 100644 --- a/src/MQTT.cpp +++ b/src/MQTT.cpp @@ -46,20 +46,18 @@ void connect() { } void MQTT_publish(const char * topic, String str){ - char * buff = new char[str.length() + 1]; - str.toCharArray(buff, str.length() + 1); - MQTT_publish(topic, buff); - delete buff; + // char * buff = new char[str.length() + 1]; + // str.toCharArray(buff, str.length() + 1); + MQTT_publish(topic, str.c_str()); + // delete buff; } void MQTT_publish(const char * topic, const char * msg){ + Serial.printf("MQTT_publish(%s, %s)\n", topic, msg); client.publish(topic, msg); } -void (*pCallback)(uint8_t *, unsigned int) = NULL; - - -void MQTT_subscribe(char * topic, void (*callback)(uint8_t *, unsigned int)){ +void MQTT_subscribe(char * topic, mqtt_callback callback){ Serial.println("MQTT_subscribe"); Serial.printf("Topic: [%s]\n", topic); @@ -88,7 +86,7 @@ void MQTT_callback(char* topic, uint8_t * payload, unsigned int length){ void MQTT_setup(){ - for (int i = 0; i < 17; i = i + 8) { + for (int i = 0; i < 17; i = i + 8) { chipId |= ((ESP.getEfuseMac() >> (40 - i)) & 0xff) << i; } @@ -96,14 +94,9 @@ void MQTT_setup(){ client.setServer(mqtt_server, String(mqtt_port).toInt()); client.setCallback(MQTT_callback); - -// Serial.println("MQTT_init after callback"); -// char buff[256]; -// sprintf(buff, "%08x", _pCallback); -// Serial.println(buff); TaskHandle_t taskMqtt = NULL; - xTaskCreate(MQTT_loop, "Wifi_loop", 10000, NULL, tskIDLE_PRIORITY, &taskMqtt); + xTaskCreate(MQTT_loop, "MQTT_loop", 10000, NULL, tskIDLE_PRIORITY, &taskMqtt); } void MQTT_loop(void* params){ @@ -119,7 +112,10 @@ void MQTT_loop(void* params){ connect(); if(client.connected()){ - Serial.println("MQTT: succes!"); + Serial.println("MQTT: success!"); + for (auto channel = channels->begin(); channel != channels->end(); ++channel){ + client.subscribe(channel->topic->c_str()); + } break; }else{ Serial.println("MQTT: connection failed, try again in 5 seconds"); diff --git a/src/MQTT.h b/src/MQTT.h index 39c1d2a..acd5bc3 100644 --- a/src/MQTT.h +++ b/src/MQTT.h @@ -1,6 +1,6 @@ #pragma once -#include "settings.h" +#include "config.h" #include "Arduino.h" @@ -11,14 +11,20 @@ using namespace std; +extern char mqtt_server[40]; +extern char mqtt_port[6]; + +typedef std::function mqtt_callback; struct SubscribedChannel { String * topic; - void (*callback)(uint8_t *, unsigned int); + mqtt_callback callback; }; +void MQTT_subscribe(char * topic, mqtt_callback callback); + void MQTT_publish(const char * topic, String str); void MQTT_publish(const char * topic, const char * msg); diff --git a/src/PinFinder.h b/src/PinFinder.h index 68c5a39..318a19b 100644 --- a/src/PinFinder.h +++ b/src/PinFinder.h @@ -1,2 +1,5 @@ + +#include "config.h" + void PinFinder_setup(); void PinFinder_loop(); \ No newline at end of file diff --git a/src/Wifi.h b/src/Wifi.h index 8523e21..c696ba6 100644 --- a/src/Wifi.h +++ b/src/Wifi.h @@ -1,3 +1,3 @@ - +#include "config.h" void Wifi_setup(); \ No newline at end of file diff --git a/src/config.h b/src/config.h new file mode 100644 index 0000000..70982f1 --- /dev/null +++ b/src/config.h @@ -0,0 +1,12 @@ +#pragma once + +#define INCLUDE_LED +#define ENABLE_MQTT +// #define ENABLE_OTA +#define ENABLE_WIFI +// #define ENABLE_FS +// #define ENABLE_PINFINDER +#define ENABLE_COLORS +// #define ENABLE_PIN_SENSING +#define ENABLE_CONTROLS + diff --git a/src/main.cpp b/src/main.cpp index 5d44121..849a4bc 100644 --- a/src/main.cpp +++ b/src/main.cpp @@ -1,4 +1,6 @@ -#define INCLUDE_LED + +#include "config.h" + #ifdef INCLUDE_LED #include "Led.h" #endif @@ -8,13 +10,7 @@ #define _TASK_SLEEP_ON_IDLE_RUN // Enable 1 ms SLEEP_IDLE powerdowns between runs if no callback methods were invoked during the pass #define _TASK_STATUS_REQUEST // Compile with support for StatusRequest functionality - triggering tasks on status change events in addition to time only -#define ENABLE_MQTT -#define ENABLE_WIFI -// #define ENABLE_FS -// #define ENABLE_PINFINDER -#define ENABLE_COLORS -// #define ENABLE_PIN_SENSING -#define ENABLE_CONTROLS + #ifdef ENABLE_WIFI #include "Wifi.h" diff --git a/src/settings.h b/src/settings.h deleted file mode 100644 index c0553ff..0000000 --- a/src/settings.h +++ /dev/null @@ -1,7 +0,0 @@ -#ifndef SETTINGS_H -#define SETTINGS_H - -extern char mqtt_server[40]; -extern char mqtt_port[6]; - -#endif \ No newline at end of file