firmware wip - gauge meter for Grow overview :)
This commit is contained in:
parent
cc34bc851b
commit
67d8968d0c
8 changed files with 806 additions and 88 deletions
|
@ -184,14 +184,12 @@ const char HTMLheaderP1[] PROGMEM = R"EOF(
|
|||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||||
<title>
|
||||
)EOF";
|
||||
// here comes the page title in returnHTMLheader()
|
||||
|
||||
// second part of HTML header stuff
|
||||
// Having the whole CSS here ensures it's all the time present
|
||||
const char HTMLheaderP2[] PROGMEM = R"EOF(
|
||||
</title>
|
||||
<link rel='icon' href='data:;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAABcElEQVQ4y42TzU/bQBDFf7Nx1qGuAYVgQSuo2khBggPhyIH//9AiJAQ9tEeLqCKiUD6sxF52OMSEBCdW57aa9968fTsr3V5XWVLPO6sANNL7ZRAMNeU6Ea4T1UEI6pr55kcAwhpMrYOpk2/r/yEQmKWkIonf+TZVgex4Fw0bIEtIAALF3gbZ8U5VwKa3PJ18JT9IpiLvyflBwuhLG5veVUM0/0aoCONPa2hQjWZ8uEVeupJnXSBwO8YOH8iTeAKc2Q4Xt2C1VZL93F7MjbK/bxDnp5Zn7b+So+9pdQ+K/Q5qJlrRj5Ts6DM+rK7Ih7Mr3HaM7jYQVZqXQ6Tb6yqBYdTfomhHiFfUyMI3f+01/z7RHNzTGDyWGThP63SA2d8EEfIkrgQpzmOvH0AV+3M4zegNpUwagAYG8Yp4BS0nl4Kz5Mpf0JXJMby6w/66Aa+M+9uE53/Iexsggq4ESOYWC0jmsBfX8xdXhcJjL4cLc3kBl8uJGQ/CrpAAAAAASUVORK5CYII='>
|
||||
<style>
|
||||
body {
|
||||
|
@ -321,6 +319,284 @@ function convertDateToEpoch(src, dst) {
|
|||
</script>
|
||||
)EOF";
|
||||
|
||||
// The gauge meter are based on sathomas' gaugemeter
|
||||
// https://github.com/sathomas/material-gauge
|
||||
|
||||
const char CSSgauge[] PROGMEM = R"EOF(
|
||||
.gauge {
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.gaugeWrapper {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.gaugeLabel {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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; }
|
||||
|
||||
@media only screen and (min-width: 720px) {
|
||||
.gauge { height: calc(120px + 3em); }
|
||||
.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; }
|
||||
}
|
||||
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
)EOF";
|
||||
|
||||
const char JSgauge[] PROGMEM = R"EOF(
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
)EOF";
|
||||
|
||||
const char HTMLgauge[] PROGMEM = R"EOF(
|
||||
|
||||
<div class='gaugeWrapper'>
|
||||
<div class='gauge gauge--liveupdate' id='gaugeTemperature' style='float:left;'>
|
||||
<span class='gaugeLabel'>Temperature</span>
|
||||
<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>
|
||||
<span class='gauge__label--high'></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='gauge gauge--liveupdate' id='gaugeHumidity' style='float:left;'>
|
||||
<span class='gaugeLabel'>Humidity</span>
|
||||
<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>
|
||||
|
||||
<div class='gauge gauge--liveupdate' id='gaugeSoilmoisture' style='float:left;'>
|
||||
<span class='gaugeLabel'>Moisture</span>
|
||||
<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>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script src='gauge.js'></script>
|
||||
<script>
|
||||
var gaugeTemperature = new Gauge(document.getElementById('gaugeTemperature'));
|
||||
var gaugeHumidity = new Gauge(document.getElementById('gaugeHumidity'));
|
||||
var gaugeSoilmoisture = new Gauge(document.getElementById('gaugeSoilmoisture'));
|
||||
</script>
|
||||
|
||||
)EOF";
|
||||
/*
|
||||
*
|
||||
* Pin assignments
|
||||
|
@ -1350,6 +1626,10 @@ void WebHandler() {
|
|||
// api stuff
|
||||
webserver.on("/api/sensors", HTTP_GET, APIgetSensors);
|
||||
|
||||
|
||||
// gauge meter stuff
|
||||
webserver.on("/gauge.css", HTTP_GET, WEBgaugeCss);
|
||||
webserver.on("/gauge.js", HTTP_GET, WEBgaugeJs);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -1362,6 +1642,8 @@ String returnHTMLheader(String MenuEntry = "") {
|
|||
String activeMenu = "class='activeMenu'";
|
||||
// add first part of the header
|
||||
header += FPSTR(HTMLheaderP1);
|
||||
// add title tag
|
||||
header += "<title>";
|
||||
// check if GrowName was set. if yes, its part of the page title.
|
||||
if(strlen(GrowName) > 0) {
|
||||
header += "CanGrow - ";
|
||||
|
@ -1369,6 +1651,13 @@ String returnHTMLheader(String MenuEntry = "") {
|
|||
} else {
|
||||
header += "CanGrow";
|
||||
}
|
||||
// close title tag
|
||||
header += "</title>\n";
|
||||
|
||||
// add additional header stuff, like loading guage files
|
||||
if(MenuEntry == "root") {
|
||||
header += "<link rel='stylesheet' type='text/css' href='gauge.css'>";
|
||||
}
|
||||
|
||||
header += FPSTR(HTMLheaderP2);
|
||||
|
||||
|
@ -1580,6 +1869,19 @@ void Syslogout() {
|
|||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Gauge meter files
|
||||
*/
|
||||
void WEBgaugeCss() {
|
||||
//String css = CSSgauge;
|
||||
webserver.send(200, "text/css", FPSTR(CSSgauge));
|
||||
}
|
||||
|
||||
void WEBgaugeJs() {
|
||||
//String javascript = JSgauge;
|
||||
webserver.send(200, "text/javascript", FPSTR(JSgauge));
|
||||
}
|
||||
|
||||
/*
|
||||
* Root page
|
||||
*/
|
||||
|
@ -1595,37 +1897,50 @@ void WEBroot() {
|
|||
webserver.sendHeader("Location", String("/growSettings"), true);
|
||||
webserver.send(302, "text/plain", "please configure growSettings first");
|
||||
} else {
|
||||
String body = returnHTMLheader();
|
||||
String body = returnHTMLheader("root");
|
||||
|
||||
body += "<h1>🌱 ";
|
||||
body += "<h2>🌱 ";
|
||||
body += GrowName;
|
||||
body += "</h1>";
|
||||
body += "</h2>";
|
||||
|
||||
// add gauge meter
|
||||
body += FPSTR(HTMLgauge);
|
||||
// and give javascript the values
|
||||
// todo: auto refresh by api call
|
||||
body += "<script>";
|
||||
|
||||
body += "gaugeTemperature.value(";
|
||||
body += valTemperature;
|
||||
body += ", 42, ' °C' ); ";
|
||||
|
||||
body += "gaugeHumidity.value(";
|
||||
body += valHumidity;
|
||||
body += " ); ";
|
||||
|
||||
body += "gaugeSoilmoisture.value(";
|
||||
body += valSoilmoisture;
|
||||
body += " ); ";
|
||||
|
||||
body += "</script>";
|
||||
|
||||
body += "Grow started: ";
|
||||
body += returnStrDateFromEpoch(GrowStart);
|
||||
body += "<br>\n";
|
||||
body += "Day of Grow: ";
|
||||
body += DayOfGrow;
|
||||
body += "<br>\n";
|
||||
body += "Soil Moisture: ";
|
||||
body += valSoilmoisture;
|
||||
body += " %<br>\n";
|
||||
body += "Humidity: ";
|
||||
body += valHumidity;
|
||||
body += " %<br>\n";
|
||||
body += "Temperature: ";
|
||||
body += valTemperature;
|
||||
body += " °C<br>\n";
|
||||
|
||||
if(UsePump == true) {
|
||||
body += "Pump water level: ";
|
||||
switch(getWaterlevel()) {
|
||||
case 0:
|
||||
body += "OK";
|
||||
body += "<span style='color: green;'>OK</span>";
|
||||
break;
|
||||
case 1:
|
||||
body += "Warning";
|
||||
body += "<span style='color: yellow;'>Warning</span>";
|
||||
break;
|
||||
case 2:
|
||||
body += "Critical";
|
||||
body += "<span style='color: red;'>Critical</span>";
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
@ -1651,7 +1966,8 @@ void WEBroot() {
|
|||
|
||||
body += "<input type='submit' value='Save'>\n";
|
||||
body += "</form>";
|
||||
|
||||
|
||||
|
||||
body += FPSTR(HTMLfooter);
|
||||
|
||||
webserver.send(200, "text/html", body);
|
||||
|
|
BIN
playground/html/material-gauge-gh-pages/.material-gauge.js.swp
Normal file
BIN
playground/html/material-gauge-gh-pages/.material-gauge.js.swp
Normal file
Binary file not shown.
|
@ -1,13 +1,13 @@
|
|||
<!doctype html>
|
||||
<html lang="en">
|
||||
<html lang='en'>
|
||||
<head>
|
||||
<meta charset="utf-8">
|
||||
<meta http-equiv="x-ua-compatible" content="ie=edge">
|
||||
<meta charset='utf-8'>
|
||||
<meta http-equiv='x-ua-compatible' content='ie=edge'>
|
||||
<title>Material Design Gauge</title>
|
||||
<meta name="description"
|
||||
content="Simple Material Design gauge control implemented in pure CSS/HTML">
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<link rel="stylesheet" type="text/css" href="material-gauge.css">
|
||||
<meta name='description'
|
||||
content='Simple Material Design gauge control implemented in pure CSS/HTML'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1'>
|
||||
<link rel='stylesheet' type='text/css' href='material-gauge.css'>
|
||||
<style>
|
||||
|
||||
body {
|
||||
|
@ -29,64 +29,64 @@
|
|||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<div class="center">
|
||||
<div style="overflow: hidden;">
|
||||
<div class="gauge gauge--liveupdate" id="gauge" style="float:left;">
|
||||
<span >Humidity</span>
|
||||
<div class="gauge__container">
|
||||
<div class='center'>
|
||||
<div style='overflow: hidden; display: flex; justify-content: center;'>
|
||||
<div class='gauge gauge--liveupdate' id='gauge' style='float:left;'>
|
||||
<span class='gaugeLabel'>Humidity</span>
|
||||
<div class='gauge__container'>
|
||||
|
||||
<!-- <div class="gauge__marker"></div> -->
|
||||
<div class="gauge__background"></div>
|
||||
<div class="gauge__center"></div>
|
||||
<div class="gauge__data"></div>
|
||||
<div class="gauge__needle"></div>
|
||||
<!-- <div class='gauge__marker'></div> -->
|
||||
<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 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>
|
||||
|
||||
<div class="gauge gauge--liveupdate" id="gauge2" style="float:left;">
|
||||
<span >Moisture</span>
|
||||
<div class="gauge__container">
|
||||
<!-- <div class="gauge__marker"></div> -->
|
||||
<div class="gauge__background"></div>
|
||||
<div class="gauge__center"></div>
|
||||
<div class="gauge__data"></div>
|
||||
<div class="gauge__needle"></div>
|
||||
<div class='gauge gauge--liveupdate' id='gauge2' style='float:left;'>
|
||||
<span class='gaugeLabel'>Moisture</span>
|
||||
<div class='gauge__container'>
|
||||
<!-- <div class='gauge__marker'></div> -->
|
||||
<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 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>
|
||||
|
||||
<div class="gauge gauge--liveupdate" id="gauge3" style="float:left;">
|
||||
<span >Temperature</span>
|
||||
<div class="gauge__container">
|
||||
<!-- <div class="gauge__marker"></div> -->
|
||||
<div class="gauge__background"></div>
|
||||
<div class="gauge__center"></div>
|
||||
<div class="gauge__data"></div>
|
||||
<div class="gauge__needle"></div>
|
||||
<div class='gauge gauge--liveupdate' id='gauge3' style='float:left;'>
|
||||
<span class='gaugeLabel'>Temperature</span>
|
||||
<div class='gauge__container'>
|
||||
<!-- <div class='gauge__marker'></div> -->
|
||||
<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>
|
||||
<span class="gauge__label--high"></span>
|
||||
<div class='gauge__labels mdl-typography__headline'>
|
||||
<span class='gauge__label--low'></span>
|
||||
<span class='gauge__label--spacer'></span></span>
|
||||
<span class='gauge__label--high'></span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<script src="material-gauge.js"></script>
|
||||
<script src='material-gauge.js'></script>
|
||||
<script>
|
||||
|
||||
var gauge = new Gauge(document.getElementById("gauge"));
|
||||
var gauge2 = new Gauge(document.getElementById("gauge2"));
|
||||
var gauge3 = new Gauge(document.getElementById("gauge3"));
|
||||
var gauge = new Gauge(document.getElementById('gauge'));
|
||||
var gauge2 = new Gauge(document.getElementById('gauge2'));
|
||||
var gauge3 = new Gauge(document.getElementById('gauge3'));
|
||||
|
||||
//gauge.value(75);
|
||||
//gauge2.value(50);
|
||||
|
|
|
@ -3,18 +3,18 @@
|
|||
*
|
||||
* The standard markup for the component is:
|
||||
*
|
||||
* <div class="gauge">
|
||||
* <div class="gauge__container">
|
||||
* <div class="gauge__marker"></div>
|
||||
* <div class="gauge__background"></div>
|
||||
* <div class="gauge__center"></div>
|
||||
* <div class="gauge__data"></div>
|
||||
* <div class="gauge__needle"></div>
|
||||
* <div class='gauge'>
|
||||
* <div class='gauge__container'>
|
||||
* <div class='gauge__marker'></div>
|
||||
* <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">
|
||||
* <span class="gauge__label--low">No</span>
|
||||
* <span class="gauge__label--spacer"></span>
|
||||
* <span class="gauge__label--high">Yes</span>
|
||||
* <div class='gauge__labels'>
|
||||
* <span class='gauge__label--low'>No</span>
|
||||
* <span class='gauge__label--spacer'></span>
|
||||
* <span class='gauge__label--high'>Yes</span>
|
||||
* </div>
|
||||
* </div>
|
||||
*/
|
||||
|
@ -93,6 +93,10 @@
|
|||
transform-origin: left center;
|
||||
}
|
||||
|
||||
.gaugeLabel {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.gauge__labels {
|
||||
display: table;
|
||||
margin: 0 auto;
|
||||
|
|
|
@ -21,11 +21,11 @@ function Gauge(el) {
|
|||
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");
|
||||
data = element.querySelector('.gauge__data');
|
||||
needle = element.querySelector('.gauge__needle');
|
||||
valueLabel = element.querySelector('.gauge__label--spacer');
|
||||
|
||||
//valueLabel = element.getElementsByTagName("span"); //valueLabel = element.querySelector("span.gauge__label--spacer");
|
||||
//valueLabel = element.getElementsByTagName('span'); //valueLabel = element.querySelector('span.gauge__label--spacer');
|
||||
|
||||
};
|
||||
|
||||
|
@ -33,13 +33,13 @@ function Gauge(el) {
|
|||
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)";
|
||||
data.style[prop] = 'rotate(' + turns + 'turn)';
|
||||
needle.style[prop] = 'rotate(' + turns + 'turn)';
|
||||
valueLabel.textContent = x + unit;
|
||||
/*
|
||||
for (var i = 0; i < valueLabel.children.length; i++) {
|
||||
window.alert(valueLabel.children[i].className);
|
||||
if (valueLabel.children[i].className == "gauge__label--spacer") {
|
||||
if (valueLabel.children[i].className == 'gauge__label--spacer') {
|
||||
window.alert(valueLabel.children[i]);
|
||||
valueLabel.children[i].textContent = x + unit;
|
||||
break;
|
||||
|
@ -68,10 +68,10 @@ function Gauge(el) {
|
|||
|
||||
// ##### Initialization
|
||||
|
||||
var body = document.getElementsByTagName("body")[0];
|
||||
["webkitTransform", "mozTransform", "msTransform", "oTransform", "transform"].
|
||||
var body = document.getElementsByTagName('body')[0];
|
||||
['webkitTransform', 'mozTransform', 'msTransform', 'oTransform', 'transform'].
|
||||
forEach(function(p) {
|
||||
if (typeof body.style[p] !== "undefined") { prop = p; }
|
||||
if (typeof body.style[p] !== 'undefined') { prop = p; }
|
||||
}
|
||||
);
|
||||
|
||||
|
|
152
playground/html/root/gauge.css
Normal file
152
playground/html/root/gauge.css
Normal file
|
@ -0,0 +1,152 @@
|
|||
|
||||
.gauge {
|
||||
position: relative;
|
||||
margin-right: 10px;
|
||||
}
|
||||
|
||||
.gaugeWrapper {
|
||||
overflow: hidden;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
}
|
||||
|
||||
.gaugeLabel {
|
||||
font-weight: bold;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
.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; }
|
||||
|
||||
@media only screen and (min-width: 720px) {
|
||||
.gauge { height: calc(120px + 3em); }
|
||||
.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; }
|
||||
}
|
||||
|
||||
.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);
|
||||
}
|
||||
|
||||
|
61
playground/html/root/gauge.js
Normal file
61
playground/html/root/gauge.js
Normal file
|
@ -0,0 +1,61 @@
|
|||
|
||||
|
||||
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;
|
||||
|
||||
};
|
||||
|
||||
|
||||
|
185
playground/html/root/index.html
Normal file
185
playground/html/root/index.html
Normal file
|
@ -0,0 +1,185 @@
|
|||
|
||||
<!DOCTYPE html>
|
||||
<html>
|
||||
<head>
|
||||
<meta charset='UTF-8'>
|
||||
<meta name='viewport' content='width=device-width, initial-scale=1.0'>
|
||||
<title>CanGrow - Ruderalis Indica</title>
|
||||
<link rel='stylesheet' type='text/css' href='gauge.css'>
|
||||
<link rel='icon' href='data:;base64,iVBORw0KGgoAAAANSUhEUgAAABAAAAAQCAYAAAAf8/9hAAAABmJLR0QAAAAAAAD5Q7t/AAAACXBIWXMAAAsTAAALEwEAmpwYAAABcElEQVQ4y42TzU/bQBDFf7Nx1qGuAYVgQSuo2khBggPhyIH//9AiJAQ9tEeLqCKiUD6sxF52OMSEBCdW57aa9968fTsr3V5XWVLPO6sANNL7ZRAMNeU6Ea4T1UEI6pr55kcAwhpMrYOpk2/r/yEQmKWkIonf+TZVgex4Fw0bIEtIAALF3gbZ8U5VwKa3PJ18JT9IpiLvyflBwuhLG5veVUM0/0aoCONPa2hQjWZ8uEVeupJnXSBwO8YOH8iTeAKc2Q4Xt2C1VZL93F7MjbK/bxDnp5Zn7b+So+9pdQ+K/Q5qJlrRj5Ts6DM+rK7Ih7Mr3HaM7jYQVZqXQ6Tb6yqBYdTfomhHiFfUyMI3f+01/z7RHNzTGDyWGThP63SA2d8EEfIkrgQpzmOvH0AV+3M4zegNpUwagAYG8Yp4BS0nl4Kz5Mpf0JXJMby6w/66Aa+M+9uE53/Iexsggq4ESOYWC0jmsBfX8xdXhcJjL4cLc3kBl8uJGQ/CrpAAAAAASUVORK5CYII='>
|
||||
<style>
|
||||
body {
|
||||
color: #cae0d0;
|
||||
background-color: #1d211e;
|
||||
font-family: helvetica;
|
||||
}
|
||||
.center {
|
||||
width: 60%; min-width: 420px;
|
||||
margin: auto;
|
||||
|
||||
}
|
||||
h1, h2, h3, h4, h5 {
|
||||
text-align: center;
|
||||
}
|
||||
a:link, a:visited {
|
||||
color: #04AA6D;
|
||||
}
|
||||
a:hover {
|
||||
color: #64AA6D;
|
||||
}
|
||||
a:active {
|
||||
color: #04AA6D;
|
||||
}
|
||||
.infomsg , .warnmsg {
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
padding: 4px;
|
||||
width: fit-content; min-width: 200px; max-width: 420px;
|
||||
margin: auto;
|
||||
margin-bottom: 5px;
|
||||
font-weight: bold;
|
||||
text-align: center;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.infomsg {
|
||||
background: #04AA6D;
|
||||
}
|
||||
.warnmsg {
|
||||
background: #aa4204;
|
||||
}
|
||||
.inputShort {
|
||||
width: 42px;
|
||||
}
|
||||
.nav {
|
||||
background: #333;
|
||||
width: 60%; min-width: 420px;
|
||||
margin: auto;
|
||||
margin-bottom: 10px;
|
||||
padding: 0;
|
||||
position: relative;
|
||||
border-radius: 3px;
|
||||
}
|
||||
|
||||
.nav li {
|
||||
display: inline-block;
|
||||
list-style: none;
|
||||
}
|
||||
|
||||
.nav li:first-of-type {
|
||||
background: #026b45;
|
||||
border-top-left-radius: 3px;
|
||||
border-bottom-left-radius: 3px;
|
||||
}
|
||||
.nav li a , .nav span {
|
||||
color: #ddd;
|
||||
display: block;
|
||||
font-family: 'Lucida Sans Unicode', 'Lucida Grande', sans-serif;
|
||||
font-size:0.8em;
|
||||
padding: 10px 20px;
|
||||
text-decoration: none;
|
||||
text-shadow: 0 -1px 0 rgba(0, 0, 0, 0.5);
|
||||
}
|
||||
.nav li a:hover , .activeMenu , .menuTime{
|
||||
background: #04AA6D;
|
||||
color: #fff;
|
||||
border-radius: 3px;
|
||||
}
|
||||
.nav li a:active {
|
||||
color: #cae0d0;
|
||||
}
|
||||
.activeMenu {
|
||||
background: #444;
|
||||
}
|
||||
.MenuTime {
|
||||
background: #292929;
|
||||
}
|
||||
</style>
|
||||
</head>
|
||||
<body>
|
||||
<ul class='nav'><li><a href='/'>🌱 Ruderalis Indica</a></li>
|
||||
<li><a href='/growSettings' >Grow settings</a></li>
|
||||
<li><a href='/systemSettings' >System settings</a></li>
|
||||
<li><a href='/wifiSettings' >WiFi settings</a></li>
|
||||
<li><a href='/help' >Help</a></li>
|
||||
<li><span class='MenuTime'>23:57:31</span></li>
|
||||
<li><a href='https://git.la10cy.net/DeltaLima/CanGrow' target='_blank'>CanGrow v0.1</a></li>
|
||||
</ul><div class='center'><h2>🌱 Ruderalis Indica</h2>
|
||||
|
||||
|
||||
<div class='gaugeWrapper'>
|
||||
<div class='gauge gauge--liveupdate' id='gaugeTemperature' style='float:left;'>
|
||||
<span class='gaugeLabel'>Temperature</span>
|
||||
<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>
|
||||
<span class='gauge__label--high'></span>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class='gauge gauge--liveupdate' id='gaugeHumidity' style='float:left;'>
|
||||
<span class='gaugeLabel'>Humidity</span>
|
||||
<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>
|
||||
|
||||
<div class='gauge gauge--liveupdate' id='gaugeSoilmoisture' style='float:left;'>
|
||||
<span class='gaugeLabel'>Moisture</span>
|
||||
<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>
|
||||
|
||||
|
||||
</div>
|
||||
|
||||
<script src='gauge.js'></script>
|
||||
<script>
|
||||
var gaugeTemperature = new Gauge(document.getElementById('gaugeTemperature'));
|
||||
var gaugeHumidity = new Gauge(document.getElementById('gaugeHumidity'));
|
||||
var gaugeSoilmoisture = new Gauge(document.getElementById('gaugeSoilmoisture'));
|
||||
</script>
|
||||
Grow started: 2024-04-12<br>
|
||||
Day of Grow: 20<br>
|
||||
<script>gaugeTemperature.value(22.00, 42, ' °C' ); gaugeHumidity.value(59.00 ); gaugeSoilmoisture.value(98 ); </script>Pump water level: <span style='color: red;'>Critical</span><br>
|
||||
Growlight brightnes: 100 %<br>
|
||||
<form method='post' action='/switch'>
|
||||
MOSFET<select id='output' name='output' required>
|
||||
<option disabled value='' selected hidden>---</option>
|
||||
<option value='1'>LED</option>
|
||||
<option value='2'>FAN</option>
|
||||
<option value='3'>PUMP</option>
|
||||
</select><br>On/Off: <select id='state' name='state' required>
|
||||
<option disabled value='' selected hidden>---</option>
|
||||
<option value='1'>On</option>
|
||||
<option value='0'>Off</option>
|
||||
</select><br>
|
||||
Intensity: <input type='range' id='OutputPWM' name='OutputPWM' min='1' max='255' value='255'/><br>
|
||||
<input type='submit' value='Save'>
|
||||
</form>
|
||||
</div>
|
||||
</body>
|
||||
</html>
|
Loading…
Reference in a new issue