diff --git a/CHANGELOG.md b/CHANGELOG.md index 6545ad8b..6403fb91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,14 @@ ### Development versions after the 0.10.2 release +#### Build 2011200 + +- Added HEX color receiving to JSON API with `"col":["RRGGBBWW"]` format +- Moved Kelvin color receiving in JSON API from `"col":[[val]]` to `"col":[val]` format + _Notice:_ This is technically a breaking change. Since no release was made since the introduction and the Kelvin property was not previously documented in the wiki, + impact should be minimal. +- BTNPIN can now be disabled by setting to -1 (fixes #1237) + #### Build 2011180 - Platformio.ini updates and streamlining (PR #1266) @@ -42,6 +50,7 @@ - More explanatory error messages in UI - Improved candle brightness - Return remaining nightlight time `nl.rem` in JSON API (PR #1302) +- UI sends timestamp with every command, allowing for timed presets without using NTP - Added gamma calculation (yet unused) - Added LED type definitions to const.h (yet unused) - Added nicer 404 page @@ -89,6 +98,7 @@ - Added Loxone parser (PR #1185) - Added support for kelvin input via `K=` HTTP and `"col":[[val]]` JSON API calls + _Notice:_ `"col":[[val]]` removed in build 2011200, use `"col":[val]` - Added supplementary UDP socket (#1205) - TMP2.net receivable by default - UDP sockets accept HTTP and JSON API commands diff --git a/wled00/button.cpp b/wled00/button.cpp index 249351c6..7adbf68b 100644 --- a/wled00/button.cpp +++ b/wled00/button.cpp @@ -17,7 +17,7 @@ void shortPressAction() bool isButtonPressed() { - #ifdef BTNPIN + #if defined(BTNPIN) && BTNPIN > -1 if (digitalRead(BTNPIN) == LOW) return true; #endif #ifdef TOUCHPIN @@ -29,7 +29,7 @@ bool isButtonPressed() void handleButton() { -#if defined(BTNPIN) || defined(TOUCHPIN) +#if (defined(BTNPIN) && BTNPIN > -1) || defined(TOUCHPIN) if (!buttonEnabled) return; if (isButtonPressed()) //pressed diff --git a/wled00/colors.cpp b/wled00/colors.cpp index 361e3e06..60416c5f 100644 --- a/wled00/colors.cpp +++ b/wled00/colors.cpp @@ -177,7 +177,7 @@ void colorRGBtoXY(byte* rgb, float* xy) //rgb to coordinates (https://www.develo } #endif // WLED_DISABLE_HUESYNC - +//RRGGBB / WWRRGGBB order for hex void colorFromDecOrHexString(byte* rgb, char* in) { if (in[0] == 0) return; @@ -198,6 +198,27 @@ void colorFromDecOrHexString(byte* rgb, char* in) rgb[2] = c & 0xFF; } +//contrary to the colorFromDecOrHexString() function, this uses the more standard RRGGBB / RRGGBBWW order +bool colorFromHexString(byte* rgb, const char* in) { + if (in == nullptr) return false; + size_t inputSize = strnlen(in, 9); + if (inputSize != 6 && inputSize != 8) return false; + + uint32_t c = strtoul(in, NULL, 16); + + if (inputSize == 6) { + rgb[0] = (c >> 16) & 0xFF; + rgb[1] = (c >> 8) & 0xFF; + rgb[2] = c & 0xFF; + } else { + rgb[0] = (c >> 24) & 0xFF; + rgb[1] = (c >> 16) & 0xFF; + rgb[2] = (c >> 8) & 0xFF; + rgb[3] = c & 0xFF; + } + return true; +} + float minf (float v, float w) { if (w > v) return v; diff --git a/wled00/fcn_declare.h b/wled00/fcn_declare.h index 729eb6bc..52f2ff34 100644 --- a/wled00/fcn_declare.h +++ b/wled00/fcn_declare.h @@ -43,6 +43,7 @@ void colorXYtoRGB(float x, float y, byte* rgb); // only defined if huesync disab void colorRGBtoXY(byte* rgb, float* xy); // only defined if huesync disabled TODO void colorFromDecOrHexString(byte* rgb, char* in); +bool colorFromHexString(byte* rgb, const char* in); void colorRGBtoRGBW(byte* rgb); //rgb to rgbw (http://codewelt.com/rgbw). (RGBW_MODE_LEGACY) //dmx.cpp diff --git a/wled00/json.cpp b/wled00/json.cpp index 12c86595..0d325840 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -36,29 +36,38 @@ void deserializeSegment(JsonObject elem, byte it) { for (uint8_t i = 0; i < 3; i++) { + int rgbw[] = {0,0,0,0}; + bool colValid = false; JsonArray colX = colarr[i]; - if (colX.isNull()) break; - byte sz = colX.size(); - if (sz > 0 && sz < 5) - { - int rgbw[] = {0,0,0,0}; - byte cp = copyArray(colX, rgbw); - - if (cp == 1) { - if (rgbw[0] == 0) seg.colors[i] = 0; - else { - byte ctrgb[] = {0,0,0,0}; - colorKtoRGB(rgbw[0], ctrgb); - for (uint8_t c = 0; c < 3; c++) rgbw[c] = ctrgb[c]; - } - } - if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment - { - if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];} - if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];} - } else { - seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))); + if (colX.isNull()) { + byte brgbw[] = {0,0,0,0}; + const char* hexCol = colarr[i]; + if (hexCol == nullptr) { //Kelvin color temperature (or invalid), e.g 2400 + int kelvin = colarr[i] | -1; + if (kelvin < 0) continue; + if (kelvin == 0) seg.colors[i] = 0; + if (kelvin > 0) colorKtoRGB(kelvin, brgbw); + colValid = true; + } else { //HEX string, e.g. "FFAA00" + colValid = colorFromHexString(brgbw, hexCol); } + for (uint8_t c = 0; c < 4; c++) rgbw[c] = brgbw[c]; + } else { //Array of ints (RGB or RGBW color), e.g. [255,160,0] + byte sz = colX.size(); + if (sz == 0) continue; //do nothing on empty array + + byte cp = copyArray(colX, rgbw, 4); + if (cp == 1 && rgbw[0] == 0) seg.colors[i] = 0; + colValid = true; + } + + if (!colValid) continue; + if (id == strip.getMainSegmentId() && i < 2) //temporary, to make transition work on main segment + { + if (i == 0) {col[0] = rgbw[0]; col[1] = rgbw[1]; col[2] = rgbw[2]; col[3] = rgbw[3];} + if (i == 1) {colSec[0] = rgbw[0]; colSec[1] = rgbw[1]; colSec[2] = rgbw[2]; colSec[3] = rgbw[3];} + } else { //normal case, apply directly to segment (=> no transition!) + seg.colors[i] = ((rgbw[3] << 24) | ((rgbw[0]&0xFF) << 16) | ((rgbw[1]&0xFF) << 8) | ((rgbw[2]&0xFF))); } } } @@ -179,7 +188,7 @@ bool deserializeState(JsonObject root) JsonObject nl = root["nl"]; nightlightActive = nl["on"] | nightlightActive; nightlightDelayMins = nl[F("dur")] | nightlightDelayMins; - nightlightMode = nl[F("fade")] | nightlightMode; //deprecated + nightlightMode = nl[F("fade")] | nightlightMode; //deprecated, remove for v0.12.0 nightlightMode = nl[F("mode")] | nightlightMode; nightlightTargetBri = nl[F("tbri")] | nightlightTargetBri; diff --git a/wled00/wled.cpp b/wled00/wled.cpp index 8930a517..d879fdc0 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -317,7 +317,7 @@ void WLED::beginStrip() strip.setBrightness(0); strip.setShowCallback(handleOverlayDraw); -#ifdef BTNPIN +#if defined(BTNPIN) && BTNPIN > -1 pinManager.allocatePin(BTNPIN, false); pinMode(BTNPIN, INPUT_PULLUP); #endif @@ -342,7 +342,7 @@ void WLED::beginStrip() #endif // disable button if it is "pressed" unintentionally -#if defined(BTNPIN) || defined(TOUCHPIN) +#if (defined(BTNPIN) && BTNPIN > -1) || defined(TOUCHPIN) if (isButtonPressed()) buttonEnabled = false; #else diff --git a/wled00/wled.h b/wled00/wled.h index c270599b..532ee993 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -8,7 +8,7 @@ */ // version code in format yymmddb (b = daily build) -#define VERSION 2011180 +#define VERSION 2011200 //uncomment this if you have a "my_config.h" file you'd like to use //#define WLED_USE_MY_CONFIG diff --git a/wled00/wled_server.cpp b/wled00/wled_server.cpp index b9e11b51..4970248f 100644 --- a/wled00/wled_server.cpp +++ b/wled00/wled_server.cpp @@ -96,7 +96,6 @@ void initServer() }); server.addHandler(handler); - //*******DEPRECATED******* server.on("/version", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/plain", (String)VERSION); }); @@ -108,7 +107,6 @@ void initServer() server.on("/freeheap", HTTP_GET, [](AsyncWebServerRequest *request){ request->send(200, "text/plain", (String)ESP.getFreeHeap()); }); - //*******END*******/ server.on("/u", HTTP_GET, [](AsyncWebServerRequest *request){ request->send_P(200, "text/html", PAGE_usermod);