1
0
mirror of https://github.com/s00500/ESPUI.git synced 2024-11-22 14:20:53 +00:00
This commit is contained in:
Nikola Kirov 2023-12-13 09:27:21 +02:00
parent ab46429b3c
commit fe75655ecc
11 changed files with 295 additions and 447 deletions

View File

@ -62,9 +62,6 @@ The Library runs on any kind of **ESP8266** and **ESP32** (NodeMCU, AI Thinker,
- Time control by @iangray001 - Time control by @iangray001
- Vertical controls by @iangray001 - Vertical controls by @iangray001
- Time/date/password/color input types by @pcbbc - Time/date/password/color input types by @pcbbc
- Delayed response support @MartinMueller2003
- Fragmented control transfer @ MartinMueller2003
- Extended Callback @MartinMueller2003
## Roadmap ## Roadmap
@ -156,9 +153,7 @@ This section will explain in detail how the Library is to be used from the Ardui
<br><br> <br><br>
Alternativly you may use the extended callback funtion which provides three parameters to the callback function `myCallback(Control *sender, int eventname, void * UserParameter)`. The `UserParameter` is provided as part of the `ESPUI.addControl` method set and allows the user to define contextual information that is to be presented to the callback function in an unmodified form. Alternativly you may use the extended callback funtion which provides three parameters to the callback function `myCallback(Control *sender, int eventname, void * UserParameter)`. The `UserParameter` is provided as part of the `ESPUI.addControl` method set and allows the user to define contextual information that is to be presented to the callback function in an unmodified form.
<br><br> <br><br>
It also possible to use a lambda function in the callback parameter. It also allows the user to define, in a more C++ way, contextual information in any form. This is shown by the [completeLambda](examples/completeLambda/completeLambda.ino) example. The below example creates a button and defines a lambda function to implicitly create an `ExtendedCallback` which then invokes a more specialized button callback handler. The example uses the `UserParameter` to hold the `this` pointer to an object instance, providing a mechanism for sending the event to a specific object without the need for a switch / map / lookup translation of the Sender Id to an object reference.
<br><br>
The below example creates a button and defines a lambda function to invoke a more specialized button callback handler:
``` ```
void YourClassName::setup() void YourClassName::setup()
{ {
@ -168,18 +163,26 @@ void YourClassName::setup()
" Button Face Text ", " Button Face Text ",
ControlColor::None, ControlColor::None,
ParentElementId, ParentElementId,
[&](Control *sender, int eventname) [](Control *sender, int eventname, void* param)
{ {
myButtonCallback(sender, eventname); // class method if(param)
}); {
reinterpret_cast<YourClassName*>(param)->myButtonCallback(sender, eventname);
}
},
this); // <-Third parameter for the extended callback
// or // or
ButtonElementId = ESPUI.button( ButtonElementId = ESPUI.button(
" Button Face Text ", " Button Face Text ",
[&](Control *sender, int eventname) [](Control *sender, int eventname, void* param)
{ {
myButtonCallback(sender, eventname); // class method if(param)
}); {
reinterpret_cast<YourClassName*>(param)->myButtonCallback(sender, eventname);
}
},
this); // <-Third parameter for the extended callback
} }
``` ```
``` ```

170
data/js/controls.js vendored
View File

@ -60,8 +60,6 @@ const UPDATE_SEPARATOR = 119;
const UI_TIME = 20; const UI_TIME = 20;
const UPDATE_TIME = 120; const UPDATE_TIME = 120;
const UI_FRAGMENT = 21;
const UP = 0; const UP = 0;
const DOWN = 1; const DOWN = 1;
const LEFT = 2; const LEFT = 2;
@ -79,8 +77,6 @@ const C_ALIZARIN = 6;
const C_DARK = 7; const C_DARK = 7;
const C_NONE = 255; const C_NONE = 255;
var controlAssemblyArray = new Object();
var FragmentAssemblyTimer = new Object();
var graphData = new Array(); var graphData = new Array();
var hasAccel = false; var hasAccel = false;
var sliderContinuous = false; var sliderContinuous = false;
@ -194,12 +190,6 @@ function restart() {
} }
function conStatusError() { function conStatusError() {
FragmentAssemblyTimer.forEach(element => {
clearInterval(element);
});
FragmentAssemblyTimer = new Object();
controlAssemblyArray = new Object();
if (true === websockConnected) { if (true === websockConnected) {
websockConnected = false; websockConnected = false;
websock.close(); websock.close();
@ -220,20 +210,17 @@ function handleVisibilityChange() {
} }
function start() { function start() {
let location = window.location.hostname;
let port = window.location.port;
// let location = "192.168.10.229";
// let port = "";
document.addEventListener("visibilitychange", handleVisibilityChange, false); document.addEventListener("visibilitychange", handleVisibilityChange, false);
if ( if (
port != "" || window.location.port != "" ||
port != 80 || window.location.port != 80 ||
port != 443 window.location.port != 443
) { ) {
websock = new WebSocket( "ws://" + location + "/ws" ); websock = new WebSocket(
"ws://" + window.location.hostname + ":" + window.location.port + "/ws"
);
} else { } else {
websock = new WebSocket("ws://" + location + "/ws"); websock = new WebSocket("ws://" + window.location.hostname + "/ws");
} }
// is the timer running? // is the timer running?
@ -254,54 +241,33 @@ function start() {
$("#conStatus").addClass("color-green"); $("#conStatus").addClass("color-green");
$("#conStatus").text("Connected"); $("#conStatus").text("Connected");
websockConnected = true; websockConnected = true;
FragmentAssemblyTimer.forEach(element => {
clearInterval(element);
});
FragmentAssemblyTimer = new Object();
controlAssemblyArray = new Object();
}; };
websock.onclose = function (evt) { websock.onclose = function (evt) {
// console.log("Close evt: '" + evt + "'");
// console.log("Close reason: '" + evt.reason + "'");
// console.log("Close code: '" + evt.code + "'");
console.log("websock close"); console.log("websock close");
conStatusError(); conStatusError();
FragmentAssemblyTimer.forEach(element => {
clearInterval(element);
});
FragmentAssemblyTimer = new Object();
controlAssemblyArray = new Object();
}; };
websock.onerror = function (evt) { websock.onerror = function (evt) {
console.log("websock Error"); console.log("websock Error");
// console.log("Error evt: '" + evt + "'"); console.log(evt);
// console.log("Error data: '" + evt.data + "'");
restart(); restart();
FragmentAssemblyTimer.forEach(element => {
clearInterval(element);
});
FragmentAssemblyTimer = new Object();
controlAssemblyArray = new Object();
}; };
var handleEvent = function (evt) { var handleEvent = function (evt) {
// console.log("handleEvent:Data evt: '" + evt + "'"); console.log(evt);
// console.log("handleEvent:Data data: '" + evt.data + "'");
try { try {
var data = JSON.parse(evt.data); var data = JSON.parse(evt.data);
} }
catch (Event) { catch (Event) {
console.error(Event); console.error(Event);
// console.info("start the update over again"); // start the update over again
websock.send("uiok:" + 0); websock.send("uiok:" + 0);
return; return;
} }
var e = document.body; var e = document.body;
var center = ""; var center = "";
// console.info("data.type: '" + data.type + "'");
switch (data.type) { switch (data.type) {
case UI_INITIAL_GUI: case UI_INITIAL_GUI:
@ -313,9 +279,7 @@ function start() {
if (data.sliderContinuous) { if (data.sliderContinuous) {
sliderContinuous = data.sliderContinuous; sliderContinuous = data.sliderContinuous;
} }
// console.info("UI_INITIAL_GUI:data record: '" + data + "'");
data.controls.forEach(element => { data.controls.forEach(element => {
// console.info("element: '" + JSON.stringify(element) + "'");
var fauxEvent = { var fauxEvent = {
data: JSON.stringify(element), data: JSON.stringify(element),
}; };
@ -331,9 +295,7 @@ function start() {
break; break;
case UI_EXTEND_GUI: case UI_EXTEND_GUI:
// console.info("UI_EXTEND_GUI data record: '" + data + "'");
data.controls.forEach(element => { data.controls.forEach(element => {
// console.info("UI_EXTEND_GUI:element: '" + JSON.stringify(element) + "'");
var fauxEvent = { var fauxEvent = {
data: JSON.stringify(element), data: JSON.stringify(element),
}; };
@ -639,88 +601,6 @@ function start() {
websock.send("time:" + rv + ":" + data.id); websock.send("time:" + rv + ":" + data.id);
break; break;
case UI_FRAGMENT:
let FragmentLen = data.length;
let FragementOffset = data.offset;
let NextFragmentOffset = FragementOffset + FragmentLen;
let Total = data.total;
let Arrived = (FragmentLen + FragementOffset);
let FragmentFinal = Total === Arrived;
// console.info("UI_FRAGMENT:FragmentLen '" + FragmentLen + "'");
// console.info("UI_FRAGMENT:FragementOffset '" + FragementOffset + "'");
// console.info("UI_FRAGMENT:NextFragmentOffset '" + NextFragmentOffset + "'");
// console.info("UI_FRAGMENT:Total '" + Total + "'");
// console.info("UI_FRAGMENT:Arrived '" + Arrived + "'");
// console.info("UI_FRAGMENT:FragmentFinal '" + FragmentFinal + "'");
if (!data.hasOwnProperty('control'))
{
console.error("UI_FRAGMENT:Missing control record, skipping control");
break;
}
let control = data.control;
StopFragmentAssemblyTimer(data.control.id);
// is this the first fragment?
if(0 === FragementOffset)
{
// console.info("Found first fragment");
controlAssemblyArray[control.id] = data;
// console.info("Value: " + controlAssemblyArray[control.id].control.value);
controlAssemblyArray[control.id].offset = NextFragmentOffset;
StartFragmentAssemblyTimer(control.id);
let TotalRequest = JSON.stringify({ 'id' : control.id, 'offset' : NextFragmentOffset });
websock.send("uifragmentok:" + 0 + ": " + TotalRequest + ":");
// console.info("asked for fragment 2");
break;
}
// not first fragment. are we assembling this control?
if("undefined" === typeof controlAssemblyArray[control.id])
{
// it looks like we missed the first fragment. Start the control over
console.error("Missing first fragment for control: " + control.id);
StartFragmentAssemblyTimer(control.id);
let TotalRequest = JSON.stringify({ 'id' : control.id, 'offset' : 0 });
websock.send("uifragmentok:" + 0 + ": " + TotalRequest + ":");
// console.info("asked for fragment 1");
break;
}
// is this the expected next fragment
if(FragementOffset !== controlAssemblyArray[control.id].offset)
{
console.error("Wrong next fragment. Expected: " + controlAssemblyArray[control.id].offset + " Got: " + FragementOffset);
StartFragmentAssemblyTimer(control.id);
let TotalRequest = JSON.stringify({ 'id' : control.id, 'offset' : controlAssemblyArray[control.id].length + controlAssemblyArray[control.id].offset });
websock.send("uifragmentok:" + 0 + ": " + TotalRequest + ":");
// console.info("asked for the expected fragment");
break;
}
// console.info("Add to existing fragment");
controlAssemblyArray[control.id].control.value += control.value;
controlAssemblyArray[control.id].offset = NextFragmentOffset;
// console.info("Value: " + controlAssemblyArray[control.id].control.value);
if(true === FragmentFinal)
{
var fauxEvent = {
data: JSON.stringify(controlAssemblyArray[control.id].control),
};
handleEvent(fauxEvent);
controlAssemblyArray[control.id] = null;
// console.info("Found last fragment");
}
else
{
// console.info("Ask for next fragment.");
StartFragmentAssemblyTimer(control.id);
let TotalRequest = JSON.stringify({ 'id' : control.id, 'offset' : NextFragmentOffset});
websock.send("uifragmentok:" + 0 + ": " + TotalRequest + ":");
}
break;
default: default:
console.error("Unknown type or event"); console.error("Unknown type or event");
break; break;
@ -770,36 +650,6 @@ function start() {
websock.onmessage = handleEvent; websock.onmessage = handleEvent;
} }
function StartFragmentAssemblyTimer(Id)
{
StopFragmentAssemblyTimer(Id);
FragmentAssemblyTimer[Id] = setInterval(function(_Id)
{
// does the fragment assembly still exist?
if("undefined" !== typeof controlAssemblyArray[_Id])
{
if(null !== controlAssemblyArray[_Id])
{
// we have a valid control that is being assembled
// ask for the next part
let TotalRequest = JSON.stringify({ 'id' : controlAssemblyArray[_Id].control.id, 'offset' : controlAssemblyArray[_Id].offset});
websock.send("uifragmentok:" + 0 + ": " + TotalRequest + ":");
}
}
}, 1000, Id);
}
function StopFragmentAssemblyTimer(Id)
{
if("undefined" !== typeof FragmentAssemblyTimer[Id])
{
if(FragmentAssemblyTimer[Id])
{
clearInterval(FragmentAssemblyTimer[Id]);
}
}
}
function sliderchange(number) { function sliderchange(number) {
var val = $("#sl" + number).val(); var val = $("#sl" + number).val();
websock.send("slvalue:" + val + ":" + number); websock.send("slvalue:" + val + ":" + number);

View File

@ -1,14 +1,14 @@
const UI_INITIAL_GUI=200;const UI_RELOAD=201;const UPDATE_OFFSET=100;const UI_EXTEND_GUI=210;const UI_TITEL=0;const UI_PAD=1;const UPDATE_PAD=101;const UI_CPAD=2;const UPDATE_CPAD=102;const UI_BUTTON=3;const UPDATE_BUTTON=103;const UI_LABEL=4;const UPDATE_LABEL=104;const UI_SWITCHER=5;const UPDATE_SWITCHER=105;const UI_SLIDER=6;const UPDATE_SLIDER=106;const UI_NUMBER=7;const UPDATE_NUMBER=107;const UI_TEXT_INPUT=8;const UPDATE_TEXT_INPUT=108;const UI_GRAPH=9;const ADD_GRAPH_POINT=10;const CLEAR_GRAPH=109;const UI_TAB=11;const UPDATE_TAB=111;const UI_SELECT=12;const UPDATE_SELECT=112;const UI_OPTION=13;const UPDATE_OPTION=113;const UI_MIN=14;const UPDATE_MIN=114;const UI_MAX=15;const UPDATE_MAX=115;const UI_STEP=16;const UPDATE_STEP=116;const UI_GAUGE=17;const UPDATE_GAUGE=117;const UI_ACCEL=18;const UPDATE_ACCEL=118;const UI_SEPARATOR=19;const UPDATE_SEPARATOR=119;const UI_TIME=20;const UPDATE_TIME=120;const UI_FRAGMENT=21;const UP=0;const DOWN=1;const LEFT=2;const RIGHT=3;const CENTER=4;const C_TURQUOISE=0;const C_EMERALD=1;const C_PETERRIVER=2;const C_WETASPHALT=3;const C_SUNFLOWER=4;const C_CARROT=5;const C_ALIZARIN=6;const C_DARK=7;const C_NONE=255;var controlAssemblyArray=new Object();var FragmentAssemblyTimer=new Object();var graphData=new Array();var hasAccel=false;var sliderContinuous=false;function colorClass(colorId){colorId=Number(colorId);switch(colorId){case C_TURQUOISE:return"turquoise";case C_EMERALD:return"emerald";case C_PETERRIVER:return"peterriver";case C_WETASPHALT:return"wetasphalt";case C_SUNFLOWER:return"sunflower";case C_CARROT:return"carrot";case C_ALIZARIN:return"alizarin";case C_DARK:case C_NONE:return"dark";default:return"";}} const UI_INITIAL_GUI=200;const UI_RELOAD=201;const UPDATE_OFFSET=100;const UI_EXTEND_GUI=210;const UI_TITEL=0;const UI_PAD=1;const UPDATE_PAD=101;const UI_CPAD=2;const UPDATE_CPAD=102;const UI_BUTTON=3;const UPDATE_BUTTON=103;const UI_LABEL=4;const UPDATE_LABEL=104;const UI_SWITCHER=5;const UPDATE_SWITCHER=105;const UI_SLIDER=6;const UPDATE_SLIDER=106;const UI_NUMBER=7;const UPDATE_NUMBER=107;const UI_TEXT_INPUT=8;const UPDATE_TEXT_INPUT=108;const UI_GRAPH=9;const ADD_GRAPH_POINT=10;const CLEAR_GRAPH=109;const UI_TAB=11;const UPDATE_TAB=111;const UI_SELECT=12;const UPDATE_SELECT=112;const UI_OPTION=13;const UPDATE_OPTION=113;const UI_MIN=14;const UPDATE_MIN=114;const UI_MAX=15;const UPDATE_MAX=115;const UI_STEP=16;const UPDATE_STEP=116;const UI_GAUGE=17;const UPDATE_GAUGE=117;const UI_ACCEL=18;const UPDATE_ACCEL=118;const UI_SEPARATOR=19;const UPDATE_SEPARATOR=119;const UI_TIME=20;const UPDATE_TIME=120;const UP=0;const DOWN=1;const LEFT=2;const RIGHT=3;const CENTER=4;const C_TURQUOISE=0;const C_EMERALD=1;const C_PETERRIVER=2;const C_WETASPHALT=3;const C_SUNFLOWER=4;const C_CARROT=5;const C_ALIZARIN=6;const C_DARK=7;const C_NONE=255;var graphData=new Array();var hasAccel=false;var sliderContinuous=false;function colorClass(colorId){colorId=Number(colorId);switch(colorId){case C_TURQUOISE:return"turquoise";case C_EMERALD:return"emerald";case C_PETERRIVER:return"peterriver";case C_WETASPHALT:return"wetasphalt";case C_SUNFLOWER:return"sunflower";case C_CARROT:return"carrot";case C_ALIZARIN:return"alizarin";case C_DARK:case C_NONE:return"dark";default:return"";}}
var websock;var websockConnected=false;var WebSocketTimer=null;function requestOrientationPermission(){} var websock;var websockConnected=false;var WebSocketTimer=null;function requestOrientationPermission(){}
function saveGraphData(){localStorage.setItem("espuigraphs",JSON.stringify(graphData));} function saveGraphData(){localStorage.setItem("espuigraphs",JSON.stringify(graphData));}
function restoreGraphData(id){var savedData=localStorage.getItem("espuigraphs",graphData);if(savedData!=null){savedData=JSON.parse(savedData);let idData=savedData[id];return Array.isArray(idData)?idData:[];} function restoreGraphData(id){var savedData=localStorage.getItem("espuigraphs",graphData);if(savedData!=null){savedData=JSON.parse(savedData);let idData=savedData[id];return Array.isArray(idData)?idData:[];}
return[];} return[];}
function restart(){$(document).add("*").off();$("#row").html("");conStatusError();start();} function restart(){$(document).add("*").off();$("#row").html("");conStatusError();start();}
function conStatusError(){FragmentAssemblyTimer.forEach(element=>{clearInterval(element);});FragmentAssemblyTimer=new Object();controlAssemblyArray=new Object();if(true===websockConnected){websockConnected=false;websock.close();$("#conStatus").removeClass("color-green");$("#conStatus").addClass("color-red");$("#conStatus").html("Error / No Connection &#8635;");$("#conStatus").off();$("#conStatus").on({click:restart,});}} function conStatusError(){if(true===websockConnected){websockConnected=false;websock.close();$("#conStatus").removeClass("color-green");$("#conStatus").addClass("color-red");$("#conStatus").html("Error / No Connection &#8635;");$("#conStatus").off();$("#conStatus").on({click:restart,});}}
function handleVisibilityChange(){if(!websockConnected&&!document.hidden){restart();}} function handleVisibilityChange(){if(!websockConnected&&!document.hidden){restart();}}
function start(){let location=window.location.hostname;let port=window.location.port;document.addEventListener("visibilitychange",handleVisibilityChange,false);if(port!=""||port!=80||port!=443){websock=new WebSocket("ws://"+location+"/ws");}else{websock=new WebSocket("ws://"+location+"/ws");} function start(){document.addEventListener("visibilitychange",handleVisibilityChange,false);if(window.location.port!=""||window.location.port!=80||window.location.port!=443){websock=new WebSocket("ws://"+window.location.hostname+":"+window.location.port+"/ws");}else{websock=new WebSocket("ws://"+window.location.hostname+"/ws");}
if(null===WebSocketTimer){WebSocketTimer=setInterval(function(){if(websock.readyState===3){restart();}},5000);} if(null===WebSocketTimer){WebSocketTimer=setInterval(function(){if(websock.readyState===3){restart();}},5000);}
websock.onopen=function(evt){console.log("websock open");$("#conStatus").addClass("color-green");$("#conStatus").text("Connected");websockConnected=true;FragmentAssemblyTimer.forEach(element=>{clearInterval(element);});FragmentAssemblyTimer=new Object();controlAssemblyArray=new Object();};websock.onclose=function(evt){console.log("websock close");conStatusError();FragmentAssemblyTimer.forEach(element=>{clearInterval(element);});FragmentAssemblyTimer=new Object();controlAssemblyArray=new Object();};websock.onerror=function(evt){console.log("websock Error");restart();FragmentAssemblyTimer.forEach(element=>{clearInterval(element);});FragmentAssemblyTimer=new Object();controlAssemblyArray=new Object();};var handleEvent=function(evt){try{var data=JSON.parse(evt.data);} websock.onopen=function(evt){console.log("websock open");$("#conStatus").addClass("color-green");$("#conStatus").text("Connected");websockConnected=true;};websock.onclose=function(evt){console.log("websock close");conStatusError();};websock.onerror=function(evt){console.log("websock Error");console.log(evt);restart();};var handleEvent=function(evt){console.log(evt);try{var data=JSON.parse(evt.data);}
catch(Event){console.error(Event);websock.send("uiok:"+0);return;} catch(Event){console.error(Event);websock.send("uiok:"+0);return;}
var e=document.body;var center="";switch(data.type){case UI_INITIAL_GUI:$("#row").html("");$("#tabsnav").html("");$("#tabscontent").html("");if(data.sliderContinuous){sliderContinuous=data.sliderContinuous;} var e=document.body;var center="";switch(data.type){case UI_INITIAL_GUI:$("#row").html("");$("#tabsnav").html("");$("#tabscontent").html("");if(data.sliderContinuous){sliderContinuous=data.sliderContinuous;}
data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});if(data.totalcontrols>(data.controls.length-1)){websock.send("uiok:"+(data.controls.length-1));} data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});if(data.totalcontrols>(data.controls.length-1)){websock.send("uiok:"+(data.controls.length-1));}
@ -43,19 +43,7 @@ if(data.hasOwnProperty('inputType')){$("#text"+data.id).attr("type",data.inputTy
break;case UPDATE_SELECT:$("#select"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#select"+data.id).attr("style",data.elementStyle);} break;case UPDATE_SELECT:$("#select"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#select"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_BUTTON:$("#btn"+data.id).val(data.value);$("#btn"+data.id).text(data.value);if(data.hasOwnProperty('elementStyle')){$("#btn"+data.id).attr("style",data.elementStyle);} break;case UPDATE_BUTTON:$("#btn"+data.id).val(data.value);$("#btn"+data.id).text(data.value);if(data.hasOwnProperty('elementStyle')){$("#btn"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_PAD:case UPDATE_CPAD:break;case UPDATE_GAUGE:$("#gauge"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#gauge"+data.id).attr("style",data.elementStyle);} break;case UPDATE_PAD:case UPDATE_CPAD:break;case UPDATE_GAUGE:$("#gauge"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#gauge"+data.id).attr("style",data.elementStyle);}
break;case UPDATE_ACCEL:break;case UPDATE_TIME:var rv=new Date().toISOString();websock.send("time:"+rv+":"+data.id);break;case UI_FRAGMENT:let FragmentLen=data.length;let FragementOffset=data.offset;let NextFragmentOffset=FragementOffset+FragmentLen;let Total=data.total;let Arrived=(FragmentLen+FragementOffset);let FragmentFinal=Total===Arrived;if(!data.hasOwnProperty('control')) break;case UPDATE_ACCEL:break;case UPDATE_TIME:var rv=new Date().toISOString();websock.send("time:"+rv+":"+data.id);break;default:console.error("Unknown type or event");break;}
{console.error("UI_FRAGMENT:Missing control record, skipping control");break;}
let control=data.control;StopFragmentAssemblyTimer(data.control.id);if(0===FragementOffset)
{controlAssemblyArray[control.id]=data;controlAssemblyArray[control.id].offset=NextFragmentOffset;StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':NextFragmentOffset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");break;}
if("undefined"===typeof controlAssemblyArray[control.id])
{console.error("Missing first fragment for control: "+control.id);StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':0});websock.send("uifragmentok:"+0+": "+TotalRequest+":");break;}
if(FragementOffset!==controlAssemblyArray[control.id].offset)
{console.error("Wrong next fragment. Expected: "+controlAssemblyArray[control.id].offset+" Got: "+FragementOffset);StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':controlAssemblyArray[control.id].length+controlAssemblyArray[control.id].offset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");break;}
controlAssemblyArray[control.id].control.value+=control.value;controlAssemblyArray[control.id].offset=NextFragmentOffset;if(true===FragmentFinal)
{var fauxEvent={data:JSON.stringify(controlAssemblyArray[control.id].control),};handleEvent(fauxEvent);controlAssemblyArray[control.id]=null;}
else
{StartFragmentAssemblyTimer(control.id);let TotalRequest=JSON.stringify({'id':control.id,'offset':NextFragmentOffset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");}
break;default:console.error("Unknown type or event");break;}
if(data.type>=UI_TITEL&&data.type<UPDATE_OFFSET){processEnabled(data);} if(data.type>=UI_TITEL&&data.type<UPDATE_OFFSET){processEnabled(data);}
if(data.type>=UPDATE_OFFSET&&data.type<UI_INITIAL_GUI){var element=$("#id"+data.id);if(data.hasOwnProperty('panelStyle')){$("#id"+data.id).attr("style",data.panelStyle);} if(data.type>=UPDATE_OFFSET&&data.type<UI_INITIAL_GUI){var element=$("#id"+data.id);if(data.hasOwnProperty('panelStyle')){$("#id"+data.id).attr("style",data.panelStyle);}
if(data.hasOwnProperty('visible')){if(data['visible']) if(data.hasOwnProperty('visible')){if(data['visible'])
@ -64,15 +52,6 @@ $("#id"+data.id).hide();}
if(data.type==UPDATE_SLIDER){element.removeClass("slider-turquoise slider-emerald slider-peterriver slider-wetasphalt slider-sunflower slider-carrot slider-alizarin");element.addClass("slider-"+colorClass(data.color));}else{element.removeClass("turquoise emerald peterriver wetasphalt sunflower carrot alizarin");element.addClass(colorClass(data.color));} if(data.type==UPDATE_SLIDER){element.removeClass("slider-turquoise slider-emerald slider-peterriver slider-wetasphalt slider-sunflower slider-carrot slider-alizarin");element.addClass("slider-"+colorClass(data.color));}else{element.removeClass("turquoise emerald peterriver wetasphalt sunflower carrot alizarin");element.addClass(colorClass(data.color));}
processEnabled(data);} processEnabled(data);}
$(".range-slider__range").each(function(){$(this)[0].value=$(this).attr("value");$(this).next().html($(this).attr("value"));});};websock.onmessage=handleEvent;} $(".range-slider__range").each(function(){$(this)[0].value=$(this).attr("value");$(this).next().html($(this).attr("value"));});};websock.onmessage=handleEvent;}
function StartFragmentAssemblyTimer(Id)
{StopFragmentAssemblyTimer(Id);FragmentAssemblyTimer[Id]=setInterval(function(_Id)
{if("undefined"!==typeof controlAssemblyArray[_Id])
{if(null!==controlAssemblyArray[_Id])
{let TotalRequest=JSON.stringify({'id':controlAssemblyArray[_Id].control.id,'offset':controlAssemblyArray[_Id].offset});websock.send("uifragmentok:"+0+": "+TotalRequest+":");}}},1000,Id);}
function StopFragmentAssemblyTimer(Id)
{if("undefined"!==typeof FragmentAssemblyTimer[Id])
{if(FragmentAssemblyTimer[Id])
{clearInterval(FragmentAssemblyTimer[Id]);}}}
function sliderchange(number){var val=$("#sl"+number).val();websock.send("slvalue:"+val+":"+number);$(".range-slider__range").each(function(){$(this).attr("value",$(this)[0].value);});} function sliderchange(number){var val=$("#sl"+number).val();websock.send("slvalue:"+val+":"+number);$(".range-slider__range").each(function(){$(this).attr("value",$(this)[0].value);});}
function numberchange(number){var val=$("#num"+number).val();websock.send("nvalue:"+val+":"+number);} function numberchange(number){var val=$("#num"+number).val();websock.send("nvalue:"+val+":"+number);}
function textchange(number){var val=$("#text"+number).val();websock.send("tvalue:"+val+":"+number);} function textchange(number){var val=$("#text"+number).val();websock.send("tvalue:"+val+":"+number);}

View File

@ -30,7 +30,6 @@
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <ESP8266mDNS.h> #include <ESP8266mDNS.h>
#include <umm_malloc/umm_heap_select.h> #include <umm_malloc/umm_heap_select.h>
#ifndef CORE_MOCK
#ifndef MMU_IRAM_HEAP #ifndef MMU_IRAM_HEAP
#warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary) #warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary)
#warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap) #warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap)
@ -40,7 +39,6 @@
#error on ESP8266 and ESPUI, you must define OOM debug option when developping #error on ESP8266 and ESPUI, you must define OOM debug option when developping
#endif #endif
#endif #endif
#endif
//Settings //Settings
#define SLOW_BOOT 0 #define SLOW_BOOT 0
@ -398,8 +396,7 @@ void extendedCallback(Control* sender, int type, void* param)
Serial.print(sender->label); Serial.print(sender->label);
Serial.print("' = "); Serial.print("' = ");
Serial.println(sender->value); Serial.println(sender->value);
Serial.print("param = "); Serial.println(String("param = ") + String((int)param));
Serial.println((long)param);
} }
void setup() { void setup() {
@ -446,7 +443,6 @@ void loop() {
#if !defined(ESP32) #if !defined(ESP32)
((void (*)())0xf00fdead)(); ((void (*)())0xf00fdead)();
#endif #endif
break;
default: default:
Serial.print('#'); Serial.print('#');
break; break;

View File

@ -1,4 +1 @@
// placeholder // placeholder
#if CORE_MOCK
#include "completeExample.cpp"
#endif

View File

@ -11,17 +11,15 @@ DNSServer dnsServer;
// esp8266 // esp8266
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <umm_malloc/umm_heap_select.h> #include <umm_malloc/umm_heap_select.h>
#ifndef CORE_MOCK
#ifndef MMU_IRAM_HEAP #ifndef MMU_IRAM_HEAP
#warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary) #warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary)
#warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap) #warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap)
#warning then check http://<ip>/heap #warning then check http://<ip>/heap
#endif // MMU_IRAM_HEAP #endif // MMU_IRAM_HEAP
#if !defined(DEBUG_ESP_OOM) #ifndef DEBUG_ESP_OOM
#error on ESP8266 and ESPUI, you must define OOM debug option when developping #error on ESP8266 and ESPUI, you must define OOM debug option when developping
#endif #endif
#endif #endif
#endif
const char* ssid = "ESPUI"; const char* ssid = "ESPUI";
const char* password = "espui"; const char* password = "espui";
@ -69,8 +67,7 @@ void buttonCallback(Control* sender, int type)
void buttonExample(Control* sender, int type, void* param) void buttonExample(Control* sender, int type, void* param)
{ {
Serial.print("param: "); Serial.println(String("param: ") + String(long(param)));
Serial.println((long)param);
switch (type) switch (type)
{ {
case B_DOWN: case B_DOWN:

View File

@ -11,7 +11,6 @@ DNSServer dnsServer;
// esp8266 // esp8266
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <umm_malloc/umm_heap_select.h> #include <umm_malloc/umm_heap_select.h>
#ifndef CORE_MOCK
#ifndef MMU_IRAM_HEAP #ifndef MMU_IRAM_HEAP
#warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary) #warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary)
#warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap) #warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap)
@ -21,7 +20,6 @@ DNSServer dnsServer;
#error on ESP8266 and ESPUI, you must define OOM debug option when developping #error on ESP8266 and ESPUI, you must define OOM debug option when developping
#endif #endif
#endif #endif
#endif
const char* ssid = "ESPUI"; const char* ssid = "ESPUI";
const char* password = "espui"; const char* password = "espui";
@ -74,8 +72,7 @@ void buttonCallback(Control* sender, int type)
void buttonExample(Control* sender, int type, void* param) void buttonExample(Control* sender, int type, void* param)
{ {
Serial.print("param: "); Serial.println(String("param: ") + String(long(param)));
Serial.println((long)param);
switch (type) switch (type)
{ {
case B_DOWN: case B_DOWN:

View File

@ -11,7 +11,6 @@ DNSServer dnsServer;
// esp8266 // esp8266
#include <ESP8266WiFi.h> #include <ESP8266WiFi.h>
#include <umm_malloc/umm_heap_select.h> #include <umm_malloc/umm_heap_select.h>
#ifndef CORE_MOCK
#ifndef MMU_IRAM_HEAP #ifndef MMU_IRAM_HEAP
#warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary) #warning Try MMU option '2nd heap shared' in 'tools' IDE menu (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#option-summary)
#warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap) #warning use decorators: { HeapSelectIram doAllocationsInIRAM; ESPUI.addControl(...) ... } (cf. https://arduino-esp8266.readthedocs.io/en/latest/mmu.html#how-to-select-heap)
@ -21,7 +20,6 @@ DNSServer dnsServer;
#error on ESP8266 and ESPUI, you must define OOM debug option when developping #error on ESP8266 and ESPUI, you must define OOM debug option when developping
#endif #endif
#endif #endif
#endif
const char* ssid = "ESPUI"; const char* ssid = "ESPUI";
const char* password = "espui"; const char* password = "espui";
@ -68,8 +66,7 @@ void buttonCallback(Control* sender, int type)
void buttonExample(Control* sender, int type, void* param) void buttonExample(Control* sender, int type, void* param)
{ {
Serial.print("param: "); Serial.println(String("param: ") + String(long(param)));
Serial.println((long)param);
switch (type) switch (type)
{ {
case B_DOWN: case B_DOWN:

View File

@ -24,6 +24,11 @@
"name": "ArduinoJson", "name": "ArduinoJson",
"authors": "Benoit Blanchon", "authors": "Benoit Blanchon",
"frameworks": "arduino" "frameworks": "arduino"
},
{
"name": "LittleFS_esp32",
"authors": "lorol",
"frameworks": "arduino"
} }
], ],
"version": "2.2.3", "version": "2.2.3",

View File

@ -5,7 +5,11 @@
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include "dataControlsJS.h" #include "dataControlsJS.h"
#ifndef ESPU_DISABLE_GRAPH
#include "dataGraphJS.h" #include "dataGraphJS.h"
#endif
#include "dataIndexHTML.h" #include "dataIndexHTML.h"
#include "dataNormalizeCSS.h" #include "dataNormalizeCSS.h"
#include "dataSliderJS.h" #include "dataSliderJS.h"
@ -17,6 +21,14 @@
#include <umm_malloc/umm_heap_select.h> #include <umm_malloc/umm_heap_select.h>
#endif #endif
#if defined(DEBUG) && defined(ESPU_DEBUG)
#define ESPU_DBG(arg) Serial.print(arg)
#define ESPU_DBGL(arg) Serial.println(arg)
#else
#define ESPU_DBG(arg)
#define ESPU_DBGL(arg)
#endif
static String heapInfo(const __FlashStringHelper* mode) static String heapInfo(const __FlashStringHelper* mode)
{ {
String result; String result;
@ -72,7 +84,7 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf_P(PSTR("Listing directory: %s\n"), dirname); ESPU_DBGf_P(PSTR("Listing directory: %s\n"), dirname);
} }
#endif #endif
@ -91,7 +103,7 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("Failed to open directory")); ESPU_DBGL(F("Failed to open directory"));
} }
#endif #endif
@ -103,7 +115,7 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("Not a directory")); ESPU_DBGL(F("Not a directory"));
} }
#endif #endif
@ -119,8 +131,8 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print(F(" DIR : ")); ESPU_DBG(F(" DIR : "));
Serial.println(file.name()); ESPU_DBGL(file.name());
} }
#endif #endif
@ -138,10 +150,10 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print(F(" FILE: ")); ESPU_DBG(F(" FILE: "));
Serial.print(file.name()); ESPU_DBG(file.name());
Serial.print(F(" SIZE: ")); ESPU_DBG(F(" SIZE: "));
Serial.println(file.size()); ESPU_DBGL(file.size());
} }
#endif #endif
} }
@ -156,7 +168,7 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf_P(PSTR("Listing directory: %s\n"), dirname); ESPU_DBGf_P(PSTR("Listing directory: %s\n"), dirname);
} }
#endif #endif
@ -169,8 +181,8 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print(F(" DIR : ")); ESPU_DBG(F(" DIR : "));
Serial.println(dir.fileName()); ESPU_DBGL(dir.fileName());
} }
#endif #endif
if (levels) if (levels)
@ -185,10 +197,10 @@ void listDir(const char* dirname, uint8_t levels)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print(F(" FILE: ")); ESPU_DBG(F(" FILE: "));
Serial.print(dir.fileName()); ESPU_DBG(dir.fileName());
Serial.print(F(" SIZE: ")); ESPU_DBG(F(" SIZE: "));
Serial.println(dir.fileSize()); ESPU_DBGL(dir.fileSize());
} }
#endif #endif
} }
@ -206,13 +218,13 @@ void ESPUIClass::list()
if (!LITTLEFS.begin()) if (!LITTLEFS.begin())
#endif #endif
{ {
Serial.println(F("LITTLEFS Mount Failed")); ESPU_DBGL(F("LITTLEFS Mount Failed"));
return; return;
} }
#else #else
if (!LittleFS.begin()) if (!LittleFS.begin())
{ {
Serial.println(F("LittleFS Mount Failed")); ESPU_DBG(F("LittleFS Mount Failed"));
return; return;
} }
#endif #endif
@ -220,27 +232,27 @@ void ESPUIClass::list()
listDir("/", 1); listDir("/", 1);
#if defined(ESP32) #if defined(ESP32)
Serial.print(F("Total KB: ")); ESPU_DBG(F("Total KB: "));
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4 #if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
Serial.println(LittleFS.totalBytes() / 1024); ESPU_DBGL(LittleFS.totalBytes() / 1024);
#else #else
Serial.println(LITTLEFS.totalBytes() / 1024); ESPU_DBGL(LITTLEFS.totalBytes() / 1024);
#endif #endif
Serial.print(F("Used KB: ")); ESPU_DBG(F("Used KB: "));
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4 #if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
Serial.println(LittleFS.usedBytes() / 1024); ESPU_DBGL(LittleFS.usedBytes() / 1024);
#else #else
Serial.println(LITTLEFS.usedBytes() / 1024); ESPU_DBGL(LITTLEFS.usedBytes() / 1024);
#endif #endif
#else #else
FSInfo fs_info; FSInfo fs_info;
LittleFS.info(fs_info); LittleFS.info(fs_info);
Serial.print(F("Total KB: ")); ESPU_DBG(F("Total KB: "));
Serial.println(fs_info.totalBytes / 1024); ESPU_DBGL(fs_info.totalBytes / 1024);
Serial.print(F("Used KB: ")); ESPU_DBG(F("Used KB: "));
Serial.println(fs_info.usedBytes / 1024); ESPU_DBGL(fs_info.usedBytes / 1024);
#endif #endif
} }
@ -261,7 +273,7 @@ void deleteFile(const char* path)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf_P(PSTR("File: %s does not exist, not deleting\n"), path); ESPU_DBGf_P(PSTR("File: %s does not exist, not deleting\n"), path);
} }
#endif #endif
@ -271,7 +283,7 @@ void deleteFile(const char* path)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf_P(PSTR("Deleting file: %s\n"), path); ESPU_DBGf_P(PSTR("Deleting file: %s\n"), path);
} }
#endif #endif
@ -289,7 +301,7 @@ void deleteFile(const char* path)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("File deleted")); ESPU_DBGL(F("File deleted"));
} }
#endif #endif
} }
@ -298,7 +310,7 @@ void deleteFile(const char* path)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("Delete failed")); ESPU_DBGL(F("Delete failed"));
} }
#endif #endif
} }
@ -309,7 +321,7 @@ void writeFile(const char* path, const char* data)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf_P(PSTR("Writing file: %s\n"), path); ESPU_DBGf_P(PSTR("Writing file: %s\n"), path);
} }
#endif #endif
@ -327,7 +339,7 @@ void writeFile(const char* path, const char* data)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("Failed to open file for writing")); ESPU_DBGL(F("Failed to open file for writing"));
} }
#endif #endif
@ -341,7 +353,7 @@ void writeFile(const char* path, const char* data)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("File written")); ESPU_DBGL(F("File written"));
} }
#endif #endif
} }
@ -350,7 +362,7 @@ void writeFile(const char* path, const char* data)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("Write failed")); ESPU_DBGL(F("Write failed"));
} }
#endif #endif
} }
@ -362,7 +374,7 @@ void writeFile(const char* path, const char* data)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("File written")); ESPU_DBGL(F("File written"));
} }
#endif #endif
} }
@ -371,7 +383,7 @@ void writeFile(const char* path, const char* data)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("Write failed")); ESPU_DBGL(F("Write failed"));
} }
#endif #endif
} }
@ -389,7 +401,7 @@ void ESPUIClass::prepareFileSystem(bool format)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("About to prepare filesystem...")); ESPU_DBGL(F("About to prepare filesystem..."));
} }
#endif #endif
@ -409,7 +421,7 @@ void ESPUIClass::prepareFileSystem(bool format)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("LittleFS Format Failed")); ESPU_DBGL(F("LittleFS Format Failed"));
} }
#endif #endif
return; return;
@ -425,7 +437,7 @@ void ESPUIClass::prepareFileSystem(bool format)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("LittleFS Formatted")); ESPU_DBGL(F("LittleFS Formatted"));
} }
#endif #endif
} }
@ -434,7 +446,7 @@ void ESPUIClass::prepareFileSystem(bool format)
if (verbosity) if (verbosity)
{ {
listDir("/", 1); listDir("/", 1);
Serial.println(F("LittleFS Mount ESP32 Done")); ESPU_DBGL(F("LittleFS Mount ESP32 Done"));
} }
#endif #endif
@ -447,7 +459,7 @@ void ESPUIClass::prepareFileSystem(bool format)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("LittleFS Formatted")); ESPU_DBGL(F("LittleFS Formatted"));
} }
#endif #endif
} }
@ -456,7 +468,7 @@ void ESPUIClass::prepareFileSystem(bool format)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("LittleFS Mount Failed")); ESPU_DBGL(F("LittleFS Mount Failed"));
} }
#endif #endif
return; return;
@ -468,7 +480,7 @@ void ESPUIClass::prepareFileSystem(bool format)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("LittleFS Formatted")); ESPU_DBGL(F("LittleFS Formatted"));
} }
#endif #endif
} }
@ -477,7 +489,7 @@ void ESPUIClass::prepareFileSystem(bool format)
if (verbosity) if (verbosity)
{ {
listDir("/", 1); listDir("/", 1);
Serial.println(F("LittleFS Mount ESP8266 Done")); ESPU_DBGL(F("LittleFS Mount ESP8266 Done"));
} }
#endif #endif
@ -491,13 +503,15 @@ void ESPUIClass::prepareFileSystem(bool format)
deleteFile("/js/zepto.min.js"); deleteFile("/js/zepto.min.js");
deleteFile("/js/controls.js"); deleteFile("/js/controls.js");
deleteFile("/js/slider.js"); deleteFile("/js/slider.js");
#ifndef ESPU_DISABLE_GRAPH
deleteFile("/js/graph.js"); deleteFile("/js/graph.js");
#endif
deleteFile("/js/tabbedcontent.js"); deleteFile("/js/tabbedcontent.js");
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("Cleanup done")); ESPU_DBGL(F("Cleanup done"));
} }
#endif #endif
@ -512,8 +526,9 @@ void ESPUIClass::prepareFileSystem(bool format)
writeFile("/js/zepto.min.js", JS_ZEPTO); writeFile("/js/zepto.min.js", JS_ZEPTO);
writeFile("/js/controls.js", JS_CONTROLS); writeFile("/js/controls.js", JS_CONTROLS);
writeFile("/js/slider.js", JS_SLIDER); writeFile("/js/slider.js", JS_SLIDER);
#ifndef ESPU_DISABLE_GRAPH
writeFile("/js/graph.js", JS_GRAPH); writeFile("/js/graph.js", JS_GRAPH);
#endif
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT); writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
#else #else
writeFile("/index.htm", HTML_INDEX); writeFile("/index.htm", HTML_INDEX);
@ -524,8 +539,9 @@ void ESPUIClass::prepareFileSystem(bool format)
writeFile("/js/zepto.min.js", JS_ZEPTO); writeFile("/js/zepto.min.js", JS_ZEPTO);
writeFile("/js/controls.js", JS_CONTROLS); writeFile("/js/controls.js", JS_CONTROLS);
writeFile("/js/slider.js", JS_SLIDER); writeFile("/js/slider.js", JS_SLIDER);
#ifndef ESPU_DISABLE_GRAPH
writeFile("/js/graph.js", JS_GRAPH); writeFile("/js/graph.js", JS_GRAPH);
#endif
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT); writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
#endif #endif
#else #else
@ -537,15 +553,16 @@ void ESPUIClass::prepareFileSystem(bool format)
writeFile("/js/zepto.min.js", JS_ZEPTO); writeFile("/js/zepto.min.js", JS_ZEPTO);
writeFile("/js/controls.js", JS_CONTROLS); writeFile("/js/controls.js", JS_CONTROLS);
writeFile("/js/slider.js", JS_SLIDER); writeFile("/js/slider.js", JS_SLIDER);
#ifndef ESPU_DISABLE_GRAPH
writeFile("/js/graph.js", JS_GRAPH); writeFile("/js/graph.js", JS_GRAPH);
#endif
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT); writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
#endif #endif
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("Done Initializing filesystem :-)")); ESPU_DBGL(F("Done Initializing filesystem :-)"));
} }
#endif #endif
@ -575,7 +592,7 @@ void ESPUIClass::prepareFileSystem(bool format)
void ESPUIClass::onWsEvent( void ESPUIClass::onWsEvent(
AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len) AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
{ {
// Serial.println(String("ESPUIClass::OnWsEvent: type: ") + String(type)); // ESPU_DBGL(String("ESPUIClass::OnWsEvent: type: ") + String(type));
RemoveToBeDeletedControls(); RemoveToBeDeletedControls();
if (WS_EVT_DISCONNECT == type) if (WS_EVT_DISCONNECT == type)
@ -583,13 +600,13 @@ void ESPUIClass::onWsEvent(
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("WS_EVT_DISCONNECT")); ESPU_DBGL(F("WS_EVT_DISCONNECT"));
} }
#endif #endif
if (MapOfClients.end() != MapOfClients.find(client->id())) if (MapOfClients.end() != MapOfClients.find(client->id()))
{ {
// Serial.println("Delete client."); // ESPU_DBGL("Delete client.");
delete MapOfClients[client->id()]; delete MapOfClients[client->id()];
MapOfClients.erase(client->id()); MapOfClients.erase(client->id());
} }
@ -598,13 +615,13 @@ void ESPUIClass::onWsEvent(
{ {
if (MapOfClients.end() == MapOfClients.find(client->id())) if (MapOfClients.end() == MapOfClients.find(client->id()))
{ {
// Serial.println("ESPUIClass::OnWsEvent:Create new client."); // ESPU_DBGL("ESPUIClass::OnWsEvent:Create new client.");
MapOfClients[client->id()] = new ESPUIclient(client); MapOfClients[client->id()] = new ESPUIclient(client);
} }
if(MapOfClients[client->id()]->onWsEvent(type, arg, data, len)) if(MapOfClients[client->id()]->onWsEvent(type, arg, data, len))
{ {
// Serial.println("ESPUIClass::OnWsEvent:notify the clients that they need to be updated."); // ESPU_DBGL("ESPUIClass::OnWsEvent:notify the clients that they need to be updated.");
NotifyClients(ESPUIclient::UpdateNeeded); NotifyClients(ESPUIclient::UpdateNeeded);
} }
} }
@ -702,7 +719,7 @@ bool ESPUIClass::removeControl(uint16_t id, bool force_rebuild_ui)
#ifdef DEBUG_ESPUI #ifdef DEBUG_ESPUI
else else
{ {
// Serial.println(String("Could not Remove Control ") + String(id)); // ESPU_DBGL(String("Could not Remove Control ") + String(id));
} }
#endif // def DEBUG_ESPUI #endif // def DEBUG_ESPUI
@ -919,7 +936,7 @@ void ESPUIClass::setEnabled(uint16_t id, bool enabled, int clientId)
Control* control = getControl(id); Control* control = getControl(id);
if (control) if (control)
{ {
// Serial.println(String("CreateAllowed: id: ") + String(clientId) + " State: " + String(enabled)); // ESPU_DBGL(String("CreateAllowed: id: ") + String(clientId) + " State: " + String(enabled));
control->enabled = enabled; control->enabled = enabled;
updateControl(control, clientId); updateControl(control, clientId);
} }
@ -943,7 +960,7 @@ void ESPUIClass::updateControl(uint16_t id, int clientId)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.printf_P(PSTR("Error: Update Control: There is no control with ID %d\n"), id); ESPU_DBGf_P(PSTR("Error: Update Control: There is no control with ID %d\n"), id);
} }
#endif #endif
return; return;
@ -972,7 +989,7 @@ void ESPUIClass::updateControlValue(uint16_t id, const String& value, int client
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.printf_P(PSTR("Error: updateControlValue Control: There is no control with ID %d\n"), id); ESPU_DBGf_P(PSTR("Error: updateControlValue Control: There is no control with ID %d\n"), id);
} }
#endif #endif
return; return;
@ -993,7 +1010,7 @@ void ESPUIClass::updateControlLabel(Control* control, const char* value, int cli
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.printf_P(PSTR("Error: updateControlLabel Control: There is no control with the requested ID \n")); ESPU_DBGf_P(PSTR("Error: updateControlLabel Control: There is no control with the requested ID \n"));
} }
#endif #endif
return; return;
@ -1146,7 +1163,7 @@ void ESPUIClass::jsonReload()
{ {
for (auto& CurrentClient : MapOfClients) for (auto& CurrentClient : MapOfClients)
{ {
// Serial.println("Requesting Reload"); // ESPU_DBGL("Requesting Reload");
CurrentClient.second->NotifyClient(ClientUpdateType_t::ReloadNeeded); CurrentClient.second->NotifyClient(ClientUpdateType_t::ReloadNeeded);
} }
} }
@ -1189,7 +1206,7 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("LITTLEFS Mount Failed, PLEASE CHECK THE README ON HOW TO " ESPU_DBGL(F("LITTLEFS Mount Failed, PLEASE CHECK THE README ON HOW TO "
"PREPARE YOUR ESP!!!!!!!")); "PREPARE YOUR ESP!!!!!!!"));
} }
#endif #endif
@ -1218,7 +1235,7 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("Please read the README!!!!!!!, Make sure to " ESPU_DBGL(F("Please read the README!!!!!!!, Make sure to "
"prepareFileSystem() once in an empty sketch")); "prepareFileSystem() once in an empty sketch"));
} }
#endif #endif
@ -1285,7 +1302,7 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("UI Initialized")); ESPU_DBGL(F("UI Initialized"));
} }
#endif #endif
} }
@ -1365,17 +1382,18 @@ void ESPUIClass::begin(const char* _title, const char* username, const char* pas
request->send(response); request->send(response);
}); });
#ifndef ESPU_DISABLE_GRAPH
server->on("/js/graph.js", HTTP_GET, [](AsyncWebServerRequest* request) { server->on("/js/graph.js", HTTP_GET, [](AsyncWebServerRequest* request) {
if (ESPUI.basicAuth && !request->authenticate(ESPUI.basicAuthUsername, ESPUI.basicAuthPassword)) if (ESPUI.basicAuth && !request->authenticate(ESPUI.basicAuthUsername, ESPUI.basicAuthPassword))
{ {
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse* response AsyncWebServerResponse* response
= request->beginResponse_P(200, "application/javascript", JS_GRAPH_GZIP, sizeof(JS_GRAPH_GZIP)); = request->beginResponse_P(200, "application/javascript", JS_GRAPH_GZIP, sizeof(JS_GRAPH_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
#endif
server->on("/js/tabbedcontent.js", HTTP_GET, [](AsyncWebServerRequest* request) { server->on("/js/tabbedcontent.js", HTTP_GET, [](AsyncWebServerRequest* request) {
if (ESPUI.basicAuth && !request->authenticate(ESPUI.basicAuthUsername, ESPUI.basicAuthPassword)) if (ESPUI.basicAuth && !request->authenticate(ESPUI.basicAuthUsername, ESPUI.basicAuthPassword))
@ -1445,7 +1463,7 @@ void ESPUIClass::begin(const char* _title, const char* username, const char* pas
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (verbosity) if (verbosity)
{ {
Serial.println(F("UI Initialized")); ESPU_DBGL(F("UI Initialized"));
} }
#endif #endif
} }

View File

@ -2,6 +2,15 @@
#include "ESPUIclient.h" #include "ESPUIclient.h"
#include "ESPUIcontrol.h" #include "ESPUIcontrol.h"
#if defined(DEBUG) && defined(ESPU_DEBUG)
#define ESPU_DBG(arg) Serial.print(arg)
#define ESPU_DBGL(arg) Serial.println(arg)
#else
#define ESPU_DBG(arg)
#define ESPU_DBGL(arg)
#endif
// JSONSlave: // JSONSlave:
// helper to process exact JSON serialization size // helper to process exact JSON serialization size
// it takes ~2ms on esp8266 and avoid large String reallocation which is really worth the cost // it takes ~2ms on esp8266 and avoid large String reallocation which is really worth the cost
@ -100,7 +109,7 @@ bool ESPUIclient::SendClientNotification(ClientUpdateType_t value)
{ {
if(!CanSend()) if(!CanSend())
{ {
// Serial.println(F("ESPUIclient::SendClientNotification:CannotSend")); // ESPU_DBGL(F("ESPUIclient::SendClientNotification:CannotSend"));
break; break;
} }
@ -108,13 +117,13 @@ bool ESPUIclient::SendClientNotification(ClientUpdateType_t value)
FillInHeader(document); FillInHeader(document);
if(ClientUpdateType_t::ReloadNeeded == value) if(ClientUpdateType_t::ReloadNeeded == value)
{ {
// Serial.println(F("ESPUIclient::SendClientNotification:set type to reload")); // ESPU_DBGL(F("ESPUIclient::SendClientNotification:set type to reload"));
document["type"] = int(UI_RELOAD); document["type"] = int(UI_RELOAD);
} }
// dont send any controls // dont send any controls
Response = SendJsonDocToWebSocket(document); Response = SendJsonDocToWebSocket(document);
// Serial.println(String("ESPUIclient::SendClientNotification:NotificationSent:Response: ") + String(Response)); // ESPU_DBGL(String("ESPUIclient::SendClientNotification:NotificationSent:Response: ") + String(Response));
} while (false); } while (false);
return Response; return Response;
@ -130,7 +139,7 @@ void ESPUIclient::NotifyClient(ClientUpdateType_t newState)
bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t len) bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t len)
{ {
bool Response = false; bool Response = false;
// Serial.println(String("ESPUIclient::OnWsEvent: type: ") + String(type)); // ESPU_DBGL(String("ESPUIclient::OnWsEvent: type: ") + String(type));
switch (type) switch (type)
{ {
@ -139,7 +148,7 @@ bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("ESPUIclient::OnWsEvent:WS_EVT_PONG")); ESPU_DBGL(F("ESPUIclient::OnWsEvent:WS_EVT_PONG"));
} }
#endif #endif
break; break;
@ -150,7 +159,7 @@ bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("ESPUIclient::OnWsEvent:WS_EVT_ERROR")); ESPU_DBGL(F("ESPUIclient::OnWsEvent:WS_EVT_ERROR"));
} }
#endif #endif
break; break;
@ -161,19 +170,19 @@ bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(F("ESPUIclient::OnWsEvent:WS_EVT_CONNECT")); ESPU_DBGL(F("ESPUIclient::OnWsEvent:WS_EVT_CONNECT"));
Serial.println(client->id()); ESPU_DBGL(client->id());
} }
#endif #endif
// Serial.println("ESPUIclient:onWsEvent:WS_EVT_CONNECT: Call NotifyClient: RebuildNeeded"); // ESPU_DBGL("ESPUIclient:onWsEvent:WS_EVT_CONNECT: Call NotifyClient: RebuildNeeded");
NotifyClient(ClientUpdateType_t::RebuildNeeded); NotifyClient(ClientUpdateType_t::RebuildNeeded);
break; break;
} }
case WS_EVT_DATA: case WS_EVT_DATA:
{ {
// Serial.println(F("ESPUIclient::OnWsEvent:WS_EVT_DATA")); // ESPU_DBGL(F("ESPUIclient::OnWsEvent:WS_EVT_DATA"));
String msg = ""; String msg = "";
msg.reserve(len + 1); msg.reserve(len + 1);
@ -189,50 +198,50 @@ bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity >= Verbosity::VerboseJSON) if (ESPUI.verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(String(F(" WS msg: ")) + msg); ESPU_DBGL(String(F(" WS msg: ")) + msg);
Serial.println(String(F(" WS cmd: ")) + cmd); ESPU_DBGL(String(F(" WS cmd: ")) + cmd);
Serial.println(String(F(" WS id: ")) + String(id)); ESPU_DBGL(String(F(" WS id: ")) + String(id));
Serial.println(String(F("WS value: ")) + String(value)); ESPU_DBGL(String(F("WS value: ")) + String(value));
} }
#endif #endif
if (cmd.equals(F("uiok"))) if (cmd.equals(F("uiok")))
{ {
// Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:ProcessAck:")) + pCurrentFsmState->GetStateName()); // ESPU_DBGL(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:ProcessAck:")) + pCurrentFsmState->GetStateName());
pCurrentFsmState->ProcessAck(id, emptyString); pCurrentFsmState->ProcessAck(id, emptyString);
break; break;
} }
if (cmd.equals(F("uifragmentok"))) if (cmd.equals(F("uifragmentok")))
{ {
// Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:uifragmentok:")) + pCurrentFsmState->GetStateName() + ":ProcessAck"); // ESPU_DBGL(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:uifragmentok:")) + pCurrentFsmState->GetStateName() + ":ProcessAck");
if(!emptyString.equals(value)) if(!emptyString.equals(value))
{ {
// Serial.println(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:uifragmentok:")) + pCurrentFsmState->GetStateName() + ":ProcessAck:value:'" + value + "'"); // ESPU_DBGL(String(F("ESPUIclient::OnWsEvent:WS_EVT_DATA:uiok:uifragmentok:")) + pCurrentFsmState->GetStateName() + ":ProcessAck:value:'" + value + "'");
pCurrentFsmState->ProcessAck(uint16_t(-1), value); pCurrentFsmState->ProcessAck(uint16_t(-1), value);
} }
else else
{ {
Serial.println(F("ERROR:ESPUIclient::OnWsEvent:WS_EVT_DATA:uifragmentok:ProcessAck:Fragment Header is missing")); ESPU_DBGL(F("ERROR:ESPUIclient::OnWsEvent:WS_EVT_DATA:uifragmentok:ProcessAck:Fragment Header is missing"));
} }
break; break;
} }
if (cmd.equals(F("uiuok"))) if (cmd.equals(F("uiuok")))
{ {
// Serial.println(F("WS_EVT_DATA: uiuok. Unlock new async notifications")); // ESPU_DBGL(F("WS_EVT_DATA: uiuok. Unlock new async notifications"));
break; break;
} }
// Serial.println(F("WS_EVT_DATA:Process Control")); // ESPU_DBGL(F("WS_EVT_DATA:Process Control"));
Control* control = ESPUI.getControl(id); Control* control = ESPUI.getControl(id);
if (nullptr == control) if (nullptr == control)
{ {
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println(String(F("No control found for ID ")) + String(id)); ESPU_DBGL(String(F("No control found for ID ")) + String(id));
} }
#endif #endif
break; break;
@ -245,7 +254,7 @@ bool ESPUIclient::onWsEvent(AwsEventType type, void* arg, uint8_t* data, size_t
default: default:
{ {
// Serial.println(F("ESPUIclient::OnWsEvent:default")); // ESPU_DBGL(F("ESPUIclient::OnWsEvent:default"));
break; break;
} }
} // end switch } // end switch
@ -267,7 +276,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
xSemaphoreTake(ESPUI.ControlsSemaphore, portMAX_DELAY); xSemaphoreTake(ESPUI.ControlsSemaphore, portMAX_DELAY);
#endif // def ESP32 #endif // def ESP32
// Serial.println(String("prepareJSONChunk: Start. InUpdateMode: ") + String(InUpdateMode)); // ESPU_DBGL(String("prepareJSONChunk: Start. InUpdateMode: ") + String(InUpdateMode));
int elementcount = 0; int elementcount = 0;
do // once do // once
@ -281,10 +290,10 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
if(!emptyString.equals(FragmentRequestString)) if(!emptyString.equals(FragmentRequestString))
{ {
// Serial.println(F("prepareJSONChunk:Fragmentation:Got Header (1)")); // ESPU_DBGL(F("prepareJSONChunk:Fragmentation:Got Header (1)"));
// Serial.println(String("prepareJSONChunk:startindex: ") + String(startindex)); // ESPU_DBGL(String("prepareJSONChunk:startindex: ") + String(startindex));
// Serial.println(String("prepareJSONChunk:currentIndex: ") + String(currentIndex)); // ESPU_DBGL(String("prepareJSONChunk:currentIndex: ") + String(currentIndex));
// Serial.println(String("prepareJSONChunk:FragmentRequestString: '") + FragmentRequestString + "'"); // ESPU_DBGL(String("prepareJSONChunk:FragmentRequestString: '") + FragmentRequestString + "'");
// this is actually a fragment or directed update request // this is actually a fragment or directed update request
// parse the string we got from the UI and try to update that specific // parse the string we got from the UI and try to update that specific
@ -292,38 +301,38 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
DynamicJsonDocument FragmentRequest(FragmentRequestString.length() * 3); DynamicJsonDocument FragmentRequest(FragmentRequestString.length() * 3);
if(0 >= FragmentRequest.capacity()) if(0 >= FragmentRequest.capacity())
{ {
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Could not allocate memory for a fragmentation request. Skipping Response")); ESPU_DBGL(F("ERROR:prepareJSONChunk:Fragmentation:Could not allocate memory for a fragmentation request. Skipping Response"));
break; break;
} }
size_t FragmentRequestStartOffset = FragmentRequestString.indexOf("{"); size_t FragmentRequestStartOffset = FragmentRequestString.indexOf("{");
DeserializationError error = deserializeJson(FragmentRequest, FragmentRequestString.substring(FragmentRequestStartOffset)); DeserializationError error = deserializeJson(FragmentRequest, FragmentRequestString.substring(FragmentRequestStartOffset));
if(DeserializationError::Ok != error) if(DeserializationError::Ok != error)
{ {
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Could not extract json from the fragment request")); ESPU_DBGL(F("ERROR:prepareJSONChunk:Fragmentation:Could not extract json from the fragment request"));
break; break;
} }
if(!FragmentRequest.containsKey(F("id"))) if(!FragmentRequest.containsKey(F("id")))
{ {
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a control ID")); ESPU_DBGL(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a control ID"));
break; break;
} }
uint16_t ControlId = uint16_t(FragmentRequest[F("id")]); uint16_t ControlId = uint16_t(FragmentRequest[F("id")]);
if(!FragmentRequest.containsKey(F("offset"))) if(!FragmentRequest.containsKey(F("offset")))
{ {
Serial.println(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a starting offset")); ESPU_DBGL(F("ERROR:prepareJSONChunk:Fragmentation:Request does not contain a starting offset"));
break; break;
} }
DataOffset = uint16_t(FragmentRequest[F("offset")]); DataOffset = uint16_t(FragmentRequest[F("offset")]);
control = ESPUI.getControlNoLock(ControlId); control = ESPUI.getControlNoLock(ControlId);
if(nullptr == control) if(nullptr == control)
{ {
Serial.println(String(F("ERROR:prepareJSONChunk:Fragmentation:Requested control: ")) + String(ControlId) + F(" does not exist")); ESPU_DBGL(String(F("ERROR:prepareJSONChunk:Fragmentation:Requested control: ")) + String(ControlId) + F(" does not exist"));
break; break;
} }
// Serial.println(F("prepareJSONChunk:Fragmentation:disable the control search operation")); // ESPU_DBGL(F("prepareJSONChunk:Fragmentation:disable the control search operation"));
currentIndex = 1; currentIndex = 1;
startindex = 0; startindex = 0;
SingleControl = true; SingleControl = true;
@ -355,7 +364,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
// any controls left to be processed? // any controls left to be processed?
if(nullptr == control) if(nullptr == control)
{ {
// Serial.println("prepareJSONChunk: No controls to process"); // ESPU_DBGL("prepareJSONChunk: No controls to process");
break; break;
} }
@ -367,7 +376,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
// skip deleted controls or controls that have not been updated // skip deleted controls or controls that have not been updated
if (control->ToBeDeleted() && !SingleControl) if (control->ToBeDeleted() && !SingleControl)
{ {
// Serial.println(String("prepareJSONChunk: Ignoring Deleted control: ") + String(control->id)); // ESPU_DBGL(String("prepareJSONChunk: Ignoring Deleted control: ") + String(control->id));
control = control->next; control = control->next;
continue; continue;
} }
@ -395,8 +404,8 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
// String("prepareJSONChunk: too much data in the message. Remove the last entry"); // String("prepareJSONChunk: too much data in the message. Remove the last entry");
if (1 == elementcount) if (1 == elementcount)
{ {
Serial.println(String(F("ERROR: prepareJSONChunk: Control ")) + String(control->id) + F(" is too large to be sent to the browser.")); ESPU_DBGL(String(F("ERROR: prepareJSONChunk: Control ")) + String(control->id) + F(" is too large to be sent to the browser."));
// Serial.println(String(F("ERROR: prepareJSONChunk: value: ")) + control->value); // ESPU_DBGL(String(F("ERROR: prepareJSONChunk: value: ")) + control->value);
rootDoc.clear(); rootDoc.clear();
item = items.createNestedObject(); item = items.createNestedObject();
control->MarshalErrorMessage(item); control->MarshalErrorMessage(item);
@ -404,8 +413,8 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
} }
else else
{ {
// Serial.println(String("prepareJSONChunk: Defering control: ") + String(control->id)); // ESPU_DBGL(String("prepareJSONChunk: Defering control: ") + String(control->id));
// Serial.println(String("prepareJSONChunk: elementcount: ") + String(elementcount)); // ESPU_DBGL(String("prepareJSONChunk: elementcount: ") + String(elementcount));
items.remove(elementcount); items.remove(elementcount);
--elementcount; --elementcount;
@ -415,7 +424,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
} }
else if (SingleControl) else if (SingleControl)
{ {
// Serial.println("prepareJSONChunk: exit loop"); // ESPU_DBGL("prepareJSONChunk: exit loop");
control = nullptr; control = nullptr;
} }
else else
@ -430,7 +439,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
xSemaphoreGive(ESPUI.ControlsSemaphore); xSemaphoreGive(ESPUI.ControlsSemaphore);
#endif // def ESP32 #endif // def ESP32
// Serial.println(String("prepareJSONChunk: elementcount: ") + String(elementcount)); // ESPU_DBGL(String("prepareJSONChunk: elementcount: ") + String(elementcount));
return elementcount; return elementcount;
} }
@ -457,18 +466,18 @@ etc.
bool ESPUIclient::SendControlsToClient(uint16_t startidx, ClientUpdateType_t TransferMode, String FragmentRequest) bool ESPUIclient::SendControlsToClient(uint16_t startidx, ClientUpdateType_t TransferMode, String FragmentRequest)
{ {
bool Response = false; bool Response = false;
// Serial.println(String("ESPUIclient:SendControlsToClient:startidx: ") + String(startidx)); // ESPU_DBGL(String("ESPUIclient:SendControlsToClient:startidx: ") + String(startidx));
do // once do // once
{ {
if(!CanSend()) if(!CanSend())
{ {
// Serial.println("ESPUIclient:SendControlsToClient: Cannot Send to clients."); // ESPU_DBGL("ESPUIclient:SendControlsToClient: Cannot Send to clients.");
break; break;
} }
else if ((startidx >= ESPUI.controlCount) && (emptyString.equals(FragmentRequest))) else if ((startidx >= ESPUI.controlCount) && (emptyString.equals(FragmentRequest)))
{ {
// Serial.println(F("ERROR:ESPUIclient:SendControlsToClient: No more controls to send.")); // ESPU_DBGL(F("ERROR:ESPUIclient:SendControlsToClient: No more controls to send."));
Response = true; Response = true;
break; break;
} }
@ -480,44 +489,44 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx, ClientUpdateType_t Tra
if(0 == startidx) if(0 == startidx)
{ {
// Serial.println("ESPUIclient:SendControlsToClient: Tell client we are starting a transfer of controls."); // ESPU_DBGL("ESPUIclient:SendControlsToClient: Tell client we are starting a transfer of controls.");
document["type"] = (ClientUpdateType_t::RebuildNeeded == TransferMode) ? UI_INITIAL_GUI : UI_EXTEND_GUI; document["type"] = (ClientUpdateType_t::RebuildNeeded == TransferMode) ? UI_INITIAL_GUI : UI_EXTEND_GUI;
CurrentSyncID = NextSyncID; CurrentSyncID = NextSyncID;
NextSyncID = ESPUI.GetNextControlChangeId(); NextSyncID = ESPUI.GetNextControlChangeId();
} }
// Serial.println(String("ESPUIclient:SendControlsToClient:type: ") + String((uint32_t)document["type"])); // ESPU_DBGL(String("ESPUIclient:SendControlsToClient:type: ") + String((uint32_t)document["type"]));
// Serial.println("ESPUIclient:SendControlsToClient: Build Controls."); // ESPU_DBGL("ESPUIclient:SendControlsToClient: Build Controls.");
if(prepareJSONChunk(startidx, document, ClientUpdateType_t::UpdateNeeded == TransferMode, FragmentRequest)) if(prepareJSONChunk(startidx, document, ClientUpdateType_t::UpdateNeeded == TransferMode, FragmentRequest))
{ {
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity >= Verbosity::VerboseJSON) if (ESPUI.verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(F("ESPUIclient:SendControlsToClient: Sending elements --------->")); ESPU_DBGL(F("ESPUIclient:SendControlsToClient: Sending elements --------->"));
serializeJson(document, Serial); serializeJson(document, Serial);
Serial.println(); ESPU_DBGL();
} }
#endif #endif
// Serial.println("ESPUIclient:SendControlsToClient: Send message."); // ESPU_DBGL("ESPUIclient:SendControlsToClient: Send message.");
if(true == SendJsonDocToWebSocket(document)) if(true == SendJsonDocToWebSocket(document))
{ {
// Serial.println("ESPUIclient:SendControlsToClient: Sent."); // ESPU_DBGL("ESPUIclient:SendControlsToClient: Sent.");
} }
else else
{ {
// Serial.println("ESPUIclient:SendControlsToClient: Send failed."); // ESPU_DBGL("ESPUIclient:SendControlsToClient: Send failed.");
} }
} }
else else
{ {
// Serial.println("ESPUIclient:SendControlsToClient: No elements to send."); // ESPU_DBGL("ESPUIclient:SendControlsToClient: No elements to send.");
Response = true; Response = true;
} }
} while(false); } while(false);
// Serial.println(String("ESPUIclient:SendControlsToClient:Response: ") + String(Response)); // ESPU_DBGL(String("ESPUIclient:SendControlsToClient:Response: ") + String(Response));
return Response; return Response;
} }
@ -532,10 +541,10 @@ bool ESPUIclient::SendJsonDocToWebSocket(DynamicJsonDocument& document)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity >= Verbosity::VerboseJSON) if (ESPUI.verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(F("ESPUIclient::SendJsonDocToWebSocket: Cannot Send to client. Not sending websocket message")); ESPU_DBGL(F("ESPUIclient::SendJsonDocToWebSocket: Cannot Send to client. Not sending websocket message"));
} }
#endif #endif
// Serial.println("ESPUIclient::SendJsonDocToWebSocket: Cannot Send to client. Not sending websocket message"); // ESPU_DBGL("ESPUIclient::SendJsonDocToWebSocket: Cannot Send to client. Not sending websocket message");
Response = false; Response = false;
break; break;
} }
@ -545,17 +554,17 @@ bool ESPUIclient::SendJsonDocToWebSocket(DynamicJsonDocument& document)
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity >= Verbosity::VerboseJSON) if (ESPUI.verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(String(F("ESPUIclient::SendJsonDocToWebSocket: json: '")) + json + "'"); ESPU_DBGL(String(F("ESPUIclient::SendJsonDocToWebSocket: json: '")) + json + "'");
} }
#endif #endif
#if defined(DEBUG_ESPUI) #if defined(DEBUG_ESPUI)
if (ESPUI.verbosity >= Verbosity::VerboseJSON) if (ESPUI.verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(F("ESPUIclient::SendJsonDocToWebSocket: client.text")); ESPU_DBGL(F("ESPUIclient::SendJsonDocToWebSocket: client.text"));
} }
#endif #endif
// Serial.println(F("ESPUIclient::SendJsonDocToWebSocket: client.text")); // ESPU_DBGL(F("ESPUIclient::SendJsonDocToWebSocket: client.text"));
client->text(json); client->text(json);
} while (false); } while (false);