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
#### 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

View File

@ -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)

View File

@ -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]) {

View File

@ -344,7 +344,7 @@ Hue Bridge IP:<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>
(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>
</form>
</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>
(c) 2016-2020 Christian Schwinne <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>
</form>
</body>

View File

@ -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();

View File

@ -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

View File

@ -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();
}
}
}

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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