From eec13e49342d6c8da13df7fb11bee93cfa2c05a6 Mon Sep 17 00:00:00 2001 From: Lukas Bachschwell Date: Tue, 23 Jun 2020 20:34:05 +0200 Subject: [PATCH] No reload per default, just send JsonDom --- README.md | 2 +- data/js/controls.js | 11 +- data/js/controls.min.js | 496 +++++++++++++++++----------------- src/ESPUI.cpp | 576 +++++++++++++++++++++++++++------------- src/ESPUI.h | 16 +- src/dataControlsJS.h | 506 +++++++++++++++++------------------ 6 files changed, 901 insertions(+), 706 deletions(-) diff --git a/README.md b/README.md index 7cfed9b..bcd4499 100644 --- a/README.md +++ b/README.md @@ -1,4 +1,4 @@ -# ESPUI (v2.X) +# ESPUI ![ESPUI](https://github.com/s00500/ESPUI/blob/master/docs/ui_complete.png) diff --git a/data/js/controls.js b/data/js/controls.js index 6d9aeb9..3cfd42c 100644 --- a/data/js/controls.js +++ b/data/js/controls.js @@ -232,6 +232,11 @@ function start() { var center = ""; switch (data.type) { case UI_INITIAL_GUI: + // Clear current elements + $("#row").html(""); + $("#tabsnav").html(""); + $("#tabscontent").html(""); + if (data.sliderContinuous) { sliderContinuous = data.sliderContinuous; } @@ -242,9 +247,9 @@ function start() { handleEvent(fauxEvent); }); break; - case UI_RELOAD: - window.location.reload(); - break; + case UI_RELOAD: + window.location.reload(); + break; case UI_TITEL: document.title = data.label; diff --git a/data/js/controls.min.js b/data/js/controls.min.js index 6c023de..ff0e134 100644 --- a/data/js/controls.min.js +++ b/data/js/controls.min.js @@ -1,249 +1,249 @@ -const UI_INITIAL_GUI=200;const UI_RELOAD=201;const UPDATE_OFFSET=100;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 UPTDATE_ACCEL=117;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_NONE:return"dark";default:return"";}} -var websock;var websockConnected=false;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("");websock.close();start();} -function conStatusError(){websockConnected=false;$("#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");} -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(evt);conStatusError();};var handleEvent=function(evt){var data=JSON.parse(evt.data);var e=document.body;var center="";switch(data.type){case UI_INITIAL_GUI:if(data.sliderContinuous){sliderContinuous=data.sliderContinuous;} -data.controls.forEach(element=>{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});break;case UI_RELOAD:window.location.reload();break;case UI_TITEL:document.title=data.label;$("#mainHeader").html(data.label);break;case UI_LABEL:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
"+ -"
"+ -data.label+ -"

"+ -""+ -data.value+ -""+ -"
");break;case UI_BUTTON:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
"+ -"
"+ -data.label+ -"

"+ -"
");$("#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:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
"+ -"
"+ -data.label+ -"

"+ -""+ -"
");switcher(data.id,data.value);break;case UI_CPAD:case UI_PAD:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
"+ -"
"+ -data.label+ -"

"+ -""+ -"
");$("#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:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
"+ -"
"+ -data.label+ -"

"+ -"
"+ -""+ -""+ -data.value+ -""+ -"
"+ -"
");rangeSlider(!sliderContinuous);break;case UI_NUMBER:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
"+ -"
"+ -data.label+ -"

"+ -""+ -"
");break;case UI_TEXT_INPUT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
"+ -"
"+ -data.label+ -"

"+ -""+ -"
");break;case UI_TAB:$("#tabsnav").append("
  • "+data.value+"
  • ");$("#tabscontent").append("
    ");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_SELECT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -parent.append("
    "+ -"
    "+ -data.label+ -"

    "+ -""+ -"
    ");break;case UI_ACCEL:if(hasAccel)break;var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} -hasAccel=true;parent.append("
    "+ -"
    "+ -data.label+ -"

    "+ -"ACCEL // Not implemented fully!
    "+
    -"
    ");requestOrientationPermission();break;case UPDATE_LABEL:$("#l"+data.id).html(data.value);break;case UPDATE_SWITCHER:switcher(data.id,data.value=="0"?0:1);break;case UPDATE_SLIDER:slider_move($("#sl"+data.id),data.value,"100",false);break;case UPDATE_NUMBER:$("#num"+data.id).val(data.value);break;case UPDATE_TEXT_INPUT:$("#text"+data.id).val(data.value);break;case UPDATE_SELECT:$("#select"+data.id).val(data.value);break;case UPDATE_BUTTON:case UPDATE_PAD:case UPDATE_CPAD:break;case UPDATE_GAUGE:$("#gauge"+data.id).val(data.value);break;case UPDATE_ACCEL:break;default:console.error("Unknown type or event");break;} -if(data.type>=UPDATE_OFFSET&&data.type{var fauxEvent={data:JSON.stringify(element),};handleEvent(fauxEvent);});break;case UI_RELOAD:window.location.reload();break;case UI_TITEL:document.title=data.label;$("#mainHeader").html(data.label);break;case UI_LABEL:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +""+ +data.value+ +""+ +"
    ");break;case UI_BUTTON:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +"
    ");$("#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:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +""+ +"
    ");switcher(data.id,data.value);break;case UI_CPAD:case UI_PAD:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +""+ +"
    ");$("#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:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +"
    "+ +""+ +""+ +data.value+ +""+ +"
    "+ +"
    ");rangeSlider(!sliderContinuous);break;case UI_NUMBER:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +""+ +"
    ");break;case UI_TEXT_INPUT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +""+ +"
    ");break;case UI_TAB:$("#tabsnav").append("
  • "+data.value+"
  • ");$("#tabscontent").append("
    ");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_SELECT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +""+ +"
    ");break;case UI_ACCEL:if(hasAccel)break;var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} +hasAccel=true;parent.append("
    "+ +"
    "+ +data.label+ +"

    "+ +"ACCEL // Not implemented fully!
    "+
    +"
    ");requestOrientationPermission();break;case UPDATE_LABEL:$("#l"+data.id).html(data.value);break;case UPDATE_SWITCHER:switcher(data.id,data.value=="0"?0:1);break;case UPDATE_SLIDER:slider_move($("#sl"+data.id),data.value,"100",false);break;case UPDATE_NUMBER:$("#num"+data.id).val(data.value);break;case UPDATE_TEXT_INPUT:$("#text"+data.id).val(data.value);break;case UPDATE_SELECT:$("#select"+data.id).val(data.value);break;case UPDATE_BUTTON:case UPDATE_PAD:case UPDATE_CPAD:break;case UPDATE_GAUGE:$("#gauge"+data.id).val(data.value);break;case UPDATE_ACCEL:break;default:console.error("Unknown type or event");break;} +if(data.type>=UPDATE_OFFSET&&data.typeverbosity) { + if (this->verbosity) + { Serial.println("About to prepare filesystem..."); } #if defined(ESP32) LittleFS.format(); - if (!LittleFS.begin(true)) { - if (this->verbosity) { + if (!LittleFS.begin(true)) + { + if (this->verbosity) + { Serial.println("SPIFFS Mount Failed"); } return; } - if (this->verbosity) { + if (this->verbosity) + { listDir("/", 1); Serial.println("SPIFFS Mount ESP32 Done"); } @@ -206,7 +252,8 @@ void ESPUIClass::prepareFileSystem() { LittleFS.format(); LittleFS.begin(); - if (this->verbosity) { + if (this->verbosity) + { Serial.println("SPIFFS Mount ESP8266 Done"); } @@ -223,7 +270,8 @@ void ESPUIClass::prepareFileSystem() { deleteFile("/js/graph.js"); deleteFile("/js/tabbedcontent.js"); - if (this->verbosity) { + if (this->verbosity) + { Serial.println("Cleanup done"); } @@ -240,13 +288,15 @@ void ESPUIClass::prepareFileSystem() { writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT); - if (this->verbosity) { + if (this->verbosity) + { Serial.println("Done Initializing filesystem :-)"); } #if defined(ESP32) - if (this->verbosity) { + if (this->verbosity) + { listDir("/", 1); } @@ -256,56 +306,71 @@ void ESPUIClass::prepareFileSystem() { } // Handle Websockets Communication -void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) { - switch (type) { - case WS_EVT_DISCONNECT: { - if (ESPUI.verbosity) { +void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) +{ + switch (type) + { + case WS_EVT_DISCONNECT: + { + if (ESPUI.verbosity) + { Serial.printf("Disconnected!\n"); } break; } - case WS_EVT_PONG: { - if (ESPUI.verbosity) { + case WS_EVT_PONG: + { + if (ESPUI.verbosity) + { Serial.printf("Received PONG!\n"); } break; } - case WS_EVT_ERROR: { - if (ESPUI.verbosity) { + case WS_EVT_ERROR: + { + if (ESPUI.verbosity) + { Serial.printf("WebSocket Error!\n"); } break; } - case WS_EVT_CONNECT: { - if (ESPUI.verbosity) { + case WS_EVT_CONNECT: + { + if (ESPUI.verbosity) + { Serial.print("Connected: "); Serial.println(client->id()); } ESPUI.jsonDom(client); - if (ESPUI.verbosity) { + if (ESPUI.verbosity) + { Serial.println("JSON Data Sent to Client!"); } - } break; + } + break; - case WS_EVT_DATA: { + case WS_EVT_DATA: + { String msg = ""; msg.reserve(len + 1); - for (size_t i = 0; i < len; i++) { + for (size_t i = 0; i < len; i++) + { msg += (char)data[i]; } uint16_t id = msg.substring(msg.lastIndexOf(':') + 1).toInt(); - if (ESPUI.verbosity >= Verbosity::VerboseJSON) { + if (ESPUI.verbosity >= Verbosity::VerboseJSON) + { Serial.print("WS rec: "); Serial.println(msg); Serial.print("WS recognised ID: "); @@ -314,8 +379,10 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp Control *c = ESPUI.getControl(id); - if (c == nullptr) { - if (ESPUI.verbosity) { + if (c == nullptr) + { + if (ESPUI.verbosity) + { Serial.print("No control found for ID "); Serial.println(id); } @@ -323,8 +390,10 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp return; } - if (c->callback == nullptr) { - if (ESPUI.verbosity) { + if (c->callback == nullptr) + { + if (ESPUI.verbosity) + { Serial.print("No callback found for ID "); Serial.println(id); } @@ -332,60 +401,99 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp return; } - if (msg.startsWith("bdown:")) { + if (msg.startsWith("bdown:")) + { c->callback(c, B_DOWN); - } else if (msg.startsWith("bup:")) { + } + else if (msg.startsWith("bup:")) + { c->callback(c, B_UP); - } else if (msg.startsWith("pfdown:")) { + } + else if (msg.startsWith("pfdown:")) + { c->callback(c, P_FOR_DOWN); - } else if (msg.startsWith("pfup:")) { + } + else if (msg.startsWith("pfup:")) + { c->callback(c, P_FOR_UP); - } else if (msg.startsWith("pldown:")) { + } + else if (msg.startsWith("pldown:")) + { c->callback(c, P_LEFT_DOWN); - } else if (msg.startsWith("plup:")) { + } + else if (msg.startsWith("plup:")) + { c->callback(c, P_LEFT_UP); - } else if (msg.startsWith("prdown:")) { + } + else if (msg.startsWith("prdown:")) + { c->callback(c, P_RIGHT_DOWN); - } else if (msg.startsWith("prup:")) { + } + else if (msg.startsWith("prup:")) + { c->callback(c, P_RIGHT_UP); - } else if (msg.startsWith("pbdown:")) { + } + else if (msg.startsWith("pbdown:")) + { c->callback(c, P_BACK_DOWN); - } else if (msg.startsWith("pbup:")) { + } + else if (msg.startsWith("pbup:")) + { c->callback(c, P_BACK_UP); - } else if (msg.startsWith("pcdown:")) { + } + else if (msg.startsWith("pcdown:")) + { c->callback(c, P_CENTER_DOWN); - } else if (msg.startsWith("pcup:")) { + } + else if (msg.startsWith("pcup:")) + { c->callback(c, P_CENTER_UP); - } else if (msg.startsWith("sactive:")) { + } + else if (msg.startsWith("sactive:")) + { c->value = "1"; ESPUI.updateControl(c, client->id()); c->callback(c, S_ACTIVE); - } else if (msg.startsWith("sinactive:")) { + } + else if (msg.startsWith("sinactive:")) + { c->value = "0"; ESPUI.updateControl(c, client->id()); c->callback(c, S_INACTIVE); - } else if (msg.startsWith("slvalue:")) { + } + else if (msg.startsWith("slvalue:")) + { c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); ESPUI.updateControl(c, client->id()); c->callback(c, SL_VALUE); - } else if (msg.startsWith("nvalue:")) { + } + else if (msg.startsWith("nvalue:")) + { c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); ESPUI.updateControl(c, client->id()); c->callback(c, N_VALUE); - } else if (msg.startsWith("tvalue:")) { + } + else if (msg.startsWith("tvalue:")) + { c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); ESPUI.updateControl(c, client->id()); c->callback(c, T_VALUE); - } else if (msg.startsWith("svalue:")) { + } + else if (msg.startsWith("svalue:")) + { c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); ESPUI.updateControl(c, client->id()); c->callback(c, S_VALUE); - } else { - if (ESPUI.verbosity) { + } + else + { + if (ESPUI.verbosity) + { Serial.println("Malformated message from the websocket"); } } - } break; + } + break; default: break; @@ -393,15 +501,20 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp } uint16_t ESPUIClass::addControl(ControlType type, const char *label, String value, ControlColor color, uint16_t parentControl, - void (*callback)(Control *, int)) { + void (*callback)(Control *, int)) +{ Control *control = new Control(type, label, callback, value, color, parentControl); - if (this->controls == nullptr) { + if (this->controls == nullptr) + { this->controls = control; - } else { + } + else + { Control *iterator = this->controls; - while (iterator->next != nullptr) { + while (iterator->next != nullptr) + { iterator = iterator->next; } @@ -411,57 +524,59 @@ uint16_t ESPUIClass::addControl(ControlType type, const char *label, String valu return control->id; } -bool ESPUIClass::remControl(uint16_t id, bool reload_ui) +bool ESPUIClass::removeControl(uint16_t id, bool force_reload_ui) { - if(nullptr == this->controls) return false; + if (nullptr == this->controls) + return false; - Control * it = this->controls; - - if(id == it->id) { + Control *it = this->controls; + + if (id == it->id) + { this->controls = it->next; delete it; - if(reload_ui) { - reload(); + if (force_reload_ui) + { + jsonReload(); + } + else + { + jsonDom(); } return true; } - Control * it_next = it->next; - while(nullptr != it_next && id != it_next->id) { + Control *it_next = it->next; + while (nullptr != it_next && id != it_next->id) + { it = it_next; it_next = it_next->next; } - if(nullptr != it_next) { + if (nullptr != it_next) + { it->next = it_next->next; delete it_next; - if(reload_ui) { - reload(); - } + if (force_reload_ui) + { + jsonReload(); + } + else + { + jsonDom(); + } return true; } - + return false; } -void ESPUIClass::reload() -{ - int tryId = 0; - - for (int count = 0; count < this->ws->count();) { - if (this->ws->hasClient(tryId)) { - ESPUI.jsonReload(this->ws->client(tryId)); - count++; - } - tryId++; - } -} - uint16_t ESPUIClass::label(const char *label, ControlColor color, String value) { return addControl(ControlType::Label, label, value, color); } 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 sliderId = addControl(ControlType::Slider, label, String(value), color, Control::noParent, callback); addControl(ControlType::Min, label, String(min), ControlColor::None, sliderId); addControl(ControlType::Max, label, String(max), ControlColor::None, sliderId); @@ -469,48 +584,59 @@ uint16_t ESPUIClass::slider(const char *label, void (*callback)(Control *, int), return sliderId; } -uint16_t ESPUIClass::button(const char *label, void (*callback)(Control *, int), ControlColor color, String value) { +uint16_t ESPUIClass::button(const char *label, void (*callback)(Control *, int), ControlColor color, String value) +{ return addControl(ControlType::Button, label, value, color, Control::noParent, callback); } -uint16_t ESPUIClass::switcher(const char *label, void (*callback)(Control *, int), ControlColor color, bool startState) { +uint16_t ESPUIClass::switcher(const char *label, void (*callback)(Control *, int), ControlColor color, bool startState) +{ return addControl(ControlType::Switcher, label, startState ? "1" : "0", color, Control::noParent, callback); } -uint16_t ESPUIClass::pad(const char *label, void (*callback)(Control *, int), ControlColor color) { +uint16_t ESPUIClass::pad(const char *label, void (*callback)(Control *, int), ControlColor color) +{ return addControl(ControlType::Pad, label, "", color, Control::noParent, callback); } -uint16_t ESPUIClass::padWithCenter(const char *label, void (*callback)(Control *, int), ControlColor color) { +uint16_t ESPUIClass::padWithCenter(const char *label, void (*callback)(Control *, int), ControlColor color) +{ return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback); } -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); addControl(ControlType::Max, label, String(max), ControlColor::None, numberId); return numberId; } -uint16_t ESPUIClass::gauge(const char *label, ControlColor color, int number, int min, int max) { +uint16_t ESPUIClass::gauge(const char *label, ControlColor color, int number, int min, int max) +{ uint16_t numberId = addControl(ControlType::Gauge, label, String(number), color, Control::noParent); addControl(ControlType::Min, label, String(min), ControlColor::None, numberId); addControl(ControlType::Max, label, String(max), ControlColor::None, numberId); return numberId; } -uint16_t ESPUIClass::accelerometer(const char *label, void (*callback)(Control *, int), ControlColor color) { +uint16_t ESPUIClass::accelerometer(const char *label, void (*callback)(Control *, int), ControlColor color) +{ return addControl(ControlType::Accel, label, "", color, Control::noParent, callback); } -uint16_t ESPUIClass::text(const char *label, void (*callback)(Control *, int), ControlColor color, String value) { +uint16_t ESPUIClass::text(const char *label, void (*callback)(Control *, int), ControlColor color, String value) +{ return addControl(ControlType::Text, label, value, color, Control::noParent, callback); } -Control *ESPUIClass::getControl(uint16_t id) { +Control *ESPUIClass::getControl(uint16_t id) +{ Control *control = this->controls; - while (control != nullptr) { - if (control->id == id) { + while (control != nullptr) + { + if (control->id == id) + { return control; } @@ -520,8 +646,10 @@ Control *ESPUIClass::getControl(uint16_t id) { return nullptr; } -void ESPUIClass::updateControl(Control *control, int clientId) { - if (!control) { +void ESPUIClass::updateControl(Control *control, int clientId) +{ + if (!control) + { return; } @@ -535,11 +663,13 @@ void ESPUIClass::updateControl(Control *control, int clientId) { root["color"] = (int)control->color; serializeJson(document, json); - if (this->verbosity >= Verbosity::VerboseJSON) { + if (this->verbosity >= Verbosity::VerboseJSON) + { Serial.println(json); } - if (clientId < 0) { + if (clientId < 0) + { this->ws->textAll(json); return; } @@ -547,12 +677,16 @@ void ESPUIClass::updateControl(Control *control, int clientId) { // function like this and it's clients array is private int tryId = 0; - for (int count = 0; count < this->ws->count();) { - if (this->ws->hasClient(tryId)) { - if (clientId != tryId) { + for (int count = 0; count < this->ws->count();) + { + if (this->ws->hasClient(tryId)) + { + if (clientId != tryId) + { this->ws->client(tryId)->text(json); - if (this->verbosity >= Verbosity::VerboseJSON) { + if (this->verbosity >= Verbosity::VerboseJSON) + { Serial.println(json); } } @@ -564,11 +698,14 @@ void ESPUIClass::updateControl(Control *control, int clientId) { } } -void ESPUIClass::updateControl(uint16_t id, int clientId) { +void ESPUIClass::updateControl(uint16_t id, int clientId) +{ Control *control = getControl(id); - if (!control) { - if (this->verbosity) { + if (!control) + { + if (this->verbosity) + { Serial.println(String("Error: There is no control with ID ") + String(id)); } return; @@ -577,8 +714,10 @@ void ESPUIClass::updateControl(uint16_t id, int clientId) { updateControl(control, clientId); } -void ESPUIClass::updateControlValue(Control *control, String value, int clientId) { - if (!control) { +void ESPUIClass::updateControlValue(Control *control, String value, int clientId) +{ + if (!control) + { return; } @@ -586,11 +725,14 @@ void ESPUIClass::updateControlValue(Control *control, String value, int clientId updateControl(control, clientId); } -void ESPUIClass::updateControlValue(uint16_t id, String value, int clientId) { +void ESPUIClass::updateControlValue(uint16_t id, String value, int clientId) +{ Control *control = getControl(id); - if (!control) { - if (this->verbosity) { + if (!control) + { + if (this->verbosity) + { Serial.println(String("Error: There is no control with ID ") + String(id)); } return; @@ -617,9 +759,11 @@ void ESPUIClass::updateGauge(uint16_t id, int number, int clientId) { updateCont void ESPUIClass::clearGraph(uint16_t id, int clientId) {} -void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId) { +void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId) +{ Control *control = getControl(id); - if (!control) { + if (!control) + { return; } @@ -632,11 +776,13 @@ void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId) { root["id"] = control->id; serializeJson(document, json); - if (this->verbosity >= Verbosity::VerboseJSON) { + if (this->verbosity >= Verbosity::VerboseJSON) + { Serial.println(json); } - if (clientId < 0) { + if (clientId < 0) + { this->ws->textAll(json); return; } @@ -644,12 +790,16 @@ void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId) { // function like this and it's clients array is private int tryId = 0; - for (int count = 0; count < this->ws->count();) { - if (this->ws->hasClient(tryId)) { - if (clientId != tryId) { + for (int count = 0; count < this->ws->count();) + { + if (this->ws->hasClient(tryId)) + { + if (clientId != tryId) + { this->ws->client(tryId)->text(json); - if (this->verbosity >= Verbosity::VerboseJSON) { + if (this->verbosity >= Verbosity::VerboseJSON) + { Serial.println(json); } } @@ -666,7 +816,8 @@ Initially this function used to send the control element data individually. Due to a change in the ESPAsyncWebserver library this had top be changed to be sent as one blob at the beginning. Therefore a new type is used as well */ -void ESPUIClass::jsonDom(AsyncWebSocketClient *client) { +void ESPUIClass::jsonDom(AsyncWebSocketClient *client) +{ String json; DynamicJsonDocument document(jsonInitialDocumentSize); document["type"] = (int)UI_INITIAL_GUI; @@ -679,7 +830,8 @@ void ESPUIClass::jsonDom(AsyncWebSocketClient *client) { titleItem["type"] = (int)UI_TITLE; titleItem["label"] = ui_title; - while (control != nullptr) { + while (control != nullptr) + { JsonObject item = items.createNestedObject(); item["id"] = String(control->id); @@ -688,16 +840,21 @@ void ESPUIClass::jsonDom(AsyncWebSocketClient *client) { item["value"] = String(control->value); item["color"] = (int)control->color; - if (control->parentControl != Control::noParent) { + if (control->parentControl != Control::noParent) + { item["parentControl"] = String(control->parentControl); } // special case for selects: to preselect an option, you have to add // "selected" to