Merge branch 'dev' of github.com:blazoncek/WLED into dev

This commit is contained in:
Blaz Kristan 2021-07-14 16:20:16 +02:00
commit b10568e917
16 changed files with 2282 additions and 2260 deletions

View File

@ -2,6 +2,14 @@
### Builds after release 0.12.0 ### Builds after release 0.12.0
#### Build 2107100
- Version bump to 0.13.0-b2 "Toki"
- Accept hex color strings in individual LED API
- Fixed transition property not applying unless power/bri/color changed next
- Moved transition field below segments (temporarily)
- Reduced unneeded websockets pushes
#### Build 2107091 #### Build 2107091
- Fixed presets using wrong call mode (e.g. causing buttons to send UDP under direct change type) - Fixed presets using wrong call mode (e.g. causing buttons to send UDP under direct change type)

2
package-lock.json generated
View File

@ -1,6 +1,6 @@
{ {
"name": "wled", "name": "wled",
"version": "0.13.0-bl1", "version": "0.13.0-bl2",
"lockfileVersion": 1, "lockfileVersion": 1,
"requires": true, "requires": true,
"dependencies": { "dependencies": {

View File

@ -1,6 +1,6 @@
{ {
"name": "wled", "name": "wled",
"version": "0.13.0-bl1", "version": "0.13.0-bl2",
"description": "Tools for WLED project", "description": "Tools for WLED project",
"main": "tools/cdata.js", "main": "tools/cdata.js",
"directories": { "directories": {

View File

@ -32,7 +32,7 @@ def bin_rename_copy(source, target, env):
release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME") release_name = _get_cpp_define_value(env, "WLED_RELEASE_NAME")
if release_name and os.getenv("WLED_RELEASE"): if release_name:
_create_dirs(["release"]) _create_dirs(["release"])
version = _get_cpp_define_value(env, "WLED_VERSION") version = _get_cpp_define_value(env, "WLED_VERSION")
release_file = "{}release{}WLED_{}_{}.bin".format(OUTPUT_DIR, os.path.sep, version, release_name) release_file = "{}release{}WLED_{}_{}.bin".format(OUTPUT_DIR, os.path.sep, version, release_name)

View File

@ -263,7 +263,7 @@ bool deserializeConfig(JsonObject doc, bool fromFS) {
JsonObject if_sync_recv = if_sync["recv"]; JsonObject if_sync_recv = if_sync["recv"];
CJSON(receiveNotificationBrightness, if_sync_recv["bri"]); CJSON(receiveNotificationBrightness, if_sync_recv["bri"]);
CJSON(receiveNotificationColor, if_sync_recv["col"]); CJSON(receiveNotificationColor, if_sync_recv["col"]);
CJSON(receiveNotificationEffects, if_sync_recv[F("fx")]); CJSON(receiveNotificationEffects, if_sync_recv["fx"]);
//! following line might be a problem if called after boot //! following line might be a problem if called after boot
receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects); receiveNotifications = (receiveNotificationBrightness || receiveNotificationColor || receiveNotificationEffects);

View File

@ -643,6 +643,12 @@ input[type=range]::-moz-range-thumb {
-webkit-backface-visibility: hidden; -webkit-backface-visibility: hidden;
-webkit-transform:translate3d(0,0,0); -webkit-transform:translate3d(0,0,0);
} }
#tt {
text-align: center;
}
.cl {
width: 42px;
}
.sel-pl { .sel-pl {
width: 165px; width: 165px;
background-position: 141px 16px; background-position: 141px 16px;

View File

@ -172,6 +172,7 @@
<div id="segutil2"> <div id="segutil2">
<button class="btn btn-s" id="rsbtn" onclick="rSegs()">Reset segments</button> <button class="btn btn-s" id="rsbtn" onclick="rSegs()">Reset segments</button>
</div> </div>
<p>Transition: <input id="tt" class="noslide" type="number" min="0" max="65.5" step="0.1" value="0.7">s</p>
</div> </div>
<div id="Favorites" class="tabcontent"> <div id="Favorites" class="tabcontent">
@ -181,8 +182,7 @@
</div> </div>
<div id="pcont"> <div id="pcont">
Loading... Loading...
</div><br> </div>
Transition <input id="tt" class="noslide" type="number" min="0" max="65.5" step="0.1" value="0.7">s
</div> </div>
</div> </div>

View File

@ -1200,6 +1200,11 @@ function requestJson(command, rinfo = true)
{ {
command.v = true; // force complete /json/si API response command.v = true; // force complete /json/si API response
command.time = Math.floor(Date.now() / 1000); command.time = Math.floor(Date.now() / 1000);
var t = d.getElementById('tt');
if (t.validity.valid) {
var tn = parseInt(t.value*10);
if (tn != tr) command.transition = tn;
}
req = JSON.stringify(command); req = JSON.stringify(command);
if (req.length > 1000) useWs = false; //do not send very long requests over websocket if (req.length > 1000) useWs = false; //do not send very long requests over websocket
} }
@ -1242,7 +1247,6 @@ function togglePower()
{ {
isOn = !isOn; isOn = !isOn;
var obj = {"on": isOn}; var obj = {"on": isOn};
obj.transition = parseInt(gId('tt').value*10);
requestJson(obj, false); requestJson(obj, false);
} }
@ -1639,7 +1643,6 @@ function setPalette(paletteId = null)
function setBri() function setBri()
{ {
var obj = {"bri": parseInt(gId('sliderBri').value)}; var obj = {"bri": parseInt(gId('sliderBri').value)};
obj.transition = parseInt(gId('tt').value*10);
requestJson(obj, false); requestJson(obj, false);
} }
@ -1855,7 +1858,6 @@ function setColor(sr)
} }
updateHex(); updateHex();
updateRgb(); updateRgb();
obj.transition = parseInt(gId('tt').value*10);
requestJson(obj, false); requestJson(obj, false);
} }

View File

@ -179,7 +179,7 @@ void _drawOverlayCronixie();
//playlist.cpp //playlist.cpp
void shufflePlaylist(); void shufflePlaylist();
void unloadPlaylist(); void unloadPlaylist();
void loadPlaylist(JsonObject playlistObject, byte presetId = 0); int16_t loadPlaylist(JsonObject playlistObject, byte presetId = 0);
void handlePlaylist(); void handlePlaylist();
//presets.cpp //presets.cpp

View File

@ -42,7 +42,7 @@ function B(){window.history.back()}function U(){document.getElementById("uf").st
.bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none} .bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none}
</style></head><body><h2>WLED Software Update</h2><form method="POST" </style></head><body><h2>WLED Software Update</h2><form method="POST"
action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()"> action="/update" id="uf" enctype="multipart/form-data" onsubmit="U()">
Installed version: 0.13.0-bl1<br>Download the latest binary: <a Installed version: 0.13.0-bl2<br>Download the latest binary: <a
href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img href="https://github.com/Aircoookie/WLED/releases" target="_blank"><img
src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square"> src="https://img.shields.io/github/release/Aircoookie/WLED.svg?style=flat-square">
</a><br><input type="file" class="bt" name="update" required><br><input </a><br><input type="file" class="bt" name="update" required><br><input

View File

@ -395,7 +395,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form
<h3>Software Update</h3><button type="button" onclick="U()">Manual OTA Update <h3>Software Update</h3><button type="button" onclick="U()">Manual OTA Update
</button><br>Enable ArduinoOTA: <input type="checkbox" name="AO"><br><h3>About </button><br>Enable ArduinoOTA: <input type="checkbox" name="AO"><br><h3>About
</h3><a href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a> </h3><a href="https://github.com/Aircoookie/WLED/" target="_blank">WLED</a>
version 0.13.0-bl1<br><br><a version 0.13.0-bl2<br><br><a
href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits" href="https://github.com/Aircoookie/WLED/wiki/Contributors-and-credits"
target="_blank">Contributors, dependencies and special thanks</a><br> target="_blank">Contributors, dependencies and special thanks</a><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>

File diff suppressed because it is too large Load Diff

View File

@ -143,13 +143,13 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
//temporary, strip object gets updated via colorUpdated() //temporary, strip object gets updated via colorUpdated()
if (id == strip.getMainSegmentId()) { if (id == strip.getMainSegmentId()) {
byte effectPrev = effectCurrent; byte effectPrev = effectCurrent;
effectCurrent = elem[F("fx")] | effectCurrent; effectCurrent = elem["fx"] | effectCurrent;
if (!presetId && effectCurrent != effectPrev) unloadPlaylist(); //stop playlist if active and FX changed manually if (!presetId && effectCurrent != effectPrev) unloadPlaylist(); //stop playlist if active and FX changed manually
effectSpeed = elem[F("sx")] | effectSpeed; effectSpeed = elem[F("sx")] | effectSpeed;
effectIntensity = elem[F("ix")] | effectIntensity; effectIntensity = elem[F("ix")] | effectIntensity;
effectPalette = elem["pal"] | effectPalette; effectPalette = elem["pal"] | effectPalette;
} else { //permanent } else { //permanent
byte fx = elem[F("fx")] | seg.mode; byte fx = elem["fx"] | seg.mode;
if (fx != seg.mode && fx < strip.getModeCount()) { if (fx != seg.mode && fx < strip.getModeCount()) {
strip.setMode(id, fx); strip.setMode(id, fx);
if (!presetId) unloadPlaylist(); //stop playlist if active and FX changed manually if (!presetId) unloadPlaylist(); //stop playlist if active and FX changed manually
@ -181,22 +181,19 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
stop = iarr[i]; stop = iarr[i];
set = 2; set = 2;
} }
} else { } else { //color
JsonArray icol = iarr[i];
if (icol.isNull()) break;
byte sz = icol.size();
if (sz == 0 || sz > 4) break;
int rgbw[] = {0,0,0,0}; int rgbw[] = {0,0,0,0};
copyArray(icol, rgbw); JsonArray icol = iarr[i];
if (!icol.isNull()) { //array, e.g. [255,0,0]
if (set < 2) stop = start + 1; byte sz = icol.size();
for (uint16_t i = start; i < stop; i++) { if (sz > 0 || sz < 5) copyArray(icol, rgbw);
strip.setPixelColor(i, rgbw[0], rgbw[1], rgbw[2], rgbw[3]); } else { //hex string, e.g. "FF0000"
byte brgbw[] = {0,0,0,0};
const char* hexCol = iarr[i];
if (colorFromHexString(brgbw, hexCol)) {
for (uint8_t c = 0; c < 4; c++) rgbw[c] = brgbw[c];
}
} }
if (!set) start++;
set = 0;
} }
} }
strip.setPixelSegment(255); strip.setPixelSegment(255);
@ -204,7 +201,7 @@ void deserializeSegment(JsonObject elem, byte it, byte presetId)
} else { //return to regular effect } else { //return to regular effect
seg.setOption(SEG_OPTION_FREEZE, false); seg.setOption(SEG_OPTION_FREEZE, false);
} }
return; // seg.hasChanged(prev); return; // seg.differs(prev);
} }
bool deserializeState(JsonObject root, byte callMode, byte presetId) bool deserializeState(JsonObject root, byte callMode, byte presetId)
@ -351,9 +348,9 @@ bool deserializeState(JsonObject root, byte callMode, byte presetId)
} }
JsonObject playlist = root[F("playlist")]; JsonObject playlist = root[F("playlist")];
if (!playlist.isNull()) { if (!playlist.isNull() && loadPlaylist(playlist, presetId)) {
loadPlaylist(playlist, presetId); //do not notify here, because the first playlist entry will do
noNotification = true; //do not notify both for this request and the first playlist entry noNotification = true;
} else { } else {
interfaceUpdateCallMode = CALL_MODE_WS_SEND; interfaceUpdateCallMode = CALL_MODE_WS_SEND;
} }

View File

@ -53,16 +53,16 @@ void unloadPlaylist() {
} }
void loadPlaylist(JsonObject playlistObj, byte presetId) { int16_t loadPlaylist(JsonObject playlistObj, byte presetId) {
unloadPlaylist(); unloadPlaylist();
JsonArray presets = playlistObj["ps"]; JsonArray presets = playlistObj["ps"];
playlistLen = presets.size(); playlistLen = presets.size();
if (playlistLen == 0) return; if (playlistLen == 0) return -1;
if (playlistLen > 100) playlistLen = 100; if (playlistLen > 100) playlistLen = 100;
playlistEntries = new PlaylistEntry[playlistLen]; playlistEntries = new PlaylistEntry[playlistLen];
if (playlistEntries == nullptr) return; if (playlistEntries == nullptr) return -1;
byte it = 0; byte it = 0;
for (int ps : presets) { for (int ps : presets) {
@ -113,6 +113,7 @@ void loadPlaylist(JsonObject playlistObj, byte presetId) {
currentPlaylist = presetId; currentPlaylist = presetId;
DEBUG_PRINTLN(F("Playlist loaded.")); DEBUG_PRINTLN(F("Playlist loaded."));
return currentPlaylist;
} }

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.13.0-bl1 @version 0.13.0-bl2
@author Christian Schwinne @author Christian Schwinne
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2107101 #define VERSION 2107141
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG
@ -499,7 +499,7 @@ WLED_GLOBAL bool blynkEnabled _INIT(false);
//playlists //playlists
WLED_GLOBAL unsigned long presetCycledTime _INIT(0); WLED_GLOBAL unsigned long presetCycledTime _INIT(0);
WLED_GLOBAL int16_t currentPlaylist _INIT(0); WLED_GLOBAL int16_t currentPlaylist _INIT(-1);
//still used for "PL=~" HTTP API command //still used for "PL=~" HTTP API command
WLED_GLOBAL byte presetCycleMin _INIT(1), presetCycleMax _INIT(5); WLED_GLOBAL byte presetCycleMin _INIT(1), presetCycleMax _INIT(5);
WLED_GLOBAL byte presetCycCurr _INIT(presetCycleMin); WLED_GLOBAL byte presetCycCurr _INIT(presetCycleMin);

View File

@ -38,13 +38,20 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
serializeJson(root,Serial); serializeJson(root,Serial);
DEBUG_PRINTLN(); DEBUG_PRINTLN();
#endif #endif
if (root.containsKey("lv")) if (root["v"] && root.size() == 1) {
//if the received value is just "{"v":true}", send only to this client
verboseResponse = true;
} else if (root.containsKey("lv"))
{ {
wsLiveClientId = root["lv"] ? client->id() : 0; wsLiveClientId = root["lv"] ? client->id() : 0;
} else { } else {
fileDoc = &jsonBuffer; fileDoc = &jsonBuffer;
verboseResponse = deserializeState(root); verboseResponse = deserializeState(root);
fileDoc = nullptr; fileDoc = nullptr;
if (!interfaceUpdateCallMode) {
//special case, only on playlist load, avoid sending twice in rapid succession
if (millis() - lastInterfaceUpdate > 1700) verboseResponse = false;
}
} }
} }
//update if it takes longer than 300ms until next "broadcast" //update if it takes longer than 300ms until next "broadcast"