mirror of
https://github.com/s00500/ESPUI.git
synced 2025-07-02 23:30:17 +00:00
Compare commits
23 Commits
Author | SHA1 | Date | |
---|---|---|---|
679a3b5a8d
|
|||
f8fbcf887a
|
|||
fd1cc14e87
|
|||
372157b980 | |||
f08cd5c51a
|
|||
b45f4f7356 | |||
c3bf9c5d00 | |||
678a2ccf53 | |||
270f0dd16b | |||
be8cf73d55 | |||
cc69f8a469 | |||
48e947287a | |||
5cf0ce6afa | |||
35c2f5b6b1 | |||
b1b9fd2c79 | |||
0aaca5449b | |||
7b4ec5920a | |||
048f337d61 | |||
8e3c12935e | |||
f35d3a19d4 | |||
48594de29a | |||
d53fdb57a9 | |||
b8079cfb63 |
@ -495,7 +495,7 @@ ESPUI includes a range of advanced features that can customise your UIs.
|
||||
|
||||
### Dynamic Visibility
|
||||
|
||||
Cotrols can be made visible or invisible at runtime with the `updateVisibility()` function.
|
||||
Controls can be made visible or invisible at runtime with the `updateVisibility()` function.
|
||||
|
||||
```
|
||||
ESPUI.updateVisibility(controlId, false);
|
||||
|
2
data/css/normalize.css
vendored
2
data/css/normalize.css
vendored
@ -111,7 +111,7 @@
|
||||
}
|
||||
|
||||
svg:not(:root) {
|
||||
overflow: hidden;
|
||||
overflow: visible;
|
||||
}
|
||||
|
||||
/* Grouping content
|
||||
|
2
data/css/normalize.min.css
vendored
2
data/css/normalize.min.css
vendored
@ -1 +1 @@
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:visible}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
14
data/js/controls.js
vendored
14
data/js/controls.js
vendored
@ -176,7 +176,8 @@ function restoreGraphData(id) {
|
||||
var savedData = localStorage.getItem("espuigraphs", graphData);
|
||||
if (savedData != null) {
|
||||
savedData = JSON.parse(savedData);
|
||||
return savedData[id];
|
||||
let idData = savedData[id];
|
||||
return Array.isArray(idData) ? idData : [];
|
||||
}
|
||||
return [];
|
||||
}
|
||||
@ -488,9 +489,12 @@ function start() {
|
||||
|
||||
case UI_STEP:
|
||||
if (data.parentControl) {
|
||||
var parent = $("#id" + data.parentControl + " input");
|
||||
if (parent.size()) {
|
||||
parent.attr("step", data.value);
|
||||
//Is it applied to a slider?
|
||||
if ($('#sl' + data.parentControl).length) {
|
||||
$('#sl' + data.parentControl).attr("step", data.value);
|
||||
} else if ($('#num' + data.parentControl).length) {
|
||||
//Or a number
|
||||
$('#num' + data.parentControl).attr("step", data.value);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -503,7 +507,7 @@ function start() {
|
||||
}
|
||||
break;
|
||||
case ADD_GRAPH_POINT:
|
||||
var ts = Math.round(new Date().getTime() / 1000);
|
||||
var ts = new Date().getTime();
|
||||
graphData[data.id].push({ x: ts, y: data.value });
|
||||
saveGraphData();
|
||||
renderGraphSvg(graphData[data.id], "graph" + data.id);
|
||||
|
212
data/js/controls.min.js
vendored
212
data/js/controls.min.js
vendored
@ -1,107 +1,107 @@
|
||||
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(){}
|
||||
function saveGraphData(){localStorage.setItem("espuigraphs",JSON.stringify(graphData));}
|
||||
function restoreGraphData(id){var savedData=localStorage.getItem("espuigraphs",graphData);if(savedData!=null){savedData=JSON.parse(savedData);return savedData[id];}
|
||||
return[];}
|
||||
function restart(){$(document).add("*").off();$("#row").html("");conStatusError();start();}
|
||||
function conStatusError(){if(true===websockConnected){websockConnected=false;websock.close();$("#conStatus").removeClass("color-green");$("#conStatus").addClass("color-red");$("#conStatus").html("Error / No Connection ↻");$("#conStatus").off();$("#conStatus").on({click:restart,});}}
|
||||
function handleVisibilityChange(){if(!websockConnected&&!document.hidden){restart();}}
|
||||
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);}
|
||||
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;}
|
||||
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));}
|
||||
break;case UI_EXTEND_GUI:data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});if(data.totalcontrols>data.startindex+(data.controls.length-1)){websock.send("uiok:"+(data.startindex+(data.controls.length-1)));}
|
||||
break;case UI_RELOAD:window.location.reload();break;case UI_TITEL:document.title=data.label;$("#mainHeader").html(data.label);break;case UI_LABEL:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GAUGE:case UI_SEPARATOR:if(data.visible)addToHTML(data);break;case UI_BUTTON:if(data.visible){addToHTML(data);$("#btn"+data.id).on({touchstart:function(e){e.preventDefault();buttonclick(data.id,true);},touchend:function(e){e.preventDefault();buttonclick(data.id,false);},});}
|
||||
break;case UI_SWITCHER:if(data.visible){addToHTML(data);switcher(data.id,data.value);}
|
||||
break;case UI_CPAD:case UI_PAD:if(data.visible){addToHTML(data);$("#pf"+data.id).on({touchstart:function(e){e.preventDefault();padclick(UP,data.id,true);},touchend:function(e){e.preventDefault();padclick(UP,data.id,false);},});$("#pl"+data.id).on({touchstart:function(e){e.preventDefault();padclick(LEFT,data.id,true);},touchend:function(e){e.preventDefault();padclick(LEFT,data.id,false);},});$("#pr"+data.id).on({touchstart:function(e){e.preventDefault();padclick(RIGHT,data.id,true);},touchend:function(e){e.preventDefault();padclick(RIGHT,data.id,false);},});$("#pb"+data.id).on({touchstart:function(e){e.preventDefault();padclick(DOWN,data.id,true);},touchend:function(e){e.preventDefault();padclick(DOWN,data.id,false);},});$("#pc"+data.id).on({touchstart:function(e){e.preventDefault();padclick(CENTER,data.id,true);},touchend:function(e){e.preventDefault();padclick(CENTER,data.id,false);},});}
|
||||
break;case UI_SLIDER:if(data.visible){addToHTML(data);rangeSlider(!sliderContinuous);}
|
||||
break;case UI_TAB:if(data.visible){$("#tabsnav").append("<li><a onmouseup='tabclick("+data.id+")' href='#tab"+data.id+"'>"+data.value+"</a></li>");$("#tabscontent").append("<div id='tab"+data.id+"'></div>");tabs=$(".tabscontent").tabbedContent({loop:true}).data("api");$("a").filter(function(){return $(this).attr("href")==="#click-to-switch";}).on("click",function(e){var tab=prompt("Tab to switch to (number or id)?");if(!tabs.switchTab(tab)){alert("That tab does not exist :\\");}
|
||||
e.preventDefault();});}
|
||||
break;case UI_OPTION:if(data.parentControl){var parent=$("#select"+data.parentControl);parent.append("<option id='option"+
|
||||
data.id+
|
||||
"' value='"+
|
||||
data.value+
|
||||
"' "+
|
||||
data.selected+
|
||||
">"+
|
||||
data.label+
|
||||
"</option>");}
|
||||
break;case UI_MIN:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("min",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("min",data.value);}}
|
||||
break;case UI_MAX:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("max",data.value);}else if($('#text'+data.parentControl).length){$('#text'+data.parentControl).attr("maxlength",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("max",data.value);}}
|
||||
break;case UI_STEP:if(data.parentControl){var parent=$("#id"+data.parentControl+" input");if(parent.size()){parent.attr("step",data.value);}}
|
||||
break;case UI_GRAPH:if(data.visible){addToHTML(data);graphData[data.id]=restoreGraphData(data.id);renderGraphSvg(graphData[data.id],"graph"+data.id);}
|
||||
break;case ADD_GRAPH_POINT:var ts=Math.round(new Date().getTime()/1000);graphData[data.id].push({x:ts,y:data.value});saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case CLEAR_GRAPH:graphData[data.id]=[];saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case UI_ACCEL:if(hasAccel)break;hasAccel=true;if(data.visible){addToHTML(data);requestOrientationPermission();}
|
||||
break;case UPDATE_LABEL:$("#l"+data.id).html(data.value);if(data.hasOwnProperty('elementStyle')){$("#l"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_SWITCHER:switcher(data.id,data.value=="0"?0:1);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_SLIDER:$("#sl"+data.id).attr("value",data.value)
|
||||
slider_move($("#sl"+data.id).parent().parent(),data.value,"100",false);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_NUMBER:$("#num"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#num"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_TEXT_INPUT:$("#text"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#text"+data.id).attr("style",data.elementStyle);}
|
||||
if(data.hasOwnProperty('inputType')){$("#text"+data.id).attr("type",data.inputType);}
|
||||
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_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;default:console.error("Unknown type or event");break;}
|
||||
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.hasOwnProperty('visible')){if(data['visible'])
|
||||
$("#id"+data.id).show();else
|
||||
$("#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));}
|
||||
processEnabled(data);}
|
||||
$(".range-slider__range").each(function(){$(this)[0].value=$(this).attr("value");$(this).next().html($(this).attr("value"));});};websock.onmessage=handleEvent;}
|
||||
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 textchange(number){var val=$("#text"+number).val();websock.send("tvalue:"+val+":"+number);}
|
||||
function tabclick(number){var val=$("#tab"+number).val();websock.send("tabvalue:"+val+":"+number);}
|
||||
function selectchange(number){var val=$("#select"+number).val();websock.send("svalue:"+val+":"+number);}
|
||||
function buttonclick(number,isdown){if(isdown)websock.send("bdown:"+number);else websock.send("bup:"+number);}
|
||||
function padclick(type,number,isdown){if($("#id"+number+" nav").hasClass("disabled")){return;}
|
||||
switch(type){case CENTER:if(isdown)websock.send("pcdown:"+number);else websock.send("pcup:"+number);break;case UP:if(isdown)websock.send("pfdown:"+number);else websock.send("pfup:"+number);break;case DOWN:if(isdown)websock.send("pbdown:"+number);else websock.send("pbup:"+number);break;case LEFT:if(isdown)websock.send("pldown:"+number);else websock.send("plup:"+number);break;case RIGHT:if(isdown)websock.send("prdown:"+number);else websock.send("prup:"+number);break;}}
|
||||
function switcher(number,state){if(state==null){if(!$("#sl"+number).hasClass("checked")){websock.send("sactive:"+number);$("#sl"+number).addClass("checked");}else{websock.send("sinactive:"+number);$("#sl"+number).removeClass("checked");}}else if(state==1){$("#sl"+number).addClass("checked");$("#sl"+number).prop("checked",true);}else if(state==0){$("#sl"+number).removeClass("checked");$("#sl"+number).prop("checked",false);}}
|
||||
var rangeSlider=function(isDiscrete){var range=$(".range-slider__range");var slidercb=function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));};range.on({input:function(){$(this).next().html(this.value)}});range.each(function(){$(this).next().html(this.value);if($(this).attr("callbackSet")!="true"){if(!isDiscrete){$(this).on({input:slidercb});}else{$(this).on({change:slidercb});}
|
||||
$(this).attr("callbackSet","true");}});};var addToHTML=function(data){panelStyle=data.hasOwnProperty('panelStyle')?" style='"+data.panelStyle+"' ":"";panelwide=data.hasOwnProperty('wide')?"wide":"";if(!data.hasOwnProperty('parentControl')||$("#tab"+data.parentControl).length>0){var parent=data.hasOwnProperty('parentControl')?$("#tab"+data.parentControl):$("#row");var html="";switch(data.type){case UI_LABEL:case UI_BUTTON:case UI_SWITCHER:case UI_CPAD:case UI_PAD:case UI_SLIDER:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GRAPH:case UI_GAUGE:case UI_ACCEL:html="<div id='id"+data.id+"' "+panelStyle+" class='two columns "+panelwide+" card tcenter "+
|
||||
colorClass(data.color)+"'><h5>"+data.label+"</h5><hr/>"+
|
||||
elementHTML(data)+
|
||||
"</div>";break;case UI_SEPARATOR:html="<div id='id"+data.id+"' "+panelStyle+" class='sectionbreak columns'>"+
|
||||
"<h5>"+data.label+"</h5><hr/></div>";break;case UI_TIME:break;}
|
||||
parent.append(html);}else{var parent=$("#id"+data.parentControl);parent.append(elementHTML(data));}}
|
||||
var elementHTML=function(data){var id=data.id
|
||||
var elementStyle=data.hasOwnProperty('elementStyle')?" style='"+data.elementStyle+"' ":"";var inputType=data.hasOwnProperty('inputType')?" type='"+data.inputType+"' ":"";switch(data.type){case UI_LABEL:return"<span id='l"+id+"' "+elementStyle+
|
||||
" class='label label-wrap'>"+data.value+"</span>";case UI_BUTTON:return"<button id='btn"+id+"' "+elementStyle+
|
||||
" onmousedown='buttonclick("+id+", true)'"+
|
||||
" onmouseup='buttonclick("+id+", false)'>"+
|
||||
data.value+"</button>";case UI_SWITCHER:return"<label id='sl"+id+"' "+elementStyle+
|
||||
" class='switch "+(data.value=="1"?"checked":"")+
|
||||
(data.hasOwnProperty('vertical')?" vert-switcher ":"")+
|
||||
"'>"+
|
||||
"<div class='in'>"+
|
||||
"<input type='checkbox' id='s"+id+"' onClick='switcher("+id+",null)' "+
|
||||
(data.value=="1"?"checked":"")+"/></div></label>";case UI_CPAD:case UI_PAD:return"<nav class='control'><ul>"+
|
||||
"<li><a onmousedown='padclick(UP, "+id+", true)' "+
|
||||
"onmouseup='padclick(UP, "+id+", false)' id='pf"+id+"'>▲</a></li>"+
|
||||
"<li><a onmousedown='padclick(RIGHT, "+id+", true)' "+
|
||||
"onmouseup='padclick(RIGHT, "+id+", false)' id='pr"+id+"'>▲</a></li>"+
|
||||
"<li><a onmousedown='padclick(LEFT, "+id+", true)' "+
|
||||
"onmouseup='padclick(LEFT, "+id+", false)' id='pl"+id+"'>▲</a></li>"+
|
||||
"<li><a onmousedown='padclick(DOWN, "+id+", true)' "+
|
||||
"onmouseup='padclick(DOWN, "+id+", false)' id='pb"+id+"'>▲</a></li>"+
|
||||
"</ul>"+
|
||||
(data.type==UI_CPAD?"<a class='confirm' onmousedown='padclick(CENTER,"+id+", true)' "+
|
||||
"onmouseup='padclick(CENTER, "+id+", false)' id='pc"+id+"'>OK</a>":"")+
|
||||
"</nav>";case UI_SLIDER:return"<div class='range-slider "+
|
||||
(data.hasOwnProperty('vertical')?" vert-slider ":"")+
|
||||
"'>"+
|
||||
"<input id='sl"+id+"' type='range' min='0' max='100' value='"+data.value+"' "+
|
||||
elementStyle+" class='range-slider__range'><span class='range-slider__value'>"+
|
||||
data.value+"</span></div>";case UI_NUMBER:return"<input style='color:black; "+data.elementStyle+"' id='num"+id+
|
||||
"' type='number' value='"+data.value+"' onchange='numberchange("+id+")' />";case UI_TEXT_INPUT:return"<input "+inputType+"style='color:black; "+data.elementStyle+"' id='text"+id+
|
||||
"' value='"+data.value+"' onchange='textchange("+id+")' />";case UI_SELECT:return"<select style='color:black; "+data.elementStyle+"' id='select"+id+
|
||||
"' onchange='selectchange("+id+")' />";case UI_GRAPH:return"<figure id='graph"+id+"'><figcaption>"+data.label+"</figcaption></figure>";case UI_GAUGE:return"WILL BE A GAUGE <input style='color:black;' id='gauge"+id+
|
||||
"' type='number' value='"+data.value+"' onchange='numberchange("+id+")' />";case UI_ACCEL:return"ACCEL // Not implemented fully!<div class='accelerometer' id='accel"+id+
|
||||
"' ><div class='ball"+id+"'></div><pre class='accelerometeroutput"+id+"'></pre>";default:return"";}}
|
||||
var processEnabled=function(data){switch(data.type){case UI_SWITCHER:case UPDATE_SWITCHER:if(data.enabled){$("#sl"+data.id).removeClass('disabled');$("#s"+data.id).prop("disabled",false);}else{$("#sl"+data.id).addClass('disabled');$("#s"+data.id).prop("disabled",true);}
|
||||
break;case UI_SLIDER:case UPDATE_SLIDER:$("#sl"+data.id).prop("disabled",!data.enabled);break;case UI_NUMBER:case UPDATE_NUMBER:$("#num"+data.id).prop("disabled",!data.enabled);break;case UI_TEXT_INPUT:case UPDATE_TEXT_INPUT:$("#text"+data.id).prop("disabled",!data.enabled);break;case UI_SELECT:case UPDATE_SELECT:$("#select"+data.id).prop("disabled",!data.enabled);break;case UI_BUTTON:case UPDATE_BUTTON:$("#btn"+data.id).prop("disabled",!data.enabled);break;case UI_PAD:case UI_CPAD:case UPDATE_PAD:case UPDATE_CPAD:if(data.enabled){$("#id"+data.id+" nav").removeClass('disabled');}else{$("#id"+data.id+" nav").addClass('disabled');}
|
||||
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(){}
|
||||
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:[];}
|
||||
return[];}
|
||||
function restart(){$(document).add("*").off();$("#row").html("");conStatusError();start();}
|
||||
function conStatusError(){if(true===websockConnected){websockConnected=false;websock.close();$("#conStatus").removeClass("color-green");$("#conStatus").addClass("color-red");$("#conStatus").html("Error / No Connection ↻");$("#conStatus").off();$("#conStatus").on({click:restart,});}}
|
||||
function handleVisibilityChange(){if(!websockConnected&&!document.hidden){restart();}}
|
||||
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);}
|
||||
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;}
|
||||
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));}
|
||||
break;case UI_EXTEND_GUI:data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});if(data.totalcontrols>data.startindex+(data.controls.length-1)){websock.send("uiok:"+(data.startindex+(data.controls.length-1)));}
|
||||
break;case UI_RELOAD:window.location.reload();break;case UI_TITEL:document.title=data.label;$("#mainHeader").html(data.label);break;case UI_LABEL:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GAUGE:case UI_SEPARATOR:if(data.visible)addToHTML(data);break;case UI_BUTTON:if(data.visible){addToHTML(data);$("#btn"+data.id).on({touchstart:function(e){e.preventDefault();buttonclick(data.id,true);},touchend:function(e){e.preventDefault();buttonclick(data.id,false);},});}
|
||||
break;case UI_SWITCHER:if(data.visible){addToHTML(data);switcher(data.id,data.value);}
|
||||
break;case UI_CPAD:case UI_PAD:if(data.visible){addToHTML(data);$("#pf"+data.id).on({touchstart:function(e){e.preventDefault();padclick(UP,data.id,true);},touchend:function(e){e.preventDefault();padclick(UP,data.id,false);},});$("#pl"+data.id).on({touchstart:function(e){e.preventDefault();padclick(LEFT,data.id,true);},touchend:function(e){e.preventDefault();padclick(LEFT,data.id,false);},});$("#pr"+data.id).on({touchstart:function(e){e.preventDefault();padclick(RIGHT,data.id,true);},touchend:function(e){e.preventDefault();padclick(RIGHT,data.id,false);},});$("#pb"+data.id).on({touchstart:function(e){e.preventDefault();padclick(DOWN,data.id,true);},touchend:function(e){e.preventDefault();padclick(DOWN,data.id,false);},});$("#pc"+data.id).on({touchstart:function(e){e.preventDefault();padclick(CENTER,data.id,true);},touchend:function(e){e.preventDefault();padclick(CENTER,data.id,false);},});}
|
||||
break;case UI_SLIDER:if(data.visible){addToHTML(data);rangeSlider(!sliderContinuous);}
|
||||
break;case UI_TAB:if(data.visible){$("#tabsnav").append("<li><a onmouseup='tabclick("+data.id+")' href='#tab"+data.id+"'>"+data.value+"</a></li>");$("#tabscontent").append("<div id='tab"+data.id+"'></div>");tabs=$(".tabscontent").tabbedContent({loop:true}).data("api");$("a").filter(function(){return $(this).attr("href")==="#click-to-switch";}).on("click",function(e){var tab=prompt("Tab to switch to (number or id)?");if(!tabs.switchTab(tab)){alert("That tab does not exist :\\");}
|
||||
e.preventDefault();});}
|
||||
break;case UI_OPTION:if(data.parentControl){var parent=$("#select"+data.parentControl);parent.append("<option id='option"+
|
||||
data.id+
|
||||
"' value='"+
|
||||
data.value+
|
||||
"' "+
|
||||
data.selected+
|
||||
">"+
|
||||
data.label+
|
||||
"</option>");}
|
||||
break;case UI_MIN:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("min",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("min",data.value);}}
|
||||
break;case UI_MAX:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("max",data.value);}else if($('#text'+data.parentControl).length){$('#text'+data.parentControl).attr("maxlength",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("max",data.value);}}
|
||||
break;case UI_STEP:if(data.parentControl){if($('#sl'+data.parentControl).length){$('#sl'+data.parentControl).attr("step",data.value);}else if($('#num'+data.parentControl).length){$('#num'+data.parentControl).attr("step",data.value);}}
|
||||
break;case UI_GRAPH:if(data.visible){addToHTML(data);graphData[data.id]=restoreGraphData(data.id);renderGraphSvg(graphData[data.id],"graph"+data.id);}
|
||||
break;case ADD_GRAPH_POINT:var ts=new Date().getTime();graphData[data.id].push({x:ts,y:data.value});saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case CLEAR_GRAPH:graphData[data.id]=[];saveGraphData();renderGraphSvg(graphData[data.id],"graph"+data.id);break;case UI_ACCEL:if(hasAccel)break;hasAccel=true;if(data.visible){addToHTML(data);requestOrientationPermission();}
|
||||
break;case UPDATE_LABEL:$("#l"+data.id).html(data.value);if(data.hasOwnProperty('elementStyle')){$("#l"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_SWITCHER:switcher(data.id,data.value=="0"?0:1);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_SLIDER:$("#sl"+data.id).attr("value",data.value)
|
||||
slider_move($("#sl"+data.id).parent().parent(),data.value,"100",false);if(data.hasOwnProperty('elementStyle')){$("#sl"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_NUMBER:$("#num"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#num"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_TEXT_INPUT:$("#text"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#text"+data.id).attr("style",data.elementStyle);}
|
||||
if(data.hasOwnProperty('inputType')){$("#text"+data.id).attr("type",data.inputType);}
|
||||
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_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;default:console.error("Unknown type or event");break;}
|
||||
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.hasOwnProperty('visible')){if(data['visible'])
|
||||
$("#id"+data.id).show();else
|
||||
$("#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));}
|
||||
processEnabled(data);}
|
||||
$(".range-slider__range").each(function(){$(this)[0].value=$(this).attr("value");$(this).next().html($(this).attr("value"));});};websock.onmessage=handleEvent;}
|
||||
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 textchange(number){var val=$("#text"+number).val();websock.send("tvalue:"+val+":"+number);}
|
||||
function tabclick(number){var val=$("#tab"+number).val();websock.send("tabvalue:"+val+":"+number);}
|
||||
function selectchange(number){var val=$("#select"+number).val();websock.send("svalue:"+val+":"+number);}
|
||||
function buttonclick(number,isdown){if(isdown)websock.send("bdown:"+number);else websock.send("bup:"+number);}
|
||||
function padclick(type,number,isdown){if($("#id"+number+" nav").hasClass("disabled")){return;}
|
||||
switch(type){case CENTER:if(isdown)websock.send("pcdown:"+number);else websock.send("pcup:"+number);break;case UP:if(isdown)websock.send("pfdown:"+number);else websock.send("pfup:"+number);break;case DOWN:if(isdown)websock.send("pbdown:"+number);else websock.send("pbup:"+number);break;case LEFT:if(isdown)websock.send("pldown:"+number);else websock.send("plup:"+number);break;case RIGHT:if(isdown)websock.send("prdown:"+number);else websock.send("prup:"+number);break;}}
|
||||
function switcher(number,state){if(state==null){if(!$("#sl"+number).hasClass("checked")){websock.send("sactive:"+number);$("#sl"+number).addClass("checked");}else{websock.send("sinactive:"+number);$("#sl"+number).removeClass("checked");}}else if(state==1){$("#sl"+number).addClass("checked");$("#sl"+number).prop("checked",true);}else if(state==0){$("#sl"+number).removeClass("checked");$("#sl"+number).prop("checked",false);}}
|
||||
var rangeSlider=function(isDiscrete){var range=$(".range-slider__range");var slidercb=function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));};range.on({input:function(){$(this).next().html(this.value)}});range.each(function(){$(this).next().html(this.value);if($(this).attr("callbackSet")!="true"){if(!isDiscrete){$(this).on({input:slidercb});}else{$(this).on({change:slidercb});}
|
||||
$(this).attr("callbackSet","true");}});};var addToHTML=function(data){panelStyle=data.hasOwnProperty('panelStyle')?" style='"+data.panelStyle+"' ":"";panelwide=data.hasOwnProperty('wide')?"wide":"";if(!data.hasOwnProperty('parentControl')||$("#tab"+data.parentControl).length>0){var parent=data.hasOwnProperty('parentControl')?$("#tab"+data.parentControl):$("#row");var html="";switch(data.type){case UI_LABEL:case UI_BUTTON:case UI_SWITCHER:case UI_CPAD:case UI_PAD:case UI_SLIDER:case UI_NUMBER:case UI_TEXT_INPUT:case UI_SELECT:case UI_GRAPH:case UI_GAUGE:case UI_ACCEL:html="<div id='id"+data.id+"' "+panelStyle+" class='two columns "+panelwide+" card tcenter "+
|
||||
colorClass(data.color)+"'><h5>"+data.label+"</h5><hr/>"+
|
||||
elementHTML(data)+
|
||||
"</div>";break;case UI_SEPARATOR:html="<div id='id"+data.id+"' "+panelStyle+" class='sectionbreak columns'>"+
|
||||
"<h5>"+data.label+"</h5><hr/></div>";break;case UI_TIME:break;}
|
||||
parent.append(html);}else{var parent=$("#id"+data.parentControl);parent.append(elementHTML(data));}}
|
||||
var elementHTML=function(data){var id=data.id
|
||||
var elementStyle=data.hasOwnProperty('elementStyle')?" style='"+data.elementStyle+"' ":"";var inputType=data.hasOwnProperty('inputType')?" type='"+data.inputType+"' ":"";switch(data.type){case UI_LABEL:return"<span id='l"+id+"' "+elementStyle+
|
||||
" class='label label-wrap'>"+data.value+"</span>";case UI_BUTTON:return"<button id='btn"+id+"' "+elementStyle+
|
||||
" onmousedown='buttonclick("+id+", true)'"+
|
||||
" onmouseup='buttonclick("+id+", false)'>"+
|
||||
data.value+"</button>";case UI_SWITCHER:return"<label id='sl"+id+"' "+elementStyle+
|
||||
" class='switch "+(data.value=="1"?"checked":"")+
|
||||
(data.hasOwnProperty('vertical')?" vert-switcher ":"")+
|
||||
"'>"+
|
||||
"<div class='in'>"+
|
||||
"<input type='checkbox' id='s"+id+"' onClick='switcher("+id+",null)' "+
|
||||
(data.value=="1"?"checked":"")+"/></div></label>";case UI_CPAD:case UI_PAD:return"<nav class='control'><ul>"+
|
||||
"<li><a onmousedown='padclick(UP, "+id+", true)' "+
|
||||
"onmouseup='padclick(UP, "+id+", false)' id='pf"+id+"'>▲</a></li>"+
|
||||
"<li><a onmousedown='padclick(RIGHT, "+id+", true)' "+
|
||||
"onmouseup='padclick(RIGHT, "+id+", false)' id='pr"+id+"'>▲</a></li>"+
|
||||
"<li><a onmousedown='padclick(LEFT, "+id+", true)' "+
|
||||
"onmouseup='padclick(LEFT, "+id+", false)' id='pl"+id+"'>▲</a></li>"+
|
||||
"<li><a onmousedown='padclick(DOWN, "+id+", true)' "+
|
||||
"onmouseup='padclick(DOWN, "+id+", false)' id='pb"+id+"'>▲</a></li>"+
|
||||
"</ul>"+
|
||||
(data.type==UI_CPAD?"<a class='confirm' onmousedown='padclick(CENTER,"+id+", true)' "+
|
||||
"onmouseup='padclick(CENTER, "+id+", false)' id='pc"+id+"'>OK</a>":"")+
|
||||
"</nav>";case UI_SLIDER:return"<div class='range-slider "+
|
||||
(data.hasOwnProperty('vertical')?" vert-slider ":"")+
|
||||
"'>"+
|
||||
"<input id='sl"+id+"' type='range' min='0' max='100' value='"+data.value+"' "+
|
||||
elementStyle+" class='range-slider__range'><span class='range-slider__value'>"+
|
||||
data.value+"</span></div>";case UI_NUMBER:return"<input style='color:black; "+data.elementStyle+"' id='num"+id+
|
||||
"' type='number' value='"+data.value+"' onchange='numberchange("+id+")' />";case UI_TEXT_INPUT:return"<input "+inputType+"style='color:black; "+data.elementStyle+"' id='text"+id+
|
||||
"' value='"+data.value+"' onchange='textchange("+id+")' />";case UI_SELECT:return"<select style='color:black; "+data.elementStyle+"' id='select"+id+
|
||||
"' onchange='selectchange("+id+")' />";case UI_GRAPH:return"<figure id='graph"+id+"'><figcaption>"+data.label+"</figcaption></figure>";case UI_GAUGE:return"WILL BE A GAUGE <input style='color:black;' id='gauge"+id+
|
||||
"' type='number' value='"+data.value+"' onchange='numberchange("+id+")' />";case UI_ACCEL:return"ACCEL // Not implemented fully!<div class='accelerometer' id='accel"+id+
|
||||
"' ><div class='ball"+id+"'></div><pre class='accelerometeroutput"+id+"'></pre>";default:return"";}}
|
||||
var processEnabled=function(data){switch(data.type){case UI_SWITCHER:case UPDATE_SWITCHER:if(data.enabled){$("#sl"+data.id).removeClass('disabled');$("#s"+data.id).prop("disabled",false);}else{$("#sl"+data.id).addClass('disabled');$("#s"+data.id).prop("disabled",true);}
|
||||
break;case UI_SLIDER:case UPDATE_SLIDER:$("#sl"+data.id).prop("disabled",!data.enabled);break;case UI_NUMBER:case UPDATE_NUMBER:$("#num"+data.id).prop("disabled",!data.enabled);break;case UI_TEXT_INPUT:case UPDATE_TEXT_INPUT:$("#text"+data.id).prop("disabled",!data.enabled);break;case UI_SELECT:case UPDATE_SELECT:$("#select"+data.id).prop("disabled",!data.enabled);break;case UI_BUTTON:case UPDATE_BUTTON:$("#btn"+data.id).prop("disabled",!data.enabled);break;case UI_PAD:case UI_CPAD:case UPDATE_PAD:case UPDATE_CPAD:if(data.enabled){$("#id"+data.id+" nav").removeClass('disabled');}else{$("#id"+data.id+" nav").addClass('disabled');}
|
||||
break;}}
|
@ -55,13 +55,13 @@ function lineGraph(parent, xAccessor, yAccessor) {
|
||||
|
||||
// generate labels
|
||||
for (var i = xMin; i <= xMax; i++) {
|
||||
if ((i - xMin) % pixelsPerTick === 0 && i !== xMin) {
|
||||
if ((i - xMin) % (pixelsPerTick*3) === 0 && i !== xMin) {
|
||||
var text = document.createElementNS(
|
||||
"http://www.w3.org/2000/svg",
|
||||
"text"
|
||||
);
|
||||
// primitive formatting
|
||||
text.innerHTML = Math.floor(transform(i));
|
||||
text.innerHTML = new Date(Math.floor(transform(i))).toLocaleTimeString();
|
||||
text.setAttribute("x", i);
|
||||
text.setAttribute("y", yMin);
|
||||
// offset the text by 1 em
|
||||
|
28
data/js/graph.min.js
vendored
28
data/js/graph.min.js
vendored
@ -1,15 +1,15 @@
|
||||
function lineGraph(parent,xAccessor,yAccessor){const width=620;const height=420;const gutter=40;const pixelsPerTick=30;function numericTransformer(dataMin,dataMax,pxMin,pxMax){var dataDiff=dataMax-dataMin,pxDiff=pxMax-pxMin,dataRatio=pxDiff/dataDiff,coordRatio=dataDiff/pxDiff;return{toCoord:function(data){return(data-dataMin)*dataRatio+pxMin;},toData:function(coord){return(coord-pxMin)*coordRatio+dataMin;}};}
|
||||
function axisRenderer(orientation,transform){var axisGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var axisPath=document.createElementNS("http://www.w3.org/2000/svg","path");axisGroup.setAttribute("class",orientation+"-axis");var xMin=gutter;var xMax=width-gutter;var yMin=height-gutter;var yMax=gutter;if(orientation==="x"){axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMax+" "+yMin);for(var i=xMin;i<=xMax;i++){if((i-xMin)%pixelsPerTick===0&&i!==xMin){var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",i);text.setAttribute("y",yMin);text.setAttribute("dy","1em");axisGroup.appendChild(text);}}}else{axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMin+" "+yMax);for(var i=yMax;i<=yMin;i++){if((i-yMin)%pixelsPerTick===0&&i!==yMin){var tickGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var gridLine=document.createElementNS("http://www.w3.org/2000/svg","path");text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",xMin);text.setAttribute("y",i);text.setAttribute("dx","-.5em");text.setAttribute("dy",".3em");gridLine.setAttribute("d","M "+xMin+" "+i+" L "+xMax+" "+i);tickGroup.appendChild(gridLine);tickGroup.appendChild(text);axisGroup.appendChild(tickGroup);}}}
|
||||
axisGroup.appendChild(axisPath);parent.appendChild(axisGroup);}
|
||||
function lineRenderer(xAccessor,yAccessor,xTransform,yTransform){var line=document.createElementNS("http://www.w3.org/2000/svg","path");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
var pathString="M "+xTransform(xAccessor.next())+" "+yTransform(yAccessor.next());while(xAccessor.hasNext()&&yAccessor.hasNext()){pathString+=" L "+
|
||||
xTransform(xAccessor.next())+
|
||||
" "+
|
||||
yTransform(yAccessor.next());}
|
||||
line.setAttribute("class","series");line.setAttribute("d",pathString);parent.appendChild(line);}
|
||||
function pointRenderer(xAccessor,yAccessor,xTransform,yTransform){var pointGroup=document.createElementNS("http://www.w3.org/2000/svg","g");pointGroup.setAttribute("class","data-points");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
while(xAccessor.hasNext()&&yAccessor.hasNext()){var xDataValue=xAccessor.next();var x=xTransform(xDataValue);var yDataValue=yAccessor.next();var y=yTransform(yDataValue);var circle=document.createElementNS("http://www.w3.org/2000/svg","circle");circle.setAttribute("cx",x);circle.setAttribute("cy",y);circle.setAttribute("r","4");var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(xDataValue)+" / "+Math.floor(yDataValue);text.setAttribute("x",x);text.setAttribute("y",y);text.setAttribute("dx","1em");text.setAttribute("dy","-.7em");pointGroup.appendChild(circle);pointGroup.appendChild(text);}
|
||||
parent.appendChild(pointGroup);}
|
||||
xTransform=numericTransformer(xAccessor.min(),xAccessor.max(),0+gutter,width-gutter);yTransform=numericTransformer(yAccessor.min(),yAccessor.max(),height-gutter,0+gutter);axisRenderer("x",xTransform.toData);axisRenderer("y",yTransform.toData);lineRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);pointRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);}
|
||||
function renderGraphSvg(dataArray,renderId){var figure=document.getElementById(renderId);while(figure.hasChildNodes()){figure.removeChild(figure.lastChild);}
|
||||
function lineGraph(parent,xAccessor,yAccessor){const width=620;const height=420;const gutter=40;const pixelsPerTick=30;function numericTransformer(dataMin,dataMax,pxMin,pxMax){var dataDiff=dataMax-dataMin,pxDiff=pxMax-pxMin,dataRatio=pxDiff/dataDiff,coordRatio=dataDiff/pxDiff;return{toCoord:function(data){return(data-dataMin)*dataRatio+pxMin;},toData:function(coord){return(coord-pxMin)*coordRatio+dataMin;}};}
|
||||
function axisRenderer(orientation,transform){var axisGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var axisPath=document.createElementNS("http://www.w3.org/2000/svg","path");axisGroup.setAttribute("class",orientation+"-axis");var xMin=gutter;var xMax=width-gutter;var yMin=height-gutter;var yMax=gutter;if(orientation==="x"){axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMax+" "+yMin);for(var i=xMin;i<=xMax;i++){if((i-xMin)%(pixelsPerTick*3)===0&&i!==xMin){var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=new Date(Math.floor(transform(i))).toLocaleTimeString();text.setAttribute("x",i);text.setAttribute("y",yMin);text.setAttribute("dy","1em");axisGroup.appendChild(text);}}}else{axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMin+" "+yMax);for(var i=yMax;i<=yMin;i++){if((i-yMin)%pixelsPerTick===0&&i!==yMin){var tickGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var gridLine=document.createElementNS("http://www.w3.org/2000/svg","path");text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",xMin);text.setAttribute("y",i);text.setAttribute("dx","-.5em");text.setAttribute("dy",".3em");gridLine.setAttribute("d","M "+xMin+" "+i+" L "+xMax+" "+i);tickGroup.appendChild(gridLine);tickGroup.appendChild(text);axisGroup.appendChild(tickGroup);}}}
|
||||
axisGroup.appendChild(axisPath);parent.appendChild(axisGroup);}
|
||||
function lineRenderer(xAccessor,yAccessor,xTransform,yTransform){var line=document.createElementNS("http://www.w3.org/2000/svg","path");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
var pathString="M "+xTransform(xAccessor.next())+" "+yTransform(yAccessor.next());while(xAccessor.hasNext()&&yAccessor.hasNext()){pathString+=" L "+
|
||||
xTransform(xAccessor.next())+
|
||||
" "+
|
||||
yTransform(yAccessor.next());}
|
||||
line.setAttribute("class","series");line.setAttribute("d",pathString);parent.appendChild(line);}
|
||||
function pointRenderer(xAccessor,yAccessor,xTransform,yTransform){var pointGroup=document.createElementNS("http://www.w3.org/2000/svg","g");pointGroup.setAttribute("class","data-points");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
while(xAccessor.hasNext()&&yAccessor.hasNext()){var xDataValue=xAccessor.next();var x=xTransform(xDataValue);var yDataValue=yAccessor.next();var y=yTransform(yDataValue);var circle=document.createElementNS("http://www.w3.org/2000/svg","circle");circle.setAttribute("cx",x);circle.setAttribute("cy",y);circle.setAttribute("r","4");var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(xDataValue)+" / "+Math.floor(yDataValue);text.setAttribute("x",x);text.setAttribute("y",y);text.setAttribute("dx","1em");text.setAttribute("dy","-.7em");pointGroup.appendChild(circle);pointGroup.appendChild(text);}
|
||||
parent.appendChild(pointGroup);}
|
||||
xTransform=numericTransformer(xAccessor.min(),xAccessor.max(),0+gutter,width-gutter);yTransform=numericTransformer(yAccessor.min(),yAccessor.max(),height-gutter,0+gutter);axisRenderer("x",xTransform.toData);axisRenderer("y",yTransform.toData);lineRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);pointRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);}
|
||||
function renderGraphSvg(dataArray,renderId){var figure=document.getElementById(renderId);while(figure.hasChildNodes()){figure.removeChild(figure.lastChild);}
|
||||
var svg=document.createElementNS("http://www.w3.org/2000/svg","svg");svg.setAttribute("viewBox","0 0 640 440");svg.setAttribute("preserveAspectRatio","xMidYMid meet");lineGraph(svg,(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].x;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.x;})),Math.max.apply(Math,dataArray.map(function(o){return o.x;}))),(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].y;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.y;})),Math.max.apply(Math,dataArray.map(function(o){return o.y;}))));figure.appendChild(svg);}
|
@ -26,8 +26,18 @@
|
||||
#include <WiFi.h>
|
||||
#include <ESPmDNS.h>
|
||||
#else
|
||||
// esp8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <ESP8266mDNS.h>
|
||||
#include <umm_malloc/umm_heap_select.h>
|
||||
#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 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
|
||||
#endif // MMU_IRAM_HEAP
|
||||
#ifndef DEBUG_ESP_OOM
|
||||
#error on ESP8266 and ESPUI, you must define OOM debug option when developping
|
||||
#endif
|
||||
#endif
|
||||
|
||||
//Settings
|
||||
@ -62,6 +72,11 @@ volatile bool updates = false;
|
||||
|
||||
// This is the main function which builds our GUI
|
||||
void setUpUI() {
|
||||
|
||||
#ifdef ESP8266
|
||||
{ HeapSelectIram doAllocationsInIRAM;
|
||||
#endif
|
||||
|
||||
//Turn off verbose debugging
|
||||
ESPUI.setVerbosity(Verbosity::Quiet);
|
||||
|
||||
@ -274,6 +289,11 @@ void setUpUI() {
|
||||
//Finally, start up the UI.
|
||||
//This should only be called once we are connected to WiFi.
|
||||
ESPUI.begin(HOSTNAME);
|
||||
|
||||
#ifdef ESP8266
|
||||
} // HeapSelectIram
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
//This callback generates and applies inline styles to a bunch of controls to change their colour.
|
||||
|
1
examples/completeExample/completeExample.ino
Normal file
1
examples/completeExample/completeExample.ino
Normal file
@ -0,0 +1 @@
|
||||
// placeholder
|
@ -8,7 +8,17 @@ DNSServer dnsServer;
|
||||
#if defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
// esp8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <umm_malloc/umm_heap_select.h>
|
||||
#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 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
|
||||
#endif // MMU_IRAM_HEAP
|
||||
#ifndef DEBUG_ESP_OOM
|
||||
#error on ESP8266 and ESPUI, you must define OOM debug option when developping
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const char* ssid = "ESPUI";
|
||||
@ -57,7 +67,7 @@ void buttonCallback(Control* sender, int type)
|
||||
|
||||
void buttonExample(Control* sender, int type, void* param)
|
||||
{
|
||||
Serial.println(String("param: ") + String(int(param)));
|
||||
Serial.println(String("param: ") + String(long(param)));
|
||||
switch (type)
|
||||
{
|
||||
case B_DOWN:
|
||||
@ -235,6 +245,10 @@ void setup(void)
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.getMode() == WIFI_AP ? WiFi.softAPIP() : WiFi.localIP());
|
||||
|
||||
#ifdef ESP8266
|
||||
{ HeapSelectIram doAllocationsInIRAM;
|
||||
#endif
|
||||
|
||||
status = ESPUI.addControl(ControlType::Label, "Status:", "Stop", ControlColor::Turquoise);
|
||||
|
||||
uint16_t select1 = ESPUI.addControl(
|
||||
@ -281,6 +295,10 @@ void setup(void)
|
||||
*/
|
||||
|
||||
ESPUI.begin("ESPUI Control");
|
||||
|
||||
#ifdef ESP8266
|
||||
} // HeapSelectIram
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
|
@ -8,7 +8,17 @@ DNSServer dnsServer;
|
||||
#if defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
// esp8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <umm_malloc/umm_heap_select.h>
|
||||
#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 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
|
||||
#endif // MMU_IRAM_HEAP
|
||||
#ifndef DEBUG_ESP_OOM
|
||||
#error on ESP8266 and ESPUI, you must define OOM debug option when developping
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const char* ssid = "ESPUI";
|
||||
@ -62,7 +72,7 @@ void buttonCallback(Control* sender, int type)
|
||||
|
||||
void buttonExample(Control* sender, int type, void* param)
|
||||
{
|
||||
Serial.println(String("param: ") + String(int(param)));
|
||||
Serial.println(String("param: ") + String(long(param)));
|
||||
switch (type)
|
||||
{
|
||||
case B_DOWN:
|
||||
@ -225,6 +235,10 @@ void setup(void)
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.getMode() == WIFI_AP ? WiFi.softAPIP() : WiFi.localIP());
|
||||
|
||||
#ifdef ESP8266
|
||||
{ HeapSelectIram doAllocationsInIRAM;
|
||||
#endif
|
||||
|
||||
statusLabelId = ESPUI.label("Status:", ControlColor::Turquoise, "Stop");
|
||||
millisLabelId = ESPUI.label("Millis:", ControlColor::Emerald, "0");
|
||||
ESPUI.button("Push Button", &buttonCallback, ControlColor::Peterriver, "Press");
|
||||
@ -257,6 +271,10 @@ void setup(void)
|
||||
* password, for example begin("ESPUI Control", "username", "password")
|
||||
*/
|
||||
ESPUI.begin("ESPUI Control");
|
||||
|
||||
#ifdef ESP8266
|
||||
} // HeapSelectIram
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
|
@ -8,7 +8,17 @@ DNSServer dnsServer;
|
||||
#if defined(ESP32)
|
||||
#include <WiFi.h>
|
||||
#else
|
||||
// esp8266
|
||||
#include <ESP8266WiFi.h>
|
||||
#include <umm_malloc/umm_heap_select.h>
|
||||
#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 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
|
||||
#endif // MMU_IRAM_HEAP
|
||||
#ifndef DEBUG_ESP_OOM
|
||||
#error on ESP8266 and ESPUI, you must define OOM debug option when developping
|
||||
#endif
|
||||
#endif
|
||||
|
||||
const char* ssid = "ESPUI";
|
||||
@ -56,7 +66,7 @@ void buttonCallback(Control* sender, int type)
|
||||
|
||||
void buttonExample(Control* sender, int type, void* param)
|
||||
{
|
||||
Serial.println(String("param: ") + String(int(param)));
|
||||
Serial.println(String("param: ") + String(long(param)));
|
||||
switch (type)
|
||||
{
|
||||
case B_DOWN:
|
||||
@ -233,6 +243,10 @@ void setup(void)
|
||||
Serial.print("IP address: ");
|
||||
Serial.println(WiFi.getMode() == WIFI_AP ? WiFi.softAPIP() : WiFi.localIP());
|
||||
|
||||
#ifdef ESP8266
|
||||
{ HeapSelectIram doAllocationsInIRAM;
|
||||
#endif
|
||||
|
||||
uint16_t tab1 = ESPUI.addControl(ControlType::Tab, "Settings 1", "Settings 1");
|
||||
uint16_t tab2 = ESPUI.addControl(ControlType::Tab, "Settings 2", "Settings 2");
|
||||
uint16_t tab3 = ESPUI.addControl(ControlType::Tab, "Settings 3", "Settings 3");
|
||||
@ -279,6 +293,10 @@ void setup(void)
|
||||
*/
|
||||
|
||||
ESPUI.begin("ESPUI Control");
|
||||
|
||||
#ifdef ESP8266
|
||||
} // HeapSelectIram
|
||||
#endif
|
||||
}
|
||||
|
||||
void loop(void)
|
||||
|
@ -31,7 +31,7 @@
|
||||
"frameworks": "arduino"
|
||||
}
|
||||
],
|
||||
"version": "2.1.1",
|
||||
"version": "2.2.3",
|
||||
"frameworks": "arduino",
|
||||
"platforms": "*"
|
||||
}
|
||||
|
@ -1,5 +1,5 @@
|
||||
name=ESPUI
|
||||
version=2.1.1
|
||||
version=2.2.3
|
||||
author=Lukas Bachschwell
|
||||
maintainer=Lukas Bachschwell <lukas@lbsfilm.at>
|
||||
sentence=ESP32 and ESP8266 Web Interface Library
|
||||
|
@ -18,7 +18,7 @@ board_build.filesystem = littlefs
|
||||
lib_extra_dirs = ../../
|
||||
lib_deps =
|
||||
bblanchon/ArduinoJson @ ^6.18.5
|
||||
https://github.com/esphome/ESPAsyncWebServer @ 3.0.0 ; Updated lib, seems to have recent patches.
|
||||
https://github.com/bmedici/ESPAsyncWebServer ; Use a fork of the library that has a bugfix for the compile.... https://github.com/esphome/ESPAsyncWebServer/pull/17
|
||||
|
||||
lib_ignore =
|
||||
ESP Async WebServer ; force the use of the esphome version
|
||||
@ -40,4 +40,4 @@ monitor_filters = esp32_exception_decoder
|
||||
board_build.flash_mode = dout
|
||||
lib_deps =
|
||||
${env.lib_deps}
|
||||
me-no-dev/AsyncTCP@1.1.1
|
||||
me-no-dev/AsyncTCP
|
||||
|
@ -62,7 +62,7 @@ void buttonCallback(Control* sender, int type)
|
||||
|
||||
void buttonExample(Control* sender, int type, void* param)
|
||||
{
|
||||
Serial.println(String("param: ") + String(int(param)));
|
||||
Serial.println(String("param: ") + String(long(param)));
|
||||
switch (type)
|
||||
{
|
||||
case B_DOWN:
|
||||
|
530
src/ESPUI.cpp
530
src/ESPUI.cpp
@ -13,6 +13,58 @@
|
||||
#include "dataTabbedcontentJS.h"
|
||||
#include "dataZeptoJS.h"
|
||||
|
||||
#if ESP8266
|
||||
#include <umm_malloc/umm_heap_select.h>
|
||||
#endif
|
||||
|
||||
static String heapInfo(const __FlashStringHelper* mode)
|
||||
{
|
||||
String result;
|
||||
#if ESP8266
|
||||
|
||||
uint32_t hfree;
|
||||
uint16_t hmax;
|
||||
uint8_t hfrag;
|
||||
result.reserve(128);
|
||||
|
||||
#ifdef UMM_HEAP_IRAM
|
||||
// here esp8266 is configurerd to use an extra 16KB (i)ram
|
||||
{
|
||||
HeapSelectIram useInstructionRamHere;
|
||||
ESP.getHeapStats(&hfree, &hmax, &hfrag);
|
||||
}
|
||||
result += F("IRAM: free: ");
|
||||
result += hfree;
|
||||
result += F(" max: ");
|
||||
result += hmax;
|
||||
result += F(" frag: ");
|
||||
result += hfrag;
|
||||
result += "%\n";
|
||||
#endif // !UMM_HEAP_IRAM
|
||||
{
|
||||
HeapSelectDram useRegularRamHere;
|
||||
ESP.getHeapStats(&hfree, &hmax, &hfrag);
|
||||
}
|
||||
result += F("DRAM: free: ");
|
||||
result += hfree;
|
||||
result += F(" max: ");
|
||||
result += hmax;
|
||||
result += F(" frag: ");
|
||||
result += hfrag;
|
||||
result += "%\n";
|
||||
|
||||
#else // !ESP8266
|
||||
|
||||
result += ESP.getFreeHeap();
|
||||
result += ' ';
|
||||
|
||||
#endif // !ESP8266
|
||||
|
||||
result += mode;
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
// ################# LITTLEFS functions
|
||||
#if defined(ESP32)
|
||||
void listDir(const char* dirname, uint8_t levels)
|
||||
@ -25,11 +77,11 @@ void listDir(const char* dirname, uint8_t levels)
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
File root = LittleFS.open(dirname);
|
||||
#else
|
||||
File root = LITTLEFS.open(dirname);
|
||||
#endif
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
File root = LittleFS.open(dirname);
|
||||
#else
|
||||
File root = LITTLEFS.open(dirname);
|
||||
#endif
|
||||
#else
|
||||
File root = LittleFS.open(dirname);
|
||||
#endif
|
||||
@ -74,11 +126,11 @@ void listDir(const char* dirname, uint8_t levels)
|
||||
|
||||
if (levels)
|
||||
{
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
listDir(file.path(), levels - 1);
|
||||
#else
|
||||
listDir(file.name(), levels - 1);
|
||||
#endif
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
listDir(file.path(), levels - 1);
|
||||
#else
|
||||
listDir(file.name(), levels - 1);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
else
|
||||
@ -123,13 +175,13 @@ void listDir(const char* dirname, uint8_t levels)
|
||||
#endif
|
||||
if (levels)
|
||||
{
|
||||
File file = dir.openFile("r");
|
||||
listDir(file.fullName(), levels - 1);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
File file = dir.openFile("r");
|
||||
listDir(file.fullName(), levels - 1);
|
||||
file.close();
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (ESPUI.verbosity)
|
||||
{
|
||||
@ -139,7 +191,7 @@ void listDir(const char* dirname, uint8_t levels)
|
||||
Serial.println(dir.fileSize());
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -148,11 +200,11 @@ void listDir(const char* dirname, uint8_t levels)
|
||||
void ESPUIClass::list()
|
||||
{
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
if (!LittleFS.begin())
|
||||
#else
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
if (!LittleFS.begin())
|
||||
#else
|
||||
if (!LITTLEFS.begin())
|
||||
#endif
|
||||
#endif
|
||||
{
|
||||
Serial.println(F("LITTLEFS Mount Failed"));
|
||||
return;
|
||||
@ -168,27 +220,27 @@ void ESPUIClass::list()
|
||||
listDir("/", 1);
|
||||
#if defined(ESP32)
|
||||
|
||||
Serial.print(F("Total KB: "));
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
Serial.println(LittleFS.totalBytes()/1024);
|
||||
#else
|
||||
Serial.println(LITTLEFS.totalBytes()/1024);
|
||||
#endif
|
||||
Serial.print(F("Used KB: "));
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
Serial.println(LittleFS.usedBytes()/1024);
|
||||
#else
|
||||
Serial.println(LITTLEFS.usedBytes()/1024);
|
||||
#endif
|
||||
Serial.print(F("Total KB: "));
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
Serial.println(LittleFS.totalBytes() / 1024);
|
||||
#else
|
||||
Serial.println(LITTLEFS.totalBytes() / 1024);
|
||||
#endif
|
||||
Serial.print(F("Used KB: "));
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
Serial.println(LittleFS.usedBytes() / 1024);
|
||||
#else
|
||||
Serial.println(LITTLEFS.usedBytes() / 1024);
|
||||
#endif
|
||||
|
||||
#else
|
||||
FSInfo fs_info;
|
||||
LittleFS.info(fs_info);
|
||||
|
||||
Serial.print(F("Total KB: "));
|
||||
Serial.println(fs_info.totalBytes/1024);
|
||||
Serial.print(F("Used KB: "));
|
||||
Serial.println(fs_info.usedBytes/1024);
|
||||
Serial.print(F("Total KB: "));
|
||||
Serial.println(fs_info.totalBytes / 1024);
|
||||
Serial.print(F("Used KB: "));
|
||||
Serial.println(fs_info.usedBytes / 1024);
|
||||
|
||||
#endif
|
||||
}
|
||||
@ -196,11 +248,11 @@ void ESPUIClass::list()
|
||||
void deleteFile(const char* path)
|
||||
{
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool exists = LittleFS.exists(path);
|
||||
#else
|
||||
bool exists = LITTLEFS.exists(path);
|
||||
#endif
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool exists = LittleFS.exists(path);
|
||||
#else
|
||||
bool exists = LITTLEFS.exists(path);
|
||||
#endif
|
||||
#else
|
||||
bool exists = LittleFS.exists(path);
|
||||
#endif
|
||||
@ -224,11 +276,11 @@ void deleteFile(const char* path)
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool didRemove = LittleFS.remove(path);
|
||||
#else
|
||||
bool didRemove = LITTLEFS.remove(path);
|
||||
#endif
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool didRemove = LittleFS.remove(path);
|
||||
#else
|
||||
bool didRemove = LITTLEFS.remove(path);
|
||||
#endif
|
||||
#else
|
||||
bool didRemove = LittleFS.remove(path);
|
||||
#endif
|
||||
@ -262,11 +314,11 @@ void writeFile(const char* path, const char* data)
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
File file = LittleFS.open(path, FILE_WRITE);
|
||||
#else
|
||||
File file = LITTLEFS.open(path, FILE_WRITE);
|
||||
#endif
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
File file = LittleFS.open(path, FILE_WRITE);
|
||||
#else
|
||||
File file = LITTLEFS.open(path, FILE_WRITE);
|
||||
#endif
|
||||
#else
|
||||
File file = LittleFS.open(path, FILE_WRITE);
|
||||
#endif
|
||||
@ -343,40 +395,40 @@ void ESPUIClass::prepareFileSystem(bool format)
|
||||
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
if(!LittleFS.begin(false)) //Test for an already formatted LittleFS by a mount failure
|
||||
if (!LittleFS.begin(false)) // Test for an already formatted LittleFS by a mount failure
|
||||
#else
|
||||
if(!LITTLEFS.begin(false)) //Test for an already formatted LittleFS by a mount failure
|
||||
if (!LITTLEFS.begin(false)) // Test for an already formatted LittleFS by a mount failure
|
||||
#endif
|
||||
{
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
if(!LittleFS.begin(true)) //Attempt to format LittleFS
|
||||
if (!LittleFS.begin(true)) // Attempt to format LittleFS
|
||||
#else
|
||||
if(!LITTLEFS.begin(true)) //Attempt to format LittleFS
|
||||
if (!LITTLEFS.begin(true)) // Attempt to format LittleFS
|
||||
#endif
|
||||
{
|
||||
{
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Format Failed"));
|
||||
}
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Format Failed"));
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(format)
|
||||
{
|
||||
else if (format)
|
||||
{
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
LittleFS.format();
|
||||
LittleFS.format();
|
||||
#else
|
||||
LITTLEFS.format();
|
||||
LITTLEFS.format();
|
||||
#endif
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Formatted"));
|
||||
}
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Formatted"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
@ -388,38 +440,38 @@ void ESPUIClass::prepareFileSystem(bool format)
|
||||
|
||||
#else
|
||||
|
||||
if (!LittleFS.begin()) //Test for an already formatted LittleFS by a mount failure
|
||||
if (!LittleFS.begin()) // Test for an already formatted LittleFS by a mount failure
|
||||
{
|
||||
if(LittleFS.format()) //Attempt to format LittleFS
|
||||
{
|
||||
if (LittleFS.format()) // Attempt to format LittleFS
|
||||
{
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Formatted"));
|
||||
}
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Formatted"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Mount Failed"));
|
||||
}
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Mount Failed"));
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
else if(format)
|
||||
{
|
||||
LittleFS.format();
|
||||
else if (format)
|
||||
{
|
||||
LittleFS.format();
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Formatted"));
|
||||
}
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("LittleFS Formatted"));
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
@ -450,33 +502,33 @@ void ESPUIClass::prepareFileSystem(bool format)
|
||||
#endif
|
||||
|
||||
// Now write
|
||||
#ifdef ESP32
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
writeFile("/index.htm", HTML_INDEX);
|
||||
LittleFS.mkdir("/css");
|
||||
writeFile("/css/style.css", CSS_STYLE);
|
||||
writeFile("/css/normalize.css", CSS_NORMALIZE);
|
||||
LittleFS.mkdir("/js");
|
||||
writeFile("/js/zepto.min.js", JS_ZEPTO);
|
||||
writeFile("/js/controls.js", JS_CONTROLS);
|
||||
writeFile("/js/slider.js", JS_SLIDER);
|
||||
writeFile("/js/graph.js", JS_GRAPH);
|
||||
#ifdef ESP32
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
writeFile("/index.htm", HTML_INDEX);
|
||||
LittleFS.mkdir("/css");
|
||||
writeFile("/css/style.css", CSS_STYLE);
|
||||
writeFile("/css/normalize.css", CSS_NORMALIZE);
|
||||
LittleFS.mkdir("/js");
|
||||
writeFile("/js/zepto.min.js", JS_ZEPTO);
|
||||
writeFile("/js/controls.js", JS_CONTROLS);
|
||||
writeFile("/js/slider.js", JS_SLIDER);
|
||||
writeFile("/js/graph.js", JS_GRAPH);
|
||||
|
||||
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
|
||||
#else
|
||||
writeFile("/index.htm", HTML_INDEX);
|
||||
LITTLEFS.mkdir("/css");
|
||||
writeFile("/css/style.css", CSS_STYLE);
|
||||
writeFile("/css/normalize.css", CSS_NORMALIZE);
|
||||
LITTLEFS.mkdir("/js");
|
||||
writeFile("/js/zepto.min.js", JS_ZEPTO);
|
||||
writeFile("/js/controls.js", JS_CONTROLS);
|
||||
writeFile("/js/slider.js", JS_SLIDER);
|
||||
writeFile("/js/graph.js", JS_GRAPH);
|
||||
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
|
||||
#else
|
||||
writeFile("/index.htm", HTML_INDEX);
|
||||
LITTLEFS.mkdir("/css");
|
||||
writeFile("/css/style.css", CSS_STYLE);
|
||||
writeFile("/css/normalize.css", CSS_NORMALIZE);
|
||||
LITTLEFS.mkdir("/js");
|
||||
writeFile("/js/zepto.min.js", JS_ZEPTO);
|
||||
writeFile("/js/controls.js", JS_CONTROLS);
|
||||
writeFile("/js/slider.js", JS_SLIDER);
|
||||
writeFile("/js/graph.js", JS_GRAPH);
|
||||
|
||||
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
|
||||
#endif
|
||||
#else
|
||||
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
|
||||
#endif
|
||||
#else
|
||||
writeFile("/index.htm", HTML_INDEX);
|
||||
|
||||
writeFile("/css/style.css", CSS_STYLE);
|
||||
@ -488,7 +540,7 @@ void ESPUIClass::prepareFileSystem(bool format)
|
||||
writeFile("/js/graph.js", JS_GRAPH);
|
||||
|
||||
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
@ -509,33 +561,33 @@ void ESPUIClass::prepareFileSystem(bool format)
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
LittleFS.end();
|
||||
#else
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
LittleFS.end();
|
||||
#else
|
||||
LITTLEFS.end();
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
LittleFS.end();
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
// Handle Websockets Communication
|
||||
void ESPUIClass::onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
|
||||
void ESPUIClass::onWsEvent(
|
||||
AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
|
||||
{
|
||||
// Serial.println(String("ESPUIClass::OnWsEvent: type: ") + String(type));
|
||||
RemoveToBeDeletedControls();
|
||||
|
||||
if(WS_EVT_DISCONNECT == type)
|
||||
if (WS_EVT_DISCONNECT == type)
|
||||
{
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("WS_EVT_DISCONNECT"));
|
||||
}
|
||||
#endif
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (verbosity)
|
||||
{
|
||||
Serial.println(F("WS_EVT_DISCONNECT"));
|
||||
}
|
||||
#endif
|
||||
|
||||
if(MapOfClients.end() != MapOfClients.find(client->id()))
|
||||
if (MapOfClients.end() != MapOfClients.find(client->id()))
|
||||
{
|
||||
// Serial.println("Delete client.");
|
||||
delete MapOfClients[client->id()];
|
||||
@ -544,7 +596,7 @@ void ESPUIClass::onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client,
|
||||
}
|
||||
else
|
||||
{
|
||||
if(MapOfClients.end() == MapOfClients.find(client->id()))
|
||||
if (MapOfClients.end() == MapOfClients.find(client->id()))
|
||||
{
|
||||
// Serial.println("ESPUIClass::OnWsEvent:Create new client.");
|
||||
MapOfClients[client->id()] = new ESPUIclient(client);
|
||||
@ -572,12 +624,14 @@ uint16_t ESPUIClass::addControl(ControlType type, const char* label, const Strin
|
||||
return addControl(type, label, value, color, Control::noParent);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl)
|
||||
uint16_t ESPUIClass::addControl(
|
||||
ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl)
|
||||
{
|
||||
return addControl(type, label, value, color, parentControl, nullptr);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, void (*callback)(Control*, int))
|
||||
uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color,
|
||||
uint16_t parentControl, void (*callback)(Control*, int))
|
||||
{
|
||||
uint16_t id = addControl(type, label, value, color, parentControl, nullptr, nullptr);
|
||||
// set the original style callback
|
||||
@ -585,7 +639,8 @@ uint16_t ESPUIClass::addControl(ControlType type, const char* label, const Strin
|
||||
return id;
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color, uint16_t parentControl, void (*callback)(Control*, int, void *), void * UserData)
|
||||
uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color,
|
||||
uint16_t parentControl, void (*callback)(Control*, int, void*), void* UserData)
|
||||
{
|
||||
#ifdef ESP32
|
||||
xSemaphoreTake(ControlsSemaphore, portMAX_DELAY);
|
||||
@ -631,7 +686,7 @@ bool ESPUIClass::removeControl(uint16_t id, bool force_rebuild_ui)
|
||||
control->DeleteControl();
|
||||
controlCount--;
|
||||
|
||||
if(force_rebuild_ui)
|
||||
if (force_rebuild_ui)
|
||||
{
|
||||
jsonReload();
|
||||
}
|
||||
@ -652,9 +707,9 @@ bool ESPUIClass::removeControl(uint16_t id, bool force_rebuild_ui)
|
||||
|
||||
void ESPUIClass::RemoveToBeDeletedControls()
|
||||
{
|
||||
#ifdef ESP32
|
||||
#ifdef ESP32
|
||||
xSemaphoreTake(ControlsSemaphore, portMAX_DELAY);
|
||||
#endif // def ESP32
|
||||
#endif // def ESP32
|
||||
|
||||
Control* PreviousControl = nullptr;
|
||||
Control* CurrentControl = controls;
|
||||
@ -682,9 +737,9 @@ void ESPUIClass::RemoveToBeDeletedControls()
|
||||
CurrentControl = NextControl;
|
||||
}
|
||||
}
|
||||
#ifdef ESP32
|
||||
#ifdef ESP32
|
||||
xSemaphoreGive(ControlsSemaphore);
|
||||
#endif // def ESP32
|
||||
#endif // def ESP32
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::label(const char* label, ControlColor color, const String& value)
|
||||
@ -697,16 +752,19 @@ uint16_t ESPUIClass::graph(const char* label, ControlColor color)
|
||||
return addControl(ControlType::Graph, label, "", color);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min, int max)
|
||||
uint16_t ESPUIClass::slider(
|
||||
const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min, int max)
|
||||
{
|
||||
uint16_t id = slider(label, nullptr, color, value, min, max, nullptr);
|
||||
getControl(id)->callback = callback;
|
||||
return id;
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::slider(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int value, int min, int max, void* userData)
|
||||
uint16_t ESPUIClass::slider(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int value,
|
||||
int min, int max, void* userData)
|
||||
{
|
||||
uint16_t sliderId = addControl(ControlType::Slider, label, String(value), color, Control::noParent, callback, userData);
|
||||
uint16_t sliderId
|
||||
= addControl(ControlType::Slider, label, String(value), color, Control::noParent, callback, userData);
|
||||
addControl(ControlType::Min, label, String(min), ControlColor::None, sliderId);
|
||||
addControl(ControlType::Max, label, String(max), ControlColor::None, sliderId);
|
||||
|
||||
@ -718,7 +776,8 @@ uint16_t ESPUIClass::button(const char* label, void (*callback)(Control*, int),
|
||||
return addControl(ControlType::Button, label, value, color, Control::noParent, callback);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::button(const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData)
|
||||
uint16_t ESPUIClass::button(
|
||||
const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData)
|
||||
{
|
||||
return addControl(ControlType::Button, label, value, color, Control::noParent, callback, UserData);
|
||||
}
|
||||
@ -728,9 +787,11 @@ uint16_t ESPUIClass::switcher(const char* label, void (*callback)(Control*, int)
|
||||
return addControl(ControlType::Switcher, label, startState ? "1" : "0", color, Control::noParent, callback);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::switcher(const char* label, void (*callback)(Control*, int, void*), ControlColor color, bool startState, void* UserData)
|
||||
uint16_t ESPUIClass::switcher(
|
||||
const char* label, void (*callback)(Control*, int, void*), ControlColor color, bool startState, void* UserData)
|
||||
{
|
||||
return addControl(ControlType::Switcher, label, startState ? "1" : "0", color, Control::noParent, callback, UserData);
|
||||
return addControl(
|
||||
ControlType::Switcher, label, startState ? "1" : "0", color, Control::noParent, callback, UserData);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::pad(const char* label, void (*callback)(Control*, int), ControlColor color)
|
||||
@ -748,12 +809,14 @@ uint16_t ESPUIClass::padWithCenter(const char* label, void (*callback)(Control*,
|
||||
return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::padWithCenter(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
|
||||
uint16_t ESPUIClass::padWithCenter(
|
||||
const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
|
||||
{
|
||||
return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback, UserData);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::number(const char* label, void (*callback)(Control*, int), ControlColor color, int number, int min, int max)
|
||||
uint16_t ESPUIClass::number(
|
||||
const char* label, void (*callback)(Control*, int), ControlColor color, int number, int min, int max)
|
||||
{
|
||||
uint16_t numberId = addControl(ControlType::Number, label, String(number), color, Control::noParent, callback);
|
||||
addControl(ControlType::Min, label, String(min), ControlColor::None, numberId);
|
||||
@ -761,9 +824,11 @@ uint16_t ESPUIClass::number(const char* label, void (*callback)(Control*, int),
|
||||
return numberId;
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::number(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int number, int min, int max, void* UserData)
|
||||
uint16_t ESPUIClass::number(const char* label, void (*callback)(Control*, int, void*), ControlColor color, int number,
|
||||
int min, int max, void* UserData)
|
||||
{
|
||||
uint16_t numberId = addControl(ControlType::Number, label, String(number), color, Control::noParent, callback, UserData);
|
||||
uint16_t numberId
|
||||
= addControl(ControlType::Number, label, String(number), color, Control::noParent, callback, UserData);
|
||||
addControl(ControlType::Min, label, String(min), ControlColor::None, numberId);
|
||||
addControl(ControlType::Max, label, String(max), ControlColor::None, numberId);
|
||||
return numberId;
|
||||
@ -777,7 +842,8 @@ uint16_t ESPUIClass::gauge(const char* label, ControlColor color, int number, in
|
||||
return numberId;
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::separator(const char* label) {
|
||||
uint16_t ESPUIClass::separator(const char* label)
|
||||
{
|
||||
return addControl(ControlType::Separator, label, "", ControlColor::Alizarin, Control::noParent, nullptr);
|
||||
}
|
||||
|
||||
@ -786,7 +852,8 @@ uint16_t ESPUIClass::accelerometer(const char* label, void (*callback)(Control*,
|
||||
return addControl(ControlType::Accel, label, "", color, Control::noParent, callback);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::accelerometer(const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
|
||||
uint16_t ESPUIClass::accelerometer(
|
||||
const char* label, void (*callback)(Control*, int, void*), ControlColor color, void* UserData)
|
||||
{
|
||||
return addControl(ControlType::Accel, label, "", color, Control::noParent, callback, UserData);
|
||||
}
|
||||
@ -796,7 +863,8 @@ uint16_t ESPUIClass::text(const char* label, void (*callback)(Control*, int), Co
|
||||
return addControl(ControlType::Text, label, value, color, Control::noParent, callback);
|
||||
}
|
||||
|
||||
uint16_t ESPUIClass::text(const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData)
|
||||
uint16_t ESPUIClass::text(
|
||||
const char* label, void (*callback)(Control*, int, void*), ControlColor color, const String& value, void* UserData)
|
||||
{
|
||||
return addControl(ControlType::Text, label, value, color, Control::noParent, callback, UserData);
|
||||
}
|
||||
@ -825,7 +893,7 @@ Control* ESPUIClass::getControlNoLock(uint16_t id)
|
||||
{
|
||||
if (control->id == id)
|
||||
{
|
||||
if(!control->ToBeDeleted())
|
||||
if (!control->ToBeDeleted())
|
||||
{
|
||||
Response = control;
|
||||
}
|
||||
@ -887,7 +955,8 @@ void ESPUIClass::setPanelWide(uint16_t id, bool wide)
|
||||
}
|
||||
}
|
||||
|
||||
void ESPUIClass::setEnabled(uint16_t id, bool enabled, int clientId) {
|
||||
void ESPUIClass::setEnabled(uint16_t id, bool enabled, int clientId)
|
||||
{
|
||||
Control* control = getControl(id);
|
||||
if (control)
|
||||
{
|
||||
@ -897,7 +966,8 @@ void ESPUIClass::setEnabled(uint16_t id, bool enabled, int clientId) {
|
||||
}
|
||||
}
|
||||
|
||||
void ESPUIClass::setVertical(uint16_t id, bool vert) {
|
||||
void ESPUIClass::setVertical(uint16_t id, bool vert)
|
||||
{
|
||||
Control* control = getControl(id);
|
||||
if (control)
|
||||
{
|
||||
@ -952,12 +1022,12 @@ void ESPUIClass::updateControlValue(uint16_t id, const String& value, int client
|
||||
updateControlValue(control, value, clientId);
|
||||
}
|
||||
|
||||
void ESPUIClass::updateControlLabel(uint16_t id, const char * value, int clientId)
|
||||
void ESPUIClass::updateControlLabel(uint16_t id, const char* value, int clientId)
|
||||
{
|
||||
updateControlLabel(getControl(id), value, clientId);
|
||||
}
|
||||
|
||||
void ESPUIClass::updateControlLabel(Control* control, const char * value, int clientId)
|
||||
void ESPUIClass::updateControlLabel(Control* control, const char* value, int clientId)
|
||||
{
|
||||
if (!control)
|
||||
{
|
||||
@ -973,9 +1043,10 @@ void ESPUIClass::updateControlLabel(Control* control, const char * value, int cl
|
||||
updateControl(control, clientId);
|
||||
}
|
||||
|
||||
void ESPUIClass::updateVisibility(uint16_t id, bool visibility, int clientId) {
|
||||
void ESPUIClass::updateVisibility(uint16_t id, bool visibility, int clientId)
|
||||
{
|
||||
Control* control = getControl(id);
|
||||
if(control)
|
||||
if (control)
|
||||
{
|
||||
control->visible = visibility;
|
||||
updateControl(control, clientId);
|
||||
@ -992,7 +1063,8 @@ void ESPUIClass::updateLabel(uint16_t id, const String& value)
|
||||
updateControlValue(id, value);
|
||||
}
|
||||
|
||||
void ESPUIClass::updateButton(uint16_t id, const String& value) {
|
||||
void ESPUIClass::updateButton(uint16_t id, const String& value)
|
||||
{
|
||||
updateControlValue(id, value);
|
||||
}
|
||||
|
||||
@ -1031,7 +1103,27 @@ void ESPUIClass::updateTime(uint16_t id, int clientId)
|
||||
updateControl(id, clientId);
|
||||
}
|
||||
|
||||
void ESPUIClass::clearGraph(uint16_t id, int clientId) { }
|
||||
void ESPUIClass::clearGraph(uint16_t id, int clientId)
|
||||
{
|
||||
do // once
|
||||
{
|
||||
Control* control = getControl(id);
|
||||
if (!control)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
DynamicJsonDocument document(jsonUpdateDocumentSize);
|
||||
JsonObject root = document.to<JsonObject>();
|
||||
|
||||
root[F("type")] = (int)ControlType::Graph + UpdateOffset;
|
||||
root[F("value")] = 0;
|
||||
root[F("id")] = control->id;
|
||||
|
||||
SendJsonDocToWebSocket(document, clientId);
|
||||
|
||||
} while (false);
|
||||
}
|
||||
|
||||
void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId)
|
||||
{
|
||||
@ -1052,23 +1144,23 @@ void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId)
|
||||
|
||||
SendJsonDocToWebSocket(document, clientId);
|
||||
|
||||
} while(false);
|
||||
} while (false);
|
||||
}
|
||||
|
||||
bool ESPUIClass::SendJsonDocToWebSocket(ArduinoJson::DynamicJsonDocument& document, uint16_t clientId)
|
||||
{
|
||||
bool Response = false;
|
||||
|
||||
if(0 > clientId)
|
||||
if (0 > clientId)
|
||||
{
|
||||
if(MapOfClients.end() != MapOfClients.find(clientId))
|
||||
if (MapOfClients.end() != MapOfClients.find(clientId))
|
||||
{
|
||||
Response = MapOfClients[clientId]->SendJsonDocToWebSocket(document);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
for(auto CurrentClient : MapOfClients)
|
||||
for (auto CurrentClient : MapOfClients)
|
||||
{
|
||||
Response |= CurrentClient.second->SendJsonDocToWebSocket(document);
|
||||
}
|
||||
@ -1095,19 +1187,19 @@ void ESPUIClass::ClearControlUpdateFlags()
|
||||
{
|
||||
bool CanClearUpdateFlags = true;
|
||||
|
||||
for(auto& CurrentClient : MapOfClients)
|
||||
for (auto& CurrentClient : MapOfClients)
|
||||
{
|
||||
if(!CurrentClient.second->IsSyncronized())
|
||||
if (!CurrentClient.second->IsSyncronized())
|
||||
{
|
||||
CanClearUpdateFlags = false;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(CanClearUpdateFlags)
|
||||
if (CanClearUpdateFlags)
|
||||
{
|
||||
Control* control = controls;
|
||||
while(nullptr != control)
|
||||
while (nullptr != control)
|
||||
{
|
||||
control->HasBeenSynchronized();
|
||||
control = control->next;
|
||||
@ -1117,7 +1209,7 @@ void ESPUIClass::ClearControlUpdateFlags()
|
||||
|
||||
void ESPUIClass::jsonReload()
|
||||
{
|
||||
for(auto& CurrentClient : MapOfClients)
|
||||
for (auto& CurrentClient : MapOfClients)
|
||||
{
|
||||
// Serial.println("Requesting Reload");
|
||||
CurrentClient.second->NotifyClient(ClientUpdateType_t::ReloadNeeded);
|
||||
@ -1149,11 +1241,11 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
|
||||
ws = new AsyncWebSocket("/ws");
|
||||
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool fsBegin = LittleFS.begin();
|
||||
#else
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool fsBegin = LittleFS.begin();
|
||||
#else
|
||||
bool fsBegin = LITTLEFS.begin();
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
bool fsBegin = LittleFS.begin();
|
||||
#endif
|
||||
@ -1178,11 +1270,11 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
|
||||
#endif
|
||||
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool indexExists = LittleFS.exists("/index.htm");
|
||||
#else
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
bool indexExists = LittleFS.exists("/index.htm");
|
||||
#else
|
||||
bool indexExists = LITTLEFS.exists("/index.htm");
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
bool indexExists = LittleFS.exists("/index.htm");
|
||||
#endif
|
||||
@ -1199,10 +1291,8 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
|
||||
return;
|
||||
}
|
||||
|
||||
ws->onEvent([](AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
|
||||
{
|
||||
ESPUI.onWsEvent(server, client, type, arg, data, len);
|
||||
});
|
||||
ws->onEvent([](AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data,
|
||||
size_t len) { ESPUI.onWsEvent(server, client, type, arg, data, len); });
|
||||
server->addHandler(ws);
|
||||
|
||||
if (basicAuth)
|
||||
@ -1212,11 +1302,11 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
|
||||
ws->setAuthentication(basicAuthUsername, basicAuthPassword);
|
||||
}
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(username, password);
|
||||
#else
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(username, password);
|
||||
#else
|
||||
server->serveStatic("/", LITTLEFS, "/").setDefaultFile("index.htm").setAuthentication(username, password);
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(username, password);
|
||||
#endif
|
||||
@ -1224,11 +1314,11 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
|
||||
else
|
||||
{
|
||||
#if defined(ESP32)
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm");
|
||||
#else
|
||||
#if (ESP_IDF_VERSION_MAJOR == 4 && ESP_IDF_VERSION_MINOR >= 4) || ESP_IDF_VERSION_MAJOR > 4
|
||||
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm");
|
||||
#else
|
||||
server->serveStatic("/", LITTLEFS, "/").setDefaultFile("index.htm");
|
||||
#endif
|
||||
#endif
|
||||
#else
|
||||
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm");
|
||||
#endif
|
||||
@ -1241,19 +1331,19 @@ void ESPUIClass::beginLITTLEFS(const char* _title, const char* username, const c
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
|
||||
request->send(200, "text/plain", String(ESP.getFreeHeap()) + " In LITTLEFS mode");
|
||||
request->send(200, "text/plain", heapInfo(F("In LITTLEFS mode")));
|
||||
});
|
||||
|
||||
server->onNotFound([this](AsyncWebServerRequest* request) {
|
||||
if(captivePortal)
|
||||
{
|
||||
request->redirect("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404);
|
||||
}
|
||||
});
|
||||
if (captivePortal)
|
||||
{
|
||||
request->redirect("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404);
|
||||
}
|
||||
});
|
||||
|
||||
server->begin();
|
||||
|
||||
@ -1284,10 +1374,8 @@ void ESPUIClass::begin(const char* _title, const char* username, const char* pas
|
||||
server = new AsyncWebServer(port);
|
||||
ws = new AsyncWebSocket("/ws");
|
||||
|
||||
ws->onEvent([](AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
|
||||
{
|
||||
ESPUI.onWsEvent(server, client, type, arg, data, len);
|
||||
});
|
||||
ws->onEvent([](AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data,
|
||||
size_t len) { ESPUI.onWsEvent(server, client, type, arg, data, len); });
|
||||
|
||||
server->addHandler(ws);
|
||||
|
||||
@ -1399,19 +1487,19 @@ void ESPUIClass::begin(const char* _title, const char* username, const char* pas
|
||||
return request->requestAuthentication();
|
||||
}
|
||||
|
||||
request->send(200, "text/plain", String(ESP.getFreeHeap()) + " In Memorymode");
|
||||
request->send(200, "text/plain", heapInfo(F("In Memorymode")));
|
||||
});
|
||||
|
||||
server->onNotFound([this](AsyncWebServerRequest* request) {
|
||||
if(captivePortal)
|
||||
{
|
||||
request->redirect("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404);
|
||||
}
|
||||
});
|
||||
if (captivePortal)
|
||||
{
|
||||
request->redirect("/");
|
||||
}
|
||||
else
|
||||
{
|
||||
request->send(404);
|
||||
}
|
||||
});
|
||||
|
||||
server->begin();
|
||||
|
||||
|
31
src/ESPUI.h
31
src/ESPUI.h
@ -87,20 +87,25 @@ enum Verbosity : uint8_t
|
||||
class ESPUIClass
|
||||
{
|
||||
public:
|
||||
|
||||
#ifdef ESP32
|
||||
ESPUIClass()
|
||||
{
|
||||
verbosity = Verbosity::Quiet;
|
||||
jsonUpdateDocumentSize = 2000;
|
||||
jsonInitialDocumentSize = 8000;
|
||||
sliderContinuous = false;
|
||||
#ifdef ESP32
|
||||
ControlsSemaphore = xSemaphoreCreateMutex();
|
||||
xSemaphoreGive(ControlsSemaphore);
|
||||
#endif // def ESP32
|
||||
}
|
||||
unsigned int jsonUpdateDocumentSize;
|
||||
unsigned int jsonInitialDocumentSize;
|
||||
bool sliderContinuous;
|
||||
SemaphoreHandle_t ControlsSemaphore = NULL;
|
||||
#endif // def ESP32
|
||||
|
||||
unsigned int jsonUpdateDocumentSize = 2000;
|
||||
#ifdef ESP8266
|
||||
unsigned int jsonInitialDocumentSize = 2000;
|
||||
unsigned int jsonChunkNumberMax = 5;
|
||||
#else
|
||||
unsigned int jsonInitialDocumentSize = 8000;
|
||||
unsigned int jsonChunkNumberMax = 0;
|
||||
#endif
|
||||
bool sliderContinuous = false;
|
||||
void onWsEvent(AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len);
|
||||
bool captivePortal = true;
|
||||
|
||||
@ -205,19 +210,15 @@ public:
|
||||
void jsonReload();
|
||||
void jsonDom(uint16_t startidx, AsyncWebSocketClient* client = nullptr, bool Updating = false);
|
||||
|
||||
Verbosity verbosity;
|
||||
Verbosity verbosity = Verbosity::Quiet;
|
||||
AsyncWebServer* server;
|
||||
|
||||
protected:
|
||||
friend class ESPUIclient;
|
||||
friend class ESPUIcontrol;
|
||||
|
||||
#ifdef ESP32
|
||||
SemaphoreHandle_t ControlsSemaphore = NULL;
|
||||
#endif // def ESP32
|
||||
|
||||
void RemoveToBeDeletedControls();
|
||||
|
||||
AsyncWebServer* server;
|
||||
AsyncWebSocket* ws;
|
||||
|
||||
const char* basicAuthUsername = nullptr;
|
||||
|
@ -2,6 +2,42 @@
|
||||
#include "ESPUIclient.h"
|
||||
#include "ESPUIcontrol.h"
|
||||
|
||||
// JSONSlave:
|
||||
// helper to process exact JSON serialization size
|
||||
// it takes ~2ms on esp8266 and avoid large String reallocation which is really worth the cost
|
||||
class JSONSlave: public Print
|
||||
{
|
||||
public:
|
||||
size_t write (uint8_t c) override { counter++; return 1; }
|
||||
size_t write (const uint8_t* buf, size_t count) override { counter += count; return count; }
|
||||
size_t get_counter () { return counter; }
|
||||
|
||||
static size_t serializedSize (JsonDocument& doc)
|
||||
{
|
||||
JSONSlave counter;
|
||||
serializeJson(doc, counter);
|
||||
return counter.get_counter();
|
||||
}
|
||||
|
||||
static size_t serialize (JsonDocument& doc, String& str)
|
||||
{
|
||||
size_t s = serializedSize(doc) + 10; // 10 is paranoid
|
||||
str.reserve(s);
|
||||
serializeJson(doc, str);
|
||||
return s;
|
||||
}
|
||||
|
||||
static String toString (JsonDocument& doc)
|
||||
{
|
||||
String str;
|
||||
serialize(doc, str);
|
||||
return str;
|
||||
}
|
||||
|
||||
protected:
|
||||
size_t counter = 0;
|
||||
};
|
||||
|
||||
ESPUIclient::ESPUIclient(AsyncWebSocketClient * _client):
|
||||
client(_client)
|
||||
{
|
||||
@ -309,7 +345,7 @@ uint32_t ESPUIclient::prepareJSONChunk(uint16_t startindex,
|
||||
elementcount++;
|
||||
control->MarshalControl(item, InUpdateMode);
|
||||
|
||||
if (rootDoc.overflowed())
|
||||
if (rootDoc.overflowed() || (ESPUI.jsonChunkNumberMax > 0 && (elementcount % ESPUI.jsonChunkNumberMax) == 0))
|
||||
{
|
||||
// String("prepareJSONChunk: too much data in the message. Remove the last entry");
|
||||
if (1 == elementcount)
|
||||
@ -407,9 +443,8 @@ bool ESPUIclient::SendControlsToClient(uint16_t startidx,
|
||||
if (ESPUI.verbosity >= Verbosity::VerboseJSON)
|
||||
{
|
||||
Serial.println(F("ESPUIclient:SendControlsToClient: Sending elements --------->"));
|
||||
String json;
|
||||
serializeJson(document, json);
|
||||
Serial.println(json);
|
||||
serializeJson(document, Serial);
|
||||
Serial.println();
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -454,10 +489,7 @@ bool ESPUIclient::SendJsonDocToWebSocket(DynamicJsonDocument& document)
|
||||
break;
|
||||
}
|
||||
|
||||
String json;
|
||||
json.reserve(document.size() / 2);
|
||||
json.clear();
|
||||
serializeJson(document, json);
|
||||
String json = JSONSlave::toString(document);
|
||||
|
||||
#if defined(DEBUG_ESPUI)
|
||||
if (ESPUI.verbosity >= Verbosity::VerboseJSON)
|
||||
|
@ -59,16 +59,17 @@ void Control::DeleteControl()
|
||||
void Control::MarshalControl(JsonObject & item, bool refresh)
|
||||
{
|
||||
item[F("id")] = id;
|
||||
ControlType TempType = (ControlType::Password == type) ? ControlType::Text : type;
|
||||
if(refresh)
|
||||
{
|
||||
item[F("type")] = uint32_t(type) + uint32_t(ControlType::UpdateOffset);
|
||||
item[F("type")] = uint32_t(TempType) + uint32_t(ControlType::UpdateOffset);
|
||||
}
|
||||
else
|
||||
{
|
||||
item[F("type")] = uint32_t(type);
|
||||
item[F("type")] = uint32_t(TempType);
|
||||
}
|
||||
item[F("label")] = label;
|
||||
item[F("value")] = value;
|
||||
item[F ("value")] = (ControlType::Password == type) ? F ("--------") : value;
|
||||
item[F("visible")] = visible;
|
||||
item[F("color")] = (int)color;
|
||||
item[F("enabled")] = enabled;
|
||||
|
@ -30,6 +30,7 @@ enum ControlType : uint8_t
|
||||
Separator,
|
||||
Time,
|
||||
|
||||
Password = 99,
|
||||
UpdateOffset = 100,
|
||||
};
|
||||
|
||||
|
File diff suppressed because one or more lines are too long
@ -1,19 +1,19 @@
|
||||
const char JS_GRAPH[] PROGMEM = R"=====(
|
||||
function lineGraph(parent,xAccessor,yAccessor){const width=620;const height=420;const gutter=40;const pixelsPerTick=30;function numericTransformer(dataMin,dataMax,pxMin,pxMax){var dataDiff=dataMax-dataMin,pxDiff=pxMax-pxMin,dataRatio=pxDiff/dataDiff,coordRatio=dataDiff/pxDiff;return{toCoord:function(data){return(data-dataMin)*dataRatio+pxMin;},toData:function(coord){return(coord-pxMin)*coordRatio+dataMin;}};}
|
||||
function axisRenderer(orientation,transform){var axisGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var axisPath=document.createElementNS("http://www.w3.org/2000/svg","path");axisGroup.setAttribute("class",orientation+"-axis");var xMin=gutter;var xMax=width-gutter;var yMin=height-gutter;var yMax=gutter;if(orientation==="x"){axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMax+" "+yMin);for(var i=xMin;i<=xMax;i++){if((i-xMin)%pixelsPerTick===0&&i!==xMin){var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",i);text.setAttribute("y",yMin);text.setAttribute("dy","1em");axisGroup.appendChild(text);}}}else{axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMin+" "+yMax);for(var i=yMax;i<=yMin;i++){if((i-yMin)%pixelsPerTick===0&&i!==yMin){var tickGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var gridLine=document.createElementNS("http://www.w3.org/2000/svg","path");text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",xMin);text.setAttribute("y",i);text.setAttribute("dx","-.5em");text.setAttribute("dy",".3em");gridLine.setAttribute("d","M "+xMin+" "+i+" L "+xMax+" "+i);tickGroup.appendChild(gridLine);tickGroup.appendChild(text);axisGroup.appendChild(tickGroup);}}}
|
||||
axisGroup.appendChild(axisPath);parent.appendChild(axisGroup);}
|
||||
function lineRenderer(xAccessor,yAccessor,xTransform,yTransform){var line=document.createElementNS("http://www.w3.org/2000/svg","path");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
var pathString="M "+xTransform(xAccessor.next())+" "+yTransform(yAccessor.next());while(xAccessor.hasNext()&&yAccessor.hasNext()){pathString+=" L "+
|
||||
xTransform(xAccessor.next())+
|
||||
" "+
|
||||
yTransform(yAccessor.next());}
|
||||
line.setAttribute("class","series");line.setAttribute("d",pathString);parent.appendChild(line);}
|
||||
function pointRenderer(xAccessor,yAccessor,xTransform,yTransform){var pointGroup=document.createElementNS("http://www.w3.org/2000/svg","g");pointGroup.setAttribute("class","data-points");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
while(xAccessor.hasNext()&&yAccessor.hasNext()){var xDataValue=xAccessor.next();var x=xTransform(xDataValue);var yDataValue=yAccessor.next();var y=yTransform(yDataValue);var circle=document.createElementNS("http://www.w3.org/2000/svg","circle");circle.setAttribute("cx",x);circle.setAttribute("cy",y);circle.setAttribute("r","4");var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(xDataValue)+" / "+Math.floor(yDataValue);text.setAttribute("x",x);text.setAttribute("y",y);text.setAttribute("dx","1em");text.setAttribute("dy","-.7em");pointGroup.appendChild(circle);pointGroup.appendChild(text);}
|
||||
parent.appendChild(pointGroup);}
|
||||
xTransform=numericTransformer(xAccessor.min(),xAccessor.max(),0+gutter,width-gutter);yTransform=numericTransformer(yAccessor.min(),yAccessor.max(),height-gutter,0+gutter);axisRenderer("x",xTransform.toData);axisRenderer("y",yTransform.toData);lineRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);pointRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);}
|
||||
function renderGraphSvg(dataArray,renderId){var figure=document.getElementById(renderId);while(figure.hasChildNodes()){figure.removeChild(figure.lastChild);}
|
||||
var svg=document.createElementNS("http://www.w3.org/2000/svg","svg");svg.setAttribute("viewBox","0 0 640 440");svg.setAttribute("preserveAspectRatio","xMidYMid meet");lineGraph(svg,(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].x;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.x;})),Math.max.apply(Math,dataArray.map(function(o){return o.x;}))),(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].y;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.y;})),Math.max.apply(Math,dataArray.map(function(o){return o.y;}))));figure.appendChild(svg);}
|
||||
)=====";
|
||||
|
||||
const uint8_t JS_GRAPH_GZIP[1245] PROGMEM = { 31,139,8,0,210,8,51,99,2,255,205,87,95,111,219,54,16,127,247,167,112,4,44,16,107,89,86,27,175,3,170,240,33,109,135,174,64,18,20,77,48,96,24,246,192,73,180,76,76,150,4,138,182,69,184,254,238,59,146,162,36,219,82,134,58,45,186,135,56,226,253,231,241,119,119,228,98,157,69,130,229,217,56,101,25,253,192,73,177,116,11,194,105,38,188,234,38,138,104,89,230,220,147,246,11,237,162,60,43,197,120,203,98,177,196,175,95,5,161,89,47,41,75,150,2,207,27,66,178,22,130,114,60,183,235,130,85,52,45,63,81,254,200,162,127,240,85,16,46,172,219,108,189,162,156,69,143,156,100,229,34,231,176,112,99,34,200,29,203,60,253,159,84,94,81,169,21,252,146,10,237,54,132,143,21,227,61,91,44,112,45,49,181,26,69,165,201,90,116,106,212,20,235,51,1,87,216,48,103,86,217,139,242,156,199,134,101,105,51,35,19,114,42,214,60,219,137,252,157,146,121,99,131,213,145,161,157,225,234,133,245,140,94,52,126,38,218,111,184,247,68,254,30,104,173,178,246,215,104,235,149,137,17,189,104,67,153,212,6,195,253,62,220,143,154,44,145,138,149,159,105,22,83,14,249,201,57,131,243,81,210,153,39,108,222,76,102,148,220,7,158,175,11,28,231,17,100,54,19,126,196,41,17,244,215,148,170,213,253,131,235,44,133,40,222,204,102,219,237,214,223,94,249,57,79,102,175,130,32,152,149,155,196,241,156,196,65,161,53,244,137,192,33,159,105,167,0,93,48,213,196,227,151,84,220,8,193,217,223,107,65,93,39,74,73,89,58,94,103,39,19,103,170,132,107,247,42,45,216,128,168,94,147,10,107,212,77,59,84,169,164,12,246,14,201,32,92,175,217,162,155,46,140,177,83,57,104,103,119,119,20,85,12,129,223,141,157,137,242,62,113,224,67,154,143,91,77,35,85,67,67,33,164,220,85,190,24,214,167,205,174,177,18,8,217,100,130,118,224,211,101,83,125,178,63,29,2,31,227,224,242,146,93,96,173,100,78,76,208,74,156,155,100,165,11,9,83,255,124,150,101,148,255,246,120,119,139,239,212,198,22,41,64,202,109,208,225,50,84,203,29,238,184,114,60,214,203,144,142,103,54,218,195,139,129,233,188,164,171,131,243,37,69,1,248,124,183,100,105,236,42,29,4,8,222,195,214,233,121,201,110,104,80,243,157,100,75,157,228,107,44,117,210,219,100,203,167,146,45,219,100,3,253,155,148,71,194,89,124,11,13,243,153,229,241,195,15,191,26,58,99,57,4,140,24,180,156,169,255,179,62,254,33,112,248,87,154,109,179,244,95,39,207,142,107,76,185,182,71,117,128,44,107,113,136,111,144,55,128,74,171,161,161,57,234,23,178,96,69,161,153,130,39,76,107,161,237,205,106,112,54,189,185,103,104,122,85,51,220,60,249,120,216,175,211,231,99,168,241,232,115,10,121,118,81,40,79,40,80,36,23,173,220,146,148,247,144,39,23,125,249,114,33,79,169,118,68,193,30,85,136,202,205,3,156,93,150,96,115,106,205,22,218,205,250,153,209,52,53,219,10,200,99,129,112,11,137,164,110,79,44,151,151,189,161,180,222,39,216,128,100,244,100,0,35,21,193,232,201,16,246,163,244,20,147,245,64,114,74,184,140,80,53,133,210,94,220,182,225,244,2,36,213,208,236,96,163,200,89,38,206,5,135,86,126,118,187,106,173,12,108,89,223,99,180,84,249,157,225,244,181,135,175,39,191,186,68,253,78,210,53,197,199,167,109,110,6,184,139,135,70,216,48,101,171,44,251,148,37,238,34,229,72,57,98,60,74,207,174,78,163,13,9,53,31,199,185,87,189,119,136,167,102,239,0,143,131,229,121,61,131,190,235,240,232,100,18,138,122,6,69,213,97,118,51,53,48,87,6,47,21,195,67,229,229,147,35,101,234,255,162,249,29,56,119,43,207,100,107,144,93,223,72,70,61,53,219,106,40,129,22,76,184,231,101,210,34,112,197,50,23,121,157,53,169,96,29,76,204,181,211,235,94,85,161,130,158,52,42,143,140,202,35,163,7,23,220,198,133,153,114,77,107,209,73,111,172,250,230,237,113,44,163,242,127,42,243,21,243,203,175,95,68,135,102,52,169,78,253,183,48,212,233,159,92,155,211,207,210,135,77,162,159,92,55,156,19,233,25,198,199,216,52,137,5,75,214,188,83,170,9,21,117,37,188,149,31,99,183,17,174,199,143,17,87,157,70,67,224,62,143,105,169,250,77,77,231,116,149,111,168,65,71,77,130,86,41,52,1,213,83,17,202,232,220,218,83,191,40,132,223,35,152,111,24,221,190,205,85,37,4,227,96,252,122,30,140,231,243,160,87,178,80,141,152,111,232,77,89,208,72,232,119,35,104,193,117,42,254,3,254,198,43,74,69,61,193,204,131,30,44,120,238,193,35,214,3,168,121,43,251,158,102,56,176,79,222,186,251,182,175,86,219,190,199,236,90,41,250,41,205,18,177,132,231,109,214,47,166,132,254,132,155,249,95,126,5,66,122,98,116,165,148,171,189,242,222,163,186,210,207,102,136,170,143,7,247,126,245,36,70,29,12,232,142,4,74,170,156,83,233,170,165,215,112,161,120,138,118,207,121,99,40,87,113,33,84,43,147,234,28,101,244,3,178,41,255,167,217,148,207,201,166,86,134,43,89,93,101,221,182,12,152,133,90,251,23,198,24,146,161,158,18,0,0 };
|
||||
const char JS_GRAPH[] PROGMEM = R"=====(
|
||||
function lineGraph(parent,xAccessor,yAccessor){const width=620;const height=420;const gutter=40;const pixelsPerTick=30;function numericTransformer(dataMin,dataMax,pxMin,pxMax){var dataDiff=dataMax-dataMin,pxDiff=pxMax-pxMin,dataRatio=pxDiff/dataDiff,coordRatio=dataDiff/pxDiff;return{toCoord:function(data){return(data-dataMin)*dataRatio+pxMin;},toData:function(coord){return(coord-pxMin)*coordRatio+dataMin;}};}
|
||||
function axisRenderer(orientation,transform){var axisGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var axisPath=document.createElementNS("http://www.w3.org/2000/svg","path");axisGroup.setAttribute("class",orientation+"-axis");var xMin=gutter;var xMax=width-gutter;var yMin=height-gutter;var yMax=gutter;if(orientation==="x"){axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMax+" "+yMin);for(var i=xMin;i<=xMax;i++){if((i-xMin)%(pixelsPerTick*3)===0&&i!==xMin){var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=new Date(Math.floor(transform(i))).toLocaleTimeString();text.setAttribute("x",i);text.setAttribute("y",yMin);text.setAttribute("dy","1em");axisGroup.appendChild(text);}}}else{axisPath.setAttribute("d","M "+xMin+" "+yMin+" L "+xMin+" "+yMax);for(var i=yMax;i<=yMin;i++){if((i-yMin)%pixelsPerTick===0&&i!==yMin){var tickGroup=document.createElementNS("http://www.w3.org/2000/svg","g");var gridLine=document.createElementNS("http://www.w3.org/2000/svg","path");text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(transform(i));text.setAttribute("x",xMin);text.setAttribute("y",i);text.setAttribute("dx","-.5em");text.setAttribute("dy",".3em");gridLine.setAttribute("d","M "+xMin+" "+i+" L "+xMax+" "+i);tickGroup.appendChild(gridLine);tickGroup.appendChild(text);axisGroup.appendChild(tickGroup);}}}
|
||||
axisGroup.appendChild(axisPath);parent.appendChild(axisGroup);}
|
||||
function lineRenderer(xAccessor,yAccessor,xTransform,yTransform){var line=document.createElementNS("http://www.w3.org/2000/svg","path");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
var pathString="M "+xTransform(xAccessor.next())+" "+yTransform(yAccessor.next());while(xAccessor.hasNext()&&yAccessor.hasNext()){pathString+=" L "+
|
||||
xTransform(xAccessor.next())+
|
||||
" "+
|
||||
yTransform(yAccessor.next());}
|
||||
line.setAttribute("class","series");line.setAttribute("d",pathString);parent.appendChild(line);}
|
||||
function pointRenderer(xAccessor,yAccessor,xTransform,yTransform){var pointGroup=document.createElementNS("http://www.w3.org/2000/svg","g");pointGroup.setAttribute("class","data-points");xAccessor.reset();yAccessor.reset();if(!xAccessor.hasNext()||!yAccessor.hasNext()){return;}
|
||||
while(xAccessor.hasNext()&&yAccessor.hasNext()){var xDataValue=xAccessor.next();var x=xTransform(xDataValue);var yDataValue=yAccessor.next();var y=yTransform(yDataValue);var circle=document.createElementNS("http://www.w3.org/2000/svg","circle");circle.setAttribute("cx",x);circle.setAttribute("cy",y);circle.setAttribute("r","4");var text=document.createElementNS("http://www.w3.org/2000/svg","text");text.innerHTML=Math.floor(xDataValue)+" / "+Math.floor(yDataValue);text.setAttribute("x",x);text.setAttribute("y",y);text.setAttribute("dx","1em");text.setAttribute("dy","-.7em");pointGroup.appendChild(circle);pointGroup.appendChild(text);}
|
||||
parent.appendChild(pointGroup);}
|
||||
xTransform=numericTransformer(xAccessor.min(),xAccessor.max(),0+gutter,width-gutter);yTransform=numericTransformer(yAccessor.min(),yAccessor.max(),height-gutter,0+gutter);axisRenderer("x",xTransform.toData);axisRenderer("y",yTransform.toData);lineRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);pointRenderer(xAccessor,yAccessor,xTransform.toCoord,yTransform.toCoord);}
|
||||
function renderGraphSvg(dataArray,renderId){var figure=document.getElementById(renderId);while(figure.hasChildNodes()){figure.removeChild(figure.lastChild);}
|
||||
var svg=document.createElementNS("http://www.w3.org/2000/svg","svg");svg.setAttribute("viewBox","0 0 640 440");svg.setAttribute("preserveAspectRatio","xMidYMid meet");lineGraph(svg,(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].x;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.x;})),Math.max.apply(Math,dataArray.map(function(o){return o.x;}))),(function(data,min,max){var i=0;return{hasNext:function(){return i<data.length;},next:function(){return data[i++].y;},reset:function(){i=0;},min:function(){return min;},max:function(){return max;}};})(dataArray,Math.min.apply(Math,dataArray.map(function(o){return o.y;})),Math.max.apply(Math,dataArray.map(function(o){return o.y;}))));figure.appendChild(svg);}
|
||||
)=====";
|
||||
|
||||
const uint8_t JS_GRAPH_GZIP[1280] PROGMEM = { 31,139,8,0,22,146,123,99,2,255,205,87,95,111,219,54,16,127,247,167,112,4,52,16,99,89,86,27,175,3,170,240,33,109,135,174,64,18,20,77,48,96,24,246,192,73,180,76,76,150,4,138,182,69,184,254,238,59,146,162,36,59,82,134,58,41,182,135,56,34,239,47,239,126,119,71,46,214,89,36,88,158,141,83,150,209,79,156,20,75,183,32,156,102,194,171,174,163,136,150,101,206,61,105,191,208,46,202,179,82,140,183,44,22,75,252,246,77,16,154,245,146,178,100,41,240,188,217,72,214,66,80,142,231,118,93,176,138,166,229,23,202,31,88,244,55,190,12,194,133,53,155,173,87,148,179,232,129,147,172,92,228,28,22,110,76,4,185,101,153,167,255,147,202,43,42,181,130,95,82,161,221,134,240,177,34,124,100,139,5,174,57,166,86,162,168,244,182,102,157,26,49,69,250,74,192,20,54,196,153,21,246,162,60,231,177,33,217,189,153,225,9,57,21,107,158,237,68,254,65,241,188,179,206,106,207,208,206,80,245,194,90,70,23,141,157,137,182,27,238,61,145,127,132,189,86,88,219,107,164,245,202,248,136,46,90,87,38,181,194,112,191,15,247,163,38,74,164,98,229,87,154,197,148,67,124,114,206,32,63,138,59,243,132,141,155,137,140,226,251,196,243,117,129,227,60,130,200,102,194,143,56,37,130,254,146,82,181,186,187,119,157,165,16,197,187,217,108,187,221,250,219,75,63,231,201,236,77,16,4,179,114,147,56,158,147,56,40,180,138,190,16,72,242,137,122,10,144,5,85,141,63,126,73,197,181,16,156,253,181,22,212,117,162,148,148,165,227,117,78,50,113,166,138,185,54,175,194,130,13,136,234,53,169,176,70,221,180,179,43,21,151,193,222,225,54,48,215,107,182,232,134,11,99,236,84,14,218,217,211,29,121,21,131,227,183,99,103,162,172,79,28,248,144,230,227,70,239,145,170,217,67,33,132,220,85,182,24,214,217,102,87,88,49,132,108,50,65,59,176,233,178,169,206,236,43,247,0,249,23,151,8,92,8,206,207,217,25,214,130,38,107,130,86,226,212,64,43,89,8,154,250,231,179,44,163,252,215,135,219,27,156,209,237,24,208,71,221,91,117,202,69,10,248,114,27,168,184,12,33,228,139,252,38,143,72,74,31,216,138,222,67,8,178,196,173,213,28,6,165,114,60,214,75,144,142,103,98,209,67,139,129,232,188,166,171,3,8,144,162,0,8,127,88,178,52,118,149,12,2,144,239,33,56,244,180,124,52,123,208,22,58,249,144,58,15,87,88,234,188,180,249,208,190,190,58,108,68,77,46,100,155,11,216,127,145,10,74,56,139,111,160,167,62,179,130,94,30,27,67,144,24,72,126,53,148,99,57,4,140,24,164,156,169,255,147,78,255,16,56,252,75,77,182,81,250,183,204,179,227,50,84,166,109,170,14,144,101,53,14,209,13,242,6,80,105,37,52,52,71,253,76,22,172,40,52,131,242,17,209,106,104,219,183,154,173,77,251,238,153,171,94,213,204,63,79,62,28,182,244,244,249,24,106,44,250,156,66,156,161,206,229,163,29,40,146,179,150,111,73,202,59,136,147,139,190,125,59,147,143,119,237,20,131,51,42,23,149,25,211,66,176,201,90,115,132,246,176,126,102,36,77,205,182,12,242,152,33,220,66,32,169,219,227,203,249,121,175,43,173,245,9,54,32,25,61,233,192,72,121,48,122,210,133,253,40,125,140,201,122,102,57,37,220,87,168,26,84,105,47,110,91,119,122,1,146,106,104,118,176,81,228,44,19,167,130,67,11,63,187,93,181,90,6,142,172,175,58,154,171,252,193,112,250,222,228,235,203,129,186,103,253,70,210,53,197,199,217,54,151,7,220,197,67,195,108,136,178,21,150,125,194,18,119,145,114,36,28,49,30,165,39,87,167,145,134,128,154,143,227,216,171,222,59,68,83,179,119,128,198,65,243,188,158,65,63,116,120,116,34,9,69,61,131,162,234,16,187,145,26,152,43,131,151,138,225,161,242,250,201,145,50,245,127,214,244,14,156,187,149,103,162,53,72,174,111,36,163,158,154,109,37,20,67,11,38,220,243,120,105,17,184,98,153,139,188,206,154,84,176,14,38,230,102,234,117,111,179,80,65,79,42,149,71,74,229,145,210,131,59,112,99,194,76,185,166,181,232,160,55,90,125,243,60,57,230,81,241,127,204,243,29,243,203,175,31,77,135,106,244,86,29,250,151,80,212,233,159,92,171,211,47,215,251,77,162,95,101,215,156,19,233,25,194,231,216,52,137,5,75,214,188,83,170,9,21,117,37,188,151,159,99,183,97,174,199,143,97,87,157,70,67,224,46,143,105,169,250,77,189,207,233,42,223,80,131,142,122,11,90,165,208,27,168,158,138,80,70,167,214,158,250,69,33,252,30,193,124,195,232,246,125,174,42,33,24,7,227,183,243,96,60,159,7,189,156,133,106,196,124,67,175,203,130,70,66,63,45,65,10,174,83,241,239,240,55,94,81,42,234,9,102,222,252,160,193,115,15,222,185,30,64,205,91,217,39,55,195,129,125,21,215,221,183,125,216,218,246,61,102,87,74,208,79,105,150,136,37,188,128,179,126,54,197,244,7,220,204,255,244,43,96,210,19,163,203,165,76,237,149,245,30,209,149,126,89,131,87,125,52,184,247,171,87,51,234,96,64,119,36,16,82,229,156,74,253,26,242,26,42,20,79,209,158,57,111,20,229,202,47,132,106,97,82,157,34,140,254,131,104,202,255,105,52,229,115,162,169,133,225,74,86,87,89,183,45,3,102,161,214,254,1,223,145,42,131,193,18,0,0 };
|
||||
|
@ -1,5 +1,27 @@
|
||||
// Old PNG File
|
||||
//const char HTML_INDEX[] PROGMEM = R"=====(
|
||||
//<!DOCTYPE html><html> <head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="shortcut icon" href=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAPFBMVEUAAACA1VWR21qQ2liR3FqR3FqS3VuR3VqR3VuR3VqO21mS21uS3FqS3FqS21uJ2GKQ21qR3FuR3FoAAAB/3Gu7AAAAEnRSTlMABoA3kPBwz8i5Kzioxg4NVcU3uEJHAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+EFEhcEM+HpYwQAAABYSURBVBjThY/JDsAgCESt4lpX/v9jLQZJ6qF9t3khAyj1xXUKbQ4BVowDwqOYgExkkW4iY6lPaF06RqM8YItOuRbMaz6xjbsusDAW/drplBg47jP696cXE8bPA1eUDeK2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA1LTE4VDIzOjA0OjUxKzAyOjAwxE59ewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNS0xOFQyMzowNDo1MSswMjowMLUTxccAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head> <body onload=javascript:start();> <div> <h4> <div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span> </h4> </div> <hr> <div class=container> <div id=row class="row u-full-width"></div> <ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul> <div id=tabscontent class="tabscontent u-full-width"></div> </div> </body> </html>
|
||||
//)=====";
|
||||
|
||||
// SVG Water Drop Icon
|
||||
//const char HTML_INDEX[] PROGMEM = R"=====(
|
||||
//<!DOCTYPE html><html> <head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="shortcut icon" href="data:image/svg+xml,%3Csvg data-name='Layer 1' xmlns='http://www.w3.org/2000/svg' viewBox='0 0 512 512'%3E%3Cpath d='M504.08 256C504.08 119 393 7.92 256 7.92S7.92 119 7.92 256 119 504.08 256 504.08 504.08 393 504.08 256z' style='fill:%23009040'/%3E%3Cpath d='M289.15 157.48A306.25 306.25 0 0 1 256 84.69a306.22 306.22 0 0 1-33.14 72.8c-28.24 56.86-73.39 86.85-73.39 158.38 0 61.55 45 111.44 106.53 111.44 61.55 0 106.53-49.89 106.53-111.44.01-71.54-45.14-101.52-73.38-158.39z' style='fill:%2398c8f0'/%3E%3Cpath d='M289.15 157.48A306.25 306.25 0 0 1 256 84.69s-61.57 342.62 0 342.62c61.55 0 106.53-49.89 106.53-111.44.01-71.54-45.14-101.52-73.38-158.39z' style='fill:%23b0e0ff'/%3E%3Cpath d='M262.08 409.12c48.17 0 83.38-39 83.38-87.22.01-55.99-131.55 87.22-83.38 87.22z' style='fill:%23ffffff'/%3E%3C/svg%3E"><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head> <body onload=javascript:start();> <div> <h4> <div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span> </h4> </div> <hr> <div class=container> <div id=row class="row u-full-width"></div> <ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul> <div id=tabscontent class="tabscontent u-full-width"></div> </div> </body> </html>
|
||||
//)=====";
|
||||
|
||||
// Apple icon only
|
||||
//const char HTML_INDEX[] PROGMEM = R"=====(
|
||||
//<!DOCTYPE html><html> <head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="apple-touch-icon" href=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAC0AQMAAAAHA5RxAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAGUExURYi/Sv///zEELvQAAAFGSURBVFjD7dUxbsUgEIRhLAqXPoKPskczRyNKkTJX4AiUFAhHr4g0kfZXslJKU36VwbOz6XZPT48//jqf4B/g7+Bv4JX8AjfwE/wA38Ez+AaeyC9wAz/BD/AdPINv4In8AjfwE/z44S19nx08g2/gifwCN/AT/ADfwTP4Bp7Ir3/y4Pfk4H2P4Hta8H8F85D/lDfK5+95tuC8BOdR59f8eV/m98M0v0+G+f3Tze+rZn6/VfP7sJjfn8ncvl3q0s9TXfp8qEv/d3XZF01d9ksV131UxHV/JXHZd0td9uNUl306wDt4A6/gBTz5vnTgxCf4AO/gDbyCF/Dk+wKf4AO8g7d/8h78nhm8L70PvmcN/q8ezAPlh/JG+cQ81+C89OA80vwu8Ju8gFfwBt7BB/gEX+A3eQGv4A28gw/wCb7Ab/L78cdf/gVoGRZWiw+tcgAAAABJRU5ErkJggg==><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head> <body onload=javascript:start();> <div> <h4> <div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span> </h4> </div> <hr> <div class=container> <div id=row class="row u-full-width"></div> <ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul> <div id=tabscontent class="tabscontent u-full-width"></div> </div> </body> </html>
|
||||
//)=====";
|
||||
|
||||
// SVG Logo Only
|
||||
//const char HTML_INDEX[] PROGMEM = R"=====(
|
||||
//<!DOCTYPE html><html> <head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="shortcut icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 180 180'%3E%3Cpath d='M74 46v28h55v27l40-40l-40-40v27zM104 100v28h-55v27l-40-40l40-40v27z' fill='%2388BF4A' /%3E%3C/svg%3E"><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head> <body onload=javascript:start();> <div> <h4> <div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span> </h4> </div> <hr> <div class=container> <div id=row class="row u-full-width"></div> <ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul> <div id=tabscontent class="tabscontent u-full-width"></div> </div> </body> </html>
|
||||
//)=====";
|
||||
|
||||
// SVG Logo & Apple icon
|
||||
const char HTML_INDEX[] PROGMEM = R"=====(
|
||||
<!DOCTYPE html><html> <head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="shortcut icon" href=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAMAAAAoLQ9TAAAABGdBTUEAALGPC/xhBQAAACBjSFJNAAB6JgAAgIQAAPoAAACA6AAAdTAAAOpgAAA6mAAAF3CculE8AAAAPFBMVEUAAACA1VWR21qQ2liR3FqR3FqS3VuR3VqR3VuR3VqO21mS21uS3FqS3FqS21uJ2GKQ21qR3FuR3FoAAAB/3Gu7AAAAEnRSTlMABoA3kPBwz8i5Kzioxg4NVcU3uEJHAAAAAWJLR0QAiAUdSAAAAAlwSFlzAAAN1wAADdcBQiibeAAAAAd0SU1FB+EFEhcEM+HpYwQAAABYSURBVBjThY/JDsAgCESt4lpX/v9jLQZJ6qF9t3khAyj1xXUKbQ4BVowDwqOYgExkkW4iY6lPaF06RqM8YItOuRbMaz6xjbsusDAW/drplBg47jP696cXE8bPA1eUDeK2AAAAJXRFWHRkYXRlOmNyZWF0ZQAyMDE3LTA1LTE4VDIzOjA0OjUxKzAyOjAwxE59ewAAACV0RVh0ZGF0ZTptb2RpZnkAMjAxNy0wNS0xOFQyMzowNDo1MSswMjowMLUTxccAAAAZdEVYdFNvZnR3YXJlAHd3dy5pbmtzY2FwZS5vcmeb7jwaAAAAAElFTkSuQmCC><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head> <body onload=javascript:start();> <div> <h4> <div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span> </h4> </div> <hr> <div class=container> <div id=row class="row u-full-width"></div> <ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul> <div id=tabscontent class="tabscontent u-full-width"></div> </div> </body> </html>
|
||||
<!DOCTYPE html><html><head><meta charset=utf-8><title>Control</title><meta name=viewport content="width=device-width, initial-scale=1"><link rel="shortcut icon" href="data:image/svg+xml,%3Csvg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 180 180'%3E%3Cpath d='M74 46v28h55v27l40-40l-40-40v27zM104 100v28h-55v27l-40-40l40-40v27z' fill='%2388BF4A' /%3E%3C/svg%3E"><link rel="apple-touch-icon" href=data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAALQAAAC0AQMAAAAHA5RxAAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsIAAA7CARUoSoAAAAAGUExURYi/Sv///zEELvQAAAFGSURBVFjD7dUxbsUgEIRhLAqXPoKPskczRyNKkTJX4AiUFAhHr4g0kfZXslJKU36VwbOz6XZPT48//jqf4B/g7+Bv4JX8AjfwE/wA38Ez+AaeyC9wAz/BD/AdPINv4In8AjfwE/z44S19nx08g2/gifwCN/AT/ADfwTP4Bp7Ir3/y4Pfk4H2P4Hta8H8F85D/lDfK5+95tuC8BOdR59f8eV/m98M0v0+G+f3Tze+rZn6/VfP7sJjfn8ncvl3q0s9TXfp8qEv/d3XZF01d9ksV131UxHV/JXHZd0td9uNUl306wDt4A6/gBTz5vnTgxCf4AO/gDbyCF/Dk+wKf4AO8g7d/8h78nhm8L70PvmcN/q8ezAPlh/JG+cQ81+C89OA80vwu8Ju8gFfwBt7BB/gEX+A3eQGv4A28gw/wCb7Ab/L78cdf/gVoGRZWiw+tcgAAAABJRU5ErkJggg==><link rel=stylesheet href=/css/normalize.css><link rel=stylesheet href=/css/style.css><script src=/js/zepto.min.js></script><script src=/js/slider.js></script><script src=/js/graph.js></script><script src=/js/controls.js></script><script src=/js/tabbedcontent.js></script></head><body onload=javascript:start();><div><h4><div id=mainHeader>Control</div> <span id=conStatus class=label>Offline</span></h4></div><hr><div class=container><div id=row class="row u-full-width"></div><ul id=tabsnav class="navigation navigation-tabs u-full-width"></ul><div id=tabscontent class="tabscontent u-full-width"></div></div></body></html>
|
||||
)=====";
|
||||
|
||||
|
||||
const uint8_t HTML_INDEX_GZIP[916] PROGMEM = { 31,139,8,0,210,8,51,99,2,255,133,148,235,115,162,58,20,192,255,21,174,159,238,157,221,22,95,181,237,174,56,19,20,108,85,68,64,240,241,45,64,42,193,240,40,9,162,254,245,155,128,157,238,157,189,211,235,12,201,201,57,191,243,200,17,206,240,175,137,57,94,239,86,154,20,177,132,140,134,245,42,13,35,4,195,209,48,65,12,74,65,4,11,138,152,82,178,183,187,167,209,144,97,70,208,104,156,165,172,200,200,80,110,142,13,153,194,4,41,39,140,170,60,43,152,20,112,4,165,76,105,85,56,100,145,18,162,19,14,208,93,125,248,46,225,20,51,12,201,29,13,32,65,74,167,53,26,18,156,30,165,2,17,165,69,35,238,30,148,76,194,60,68,75,138,10,244,166,132,144,193,31,56,129,7,36,231,233,225,167,15,41,26,244,191,99,79,53,237,170,61,159,30,50,192,127,75,199,141,52,247,192,37,85,28,129,53,6,134,216,179,133,245,188,22,130,58,13,213,181,171,1,176,152,174,198,242,57,82,45,174,28,171,177,163,207,150,220,58,152,113,223,195,43,87,174,68,188,49,24,240,53,20,158,102,46,162,14,18,190,232,189,113,80,18,237,73,196,91,233,170,225,105,110,205,118,188,141,221,237,188,91,93,130,237,158,254,46,30,167,231,149,118,207,227,114,179,155,221,78,226,116,59,165,83,219,248,195,229,89,119,58,183,184,31,231,57,163,139,188,170,220,155,150,143,34,190,150,218,206,154,24,64,205,64,239,184,82,171,235,19,126,152,95,113,118,62,244,151,94,224,246,74,109,246,82,223,116,51,91,216,109,11,96,224,134,78,173,32,149,163,147,171,232,73,167,2,96,18,6,170,133,177,143,106,91,216,118,220,142,174,126,211,116,45,10,52,227,219,75,190,171,68,35,212,157,227,218,170,167,198,235,104,39,207,38,20,28,198,154,195,250,36,223,202,167,231,120,97,237,103,131,119,253,153,245,142,17,184,196,157,243,214,157,251,86,95,245,178,106,82,189,155,187,131,118,62,30,55,125,188,27,144,21,212,219,3,251,221,120,218,189,50,179,180,125,3,94,7,231,216,167,37,157,128,141,28,22,57,81,15,253,199,120,53,120,30,4,91,237,201,95,129,14,114,39,104,222,21,213,205,182,182,190,121,177,143,187,173,77,204,100,121,217,111,244,246,222,2,23,99,162,245,22,107,208,89,172,181,190,55,121,189,154,49,104,155,177,123,158,95,193,133,203,213,89,123,120,70,149,248,43,188,182,237,69,237,253,148,251,173,115,230,119,237,124,159,30,129,17,131,243,242,210,174,150,78,251,108,234,214,197,184,102,213,114,146,117,12,135,86,70,156,85,198,194,93,159,131,64,148,176,15,53,111,23,234,203,211,62,181,123,187,237,140,128,151,176,23,94,30,114,63,97,215,93,87,175,246,206,195,41,72,144,255,24,87,176,110,169,70,244,245,209,41,173,100,60,254,237,77,166,236,66,16,141,16,98,205,75,44,7,148,202,105,86,36,144,224,43,186,231,167,255,131,107,101,3,210,160,192,57,147,104,17,40,114,76,229,43,202,89,118,159,224,244,62,230,70,185,177,254,65,81,130,67,84,124,137,28,10,152,71,95,18,65,243,173,211,47,33,6,125,31,133,183,111,254,223,164,92,15,19,105,232,103,225,69,202,82,146,193,80,137,225,9,54,246,31,148,193,130,253,253,207,79,78,132,248,36,102,79,191,17,37,28,42,9,196,233,11,119,71,197,231,200,105,40,154,195,84,16,60,165,195,32,43,169,20,16,72,169,66,160,143,200,200,124,123,227,157,69,188,8,142,113,90,174,131,222,92,163,226,150,160,241,16,69,243,52,168,248,76,91,100,213,205,216,18,98,121,247,86,18,210,204,46,62,170,110,97,74,34,80,126,113,154,194,143,88,45,46,226,3,100,56,75,165,79,241,78,64,127,68,41,201,103,66,1,220,154,247,17,233,119,213,127,23,240,177,137,198,214,119,172,103,247,47,103,53,186,226,210,5,0,0 };
|
||||
|
@ -1,5 +1,5 @@
|
||||
const char CSS_NORMALIZE[] PROGMEM = R"=====(
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:hidden}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
||||
)=====";
|
||||
|
||||
const uint8_t CSS_NORMALIZE_GZIP[861] PROGMEM = { 31,139,8,0,210,8,51,99,2,255,149,84,237,142,155,58,16,125,149,104,171,74,183,146,137,216,237,199,94,25,221,39,137,242,99,176,7,112,227,47,217,38,155,20,241,238,119,12,132,36,219,108,165,254,2,6,123,230,204,57,103,166,75,70,15,141,179,169,104,192,40,125,230,17,108,44,34,6,213,84,133,137,69,194,83,42,162,250,133,5,200,159,125,76,252,185,44,63,87,197,27,214,7,149,30,255,29,107,39,207,131,129,208,42,203,203,17,66,82,66,35,131,168,36,50,137,9,148,142,172,81,173,0,159,148,179,249,181,15,200,26,231,18,6,214,33,200,252,104,131,235,61,51,160,44,51,104,123,102,225,200,34,138,233,70,236,13,165,63,15,82,69,175,225,204,107,237,196,97,132,94,42,199,4,216,35,68,230,131,107,3,198,200,142,84,213,173,39,149,213,202,98,49,93,168,142,152,161,129,46,64,171,214,242,26,34,230,191,115,34,110,93,250,103,39,136,153,224,116,220,127,89,83,88,103,177,234,80,181,93,162,238,118,157,146,18,237,158,37,52,244,59,225,221,185,17,134,26,196,33,247,98,101,33,156,118,129,167,64,12,123,8,104,211,8,28,168,163,35,145,195,59,71,112,6,215,167,12,33,211,86,215,97,151,84,210,184,31,106,23,136,147,162,118,41,57,195,159,253,105,35,233,21,229,88,179,72,240,108,59,43,248,54,131,170,157,150,163,108,236,28,140,233,172,145,171,68,61,138,177,123,94,130,36,25,127,65,83,45,42,109,127,188,162,217,148,35,125,30,110,16,243,79,77,83,86,51,236,79,101,89,142,209,128,214,55,41,254,37,181,99,79,40,122,127,19,125,253,254,185,154,104,190,176,84,121,23,85,86,142,7,36,142,168,225,15,185,207,153,146,243,188,216,126,71,147,115,15,75,215,197,246,37,71,148,105,23,58,136,163,120,108,39,153,120,32,239,124,25,50,131,141,118,111,124,214,100,156,141,117,113,226,51,117,248,173,244,167,177,11,67,97,220,47,162,243,148,241,42,219,242,44,51,233,145,67,213,7,225,85,113,79,41,215,74,208,39,55,10,71,198,62,212,146,76,135,44,130,241,119,3,101,156,117,164,183,64,182,190,85,87,174,8,213,88,247,212,161,101,202,250,62,49,231,211,108,125,34,132,236,206,242,136,145,89,96,152,101,80,182,163,217,76,83,134,245,99,157,181,57,211,21,222,81,69,85,107,188,84,152,83,14,211,212,78,54,108,92,48,179,81,151,19,29,173,131,205,4,100,151,206,30,255,123,154,227,79,123,118,27,164,193,194,244,46,70,82,25,69,193,225,178,27,192,123,4,42,34,144,207,73,42,209,135,72,45,120,167,136,214,176,148,220,209,188,0,97,148,251,219,226,107,112,88,46,73,108,160,215,105,185,196,249,164,96,227,68,31,11,101,45,45,140,233,222,239,241,213,44,149,7,41,179,168,229,56,29,29,110,29,106,137,7,208,227,109,63,162,67,113,32,225,223,183,14,180,27,158,242,72,174,46,89,167,243,244,190,198,114,199,246,166,198,240,180,39,116,11,55,19,180,34,122,101,139,91,241,63,60,79,107,225,254,252,176,0,159,252,119,39,3,113,46,186,199,50,100,221,27,133,90,86,127,242,255,229,226,95,141,199,67,12,87,252,115,164,16,25,134,126,212,242,135,87,36,10,23,32,239,142,71,29,77,214,157,90,34,67,94,164,206,251,49,58,173,228,38,42,77,147,176,142,199,230,197,95,37,218,126,165,117,178,217,254,120,153,30,175,121,183,104,108,209,202,71,142,89,135,240,126,240,47,179,250,251,250,77,217,189,151,189,77,147,171,193,71,228,151,151,106,249,145,151,193,82,64,178,212,13,215,130,255,3,4,241,118,208,151,7,0,0 };
|
||||
const char CSS_NORMALIZE[] PROGMEM = R"=====(
|
||||
html{font-family:sans-serif;-ms-text-size-adjust:100%;-webkit-text-size-adjust:100%}body{margin:0}article,aside,details,figcaption,figure,footer,header,hgroup,main,menu,nav,section,summary{display:block}audio,canvas,progress,video{display:inline-block;vertical-align:baseline}audio:not([controls]){display:none;height:0}[hidden],template{display:none}a{background-color:transparent}a:active,a:hover{outline:0}abbr[title]{border-bottom:1px dotted}b,strong{font-weight:bold}dfn{font-style:italic}h1{font-size:2em;margin:.67em 0}mark{background:#ff0;color:#000}small{font-size:80%}sub,sup{font-size:75%;line-height:0;position:relative;vertical-align:baseline}sup{top:-.5em}sub{bottom:-.25em}img{border:0}svg:not(:root){overflow:visible}figure{margin:1em 40px}hr{-moz-box-sizing:content-box;box-sizing:content-box;height:0}pre{overflow:auto}code,kbd,pre,samp{font-family:monospace,monospace;font-size:1em}button,input,optgroup,select,textarea{color:inherit;font:inherit;margin:0}button{overflow:visible}button,select{text-transform:none}button,html input[type="button"],input[type="reset"],input[type="submit"]{-webkit-appearance:button;cursor:pointer}button[disabled],html input[disabled]{cursor:default}button::-moz-focus-inner,input::-moz-focus-inner{border:0;padding:0}input{line-height:normal}input[type="checkbox"],input[type="radio"]{box-sizing:border-box;padding:0}input[type="number"]::-webkit-inner-spin-button,input[type="number"]::-webkit-outer-spin-button{height:auto}input[type="search"]{-webkit-appearance:textfield;-moz-box-sizing:content-box;-webkit-box-sizing:content-box;box-sizing:content-box}input[type="search"]::-webkit-search-cancel-button,input[type="search"]::-webkit-search-decoration{-webkit-appearance:none}fieldset{border:1px solid silver;margin:0 2px;padding:.35em .625em .75em}legend{border:0;padding:0}textarea{overflow:auto}optgroup{font-weight:bold}table{border-collapse:collapse;border-spacing:0}td,th{padding:0}
|
||||
)=====";
|
||||
|
||||
const uint8_t CSS_NORMALIZE_GZIP[859] PROGMEM = { 31,139,8,0,53,140,123,99,2,255,149,84,237,110,163,58,16,125,149,168,171,74,187,146,137,104,247,163,87,70,247,73,162,252,24,236,1,124,227,47,217,38,77,22,241,238,59,6,66,147,54,93,233,254,2,6,123,230,204,57,103,166,75,70,15,141,179,169,104,192,40,125,230,17,108,44,34,6,213,84,133,137,69,194,83,42,162,250,141,5,200,255,250,152,248,83,89,62,86,197,43,214,7,149,238,255,29,107,39,207,131,129,208,42,203,203,17,66,82,66,35,131,168,36,50,137,9,148,142,172,81,173,0,159,148,179,249,181,15,200,26,231,18,6,214,33,200,252,104,131,235,61,51,160,44,51,104,123,102,225,200,34,138,233,70,236,13,165,63,15,82,69,175,225,204,107,237,196,97,132,94,42,199,4,216,35,68,230,131,107,3,198,200,142,84,213,173,39,149,213,202,98,49,93,168,142,152,161,129,46,64,171,214,242,26,34,230,191,115,34,110,93,250,186,19,196,76,112,58,238,191,173,41,172,179,88,117,168,218,46,81,119,187,78,73,137,118,207,18,26,250,157,240,230,220,8,67,13,226,144,123,177,178,16,78,187,192,83,32,134,61,4,180,105,4,14,212,209,145,200,225,157,35,56,131,235,83,134,144,105,171,235,176,75,42,105,220,15,181,11,196,73,81,187,148,156,225,79,254,180,145,244,138,114,172,89,36,120,182,157,21,124,157,65,213,78,203,81,54,118,14,198,116,214,200,85,162,30,197,216,61,45,65,146,140,63,163,169,22,149,182,191,94,208,108,202,145,62,15,87,136,249,151,166,41,171,25,246,151,178,44,199,104,64,235,171,20,255,144,218,177,39,20,189,191,138,190,252,124,172,38,154,47,44,85,222,69,149,149,227,1,137,35,106,248,83,238,115,166,228,60,47,182,63,209,228,220,195,210,117,177,125,206,17,101,218,133,14,226,40,30,219,73,38,30,200,59,223,134,204,96,163,221,43,63,170,168,106,141,227,236,172,139,21,159,168,197,31,165,63,141,93,24,10,227,126,19,159,167,12,88,217,150,103,157,73,144,28,170,62,9,175,146,123,74,185,150,130,62,185,81,56,114,246,161,150,228,58,100,17,140,191,153,40,227,172,35,193,5,178,245,173,122,35,139,80,141,117,79,45,90,166,172,239,19,115,62,205,222,39,70,200,239,44,207,24,185,5,134,89,7,101,59,26,206,52,101,88,63,214,97,155,51,125,100,98,169,48,167,28,166,177,157,124,216,184,96,102,167,46,39,58,218,7,155,9,200,46,157,61,254,251,48,199,31,246,236,58,72,147,133,233,93,140,180,50,138,130,195,101,57,128,247,8,84,68,32,159,147,84,162,15,145,90,240,78,17,173,97,41,185,163,129,1,194,40,247,215,197,215,224,176,92,146,216,64,175,211,114,137,243,73,193,198,137,62,22,202,90,218,24,211,189,143,241,213,45,149,7,41,179,168,229,56,29,29,174,45,106,137,7,208,227,117,63,162,67,113,32,225,223,183,14,180,28,30,242,76,174,46,89,199,243,244,190,198,114,199,246,166,198,240,176,39,116,11,55,19,180,34,122,101,139,107,241,63,61,79,123,225,246,252,176,0,159,252,119,35,3,113,46,186,251,50,100,221,27,133,90,86,127,243,255,229,226,255,26,143,187,24,222,240,207,145,66,100,24,250,94,203,159,94,145,40,92,128,188,60,238,117,52,89,119,106,137,12,121,145,58,47,200,232,180,146,155,168,52,77,194,58,30,155,103,255,38,209,246,59,237,147,205,246,215,243,244,120,201,203,69,99,139,86,222,115,204,58,132,183,131,127,153,213,143,251,55,101,247,94,22,55,77,174,6,31,145,95,94,170,229,71,94,6,75,1,201,82,55,188,21,252,3,26,45,63,124,152,7,0,0 };
|
||||
|
Reference in New Issue
Block a user