dashboard gauge wip
This commit is contained in:
parent
30b06c351a
commit
0103a0bfe5
5 changed files with 343 additions and 4 deletions
|
@ -247,7 +247,165 @@ a.disabled {
|
|||
|
||||
/*@media only screen and (min-width: 640px) {
|
||||
|
||||
}*/)";
|
||||
}*/
|
||||
|
||||
|
||||
/* Gauge CSS
|
||||
* based on https://github.com/sathomas/material-gauge */
|
||||
|
||||
.gauge {
|
||||
position: relative;
|
||||
}
|
||||
|
||||
.gaugeWrapper {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.gauge__container {
|
||||
margin: 0;
|
||||
padding: 0;
|
||||
position: absolute;
|
||||
left: 50%;
|
||||
overflow: hidden;
|
||||
text-align: center;
|
||||
-webkit-transform: translateX(-50%);
|
||||
-moz-transform: translateX(-50%);
|
||||
-ms-transform: translateX(-50%);
|
||||
-o-transform: translateX(-50%);
|
||||
transform: translateX(-50%);
|
||||
}
|
||||
|
||||
.gauge__background {
|
||||
z-index: 0;
|
||||
position: absolute;
|
||||
background-color: #cae0d0;
|
||||
top: 0;
|
||||
border-radius: 300px 300px 0 0;
|
||||
}
|
||||
|
||||
.gauge__data {
|
||||
z-index: 1;
|
||||
position: absolute;
|
||||
background-color: #04AA6D;
|
||||
margin-left: auto;
|
||||
margin-right: auto;
|
||||
border-radius: 300px 300px 0 0;
|
||||
-webkit-transform-origin: center bottom;
|
||||
-moz-transform-origin: center bottom;
|
||||
-ms-transform-origin: center bottom;
|
||||
-o-transform-origin: center bottom;
|
||||
transform-origin: center bottom;
|
||||
}
|
||||
|
||||
.gauge__center {
|
||||
z-index: 2;
|
||||
position: absolute;
|
||||
background-color: #1d211e;
|
||||
margin-right: auto;
|
||||
border-radius: 300px 300px 0 0;
|
||||
}
|
||||
|
||||
.gauge__marker {
|
||||
z-index: 3;
|
||||
background-color: #fff;
|
||||
position: absolute;
|
||||
width: 1px;
|
||||
}
|
||||
|
||||
.gauge__needle {
|
||||
z-index: 4;
|
||||
background-color: #E91E63;
|
||||
height: 3px;
|
||||
position: absolute;
|
||||
-webkit-transform-origin: left center;
|
||||
-moz-transform-origin: left center;
|
||||
-ms-transform-origin: left center;
|
||||
-o-transform-origin: left center;
|
||||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.gauge__labels {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
position: relative;
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gauge__label--low {
|
||||
display: table-cell;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.gauge__label--spacer {
|
||||
display: table-cell;
|
||||
}
|
||||
|
||||
.gauge__label--high {
|
||||
display: table-cell;
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
|
||||
.gauge { height: calc(60px + 3em); }
|
||||
.gauge__container { width: 120px; height: 60px; }
|
||||
.gauge__marker { height: 60px; left: 59.5px; }
|
||||
.gauge__background { width: 120px; height: 60px; }
|
||||
.gauge__center { width: 72px; height: 36px; top: 24px; margin-left: 24px; }
|
||||
.gauge__data { width: 120px; height: 60px; }
|
||||
.gauge__needle { left: 60px; top: 58px; width: 60px; }
|
||||
.gauge__labels { top: 60px; width: 120px; }
|
||||
.gauge__label--low { width: 24px; }
|
||||
.gauge__label--spacer { width: 72px; text-align: center;}
|
||||
.gauge__label--high { width: 24px; }
|
||||
.gaugeLabel { text-align: center; }
|
||||
|
||||
|
||||
@media only screen and (min-width: 720px) {
|
||||
.gauge { height: calc(120px + 4.2em); }
|
||||
.gauge__container { width: 240px; height: 120px; }
|
||||
.gauge__marker { height: 120px; left: 119.5px; }
|
||||
.gauge__background { width: 240px; height: 120px; }
|
||||
.gauge__center { width: 144px; height: 72px; top: 48px; margin-left: 48px; }
|
||||
.gauge__data { width: 240px; height: 120px; }
|
||||
.gauge__needle { left: 120px; top: 117px; width: 120px; }
|
||||
.gauge__labels { top: 120px; width: 240px; }
|
||||
.gauge__label--low { width: 48px; }
|
||||
.gauge__label--spacer { width: 144px; text-align: center;}
|
||||
.gauge__label--high { width: 48px; }
|
||||
.gaugeLabel { font-size: 1.3em; }
|
||||
.gauge__labels { font-size: 2em; }
|
||||
}
|
||||
|
||||
.gauge--liveupdate .gauge__data,
|
||||
.gauge--liveupdate .gauge__needle {
|
||||
-webkit-transition: all 1s ease-in-out;
|
||||
-moz-transition: all 1s ease-in-out;
|
||||
-ms-transition: all 1s ease-in-out;
|
||||
-o-transition: all 1s ease-in-out;
|
||||
transition: all 1s ease-in-out;
|
||||
}
|
||||
|
||||
|
||||
.gauge__data {
|
||||
-webkit-transform: rotate(-.50turn);
|
||||
-moz-transform: rotate(-.50turn);
|
||||
-ms-transform: rotate(-.50turn);
|
||||
-o-transform: rotate(-.50turn);
|
||||
transform: rotate(-.50turn);
|
||||
}
|
||||
.gauge__needle {
|
||||
-webkit-transform: rotate(-.50turn);
|
||||
-moz-transform: rotate(-.50turn);
|
||||
-ms-transform: rotate(-.50turn);
|
||||
-o-transform: rotate(-.50turn);
|
||||
transform: rotate(-.50turn);
|
||||
}
|
||||
|
||||
|
||||
|
||||
)";
|
||||
|
||||
void WebFile_cangrow_CSS(AsyncWebServerRequest *request) {
|
||||
AsyncWebServerResponse *response = request->beginResponse_P(200, F("text/css"), File_cangrow_CSS);
|
||||
|
|
|
@ -231,6 +231,70 @@ function sensorRefresh(sensor, reading, id) {
|
|||
//console.log('sensor:' + sensor + ';reading:' + reading + ';id:' + id + ';element:' + element);
|
||||
}
|
||||
|
||||
|
||||
|
||||
/* Gauge JS
|
||||
* based on https://github.com/sathomas/material-gauge */
|
||||
|
||||
|
||||
function Gauge(el) {
|
||||
|
||||
var element, // Containing element for the info component
|
||||
data, // `.gauge__data` element
|
||||
needle, // `.gauge__needle` element
|
||||
value = 0.0, // Current gauge value from 0 to 1
|
||||
prop, // Style for transform
|
||||
valueLabel; // `.gauge__label--spacer` element
|
||||
|
||||
var setElement = function(el) {
|
||||
// Keep a reference to the various elements and sub-elements
|
||||
element = el;
|
||||
data = element.querySelector('.gauge__data');
|
||||
needle = element.querySelector('.gauge__needle');
|
||||
valueLabel = element.querySelector('.gauge__label--spacer');
|
||||
|
||||
};
|
||||
|
||||
var setValue = function(x, max, unit) {
|
||||
percentage = x * 100 / max;
|
||||
value = percentage / 100;
|
||||
var turns = -0.5 + (value * 0.5);
|
||||
data.style[prop] = 'rotate(' + turns + 'turn)';
|
||||
needle.style[prop] = 'rotate(' + turns + 'turn)';
|
||||
valueLabel.textContent = x + unit;
|
||||
|
||||
};
|
||||
|
||||
function exports() { };
|
||||
|
||||
exports.element = function(el) {
|
||||
if (!arguments.length) { return element; }
|
||||
setElement(el);
|
||||
return this;
|
||||
};
|
||||
|
||||
exports.value = function(x, max=100, unit='%') {
|
||||
if (!arguments.length) { return value; }
|
||||
setValue(x, max, unit);
|
||||
return this;
|
||||
};
|
||||
|
||||
var body = document.getElementsByTagName('body')[0];
|
||||
['webkitTransform', 'mozTransform', 'msTransform', 'oTransform', 'transform'].
|
||||
forEach(function(p) {
|
||||
if (typeof body.style[p] !== 'undefined') { prop = p; }
|
||||
}
|
||||
);
|
||||
|
||||
if (arguments.length) {
|
||||
setElement(el);
|
||||
}
|
||||
|
||||
return exports;
|
||||
|
||||
};
|
||||
|
||||
|
||||
)";
|
||||
|
||||
void WebFile_cangrow_JS(AsyncWebServerRequest *request) {
|
||||
|
|
|
@ -8,14 +8,113 @@
|
|||
|
||||
#include "Page_root_HTML.h"
|
||||
|
||||
|
||||
const byte Max_Dashboard_Gauge_PerLine = 3;
|
||||
|
||||
// https://techtutorialsx.com/2018/07/23/esp32-arduino-http-server-template-processing-with-multiple-placeholders/
|
||||
String Proc_WebPage_root(const String& var) {
|
||||
if(TestHeaderFooter(var)) {
|
||||
return AddHeaderFooter(var);
|
||||
} else if(var == "LOL") {
|
||||
return String("Nice");
|
||||
} else if(var == "GAUGE") {
|
||||
String html;
|
||||
|
||||
/* first count, if any gauges are configured */
|
||||
byte gaugeCount = 0;
|
||||
for(byte i = 0; i < Max_Dashboard_Gauge; i++) {
|
||||
if(config.grow.dashboard.gaugeConfigured[i] == true)
|
||||
gaugeCount++;
|
||||
}
|
||||
|
||||
|
||||
/* if any gauges are configured, create anything needed for drawing gauges */
|
||||
if(gaugeCount > 0) {
|
||||
/* which gauge we are drawing, we count it here. begin with 1 */
|
||||
byte gaugeNr = 0;
|
||||
/* count how many gauges this line are drawn */
|
||||
byte gaugeNrLine = 0;
|
||||
|
||||
for(byte i = 0; i < Max_Dashboard_Gauge; i++) {
|
||||
if(config.grow.dashboard.gaugeConfigured[i] == true) {
|
||||
|
||||
/* increment gaugeNr and gauteNrLine */
|
||||
gaugeNr++;
|
||||
gaugeNrLine++;
|
||||
|
||||
/* when its the first gauge this line */
|
||||
if(gaugeNrLine == 1)
|
||||
/* open gauge wrapper div*/
|
||||
html += F("<div class='gaugeWrapper'>");
|
||||
|
||||
/* open gauge div */
|
||||
html += F("<div class='gauge gauge--liveupdate spacer' id='gauge-");
|
||||
html += config.grow.dashboard.gaugeSensor[i];
|
||||
html += F("-");
|
||||
html += config.grow.dashboard.gaugeRead[i];
|
||||
html += F("' style='float:left; ");
|
||||
|
||||
/* if it is the last gauge, dont add a margin */
|
||||
if(gaugeNrLine < Max_Dashboard_Gauge_PerLine) {
|
||||
html += F("margin-right: 10px;'>");
|
||||
} else {
|
||||
html += F("'>");
|
||||
}
|
||||
|
||||
/* gauge label */
|
||||
html += F("<div class='gaugeLabel'>");
|
||||
html += FPSTR(Sensor_Read_descr[SensorIndex[config.system.sensor.type[config.grow.dashboard.gaugeSensor[i]]].read[config.grow.dashboard.gaugeRead[i]]]);
|
||||
html += F("</div>\n");
|
||||
|
||||
/* rest of the gauge body, its always the same */
|
||||
html += FPSTR(Common_HTML_Gauge_Body);
|
||||
|
||||
if(gaugeNrLine >= Max_Dashboard_Gauge_PerLine) {
|
||||
/* close gauge wrapper div*/
|
||||
html += F("</div>\n");
|
||||
/* reset to 0 , max gauges per line reached */
|
||||
gaugeNrLine = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* build javascript calls for gauges */
|
||||
html += F("<script>");
|
||||
/* iterate again through all configured gauges */
|
||||
for(byte i = 0; i < Max_Dashboard_Gauge; i++) {
|
||||
if(config.grow.dashboard.gaugeConfigured[i] == true) {
|
||||
/* build name of the gauge object */
|
||||
String gaugeName;
|
||||
gaugeName += config.grow.dashboard.gaugeSensor[i];
|
||||
gaugeName += F("-");
|
||||
gaugeName += config.grow.dashboard.gaugeRead[i];
|
||||
|
||||
html += F("var gaugeJS-");
|
||||
html += gaugeName;
|
||||
html += F(" = new Gauge(document.getElementById('gauge-");
|
||||
html += gaugeName;
|
||||
html += F("'));\n");
|
||||
/* "execute" gauge with actual sensor reading */
|
||||
html += F("gauge-");
|
||||
html += gaugeName;
|
||||
html += F(".value('");
|
||||
/* sensor reading */
|
||||
html += Sensor_getCalibratedValue(config.grow.dashboard.gaugeSensor[i], config.grow.dashboard.gaugeRead[i]);
|
||||
html += F("', ");
|
||||
/* gaugeMax */
|
||||
html += config.grow.dashboard.gaugeMax[i];
|
||||
html += F(", ' ");
|
||||
/* reading unit */
|
||||
String unit;
|
||||
unit = FPSTR(Sensor_Read_unit[SensorIndex[config.system.sensor.type[config.grow.dashboard.gaugeSensor[i]]].read[config.grow.dashboard.gaugeRead[i]]]);
|
||||
unit.replace(F("%"), F("%"));
|
||||
html += unit;
|
||||
html += F("');\n");
|
||||
}
|
||||
}
|
||||
/* close script section */
|
||||
html += F("</script>");
|
||||
}
|
||||
|
||||
return html;
|
||||
//return String("Nice");
|
||||
} else if(var == "LOL") {
|
||||
return String("Jojoojo :)");
|
||||
} else {
|
||||
|
|
|
@ -10,4 +10,7 @@
|
|||
const char Page_root_HTML[] PROGMEM = R"EOF(%HEADER%
|
||||
<h2>🌱 Hello world!</h2>
|
||||
<a href='/api/sensor/'>Sensor data -> /api/sensor/</a>
|
||||
|
||||
%GAUGE%
|
||||
|
||||
%FOOTER% )EOF";
|
||||
|
|
|
@ -27,3 +27,18 @@ const char Common_HTML_NEED_RESTART[] PROGMEM = R"EOF(
|
|||
|
||||
const char Common_HTML_ACTION_ADD[] PROGMEM = {"➕ Add"};
|
||||
const char Common_HTML_ACTION_EDIT[] PROGMEM = {"✏️ Edit"};
|
||||
|
||||
const char Common_HTML_Gauge_Body[] PROGMEM = R"EOF(
|
||||
<div class='gauge__container'>
|
||||
<div class='gauge__background'></div>
|
||||
<div class='gauge__center'></div>
|
||||
<div class='gauge__data'></div>
|
||||
<div class='gauge__needle'></div>
|
||||
</div>
|
||||
<div class='gauge__labels mdl-typography__headline'>
|
||||
<span class='gauge__label--low'></span>
|
||||
<span class='gauge__label--spacer'></span>
|
||||
<span class='gauge__label--high'></span>
|
||||
</div>
|
||||
</div>
|
||||
)EOF";
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue