Compare commits

...

6 commits

9 changed files with 100 additions and 21 deletions

View file

@ -10,7 +10,7 @@
* DEBUG is less noisy messages
* DEBUG2 are noisy messages
* DEBUG3 are super noisy messages */
//#define DEBUG
#define DEBUG
//#define DEBUG2
//#define DEBUG3
@ -55,6 +55,7 @@ const byte Max_Sensors_GPIO = 2;
/* Max Limits for Dashboard elements*/
const byte Max_Dashboard_Gauge = 6;
const byte Max_Dashboard_Chart = 6;
const byte Max_Dashboard_Data = 6;
/* actual structure initialization for GPIO_Index is done within the header files
* for ESP32 and ESP8266
@ -340,9 +341,9 @@ struct Config_Grow_Dashboard {
byte chartSensor[Max_Dashboard_Chart];
byte chartRead[Max_Dashboard_Chart];
char chartColor[Max_Dashboard_Chart][8];
bool dataConfigured[Max_Sensors];
byte dataSensor[Max_Sensors];
byte dataRead[Max_Sensors];
bool dataConfigured[Max_Dashboard_Data];
byte dataSensor[Max_Dashboard_Data];
byte dataRead[Max_Dashboard_Data];
};

View file

@ -42,7 +42,7 @@ byte Light_Power(byte id, unsigned int sunriseSec, unsigned int sunsetSec, unsig
//}
#ifdef DEBUG
#ifdef DEBUG2
Log.verbose(F("%s Light %d - power_tmp %d" CR), LogLoc, id, power_tmp);
#endif
return power_tmp;
@ -68,14 +68,14 @@ void Control_Light() {
if((config.grow.start < 1) || (now() - config.grow.start <= config.grow.daysVeg * 24 * 60 * 60)) {
sunriseSec = (config.grow.light.sunriseHourVeg[i] * 60 * 60) + (config.grow.light.sunriseMinuteVeg[i] * 60);
sunsetSec = (config.grow.light.sunsetHourVeg[i] * 60 * 60) + (config.grow.light.sunsetMinuteVeg[i] * 60);
#ifdef DEBUG
#ifdef DEBUG2
Log.verbose(F("%s Veg" CR), LogLoc);
#endif
/* now > than veg = bloom */
} else if(now() - config.grow.start > config.grow.daysVeg * 24 * 60 * 60) {
sunriseSec = (config.grow.light.sunriseHourBloom[i] * 60 * 60) + (config.grow.light.sunriseMinuteBloom[i] * 60);
sunsetSec = (config.grow.light.sunsetHourBloom[i] * 60 * 60) + (config.grow.light.sunsetMinuteBloom[i] * 60);
#ifdef DEBUG
#ifdef DEBUG2
Log.verbose(F("%s Bloom" CR), LogLoc);
#endif
/* now > than veg+bloom = harvest*/

View file

@ -175,7 +175,7 @@ byte Give_Free_Dashboard_DataId() {
const static char LogLoc[] PROGMEM = "[Core:Give_Free_Dashboard_DataId]";
byte dataId_free;
for(byte i=0; i < Max_Sensors; i++) {
for(byte i=0; i < Max_Dashboard_Data; i++) {
if(config.grow.dashboard.dataConfigured[i] > 0) {
// here i define that 255 stands for "no more free outputs"
dataId_free = 255;
@ -185,7 +185,7 @@ byte Give_Free_Dashboard_DataId() {
}
}
#ifdef DEBUG
Log.verbose(F("%s next free chart id: %d" CR), LogLoc, dataId_free);
Log.verbose(F("%s next free data id: %d" CR), LogLoc, dataId_free);
#endif
return dataId_free;
}

View file

@ -456,7 +456,7 @@ bool LoadConfig() {
}
/* iterate through data */
for(byte i = 0; i < Max_Sensors; i++) {
for(byte i = 0; i < Max_Dashboard_Data; i++) {
if(objDashboard.containsKey("dataConfigured"))
config.grow.dashboard.dataConfigured[i] = objDashboard["dataConfigured"][i];
if(config.grow.dashboard.dataConfigured[i] == true) {
@ -671,7 +671,7 @@ bool SaveConfig(bool writeToSerial = false) {
}
/* iterate through data */
for(byte i = 0; i < Max_Sensors; i++) {
for(byte i = 0; i < Max_Dashboard_Data; i++) {
if(config.grow.dashboard.dataConfigured[i] == true) {
objDashboard["dataConfigured"][i] = config.grow.dashboard.dataConfigured[i];
objDashboard["dataSensor"][i] = config.grow.dashboard.dataSensor[i];

View file

@ -55,6 +55,7 @@ void Webserver_Init() {
webserver.on("/system/update", HTTP_GET, WebPage_system_update);
webserver.on("/system/update", HTTP_POST, WebPage_system_update, WebPage_system_update_ApplyUpdate);
webserver.on("/system/updateConfig", HTTP_POST, WebPage_system_updateConfig, WebPage_system_update_ApplyUpdateConfig);
webserver.on("/system/restart", HTTP_GET, WebPage_system_restart);
webserver.on("/system/restart", HTTP_POST, WebPage_system_restart);
@ -104,7 +105,7 @@ void Webserver_Init() {
/* DEBUG only - offer config for direct download */
#ifndef DEBUG
#ifdef DEBUG
webserver.serveStatic(CANGROW_CFG, LittleFS, CANGROW_CFG);
#endif

View file

@ -963,6 +963,25 @@ String Proc_WebPage_grow_dashboard(const String& var) {
return AddHeaderFooter(var, 1);
} else if(Test_WebPage_grow_SUBNAV(var)) {
return Proc_WebPage_grow_SUBNAV(var, WEB_GROW_SUBNAV_DASHBOARD);
}
else if(var == "ADD_DISABLED_GAUGE") {
if(Give_Free_Dashboard_GaugeId() > Max_Dashboard_Gauge ) {
return F("disabled force_hide");
} else {
return String();
}
} else if(var == "ADD_DISABLED_CHART") {
if(Give_Free_Dashboard_ChartId() > Max_Dashboard_Chart ) {
return F("disabled force_hide");
} else {
return String();
}
} else if(var == "ADD_DISABLED_DATA") {
if(Give_Free_Dashboard_DataId() > Max_Dashboard_Data ) {
return F("disabled force_hide");
} else {
return String();
}
} else if(var == "TR_TD_GAUGE") {
String html;
for(byte i = 0; i < Max_Dashboard_Gauge; i++) {
@ -1084,7 +1103,7 @@ String Proc_WebPage_grow_dashboard(const String& var) {
return html;
} else if(var == "TR_TD_DATA") {
String html;
for(byte i = 0; i < Max_Sensors; i++) {
for(byte i = 0; i < Max_Dashboard_Data; i++) {
if(config.grow.dashboard.dataConfigured[i] == true) {
html += F("<tr><td>");
html += i;
@ -1355,7 +1374,7 @@ void WebPage_grow_dashboard_gaugeAdd(AsyncWebServerRequest *request) {
tmpParam_editGaugeId = param->value().toInt();
request->send_P(200, TEXT_HTML, Page_grow_dashboard_gaugeAdd_HTML, Proc_WebPage_grow_dashboard_gaugeAddEdit);
/* if we want to add new sensor, check if a sensor id is available. if not send error */
} else if(Give_Free_SensorId() > Max_Sensors) {
} else if(Give_Free_Dashboard_GaugeId() > Max_Dashboard_Gauge) {
request->send_P(200, TEXT_HTML, Page_grow_dashboard_gaugeAdd_HTML_NO_ID_AVAILABLE, Proc_WebPage_grow_dashboard_gaugeAdd);
/* Otherwise let the user create new sensor */
} else {
@ -1481,7 +1500,7 @@ void WebPage_grow_dashboard_chartAdd(AsyncWebServerRequest *request) {
tmpParam_editChartId = param->value().toInt();
request->send_P(200, TEXT_HTML, Page_grow_dashboard_chartAdd_HTML, Proc_WebPage_grow_dashboard_chartAddEdit);
/* if we want to add new sensor, check if a sensor id is available. if not send error */
} else if(Give_Free_SensorId() > Max_Sensors) {
} else if(Give_Free_Dashboard_ChartId() > Max_Dashboard_Chart) {
request->send_P(200, TEXT_HTML, Page_grow_dashboard_chartAdd_HTML_NO_ID_AVAILABLE, Proc_WebPage_grow_dashboard_chartAdd);
/* Otherwise let the user create new sensor */
} else {
@ -1604,7 +1623,7 @@ void WebPage_grow_dashboard_dataAdd(AsyncWebServerRequest *request) {
tmpParam_editDataId = param->value().toInt();
request->send_P(200, TEXT_HTML, Page_grow_dashboard_dataAdd_HTML, Proc_WebPage_grow_dashboard_dataAddEdit);
/* if we want to add new sensor, check if a sensor id is available. if not send error */
} else if(Give_Free_SensorId() > Max_Sensors) {
} else if(Give_Free_Dashboard_DataId() > Max_Dashboard_Data) {
request->send_P(200, TEXT_HTML, Page_grow_dashboard_dataAdd_HTML_NO_ID_AVAILABLE, Proc_WebPage_grow_dashboard_dataAdd);
/* Otherwise let the user create new sensor */
} else {

View file

@ -92,7 +92,7 @@ const char Page_grow_dashboard_HTML[] PROGMEM = R"(%HEADER%
<p>here you can set dashboard stuff<br></p>
<h3>Gauge</h3>
<a class='button %ADD_DISABLED%' href='/grow/dashboard/gaugeAdd'>&#10133; Add gauge</a>
<a class='button %ADD_DISABLED_GAUGE%' href='/grow/dashboard/gaugeAdd'>&#10133; Add gauge</a>
<table class='centered'>
<tr>
<th>ID</th>
@ -106,7 +106,7 @@ const char Page_grow_dashboard_HTML[] PROGMEM = R"(%HEADER%
<hr>
<h3>Chart</h3>
<a class='button %ADD_DISABLED%' href='/grow/dashboard/chartAdd''>&#10133; Add chart</a>
<a class='button %ADD_DISABLED_CHART%' href='/grow/dashboard/chartAdd'>&#10133; Add chart</a>
<table class='centered'>
<tr>
<th>ID</th>
@ -120,7 +120,7 @@ const char Page_grow_dashboard_HTML[] PROGMEM = R"(%HEADER%
<hr>
<h3>Data</h3>
<a class='button %ADD_DISABLED%' href='/grow/dashboard/dataAdd'>&#10133; Add data</a>
<a class='button %ADD_DISABLED_DATA%' href='/grow/dashboard/dataAdd'>&#10133; Add data</a>
<table class='centered'>
<tr>
<th>ID</th>

View file

@ -334,13 +334,15 @@ void WebPage_system_update_ApplyUpdate(AsyncWebServerRequest *request, String fi
Update.printError(Serial);
}
}
}
}
String Proc_WebPage_system_update(const String& var) {
if(TestHeaderFooter(var)) {
return AddHeaderFooter(var, 2);
} else if(Test_WebPage_system_SUBNAV(var)) {
return Proc_WebPage_system_SUBNAV(var, WEB_SYSTEM_SUBNAV_UPDATE);
} else if(var == "SAVE_MSG") {
return String(Common_HTML_SAVE_MSG);
} else {
return String();
}
@ -373,6 +375,52 @@ void WebPage_system_update(AsyncWebServerRequest *request) {
}
/* Config Update handling
* https://github.com/ESP32Async/ESPAsyncWebServer/blob/main/examples/Upload/Upload.ino */
void WebPage_system_update_ApplyUpdateConfig(AsyncWebServerRequest *request, String filename, size_t index, uint8_t *data, size_t len, bool final){
const static char LogLoc[] PROGMEM = "[Webserver:system:update:ApplyUpdateConfig]";
Log.notice(F("%s Upload[%s]: start=%u, len=%u, final=%d" CR), LogLoc, filename.c_str(), index, len, final); //Serial.printf("Upload[%s]: start=%u, len=%u, final=%d\n", filename.c_str(), index, len, final);
if (!index) {
request->_tempFile = LittleFS.open(CANGROW_CFG, "w");
if (!request->_tempFile) {
Log.notice(F("%s Upload[%s]: File not available for writing" CR), LogLoc, filename.c_str());
request->send(400, "text/plain", "File not available for writing");
}
}
if (len) {
request->_tempFile.write(data, len);
}
if (final) {
request->_tempFile.close();
}
}
void WebPage_system_updateConfig(AsyncWebServerRequest *request) {
if(request->method() == HTTP_POST) {
if (request->getResponse()) {
// 400 File not available for writing
return;
}
if (!LittleFS.exists(CANGROW_CFG)) {
return request->send(400, "text/plain", "Nothing uploaded");
}
// sends back the uploaded file
// request->send(LittleFS, CANGROW_CFG, "text/plain");
/* set needRestart to true and redirect to update page */
needRestart = true;
request->redirect(F("/system/update?success"));
} else {
request->send_P(200, TEXT_HTML, Page_system_update_HTML, Proc_WebPage_system_update);
}
}
/*******************************************************************************
* Subpage wipe
*/

View file

@ -67,16 +67,26 @@ const char Page_system_HTML[] PROGMEM = R"(%HEADER%
const char Page_system_update_HTML[] PROGMEM = R"(%HEADER%
%SUBNAV%
%SAVE_MSG%
Version: %CGVER% <br>
Build : %CGBUILD% <br>
<p>You find the latest CanGrow firmware version on the <a href='https://git.la10cy.net/DeltaLima/CanGrow/releases' target='_blank'>release page</a> of the git repository.</p>
<div id='divUploading' style='display: none;' class='warnmsg'>&#x1F6DC; Uploading, please wait...</div>
<h3>Firmware</h3>
<form method='POST' action='/system/update' enctype='multipart/form-data' onsubmit="document.getElementById('divUploading').style.display = '';">
<b>Select .bin file:</b><br>
<input type='file' accept='.bin,.bin.gz' name='firmware' required>
<input type='submit' value='Update Firmware'>
</form>
<div id='divUploading' style='display: none;' class='warnmsg'>&#x1F6DC; Uploading, please wait...</div>
<h3>Config</h3>
<form method='POST' action='/system/updateConfig' enctype='multipart/form-data' onsubmit="document.getElementById('divUploading').style.display = '';">
<b>Select config.json file:</b><br>
<input type='file' accept='.json' name='config' required>
<input type='submit' value='Update Config'>
</form>
%FOOTER% )";