Documentation updates

This commit is contained in:
2023-11-10 12:19:06 -06:00
parent a81d497dcc
commit 7c53fd81b4
10 changed files with 113 additions and 94 deletions

View File

@@ -179,6 +179,7 @@ void HandleAPConfigPage() {
String url = wifiConfig.getURL();
String ntp = wifiConfig.getNTPServerName();
// Handle submissions from the client
if (server.hasArg("ssid") && server.hasArg("pass")) {
String _ssid = server.hasArg("_ssid") ? server.arg("_ssid") : "";
String _pass = server.hasArg("_pass") ? server.arg("_pass") : "";
@@ -207,11 +208,17 @@ void HandleAPConfigPage() {
}
}
// Send [updated] Configuration page to client
//
String modeText = (WiFiStateGet() == WFC_JoinedAP) ? "Station mode<br/>" : "Access Point mode<br/>";
if (server.hasArg("ssid") && !server.hasArg("pass")) {
ssid = server.arg("ssid");
pass = "";
Serial.println("ssid: " + ssid + ", pass: " + pass);
} else {
Serial.printf("name : %s\n", name.c_str());
Serial.printf(" ssid: %s\n", ssid.c_str());
Serial.printf(" pass: %s\n", pass.c_str());
}
if (server.hasArg("url"))
url = server.arg("url");
@@ -220,60 +227,55 @@ void HandleAPConfigPage() {
server.send(200, "text/html",
"<!DOCTYPE html>\n"
"<html>\n"
"<head><title>Grow Controller - Config</title></head>\n"
"<body>\n"
"<head><title>Grow Controller - Config</title>\n"
"<meta http-equiv='Content-Type' content='text/html;charset=UTF-8'>\n"
"<meta name='viewport' content='initial-scale=1.0, width=device-width'>\n"
"</head>\n"
"<body onload='NavInit();'>\n"
"<h1>Grow Controller - Configuration</h1>"
" <form action=\"\">\n"
" <blockquote>\n"
" <table border='0'>\n"
" <tr>\n"
" <td>Node Name</td>\n"
" <td><input type=\"text\" size=\"32\" name=\"name\" value=\"" + name + "\" /></td>\n"
" <td><input type='text' size='32' maxlength='32' name='name' value='" + name + "' /></td>\n"
" </tr>\n"
" <tr>\n"
" <td>SSID</td>\n"
" <td><input type=\"text\" size=\"32\" name=\"ssid\" value=\"" + ssid + "\" />&nbsp;**\n"
" <input type=\"hidden\" name=\"_ssid\" value=\"" + ssid + "\" /></td>\n"
" <td><input type='text' size='32' maxlength='32' name='ssid' value='" + ssid + "' />&nbsp;**\n"
" <input type='hidden' name='_ssid' value='" + ssid + "' /></td>\n"
" </tr>\n"
" <tr nowrap='nowrap'>\n"
" <td>Password</td>\n"
" <td nowrap='nowrap'><input type=\"password\" size=\"64\" name=\"pass\" value=\"" + pass + "\" />&nbsp;**\n"
" <input type=\"hidden\" name=\"_pass\" value=\"" + pass + "\" /></td>\n"
" <td nowrap='nowrap'><input type='password' size='32' maxlength='64' name='pass' value='" + pass + "' />&nbsp;**\n"
" <input type='hidden' name='_pass' value='" + pass + "' /></td>\n"
" </tr>\n"
" <tr>\n"
" <td>Update URL</td>\n"
" <td><input type=\"text\" size=\"64\" name=\"url\" value=\"" + url + "\" /></td>\n"
" <td><input type='text' size='32' maxlength='64' name='url' value='" + url + "' /></td>\n"
" </tr>\n"
" <tr>\n"
" <td>NTP Server</td>\n"
" <td><input type=\"text\" size=\"64\" name=\"ntp\" value=\"" + ntp + "\" /></td>\n"
" </tr>\n"
// " <tr>\n"
// " <td>NTP Server</td>\n"
// " <td><input type=\"text\" size=\"64\" name=\"ntp\" value=\"" + ntp + "\" /></td>\n"
// " </tr>\n"
" <tr>\n"
" <td>&nbsp;</td>\n"
" <td>\n"
" <input type=\"submit\" value=\"Save\" />\n"
" <input type=\"reset\"/> ** Changes to these will trigger a module restart.\n"
" <input type='submit' value='Save' />\n"
" <input type='reset'/> ** Changes to these will trigger a module restart.\n"
" </td>\n"
" </tr>\n"
" <tr>\n"
" <tr>\n"
" <td colspan='2'><hr/></td>\n"
" </tr>\n"
" <tr>\n"
" <td>&nbsp;</td>\n"
" <td><a href='/swupdatecheck'>Check for SW update (module will restart if updated)</a></td/>\n"
" </tr>\n"
" </tr>\n"
" <tr>\n"
" <td>&nbsp;</td>\n"
" <td><a href='/swupdatecheck'>Check for SW update (module will restart if updated)</a></td/>\n"
" </tr>\n"
" </table>\n"
" </blockquote>\n"
" </form>\n"
"NAV:&nbsp;&nbsp;"
" <a href='/'>Home</a> | "
" <a href='/config'>Config</a> | "
" <a href='/scan'>Scan</a> | "
" <a href='/rssi'>RSSI</a> | "
" <a href='/curr'>Current</a> | "
" <a href='/config?ssid=reset&pass=reset' onclick=\"return confirm('Are you sure?')\">Factory Reset</a> | "
" <a href='/about'>About</a>\n"
" <br/>\n"
"<span id='nav'></span>\n"
"</body>\n"
"</html>\n"
);

View File

@@ -1,9 +1,12 @@
//
//
//
#ifndef PLANTMODEL_H
#define PLANTMODEL_H
#include "ProjGlobals.h"
void HandleGetState();
void simulation();
#endif // PLANTMODEL_H

Binary file not shown.

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

@@ -28,12 +28,12 @@ getIt = function (aUrl, callback) {
function RefreshStatus() {
getIt(url,
function (data) {
obj = JSON.parse(data);
UpdateGraph(obj.raw, obj.sense); // raw and averaged
document.getElementById('uptime').innerHTML = 'Uptime: ' + obj.uptime;
document.getElementById('currText').innerHTML = 'raw: ' + obj.raw + ', avg: ' + obj.sense;
}
function (data) {
obj = JSON.parse(data);
UpdateGraph(obj.raw, obj.sense); // raw and averaged
document.getElementById('uptime').innerHTML = 'Uptime: ' + obj.uptime;
document.getElementById('currText').innerHTML = 'raw: ' + obj.raw + ', avg: ' + obj.sense;
}
);
}

View File

@@ -39,7 +39,7 @@
<div class='SoilTemp_C' id='SoilTemp_C' >--.- &deg;F</div>
<div class='SoilMoisture_X' id='SoilMoisture_X' >-- %</div>
<div class='DrumDoorIcon' id='DrumDoorIcon' ><img src='open.png' title='Open' /></div>
<div class='DrumState' id='DrumState' ><img src='open.png' title='Open' /></div>
<div class='DrumOpenSensor' id='DrumOpenSensor' >O</div>
<div class='DrumClosedSensor' id='DrumClosedSensor' >C</div>
<div class='DrumMotorLabel' id='DrumMotorLabel' >Motor</div>
@@ -57,7 +57,7 @@
<div class='WaterCycleOn_sec' id='WaterCycleOn_sec' >8 s</div>
<div class='WaterCycle_sec' id='WaterCycle_sec' >10 s</div>
<div class='WaterCycleOnBox' id='WaterCycleOnBox' ></div>
<div class='WaterCycleStatusIcon' id='WaterCycleStatusIcon' ><img src='pointer.png' title='Pump On Time' /></div>
<div class='WaterCyclePointer_sec' id='WaterCyclePointer_sec' ><img src='pointer.png' title='Pump On Time' /></div>
</div>
</td>
<td width='10%' align='center'>

View File

@@ -1,9 +1,13 @@
//
// Main Page period status update
//
// @todo Draw the 'drum' as an arc instead of trying to rotate a picture of an arc.
// which will work better to reflect the opening.
//
//
// var mySite = 'http://192.168.1.23'; // from myip.js
var url = mySite + '/state';
setInterval(RefreshStatus, 2500);
setInterval(RefreshStatus, 1000); // @todo speed this up to 500 msec or even 250
getIt = function (aUrl, callback) {
var xhr = new XMLHttpRequest();
@@ -19,28 +23,24 @@ getIt = function (aUrl, callback) {
function ConvertTempToString(tempC, showF) {
var tempF = tempC * 9 / 5 + 32;
if (showF)
return tempF.toFixed(1) + "&deg;F";
if (showF == 0)
return tempF.toFixed(0) + "&deg;F";
else
return tempC.toFixed(1) + "&deg;C";
return tempC.toFixed(0) + "&deg;C";
}
function ConvertSecToMMSS(sec) {
mm = parseInt(sec/60).toString().padStart(4,'0');
ss = (sec%60).toString().padStart(2,'0');
return mm + ":" + ss;
}
function RefreshStatus() {
getIt(url,
function(data) {
obj = JSON.parse(data);
if (obj.state === 1)
state = "On";
else
state = "Off";
document.getElementById('version').innerHTML = obj.version;
document.getElementById('name').innerHTML = obj.name;
//document.getElementById('state').innerHTML = 'Output: ' + state;
//document.getElementById('raw').innerHTML = 'raw: ' + obj.raw;
//document.getElementById('sense').innerHTML = 'Sense: ' + obj.sense;
//document.getElementById('toggle').innerHTML = 'Toggle: ' + obj.toggle;
//document.getElementById('reset').innerHTML = 'Reset: ' + obj.reset;
//document.getElementById('countdown').innerHTML = 'Countdown: ' + obj.countdown;
document.getElementById('uptime').innerHTML = 'Uptime: ' + obj.uptime;
document.getElementById('wifimode').innerHTML = 'WiFi Mode: ' + obj.wifimode;
// IP Address
@@ -67,7 +67,7 @@ function RefreshStatus() {
}
if (typeof obj.SoilHeater != "undefined") {
document.getElementById('SoilHeater').innerHTML = obj.SoilHeater;
document.getElementById('SoilHeater').innerHTML = (obj.SoilHeater) ? "Heat On" : "Heat Off";
} else {
document.getElementById('SoilHeater').innerHTML = "--";
}
@@ -83,24 +83,34 @@ function RefreshStatus() {
document.getElementById('SoilMoisture_X').innerHTML = "--";
}
if (obj.DrumDoorIcon == 1) {
document.getElementById('DrumDoorIcon').style.display === "none";
if (obj.DrumState == 1) { // closed, hide the "open" image
document.getElementById('DrumState').style.display === "none";
} else {
document.getElementById('DrumDoorIcon').style.display === "block";
document.getElementById('DrumState').style.display === "block";
}
document.getElementById('DrumOpenSensor').innerHTML = obj.DrumOpenSensor;
document.getElementById('DrumClosedSensor').innerHTML = obj.DrumClosedSensor;
document.getElementById('DrumMotorStatus').innerHTML = obj.DrumMotorStatus;
document.getElementById('DrumOpenSensor').innerHTML = (obj.DrumOpenSensor) ? "O" : "!O";
document.getElementById('DrumClosedSensor').innerHTML = (obj.DrumClosedSensor) ? "C" : "!C";
document.getElementById('DrumMotorStatus').innerHTML = (obj.DrumMotorStatus == 0) ? "stopped" : (obj.DrumMotorStatus == 1) ? "CW" : "CCW";
document.getElementById('DrumMotorOn_sec').innerHTML = obj.DrumMotorOn_sec + "s";
document.getElementById('DrumMotor_V').innerHTML = parseFloat(obj.DrumMotor_V).toFixed(1) + "V";
document.getElementById('DrumMotor_I').innerHTML = parseFloat(obj.DrumMotor_I).toFixed(1) + "A";
document.getElementById('DrumMotor_V').innerHTML = parseFloat(obj.DrumMotor_V).toFixed(1) + " V";
document.getElementById('DrumMotor_I').innerHTML = parseFloat(obj.DrumMotor_I).toFixed(1) + " A";
document.getElementById('WaterInTank').innerHTML = obj.WaterInTank;
document.getElementById('WaterPumpStatus').innerHTML = obj.WaterPumpStatus;
document.getElementById('WaterMotor_V').innerHTML = parseFloat(obj.WaterMotor_V).toFixed(1) + "V";
document.getElementById('WaterCyclePeriod_sec').innerHTML = obj.WaterCyclePeriod_sec + "s";
document.getElementById('WaterCycleOn_sec').innerHTML = obj.WaterCycleOn_sec + "s";
document.getElementById('WaterCycle_sec').innerHTML = obj.WaterCycle_sec + "s";
document.getElementById('WaterPumpStatus').innerHTML = (obj.WaterPumpStatus) ? "On" : "Off";
document.getElementById('WaterMotor_V').innerHTML = parseFloat(obj.WaterMotor_V).toFixed(1) + " V";
document.getElementById('WaterCyclePeriod_sec').innerHTML = ConvertSecToMMSS(obj.WaterCyclePeriod_sec);
document.getElementById('WaterCycleOn_sec').innerHTML = ConvertSecToMMSS(obj.WaterCycleOn_sec);
document.getElementById('WaterCycle_sec').innerHTML = ConvertSecToMMSS(obj.WaterCycle_sec);
// The full-scale pump timer box ranges from 22 to 234px
// The WaterCycleOnBox.width is proportional to the WaterCyclePeriod_sec and the (234 - 22)px width
var boxW = (234 - 22);
// The WaterCyclePointer_sec.width (24) is positioned from 22 to 234 - 1/2 width.
var onW = (obj.WaterCycleOn_sec/obj.WaterCyclePeriod_sec) * boxW;
var ptrX = 22 + (obj.WaterCycle_sec/obj.WaterCyclePeriod_sec) * boxW - 12;
console.log("onW: " + onW + ", ptrX: " + ptrX);
document.getElementById('WaterCycleOnBox').width = onW;
document.getElementById('WaterCyclePointer_sec').left = ptrX;
}
);
}

View File

@@ -53,7 +53,7 @@ div.ChamberHumi {
}
div.SoilMoisture_X {
position: absolute;
left: 130px;
left: 135px;
top: 135px;
color: white;
}
@@ -64,12 +64,12 @@ div.SoilHumiIcon {
}
div.SoilThermoIcon {
position: absolute;
left: 170px;
left: 175px;
top: 100px;
}
div.SoilTemp_C {
position: absolute;
left: 165px;
left: 170px;
top: 135px;
color: white;
}
@@ -90,7 +90,7 @@ div.SoilHeaterOffIcon {
top: 181px;
}
div.DrumDoorIcon {
div.DrumState {
position: absolute;
transform: rotate(180deg);
left: 14px;
@@ -109,7 +109,7 @@ div.DrumClosedSensor {
div.DrumMotorLabel {
position: absolute;
left: 95px;
top: 270px;
top: 260px;
width: 50px;
text-align: center;
color: white;
@@ -117,7 +117,7 @@ div.DrumMotorLabel {
div.DrumMotorStatus {
position: absolute;
left: 95px;
top: 290px;
top: 280px;
width: 50px;
text-align: center;
color: white;
@@ -231,19 +231,19 @@ div.WaterCycleOnBox {
height: 20px;
background-color: #BDD7EE;
z-index: -35;
//border-color: red;
border-color: red;
border-style: solid;
border-width: 1px;
}
div.WaterCycleStatusIcon {
div.WaterCyclePointer_sec {
position: absolute;
left: 80px;
top: 469px;
width: 25px;
width: 24px;
text-align: center;
z-index: -25;
border-color: green;
//border-style: solid;
border-style: solid;
border-width: 1px;
}
</style>

View File

@@ -1,8 +1,8 @@
//
// Command: MakeByteArray -ESP -DIR -ROOT *.* -o=..\Web_Resources.h
// version: 1.0
// From cwd: D:/Projects/GrowController/gcfw/Resources
// Generated: Mon Oct 25 17:32:22 2021
// From cwd: C:/Projects/GrowController/Firmware/Resources
// Generated: Tue Oct 26 13:26:40 2021
// NOTE: Run script in command shell, not PowerShell
//
// PROGMEM is not recognized by Win32 tools...
@@ -1208,7 +1208,7 @@ const char index_htm[] PROGMEM = {
" <div class='SoilTemp_C' id='SoilTemp_C' >--.- &deg;F</div>\n"
" <div class='SoilMoisture_X' id='SoilMoisture_X' >-- %</div>\n"
" \n"
" <div class='DrumDoorIcon' id='DrumDoorIcon' ><img src='open.png' title='Open' /></div>\n"
" <div class='DrumState' id='DrumState' ><img src='open.png' title='Open' /></div>\n"
" <div class='DrumOpenSensor' id='DrumOpenSensor' >O</div>\n"
" <div class='DrumClosedSensor' id='DrumClosedSensor' >C</div>\n"
" <div class='DrumMotorLabel' id='DrumMotorLabel' >Motor</div>\n"
@@ -1226,7 +1226,7 @@ const char index_htm[] PROGMEM = {
" <div class='WaterCycleOn_sec' id='WaterCycleOn_sec' >8 s</div>\n"
" <div class='WaterCycle_sec' id='WaterCycle_sec' >10 s</div>\n"
" <div class='WaterCycleOnBox' id='WaterCycleOnBox' ></div>\n"
" <div class='WaterCycleStatusIcon' id='WaterCycleStatusIcon' ><img src='pointer.png' title='Pump On Time' /></div>\n"
" <div class='WaterCyclePointer_sec' id='WaterCyclePointer_sec' ><img src='pointer.png' title='Pump On Time' /></div>\n"
" </div>\n"
" </td>\n"
" <td width='10%' align='center'>\n"
@@ -1343,7 +1343,7 @@ const char index_js[] PROGMEM = {
" } \n"
"\n"
" if (typeof obj.SoilHeater != \"undefined\") {\n"
" document.getElementById('SoilHeater').innerHTML = obj.SoilHeater;\n"
" document.getElementById('SoilHeater').innerHTML = (obj.SoilHeater) ? \"Heat On\" : \"Heat Off\";\n"
" } else {\n"
" document.getElementById('SoilHeater').innerHTML = \"--\";\n"
" }\n"
@@ -1359,14 +1359,14 @@ const char index_js[] PROGMEM = {
" document.getElementById('SoilMoisture_X').innerHTML = \"--\";\n"
" }\n"
" \n"
" if (obj.DrumDoorIcon == 1) {\n"
" document.getElementById('DrumDoorIcon').style.display === \"none\";\n"
" if (obj.DrumState == 1) { // closed, hide the \"open\" image\n"
" document.getElementById('DrumState').style.display === \"none\";\n"
" } else {\n"
" document.getElementById('DrumDoorIcon').style.display === \"block\";\n"
" document.getElementById('DrumState').style.display === \"block\";\n"
" }\n"
" document.getElementById('DrumOpenSensor').innerHTML = obj.DrumOpenSensor;\n"
" document.getElementById('DrumClosedSensor').innerHTML = obj.DrumClosedSensor;\n"
" document.getElementById('DrumMotorStatus').innerHTML = obj.DrumMotorStatus;\n"
" document.getElementById('DrumOpenSensor').innerHTML = (obj.DrumOpenSensor) ? \"O\" : \"!O\";\n"
" document.getElementById('DrumClosedSensor').innerHTML = (obj.DrumClosedSensor) ? \"C\" : \"!C\";\n"
" document.getElementById('DrumMotorStatus').innerHTML = (obj.DrumMotorStatus == 0) ? \"stopped\" : (obj.DrumMotorStatus == 1) ? \"CW\" : \"CCW\";\n"
" document.getElementById('DrumMotorOn_sec').innerHTML = obj.DrumMotorOn_sec + \"s\";\n"
" document.getElementById('DrumMotor_V').innerHTML = parseFloat(obj.DrumMotor_V).toFixed(1) + \"V\";\n"
" document.getElementById('DrumMotor_I').innerHTML = parseFloat(obj.DrumMotor_I).toFixed(1) + \"A\";\n"
@@ -1380,7 +1380,7 @@ const char index_js[] PROGMEM = {
" }\n"
" );\n"
"}\n"
}; // index_js, 4528 bytes
}; // index_js, 4702 bytes
// File: myip.js
//
@@ -2475,7 +2475,7 @@ const char plantmodel_css[] PROGMEM = {
" top: 181px;\n"
"}\n"
"\n"
"div.DrumDoorIcon {\n"
"div.DrumState {\n"
" position: absolute;\n"
" transform: rotate(180deg);\n"
" left: 14px;\n"
@@ -2494,7 +2494,7 @@ const char plantmodel_css[] PROGMEM = {
"div.DrumMotorLabel {\n"
" position: absolute;\n"
" left: 95px;\n"
" top: 270px;\n"
" top: 260px;\n"
" width: 50px;\n"
" text-align: center;\n"
" color: white;\n"
@@ -2502,7 +2502,7 @@ const char plantmodel_css[] PROGMEM = {
"div.DrumMotorStatus {\n"
" position: absolute;\n"
" left: 95px;\n"
" top: 290px;\n"
" top: 280px;\n"
" width: 50px;\n"
" text-align: center;\n"
" color: white;\n"
@@ -2620,7 +2620,7 @@ const char plantmodel_css[] PROGMEM = {
" border-style: solid;\n"
" border-width: 1px;\n"
"}\n"
"div.WaterCycleStatusIcon {\n"
"div.WaterCyclePointer_sec {\n"
" position: absolute;\n"
" left: 80px;\n"
" top: 469px;\n"
@@ -4634,7 +4634,7 @@ const DirEntry Directory[] PROGMEM = {
{ "/green1x1.png" , green1x1_png , "image/png", 119 },
{ "/icon.png" , icon_png , "image/png", 8721 },
{ "/index.htm" , index_htm , "text/html", 5346 },
{ "/index.js" , index_js , "text/javascript", 4528 },
{ "/index.js" , index_js , "text/javascript", 4702 },
{ "/myip.js" , myip_js , "text/javascript", 167 },
{ "/nav.js" , nav_js , "text/javascript", 684 },
{ "/navigation.htm" , navigation_htm , "text/html", 557 },

View File

@@ -5,6 +5,10 @@
#include "ProjGlobals.h"
#include "WiFiStateHandler.h"
#include <DNSServer.h> ///< Required for Captive Portal behavior.
const byte DNS_PORT = 53; ///< Capture DNS requests on port 53
//DNSServer dnsServer; ///< Used for the captive portal AP mode
WiFiConnectState wifiConState; ///< Track the current WiFi state
@@ -73,7 +77,7 @@ WiFiConnectState WiFiStateHandler() {
WiFi.softAP(AP_NAME.c_str());
myIP = WiFi.softAPIP();
Serial.printf("IP Address: %s\n", myIP.toString().c_str());
// @todo dnsServer.start(DNS_PORT, "*", apIP);
//dnsServer.start(DNS_PORT, "growcontroller.info", myIP);
timeStateChange = millis();
//StartWebServer();
wifiConState = WFC_HostingAP;
@@ -93,7 +97,7 @@ WiFiConnectState WiFiStateHandler() {
// @todo SetLED(LED_WIFI, 0);
// @todo }
// @todo server.handleClient();
// @todo dnsServer.processNextRequest();
// dnsServer.processNextRequest();
break;
default:
case WFC_Idle: