Added WebSockets support to UI
This commit is contained in:
parent
dc01c907f1
commit
40c8fdbf64
@ -2,6 +2,10 @@
|
|||||||
|
|
||||||
### Builds after release 0.12.0
|
### Builds after release 0.12.0
|
||||||
|
|
||||||
|
#### Build 2107021
|
||||||
|
|
||||||
|
- Added WebSockets support to UI
|
||||||
|
|
||||||
#### Build 2107020
|
#### Build 2107020
|
||||||
|
|
||||||
- Send websockets on every state change
|
- Send websockets on every state change
|
||||||
|
@ -970,12 +970,12 @@ input[type=number]::-webkit-outer-spin-button {
|
|||||||
z-index: 1;
|
z-index: 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#selectPalette .lstI.selected {
|
#pallist .lstI.selected {
|
||||||
top: 27px;
|
top: 27px;
|
||||||
bottom: -11px;
|
bottom: -11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#selectPalette .lstI.sticky {
|
#pallist .lstI.sticky {
|
||||||
top: -11px;
|
top: -11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -93,7 +93,7 @@
|
|||||||
Color palette
|
Color palette
|
||||||
</p>
|
</p>
|
||||||
<div class="il">
|
<div class="il">
|
||||||
<div id="selectPalette" class="list">
|
<div id="pallist" class="list">
|
||||||
<div class="lstI" data-id="0">
|
<div class="lstI" data-id="0">
|
||||||
<label class="check schkl">
|
<label class="check schkl">
|
||||||
|
|
||||||
|
@ -7,7 +7,7 @@ var selColors;
|
|||||||
var expanded = [false];
|
var expanded = [false];
|
||||||
var powered = [true];
|
var powered = [true];
|
||||||
var nlDur = 60, nlTar = 0;
|
var nlDur = 60, nlTar = 0;
|
||||||
var nlFade = false;
|
var nlMode = false;
|
||||||
var selectedFx = 0;
|
var selectedFx = 0;
|
||||||
var csel = 0;
|
var csel = 0;
|
||||||
var currentPreset = -1;
|
var currentPreset = -1;
|
||||||
@ -22,6 +22,8 @@ var pJson = {};
|
|||||||
var pN = "", pI = 0, pNum = 0;
|
var pN = "", pI = 0, pNum = 0;
|
||||||
var pmt = 1, pmtLS = 0, pmtLast = 0;
|
var pmt = 1, pmtLS = 0, pmtLast = 0;
|
||||||
var lastinfo = {};
|
var lastinfo = {};
|
||||||
|
var ws, useWs = false;
|
||||||
|
var fxlist = d.getElementById('fxlist'), pallist = d.getElementById('pallist');
|
||||||
var cfg = {
|
var cfg = {
|
||||||
theme:{base:"dark", bg:{url:""}, alpha:{bg:0.6,tab:0.8}, color:{bg:""}},
|
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}
|
comp :{colors:{picker: true, rgb: false, quick: true, hex: false}, labels:true, pcmbot:false, pid:true}
|
||||||
@ -619,7 +621,7 @@ function populateEffects(effects)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
d.getElementById('fxlist').innerHTML=html;
|
fxlist.innerHTML=html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function populatePalettes(palettes)
|
function populatePalettes(palettes)
|
||||||
@ -653,12 +655,12 @@ function populatePalettes(palettes)
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
d.getElementById('selectPalette').innerHTML=html;
|
pallist.innerHTML=html;
|
||||||
}
|
}
|
||||||
|
|
||||||
function redrawPalPrev()
|
function redrawPalPrev()
|
||||||
{
|
{
|
||||||
let palettes = d.querySelectorAll('#selectPalette .lstI');
|
let palettes = d.querySelectorAll('#pallist .lstI');
|
||||||
for (let i = 0; i < palettes.length; i++) {
|
for (let i = 0; i < palettes.length; i++) {
|
||||||
let id = palettes[i].dataset.id;
|
let id = palettes[i].dataset.id;
|
||||||
let lstPrev = palettes[i].querySelector('.lstIprev');
|
let lstPrev = palettes[i].querySelector('.lstIprev');
|
||||||
@ -909,6 +911,117 @@ function cmpP(a, b) {
|
|||||||
return a[1].n.localeCompare(b[1].n,undefined, {numeric: true});
|
return a[1].n.localeCompare(b[1].n,undefined, {numeric: true});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function makeWS() {
|
||||||
|
if (ws) return;
|
||||||
|
ws = new WebSocket('ws://'+(loc?locip:window.location.hostname)+'/ws');
|
||||||
|
ws.onmessage = function(event) {
|
||||||
|
clearTimeout(jsonTimeout);
|
||||||
|
jsonTimeout = null;
|
||||||
|
clearErrorToast();
|
||||||
|
d.getElementById('connind').style.backgroundColor = "#079";
|
||||||
|
var json = JSON.parse(event.data);
|
||||||
|
var info = json.info;
|
||||||
|
d.getElementById('buttonNodes').style.display = (info.ndc > 0 && window.innerWidth > 770) ? "block":"none";
|
||||||
|
lastinfo = info;
|
||||||
|
if (isInfo) {
|
||||||
|
populateInfo(info);
|
||||||
|
}
|
||||||
|
s = json.state;
|
||||||
|
displayRover(info, s);
|
||||||
|
readState(json.state);
|
||||||
|
};
|
||||||
|
ws.onclose = function(event) {
|
||||||
|
d.getElementById('connind').style.backgroundColor = "#831";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function readState(s,command=false) {
|
||||||
|
isOn = s.on;
|
||||||
|
d.getElementById('sliderBri').value= s.bri;
|
||||||
|
nlA = s.nl.on;
|
||||||
|
nlDur = s.nl.dur;
|
||||||
|
nlTar = s.nl.tbri;
|
||||||
|
nlMode = s.nl.mode;
|
||||||
|
syncSend = s.udpn.send;
|
||||||
|
currentPreset = s.ps;
|
||||||
|
tr = s.transition;
|
||||||
|
d.getElementById('tt').value = tr/10;
|
||||||
|
|
||||||
|
var selc=0; var ind=0;
|
||||||
|
populateSegments(s);
|
||||||
|
for (let i = 0; i < (s.seg||[]).length; i++)
|
||||||
|
{
|
||||||
|
if(s.seg[i].sel) {selc = ind; break;} ind++;
|
||||||
|
}
|
||||||
|
var i=s.seg[selc];
|
||||||
|
if (!i) {
|
||||||
|
showToast('No Segments!', true);
|
||||||
|
updateUI();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
selColors = i.col;
|
||||||
|
var cd = d.getElementById('csl').children;
|
||||||
|
for (let e = 2; e >= 0; e--)
|
||||||
|
{
|
||||||
|
cd[e].style.backgroundColor = "rgb(" + i.col[e][0] + "," + i.col[e][1] + "," + i.col[e][2] + ")";
|
||||||
|
if (isRgbw) whites[e] = parseInt(i.col[e][3]);
|
||||||
|
selectSlot(csel);
|
||||||
|
}
|
||||||
|
d.getElementById('sliderSpeed').value = whites[csel];
|
||||||
|
|
||||||
|
d.getElementById('sliderSpeed').value = i.sx;
|
||||||
|
d.getElementById('sliderIntensity').value = i.ix;
|
||||||
|
|
||||||
|
// Effects
|
||||||
|
var selFx = fxlist.querySelector(`input[name="fx"][value="${i.fx}"]`);
|
||||||
|
if (selFx) selFx.checked = true;
|
||||||
|
else location.reload(); //effect list is gone (e.g. if restoring tab). Reload.
|
||||||
|
|
||||||
|
var selElement = fxlist.querySelector('.selected');
|
||||||
|
if (selElement) {
|
||||||
|
selElement.classList.remove('selected')
|
||||||
|
}
|
||||||
|
var selectedEffect = fxlist.querySelector(`.lstI[data-id="${i.fx}"]`);
|
||||||
|
selectedEffect.classList.add('selected');
|
||||||
|
selectedFx = i.fx;
|
||||||
|
|
||||||
|
// Palettes
|
||||||
|
pallist.querySelector(`input[name="palette"][value="${i.pal}"]`).checked = true;
|
||||||
|
selElement = pallist.querySelector('.selected');
|
||||||
|
if (selElement) {
|
||||||
|
selElement.classList.remove('selected')
|
||||||
|
}
|
||||||
|
pallist.querySelector(`.lstI[data-id="${i.pal}"]`).classList.add('selected');
|
||||||
|
|
||||||
|
if (!command) {
|
||||||
|
selectedEffect.scrollIntoView({
|
||||||
|
behavior: 'smooth',
|
||||||
|
block: 'nearest',
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
if (s.error && s.error != 0) {
|
||||||
|
var errstr = "";
|
||||||
|
switch (s.error) {
|
||||||
|
case 10:
|
||||||
|
errstr = "Could not mount filesystem!";
|
||||||
|
break;
|
||||||
|
case 11:
|
||||||
|
errstr = "Not enough space to save preset!";
|
||||||
|
break;
|
||||||
|
case 12:
|
||||||
|
errstr = "Preset not found.";
|
||||||
|
break;
|
||||||
|
case 19:
|
||||||
|
errstr = "A filesystem error has occured.";
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
showToast('Error ' + s.error + ": " + errstr, true);
|
||||||
|
}
|
||||||
|
updateUI();
|
||||||
|
}
|
||||||
|
|
||||||
var jsonTimeout;
|
var jsonTimeout;
|
||||||
var reqsLegal = false;
|
var reqsLegal = false;
|
||||||
|
|
||||||
@ -918,8 +1031,6 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
lastUpdate = new Date();
|
lastUpdate = new Date();
|
||||||
if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000);
|
if (!jsonTimeout) jsonTimeout = setTimeout(showErrorToast, 3000);
|
||||||
var req = null;
|
var req = null;
|
||||||
var e1 = d.getElementById('fxlist');
|
|
||||||
var e2 = d.getElementById('selectPalette');
|
|
||||||
|
|
||||||
var url = rinfo ? '/json/si': (command ? '/json/state':'/json');
|
var url = rinfo ? '/json/si': (command ? '/json/state':'/json');
|
||||||
if (loc) {
|
if (loc) {
|
||||||
@ -932,8 +1043,13 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
command.v = verbose;
|
command.v = verbose;
|
||||||
command.time = Math.floor(Date.now() / 1000);
|
command.time = Math.floor(Date.now() / 1000);
|
||||||
req = JSON.stringify(command);
|
req = JSON.stringify(command);
|
||||||
//console.log(req);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((command || rinfo) && ws && ws.readyState === WebSocket.OPEN) {
|
||||||
|
ws.send(req?req:'{"v":true}');
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
fetch
|
fetch
|
||||||
(url, {
|
(url, {
|
||||||
method: type,
|
method: type,
|
||||||
@ -961,8 +1077,8 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
}
|
}
|
||||||
var s = json;
|
var s = json;
|
||||||
|
|
||||||
if (!command || rinfo) {
|
if (!command || rinfo) { //we have info object
|
||||||
if (!rinfo) {
|
if (!rinfo) { //entire JSON (on load)
|
||||||
pmt = json.info.fs.pmt;
|
pmt = json.info.fs.pmt;
|
||||||
if (pmt != pmtLS || pmt == 0) {
|
if (pmt != pmtLS || pmt == 0) {
|
||||||
setTimeout(loadPresets,99);
|
setTimeout(loadPresets,99);
|
||||||
@ -995,6 +1111,7 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
syncTglRecv = info.str;
|
syncTglRecv = info.str;
|
||||||
maxSeg = info.leds.maxseg;
|
maxSeg = info.leds.maxseg;
|
||||||
pmt = info.fs.pmt;
|
pmt = info.fs.pmt;
|
||||||
|
if (!ws && info.ws > -1) setTimeout(makeWS,1000);
|
||||||
|
|
||||||
if (!command && pmt != pmtLast) {
|
if (!command && pmt != pmtLast) {
|
||||||
setTimeout(loadPresets,99);
|
setTimeout(loadPresets,99);
|
||||||
@ -1011,90 +1128,7 @@ function requestJson(command, rinfo = true, verbose = true) {
|
|||||||
if (!rinfo) loadPalettesData();
|
if (!rinfo) loadPalettesData();
|
||||||
}
|
}
|
||||||
|
|
||||||
isOn = s.on;
|
readState(s,command);
|
||||||
d.getElementById('sliderBri').value= s.bri;
|
|
||||||
nlA = s.nl.on;
|
|
||||||
nlDur = s.nl.dur;
|
|
||||||
nlTar = s.nl.tbri;
|
|
||||||
nlFade = s.nl.fade;
|
|
||||||
syncSend = s.udpn.send;
|
|
||||||
currentPreset = s.ps;
|
|
||||||
tr = s.transition;
|
|
||||||
d.getElementById('tt').value = tr/10;
|
|
||||||
|
|
||||||
var selc=0; var ind=0;
|
|
||||||
populateSegments(s);
|
|
||||||
for (let i = 0; i < (s.seg||[]).length; i++)
|
|
||||||
{
|
|
||||||
if(s.seg[i].sel) {selc = ind; break;} ind++;
|
|
||||||
}
|
|
||||||
var i=s.seg[selc];
|
|
||||||
if (!i) {
|
|
||||||
showToast('No Segments!', true);
|
|
||||||
updateUI();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
selColors = i.col;
|
|
||||||
var cd = d.getElementById('csl').children;
|
|
||||||
for (let e = 2; e >= 0; e--)
|
|
||||||
{
|
|
||||||
cd[e].style.backgroundColor = "rgb(" + i.col[e][0] + "," + i.col[e][1] + "," + i.col[e][2] + ")";
|
|
||||||
if (isRgbw) whites[e] = parseInt(i.col[e][3]);
|
|
||||||
selectSlot(csel);
|
|
||||||
}
|
|
||||||
d.getElementById('sliderSpeed').value = whites[csel];
|
|
||||||
|
|
||||||
d.getElementById('sliderSpeed').value = i.sx;
|
|
||||||
d.getElementById('sliderIntensity').value = i.ix;
|
|
||||||
|
|
||||||
// Effects
|
|
||||||
var selFx = e1.querySelector(`input[name="fx"][value="${i.fx}"]`);
|
|
||||||
if (selFx) selFx.checked = true;
|
|
||||||
else location.reload(); //effect list is gone (e.g. if restoring tab). Reload.
|
|
||||||
|
|
||||||
var selElement = e1.querySelector('.selected');
|
|
||||||
if (selElement) {
|
|
||||||
selElement.classList.remove('selected')
|
|
||||||
}
|
|
||||||
var selectedEffect = e1.querySelector(`.lstI[data-id="${i.fx}"]`);
|
|
||||||
selectedEffect.classList.add('selected');
|
|
||||||
selectedFx = i.fx;
|
|
||||||
|
|
||||||
// Palettes
|
|
||||||
e2.querySelector(`input[name="palette"][value="${i.pal}"]`).checked = true;
|
|
||||||
selElement = e2.querySelector('.selected');
|
|
||||||
if (selElement) {
|
|
||||||
selElement.classList.remove('selected')
|
|
||||||
}
|
|
||||||
e2.querySelector(`.lstI[data-id="${i.pal}"]`).classList.add('selected');
|
|
||||||
|
|
||||||
if (!command) {
|
|
||||||
selectedEffect.scrollIntoView({
|
|
||||||
behavior: 'smooth',
|
|
||||||
block: 'nearest',
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
if (s.error && s.error != 0) {
|
|
||||||
var errstr = "";
|
|
||||||
switch (s.error) {
|
|
||||||
case 10:
|
|
||||||
errstr = "Could not mount filesystem!";
|
|
||||||
break;
|
|
||||||
case 11:
|
|
||||||
errstr = "Not enough space to save preset!";
|
|
||||||
break;
|
|
||||||
case 12:
|
|
||||||
errstr = "Preset not found.";
|
|
||||||
break;
|
|
||||||
case 19:
|
|
||||||
errstr = "A filesystem error has occured.";
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
showToast('Error ' + s.error + ": " + errstr, true);
|
|
||||||
}
|
|
||||||
updateUI();
|
|
||||||
})
|
})
|
||||||
.catch(function (error) {
|
.catch(function (error) {
|
||||||
showToast(error, true);
|
showToast(error, true);
|
||||||
@ -1113,7 +1147,7 @@ function toggleNl() {
|
|||||||
nlA = !nlA;
|
nlA = !nlA;
|
||||||
if (nlA)
|
if (nlA)
|
||||||
{
|
{
|
||||||
showToast(`Timer active. Your light will turn ${nlTar > 0 ? "on":"off"} ${nlFade ? "over":"after"} ${nlDur} minutes.`);
|
showToast(`Timer active. Your light will turn ${nlTar > 0 ? "on":"off"} ${nlMode ? "over":"after"} ${nlDur} minutes.`);
|
||||||
} else {
|
} else {
|
||||||
showToast('Timer deactivated.');
|
showToast('Timer deactivated.');
|
||||||
}
|
}
|
||||||
@ -1483,15 +1517,15 @@ function setX(ind = null) {
|
|||||||
function setPalette(paletteId = null)
|
function setPalette(paletteId = null)
|
||||||
{
|
{
|
||||||
if (paletteId === null) {
|
if (paletteId === null) {
|
||||||
paletteId = parseInt(d.querySelector('#selectPalette input[name="palette"]:checked').value);
|
paletteId = parseInt(d.querySelector('#pallist input[name="palette"]:checked').value);
|
||||||
} else {
|
} else {
|
||||||
d.querySelector(`#selectPalette input[name="palette"][value="${paletteId}`).checked = true;
|
d.querySelector(`#pallist input[name="palette"][value="${paletteId}`).checked = true;
|
||||||
}
|
}
|
||||||
var selElement = d.querySelector('#selectPalette .selected');
|
var selElement = d.querySelector('#pallist .selected');
|
||||||
if (selElement) {
|
if (selElement) {
|
||||||
selElement.classList.remove('selected')
|
selElement.classList.remove('selected')
|
||||||
}
|
}
|
||||||
d.querySelector(`#selectPalette .lstI[data-id="${paletteId}"]`).classList.add('selected');
|
d.querySelector(`#pallist .lstI[data-id="${paletteId}"]`).classList.add('selected');
|
||||||
var obj = {"seg": {"pal": paletteId}};
|
var obj = {"seg": {"pal": paletteId}};
|
||||||
requestJson(obj);
|
requestJson(obj);
|
||||||
}
|
}
|
||||||
|
4339
wled00/html_ui.h
4339
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)
|
// version code in format yymmddb (b = daily build)
|
||||||
#define VERSION 2107020
|
#define VERSION 2107021
|
||||||
|
|
||||||
//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
|
||||||
|
Loading…
Reference in New Issue
Block a user