From 94c5f0d7a8500e288578a001951bbc37db71d16d Mon Sep 17 00:00:00 2001 From: cschwinne Date: Thu, 30 Apr 2020 01:52:36 +0200 Subject: [PATCH] New API properties - Added realtime override option and `lor` JSON property - Added `lm` (live mode) and `lip` (live IP) properties to info in JSON API - Added reset commands to APIs - Added `json/si`, returning state and info, but no FX or Palette lists - Added rollover detection to millis(). Can track uptimes longer than 49 days - Attempted to fix Wifi issues with Unifi brand APs --- CHANGELOG.md | 9 ++++ wled00/const.h | 5 +++ wled00/e131.cpp | 4 ++ wled00/html_settings.h | 4 +- wled00/json.cpp | 37 ++++++++++++++-- wled00/set.cpp | 3 ++ wled00/udp.cpp | 97 ++++++++++++++++++++++-------------------- wled00/wled.cpp | 9 ++-- wled00/wled.h | 9 ++-- wled00/wled_serial.cpp | 4 +- wled00/xml.cpp | 6 +-- 11 files changed, 125 insertions(+), 62 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1626051d..0df948c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -2,6 +2,15 @@ ### Development versions after 0.9.1 release +#### Build 2004300 + +- Added realtime override option and `lor` JSON property +- Added `lm` (live mode) and `lip` (live IP) properties to info in JSON API +- Added reset commands to APIs +- Added `json/si`, returning state and info, but no FX or Palette lists +- Added rollover detection to millis(). Can track uptimes longer than 49 days +- Attempted to fix Wifi issues with Unifi brand APs + #### Build 2004230 - Added brightness and power for individual segments diff --git a/wled00/const.h b/wled00/const.h index 17604378..533a5f27 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -45,6 +45,11 @@ #define REALTIME_MODE_ADALIGHT 5 #define REALTIME_MODE_ARTNET 6 +//realtime override modes +#define REALTIME_OVERRIDE_NONE 0 +#define REALTIME_OVERRIDE_ONCE 1 +#define REALTIME_OVERRIDE_ALWAYS 2 + //E1.31 DMX modes #define DMX_MODE_DISABLED 0 //not used #define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels) diff --git a/wled00/e131.cpp b/wled00/e131.cpp index 6e774194..bfd93d69 100644 --- a/wled00/e131.cpp +++ b/wled00/e131.cpp @@ -56,6 +56,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){ if (uni != e131Universe) return; if (dmxChannels-DMXAddress+1 < 3) return; realtimeLock(realtimeTimeoutMs, mde); + if (realtimeOverride) return; for (uint16_t i = 0; i < ledCount; i++) setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], 0); break; @@ -64,6 +65,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){ if (uni != e131Universe) return; if (dmxChannels-DMXAddress+1 < 4) return; realtimeLock(realtimeTimeoutMs, mde); + if (realtimeOverride) return; if (DMXOldDimmer != e131_data[DMXAddress+0]) { DMXOldDimmer = e131_data[DMXAddress+0]; bri = e131_data[DMXAddress+0]; @@ -103,6 +105,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){ case DMX_MODE_MULTIPLE_RGB: realtimeLock(realtimeTimeoutMs, mde); + if (realtimeOverride) return; if (previousUniverses == 0) { // first universe of this fixture possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; @@ -125,6 +128,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){ case DMX_MODE_MULTIPLE_DRGB: realtimeLock(realtimeTimeoutMs, mde); + if (realtimeOverride) return; if (previousUniverses == 0) { // first universe of this fixture if (DMXOldDimmer != e131_data[DMXAddress+0]) { diff --git a/wled00/html_settings.h b/wled00/html_settings.h index 009dda50..b44f2942 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -344,7 +344,7 @@ Hue Bridge IP:

Press the pushlink button on the bridge, after that save this page!
(when first connecting)
-Hue status: Disabled in this build
+Hue status: Disabled in this build
)====="; @@ -475,7 +475,7 @@ Enable ArduinoOTA:
A huge thank you to everyone who helped me create WLED!

(c) 2016-2020 Christian Schwinne
Licensed under the MIT license

-Server message: Response error!
+Server message: Response error!
diff --git a/wled00/json.cpp b/wled00/json.cpp index 72d60738..8e781fc8 100644 --- a/wled00/json.cpp +++ b/wled00/json.cpp @@ -129,6 +129,10 @@ bool deserializeState(JsonObject root) int timein = root["time"] | -1; if (timein != -1) setTime(timein); + doReboot = root["rb"] | doReboot; + + realtimeOverride = root["lor"] | realtimeOverride; + if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS; byte prevMain = strip.getMainSegmentId(); strip.mainSegment = root["mainseg"] | prevMain; @@ -249,6 +253,8 @@ void serializeState(JsonObject root) udpn["send"] = notifyDirect; udpn["recv"] = receiveNotifications; + root["lor"] = realtimeOverride; + root["mainseg"] = strip.getMainSegmentId(); JsonArray seg = root.createNestedArray("seg"); @@ -287,6 +293,7 @@ void serializeInfo(JsonObject root) { root["ver"] = versionString; root["vid"] = VERSION; + root["cn"] = WLED_CODENAME; JsonObject leds = root.createNestedObject("leds"); leds["count"] = ledCount; @@ -305,6 +312,24 @@ void serializeInfo(JsonObject root) root["name"] = serverDescription; root["udpport"] = udpPort; root["live"] = (bool)realtimeMode; + + switch (realtimeMode) { + case REALTIME_MODE_INACTIVE: root["lm"] = ""; break; + case REALTIME_MODE_GENERIC: root["lm"] = ""; break; + case REALTIME_MODE_UDP: root["lm"] = "UDP"; break; + case REALTIME_MODE_HYPERION: root["lm"] = "Hyperion"; break; + case REALTIME_MODE_E131: root["lm"] = "E1.31"; break; + case REALTIME_MODE_ADALIGHT: root["lm"] = F("USB Adalight"); + case REALTIME_MODE_ARTNET: root["lm"] = "Art-Net"; break; + } + + if (realtimeIP[0] == 0) + { + root["lip"] = ""; + } else { + root["lip"] = realtimeIP.toString(); + } + root["fxcount"] = strip.getModeCount(); root["palcount"] = strip.getPaletteCount(); @@ -339,7 +364,7 @@ void serializeInfo(JsonObject root) #endif root["freeheap"] = ESP.getFreeHeap(); - root["uptime"] = millis()/1000; + root["uptime"] = millis()/1000 + rolloverMillis*4294967; byte os = 0; #ifdef WLED_DEBUG @@ -369,7 +394,7 @@ void serializeInfo(JsonObject root) root["opt"] = os; root["brand"] = "WLED"; - root["product"] = "DIY light"; + root["product"] = "FOSS"; root["mac"] = escapedMac; } @@ -379,6 +404,7 @@ void serveJson(AsyncWebServerRequest* request) const String& url = request->url(); if (url.indexOf("state") > 0) subJson = 1; else if (url.indexOf("info") > 0) subJson = 2; + else if (url.indexOf("si") > 0) subJson = 3; else if (url.indexOf("live") > 0) { serveLiveLeds(request); return; @@ -410,8 +436,11 @@ void serveJson(AsyncWebServerRequest* request) serializeState(state); JsonObject info = doc.createNestedObject("info"); serializeInfo(info); - doc["effects"] = serialized((const __FlashStringHelper*)JSON_mode_names); - doc["palettes"] = serialized((const __FlashStringHelper*)JSON_palette_names); + if (subJson != 3) + { + doc["effects"] = serialized((const __FlashStringHelper*)JSON_mode_names); + doc["palettes"] = serialized((const __FlashStringHelper*)JSON_palette_names); + } } response->setLength(); diff --git a/wled00/set.cpp b/wled00/set.cpp index d04c0cb2..7827909d 100644 --- a/wled00/set.cpp +++ b/wled00/set.cpp @@ -659,6 +659,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req) if (countdownTime - now() > 0) countdownOverTriggered = false; } + pos = req.indexOf("RB"); + if (pos > 0) doReboot = true; + //cronixie #ifndef WLED_DISABLE_CRONIXIE //mode, 1 countdown diff --git a/wled00/udp.cpp b/wled00/udp.cpp index a7f22438..2b35054f 100644 --- a/wled00/udp.cpp +++ b/wled00/udp.cpp @@ -74,16 +74,18 @@ void notify(byte callMode, bool followUp) void realtimeLock(uint32_t timeoutMs, byte md) { - if (!realtimeMode){ + if (!realtimeMode && !realtimeOverride){ for (uint16_t i = 0; i < ledCount; i++) { strip.setPixelColor(i,0,0,0,0); } - realtimeMode = md; } + realtimeTimeout = millis() + timeoutMs; if (timeoutMs == 255001 || timeoutMs == 65000) realtimeTimeout = UINT32_MAX; - if (arlsForceMaxBri) strip.setBrightness(255); + realtimeMode = md; + + if (arlsForceMaxBri && !realtimeOverride) strip.setBrightness(255); } @@ -103,8 +105,10 @@ void handleNotifications() //unlock strip when realtime UDP times out if (realtimeMode && millis() > realtimeTimeout) { + if (realtimeOverride == REALTIME_OVERRIDE_ONCE) realtimeOverride = REALTIME_OVERRIDE_NONE; strip.setBrightness(bri); realtimeMode = REALTIME_MODE_INACTIVE; + realtimeIP[0] = 0; } //receive UDP notifications @@ -122,6 +126,7 @@ void handleNotifications() uint8_t lbuf[packetSize]; rgbUdp.read(lbuf, packetSize); realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION); + if (realtimeOverride) return; uint16_t id = 0; for (uint16_t i = 0; i < packetSize -2; i += 3) { @@ -202,50 +207,52 @@ void handleNotifications() { realtimeIP = notifierUdp.remoteIP(); DEBUG_PRINTLN(notifierUdp.remoteIP()); - if (packetSize > 1) { - if (udpIn[1] == 0) - { - realtimeTimeout = 0; - return; - } else { - realtimeLock(udpIn[1]*1000 +1, REALTIME_MODE_UDP); - } - if (udpIn[0] == 1) //warls - { - for (uint16_t i = 2; i < packetSize -3; i += 4) - { - setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0); - } - } else if (udpIn[0] == 2) //drgb - { - uint16_t id = 0; - for (uint16_t i = 2; i < packetSize -2; i += 3) - { - setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0); + if (packetSize < 2) return; - id++; if (id >= ledCount) break; - } - } else if (udpIn[0] == 3) //drgbw - { - uint16_t id = 0; - for (uint16_t i = 2; i < packetSize -3; i += 4) - { - setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]); - - id++; if (id >= ledCount) break; - } - } else if (udpIn[0] == 4) //dnrgb - { - uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00); - for (uint16_t i = 4; i < packetSize -2; i += 3) - { - if (id >= ledCount) break; - setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0); - id++; - } - } - strip.show(); + if (udpIn[1] == 0) + { + realtimeTimeout = 0; + return; + } else { + realtimeLock(udpIn[1]*1000 +1, REALTIME_MODE_UDP); } + if (realtimeOverride) return; + + if (udpIn[0] == 1) //warls + { + for (uint16_t i = 2; i < packetSize -3; i += 4) + { + setRealtimePixel(udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3], 0); + } + } else if (udpIn[0] == 2) //drgb + { + uint16_t id = 0; + for (uint16_t i = 2; i < packetSize -2; i += 3) + { + setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0); + + id++; if (id >= ledCount) break; + } + } else if (udpIn[0] == 3) //drgbw + { + uint16_t id = 0; + for (uint16_t i = 2; i < packetSize -3; i += 4) + { + setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], udpIn[i+3]); + + id++; if (id >= ledCount) break; + } + } else if (udpIn[0] == 4) //dnrgb + { + uint16_t id = ((udpIn[3] << 0) & 0xFF) + ((udpIn[2] << 8) & 0xFF00); + for (uint16_t i = 4; i < packetSize -2; i += 3) + { + if (id >= ledCount) break; + setRealtimePixel(id, udpIn[i], udpIn[i+1], udpIn[i+2], 0); + id++; + } + } + strip.show(); } } } diff --git a/wled00/wled.cpp b/wled00/wled.cpp index cc853330..40ce6f60 100644 --- a/wled00/wled.cpp +++ b/wled00/wled.cpp @@ -67,7 +67,7 @@ void WLED::loop() if (doReboot) reset(); - if (!realtimeMode) // block stuff if WARLS/Adalight is enabled + if (!realtimeMode || realtimeOverride) // block stuff if WARLS/Adalight is enabled { if (apActive) dnsServer.processNextRequest(); @@ -89,8 +89,10 @@ void WLED::loop() #ifdef ESP8266 MDNS.update(); #endif - if (millis() - lastMqttReconnectAttempt > 30000) + if (millis() - lastMqttReconnectAttempt > 30000) { + if (lastMqttReconnectAttempt > millis()) rolloverMillis++; //millis() rolls over every 50 days initMqtt(); + } // DEBUG serial logging #ifdef WLED_DEBUG @@ -284,7 +286,7 @@ void WLED::initAP(bool resetAP) void WLED::initConnection() { - WiFi.disconnect(); // close old connections + WiFi.disconnect(true); // close old connections #ifdef ESP8266 WiFi.setPhyMode(WIFI_PHY_MODE_11N); #endif @@ -308,6 +310,7 @@ void WLED::initConnection() } else { DEBUG_PRINTLN("Access point disabled."); WiFi.softAPdisconnect(true); + WiFi.mode(WIFI_STA); } } showWelcomePage = false; diff --git a/wled00/wled.h b/wled00/wled.h index 64210d42..f3ffe780 100644 --- a/wled00/wled.h +++ b/wled00/wled.h @@ -3,12 +3,12 @@ /* Main sketch, global variable declarations @title WLED project sketch - @version 0.9.1n + @version 0.10.0p @author Christian Schwinne */ // version code in format yymmddb (b = daily build) -#define VERSION 2004230 +#define VERSION 2004300 // ESP8266-01 (blue) got too little storage space to work with all features of WLED. To use it, you must use ESP8266 Arduino Core v2.4.2 and the setting 512K(No SPIFFS). @@ -148,7 +148,8 @@ #endif // Global Variable definitions -WLED_GLOBAL char versionString[] _INIT("0.9.1n"); +WLED_GLOBAL char versionString[] _INIT("0.10.0p"); +#define WLED_CODENAME "Namigai" // AP and OTA default passwords (for maximum security change them!) WLED_GLOBAL char apPass[65] _INIT(DEFAULT_AP_PASS); @@ -414,6 +415,7 @@ WLED_GLOBAL bool saveCurrPresetCycConf _INIT(false); // realtime WLED_GLOBAL byte realtimeMode _INIT(REALTIME_MODE_INACTIVE); +WLED_GLOBAL byte realtimeOverride _INIT(REALTIME_OVERRIDE_NONE); WLED_GLOBAL IPAddress realtimeIP _INIT((0, 0, 0, 0)); WLED_GLOBAL unsigned long realtimeTimeout _INIT(0); @@ -447,6 +449,7 @@ WLED_GLOBAL unsigned long ntpLastSyncTime _INIT(999000000L); WLED_GLOBAL unsigned long ntpPacketSentTime _INIT(999000000L); WLED_GLOBAL IPAddress ntpServerIP; WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390); +WLED_GLOBAL uint16_t rolloverMillis _INIT(0); // Temp buffer WLED_GLOBAL char* obuf; diff --git a/wled00/wled_serial.cpp b/wled00/wled_serial.cpp index 067c5be8..aa89b713 100644 --- a/wled00/wled_serial.cpp +++ b/wled00/wled_serial.cpp @@ -67,13 +67,13 @@ void handleSerial() break; case AdaState::Data_Blue: byte blue = next; - setRealtimePixel(pixel++, red, green, blue, 0); + if (!realtimeOverride) setRealtimePixel(pixel++, red, green, blue, 0); if (--count > 0) state = AdaState::Data_Red; else { if (!realtimeMode && bri == 0) strip.setBrightness(briLast); realtimeLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT); - strip.show(); + if (!realtimeOverride) strip.show(); state = AdaState::Header_A; } break; diff --git a/wled00/xml.cpp b/wled00/xml.cpp index 6edf8aa7..ab1c8e94 100644 --- a/wled00/xml.cpp +++ b/wled00/xml.cpp @@ -382,7 +382,7 @@ void getSettingsJS(byte subPage, char* dest) default: sprintf(hueErrorString,"Bridge Error %i",hueError); } - sappends('m',"(\"hms\")[0]",hueErrorString); + sappends('m',"(\"sip\")[0]",hueErrorString); #endif } @@ -445,12 +445,12 @@ void getSettingsJS(byte subPage, char* dest) sappend('c',"NO",otaLock); sappend('c',"OW",wifiLock); sappend('c',"AO",aOtaEnabled); - sappends('m',"(\"msg\")[0]","WLED "); + sappends('m',"(\"sip\")[0]","WLED "); olen -= 2; //delete "; oappend(versionString); oappend(" (build "); oappendi(VERSION); - oappend(") OK\";"); + oappend(")\";"); } #ifdef WLED_ENABLE_DMX // include only if DMX is enabled