mirror of
https://github.com/s00500/ESPUI.git
synced 2024-11-21 17:40:54 +00:00
Merge pull request #149 from iangray001/master
One bugfix, one small feature
This commit is contained in:
commit
446f83c6c2
29
README.md
29
README.md
@ -466,6 +466,35 @@ This can be applied to every element to force a single column layout, or to indi
|
||||
|
||||
Note that this will have no effect on small screens.
|
||||
|
||||
### Advanced: Getting the Time
|
||||
|
||||
ESPUI can create an invisible control that can be used to fetch the current time from the client when they are connected to the UI. This could be used to intermittently provide an accurate time source to your ESP. Remember that clients cannot be relied upon to be correct or truthful. If this is not a concern, you can do the following:
|
||||
|
||||
```
|
||||
//Add the invisible "Time" control
|
||||
auto timeId = ESPUI.addControl(Time, "", "", None, 0, timeCallback);
|
||||
```
|
||||
|
||||
After creating the UI, sending an update to the Time control will cause it to fetch the current time from the client and then fire its callback with the result.
|
||||
|
||||
```
|
||||
//Request an update to the time
|
||||
ESPUI.updateTime(timeId);
|
||||
//Will trigger timeCallback
|
||||
```
|
||||
|
||||
In `timeCallback` you can then print the control's value as normal:
|
||||
|
||||
```
|
||||
void timeCallback(Control *sender, int type) {
|
||||
if(type == TM_VALUE) {
|
||||
Serial.println(sender->value);
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
The returned string will be an [ISO string](https://www.w3schools.com/jsref/jsref_toisostring.asp) as returned by the Javascript `new Date().toISOString()`. The format is `YYYY-MM-DDTHH:mm:ss.sssZ` so for example: `2022-01-20T21:44:22.913Z`.
|
||||
|
||||
# Notes for Development
|
||||
|
||||
If you want to work on the HTML/CSS/JS files, do make changes in the _data_
|
||||
|
12
data/js/controls.js
vendored
12
data/js/controls.js
vendored
@ -57,6 +57,9 @@ 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;
|
||||
@ -537,6 +540,7 @@ function start() {
|
||||
|
||||
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);
|
||||
}
|
||||
@ -554,6 +558,11 @@ function start() {
|
||||
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;
|
||||
@ -723,6 +732,9 @@ var addToHTML = function(data) {
|
||||
html = "<div id='id" + data.id + "' " + panelStyle + " class='sectionbreak columns'>" +
|
||||
"<h5>" + data.label + "</h5><hr/></div>";
|
||||
break;
|
||||
case UI_TIME:
|
||||
//Invisible element
|
||||
break;
|
||||
}
|
||||
|
||||
parent.append(html);
|
||||
|
8
data/js/controls.min.js
vendored
8
data/js/controls.min.js
vendored
@ -1,4 +1,4 @@
|
||||
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 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"";}}
|
||||
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;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];}
|
||||
@ -37,9 +37,9 @@ slider_move($("#id"+data.id),data.value,"100",false);if(data.hasOwnProperty('ele
|
||||
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);}
|
||||
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);if(data.hasOwnProperty('elementStyle')){$("#btn"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_BUTTON:$("#btn"+data.id).val(data.value);$("#btn"+data.id).text(data.value);if(data.hasOwnProperty('elementStyle')){$("#btn"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_PAD:case UPDATE_CPAD:break;case UPDATE_GAUGE:$("#gauge"+data.id).val(data.value);if(data.hasOwnProperty('elementStyle')){$("#gauge"+data.id).attr("style",data.elementStyle);}
|
||||
break;case UPDATE_ACCEL:break;default:console.error("Unknown type or event");break;}
|
||||
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>=UPDATE_OFFSET&&data.type<UI_INITIAL_GUI){var element=$("#id"+data.id);if(data.hasOwnProperty('panelStyle')){$("#id"+data.id).attr("style",data.panelStyle);}
|
||||
if(data.type==UPDATE_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));}}
|
||||
$(".range-slider__range").each(function(){$(this)[0].value=$(this).attr("value");$(this).next().html($(this).attr("value"));});};websock.onmessage=handleEvent;}
|
||||
@ -56,7 +56,7 @@ $(this).attr("callbackSet","true");}});};var addToHTML=function(data){panelStyle
|
||||
colorClass(data.color)+"'><h5>"+data.label+"</h5><hr/>"+
|
||||
elementHTML(data.type,data.id,data.value,data.label,elementStyle)+
|
||||
"</div>";break;case UI_SEPARATOR:html="<div id='id"+data.id+"' "+panelStyle+" class='sectionbreak columns'>"+
|
||||
"<h5>"+data.label+"</h5><hr/></div>";break;}
|
||||
"<h5>"+data.label+"</h5><hr/></div>";break;case UI_TIME:break;}
|
||||
parent.append(html);}else{var parent=$("#id"+data.parentControl);parent.append(elementHTML(data.type,data.id,data.value,data.label,elementStyle));}}
|
||||
var elementHTML=function(type,id,value,label,elementStyle){switch(type){case UI_LABEL:return"<span id='l"+id+"' "+elementStyle+
|
||||
" class='label label-wrap'>"+value+"</span>";case UI_BUTTON:return"<button id='btn"+id+"' "+elementStyle+
|
||||
|
@ -445,7 +445,7 @@ void onWsEvent(
|
||||
if (msg.startsWith(F("uiok:")))
|
||||
{
|
||||
int idx = msg.substring(msg.indexOf(':') + 1).toInt();
|
||||
ESPUI.jsonDom(idx);
|
||||
ESPUI.jsonDom(idx, client);
|
||||
} else
|
||||
{
|
||||
uint16_t id = msg.substring(msg.lastIndexOf(':') + 1).toInt();
|
||||
@ -576,6 +576,12 @@ void onWsEvent(
|
||||
ESPUI.updateControl(c, client->id());
|
||||
c->callback(c, S_VALUE);
|
||||
}
|
||||
else if (msg.startsWith(F("time:")))
|
||||
{
|
||||
c->value = msg.substring(msg.indexOf(':') + 1, msg.lastIndexOf(':'));
|
||||
ESPUI.updateControl(c, client->id());
|
||||
c->callback(c, TM_VALUE);
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(DEBUG_ESPUI)
|
||||
@ -906,6 +912,10 @@ void ESPUIClass::updateLabel(uint16_t id, const String& value)
|
||||
updateControlValue(id, value);
|
||||
}
|
||||
|
||||
void ESPUIClass::updateButton(uint16_t id, const String& value) {
|
||||
updateControlValue(id, value);
|
||||
}
|
||||
|
||||
void ESPUIClass::updateSlider(uint16_t id, int nValue, int clientId)
|
||||
{
|
||||
updateControlValue(id, String(nValue), clientId);
|
||||
@ -936,6 +946,11 @@ void ESPUIClass::updateGauge(uint16_t id, int number, int clientId)
|
||||
updateControlValue(id, String(number), clientId);
|
||||
}
|
||||
|
||||
void ESPUIClass::updateTime(uint16_t id, int clientId)
|
||||
{
|
||||
updateControl(id, clientId);
|
||||
}
|
||||
|
||||
void ESPUIClass::clearGraph(uint16_t id, int clientId) { }
|
||||
|
||||
void ESPUIClass::addGraphPoint(uint16_t id, int nValue, int clientId)
|
||||
|
@ -56,6 +56,7 @@ enum ControlType : uint8_t
|
||||
Gauge,
|
||||
Accel,
|
||||
Separator,
|
||||
Time,
|
||||
|
||||
UpdateOffset = 100,
|
||||
UpdatePad = 101,
|
||||
@ -76,6 +77,7 @@ enum ControlType : uint8_t
|
||||
UpdateGauge,
|
||||
UpdateAccel,
|
||||
UpdateSeparator,
|
||||
UpdateTime,
|
||||
|
||||
InitialGui = 200,
|
||||
Reload = 201,
|
||||
@ -199,6 +201,7 @@ private:
|
||||
#define N_VALUE 9
|
||||
#define T_VALUE 10
|
||||
#define S_VALUE 11
|
||||
#define TM_VALUE 12
|
||||
|
||||
enum Verbosity : uint8_t
|
||||
{
|
||||
@ -279,12 +282,14 @@ public:
|
||||
|
||||
void print(uint16_t id, const String& value);
|
||||
void updateLabel(uint16_t id, const String& value);
|
||||
void updateButton(uint16_t id, const String& value);
|
||||
void updateSwitcher(uint16_t id, bool 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 updateText(uint16_t id, const 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 updateTime(uint16_t id, int clientId = -1);
|
||||
|
||||
void clearGraph(uint16_t id, int clientId = -1);
|
||||
void addGraphPoint(uint16_t id, int nValue, int clientId = -1);
|
||||
|
File diff suppressed because one or more lines are too long
Loading…
Reference in New Issue
Block a user