1
0
mirror of https://github.com/s00500/ESPUI.git synced 2025-07-03 19:50:20 +00:00

25 Commits

Author SHA1 Message Date
4142e37eae Attempt fixing switcher inconsistent state
Signed-off-by: Lukas Bachschwell <lukas@lbsfilm.at>
2021-06-14 15:06:08 +02:00
0587918621 Merge pull request #109 from A-damW/master
Update README.md
2021-02-06 09:42:08 +01:00
48826caee6 Merge pull request #114 from tecteun/master
slider sends (browser dependent) lots of events, throttle using only …
2021-02-06 09:41:26 +01:00
9ab8a84ff0 slider sends (browser dependent) lots of events, throttle using only unique values. 2021-02-05 22:03:02 +00:00
d12da60df4 Update README.md
Minor typo, line 107, "to to" > "to do"
2021-01-10 08:20:16 +00:00
8cdedaf3cb Merge pull request #106 from marcusmiess/master-fix-pad-arrows
Fix for pad arrows
2021-01-02 10:10:54 +01:00
02d981cc2b Changed the ascii arrow to the HTML equivalent. Fixes the problem, where the pad arrow strings got broken. 2021-01-02 00:23:13 +01:00
4827688635 Version 2.0.2
Signed-off-by: Lukas Bachschwell <lukas@lbsfilm.at>
2020-10-19 08:57:59 +02:00
b71bc81c0d Fixing rebase errors with littlefs/debug refactor
Signed-off-by: Lukas Bachschwell <lukas@lbsfilm.at>
2020-10-18 11:06:38 +02:00
a6ddd48abb Fix all other occurences
Signed-off-by: Lukas Bachschwell <lukas@lbsfilm.at>
2020-10-17 22:46:22 +02:00
8c0161b181 Fix prepare fs example
Signed-off-by: Lukas Bachschwell <lukas@lbsfilm.at>
2020-10-16 14:47:32 +02:00
3cf1aa7f49 Fix littleFS does not exist on esp32
Signed-off-by: Lukas Bachschwell <lukas@lbsfilm.at>
2020-10-16 14:47:29 +02:00
313a069d4c Change idcounter to start at 1, closes #95 2020-10-02 19:08:45 +02:00
34d974b03b Merge pull request #97 from ericBcreator/add_tab_callback_function
Add tab callback function
2020-10-02 19:04:26 +02:00
1de52c939f Add files via upload 2020-10-01 20:28:22 +02:00
950a1fb029 Add files via upload 2020-10-01 20:27:01 +02:00
5a167091cc Update controls.js 2020-10-01 18:57:24 +02:00
57a81dbee3 Update ESPUI.cpp 2020-10-01 18:51:54 +02:00
acaf6898fd Update controls.js 2020-10-01 18:49:18 +02:00
37bbb9208d Merge pull request #91 from enwi/master
Reduce HEAP usage
2020-10-01 18:37:45 +02:00
6b2ef81b12 Fix include of ESPUI header 2020-10-01 18:04:28 +02:00
1e5ee117c5 Use DEBUG_ESPUI to en/disable debug code from being compiled
Include clang-format file for formatting code and format code
2020-10-01 18:04:28 +02:00
db4164f621 Reduce heap usage by using F and PSTR 2020-10-01 18:04:28 +02:00
bfd645d7a1 Use const String& to reduce IROM usage 2020-10-01 18:04:28 +02:00
99cf344d93 Changes suggested in #93
Signed-off-by: Lukas Bachschwell <lukas@lbsfilm.at>
2020-09-24 21:50:28 +02:00
13 changed files with 1302 additions and 1029 deletions

58
.clang-format Executable file
View File

@ -0,0 +1,58 @@
---
# Based on Webkit style
BasedOnStyle: Webkit
IndentWidth: 4
ColumnLimit: 120
---
Language: Cpp
Standard: Cpp11
# Pointers aligned to the left
DerivePointerAlignment: false
PointerAlignment: Left
AccessModifierOffset: -4
AllowShortFunctionsOnASingleLine: Inline
AlwaysBreakTemplateDeclarations: true
BreakBeforeBraces: Custom
BraceWrapping:
AfterClass: true
AfterControlStatement: true
AfterEnum: true
AfterFunction: true
AfterNamespace: true
AfterStruct: true
AfterUnion: true
AfterExternBlock: true
BeforeCatch: true
BeforeElse: true
SplitEmptyFunction: false
SplitEmptyRecord: false
SplitEmptyNamespace: false
BreakConstructorInitializers: BeforeColon
CompactNamespaces: false
ConstructorInitializerAllOnOneLineOrOnePerLine: true
ConstructorInitializerIndentWidth: 4
Cpp11BracedListStyle: true
FixNamespaceComments: true
IncludeBlocks: Regroup
IncludeCategories:
# C++ standard headers (no .h)
- Regex: '<[[:alnum:]_-]+>'
Priority: 1
# Extenal libraries (with .h)
- Regex: '<[[:alnum:]_./-]+>'
Priority: 2
# Headers from same folder
- Regex: '"[[:alnum:]_.-]+"'
Priority: 3
# Headers from other folders
- Regex: '"[[:alnum:]_/.-]+"'
Priority: 4
IndentCaseLabels: false
NamespaceIndentation: All
SortIncludes: true
SortUsingDeclarations: true
SpaceAfterTemplateKeyword: true
SpacesInAngles: false
SpacesInParentheses: false
SpacesInSquareBrackets: false
UseTab: Never

View File

@ -104,7 +104,7 @@ function `ESPUI.prepareFileSystem()`
Just open the example sketch **prepareFileSystem** and run it on the ESP, (give Just open the example sketch **prepareFileSystem** and run it on the ESP, (give
it up to 30 seconds, you can see the status on the Serial Monitor), The library it up to 30 seconds, you can see the status on the Serial Monitor), The library
will create all needed files. Congratulations, you are done, from now on you will create all needed files. Congratulations, you are done, from now on you
just need to to this again when there is a library update, or when you want to just need to do this again when there is a library update, or when you want to
use another chip :-) Now you can upload your normal sketch, when you do not call use another chip :-) Now you can upload your normal sketch, when you do not call
the `ESPUI.prepareFileSystem()` function the compiler will strip out all the the `ESPUI.prepareFileSystem()` function the compiler will strip out all the
unnecessary strings that are already saved in the chip's filesystem and you have unnecessary strings that are already saved in the chip's filesystem and you have

View File

@ -12,6 +12,7 @@
} }
.card { .card {
min-height: 100px;
margin-top: 2%; margin-top: 2%;
border-radius: 6px; border-radius: 6px;
box-shadow: 0 4px 4px rgba(204, 197, 185, 0.5); box-shadow: 0 4px 4px rgba(204, 197, 185, 0.5);
@ -28,9 +29,7 @@
} }
} }
.card-slider { .card-slider {}
padding-bottom: 10px;
}
.turquoise { .turquoise {
background: #1abc9c; background: #1abc9c;
@ -80,7 +79,7 @@
text-align: center; text-align: center;
color: #ffffff; color: #ffffff;
font-weight: 700; font-weight: 700;
line-height: 1; line-height: 1.3;
margin-bottom: 5px; margin-bottom: 5px;
display: inline-block; display: inline-block;
white-space: nowrap; white-space: nowrap;

File diff suppressed because one or more lines are too long

21
data/js/controls.js vendored
View File

@ -380,28 +380,28 @@ function start() {
data.id + data.id +
", false)' id='pf" + ", false)' id='pf" +
data.id + data.id +
"'></a></li>" + "'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(RIGHT, " + "<li><a onmousedown='padclick(RIGHT, " +
data.id + data.id +
", true)' onmouseup='padclick(RIGHT, " + ", true)' onmouseup='padclick(RIGHT, " +
data.id + data.id +
", false)' id='pr" + ", false)' id='pr" +
data.id + data.id +
"'></a></li>" + "'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(LEFT, " + "<li><a onmousedown='padclick(LEFT, " +
data.id + data.id +
", true)' onmouseup='padclick(LEFT, " + ", true)' onmouseup='padclick(LEFT, " +
data.id + data.id +
", false)' id='pl" + ", false)' id='pl" +
data.id + data.id +
"'></a></li>" + "'>&#9650;</a></li>" +
"<li><a onmousedown='padclick(DOWN, " + "<li><a onmousedown='padclick(DOWN, " +
data.id + data.id +
", true)' onmouseup='padclick(DOWN, " + ", true)' onmouseup='padclick(DOWN, " +
data.id + data.id +
", false)' id='pb" + ", false)' id='pb" +
data.id + data.id +
"'></a></li>" + "'>&#9650;</a></li>" +
"</ul>" + "</ul>" +
(data.type == UI_CPAD (data.type == UI_CPAD
? "<a class='confirm' onmousedown='padclick(CENTER," + ? "<a class='confirm' onmousedown='padclick(CENTER," +
@ -557,7 +557,7 @@ function start() {
case UI_TAB: case UI_TAB:
$("#tabsnav").append( $("#tabsnav").append(
"<li><a href='#tab" + data.id + "'>" + data.value + "</a></li>" "<li><a onmouseup='tabclick(" + data.id + ")' href='#tab" + data.id + "'>" + data.value + "</a></li>"
); );
$("#tabscontent").append("<div id='tab" + data.id + "'></div>"); $("#tabscontent").append("<div id='tab" + data.id + "'></div>");
@ -799,9 +799,11 @@ function start() {
websock.onmessage = handleEvent; websock.onmessage = handleEvent;
} }
var sliderCache = {};
function sliderchange(number) { function sliderchange(number) {
var val = $("#sl" + number).val(); var val = $("#sl" + number).val();
websock.send("slvalue:" + val + ":" + number); sliderCache[number] !== val && websock.send("slvalue:" + val + ":" + number);
sliderCache[number] = val;
} }
function numberchange(number) { function numberchange(number) {
@ -814,6 +816,11 @@ function textchange(number) {
websock.send("tvalue:" + val + ":" + number); websock.send("tvalue:" + val + ":" + number);
} }
function tabclick(number) {
var val = $("#tab" + number).val();
websock.send("tabvalue:" + val + ":" + number);
}
function selectchange(number) { function selectchange(number) {
var val = $("#select" + number).val(); var val = $("#select" + number).val();
websock.send("svalue:" + val + ":" + number); websock.send("svalue:" + val + ":" + number);
@ -854,9 +861,11 @@ function switcher(number, state) {
if ($("#s" + number).is(":checked")) { if ($("#s" + number).is(":checked")) {
websock.send("sactive:" + number); websock.send("sactive:" + number);
$("#sl" + number).addClass("checked"); $("#sl" + number).addClass("checked");
$("#sl" + number).prop("checked", true);
} else { } else {
websock.send("sinactive:" + number); websock.send("sinactive:" + number);
$("#sl" + number).removeClass("checked"); $("#sl" + number).removeClass("checked");
$("#sl" + number).prop("checked", false);
} }
} else if (state == 1) { } else if (state == 1) {
$("#sl" + number).addClass("checked"); $("#sl" + number).addClass("checked");

View File

@ -80,28 +80,28 @@ data.id+
data.id+ data.id+
", false)' id='pf"+ ", false)' id='pf"+
data.id+ data.id+
"'></a></li>"+ "'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(RIGHT, "+ "<li><a onmousedown='padclick(RIGHT, "+
data.id+ data.id+
", true)' onmouseup='padclick(RIGHT, "+ ", true)' onmouseup='padclick(RIGHT, "+
data.id+ data.id+
", false)' id='pr"+ ", false)' id='pr"+
data.id+ data.id+
"'></a></li>"+ "'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(LEFT, "+ "<li><a onmousedown='padclick(LEFT, "+
data.id+ data.id+
", true)' onmouseup='padclick(LEFT, "+ ", true)' onmouseup='padclick(LEFT, "+
data.id+ data.id+
", false)' id='pl"+ ", false)' id='pl"+
data.id+ data.id+
"'></a></li>"+ "'>&#9650;</a></li>"+
"<li><a onmousedown='padclick(DOWN, "+ "<li><a onmousedown='padclick(DOWN, "+
data.id+ data.id+
", true)' onmouseup='padclick(DOWN, "+ ", true)' onmouseup='padclick(DOWN, "+
data.id+ data.id+
", false)' id='pb"+ ", false)' id='pb"+
data.id+ data.id+
"'></a></li>"+ "'>&#9650;</a></li>"+
"</ul>"+ "</ul>"+
(data.type==UI_CPAD?"<a class='confirm' onmousedown='padclick(CENTER,"+ (data.type==UI_CPAD?"<a class='confirm' onmousedown='padclick(CENTER,"+
data.id+ data.id+
@ -162,7 +162,7 @@ data.value+
"' onchange='textchange("+ "' onchange='textchange("+
data.id+ data.id+
")' />"+ ")' />"+
"</div>");break;case UI_TAB:$("#tabsnav").append("<li><a 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 :\\");} "</div>");break;case UI_TAB:$("#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_SELECT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");} e.preventDefault();});break;case UI_SELECT:var parent;if(data.parentControl){parent=$("#tab"+data.parentControl);}else{parent=$("#row");}
parent.append("<div id='id"+ parent.append("<div id='id"+
data.id+ data.id+
@ -239,11 +239,12 @@ data.id+
"'></pre>"+ "'></pre>"+
"</div>");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($("#id"+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;} "</div>");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($("#id"+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<UI_INITIAL_GUI){var element=$("#id"+data.id);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));}}};websock.onmessage=handleEvent;} if(data.type>=UPDATE_OFFSET&&data.type<UI_INITIAL_GUI){var element=$("#id"+data.id);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));}}};websock.onmessage=handleEvent;}
function sliderchange(number){var val=$("#sl"+number).val();websock.send("slvalue:"+val+":"+number);} var sliderCache={};function sliderchange(number){var val=$("#sl"+number).val();sliderCache[number]!==val&&websock.send("slvalue:"+val+":"+number);sliderCache[number]=val;}
function numberchange(number){var val=$("#num"+number).val();websock.send("nvalue:"+val+":"+number);} function numberchange(number){var val=$("#num"+number).val();websock.send("nvalue:"+val+":"+number);}
function textchange(number){var val=$("#text"+number).val();websock.send("tvalue:"+val+":"+number);} function textchange(number){var val=$("#text"+number).val();websock.send("tvalue:"+val+":"+number);}
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 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 buttonclick(number,isdown){if(isdown)websock.send("bdown:"+number);else websock.send("bup:"+number);}
function padclick(type,number,isdown){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 padclick(type,number,isdown){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($("#s"+number).is(":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);}} function switcher(number,state){if(state==null){if($("#s"+number).is(":checked")){websock.send("sactive:"+number);$("#sl"+number).addClass("checked");$("#sl"+number).prop("checked",true);}else{websock.send("sinactive:"+number);$("#sl"+number).removeClass("checked");$("#sl"+number).prop("checked",false);}}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 slider=$(".range-slider"),range=$(".range-slider__range"),value=$(".range-slider__value");slider.each(function(){value.each(function(){var value=$(this).prev().attr("value");$(this).html(value);});if(!isDiscrete){range.on({input:function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));},});}else{range.on({input:function(){$(this).next().html(this.value);},change:function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));},});}});}; var rangeSlider=function(isDiscrete){var slider=$(".range-slider"),range=$(".range-slider__range"),value=$(".range-slider__value");slider.each(function(){value.each(function(){var value=$(this).prev().attr("value");$(this).html(value);});if(!isDiscrete){range.on({input:function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));},});}else{range.on({input:function(){$(this).next().html(this.value);},change:function(){sliderchange($(this).attr("id").replace(/^\D+/g,""));},});}});};

View File

@ -1,11 +1,11 @@
#include <ESPUI.h> #include <ESPUI.h>
ESPUIClass ESPUI( Verbosity::VerboseJSON ); void setup(void)
{
void setup(void) {
Serial.begin(115200); Serial.begin(115200);
ESPUI.prepareFileSystem(); ESPUI.prepareFileSystem();
} }
void loop() { void loop()
{
} }

View File

@ -23,7 +23,7 @@
"frameworks": "arduino" "frameworks": "arduino"
} }
], ],
"version": "2.0.1", "version": "2.0.2",
"frameworks": "arduino", "frameworks": "arduino",
"platforms": "*" "platforms": "*"
} }

View File

@ -1,5 +1,5 @@
name=ESPUI name=ESPUI
version=2.0.1 version=2.0.2
author=Lukas Bachschwell author=Lukas Bachschwell
maintainer=Lukas Bachschwell <lukas@lbsfilm.at> maintainer=Lukas Bachschwell <lukas@lbsfilm.at>
sentence=ESP32 and ESP8266 Web Interface Library sentence=ESP32 and ESP8266 Web Interface Library

View File

@ -1,48 +1,58 @@
#include "ESPUI.h" #include "ESPUI.h"
#include "dataIndexHTML.h" #include <functional>
#include "dataNormalizeCSS.h" #include <ESPAsyncWebServer.h>
#include "dataStyleCSS.h"
#include "dataControlsJS.h" #include "dataControlsJS.h"
#include "dataGraphJS.h" #include "dataGraphJS.h"
#include "dataIndexHTML.h"
#include "dataNormalizeCSS.h"
#include "dataSliderJS.h" #include "dataSliderJS.h"
#include "dataStyleCSS.h"
#include "dataTabbedcontentJS.h" #include "dataTabbedcontentJS.h"
#include "dataZeptoJS.h" #include "dataZeptoJS.h"
#include <ESPAsyncWebServer.h> uint16_t Control::idCounter = 1;
#include <functional>
uint16_t Control::idCounter = 0;
// ################# Spiffs functions // ################# Spiffs functions
#if defined(ESP32) #if defined(ESP32)
void listDir(const char* dirname, uint8_t levels) void listDir(const char* dirname, uint8_t levels)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf("Listing directory: %s\n", dirname); Serial.printf_P(PSTR("Listing directory: %s\n"), dirname);
} }
#endif
#if defined(ESP32)
File root = SPIFFS.open(dirname);
#else
File root = LittleFS.open(dirname); File root = LittleFS.open(dirname);
#endif
if (!root) if (!root)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Failed to open directory"); Serial.println(F("Failed to open directory"));
} }
#endif
return; return;
} }
if (!root.isDirectory()) if (!root.isDirectory())
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Not a directory"); Serial.println(F("Not a directory"));
} }
#endif
return; return;
} }
@ -53,11 +63,13 @@ void listDir(const char *dirname, uint8_t levels)
{ {
if (file.isDirectory()) if (file.isDirectory())
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print(" DIR : "); Serial.print(F(" DIR : "));
Serial.println(file.name()); Serial.println(file.name());
} }
#endif
if (levels) if (levels)
{ {
@ -66,13 +78,15 @@ void listDir(const char *dirname, uint8_t levels)
} }
else else
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print(" FILE: "); Serial.print(F(" FILE: "));
Serial.print(file.name()); Serial.print(file.name());
Serial.print(" SIZE: "); Serial.print(F(" SIZE: "));
Serial.println(file.size()); Serial.println(file.size());
} }
#endif
} }
file = root.openNextFile(); file = root.openNextFile();
@ -83,16 +97,16 @@ void listDir(const char *dirname, uint8_t levels)
void listDir(const char* dirname, uint8_t levels) void listDir(const char* dirname, uint8_t levels)
{ {
// ignoring levels for esp8266 // ignoring levels for esp8266
Serial.printf("Listing directory: %s\n", dirname); Serial.printf_P(PSTR("Listing directory: %s\n"), dirname);
String str = ""; String str = "";
Dir dir = LittleFS.openDir("/"); Dir dir = LittleFS.openDir("/");
while (dir.next()) while (dir.next())
{ {
Serial.print(" FILE: "); Serial.print(F(" FILE: "));
Serial.print(dir.fileName()); Serial.print(dir.fileName());
Serial.print(" SIZE: "); Serial.print(F(" SIZE: "));
Serial.println(dir.fileSize()); Serial.println(dir.fileSize());
} }
} }
@ -101,17 +115,25 @@ void listDir(const char *dirname, uint8_t levels)
void ESPUIClass::list() void ESPUIClass::list()
{ {
if (!LittleFS.begin()) #if defined(ESP32)
if (!SPIFFS.begin())
{ {
Serial.println("SPIFFS Mount Failed"); Serial.println(F("SPIFFS Mount Failed"));
return; return;
} }
#else
if (!LittleFS.begin())
{
Serial.println(F("LittleFS Mount Failed"));
return;
}
#endif
listDir("/", 1); listDir("/", 1);
#if defined(ESP32) #if defined(ESP32)
Serial.println(LittleFS.totalBytes()); Serial.println(SPIFFS.totalBytes());
Serial.println(LittleFS.usedBytes()); Serial.println(SPIFFS.usedBytes());
#else #else
FSInfo fs_info; FSInfo fs_info;
@ -125,57 +147,79 @@ void ESPUIClass::list()
void deleteFile(const char* path) void deleteFile(const char* path)
{ {
if (ESPUI.verbosity) #if defined(ESP32)
{ bool exists = SPIFFS.exists(path);
Serial.print(LittleFS.exists(path)); #else
} bool exists = LittleFS.exists(path);
#endif
if (!LittleFS.exists(path)) if (!exists)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf("File: %s does not exist, not deleting\n", path); Serial.printf_P(PSTR("File: %s does not exist, not deleting\n"), path);
} }
#endif
return; return;
} }
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf("Deleting file: %s\n", path); Serial.printf_P(PSTR("Deleting file: %s\n"), path);
} }
#endif
if (LittleFS.remove(path)) #if defined(ESP32)
bool didRemove = SPIFFS.remove(path);
#else
bool didRemove = LittleFS.remove(path);
#endif
if (didRemove)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("File deleted"); Serial.println(F("File deleted"));
} }
#endif
} }
else else
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Delete failed"); Serial.println(F("Delete failed"));
} }
#endif
} }
} }
void writeFile(const char* path, const char* data) void writeFile(const char* path, const char* data)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf("Writing file: %s\n", path); Serial.printf_P(PSTR("Writing file: %s\n"), path);
} }
#endif
#if defined(ESP32)
File file = SPIFFS.open(path, FILE_WRITE);
#else
File file = LittleFS.open(path, FILE_WRITE); File file = LittleFS.open(path, FILE_WRITE);
#endif
if (!file) if (!file)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Failed to open file for writing"); Serial.println(F("Failed to open file for writing"));
} }
#endif
return; return;
} }
@ -184,34 +228,42 @@ void writeFile(const char *path, const char *data)
if (file.print(data)) if (file.print(data))
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("File written"); Serial.println(F("File written"));
} }
#endif
} }
else else
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Write failed"); Serial.println(F("Write failed"));
} }
#endif
} }
#else #else
if (file.print(FPSTR(data))) if (file.print(FPSTR(data)))
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("File written"); Serial.println(F("File written"));
} }
#endif
} }
else else
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Write failed"); Serial.println(F("Write failed"));
} }
#endif
} }
#endif #endif
@ -224,38 +276,46 @@ void ESPUIClass::prepareFileSystem()
{ {
// this function should only be used once // this function should only be used once
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println("About to prepare filesystem..."); Serial.println(F("About to prepare filesystem..."));
} }
#endif
#if defined(ESP32) #if defined(ESP32)
LittleFS.format(); SPIFFS.format();
if (!LittleFS.begin(true)) if (!SPIFFS.begin(true))
{ {
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println("SPIFFS Mount Failed"); Serial.println(F("SPIFFS Mount Failed"));
} }
#endif
return; return;
} }
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
listDir("/", 1); listDir("/", 1);
Serial.println("SPIFFS Mount ESP32 Done"); Serial.println(F("SPIFFS Mount ESP32 Done"));
} }
#endif
#else #else
LittleFS.format(); LittleFS.format();
LittleFS.begin(); LittleFS.begin();
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println("SPIFFS Mount ESP8266 Done"); Serial.println(F("SPIFFS Mount ESP8266 Done"));
} }
#endif
#endif #endif
@ -270,10 +330,12 @@ void ESPUIClass::prepareFileSystem()
deleteFile("/js/graph.js"); deleteFile("/js/graph.js");
deleteFile("/js/tabbedcontent.js"); deleteFile("/js/tabbedcontent.js");
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println("Cleanup done"); Serial.println(F("Cleanup done"));
} }
#endif
// Now write // Now write
writeFile("/index.htm", HTML_INDEX); writeFile("/index.htm", HTML_INDEX);
@ -288,72 +350,91 @@ void ESPUIClass::prepareFileSystem()
writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT); writeFile("/js/tabbedcontent.js", JS_TABBEDCONTENT);
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println("Done Initializing filesystem :-)"); Serial.println(F("Done Initializing filesystem :-)"));
} }
#endif
#if defined(ESP32) #if defined(ESP32)
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
listDir("/", 1); listDir("/", 1);
} }
#endif
#endif #endif
#if defined(ESP32)
SPIFFS.end();
#else
LittleFS.end(); LittleFS.end();
#endif
} }
// Handle Websockets Communication // Handle Websockets Communication
void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventType type, void *arg, uint8_t *data, size_t len) void onWsEvent(
AsyncWebSocket* server, AsyncWebSocketClient* client, AwsEventType type, void* arg, uint8_t* data, size_t len)
{ {
switch (type) switch (type)
{ {
case WS_EVT_DISCONNECT: case WS_EVT_DISCONNECT:
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf("Disconnected!\n"); Serial.print(F("Disconnected!\n"));
} }
#endif
break; break;
} }
case WS_EVT_PONG: case WS_EVT_PONG:
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf("Received PONG!\n"); Serial.print(F("Received PONG!\n"));
} }
#endif
break; break;
} }
case WS_EVT_ERROR: case WS_EVT_ERROR:
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.printf("WebSocket Error!\n"); Serial.print(F("WebSocket Error!\n"));
} }
#endif
break; break;
} }
case WS_EVT_CONNECT: case WS_EVT_CONNECT:
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print("Connected: "); Serial.print(F("Connected: "));
Serial.println(client->id()); Serial.println(client->id());
} }
#endif
ESPUI.jsonDom(client); ESPUI.jsonDom(client);
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("JSON Data Sent to Client!"); Serial.println(F("JSON Data Sent to Client!"));
} }
#endif
} }
break; break;
@ -369,117 +450,127 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
uint16_t id = msg.substring(msg.lastIndexOf(':') + 1).toInt(); uint16_t id = msg.substring(msg.lastIndexOf(':') + 1).toInt();
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity >= Verbosity::VerboseJSON) if (ESPUI.verbosity >= Verbosity::VerboseJSON)
{ {
Serial.print("WS rec: "); Serial.print(F("WS rec: "));
Serial.println(msg); Serial.println(msg);
Serial.print("WS recognised ID: "); Serial.print(F("WS recognised ID: "));
Serial.println(id); Serial.println(id);
} }
#endif
Control* c = ESPUI.getControl(id); Control* c = ESPUI.getControl(id);
if (c == nullptr) if (c == nullptr)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print("No control found for ID "); Serial.print(F("No control found for ID "));
Serial.println(id); Serial.println(id);
} }
#endif
return; return;
} }
if (c->callback == nullptr) if (c->callback == nullptr)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.print("No callback found for ID "); Serial.print(F("No callback found for ID "));
Serial.println(id); Serial.println(id);
} }
#endif
return; return;
} }
if (msg.startsWith("bdown:")) if (msg.startsWith(F("bdown:")))
{ {
c->callback(c, B_DOWN); c->callback(c, B_DOWN);
} }
else if (msg.startsWith("bup:")) else if (msg.startsWith(F("bup:")))
{ {
c->callback(c, B_UP); c->callback(c, B_UP);
} }
else if (msg.startsWith("pfdown:")) else if (msg.startsWith(F("pfdown:")))
{ {
c->callback(c, P_FOR_DOWN); c->callback(c, P_FOR_DOWN);
} }
else if (msg.startsWith("pfup:")) else if (msg.startsWith(F("pfup:")))
{ {
c->callback(c, P_FOR_UP); c->callback(c, P_FOR_UP);
} }
else if (msg.startsWith("pldown:")) else if (msg.startsWith(F("pldown:")))
{ {
c->callback(c, P_LEFT_DOWN); c->callback(c, P_LEFT_DOWN);
} }
else if (msg.startsWith("plup:")) else if (msg.startsWith(F("plup:")))
{ {
c->callback(c, P_LEFT_UP); c->callback(c, P_LEFT_UP);
} }
else if (msg.startsWith("prdown:")) else if (msg.startsWith(F("prdown:")))
{ {
c->callback(c, P_RIGHT_DOWN); c->callback(c, P_RIGHT_DOWN);
} }
else if (msg.startsWith("prup:")) else if (msg.startsWith(F("prup:")))
{ {
c->callback(c, P_RIGHT_UP); c->callback(c, P_RIGHT_UP);
} }
else if (msg.startsWith("pbdown:")) else if (msg.startsWith(F("pbdown:")))
{ {
c->callback(c, P_BACK_DOWN); c->callback(c, P_BACK_DOWN);
} }
else if (msg.startsWith("pbup:")) else if (msg.startsWith(F("pbup:")))
{ {
c->callback(c, P_BACK_UP); c->callback(c, P_BACK_UP);
} }
else if (msg.startsWith("pcdown:")) else if (msg.startsWith(F("pcdown:")))
{ {
c->callback(c, P_CENTER_DOWN); c->callback(c, P_CENTER_DOWN);
} }
else if (msg.startsWith("pcup:")) else if (msg.startsWith(F("pcup:")))
{ {
c->callback(c, P_CENTER_UP); c->callback(c, P_CENTER_UP);
} }
else if (msg.startsWith("sactive:")) else if (msg.startsWith(F("sactive:")))
{ {
c->value = "1"; c->value = "1";
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, S_ACTIVE); c->callback(c, S_ACTIVE);
} }
else if (msg.startsWith("sinactive:")) else if (msg.startsWith(F("sinactive:")))
{ {
c->value = "0"; c->value = "0";
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, S_INACTIVE); c->callback(c, S_INACTIVE);
} }
else if (msg.startsWith("slvalue:")) else if (msg.startsWith(F("slvalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, SL_VALUE); c->callback(c, SL_VALUE);
} }
else if (msg.startsWith("nvalue:")) else if (msg.startsWith(F("nvalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, N_VALUE); c->callback(c, N_VALUE);
} }
else if (msg.startsWith("tvalue:")) else if (msg.startsWith(F("tvalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
c->callback(c, T_VALUE); c->callback(c, T_VALUE);
} }
else if (msg.startsWith("svalue:")) else if (msg.startsWith("tabvalue:"))
{
c->callback(c, client->id());
}
else if (msg.startsWith(F("svalue:")))
{ {
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':')); c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
ESPUI.updateControl(c, client->id()); ESPUI.updateControl(c, client->id());
@ -487,10 +578,12 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
} }
else else
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Malformated message from the websocket"); Serial.println(F("Malformated message from the websocket"));
} }
#endif
} }
} }
break; break;
@ -500,8 +593,8 @@ void onWsEvent(AsyncWebSocket *server, AsyncWebSocketClient *client, AwsEventTyp
} }
} }
uint16_t ESPUIClass::addControl(ControlType type, const char *label, String value, ControlColor color, uint16_t parentControl, uint16_t ESPUIClass::addControl(ControlType type, const char* label, const String& value, ControlColor color,
void (*callback)(Control *, int)) uint16_t parentControl, void (*callback)(Control*, int))
{ {
Control* control = new Control(type, label, callback, value, color, parentControl); Control* control = new Control(type, label, callback, value, color, parentControl);
@ -571,11 +664,18 @@ bool ESPUIClass::removeControl(uint16_t id, bool force_reload_ui)
return false; return false;
} }
uint16_t ESPUIClass::label(const char *label, ControlColor color, String value) { return addControl(ControlType::Label, label, value, color); } uint16_t ESPUIClass::label(const char* label, ControlColor color, const 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::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); uint16_t sliderId = addControl(ControlType::Slider, label, String(value), color, Control::noParent, callback);
addControl(ControlType::Min, label, String(min), ControlColor::None, sliderId); addControl(ControlType::Min, label, String(min), ControlColor::None, sliderId);
@ -584,7 +684,7 @@ uint16_t ESPUIClass::slider(const char *label, void (*callback)(Control *, int),
return sliderId; 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, const String& value)
{ {
return addControl(ControlType::Button, label, value, color, Control::noParent, callback); return addControl(ControlType::Button, label, value, color, Control::noParent, callback);
} }
@ -603,7 +703,8 @@ uint16_t ESPUIClass::padWithCenter(const char *label, void (*callback)(Control *
return addControl(ControlType::PadWithCenter, label, "", color, Control::noParent, callback); 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); uint16_t numberId = addControl(ControlType::Number, label, String(number), color, Control::noParent, callback);
addControl(ControlType::Min, label, String(min), ControlColor::None, numberId); addControl(ControlType::Min, label, String(min), ControlColor::None, numberId);
@ -624,7 +725,7 @@ uint16_t ESPUIClass::accelerometer(const char *label, void (*callback)(Control *
return addControl(ControlType::Accel, label, "", color, Control::noParent, callback); 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, const String& value)
{ {
return addControl(ControlType::Text, label, value, color, Control::noParent, callback); return addControl(ControlType::Text, label, value, color, Control::noParent, callback);
} }
@ -663,17 +764,21 @@ void ESPUIClass::updateControl(Control *control, int clientId)
root["color"] = (int)control->color; root["color"] = (int)control->color;
serializeJson(document, json); serializeJson(document, json);
#if defined(DEBUG_ESPUI)
if (this->verbosity >= Verbosity::VerboseJSON) if (this->verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(json); Serial.println(json);
} }
#endif
if (clientId < 0) if (clientId < 0)
{ {
#if defined(DEBUG_ESPUI)
if (this->verbosity >= Verbosity::VerboseJSON) if (this->verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println("TextAll"); Serial.println(F("TextAll"));
} }
#endif
this->ws->textAll(json); this->ws->textAll(json);
return; return;
} }
@ -703,17 +808,19 @@ void ESPUIClass::updateControl(uint16_t id, int clientId)
if (!control) if (!control)
{ {
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println(String("Error: There is no control with ID ") + String(id)); Serial.printf_P(PSTR("Error: There is no control with ID %d"), id);
} }
#endif
return; return;
} }
updateControl(control, clientId); updateControl(control, clientId);
} }
void ESPUIClass::updateControlValue(Control *control, String value, int clientId) void ESPUIClass::updateControlValue(Control* control, const String& value, int clientId)
{ {
if (!control) if (!control)
{ {
@ -724,37 +831,63 @@ void ESPUIClass::updateControlValue(Control *control, String value, int clientId
updateControl(control, clientId); updateControl(control, clientId);
} }
void ESPUIClass::updateControlValue(uint16_t id, String value, int clientId) void ESPUIClass::updateControlValue(uint16_t id, const String& value, int clientId)
{ {
Control* control = getControl(id); Control* control = getControl(id);
if (!control) if (!control)
{ {
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println(String("Error: There is no control with ID ") + String(id)); Serial.printf_P(PSTR("Error: There is no control with ID %d"), id);
} }
#endif
return; return;
} }
updateControlValue(control, value, clientId); updateControlValue(control, value, clientId);
} }
void ESPUIClass::print(uint16_t id, String value) { updateControlValue(id, value); } void ESPUIClass::print(uint16_t id, const String& value)
{
updateControlValue(id, value);
}
void ESPUIClass::updateLabel(uint16_t id, String value) { updateControlValue(id, value); } void ESPUIClass::updateLabel(uint16_t id, const String& value)
{
updateControlValue(id, value);
}
void ESPUIClass::updateSlider(uint16_t id, int nValue, int clientId) { updateControlValue(id, String(nValue), clientId); } void ESPUIClass::updateSlider(uint16_t id, int nValue, int clientId)
{
updateControlValue(id, String(nValue), clientId);
}
void ESPUIClass::updateSwitcher(uint16_t id, bool nValue, int clientId) { updateControlValue(id, String(nValue ? "1" : "0"), clientId); } void ESPUIClass::updateSwitcher(uint16_t id, bool nValue, int clientId)
{
updateControlValue(id, String(nValue ? "1" : "0"), clientId);
}
void ESPUIClass::updateNumber(uint16_t id, int number, int clientId) { updateControlValue(id, String(number), clientId); } void ESPUIClass::updateNumber(uint16_t id, int number, int clientId)
{
updateControlValue(id, String(number), clientId);
}
void ESPUIClass::updateText(uint16_t id, String text, int clientId) { updateControlValue(id, text, clientId); } void ESPUIClass::updateText(uint16_t id, const String& text, int clientId)
{
updateControlValue(id, text, clientId);
}
void ESPUIClass::updateSelect(uint16_t id, String text, int clientId) { updateControlValue(id, text, clientId); } void ESPUIClass::updateSelect(uint16_t id, const String& text, int clientId)
{
updateControlValue(id, text, clientId);
}
void ESPUIClass::updateGauge(uint16_t id, int number, int clientId) { updateControlValue(id, String(number), clientId); } void ESPUIClass::updateGauge(uint16_t id, int number, int clientId)
{
updateControlValue(id, String(number), clientId);
}
void ESPUIClass::clearGraph(uint16_t id, int clientId) {} void ESPUIClass::clearGraph(uint16_t id, int clientId) {}
@ -775,10 +908,12 @@ void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId)
root["id"] = control->id; root["id"] = control->id;
serializeJson(document, json); serializeJson(document, json);
#if defined(DEBUG_ESPUI)
if (this->verbosity >= Verbosity::VerboseJSON) if (this->verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(json); Serial.println(json);
} }
#endif
if (clientId < 0) if (clientId < 0)
{ {
@ -797,10 +932,12 @@ void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId)
{ {
this->ws->client(tryId)->text(json); this->ws->client(tryId)->text(json);
#if defined(DEBUG_ESPUI)
if (this->verbosity >= Verbosity::VerboseJSON) if (this->verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(json); Serial.println(json);
} }
#endif
} }
count++; count++;
@ -864,10 +1001,12 @@ void ESPUIClass::jsonDom(AsyncWebSocketClient *client)
// Send as one big bunch // Send as one big bunch
serializeJson(document, json); serializeJson(document, json);
#if defined(DEBUG_ESPUI)
if (this->verbosity >= Verbosity::VerboseJSON) if (this->verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(json); Serial.println(json);
} }
#endif
if (client != nullptr) if (client != nullptr)
{ {
@ -888,10 +1027,12 @@ void ESPUIClass::jsonReload()
root["type"] = (int)UI_RELOAD; root["type"] = (int)UI_RELOAD;
serializeJson(document, json); serializeJson(document, json);
#if defined(DEBUG_ESPUI)
if (this->verbosity >= Verbosity::VerboseJSON) if (this->verbosity >= Verbosity::VerboseJSON)
{ {
Serial.println(json); Serial.println(json);
} }
#endif
this->ws->textAll(json); this->ws->textAll(json);
} }
@ -914,27 +1055,45 @@ void ESPUIClass::beginSPIFFS(const char *_title, const char *username, const cha
server = new AsyncWebServer(80); server = new AsyncWebServer(80);
ws = new AsyncWebSocket("/ws"); ws = new AsyncWebSocket("/ws");
if (!LittleFS.begin()) #if defined(ESP32)
bool fsBegin = SPIFFS.begin();
#else
bool fsBegin = LittleFS.begin();
#endif
if (!fsBegin)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("SPIFFS Mount Failed, PLEASE CHECK THE README ON HOW TO PREPARE YOUR ESP!!!!!!!"); Serial.println(F("SPIFFS Mount Failed, PLEASE CHECK THE README ON HOW TO "
"PREPARE YOUR ESP!!!!!!!"));
} }
#endif
return; return;
} }
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
listDir("/", 1); listDir("/", 1);
} }
#endif
if (!LittleFS.exists("/index.htm")) #if defined(ESP32)
bool indexExists = SPIFFS.exists("/index.htm");
#else
bool indexExists = LittleFS.exists("/index.htm");
#endif
if (!indexExists)
{ {
#if defined(DEBUG_ESPUI)
if (ESPUI.verbosity) if (ESPUI.verbosity)
{ {
Serial.println("Please read the README!!!!!!!, Make sure to ESPUI.prepareFileSystem() once in an empty sketch"); Serial.println(F("Please read the README!!!!!!!, Make sure to "
"ESPUI.prepareFileSystem() once in an empty sketch"));
} }
#endif
return; return;
} }
@ -948,11 +1107,19 @@ void ESPUIClass::beginSPIFFS(const char *_title, const char *username, const cha
{ {
ws->setAuthentication(ESPUI.basicAuthUsername, ESPUI.basicAuthPassword); ws->setAuthentication(ESPUI.basicAuthUsername, ESPUI.basicAuthPassword);
} }
#if defined(ESP32)
server->serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm").setAuthentication(username, password);
#else
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(username, password); server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm").setAuthentication(username, password);
#endif
} }
else else
{ {
#if defined(ESP32)
server->serveStatic("/", SPIFFS, "/").setDefaultFile("index.htm");
#else
server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm"); server->serveStatic("/", LittleFS, "/").setDefaultFile("index.htm");
#endif
} }
// Heap for general Servertest // Heap for general Servertest
@ -969,10 +1136,12 @@ void ESPUIClass::beginSPIFFS(const char *_title, const char *username, const cha
server->begin(); server->begin();
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println("UI Initialized"); Serial.println(F("UI Initialized"));
} }
#endif
} }
void ESPUIClass::begin(const char* _title, const char* username, const char* password) void ESPUIClass::begin(const char* _title, const char* username, const char* password)
@ -1018,7 +1187,8 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", JS_ZEPTO_GZIP, sizeof(JS_ZEPTO_GZIP)); AsyncWebServerResponse* response
= request->beginResponse_P(200, "application/javascript", JS_ZEPTO_GZIP, sizeof(JS_ZEPTO_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
@ -1029,7 +1199,8 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", JS_CONTROLS_GZIP, sizeof(JS_CONTROLS_GZIP)); AsyncWebServerResponse* response
= request->beginResponse_P(200, "application/javascript", JS_CONTROLS_GZIP, sizeof(JS_CONTROLS_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
@ -1040,7 +1211,8 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", JS_SLIDER_GZIP, sizeof(JS_SLIDER_GZIP)); AsyncWebServerResponse* response
= request->beginResponse_P(200, "application/javascript", JS_SLIDER_GZIP, sizeof(JS_SLIDER_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
@ -1051,7 +1223,8 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", JS_GRAPH_GZIP, sizeof(JS_GRAPH_GZIP)); AsyncWebServerResponse* response
= request->beginResponse_P(200, "application/javascript", JS_GRAPH_GZIP, sizeof(JS_GRAPH_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
@ -1062,7 +1235,8 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse *response = request->beginResponse_P(200, "application/javascript", JS_TABBEDCONTENT_GZIP, sizeof(JS_TABBEDCONTENT_GZIP)); AsyncWebServerResponse* response = request->beginResponse_P(
200, "application/javascript", JS_TABBEDCONTENT_GZIP, sizeof(JS_TABBEDCONTENT_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
@ -1075,7 +1249,8 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", CSS_STYLE_GZIP, sizeof(CSS_STYLE_GZIP)); AsyncWebServerResponse* response
= request->beginResponse_P(200, "text/css", CSS_STYLE_GZIP, sizeof(CSS_STYLE_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
@ -1086,7 +1261,8 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
return request->requestAuthentication(); return request->requestAuthentication();
} }
AsyncWebServerResponse *response = request->beginResponse_P(200, "text/css", CSS_NORMALIZE_GZIP, sizeof(CSS_NORMALIZE_GZIP)); AsyncWebServerResponse* response
= request->beginResponse_P(200, "text/css", CSS_NORMALIZE_GZIP, sizeof(CSS_NORMALIZE_GZIP));
response->addHeader("Content-Encoding", "gzip"); response->addHeader("Content-Encoding", "gzip");
request->send(response); request->send(response);
}); });
@ -1105,12 +1281,17 @@ void ESPUIClass::begin(const char *_title, const char *username, const char *pas
server->begin(); server->begin();
#if defined(DEBUG_ESPUI)
if (this->verbosity) if (this->verbosity)
{ {
Serial.println("UI Initialized"); Serial.println(F("UI Initialized"));
} }
#endif
} }
void ESPUIClass::setVerbosity(Verbosity v) { this->verbosity = v; } void ESPUIClass::setVerbosity(Verbosity v)
{
this->verbosity = v;
}
ESPUIClass ESPUI; ESPUIClass ESPUI;

View File

@ -6,16 +6,15 @@
#include "Arduino.h" #include "Arduino.h"
#include "ArduinoJson.h" #include "ArduinoJson.h"
#include "FS.h"
#include "stdlib_noniso.h" #include "stdlib_noniso.h"
#if defined(ESP32) #if defined(ESP32)
#include "LittleFS.h"
#include "WiFi.h"
#include <AsyncTCP.h> #include <AsyncTCP.h>
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include "SPIFFS.h"
#include "WiFi.h"
#else #else
#include <ArduinoOTA.h> #include <ArduinoOTA.h>
@ -23,8 +22,8 @@
#include <ESP8266mDNS.h> #include <ESP8266mDNS.h>
#include <ESPAsyncTCP.h> #include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h> #include <ESPAsyncWebServer.h>
#include <LittleFS.h>
#include <Hash.h> #include <Hash.h>
#include <LittleFS.h>
#include <SPIFFSEditor.h> #include <SPIFFSEditor.h>
#define FILE_WRITE "w" #define FILE_WRITE "w"
@ -140,16 +139,29 @@ public:
static constexpr uint16_t noParent = 0xffff; static constexpr uint16_t noParent = 0xffff;
Control(ControlType type, const char *label, void (*callback)(Control *, int), String value, ControlColor color, Control(ControlType type, const char* label, void (*callback)(Control*, int), const String& value,
uint16_t parentControl = Control::noParent) ControlColor color, uint16_t parentControl = Control::noParent)
: type(type), label(label), callback(callback), value(value), color(color), parentControl(parentControl), next(nullptr) : type(type),
label(label),
callback(callback),
value(value),
color(color),
parentControl(parentControl),
next(nullptr)
{ {
id = idCounter++; id = idCounter++;
} }
Control(const Control& control) Control(const Control& control)
: type(control.type), id(control.id), label(control.label), callback(control.callback), value(control.value), color(control.color), : type(control.type),
parentControl(control.parentControl), next(control.next) {} id(control.id),
label(control.label),
callback(control.callback),
value(control.value),
color(control.color),
parentControl(control.parentControl),
next(control.next)
{ }
private: private:
static uint16_t idCounter; static uint16_t idCounter;
@ -200,31 +212,43 @@ public:
bool sliderContinuous; bool sliderContinuous;
void setVerbosity(Verbosity verbosity); void setVerbosity(Verbosity verbosity);
void begin(const char *_title, const char *username = nullptr, const char *password = nullptr); // Setup server and page in Memorymode void begin(const char* _title, const char* username = nullptr,
void beginSPIFFS(const char *_title, const char *username = nullptr, const char *password = nullptr); // Setup server and page in SPIFFSmode const char* password = nullptr); // Setup server and page in Memorymode
void beginSPIFFS(const char* _title, const char* username = nullptr,
const char* password = nullptr); // Setup server and page in SPIFFSmode
void prepareFileSystem(); // Initially preps the filesystem and loads a lot of stuff into SPIFFS void prepareFileSystem(); // Initially preps the filesystem and loads a lot of
// stuff into SPIFFS
void list(); // Lists SPIFFS directory void list(); // Lists SPIFFS directory
uint16_t addControl(ControlType type, const char *label, String value = String(""), ControlColor color = ControlColor::Turquoise, uint16_t parentControl = Control::noParent, void (*callback)(Control *, int) = nullptr); uint16_t addControl(ControlType type, const char* label, const String& value = String(""),
ControlColor color = ControlColor::Turquoise, uint16_t parentControl = Control::noParent,
void (*callback)(Control*, int) = nullptr);
bool removeControl(uint16_t id, bool force_reload_ui = false); bool removeControl(uint16_t id, bool force_reload_ui = false);
// create Elements // create Elements
uint16_t button(const char *label, void (*callback)(Control *, int), ControlColor color, String value = ""); // Create Event Button uint16_t button(const char* label, void (*callback)(Control*, int), ControlColor color,
uint16_t switcher(const char *label, void (*callback)(Control *, int), ControlColor color, bool startState = false); // Create Toggle Button const String& value = ""); // Create Event Button
uint16_t pad(const char *label, void (*callback)(Control *, int), ControlColor color); // Create Pad Control uint16_t switcher(const char* label, void (*callback)(Control*, int), ControlColor color,
uint16_t padWithCenter(const char *label, void (*callback)(Control *, int), ControlColor color); // Create Pad Control with Centerbutton bool startState = false); // Create Toggle Button
uint16_t pad(const char* label, void (*callback)(Control*, int),
ControlColor color); // Create Pad Control
uint16_t padWithCenter(const char* label, void (*callback)(Control*, int),
ControlColor color); // Create Pad Control with Centerbutton
uint16_t slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0, uint16_t slider(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
int max = 100); // Create Slider Control int max = 100); // Create Slider Control
uint16_t number(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0, uint16_t number(const char* label, void (*callback)(Control*, int), ControlColor color, int value, int min = 0,
int max = 100); // Create a Number Input Control int max = 100); // Create a Number Input Control
uint16_t text(const char *label, void (*callback)(Control *, int), ControlColor color, String value = ""); // Create a Text Input Control uint16_t text(const char* label, void (*callback)(Control*, int), ControlColor color,
const String& value = ""); // Create a Text Input Control
// Output only // Output only
uint16_t label(const char *label, ControlColor color, String value = ""); // Create Label uint16_t label(const char* label, ControlColor color,
const String& value = ""); // Create Label
uint16_t graph(const char* label, ControlColor color); // Create Graph display uint16_t graph(const char* label, ControlColor color); // Create Graph display
uint16_t gauge(const char *label, ControlColor color, int value, int min = 0, int max = 100); // Create Gauge display uint16_t gauge(const char* label, ControlColor color, int value, int min = 0,
int max = 100); // Create Gauge display
// Input only // Input only
uint16_t accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color); uint16_t accelerometer(const char* label, void (*callback)(Control*, int), ControlColor color);
@ -234,19 +258,19 @@ public:
Control* getControl(uint16_t id); Control* getControl(uint16_t id);
// Update Elements // Update Elements
void updateControlValue(uint16_t id, String value, int clientId = -1); void updateControlValue(uint16_t id, const String& value, int clientId = -1);
void updateControlValue(Control *control, String value, int clientId = -1); void updateControlValue(Control* control, const String& value, int clientId = -1);
void updateControl(uint16_t id, int clientId = -1); void updateControl(uint16_t id, int clientId = -1);
void updateControl(Control* control, int clientId = -1); void updateControl(Control* control, int clientId = -1);
void print(uint16_t id, String value); void print(uint16_t id, const String& value);
void updateLabel(uint16_t id, String value); void updateLabel(uint16_t id, const String& value);
void updateSwitcher(uint16_t id, bool nValue, int clientId = -1); void updateSwitcher(uint16_t id, bool nValue, int clientId = -1);
void updateSlider(uint16_t id, int nValue, int clientId = -1); void updateSlider(uint16_t id, int nValue, int clientId = -1);
void updateNumber(uint16_t id, int nValue, int clientId = -1); void updateNumber(uint16_t id, int nValue, int clientId = -1);
void updateText(uint16_t id, String nValue, int clientId = -1); void updateText(uint16_t id, const String& nValue, int clientId = -1);
void updateSelect(uint16_t id, String nValue, int clientId = -1); void updateSelect(uint16_t id, const String& nValue, int clientId = -1);
void updateGauge(uint16_t id, int number, int clientId); void updateGauge(uint16_t id, int number, int clientId);
void clearGraph(uint16_t id, int clientId = -1); void clearGraph(uint16_t id, int clientId = -1);

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long