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
This commit is contained in:
cschwinne 2020-04-30 01:52:36 +02:00
parent b1028086a3
commit 94c5f0d7a8
11 changed files with 125 additions and 62 deletions

View File

@ -2,6 +2,15 @@
### Development versions after 0.9.1 release ### 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 #### Build 2004230
- Added brightness and power for individual segments - Added brightness and power for individual segments

View File

@ -45,6 +45,11 @@
#define REALTIME_MODE_ADALIGHT 5 #define REALTIME_MODE_ADALIGHT 5
#define REALTIME_MODE_ARTNET 6 #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 //E1.31 DMX modes
#define DMX_MODE_DISABLED 0 //not used #define DMX_MODE_DISABLED 0 //not used
#define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels) #define DMX_MODE_SINGLE_RGB 1 //all LEDs same RGB color (3 channels)

View File

@ -56,6 +56,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
if (uni != e131Universe) return; if (uni != e131Universe) return;
if (dmxChannels-DMXAddress+1 < 3) return; if (dmxChannels-DMXAddress+1 < 3) return;
realtimeLock(realtimeTimeoutMs, mde); realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
for (uint16_t i = 0; i < ledCount; i++) for (uint16_t i = 0; i < ledCount; i++)
setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], 0); setRealtimePixel(i, e131_data[DMXAddress+0], e131_data[DMXAddress+1], e131_data[DMXAddress+2], 0);
break; break;
@ -64,6 +65,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
if (uni != e131Universe) return; if (uni != e131Universe) return;
if (dmxChannels-DMXAddress+1 < 4) return; if (dmxChannels-DMXAddress+1 < 4) return;
realtimeLock(realtimeTimeoutMs, mde); realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
if (DMXOldDimmer != e131_data[DMXAddress+0]) { if (DMXOldDimmer != e131_data[DMXAddress+0]) {
DMXOldDimmer = e131_data[DMXAddress+0]; DMXOldDimmer = e131_data[DMXAddress+0];
bri = 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: case DMX_MODE_MULTIPLE_RGB:
realtimeLock(realtimeTimeoutMs, mde); realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
if (previousUniverses == 0) { if (previousUniverses == 0) {
// first universe of this fixture // first universe of this fixture
possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3; possibleLEDsInCurrentUniverse = (dmxChannels - DMXAddress + 1) / 3;
@ -125,6 +128,7 @@ void handleE131Packet(e131_packet_t* p, IPAddress clientIP, bool isArtnet){
case DMX_MODE_MULTIPLE_DRGB: case DMX_MODE_MULTIPLE_DRGB:
realtimeLock(realtimeTimeoutMs, mde); realtimeLock(realtimeTimeoutMs, mde);
if (realtimeOverride) return;
if (previousUniverses == 0) { if (previousUniverses == 0) {
// first universe of this fixture // first universe of this fixture
if (DMXOldDimmer != e131_data[DMXAddress+0]) { if (DMXOldDimmer != e131_data[DMXAddress+0]) {

View File

@ -344,7 +344,7 @@ Hue Bridge IP:<br>
<input name=H3 type=number min=0 max=255><br> <input name=H3 type=number min=0 max=255><br>
<b>Press the pushlink button on the bridge, after that save this page!</b><br> <b>Press the pushlink button on the bridge, after that save this page!</b><br>
(when first connecting)<br> (when first connecting)<br>
Hue status: <span class=hms> Disabled in this build </span><hr> Hue status: <span class=sip> Disabled in this build </span><hr>
<button type=button onclick=B()>Back</button><button type=submit>Save</button> <button type=button onclick=B()>Back</button><button type=submit>Save</button>
</form> </form>
</body></html>)====="; </body></html>)=====";
@ -475,7 +475,7 @@ Enable ArduinoOTA: <input type="checkbox" name="AO"><br>
A huge thank you to everyone who helped me create WLED!<br><br> A huge thank you to everyone who helped me create WLED!<br><br>
(c) 2016-2020 Christian Schwinne <br> (c) 2016-2020 Christian Schwinne <br>
<i>Licensed under the MIT license</i><br><br> <i>Licensed under the MIT license</i><br><br>
Server message: <span class="msg"> Response error! </span><hr> Server message: <span class="sip"> Response error! </span><hr>
<button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button> <button type="button" onclick="B()">Back</button><button type="submit">Save & Reboot</button>
</form> </form>
</body> </body>

View File

@ -129,6 +129,10 @@ bool deserializeState(JsonObject root)
int timein = root["time"] | -1; int timein = root["time"] | -1;
if (timein != -1) setTime(timein); if (timein != -1) setTime(timein);
doReboot = root["rb"] | doReboot;
realtimeOverride = root["lor"] | realtimeOverride;
if (realtimeOverride > 2) realtimeOverride = REALTIME_OVERRIDE_ALWAYS;
byte prevMain = strip.getMainSegmentId(); byte prevMain = strip.getMainSegmentId();
strip.mainSegment = root["mainseg"] | prevMain; strip.mainSegment = root["mainseg"] | prevMain;
@ -249,6 +253,8 @@ void serializeState(JsonObject root)
udpn["send"] = notifyDirect; udpn["send"] = notifyDirect;
udpn["recv"] = receiveNotifications; udpn["recv"] = receiveNotifications;
root["lor"] = realtimeOverride;
root["mainseg"] = strip.getMainSegmentId(); root["mainseg"] = strip.getMainSegmentId();
JsonArray seg = root.createNestedArray("seg"); JsonArray seg = root.createNestedArray("seg");
@ -287,6 +293,7 @@ void serializeInfo(JsonObject root)
{ {
root["ver"] = versionString; root["ver"] = versionString;
root["vid"] = VERSION; root["vid"] = VERSION;
root["cn"] = WLED_CODENAME;
JsonObject leds = root.createNestedObject("leds"); JsonObject leds = root.createNestedObject("leds");
leds["count"] = ledCount; leds["count"] = ledCount;
@ -305,6 +312,24 @@ void serializeInfo(JsonObject root)
root["name"] = serverDescription; root["name"] = serverDescription;
root["udpport"] = udpPort; root["udpport"] = udpPort;
root["live"] = (bool)realtimeMode; 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["fxcount"] = strip.getModeCount();
root["palcount"] = strip.getPaletteCount(); root["palcount"] = strip.getPaletteCount();
@ -339,7 +364,7 @@ void serializeInfo(JsonObject root)
#endif #endif
root["freeheap"] = ESP.getFreeHeap(); root["freeheap"] = ESP.getFreeHeap();
root["uptime"] = millis()/1000; root["uptime"] = millis()/1000 + rolloverMillis*4294967;
byte os = 0; byte os = 0;
#ifdef WLED_DEBUG #ifdef WLED_DEBUG
@ -369,7 +394,7 @@ void serializeInfo(JsonObject root)
root["opt"] = os; root["opt"] = os;
root["brand"] = "WLED"; root["brand"] = "WLED";
root["product"] = "DIY light"; root["product"] = "FOSS";
root["mac"] = escapedMac; root["mac"] = escapedMac;
} }
@ -379,6 +404,7 @@ void serveJson(AsyncWebServerRequest* request)
const String& url = request->url(); const String& url = request->url();
if (url.indexOf("state") > 0) subJson = 1; if (url.indexOf("state") > 0) subJson = 1;
else if (url.indexOf("info") > 0) subJson = 2; else if (url.indexOf("info") > 0) subJson = 2;
else if (url.indexOf("si") > 0) subJson = 3;
else if (url.indexOf("live") > 0) { else if (url.indexOf("live") > 0) {
serveLiveLeds(request); serveLiveLeds(request);
return; return;
@ -410,8 +436,11 @@ void serveJson(AsyncWebServerRequest* request)
serializeState(state); serializeState(state);
JsonObject info = doc.createNestedObject("info"); JsonObject info = doc.createNestedObject("info");
serializeInfo(info); serializeInfo(info);
doc["effects"] = serialized((const __FlashStringHelper*)JSON_mode_names); if (subJson != 3)
doc["palettes"] = serialized((const __FlashStringHelper*)JSON_palette_names); {
doc["effects"] = serialized((const __FlashStringHelper*)JSON_mode_names);
doc["palettes"] = serialized((const __FlashStringHelper*)JSON_palette_names);
}
} }
response->setLength(); response->setLength();

View File

@ -659,6 +659,9 @@ bool handleSet(AsyncWebServerRequest *request, const String& req)
if (countdownTime - now() > 0) countdownOverTriggered = false; if (countdownTime - now() > 0) countdownOverTriggered = false;
} }
pos = req.indexOf("RB");
if (pos > 0) doReboot = true;
//cronixie //cronixie
#ifndef WLED_DISABLE_CRONIXIE #ifndef WLED_DISABLE_CRONIXIE
//mode, 1 countdown //mode, 1 countdown

View File

@ -74,16 +74,18 @@ void notify(byte callMode, bool followUp)
void realtimeLock(uint32_t timeoutMs, byte md) void realtimeLock(uint32_t timeoutMs, byte md)
{ {
if (!realtimeMode){ if (!realtimeMode && !realtimeOverride){
for (uint16_t i = 0; i < ledCount; i++) for (uint16_t i = 0; i < ledCount; i++)
{ {
strip.setPixelColor(i,0,0,0,0); strip.setPixelColor(i,0,0,0,0);
} }
realtimeMode = md;
} }
realtimeTimeout = millis() + timeoutMs; realtimeTimeout = millis() + timeoutMs;
if (timeoutMs == 255001 || timeoutMs == 65000) realtimeTimeout = UINT32_MAX; 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 //unlock strip when realtime UDP times out
if (realtimeMode && millis() > realtimeTimeout) if (realtimeMode && millis() > realtimeTimeout)
{ {
if (realtimeOverride == REALTIME_OVERRIDE_ONCE) realtimeOverride = REALTIME_OVERRIDE_NONE;
strip.setBrightness(bri); strip.setBrightness(bri);
realtimeMode = REALTIME_MODE_INACTIVE; realtimeMode = REALTIME_MODE_INACTIVE;
realtimeIP[0] = 0;
} }
//receive UDP notifications //receive UDP notifications
@ -122,6 +126,7 @@ void handleNotifications()
uint8_t lbuf[packetSize]; uint8_t lbuf[packetSize];
rgbUdp.read(lbuf, packetSize); rgbUdp.read(lbuf, packetSize);
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION); realtimeLock(realtimeTimeoutMs, REALTIME_MODE_HYPERION);
if (realtimeOverride) return;
uint16_t id = 0; uint16_t id = 0;
for (uint16_t i = 0; i < packetSize -2; i += 3) for (uint16_t i = 0; i < packetSize -2; i += 3)
{ {
@ -202,50 +207,52 @@ void handleNotifications()
{ {
realtimeIP = notifierUdp.remoteIP(); realtimeIP = notifierUdp.remoteIP();
DEBUG_PRINTLN(notifierUdp.remoteIP()); DEBUG_PRINTLN(notifierUdp.remoteIP());
if (packetSize > 1) { if (packetSize < 2) return;
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);
id++; if (id >= ledCount) break; if (udpIn[1] == 0)
} {
} else if (udpIn[0] == 3) //drgbw realtimeTimeout = 0;
{ return;
uint16_t id = 0; } else {
for (uint16_t i = 2; i < packetSize -3; i += 4) realtimeLock(udpIn[1]*1000 +1, REALTIME_MODE_UDP);
{
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 (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();
} }
} }
} }

View File

@ -67,7 +67,7 @@ void WLED::loop()
if (doReboot) if (doReboot)
reset(); reset();
if (!realtimeMode) // block stuff if WARLS/Adalight is enabled if (!realtimeMode || realtimeOverride) // block stuff if WARLS/Adalight is enabled
{ {
if (apActive) if (apActive)
dnsServer.processNextRequest(); dnsServer.processNextRequest();
@ -89,8 +89,10 @@ void WLED::loop()
#ifdef ESP8266 #ifdef ESP8266
MDNS.update(); MDNS.update();
#endif #endif
if (millis() - lastMqttReconnectAttempt > 30000) if (millis() - lastMqttReconnectAttempt > 30000) {
if (lastMqttReconnectAttempt > millis()) rolloverMillis++; //millis() rolls over every 50 days
initMqtt(); initMqtt();
}
// DEBUG serial logging // DEBUG serial logging
#ifdef WLED_DEBUG #ifdef WLED_DEBUG
@ -284,7 +286,7 @@ void WLED::initAP(bool resetAP)
void WLED::initConnection() void WLED::initConnection()
{ {
WiFi.disconnect(); // close old connections WiFi.disconnect(true); // close old connections
#ifdef ESP8266 #ifdef ESP8266
WiFi.setPhyMode(WIFI_PHY_MODE_11N); WiFi.setPhyMode(WIFI_PHY_MODE_11N);
#endif #endif
@ -308,6 +310,7 @@ void WLED::initConnection()
} else { } else {
DEBUG_PRINTLN("Access point disabled."); DEBUG_PRINTLN("Access point disabled.");
WiFi.softAPdisconnect(true); WiFi.softAPdisconnect(true);
WiFi.mode(WIFI_STA);
} }
} }
showWelcomePage = false; showWelcomePage = false;

View File

@ -3,12 +3,12 @@
/* /*
Main sketch, global variable declarations Main sketch, global variable declarations
@title WLED project sketch @title WLED project sketch
@version 0.9.1n @version 0.10.0p
@author Christian Schwinne @author Christian Schwinne
*/ */
// version code in format yymmddb (b = daily build) // 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). // 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 #endif
// Global Variable definitions // 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!) // AP and OTA default passwords (for maximum security change them!)
WLED_GLOBAL char apPass[65] _INIT(DEFAULT_AP_PASS); WLED_GLOBAL char apPass[65] _INIT(DEFAULT_AP_PASS);
@ -414,6 +415,7 @@ WLED_GLOBAL bool saveCurrPresetCycConf _INIT(false);
// realtime // realtime
WLED_GLOBAL byte realtimeMode _INIT(REALTIME_MODE_INACTIVE); 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 IPAddress realtimeIP _INIT((0, 0, 0, 0));
WLED_GLOBAL unsigned long realtimeTimeout _INIT(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 unsigned long ntpPacketSentTime _INIT(999000000L);
WLED_GLOBAL IPAddress ntpServerIP; WLED_GLOBAL IPAddress ntpServerIP;
WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390); WLED_GLOBAL uint16_t ntpLocalPort _INIT(2390);
WLED_GLOBAL uint16_t rolloverMillis _INIT(0);
// Temp buffer // Temp buffer
WLED_GLOBAL char* obuf; WLED_GLOBAL char* obuf;

View File

@ -67,13 +67,13 @@ void handleSerial()
break; break;
case AdaState::Data_Blue: case AdaState::Data_Blue:
byte blue = next; byte blue = next;
setRealtimePixel(pixel++, red, green, blue, 0); if (!realtimeOverride) setRealtimePixel(pixel++, red, green, blue, 0);
if (--count > 0) state = AdaState::Data_Red; if (--count > 0) state = AdaState::Data_Red;
else { else {
if (!realtimeMode && bri == 0) strip.setBrightness(briLast); if (!realtimeMode && bri == 0) strip.setBrightness(briLast);
realtimeLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT); realtimeLock(realtimeTimeoutMs, REALTIME_MODE_ADALIGHT);
strip.show(); if (!realtimeOverride) strip.show();
state = AdaState::Header_A; state = AdaState::Header_A;
} }
break; break;

View File

@ -382,7 +382,7 @@ void getSettingsJS(byte subPage, char* dest)
default: sprintf(hueErrorString,"Bridge Error %i",hueError); default: sprintf(hueErrorString,"Bridge Error %i",hueError);
} }
sappends('m',"(\"hms\")[0]",hueErrorString); sappends('m',"(\"sip\")[0]",hueErrorString);
#endif #endif
} }
@ -445,12 +445,12 @@ void getSettingsJS(byte subPage, char* dest)
sappend('c',"NO",otaLock); sappend('c',"NO",otaLock);
sappend('c',"OW",wifiLock); sappend('c',"OW",wifiLock);
sappend('c',"AO",aOtaEnabled); sappend('c',"AO",aOtaEnabled);
sappends('m',"(\"msg\")[0]","WLED "); sappends('m',"(\"sip\")[0]","WLED ");
olen -= 2; //delete "; olen -= 2; //delete ";
oappend(versionString); oappend(versionString);
oappend(" (build "); oappend(" (build ");
oappendi(VERSION); oappendi(VERSION);
oappend(") OK\";"); oappend(")\";");
} }
#ifdef WLED_ENABLE_DMX // include only if DMX is enabled #ifdef WLED_ENABLE_DMX // include only if DMX is enabled