Merge branch 'master' into dev
This commit is contained in:
commit
944b857825
18
CHANGELOG.md
18
CHANGELOG.md
@ -2,6 +2,24 @@
|
||||
|
||||
### Builds after release 0.12.0
|
||||
|
||||
#### Build 2107080
|
||||
|
||||
- Made Peek use the main websocket connection instead of opening a second one
|
||||
- Temperature usermod fix (from @blazoncek's dev branch)
|
||||
|
||||
#### Build 2107070
|
||||
|
||||
- More robust initial resource loading in UI
|
||||
- Added `getJsonValue()` for usermod config parsing (PR #2061)
|
||||
- Fixed preset saving over websocket
|
||||
- Alpha ESP32 S2 support (filesystem does not work) (PR #2067)
|
||||
|
||||
#### Build 2107042
|
||||
|
||||
- Updated ArduinoJson to 6.18.1
|
||||
- Improved Twinkleup effect
|
||||
- Fixed preset immediately deselecting when set via HTTP API `PL=`
|
||||
|
||||
#### Build 2107041
|
||||
|
||||
- Restored support for "PL=~" mistakenly removed in 2106300
|
||||
|
@ -213,6 +213,7 @@ build_flags = -g
|
||||
-DARDUINO_ARCH_ESP32
|
||||
-DCONFIG_LITTLEFS_FOR_IDF_3_2
|
||||
-DARDUINO_ARCH_ESP32S2
|
||||
-DCONFIG_IDF_TARGET_ESP32S2
|
||||
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
@ -294,6 +295,19 @@ build_unflags = ${common.build_unflags}
|
||||
build_flags = ${common.build_flags_esp32} -D WLED_RELEASE_NAME=ESP32_Ethernet -D RLYPIN=-1 -D WLED_USE_ETHERNET -D BTNPIN=-1
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
|
||||
[env:esp32s2_saola]
|
||||
board = esp32dev
|
||||
board_build.mcu = esp32s2
|
||||
platform = espressif32
|
||||
platform_packages =
|
||||
toolchain-xtensa32s2
|
||||
framework-arduinoespressif32 @ https://github.com/espressif/arduino-esp32.git#2.0.0-alpha1
|
||||
framework = arduino
|
||||
board_build.partitions = tools/WLED_ESP32_4MB_1MB_FS.csv
|
||||
upload_speed = 460800
|
||||
build_unflags = ${common.build_unflags}
|
||||
lib_deps = ${esp32s2.lib_deps}
|
||||
|
||||
[env:esp8285_4CH_MagicHome]
|
||||
board = esp8285
|
||||
platform = ${common.platform_wled_default}
|
||||
@ -378,15 +392,14 @@ build_flags = ${common.build_flags_esp32}
|
||||
-D LEDPIN=16
|
||||
-D RLYPIN=19
|
||||
-D BTNPIN=17
|
||||
-D IRPIN=18
|
||||
-D UWLED_USE_MY_CONFIG
|
||||
; -D USERMOD_DALLASTEMPERATURE
|
||||
; -D USERMOD_DALLASTEMPERATURE_CELCIUS
|
||||
; -D USERMOD_FOUR_LINE_DISPLAY
|
||||
; -D TEMPERATURE_PIN=21
|
||||
-D USERMOD_DALLASTEMPERATURE
|
||||
-D USERMOD_FOUR_LINE_DISPLAY
|
||||
-D TEMPERATURE_PIN=23
|
||||
lib_deps = ${esp32.lib_deps}
|
||||
; OneWire@~2.3.5
|
||||
; milesburton/DallasTemperature@^3.9.0
|
||||
; U8g2@~2.27.2
|
||||
OneWire@~2.3.5
|
||||
U8g2@~2.28.11
|
||||
|
||||
[env:m5atom]
|
||||
board = esp32dev
|
||||
@ -470,4 +483,3 @@ build_flags = ${common.build_flags_esp32} -D WLED_DISABLE_BROWNOUT_DET -D WLED_D
|
||||
-D USER_SETUP_LOADED
|
||||
monitor_filters = esp32_exception_decoder
|
||||
lib_deps = ${esp32.lib_deps} TFT_eSPI
|
||||
|
||||
|
@ -125,10 +125,8 @@
|
||||
#endif
|
||||
|
||||
//APA102
|
||||
#define B_HS_DOT_3 NeoPixelBrightnessBus<DotStarBgrFeature, DotStarSpiMethod> // hardware SPI
|
||||
#define B_SS_DOT_3 NeoPixelBrightnessBus<DotStarBgrFeature, DotStarMethod> // soft SPI
|
||||
#define B_HS_DOT_4 NeoPixelBrightnessBus<DotStarLbgrFeature,DotStarSpiMethod> // HW SPI, RGBW mode?
|
||||
#define B_SS_DOT_4 NeoPixelBrightnessBus<DotStarLbgrFeature,DotStarMethod> // soft SPI, RGBW mode?
|
||||
#define B_HS_DOT_3 NeoPixelBrightnessBus<DotStarBgrFeature, DotStarSpiMethod> //hardware SPI
|
||||
#define B_SS_DOT_3 NeoPixelBrightnessBus<DotStarBgrFeature, DotStarMethod> //soft SPI
|
||||
|
||||
//LPD8806
|
||||
#define B_HS_LPD_3 NeoPixelBrightnessBus<Lpd8806GrbFeature, Lpd8806SpiMethod>
|
||||
@ -666,7 +664,7 @@ class PolyBus {
|
||||
#ifndef CONFIG_IDF_TARGET_ESP32S2
|
||||
if (num > 9) return I_NONE;
|
||||
if (num > 7) offset = num -7;
|
||||
#else
|
||||
#else //ESP32 S2 only has 4 RMT channels
|
||||
if (num > 5) return I_NONE;
|
||||
if (num > 4) offset = num -4;
|
||||
#endif
|
||||
|
@ -23,7 +23,7 @@ var pJson = {}, eJson = {}, lJson = {};
|
||||
var pN = "", pI = 0, pNum = 0;
|
||||
var pmt = 1, pmtLS = 0, pmtLast = 0;
|
||||
var lastinfo = {};
|
||||
var ws, noWS = false;
|
||||
var ws;
|
||||
var cfg = {
|
||||
theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
|
||||
comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true, seglen:false}
|
||||
@ -239,7 +239,7 @@ function onLoad()
|
||||
loadFX(function() {
|
||||
loadPresets(function() {
|
||||
loadInfo(function() {
|
||||
requestJson({'v':true}, false, true);
|
||||
requestJson({'v':true}, false);
|
||||
});
|
||||
});
|
||||
});
|
||||
@ -253,6 +253,7 @@ function onLoad()
|
||||
if (localStorage.getItem('pcm') == "true") togglePcMode(true);
|
||||
var sls = d.querySelectorAll('input[type="range"]');
|
||||
for (var sl of sls) {
|
||||
//sl.addEventListener('input', updateBubble, true);
|
||||
sl.addEventListener('touchstart', toggleBubble);
|
||||
sl.addEventListener('touchend', toggleBubble);
|
||||
}
|
||||
@ -395,6 +396,20 @@ function presetError(empty)
|
||||
|
||||
function loadPresets(callback = null)
|
||||
{
|
||||
//1st boot (because there is a callback)
|
||||
if (callback && pmt == pmtLS && pmt > 0) {
|
||||
//we have a copy of the presets in local storage and don't need to fetch another one
|
||||
populatePresets(true);
|
||||
pmtLast = pmt;
|
||||
callback();
|
||||
return;
|
||||
}
|
||||
|
||||
//afterwards
|
||||
if (!callback && pmt == pmtLast) return;
|
||||
|
||||
pmtLast = pmt;
|
||||
|
||||
var url = (loc?`http://${locip}`:'') + '/presets.json';
|
||||
|
||||
fetch(url, {
|
||||
@ -415,7 +430,10 @@ function loadPresets(callback = null)
|
||||
showToast(error, true);
|
||||
console.log(error);
|
||||
presetError(false);
|
||||
if (callback) callback();
|
||||
//if (callback) callback();
|
||||
})
|
||||
.finally(() => {
|
||||
if (callback) setTimeout(callback,99);
|
||||
});
|
||||
}
|
||||
|
||||
@ -1056,11 +1074,13 @@ function makeWS() {
|
||||
if (ws) return;
|
||||
ws = new WebSocket('ws://'+(loc?locip:window.location.hostname)+'/ws');
|
||||
ws.onmessage = function(event) {
|
||||
var json = JSON.parse(event.data);
|
||||
if (json.leds) return; //liveview packet
|
||||
clearTimeout(jsonTimeout);
|
||||
jsonTimeout = null;
|
||||
clearErrorToast();
|
||||
gId('connind').style.backgroundColor = "#079";
|
||||
var json = JSON.parse(event.data);
|
||||
// json object should contain json.info AND json.state (but may not)
|
||||
var info = json.info;
|
||||
if (info) {
|
||||
lastinfo = info;
|
||||
@ -1164,7 +1184,7 @@ function readState(s,command=false)
|
||||
var jsonTimeout;
|
||||
var reqsLegal = false;
|
||||
|
||||
function requestJson(command, rinfo = true, verbose = true, callback = null)
|
||||
function requestJson(command, rinfo = true)
|
||||
{
|
||||
gId('connind').style.backgroundColor = "#a90";
|
||||
if (command && !reqsLegal) return; //stop post requests from chrome onchange event on page restore
|
||||
@ -1173,15 +1193,18 @@ function requestJson(command, rinfo = true, verbose = true, callback = null)
|
||||
var req = null;
|
||||
var url = (loc?`http://${locip}`:'') + (rinfo ? '/json/si': (command ? '/json/state':'/json/si'));
|
||||
|
||||
var useWs = ((command || rinfo) && ws && ws.readyState === WebSocket.OPEN);
|
||||
|
||||
var type = command ? 'post':'get';
|
||||
if (command)
|
||||
{
|
||||
command.v = verbose;
|
||||
command.v = true; // force complete /json/si API response
|
||||
command.time = Math.floor(Date.now() / 1000);
|
||||
req = JSON.stringify(command);
|
||||
if (req.length > 1000) useWs = false; //do not send very long requests over websocket
|
||||
}
|
||||
|
||||
if ((command || rinfo) && ws && ws.readyState === WebSocket.OPEN) {
|
||||
if (useWs) {
|
||||
ws.send(req?req:'{"v":true}');
|
||||
return;
|
||||
}
|
||||
@ -1203,20 +1226,15 @@ function requestJson(command, rinfo = true, verbose = true, callback = null)
|
||||
clearErrorToast();
|
||||
gId('connind').style.backgroundColor = "#070";
|
||||
if (!json) { showToast('Empty response', true); return; }
|
||||
if (json.success) {
|
||||
if (callback) callback();
|
||||
return;
|
||||
}
|
||||
if (json.success) return;
|
||||
var s = json.state ? json.state : json;
|
||||
readState(s);
|
||||
reqsLegal = true;
|
||||
reconnectWS();
|
||||
if (callback) callback();
|
||||
})
|
||||
.catch(function (error) {
|
||||
showToast(error, true);
|
||||
console.log(error);
|
||||
if (callback) callback();
|
||||
});
|
||||
}
|
||||
|
||||
@ -1225,7 +1243,7 @@ function togglePower()
|
||||
isOn = !isOn;
|
||||
var obj = {"on": isOn};
|
||||
obj.transition = parseInt(gId('tt').value*10);
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function toggleNl()
|
||||
@ -1258,6 +1276,7 @@ function toggleLiveview()
|
||||
var url = (loc?`http://${locip}`:'') + "/liveview";
|
||||
gId('liveview').src = (isLv) ? url:"about:blank";
|
||||
gId('buttonSr').className = (isLv) ? "active":"";
|
||||
if (!isLv && ws && ws.readyState === WebSocket.OPEN) ws.send('{"lv":false}');
|
||||
size();
|
||||
}
|
||||
|
||||
@ -1598,7 +1617,7 @@ function setX(ind = null)
|
||||
d.querySelector(`#fxlist .lstI[data-id="${ind}"]`).classList.add('selected');
|
||||
|
||||
var obj = {"seg": {"fx": parseInt(ind)}};
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function setPalette(paletteId = null)
|
||||
@ -1614,39 +1633,39 @@ function setPalette(paletteId = null)
|
||||
}
|
||||
d.querySelector(`#pallist .lstI[data-id="${paletteId}"]`).classList.add('selected');
|
||||
var obj = {"seg": {"pal": paletteId}};
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function setBri()
|
||||
{
|
||||
var obj = {"bri": parseInt(gId('sliderBri').value)};
|
||||
obj.transition = parseInt(gId('tt').value*10);
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function setSpeed()
|
||||
{
|
||||
var obj = {"seg": {"sx": parseInt(gId('sliderSpeed').value)}};
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function setIntensity()
|
||||
{
|
||||
var obj = {"seg": {"ix": parseInt(gId('sliderIntensity').value)}};
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function setLor(i)
|
||||
{
|
||||
var obj = {"lor": i};
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function setPreset(i)
|
||||
{
|
||||
var obj = {"ps": i};
|
||||
showToast("Loading preset " + pName(i) +" (" + i + ")");
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function saveP(i,pl)
|
||||
@ -1689,7 +1708,7 @@ function saveP(i,pl)
|
||||
if (pQN.length > 0) obj.ql = pQN;
|
||||
|
||||
showToast("Saving " + pN +" (" + pI + ")");
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
if (obj.o) {
|
||||
pJson[pI] = obj;
|
||||
delete pJson[pI].psave;
|
||||
@ -1716,18 +1735,18 @@ function testPl(i,bt) {
|
||||
bt.innerHTML = "<i class='icons btn-icon'></i>Stop";
|
||||
var obj = {};
|
||||
obj.playlist = plJson[i];
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function stopPl() {
|
||||
requestJson({playlist:{}}, false, noWS)
|
||||
requestJson({playlist:{}}, false)
|
||||
}
|
||||
|
||||
function delP(i) {
|
||||
var bt = gId(`p${i}del`);
|
||||
if (bt.dataset.cnf == 1) {
|
||||
var obj = {"pdel": i};
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
delete pJson[i];
|
||||
populatePresets();
|
||||
} else {
|
||||
@ -1837,7 +1856,7 @@ function setColor(sr)
|
||||
updateHex();
|
||||
updateRgb();
|
||||
obj.transition = parseInt(gId('tt').value*10);
|
||||
requestJson(obj, false, noWS);
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
var hc = 0;
|
||||
@ -1875,7 +1894,7 @@ function rSegs()
|
||||
requestJson(obj, false);
|
||||
}
|
||||
|
||||
function loadPalettesData()
|
||||
function loadPalettesData(callback = null)
|
||||
{
|
||||
if (palettesData) return;
|
||||
const lsKey = "wledPalx";
|
||||
@ -1885,6 +1904,8 @@ function loadPalettesData()
|
||||
palettesDataJson = JSON.parse(palettesDataJson);
|
||||
if (palettesDataJson && palettesDataJson.vid == lastinfo.vid) {
|
||||
palettesData = palettesDataJson.p;
|
||||
//redrawPalPrev() //?
|
||||
if (callback) callback();
|
||||
return;
|
||||
}
|
||||
} catch (e) {}
|
||||
@ -1897,6 +1918,7 @@ function loadPalettesData()
|
||||
vid: lastinfo.vid
|
||||
}));
|
||||
redrawPalPrev();
|
||||
if (callback) setTimeout(callback, 99); //go on to connect websocket
|
||||
});
|
||||
}
|
||||
|
||||
@ -1922,7 +1944,6 @@ function getPalettesData(page, callback)
|
||||
.catch(function(error) {
|
||||
showToast(error, true);
|
||||
console.log(error);
|
||||
presetError(false);
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -21,18 +21,6 @@
|
||||
<body>
|
||||
<div id="canv" />
|
||||
<script>
|
||||
console.info("Live-Preview websocket opening");
|
||||
var socket = new WebSocket("ws://"+document.location.host+"/ws");
|
||||
|
||||
socket.onopen = function () {
|
||||
console.info("Live-Preview websocket is opened");
|
||||
socket.send("{'lv':true,'rev':2}");
|
||||
}
|
||||
|
||||
socket.onclose = function () { console.info("Live-Preview websocket is closing"); }
|
||||
|
||||
socket.onerror = function (event) { console.error("Live-Preview websocket error:", event); }
|
||||
|
||||
function updatePreview(leds) {
|
||||
var str = "linear-gradient(90deg,";
|
||||
var len = leds.length;
|
||||
@ -46,7 +34,7 @@
|
||||
document.getElementById("canv").style.background = str;
|
||||
}
|
||||
|
||||
socket.onmessage = function (event) {
|
||||
function getLiveJson(event) {
|
||||
try {
|
||||
var json = JSON.parse(event.data);
|
||||
if (json && json.leds) {
|
||||
@ -54,9 +42,23 @@
|
||||
}
|
||||
}
|
||||
catch (err) {
|
||||
console.error("Live-Preview websocket error:",err);
|
||||
}
|
||||
console.error("Live-Preview ws error:",err);
|
||||
}
|
||||
}
|
||||
|
||||
var ws = top.window.ws;
|
||||
if (ws && ws.readyState === WebSocket.OPEN) {
|
||||
console.info("Use top WS for peek");
|
||||
ws.send("{'lv':true}");
|
||||
} else {
|
||||
console.info("Peek ws opening");
|
||||
ws = new WebSocket("ws://"+document.location.host+"/ws");
|
||||
ws.onopen = function () {
|
||||
console.info("Peek WS opened");
|
||||
ws.send("{'lv':true}");
|
||||
}
|
||||
}
|
||||
ws.addEventListener('message',getLiveJson);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
@ -85,7 +85,7 @@ charset="utf-8"><meta name="theme-color" content="#222222"><title>
|
||||
WLED Live Preview</title><style>
|
||||
body{margin:0}#canv{background:#000;filter:brightness(175%);width:100%;height:100%;position:absolute}
|
||||
</style></head><body><div id="canv"><script>
|
||||
console.info("Live-Preview websocket opening");var socket=new WebSocket("ws://"+document.location.host+"/ws");function updatePreview(e){var o="linear-gradient(90deg,",n=e.length;for(i=0;i<n;i++){var r=e[i];r.length>6&&(r=r.substring(2)),o+="#"+r,i<n-1&&(o+=",")}o+=")",document.getElementById("canv").style.background=o}socket.onopen=function(){console.info("Live-Preview websocket is opened"),socket.send("{'lv':true,'rev':2}")},socket.onclose=function(){console.info("Live-Preview websocket is closing")},socket.onerror=function(e){console.error("Live-Preview websocket error:",e)},socket.onmessage=function(e){try{var o=JSON.parse(e.data);o&&o.leds&&requestAnimationFrame((function(){updatePreview(o.leds)}))}catch(e){console.error("Live-Preview websocket error:",e)}}
|
||||
function updatePreview(e){var n="linear-gradient(90deg,",o=e.length;for(i=0;i<o;i++){var t=e[i];t.length>6&&(t=t.substring(2)),n+="#"+t,i<o-1&&(n+=",")}n+=")",document.getElementById("canv").style.background=n}function getLiveJson(e){try{var n=JSON.parse(e.data);n&&n.leds&&requestAnimationFrame((function(){updatePreview(n.leds)}))}catch(e){console.error("Live-Preview ws error:",e)}}var ws=top.window.ws;ws&&ws.readyState===WebSocket.OPEN?(console.info("Use top WS for peek"),ws.send("{'lv':true}")):(console.info("Peek ws opening"),(ws=new WebSocket("ws://"+document.location.host+"/ws")).onopen=function(){console.info("Peek WS opened"),ws.send("{'lv':true}")}),ws.addEventListener("message",getLiveJson)
|
||||
</script></body></html>)=====";
|
||||
|
||||
|
||||
|
4438
wled00/html_ui.h
4438
wled00/html_ui.h
File diff suppressed because it is too large
Load Diff
@ -8,7 +8,7 @@
|
||||
*/
|
||||
|
||||
// version code in format yymmddb (b = daily build)
|
||||
#define VERSION 2107072
|
||||
#define VERSION 2107080
|
||||
|
||||
//uncomment this if you have a "my_config.h" file you'd like to use
|
||||
//#define WLED_USE_MY_CONFIG
|
||||
|
@ -16,7 +16,6 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
if(type == WS_EVT_CONNECT){
|
||||
//client connected
|
||||
sendDataWs(client);
|
||||
//client->ping();
|
||||
} else if(type == WS_EVT_DISCONNECT){
|
||||
//client disconnected
|
||||
if (client->id() == wsLiveClientId) wsLiveClientId = 0;
|
||||
@ -24,7 +23,7 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
//data packet
|
||||
AwsFrameInfo * info = (AwsFrameInfo*)arg;
|
||||
if(info->final && info->index == 0 && info->len == len){
|
||||
//the whole message is in a single frame and we got all of it's data (max. 1450byte)
|
||||
//the whole message is in a single frame and we got all of its data (max. 1450byte)
|
||||
if(info->opcode == WS_TEXT)
|
||||
{
|
||||
bool verboseResponse = false;
|
||||
@ -42,10 +41,11 @@ void wsEvent(AsyncWebSocket * server, AsyncWebSocketClient * client, AwsEventTyp
|
||||
if (root.containsKey("lv"))
|
||||
{
|
||||
wsLiveClientId = root["lv"] ? client->id() : 0;
|
||||
} else {
|
||||
fileDoc = &jsonBuffer;
|
||||
verboseResponse = deserializeState(root);
|
||||
fileDoc = nullptr;
|
||||
}
|
||||
fileDoc = &jsonBuffer; // used for applying presets (presets.cpp)
|
||||
verboseResponse = deserializeState(root);
|
||||
fileDoc = nullptr;
|
||||
}
|
||||
//update if it takes longer than 300ms until next "broadcast"
|
||||
if (verboseResponse && (millis() - lastInterfaceUpdate < 1700 || !interfaceUpdateCallMode)) sendDataWs(client);
|
||||
|
Loading…
Reference in New Issue
Block a user