Optiomize flash usage, continue work on printer config

pull/125/head
Robert Stein 2020-12-21 19:35:40 +01:00
parent 061c92a260
commit 75e37d1053
77 changed files with 672 additions and 260 deletions

View File

@ -17,6 +17,7 @@ public:
virtual void updatePrintClient(PrinterDataStruct *printerData) = 0; virtual void updatePrintClient(PrinterDataStruct *printerData) = 0;
virtual String getClientType() = 0; virtual String getClientType() = 0;
virtual boolean isValidConfig(PrinterDataStruct *printerData) = 0; virtual boolean isValidConfig(PrinterDataStruct *printerData) = 0;
virtual boolean clientNeedApiKey() = 0;
/** /**
* @brief Reset all dynamic variables for printer * @brief Reset all dynamic variables for printer
@ -36,7 +37,7 @@ public:
MemoryHelper::stringToChar("", printerData->fileName, 60); MemoryHelper::stringToChar("", printerData->fileName, 60);
printerData->fileSize = 0; printerData->fileSize = 0;
printerData->lastPrintTime = 0; printerData->lastPrintTime = 0;
MemoryHelper::stringToChar("", printerData->progressCompletion, 60); printerData->progressCompletion = 0;
printerData->progressFilepos = 0; printerData->progressFilepos = 0;
printerData->progressPrintTime = 0; printerData->progressPrintTime = 0;
printerData->progressPrintTimeLeft = 0; printerData->progressPrintTimeLeft = 0;

View File

@ -16,6 +16,7 @@ public:
BasePrinterClientImpl(String clientType, GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient); BasePrinterClientImpl(String clientType, GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
void getPrinterJobResults(PrinterDataStruct *printerData) {}; void getPrinterJobResults(PrinterDataStruct *printerData) {};
void getPrinterPsuState(PrinterDataStruct *printerData) {}; void getPrinterPsuState(PrinterDataStruct *printerData) {};
boolean clientNeedApiKey() { return false; };
void updatePrintClient(PrinterDataStruct *printerData); void updatePrintClient(PrinterDataStruct *printerData);
String getClientType(); String getClientType();
boolean isOperational(PrinterDataStruct *printerData); boolean isOperational(PrinterDataStruct *printerData);

View File

@ -85,23 +85,21 @@ void DuetClient::getPrinterJobResults(PrinterDataStruct *printerData) {
return; return;
} }
//printerData.filamentLength = (const char*)(*jsonDoc)["result"]["status"]["job"]["print_stats"]["filament_used"]; printerData->filamentLength = (float)(*jsonDoc)["result"]["status"]["job"]["print_stats"]["filament_used"];
//printerData.progressPrintTime = (const char*)(*jsonDoc)["printDuration"]; printerData->progressPrintTime = (float)(*jsonDoc)["printDuration"];
//printerData.fileName = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["filename"]; MemoryHelper::stringToChar(
//printerData.progressCompletion = (int)(*jsonDoc)["fractionPrinted"]; (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["filename"],
printerData->fileName,
60
);
printerData->progressCompletion = (int)(*jsonDoc)["fractionPrinted"];
printerData->toolTemp = (int)(*jsonDoc)["temps"]["current"][1]; printerData->toolTemp = (int)(*jsonDoc)["temps"]["current"][1];
printerData->toolTargetTemp = (int)(*jsonDoc)["temps"]["tools"]["active"][0][0]; printerData->toolTargetTemp = (int)(*jsonDoc)["temps"]["tools"]["active"][0][0];
printerData->bedTemp = (int)(*jsonDoc)["temps"]["bed"]["current"]; printerData->bedTemp = (int)(*jsonDoc)["temps"]["bed"]["current"];
printerData->bedTargetTemp = (int)(*jsonDoc)["temps"]["bed"]["active"]; printerData->bedTargetTemp = (int)(*jsonDoc)["temps"]["bed"]["active"];
float fileProgress = (float)(*jsonDoc)["fractionPrinted"]; printerData->progressFilepos = (int)(*jsonDoc)["filePosition"];
//printerData.progressFilepos = (const char*)(*jsonDoc)["filePosition"];
printerData->estimatedPrintTime = (float)(*jsonDoc)["file"]; printerData->estimatedPrintTime = (float)(*jsonDoc)["file"];
printerData->progressPrintTimeLeft = (float)(*jsonDoc)["timesLeft"]["file"];
/*
printerData.progressPrintTimeLeft : No metadata is available, print duration and progress can be used to calculate the ETA:
*/
//float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress;
//printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat());
if (this->isOperational(printerData)) { if (this->isOperational(printerData)) {
this->debugController->printLn("Status: " this->debugController->printLn("Status: "

View File

@ -14,6 +14,7 @@ public:
DuetClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient); DuetClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
void getPrinterJobResults(PrinterDataStruct *printerData) override; void getPrinterJobResults(PrinterDataStruct *printerData) override;
void getPrinterPsuState(PrinterDataStruct *printerData) override; void getPrinterPsuState(PrinterDataStruct *printerData) override;
boolean clientNeedApiKey() override { return false; };
private: private:
static int translateState(String stateText); static int translateState(String stateText);

View File

@ -48,9 +48,13 @@ void KlipperClient::getPrinterJobResults(PrinterDataStruct *printerData) {
} }
printerData->state = KlipperClient::translateState((const char*)(*jsonDoc)["result"]["status"]["print_stats"]["state"]); printerData->state = KlipperClient::translateState((const char*)(*jsonDoc)["result"]["status"]["print_stats"]["state"]);
//printerData.filamentLength = (const char*)(*jsonDoc)["result"]["status"]["job"]["print_stats"]["filament_used"]; printerData->filamentLength = (float)(*jsonDoc)["result"]["status"]["job"]["print_stats"]["filament_used"];
//printerData.progressPrintTime = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["print_duration"]; printerData->progressPrintTime = (float)(*jsonDoc)["result"]["status"]["print_stats"]["print_duration"];
//printerData.fileName = (const char*)(*jsonDoc)["result"]["status"]["print_stats"]["filename"]; MemoryHelper::stringToChar(
(const char*)(*jsonDoc)["result"]["status"]["print_stats"]["filename"],
printerData->fileName,
60
);
if (this->isOperational(printerData)) { if (this->isOperational(printerData)) {
this->debugController->printLn("Status: " + this->globalDataController->getPrinterStateAsText(printerData)); this->debugController->printLn("Status: " + this->globalDataController->getPrinterStateAsText(printerData));
@ -87,20 +91,19 @@ void KlipperClient::getPrinterJobResults(PrinterDataStruct *printerData) {
return; return;
} }
//printerData.progressCompletion = (int)(*jsonDoc)["result"]["status"]["display_status"]["progress"]; float progressCompletion = (float)(*jsonDoc)["result"]["status"]["display_status"]["progress"];
printerData->toolTemp = (int)(*jsonDoc)["result"]["status"]["extruder"]["temperature"]; printerData->toolTemp = (int)(*jsonDoc)["result"]["status"]["extruder"]["temperature"];
printerData->toolTargetTemp = (int)(*jsonDoc)["result"]["status"]["extruder"]["target"]; printerData->toolTargetTemp = (int)(*jsonDoc)["result"]["status"]["extruder"]["target"];
printerData->bedTemp = (int)(*jsonDoc)["result"]["status"]["heater_bed"]["temperature"]; printerData->bedTemp = (int)(*jsonDoc)["result"]["status"]["heater_bed"]["temperature"];
printerData->bedTargetTemp = (int)(*jsonDoc)["result"]["status"]["heater_bed"]["target"]; printerData->bedTargetTemp = (int)(*jsonDoc)["result"]["status"]["heater_bed"]["target"];
float fileProgress = (float)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["progress"]; float fileProgress = (float)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["progress"];
//printerData.progressFilepos = (const char*)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["file_position"]; printerData->progressFilepos = (int)(*jsonDoc)["result"]["status"]["virtual_sdcard"]["file_position"];
printerData->estimatedPrintTime = (float)(*jsonDoc)["result"]["status"]["toolhead"]["estimated_print_time"]; printerData->estimatedPrintTime = (float)(*jsonDoc)["result"]["status"]["toolhead"]["estimated_print_time"];
printerData->progressPrintTime = (float)(*jsonDoc)["result"]["status"]["print_stats"]["print_duration"];
/* float totalPrintTime = printerData->progressPrintTime / fileProgress;
printerData.progressPrintTimeLeft : No metadata is available, print duration and progress can be used to calculate the ETA: printerData->progressPrintTimeLeft = totalPrintTime - printerData->progressPrintTime;
*/ printerData->progressCompletion = progressCompletion * 100;
//float totalPrintTime = printerData.progressPrintTime.toFloat() / fileProgress;
//printerData.progressPrintTimeLeft = String(totalPrintTime - printerData.progressPrintTime.toFloat());
if (this->isOperational(printerData)) { if (this->isOperational(printerData)) {
this->debugController->printLn("Status: " this->debugController->printLn("Status: "

View File

@ -14,6 +14,7 @@ public:
KlipperClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient); KlipperClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
void getPrinterJobResults(PrinterDataStruct *printerData) override; void getPrinterJobResults(PrinterDataStruct *printerData) override;
void getPrinterPsuState(PrinterDataStruct *printerData) override; void getPrinterPsuState(PrinterDataStruct *printerData) override;
boolean clientNeedApiKey() override { return false; };
private: private:
static int translateState(String stateText); static int translateState(String stateText);

View File

@ -14,6 +14,7 @@ public:
OctoPrintClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient); OctoPrintClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
void getPrinterJobResults(PrinterDataStruct *printerData) override; void getPrinterJobResults(PrinterDataStruct *printerData) override;
void getPrinterPsuState(PrinterDataStruct *printerData) override; void getPrinterPsuState(PrinterDataStruct *printerData) override;
boolean clientNeedApiKey() override { return true; };
private: private:
static int translateState(String stateText); static int translateState(String stateText);

View File

@ -32,10 +32,10 @@ typedef struct {
char fileName[60]; char fileName[60];
int fileSize; int fileSize;
int lastPrintTime; int lastPrintTime;
char progressCompletion[60]; int progressCompletion;
int progressFilepos; int progressFilepos;
int progressPrintTime; float progressPrintTime;
int progressPrintTimeLeft; float progressPrintTimeLeft;
int state; int state;
float toolTemp; float toolTemp;
float toolTargetTemp; float toolTargetTemp;

View File

@ -14,6 +14,7 @@ public:
RepetierClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient); RepetierClient(GlobalDataController *globalDataController, DebugController *debugController, JsonRequestClient *jsonRequestClient);
void getPrinterJobResults(PrinterDataStruct *printerData) override; void getPrinterJobResults(PrinterDataStruct *printerData) override;
void getPrinterPsuState(PrinterDataStruct *printerData) override; void getPrinterPsuState(PrinterDataStruct *printerData) override;
boolean clientNeedApiKey() override { return true; };
private: private:
static int translateState(String stateText); static int translateState(String stateText);

View File

@ -438,6 +438,24 @@ void GlobalDataController::registerPrinterClient(int id, BasePrinterClient *base
this->basePrinterClients[id] = basePrinterClient; this->basePrinterClients[id] = basePrinterClient;
} }
/**
* @brief Get all registred printer clients
*
* @return BasePrinterClient**
*/
BasePrinterClient** GlobalDataController::getRegisteredPrinterClients() {
return this->basePrinterClients;
}
/**
* @brief Get number of registred printer clients
*
* @return int
*/
int GlobalDataController::getRegisteredPrinterClientsNum() {
return this->basePrinterCount;
}
/** /**
* @brief Get viewable type of client for printer * @brief Get viewable type of client for printer
* @param printerHandle Handle to printer data * @param printerHandle Handle to printer data

View File

@ -14,7 +14,11 @@
#include "../../include/MemoryHelper.h" #include "../../include/MemoryHelper.h"
#include "EspController.h" #include "EspController.h"
static const char ERROR_MESSAGES_ERR1[] PROGMEM = "[ERR1] Printer fo update not found!"; static const char ERROR_MESSAGES_ERR1[] PROGMEM = "[ERR1] Printer for update not found!";
static const char OK_MESSAGES_SAVE1[] PROGMEM = "[OK] Printer successfully saved";
static const char OK_MESSAGES_SAVE2[] PROGMEM = "[OK] Weather api data successfully saved";
static const char OK_MESSAGES_SAVE3[] PROGMEM = "[OK] Station data successfully saved";
/** /**
* @brief Handles all needed data for all instances * @brief Handles all needed data for all instances
@ -59,6 +63,8 @@ public:
bool resetConfig(); bool resetConfig();
void registerPrinterClient(int id, BasePrinterClient *basePrinterClient); void registerPrinterClient(int id, BasePrinterClient *basePrinterClient);
BasePrinterClient** getRegisteredPrinterClients();
int getRegisteredPrinterClientsNum();
PrinterDataStruct *getPrinterSettings(); PrinterDataStruct *getPrinterSettings();
PrinterDataStruct *addPrinterSetting(); PrinterDataStruct *addPrinterSetting();
int getNumPrinters(); int getNumPrinters();

View File

@ -13,4 +13,5 @@ typedef struct {
int clockWeatherResyncMinutes; int clockWeatherResyncMinutes;
String version; String version;
String lastError; String lastError;
String lastOk;
} SystemDataStruct; } SystemDataStruct;

View File

@ -463,19 +463,15 @@ void WebServer::handleUpdatePrinter() {
targetPrinter->basicAuthNeeded = this->server->hasArg("e-tapipw"); targetPrinter->basicAuthNeeded = this->server->hasArg("e-tapipw");
MemoryHelper::stringToChar(this->server->arg("e-tapiuser"), targetPrinter->basicAuthUsername, 30); MemoryHelper::stringToChar(this->server->arg("e-tapiuser"), targetPrinter->basicAuthUsername, 30);
MemoryHelper::stringToChar(this->server->arg("e-tapipass"), targetPrinter->basicAuthPassword, 60); MemoryHelper::stringToChar(this->server->arg("e-tapipass"), targetPrinter->basicAuthPassword, 60);
this->globalDataController->getSystemSettings()->lastOk = FPSTR(OK_MESSAGES_SAVE1);
//http://192.168.0.239/configureprinter/show?id=0&e-tname=asdasd&e-tapi=Klipper&e-taddr=123.213.123.121&e-tport=80&e-tapipw=on&e-tapiuser=admin&e-tapipass=admin //http://192.168.0.239/configureprinter/show?id=0&e-tname=asdasd&e-tapi=Klipper&e-taddr=123.213.123.121&e-tport=80&e-tapipw=on&e-tapiuser=admin&e-tapipass=admin
this->globalDataController->getSystemSettings()->lastError = FPSTR(ERROR_MESSAGES_ERR1);
this->globalDataController->writeSettings(); this->globalDataController->writeSettings();
this->redirectTarget("/configureprinter/show"); this->redirectTarget("/configureprinter/show");
} }
/** /**
* @brief Send station configuration page to client * @brief Send station configuration page to client
*/ */
@ -518,6 +514,7 @@ void WebServer::handleUpdateStation() {
this->globalDataController->getDisplayClient()->handleUpdate(); this->globalDataController->getDisplayClient()->handleUpdate();
this->globalDataController->getTimeClient()->resetLastEpoch(); this->globalDataController->getTimeClient()->resetLastEpoch();
this->globalDataController->getSystemSettings()->lastOk = FPSTR(OK_MESSAGES_SAVE3);
this->redirectHome(); this->redirectHome();
} }
@ -551,6 +548,7 @@ void WebServer::handleUpdateWeather() {
this->globalDataController->getDisplayClient()->handleUpdate(); this->globalDataController->getDisplayClient()->handleUpdate();
this->globalDataController->getTimeClient()->resetLastEpoch(); this->globalDataController->getTimeClient()->resetLastEpoch();
this->globalDataController->getSystemSettings()->lastOk = FPSTR(OK_MESSAGES_SAVE2);
this->redirectHome(); this->redirectHome();
} }

View File

@ -1,5 +1,7 @@
#include "WebserverMemoryVariables.h" #include "WebserverMemoryVariables.h"
String WebserverMemoryVariables::rowExtraClass = "";
/** /**
* @brief Send out header for webpage * @brief Send out header for webpage
* @param server Send out instancce * @param server Send out instancce
@ -63,6 +65,12 @@ void WebserverMemoryVariables::sendHeader(
errorBlock.replace("%ERRORMSG%", globalDataController->getSystemSettings()->lastError); errorBlock.replace("%ERRORMSG%", globalDataController->getSystemSettings()->lastError);
server->sendContent(errorBlock); server->sendContent(errorBlock);
} }
if (globalDataController->getSystemSettings()->lastOk.length() > 0) {
String okBlock = FPSTR(HEADER_BLOCK_OK);
okBlock.replace("%OKMSG%", globalDataController->getSystemSettings()->lastOk);
server->sendContent(okBlock);
globalDataController->getSystemSettings()->lastOk = "";
}
} }
/** /**
@ -71,6 +79,28 @@ void WebserverMemoryVariables::sendHeader(
* @param globalDataController Access to global data * @param globalDataController Access to global data
*/ */
void WebserverMemoryVariables::sendFooter(ESP8266WebServer *server, GlobalDataController *globalDataController) { void WebserverMemoryVariables::sendFooter(ESP8266WebServer *server, GlobalDataController *globalDataController) {
WebserverMemoryVariables::sendModalDanger(
server,
"resetSettingsModal",
FPSTR(GLOBAL_TEXT_WARNING),
FPSTR(GLOBAL_TEXT_TRESET),
FPSTR(GLOBAL_TEXT_CRESET),
FPSTR(GLOBAL_TEXT_ABORT),
FPSTR(GLOBAL_TEXT_RESET),
"onclick='openUrl(\"/systemreset\")'"
);
WebserverMemoryVariables::sendModalDanger(
server,
"resetWifiModal",
FPSTR(GLOBAL_TEXT_WARNING),
FPSTR(GLOBAL_TEXT_TFWIFI),
FPSTR(GLOBAL_TEXT_CFWIFI),
FPSTR(GLOBAL_TEXT_ABORT),
FPSTR(GLOBAL_TEXT_RESET),
"onclick='openUrl(\"/forgetwifi\")'"
);
server->sendContent(String(FPSTR(FOOTER_BLOCK))); server->sendContent(String(FPSTR(FOOTER_BLOCK)));
server->sendContent(""); server->sendContent("");
server->client().stop(); server->client().stop();
@ -97,34 +127,53 @@ void WebserverMemoryVariables::sendWeatherConfigForm(ESP8266WebServer *server, G
server, server,
FPSTR(WEATHER_FORM1_ID), FPSTR(WEATHER_FORM1_ID),
globalDataController->getWeatherSettings()->show, globalDataController->getWeatherSettings()->show,
FPSTR(WEATHER_FORM1_LABEL) FPSTR(WEATHER_FORM1_LABEL),
true,
""
); );
WebserverMemoryVariables::sendFormCheckbox( WebserverMemoryVariables::sendFormCheckbox(
server, server,
FPSTR(WEATHER_FORM2_ID), FPSTR(WEATHER_FORM2_ID),
globalDataController->getWeatherSettings()->isMetric, globalDataController->getWeatherSettings()->isMetric,
FPSTR(WEATHER_FORM2_LABEL_ON), FPSTR(WEATHER_FORM2_LABEL_ON),
FPSTR(WEATHER_FORM2_LABEL_OFF) FPSTR(WEATHER_FORM2_LABEL_OFF),
true,
""
); );
WebserverMemoryVariables::sendFormInput(
String form = FPSTR(WEATHER_FORM3); server,
form.replace("%WEATHERKEY%", globalDataController->getWeatherSettings()->apiKey); FPSTR(WEATHER_FORM3_ID),
server->sendContent(form); FPSTR(WEATHER_FORM3_LABEL),
globalDataController->getWeatherSettings()->apiKey,
form = FPSTR(WEATHER_FORM4); 60,
form.replace("%CITY1%", String(globalDataController->getWeatherSettings()->cityId)); "",
form.replace("%CITYNAME1%", globalDataController->getWeatherClient()->getCity(0)); false,
server->sendContent(form); true,
""
form = FPSTR(WEATHER_FORM_OPTIONS);
form.replace(
">"+String(globalDataController->getWeatherSettings()->lang)+"<",
" selected>"+String(globalDataController->getWeatherSettings()->lang)+"<"
); );
server->sendContent(form); WebserverMemoryVariables::sendFormInput(
server,
form = FPSTR(WEATHER_FORM5); FPSTR(WEATHER_FORM4_ID),
server->sendContent(form); globalDataController->getWeatherClient()->getCity(0) + FPSTR(WEATHER_FORM4_LABEL),
String(globalDataController->getWeatherSettings()->cityId),
120,
"onkeypress='return isNumberKey(event)'",
false,
true,
""
);
WebserverMemoryVariables::sendFormSelect(
server,
FPSTR(WEATHER_FORM5_ID),
FPSTR(WEATHER_FORM5_LABEL),
String(globalDataController->getWeatherSettings()->lang),
"",
FPSTR(WEATHER_FORM5_OPTIONS),
true,
""
);
WebserverMemoryVariables::sendFormSubmitButton(server, true);
server->sendContent(FPSTR(WEATHER_FORM_END));
} }
/** /**
@ -138,52 +187,90 @@ void WebserverMemoryVariables::sendStationConfigForm(ESP8266WebServer *server, G
server, server,
FPSTR(STATION_CONFIG_FORM1_ID), FPSTR(STATION_CONFIG_FORM1_ID),
globalDataController->getClockSettings()->show, globalDataController->getClockSettings()->show,
FPSTR(STATION_CONFIG_FORM1_LABEL) FPSTR(STATION_CONFIG_FORM1_LABEL),
true,
""
); );
WebserverMemoryVariables::sendFormCheckbox( WebserverMemoryVariables::sendFormCheckbox(
server, server,
FPSTR(STATION_CONFIG_FORM2_ID), FPSTR(STATION_CONFIG_FORM2_ID),
globalDataController->getClockSettings()->is24h, globalDataController->getClockSettings()->is24h,
FPSTR(STATION_CONFIG_FORM2_LABEL) FPSTR(STATION_CONFIG_FORM2_LABEL),
true,
""
); );
WebserverMemoryVariables::sendFormCheckbox( WebserverMemoryVariables::sendFormCheckbox(
server, server,
FPSTR(STATION_CONFIG_FORM3_ID), FPSTR(STATION_CONFIG_FORM3_ID),
globalDataController->getSystemSettings()->invertDisplay, globalDataController->getSystemSettings()->invertDisplay,
FPSTR(STATION_CONFIG_FORM3_LABEL) FPSTR(STATION_CONFIG_FORM3_LABEL),
true,
""
); );
WebserverMemoryVariables::sendFormCheckbox( WebserverMemoryVariables::sendFormCheckbox(
server, server,
FPSTR(STATION_CONFIG_FORM4_ID), FPSTR(STATION_CONFIG_FORM4_ID),
globalDataController->getSystemSettings()->useLedFlash, globalDataController->getSystemSettings()->useLedFlash,
FPSTR(STATION_CONFIG_FORM4_LABEL) FPSTR(STATION_CONFIG_FORM4_LABEL),
true,
""
); );
WebserverMemoryVariables::sendFormSelect(
String form = FPSTR(STATION_CONFIG_FORM5); server,
String options = FPSTR(STATION_CONFIG_FORM5OPT); FPSTR(STATION_CONFIG_FORM5_ID),
options.replace( FPSTR(STATION_CONFIG_FORM5_LABEL),
">"+String(globalDataController->getSystemSettings()->clockWeatherResyncMinutes)+"<", String(globalDataController->getSystemSettings()->clockWeatherResyncMinutes),
" selected>"+String(globalDataController->getSystemSettings()->clockWeatherResyncMinutes)+"<" "",
FPSTR(STATION_CONFIG_FORM5_OPTIONS),
true,
""
);
WebserverMemoryVariables::sendFormInput(
server,
FPSTR(STATION_CONFIG_FORM6_ID),
FPSTR(STATION_CONFIG_FORM6_LABEL),
String(globalDataController->getClockSettings()->utcOffset),
120,
"onkeypress='return isNumberKey(event)'",
false,
true,
""
); );
form.replace("%OPTIONS%", options);
server->sendContent(form);
form = FPSTR(STATION_CONFIG_FORM6);
form.replace("%UTCOFFSET%", String(globalDataController->getClockSettings()->utcOffset));
server->sendContent(form);
WebserverMemoryVariables::sendFormCheckboxEvent( WebserverMemoryVariables::sendFormCheckboxEvent(
server, server,
FPSTR(STATION_CONFIG_FORM7_ID), FPSTR(STATION_CONFIG_FORM7_ID),
globalDataController->getSystemSettings()->hasBasicAuth, globalDataController->getSystemSettings()->hasBasicAuth,
FPSTR(STATION_CONFIG_FORM7_LABEL), FPSTR(STATION_CONFIG_FORM7_LABEL),
"showhide(this, 'uspw')" "showhide('isBasicAuth', 'uspw')",
true,
""
); );
WebserverMemoryVariables::rowExtraClass = "data-sh='uspw'";
form = FPSTR(STATION_CONFIG_FORM8); WebserverMemoryVariables::sendFormInput(
form.replace("%USERID%", globalDataController->getSystemSettings()->webserverUsername); server,
form.replace("%STATIONPASSWORD%", globalDataController->getSystemSettings()->webserverPassword); FPSTR(STATION_CONFIG_FORM8_ID),
server->sendContent(form); FPSTR(STATION_CONFIG_FORM8_LABEL),
globalDataController->getSystemSettings()->webserverUsername,
20,
"",
false,
true,
""
);
WebserverMemoryVariables::rowExtraClass = "data-sh='uspw'";
WebserverMemoryVariables::sendFormInput(
server,
FPSTR(STATION_CONFIG_FORM9_ID),
FPSTR(STATION_CONFIG_FORM9_LABEL),
globalDataController->getSystemSettings()->webserverPassword,
120,
"",
true,
true,
""
);
WebserverMemoryVariables::sendFormSubmitButton(server, true);
server->sendContent(FPSTR(STATION_CONFIG_FORM_END));
} }
/** /**
@ -213,46 +300,138 @@ void WebserverMemoryVariables::sendPrinterConfigForm(ESP8266WebServer *server, G
// Generate all modals // Generate all modals
for(int i=0; i<totalPrinters; i++) { for(int i=0; i<totalPrinters; i++) {
WebserverMemoryVariables::sendPrinterConfigFormAEModal(server, i + 1, &printerConfigs[i]); WebserverMemoryVariables::sendPrinterConfigFormAEModal(server, i + 1, &printerConfigs[i], globalDataController);
} }
WebserverMemoryVariables::sendPrinterConfigFormAEModal(server, 0, NULL); WebserverMemoryVariables::sendPrinterConfigFormAEModal(server, 0, NULL, globalDataController);
/*static const char CONFPRINTER_FORM_ROW_OFFLINE[] PROGMEM = "<div class='bx--tag bx--tag--magenta'>"
"Offline"
"</div>";
static const char CONFPRINTER_FORM_ROW_ONLINE[] PROGMEM = "<div class='bx--tag bx--tag--green'>"
"Online"
"</div>";
*/
server->sendContent(FPSTR(CONFPRINTER_FORM_END)); server->sendContent(FPSTR(CONFPRINTER_FORM_END));
} }
void WebserverMemoryVariables::sendPrinterConfigFormAEModal(ESP8266WebServer *server, int id, PrinterDataStruct *forPrinter) { /**
String printerEditModal = FPSTR(CONFPRINTER_FORM_ADDEDIT1); * @brief Modal for printer edit/add
printerEditModal.replace("%ID%", String(id)); *
* @param server
* @param id
* @param forPrinter
* @param globalDataController Access to global data
*/
void WebserverMemoryVariables::sendPrinterConfigFormAEModal(ESP8266WebServer *server, int id, PrinterDataStruct *forPrinter, GlobalDataController *globalDataController) {
String modalData = FPSTR(CONFPRINTER_FORM_ADDEDIT_START);
modalData.replace("%ID%", String(id));
if (id == 0) { if (id == 0) {
printerEditModal.replace("%TITLE%", FPSTR(CONFPRINTER_FORM_ADDEDIT_TA)); modalData.replace("%TITLE%", FPSTR(CONFPRINTER_FORM_ADDEDIT_TA));
} else { } else {
printerEditModal.replace("%TITLE%", FPSTR(CONFPRINTER_FORM_ADDEDIT_TE)); modalData.replace("%TITLE%", FPSTR(CONFPRINTER_FORM_ADDEDIT_TE));
}
server->sendContent(modalData);
String optionData = "";
BasePrinterClient** printerInstances = globalDataController->getRegisteredPrinterClients();
for (int i=0; i<globalDataController->getRegisteredPrinterClientsNum(); i++) {
if (printerInstances[i] == NULL) {
continue;
}
optionData += "<option class='bx--select-option' value='" + String(i) + "'";
if (printerInstances[i]->clientNeedApiKey()) {
optionData += " data-need-api='true'";
}
if ((forPrinter != NULL) && (forPrinter->apiType == i)) {
optionData += " selected='selected'";
}
optionData += ">" + printerInstances[i]->getClientType() + "</option>";
} }
if (forPrinter == NULL) { WebserverMemoryVariables::sendFormInput(
printerEditModal.replace("%NAME%", ""); server,
printerEditModal.replace("%TARGETADDR%", ""); FPSTR(CONFPRINTER_FORM_ADDEDIT1_ID),
printerEditModal.replace("%TARGETPORT%", "80"); FPSTR(CONFPRINTER_FORM_ADDEDIT1_LABEL),
} else { id > 0 ? String(forPrinter->customName) : "",
printerEditModal.replace("%NAME%", String(forPrinter->customName)); 20,
printerEditModal.replace("%TARGETADDR%", String(forPrinter->remoteAddress)); "",
printerEditModal.replace("%TARGETPORT%", String(forPrinter->remotePort)); false,
} false,
String(id)
);
server->sendContent(printerEditModal); WebserverMemoryVariables::sendFormSelect(
server,
FPSTR(CONFPRINTER_FORM_ADDEDIT2_ID),
FPSTR(CONFPRINTER_FORM_ADDEDIT2_LABEL),
"",
"",
optionData,
false,
String(id)
);
WebserverMemoryVariables::sendFormInput(
server,
FPSTR(CONFPRINTER_FORM_ADDEDIT3_ID),
FPSTR(CONFPRINTER_FORM_ADDEDIT3_LABEL),
id > 0 ? String(forPrinter->apiKey) : "",
60,
"",
false,
false,
String(id)
);
WebserverMemoryVariables::sendFormInput(
server,
FPSTR(CONFPRINTER_FORM_ADDEDIT4_ID),
FPSTR(CONFPRINTER_FORM_ADDEDIT4_LABEL),
id > 0 ? String(forPrinter->remoteAddress) : "",
60,
"",
false,
false,
String(id)
);
WebserverMemoryVariables::sendFormInput(
server,
FPSTR(CONFPRINTER_FORM_ADDEDIT5_ID),
FPSTR(CONFPRINTER_FORM_ADDEDIT5_LABEL),
id > 0 ? String(forPrinter->remotePort) : "80",
5,
"onkeypress='return isNumberKey(event)'",
false,
false,
String(id)
);
WebserverMemoryVariables::sendFormCheckboxEvent(
server,
FPSTR(CONFPRINTER_FORM_ADDEDIT6_ID),
id > 0 ? forPrinter->basicAuthNeeded : true,
FPSTR(CONFPRINTER_FORM_ADDEDIT6_LABEL),
"showhide('" + String(FPSTR(CONFPRINTER_FORM_ADDEDIT6_ID)) + "-" + String(id) + "', 'apac-" + String(id) + "')",
false,
String(id)
);
WebserverMemoryVariables::rowExtraClass = "data-sh='apac-" + String(id) + "'";
WebserverMemoryVariables::sendFormInput(
server,
FPSTR(STATION_CONFIG_FORM7_ID),
FPSTR(STATION_CONFIG_FORM7_LABEL),
id > 0 ? String(forPrinter->basicAuthUsername) : "",
30,
"",
false,
false,
String(id)
);
WebserverMemoryVariables::rowExtraClass = "data-sh='apac-" + String(id) + "'";
WebserverMemoryVariables::sendFormInput(
server,
FPSTR(STATION_CONFIG_FORM8_ID),
FPSTR(STATION_CONFIG_FORM8_LABEL),
id > 0 ? String(forPrinter->basicAuthPassword) : "",
120,
"",
true,
false,
String(id)
);
modalData = FPSTR(CONFPRINTER_FORM_ADDEDIT_END);
modalData.replace("%ID%", String(id));
server->sendContent(modalData);
} }
@ -283,9 +462,10 @@ void WebserverMemoryVariables::sendPrinterConfigFormAEModal(ESP8266WebServer *se
* @param formId Form id/name * @param formId Form id/name
* @param isChecked Checkbox checked * @param isChecked Checkbox checked
* @param label Text for activated/deactivated * @param label Text for activated/deactivated
* @param inRow Extend the field with row div
*/ */
void WebserverMemoryVariables::sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String label) { void WebserverMemoryVariables::sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String label, bool inRow, String uniqueId = "") {
WebserverMemoryVariables::sendFormCheckboxEvent(server, formId, isChecked, label, ""); WebserverMemoryVariables::sendFormCheckboxEvent(server, formId, isChecked, label, "", inRow, uniqueId);
} }
/** /**
@ -295,9 +475,10 @@ void WebserverMemoryVariables::sendFormCheckbox(ESP8266WebServer *server, String
* @param isChecked Checkbox checked * @param isChecked Checkbox checked
* @param labelOn Text for activated * @param labelOn Text for activated
* @param labelOff Text for deactivated * @param labelOff Text for deactivated
* @param inRow Extend the field with row div
*/ */
void WebserverMemoryVariables::sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String labelOn, String labelOff) { void WebserverMemoryVariables::sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String labelOn, String labelOff, bool inRow, String uniqueId = "") {
WebserverMemoryVariables::sendFormCheckboxEvent(server, formId, isChecked, labelOn, labelOff, ""); WebserverMemoryVariables::sendFormCheckboxEvent(server, formId, isChecked, labelOn, labelOff, "", inRow, uniqueId);
} }
/** /**
@ -307,14 +488,22 @@ void WebserverMemoryVariables::sendFormCheckbox(ESP8266WebServer *server, String
* @param isChecked Checkbox checked * @param isChecked Checkbox checked
* @param label Text for activated/deactivated * @param label Text for activated/deactivated
* @param onChange Javascript function * @param onChange Javascript function
* @param inRow Extend the field with row div
*/ */
void WebserverMemoryVariables::sendFormCheckboxEvent(ESP8266WebServer *server, String formId, bool isChecked, String label, String onChange) { void WebserverMemoryVariables::sendFormCheckboxEvent(
ESP8266WebServer *server,
String formId,
bool isChecked,
String label,
String onChange,
bool inRow,
String uniqueId = ""
) {
String onAdd = FPSTR(FORM_ITEM_CHECKBOX_ON); String onAdd = FPSTR(FORM_ITEM_CHECKBOX_ON);
String offAdd = FPSTR(FORM_ITEM_CHECKBOX_OFF); String offAdd = FPSTR(FORM_ITEM_CHECKBOX_OFF);
WebserverMemoryVariables::sendFormCheckboxEvent(server, formId, isChecked, label + onAdd, label + offAdd, onChange); WebserverMemoryVariables::sendFormCheckboxEvent(server, formId, isChecked, label + onAdd, label + offAdd, onChange, inRow, uniqueId);
} }
/** /**
* @brief Send out an single checkbox form row with onChangeEvent * @brief Send out an single checkbox form row with onChangeEvent
* @param server Send out instancce * @param server Send out instancce
@ -323,8 +512,18 @@ void WebserverMemoryVariables::sendFormCheckboxEvent(ESP8266WebServer *server, S
* @param labelOn Text for activated * @param labelOn Text for activated
* @param labelOff Text for deactivated * @param labelOff Text for deactivated
* @param onChange Javascript function * @param onChange Javascript function
* @param inRow Extend the field with row div
*/ */
void WebserverMemoryVariables::sendFormCheckboxEvent(ESP8266WebServer *server, String formId, bool isChecked, String labelOn, String labelOff, String onChange) { void WebserverMemoryVariables::sendFormCheckboxEvent(
ESP8266WebServer *server,
String formId,
bool isChecked,
String labelOn,
String labelOff,
String onChange,
bool inRow,
String uniqueId = ""
) {
String isCheckedText = ""; String isCheckedText = "";
String onChangeText = ""; String onChangeText = "";
if (isChecked) { if (isChecked) {
@ -339,5 +538,177 @@ void WebserverMemoryVariables::sendFormCheckboxEvent(ESP8266WebServer *server, S
form.replace("%LABELON%", labelOn); form.replace("%LABELON%", labelOn);
form.replace("%LABELOFF%", labelOff); form.replace("%LABELOFF%", labelOff);
form.replace("%ONCHANGE%", onChangeText); form.replace("%ONCHANGE%", onChangeText);
server->sendContent(form); WebserverMemoryVariables::sendForm(server, formId, form, inRow, uniqueId);
} }
/**
* @brief Send out an single input field form row
* @param server Send out instancce
* @param formId Form id/name
* @param label Text for label head
* @param value Value in field
* @param maxLen Max text len in input field
* @param events Extra events for input field
* @param isPassword True if password field
* @param inRow Extend the field with row div
* @param uniqueId Unique key for ids
*/
void WebserverMemoryVariables::sendFormInput(
ESP8266WebServer *server,
String formId,
String label,
String value,
int maxLen,
String events,
bool isPassword,
bool inRow,
String uniqueId = ""
) {
String form = FPSTR(FORM_ITEM_INPUT);
form.replace("%FORMID%", formId);
form.replace("%LABEL%", label);
form.replace("%VALUE%", value);
form.replace("%MAXLEN%", String(maxLen));
form.replace("%EVENTS%", events);
if (isPassword) {
form.replace("%FIELDTYPE%", "password");
}
else {
form.replace("%FIELDTYPE%", "text");
}
WebserverMemoryVariables::sendForm(server, formId, form, inRow, uniqueId);
}
/**
* @brief Send out an single input field form row
* @param server Send out instancce
* @param formId Form id/name
* @param label Text for label head
* @param value Value in field
* @param events Extra events for input field
* @param inRow Extend the field with row div
* @param uniqueId Unique key for ids
*/
void WebserverMemoryVariables::sendFormSelect(
ESP8266WebServer *server,
String formId,
String label,
String value,
String events,
String options,
bool inRow,
String uniqueId = ""
) {
String form = FPSTR(FORM_ITEM_SELECT_START);
form.replace("%FORMID%", formId);
form.replace("%LABEL%", label);
form.replace("%EVENTS%", events);
if (value.length() > 0) {
options.replace(
">"+ value + "<",
" selected>" + String(value) + "<"
);
}
WebserverMemoryVariables::sendForm(
server,
formId,
form + options + FPSTR(FORM_ITEM_SELECT_END),
inRow,
uniqueId
);
}
/**
* @brief Send form out to client
*
* @param server Send out instancce
* @param formElement Form element
* @param inRow True if in row
*/
void WebserverMemoryVariables::sendFormSubmitButton(
ESP8266WebServer *server,
bool inRow
) {
WebserverMemoryVariables::sendForm(
server,
"",
FPSTR(FORM_ITEM_SUBMIT),
inRow,
""
);
}
/**
* @brief Send form out to client
*
* @param server Send out instance
* @param formId Form id/name
* @param formElement Form element
* @param inRow True if in row
* @param uniqueId Unique key for ids
*/
void WebserverMemoryVariables::sendForm(
ESP8266WebServer *server,
String formId,
String formElement,
bool inRow,
String uniqueId
) {
if (uniqueId.length() > 0) {
formElement.replace("id='" + formId + "'", "id='" + formId + "-" + uniqueId + "'");
formElement.replace("for='" + formId + "'", "for='" + formId + "-" + uniqueId + "'");
}
if (inRow) {
String rowStartData = FPSTR(FORM_ITEM_ROW_START);
rowStartData.replace("%ROWEXTRACLASS%", WebserverMemoryVariables::rowExtraClass);
WebserverMemoryVariables::rowExtraClass = "";
server->sendContent(rowStartData);
formElement.replace("%ROWEXT%", FPSTR(FORM_ITEM_ROW_EXT));
formElement.replace("%DIVEXTRACLASS%", "");
} else {
formElement.replace("%ROWEXT%", "");
formElement.replace("%DIVEXTRACLASS%", WebserverMemoryVariables::rowExtraClass);
}
server->sendContent(formElement);
if (inRow) {
server->sendContent(FPSTR(FORM_ITEM_ROW_END));
}
}
/**
* @brief Send danger modal out to client
*
* @param server Send out instancce
* @param formId ID of element
* @param label Label top
* @param title Dialog title
* @param content Dialog detailed content
* @param secActionTitle Title of secondary button
* @param primActionTitle Title of primary button
* @param primActionEvent Event of primary button
*/
void WebserverMemoryVariables::sendModalDanger(
ESP8266WebServer *server,
String formId,
String label,
String title,
String content,
String secActionTitle,
String primActionTitle,
String primActionEvent
) {
String modalDialog = FPSTR(MODAL_DANGER);
modalDialog.replace("%ID%", formId);
modalDialog.replace("%LABEL%", label);
modalDialog.replace("%HEADING%", title);
modalDialog.replace("%CONTENT%", content);
modalDialog.replace("%SECACTION%", secActionTitle);
modalDialog.replace("%MAINACTION%", primActionTitle);
modalDialog.replace("%MAINEVENT%", primActionEvent);
server->sendContent(modalDialog);
}

View File

@ -7,8 +7,12 @@
/** /**
* Webpage form items for reuse * Webpage form items for reuse
*/ */
static const char FORM_ITEM_CHECKBOX[] PROGMEM = "<div class='bx--row'>" static const char FORM_ITEM_ROW_START[] PROGMEM = "<div class='bx--row' %ROWEXTRACLASS%>";
"<div class='bx--col bx--col--auto bx--form-item'>" static const char FORM_ITEM_ROW_EXT[] PROGMEM = "bx--col bx--col--auto";
static const char FORM_ITEM_ROW_END[] PROGMEM = "</div>";
static const char FORM_ITEM_CHECKBOX[] PROGMEM = "<div class='%ROWEXT% bx--form-item' %DIVEXTRACLASS%>"
"<input class='bx--toggle-input bx--toggle-input--small' id='%FORMID%' type='checkbox' name='%FORMID%' %CHECKED% %ONCHANGE%>" "<input class='bx--toggle-input bx--toggle-input--small' id='%FORMID%' type='checkbox' name='%FORMID%' %CHECKED% %ONCHANGE%>"
"<label class='bx--toggle-input__label' for='%FORMID%'>" "<label class='bx--toggle-input__label' for='%FORMID%'>"
"<span class='bx--toggle__switch'>" "<span class='bx--toggle__switch'>"
@ -19,11 +23,28 @@ static const char FORM_ITEM_CHECKBOX[] PROGMEM = "<div class='bx--row'>"
"<span class='bx--toggle__text--on' aria-hidden='true'>%LABELON%</span>" "<span class='bx--toggle__text--on' aria-hidden='true'>%LABELON%</span>"
"</span>" "</span>"
"</label>" "</label>"
"</div>"
"</div>"; "</div>";
static const char FORM_ITEM_CHECKBOX_ON[] PROGMEM = " activated"; static const char FORM_ITEM_CHECKBOX_ON[] PROGMEM = " activated";
static const char FORM_ITEM_CHECKBOX_OFF[] PROGMEM = " deactivated"; static const char FORM_ITEM_CHECKBOX_OFF[] PROGMEM = " deactivated";
static const char FORM_ITEM_INPUT[] PROGMEM = "<div class='%ROWEXT% bx--form-item' %DIVEXTRACLASS%>"
"<label for='%FORMID%' class='bx--label'>%LABEL%</label>"
"<input id='%FORMID%' type='%FIELDTYPE%' class='bx--text-input' name='%FORMID%' value='%VALUE%' maxlength='%MAXLEN%' %EVENTS%>"
"</div>";
static const char FORM_ITEM_SELECT_START[] PROGMEM = "<div class='bx--form-item bx--select %ROWEXT%' %DIVEXTRACLASS%>"
"<label for='%FORMID%' class='bx--label'>%LABEL%</label>"
"<div class='bx--select-input__wrapper'>"
"<select id='%FORMID%' class='bx--select-input' name='%FORMID%' %EVENTS%>";
static const char FORM_ITEM_SELECT_END[] PROGMEM = "</select>"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--select__arrow' width='10' height='6' viewBox='0 0 10 6' aria-hidden='true'><path d='M5 6L0 1 0.7 0.3 5 4.6 9.3 0.3 10 1z'></path></svg>"
"</div>"
"</div>";
static const char FORM_ITEM_SUBMIT[] PROGMEM = "<div class='bx--form-item %ROWEXT%' %DIVEXTRACLASS%>"
"<button class='bx--btn bx--btn--primary' type='submit'>Save</button>"
"</div>";
/** /**
* Webpage side menu right for main items * Webpage side menu right for main items
*/ */
@ -48,11 +69,11 @@ static const char MENUE_ITEMS[] PROGMEM =
"Configure Sensor" "Configure Sensor"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='16' height='16' viewBox='0 0 32 32' aria-hidden='true'><path d='M30,19H26V15H24v9H8V8l9-.0009V6H13V2H11V6H8A2.002,2.002,0,0,0,6,8v3H2v2H6v6H2v2H6v3a2.0023,2.0023,0,0,0,2,2h3v4h2V26h6v4h2V26h3a2.0027,2.0027,0,0,0,2-2V21h4Z'></path><path d='M26,2a4.0042,4.0042,0,0,0-4,4,3.9556,3.9556,0,0,0,.5668,2.0192L19.5859,11H11V21H21V12.4141l2.9808-2.9808A3.9553,3.9553,0,0,0,26,10a4,4,0,0,0,0-8ZM19,19H13V13h6ZM26,8a2,2,0,1,1,2-2A2.0023,2.0023,0,0,1,26,8Z'></path></svg>" "<svg focusable='false' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='16' height='16' viewBox='0 0 32 32' aria-hidden='true'><path d='M30,19H26V15H24v9H8V8l9-.0009V6H13V2H11V6H8A2.002,2.002,0,0,0,6,8v3H2v2H6v6H2v2H6v3a2.0023,2.0023,0,0,0,2,2h3v4h2V26h6v4h2V26h3a2.0027,2.0027,0,0,0,2-2V21h4Z'></path><path d='M26,2a4.0042,4.0042,0,0,0-4,4,3.9556,3.9556,0,0,0,.5668,2.0192L19.5859,11H11V21H21V12.4141l2.9808-2.9808A3.9553,3.9553,0,0,0,26,10a4,4,0,0,0,0-8ZM19,19H13V13h6ZM26,8a2,2,0,1,1,2-2A2.0023,2.0023,0,0,1,26,8Z'></path></svg>"
"</a></li>" "</a></li>"
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link menitem' href='/systemreset' onclick='return confirm(\"Do you want to reset to default settings?\")'>" "<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link menitem' onclick='openModal(\"resetSettingsModal\")'>"
"Reset Settings" "Reset Settings"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='16' height='16' viewBox='0 0 32 32' aria-hidden='true'><path d='M18,28A12,12,0,1,0,6,16v6.2L2.4,18.6,1,20l6,6,6-6-1.4-1.4L8,22.2V16H8A10,10,0,1,1,18,26Z'></path></svg>" "<svg focusable='false' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='16' height='16' viewBox='0 0 32 32' aria-hidden='true'><path d='M18,28A12,12,0,1,0,6,16v6.2L2.4,18.6,1,20l6,6,6-6-1.4-1.4L8,22.2V16H8A10,10,0,1,1,18,26Z'></path></svg>"
"</a></li>" "</a></li>"
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link menitem' href='/forgetwifi' onclick='return confirm(\"Do you want to forget to WiFi connection?\")'>" "<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link menitem' onclick='openModal(\"resetWifiModal\")'>"
"Forget WiFi" "Forget WiFi"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='16' height='16' viewBox='0 0 32 32' aria-hidden='true'><circle cx='16' cy='25' r='2'></circle><path d='M30 3.4141L28.5859 2 2 28.5859 3.4141 30 14.0962 19.3179a5.9359 5.9359 0 016.01 1.3193L21.52 19.2236a7.9669 7.9669 0 00-5.125-2.2041l3.3875-3.3877a11.9908 11.9908 0 014.5647 2.7647L25.76 14.9829A13.975 13.975 0 0021.334 12.08L24.3308 9.083a17.9364 17.9364 0 014.2546 3.0747L30 10.7432v-.002a20.02 20.02 0 00-4.1895-3.1377zM14.68 13.0776l2.0415-2.0415C16.481 11.0234 16.2437 11 16 11a13.9447 13.9447 0 00-9.771 3.9927l1.4136 1.4136A11.97 11.97 0 0114.68 13.0776zM16 7a17.87 17.87 0 014.2324.5254L21.875 5.8828A19.9537 19.9537 0 002 10.7412v.0225L3.4043 12.168A17.9193 17.9193 0 0116 7z'></path></svg>" "<svg focusable='false' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='16' height='16' viewBox='0 0 32 32' aria-hidden='true'><circle cx='16' cy='25' r='2'></circle><path d='M30 3.4141L28.5859 2 2 28.5859 3.4141 30 14.0962 19.3179a5.9359 5.9359 0 016.01 1.3193L21.52 19.2236a7.9669 7.9669 0 00-5.125-2.2041l3.3875-3.3877a11.9908 11.9908 0 014.5647 2.7647L25.76 14.9829A13.975 13.975 0 0021.334 12.08L24.3308 9.083a17.9364 17.9364 0 014.2546 3.0747L30 10.7432v-.002a20.02 20.02 0 00-4.1895-3.1377zM14.68 13.0776l2.0415-2.0415C16.481 11.0234 16.2437 11 16 11a13.9447 13.9447 0 00-9.771 3.9927l1.4136 1.4136A11.97 11.97 0 0114.68 13.0776zM16 7a17.87 17.87 0 014.2324.5254L21.875 5.8828A19.9537 19.9537 0 002 10.7412v.0225L3.4043 12.168A17.9193 17.9193 0 0116 7z'></path></svg>"
"</a></li>" "</a></li>"
@ -77,9 +98,12 @@ static const char HEADER_BLOCK2[] PROGMEM = "<link rel='stylesheet' href='https:
"<link rel='stylesheet' href='https://unpkg.com/carbon-components/css/carbon-components.min.css'></style>" "<link rel='stylesheet' href='https://unpkg.com/carbon-components/css/carbon-components.min.css'></style>"
"<link rel='stylesheet' href='https://use.fontawesome.com/releases/v5.15.1/css/all.css'>" "<link rel='stylesheet' href='https://use.fontawesome.com/releases/v5.15.1/css/all.css'>"
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>" "<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>"
"<script>function showhide(a,b) {var e=$(\"[data-sh='\"+b+\"']\");if(a.checked||a.prop('checked')){e.removeClass('hidden')}else{e.addClass('hidden')}}</script>"
"<style>.hidden{display:none} .bx--form-item{margin-bottom:20px} .bx--table-column-menu{width: 3.25rem} .menitem{padding:6px 1rem;font-size:.875rem;font-weight:600;line-height:1.29;letter-spacing:.16px;display:flex;justify-content:space-between;text-decoration:none;color:#c6c6c6}</style>" "<style>.hidden{display:none} .bx--form-item{margin-bottom:20px} .bx--table-column-menu{width: 3.25rem} .menitem{padding:6px 1rem;font-size:.875rem;font-weight:600;line-height:1.29;letter-spacing:.16px;display:flex;justify-content:space-between;text-decoration:none;color:#c6c6c6}</style>"
"<script>function showhide(a,b) {var e=$(\"[data-sh='\"+b+\"']\");var f=$(\"#\" + a);if (f.checked||f.prop('checked')){e.removeClass('hidden');}else{e.addClass('hidden');}}</script>"
"<script>function openModal(refelementId){document.body.classList.add(\"bx--body--with-modal-open\");document.getElementById(refelementId).classList.add(\"is-visible\")} function closeModal(refelementId){document.getElementById(refelementId).classList.remove(\"is-visible\");document.body.classList.remove(\"bx--body--with-modal-open\")}</script>" "<script>function openModal(refelementId){document.body.classList.add(\"bx--body--with-modal-open\");document.getElementById(refelementId).classList.add(\"is-visible\")} function closeModal(refelementId){document.getElementById(refelementId).classList.remove(\"is-visible\");document.body.classList.remove(\"bx--body--with-modal-open\")}</script>"
"<script>function isNumberKey(e){var h=e.which?e.which:event.keyCode;return!(h>31&&(h<48||h>57))}</script>"
"<script>function openUrl(e){window.location.assign(e)}</script>"
"</head><body>" "</head><body>"
"<header class='cv-header bx--header'>" "<header class='cv-header bx--header'>"
"<a href='/' class='cv-header-name bx--header__name'>"; "<a href='/' class='cv-header-name bx--header__name'>";
@ -129,6 +153,15 @@ static const char HEADER_BLOCK_ERROR[] PROGMEM = "<div class='bx--inline-notific
"</button>" "</button>"
"</div>"; "</div>";
static const char HEADER_BLOCK_OK[] PROGMEM = "<div class='bx--inline-notification bx--inline-notification--success' role='alert' style='max-width:100%'>"
"<div class='bx--inline-notification__details'>"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--inline-notification__icon' width='20' height='20' viewBox='0 0 20 20' aria-hidden='true'><path d='M10,1c-4.9,0-9,4.1-9,9s4.1,9,9,9s9-4,9-9S15,1,10,1z M8.7,13.5l-3.2-3.2l1-1l2.2,2.2l4.8-4.8l1,1L8.7,13.5z'></path><path fill='none' d='M8.7,13.5l-3.2-3.2l1-1l2.2,2.2l4.8-4.8l1,1L8.7,13.5z' data-icon-path='inner-path' opacity='0'></path></svg>"
"<div class='bx--inline-notification__text-wrapper'>"
"<p class='bx--inline-notification__title'>%OKMSG%</p>"
"</div>"
"</div>"
"</div>";
static const char FOOTER_BLOCK[] PROGMEM = "<br><br><br></div>" static const char FOOTER_BLOCK[] PROGMEM = "<br><br><br></div>"
"<div class='bx--loading-overlay hidden' id='pageloading'>" "<div class='bx--loading-overlay hidden' id='pageloading'>"
"<div data-loading class='bx--loading'>" "<div data-loading class='bx--loading'>"
@ -143,6 +176,18 @@ static const char FOOTER_BLOCK[] PROGMEM = "<br><br><br></div>"
"</body>" "</body>"
"</html>"; "</html>";
/**
* Global Text
*/
static const char GLOBAL_TEXT_WARNING[] PROGMEM = "WARNING";
static const char GLOBAL_TEXT_ABORT[] PROGMEM = "Abort";
static const char GLOBAL_TEXT_RESET[] PROGMEM = "Reset";
static const char GLOBAL_TEXT_TRESET[] PROGMEM = "Reset settings";
static const char GLOBAL_TEXT_CRESET[] PROGMEM = "Do you want to reset to default settings?";
static const char GLOBAL_TEXT_TFWIFI[] PROGMEM = "Reset wifi";
static const char GLOBAL_TEXT_CFWIFI[] PROGMEM = "Do you want to reset wifi to default settings?";
/** /**
* Controls for update firmware/filesystem * Controls for update firmware/filesystem
*/ */
@ -197,39 +242,15 @@ static const char WEATHER_FORM2_ID[] PROGMEM = "metric";
static const char WEATHER_FORM2_LABEL_ON[] PROGMEM = "Show in Celsius"; static const char WEATHER_FORM2_LABEL_ON[] PROGMEM = "Show in Celsius";
static const char WEATHER_FORM2_LABEL_OFF[] PROGMEM = "Show in Fahrenheit"; static const char WEATHER_FORM2_LABEL_OFF[] PROGMEM = "Show in Fahrenheit";
static const char WEATHER_FORM3[] PROGMEM = "<div class='bx--row'>" static const char WEATHER_FORM3_ID[] PROGMEM = "openWeatherMapApiKey";
"<div class='bx--form-item bx--col bx--col--auto'>" static const char WEATHER_FORM3_LABEL[] PROGMEM = "OpenWeatherMap API Key (get from <a href='https://openweathermap.org/' target='_BLANK'>here</a>)";
"<label for='openWeatherMapApiKey' class='bx--label'>OpenWeatherMap API Key (get from <a href='https://openweathermap.org/' target='_BLANK'>here</a>)</label>"
"<input id='openWeatherMapApiKey' type='text' class='bx--text-input' name='openWeatherMapApiKey' value='%WEATHERKEY%' maxlength='60'>"
"</div>"
"</div>";
static const char WEATHER_FORM4[] PROGMEM = "<div class='bx--row'>" static const char WEATHER_FORM4_ID[] PROGMEM = "city1";
"<div class='bx--form-item bx--col bx--col--auto'>" static const char WEATHER_FORM4_LABEL[] PROGMEM = "(<a href='http://openweathermap.org/find' target='_BLANK'><i class='fa fa-search'></i> Search for City ID</a>)";
"<label for='city1' class='bx--label'>%CITYNAME1% (<a href='http://openweathermap.org/find' target='_BLANK'><i class='fa fa-search'></i> Search for City ID</a>)</label>"
"<input id='city1' type='text' class='bx--text-input' name='city1' value='%CITY1%' onkeypress='return isNumberKey(event)'>"
"</div>"
"</div>"
"<div class='bx--row'>"
"<div class='bx--form-item bx--col bx--col--auto bx--select'>"
"<label for='language' class='bx--label'>Weather Language</label>"
"<div class='bx--select-input__wrapper'>"
"<select id='language' class='bx--select-input' name='language'>";
static const char WEATHER_FORM5[] PROGMEM = "</select>" static const char WEATHER_FORM5_ID[] PROGMEM = "language";
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--select__arrow' width='10' height='6' viewBox='0 0 10 6' aria-hidden='true'><path d='M5 6L0 1 0.7 0.3 5 4.6 9.3 0.3 10 1z'></path></svg>" static const char WEATHER_FORM5_LABEL[] PROGMEM = "Weather Language";
"</div>" static const char WEATHER_FORM5_OPTIONS[] PROGMEM = "<option class='bx--select-option'>ar</option>"
"</div>"
"</div>"
"<div class='bx--row'>"
"<div class='bx--form-item bx--col bx--col--auto'>"
"<button class='bx--btn bx--btn--primary' type='submit'>Save</button>"
"</div>"
"</div>"
"</form>"
"<script>function isNumberKey(e){var h=e.which?e.which:event.keyCode;return!(h>31&&(h<48||h>57))}</script>";
static const char WEATHER_FORM_OPTIONS[] PROGMEM = "<option class='bx--select-option'>ar</option>"
"<option class='bx--select-option'>bg</option>" "<option class='bx--select-option'>bg</option>"
"<option class='bx--select-option'>ca</option>" "<option class='bx--select-option'>ca</option>"
"<option class='bx--select-option'>cz</option>" "<option class='bx--select-option'>cz</option>"
@ -263,6 +284,8 @@ static const char WEATHER_FORM_OPTIONS[] PROGMEM = "<option class='bx--select-op
"<option class='bx--select-option'>zh_cn</option>" "<option class='bx--select-option'>zh_cn</option>"
"<option class='bx--select-option'>zh_tw</option>"; "<option class='bx--select-option'>zh_tw</option>";
static const char WEATHER_FORM_END[] PROGMEM = "</form>";
/** /**
* Controls for station configuration * Controls for station configuration
*/ */
@ -280,52 +303,27 @@ static const char STATION_CONFIG_FORM3_LABEL[] PROGMEM = "Flip display orientati
static const char STATION_CONFIG_FORM4_ID[] PROGMEM = "useFlash"; static const char STATION_CONFIG_FORM4_ID[] PROGMEM = "useFlash";
static const char STATION_CONFIG_FORM4_LABEL[] PROGMEM = "Flash System LED on Service Call"; static const char STATION_CONFIG_FORM4_LABEL[] PROGMEM = "Flash System LED on Service Call";
static const char STATION_CONFIG_FORM5[] PROGMEM = "<div class='bx--row'>" static const char STATION_CONFIG_FORM5_ID[] PROGMEM = "refresh";
"<div class='bx--form-item bx--col bx--col--auto bx--select'>" static const char STATION_CONFIG_FORM5_LABEL[] PROGMEM = "Clock Sync / Weather Refresh (minutes)";
"<label for='refresh' class='bx--label'>Clock Sync / Weather Refresh (minutes)</label>" static const char STATION_CONFIG_FORM5_OPTIONS[] PROGMEM = "<option class='bx--select-option'>10</option>"
"<div class='bx--select-input__wrapper'>"
"<select id='refresh' class='bx--select-input' name='refresh'>"
"%OPTIONS%"
"</select>"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--select__arrow' width='10' height='6' viewBox='0 0 10 6' aria-hidden='true'><path d='M5 6L0 1 0.7 0.3 5 4.6 9.3 0.3 10 1z'></path></svg>"
"</div>"
"</div>"
"</div>";
static const char STATION_CONFIG_FORM5OPT[] PROGMEM = "<option class='bx--select-option'>10</option>"
"<option class='bx--select-option'>15</option>" "<option class='bx--select-option'>15</option>"
"<option class='bx--select-option'>20</option>" "<option class='bx--select-option'>20</option>"
"<option class='bx--select-option'>30</option>" "<option class='bx--select-option'>30</option>"
"<option class='bx--select-option'>60</option>"; "<option class='bx--select-option'>60</option>";
static const char STATION_CONFIG_FORM6[] PROGMEM = "<div class='bx--row'>" static const char STATION_CONFIG_FORM6_ID[] PROGMEM = "utcoffset";
"<div class='bx--form-item bx--col bx--col--auto'>" static const char STATION_CONFIG_FORM6_LABEL[] PROGMEM = "UTC Time Offset";
"<label for='utcoffset' class='bx--label'>UTC Time Offset</label>"
"<input id='utcoffset' type='text' class='bx--text-input' name='utcoffset' value='%UTCOFFSET%' maxlength='1'>"
"</div>"
"</div>";
static const char STATION_CONFIG_FORM7_ID[] PROGMEM = "isBasicAuth"; static const char STATION_CONFIG_FORM7_ID[] PROGMEM = "isBasicAuth";
static const char STATION_CONFIG_FORM7_LABEL[] PROGMEM = "Use Security Credentials for Configuration Changes"; static const char STATION_CONFIG_FORM7_LABEL[] PROGMEM = "Use Security Credentials for Configuration Changes";
static const char STATION_CONFIG_FORM8[] PROGMEM = "<div class='bx--row' data-sh='uspw'>" static const char STATION_CONFIG_FORM8_ID[] PROGMEM = "userid";
"<div class='bx--form-item bx--col bx--col--auto'>" static const char STATION_CONFIG_FORM8_LABEL[] PROGMEM = "User ID (for this interface)";
"<label for='userid' class='bx--label'>User ID (for this interface)</label>"
"<input id='userid' type='text' class='bx--text-input' name='userid' value='%USERID%' maxlength='20'>" static const char STATION_CONFIG_FORM9_ID[] PROGMEM = "stationpassword";
"</div>" static const char STATION_CONFIG_FORM9_LABEL[] PROGMEM = "Password (for this interface)";
"</div>"
"<div class='bx--row' data-sh='uspw'>" static const char STATION_CONFIG_FORM_END[] PROGMEM = "</form><script>showhide('isBasicAuth', 'uspw')</script>";
"<div class='bx--form-item bx--col bx--col--auto'>"
"<label for='stationpassword' class='bx--label'>Password (for this interface)</label>"
"<input id='stationpassword' type='password' class='bx--text-input' name='stationpassword' value='%STATIONPASSWORD%'>"
"</div>"
"</div>"
"<div class='bx--row'>"
"<div class='bx--form-item bx--col bx--col--auto'>"
"<button class='bx--btn bx--btn--primary' type='submit'>Save</button>"
"</div>"
"</div>"
"</form><script>showhide($('#isBasicAuth'), 'uspw')</script>";
/** /**
* Controls for printer configuration * Controls for printer configuration
@ -400,7 +398,7 @@ static const char CONFPRINTER_FORM_END[] PROGMEM = "</tbody>"
static const char CONFPRINTER_FORM_ADDEDIT_TA[] PROGMEM = "Create new printer"; static const char CONFPRINTER_FORM_ADDEDIT_TA[] PROGMEM = "Create new printer";
static const char CONFPRINTER_FORM_ADDEDIT_TE[] PROGMEM = "Edit data for printer"; static const char CONFPRINTER_FORM_ADDEDIT_TE[] PROGMEM = "Edit data for printer";
static const char CONFPRINTER_FORM_ADDEDIT1[] PROGMEM = "<div data-modal id='mae-%ID%' class='bx--modal' role='dialog' aria-modal='true' aria-labelledby='mae-%ID%-label' aria-describedby='mae-%ID%-heading' tabindex='-1'>" static const char CONFPRINTER_FORM_ADDEDIT_START[] PROGMEM = "<div data-modal id='mae-%ID%' class='bx--modal' role='dialog' aria-modal='true' aria-labelledby='mae-%ID%-label' aria-describedby='mae-%ID%-heading' tabindex='-1'>"
"<div class='bx--modal-container'>" "<div class='bx--modal-container'>"
"<form method='GET' action='/configureprinter/edit'>" "<form method='GET' action='/configureprinter/edit'>"
"<input type='hidden' name='id' value='%ID%'>" "<input type='hidden' name='id' value='%ID%'>"
@ -411,64 +409,33 @@ static const char CONFPRINTER_FORM_ADDEDIT1[] PROGMEM = "<div data-modal id='mae
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--modal-close__icon' width='16' height='16' viewBox='0 0 16 16' aria-hidden='true'><path d='M12 4.7L11.3 4 8 7.3 4.7 4 4 4.7 7.3 8 4 11.3 4.7 12 8 8.7 11.3 12 12 11.3 8.7 8z'></path></svg>" "<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--modal-close__icon' width='16' height='16' viewBox='0 0 16 16' aria-hidden='true'><path d='M12 4.7L11.3 4 8 7.3 4.7 4 4 4.7 7.3 8 4 11.3 4.7 12 8 8.7 11.3 12 12 11.3 8.7 8z'></path></svg>"
"</button>" "</button>"
"</div>" "</div>"
"<div class='bx--modal-content bx--modal-content--with-form'>" "<div class='bx--modal-content bx--modal-content--with-form'>";
"<div class='bx--form-item'>"
"<label for='e-tname-%ID%' class='bx--label'>Printer Name</label>" static const char CONFPRINTER_FORM_ADDEDIT1_ID[] PROGMEM = "e-tname";
"<input id='e-tname-%ID%' name='e-tname' type='text' class='bx--text-input' placeholder='Custom name' data-modal-primary-focus maxlength='20' value='%NAME%'>" static const char CONFPRINTER_FORM_ADDEDIT1_LABEL[] PROGMEM = "Printer Name";
"</div>"
"<div class='bx--form-item bx--select'>" static const char CONFPRINTER_FORM_ADDEDIT2_ID[] PROGMEM = "e-tapi";
"<label for='e-tapi-%ID%' class='bx--label'>API Type</label>" static const char CONFPRINTER_FORM_ADDEDIT2_LABEL[] PROGMEM = "API Type";
"<div class='bx--select-input__wrapper'>"
"<select id='e-tapi-%ID%' class='bx--select-input' name='e-tapi'>" static const char CONFPRINTER_FORM_ADDEDIT3_ID[] PROGMEM = "e-tapikey";
"<option class='bx--select-option' value='0'>Duet</option>" static const char CONFPRINTER_FORM_ADDEDIT3_LABEL[] PROGMEM = "API Key";
"<option class='bx--select-option' value='1'>Klipper</option>"
"<option class='bx--select-option' selected value='2'>Octoprint</option>" static const char CONFPRINTER_FORM_ADDEDIT4_ID[] PROGMEM = "e-taddr";
"<option class='bx--select-option' value='3'>Repetier</option>" static const char CONFPRINTER_FORM_ADDEDIT4_LABEL[] PROGMEM = "Hostname or IP Address (do not include http://)";
"</select>"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--select__arrow' width='10' height='6' viewBox='0 0 10 6' aria-hidden='true'><path d='M5 6L0 1 0.7 0.3 5 4.6 9.3 0.3 10 1z'></path></svg>" static const char CONFPRINTER_FORM_ADDEDIT5_ID[] PROGMEM = "e-tport";
"</div>" static const char CONFPRINTER_FORM_ADDEDIT5_LABEL[] PROGMEM = "Port";
"</div>"
"<div class='bx--form-item'>" static const char CONFPRINTER_FORM_ADDEDIT6_ID[] PROGMEM = "e-tapipw";
"<label for='e-taddr-%ID%' class='bx--label'>Hostname or IP Address (do not include http://)</label>" static const char CONFPRINTER_FORM_ADDEDIT6_LABEL[] PROGMEM = "Haproxy or basic auth";
"<input id='e-taddr-%ID%' name='e-taddr' type='text' class='bx--text-input' placeholder='Target Address' maxlength='60' value='%TARGETADDR%'>"
"</div>" static const char CONFPRINTER_FORM_ADDEDIT7_ID[] PROGMEM = "e-tapiuser";
"<div class='bx--form-item'>" static const char CONFPRINTER_FORM_ADDEDIT7_LABEL[] PROGMEM = "User ID";
"<label for='e-tport-%ID%' class='bx--label'>Port</label>"
"<input id='e-tport-%ID%' name='e-tport' type='text' class='bx--text-input' placeholder='Target port' maxlength='5' value='%TARGETPORT%'>" static const char CONFPRINTER_FORM_ADDEDIT8_ID[] PROGMEM = "e-tapipass";
"</div>" static const char CONFPRINTER_FORM_ADDEDIT8_LABEL[] PROGMEM = "Password";
"<div class='bx--form-item'>"
"<input class='bx--toggle-input bx--toggle-input--small' id='e-tpsu-%ID%' type='checkbox' name='e-tpsu'>" static const char CONFPRINTER_FORM_ADDEDIT_END[] PROGMEM = "<br><br></div>"
"<label class='bx--toggle-input__label' for='e-tpsu-%ID%'>"
"<span class='bx--toggle__switch'>"
"<svg class='bx--toggle__check' width='6px' height='5px' viewBox='0 0 6 5'>"
"<path d='M2.2 2.7L5 0 6 1 2.2 5 0 2.7 1 1.5z' />"
"</svg>"
"<span class='bx--toggle__text--off' aria-hidden='true'>PSU control deactivated</span>"
"<span class='bx--toggle__text--on' aria-hidden='true'>PSU control activated</span>"
"</span>"
"</label>"
"</div>"
"<div class='bx--form-item'>"
"<input class='bx--toggle-input bx--toggle-input--small' id='e-tapipw-%ID%' type='checkbox' name='e-tapipw' onchange='showhide(this, \"apac-%ID%\")' checked='checked'>"
"<label class='bx--toggle-input__label' for='e-tapipw-%ID%'>"
"<span class='bx--toggle__switch'>"
"<svg class='bx--toggle__check' width='6px' height='5px' viewBox='0 0 6 5'>"
"<path d='M2.2 2.7L5 0 6 1 2.2 5 0 2.7 1 1.5z' />"
"</svg>"
"<span class='bx--toggle__text--off' aria-hidden='true'>Haproxy or basic auth deactivated</span>"
"<span class='bx--toggle__text--on' aria-hidden='true'>Haproxy or basic auth activated</span>"
"</span>"
"</label>"
"</div>"
"<div class='bx--form-item' data-sh='apac-%ID%'>"
"<label for='e-tapiuser-%ID%' class='bx--label'>User ID (for this interface)</label>"
"<input id='e-tapiuser-%ID%' type='text' class='bx--text-input' name='e-tapiuser' value='admin' maxlength='30'>"
"</div>"
"<div class='bx--form-item' data-sh='apac-%ID%'>"
"<label for='e-tapipass-%ID%' class='bx--label'>Password (for this interface)</label>"
"<input id='e-tapipass-%ID%' type='password' class='bx--text-input' name='e-tapipass' value='admin'>"
"</div><br><br>"
"</div>"
"<div class='bx--modal-content--overflow-indicator'></div>" "<div class='bx--modal-content--overflow-indicator'></div>"
"<div class='bx--modal-footer'>" "<div class='bx--modal-footer'>"
"<button class='bx--btn bx--btn--secondary' type='reset' onclick='closeModal(\"mae-%ID%\")'>Abort</button>" "<button class='bx--btn bx--btn--secondary' type='reset' onclick='closeModal(\"mae-%ID%\")'>Abort</button>"
@ -480,10 +447,42 @@ static const char CONFPRINTER_FORM_ADDEDIT1[] PROGMEM = "<div data-modal id='mae
"</div>" "</div>"
"</div>"; "</div>";
static const char MODAL_DANGER[] PROGMEM = "<div data-modal id='%ID%' class='bx--modal bx--modal--danger' role='dialog' aria-modal='true' aria-labelledby='%ID%-label' aria-describedby='%ID%-heading' tabindex='-1'>"
"<div class='bx--modal-container'>"
"<div class='bx--modal-header'>"
"<p class='bx--modal-header__label bx--type-delta' id='%ID%-label'>%LABEL%</p>"
"<p class='bx--modal-header__heading bx--type-beta' id='%ID%-heading'>%HEADING%</p>"
"<button class='bx--modal-close' type='button' aria-label='close modal' onclick='closeModal(\"%ID%\")'>"
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' style='will-change: transform;' xmlns='http://www.w3.org/2000/svg' class='bx--modal-close__icon' width='16' height='16' viewBox='0 0 16 16' aria-hidden='true'><path d='M12 4.7L11.3 4 8 7.3 4.7 4 4 4.7 7.3 8 4 11.3 4.7 12 8 8.7 11.3 12 12 11.3 8.7 8z'></path></svg>"
"</button>"
"</div>"
"<div class='bx--modal-content' >"
"<p>%CONTENT%</p><br><br><br>"
"</div>"
"<div class='bx--modal-content--overflow-indicator'></div>"
"<div class='bx--modal-footer'>"
"<button class='bx--btn bx--btn--secondary' type='button' onclick='closeModal(\"%ID%\")'>%SECACTION%</button>"
"<button class='bx--btn bx--btn--danger' type='button' aria-label='Danger' data-modal-primary-focus %MAINEVENT%>%MAINACTION%</button>"
"</div>"
"</div>"
"<span tabindex='0'></span>"
"</div>";
/** /**
* @brief Class to generate HTML content from Memory * @brief Class to generate HTML content from Memory
*/ */
class WebserverMemoryVariables { class WebserverMemoryVariables {
private:
static String rowExtraClass;
public: public:
static void sendHeader(ESP8266WebServer *server, GlobalDataController *globalDataController, String pageLabel, String pageTitle); static void sendHeader(ESP8266WebServer *server, GlobalDataController *globalDataController, String pageLabel, String pageTitle);
static void sendHeader(ESP8266WebServer *server, GlobalDataController *globalDataController, String pageLabel, String pageTitle, boolean refresh); static void sendHeader(ESP8266WebServer *server, GlobalDataController *globalDataController, String pageLabel, String pageTitle, boolean refresh);
@ -495,10 +494,16 @@ public:
static void sendPrinterConfigForm(ESP8266WebServer *server, GlobalDataController *globalDataController); static void sendPrinterConfigForm(ESP8266WebServer *server, GlobalDataController *globalDataController);
private: private:
static void sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String label); static void sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String label, bool inRow, String uniqueId);
static void sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String labelOn, String labelOff); static void sendFormCheckbox(ESP8266WebServer *server, String formId, bool isChecked, String labelOn, String labelOff, bool inRow, String uniqueId);
static void sendFormCheckboxEvent(ESP8266WebServer *server, String formId, bool isChecked, String label, String onChange); static void sendFormCheckboxEvent(ESP8266WebServer *server, String formId, bool isChecked, String label, String onChange, bool inRow, String uniqueId);
static void sendFormCheckboxEvent(ESP8266WebServer *server, String formId, bool isChecked, String labelOn, String labelOff, String onChange); static void sendFormCheckboxEvent(ESP8266WebServer *server, String formId, bool isChecked, String labelOn, String labelOff, String onChange, bool inRow, String uniqueId);
static void sendFormInput(ESP8266WebServer *server, String formId, String label, String value, int maxLen, String events, bool isPassword, bool inRow, String uniqueId);
static void sendFormSelect(ESP8266WebServer *server, String formId, String label, String value, String events, String options, bool inRow, String uniqueId);
static void sendFormSubmitButton(ESP8266WebServer *server, bool inRow);
static void sendForm(ESP8266WebServer *server, String formId, String formElement, bool inRow, String uniqueId);
static void sendPrinterConfigFormAEModal(ESP8266WebServer *server, int id, PrinterDataStruct *forPrinter); static void sendPrinterConfigFormAEModal(ESP8266WebServer *server, int id, PrinterDataStruct *forPrinter, GlobalDataController *globalDataController);
static void sendModalDanger(ESP8266WebServer *server, String formId, String label, String title, String content, String secActionTitle, String primActionTitle, String primActionEvent);
}; };

0
src/Sensors/BME280.cpp Normal file
View File

1
src/Sensors/BME280.h Normal file
View File

@ -0,0 +1 @@
#pragma once

0
src/Sensors/BME680.cpp Normal file
View File

1
src/Sensors/BME680.h Normal file
View File

@ -0,0 +1 @@
#pragma once

0
src/Sensors/HTU21D.cpp Normal file
View File

1
src/Sensors/HTU21D.h Normal file
View File

@ -0,0 +1 @@
#pragma once

View File

@ -0,0 +1,2 @@
#pragma once

View File

@ -262,7 +262,7 @@
</label> </label>
</div> </div>
<div class="bx--form-item"> <div class="bx--form-item">
<input class="bx--toggle-input bx--toggle-input--small" id="e-tapipw" type="checkbox" name="e-tapipw" onchange="showhide(this, 'apac')" checked="checked"> <input class="bx--toggle-input bx--toggle-input--small" id="e-tapipw" type="checkbox" name="e-tapipw" onchange="showhide('e-tapipw', 'apac')" checked="checked">
<label class="bx--toggle-input__label" for="e-tapipw"> <label class="bx--toggle-input__label" for="e-tapipw">
<span class="bx--toggle__switch"> <span class="bx--toggle__switch">
<svg class="bx--toggle__check" width="6px" height="5px" viewBox="0 0 6 5"> <svg class="bx--toggle__check" width="6px" height="5px" viewBox="0 0 6 5">
@ -366,8 +366,9 @@
function showhide(a,b) { function showhide(a,b) {
var e = $("[data-sh='"+b+"']"); var e = $("[data-sh='"+b+"']");
console.log(); var f = $("#" + a);
if (a.checked||a.prop('checked')) {
if (f.checked||f.prop('checked')) {
e.removeClass('hidden'); e.removeClass('hidden');
} else { } else {
e.addClass('hidden'); e.addClass('hidden');
@ -381,7 +382,7 @@
$(function() { $(function() {
$('form').on("submit", function(e){$('#pageloading').removeClass('hidden'); e.preventDefault(); return false;}) $('form').on("submit", function(e){$('#pageloading').removeClass('hidden'); e.preventDefault(); return false;})
}); });
showhide($('#e-tapipw'), 'apac'); showhide('e-tapipw', 'apac');
</script> </script>
</body> </body>

View File

Before

Width:  |  Height:  |  Size: 2.3 KiB

After

Width:  |  Height:  |  Size: 2.3 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 2.6 KiB

After

Width:  |  Height:  |  Size: 2.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.5 KiB

After

Width:  |  Height:  |  Size: 2.5 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.1 KiB

After

Width:  |  Height:  |  Size: 2.1 KiB

View File

Before

Width:  |  Height:  |  Size: 1.8 KiB

After

Width:  |  Height:  |  Size: 1.8 KiB

View File

Before

Width:  |  Height:  |  Size: 1.6 KiB

After

Width:  |  Height:  |  Size: 1.6 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.4 KiB

After

Width:  |  Height:  |  Size: 2.4 KiB

View File

Before

Width:  |  Height:  |  Size: 2.8 KiB

After

Width:  |  Height:  |  Size: 2.8 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.2 KiB

After

Width:  |  Height:  |  Size: 2.2 KiB

View File

Before

Width:  |  Height:  |  Size: 2.0 KiB

After

Width:  |  Height:  |  Size: 2.0 KiB

View File

Before

Width:  |  Height:  |  Size: 2.7 KiB

After

Width:  |  Height:  |  Size: 2.7 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 14 KiB

After

Width:  |  Height:  |  Size: 14 KiB

View File

Before

Width:  |  Height:  |  Size: 1.9 KiB

After

Width:  |  Height:  |  Size: 1.9 KiB

View File

Before

Width:  |  Height:  |  Size: 1.2 KiB

After

Width:  |  Height:  |  Size: 1.2 KiB

View File

Before

Width:  |  Height:  |  Size: 7.4 KiB

After

Width:  |  Height:  |  Size: 7.4 KiB

View File

Before

Width:  |  Height:  |  Size: 1.7 KiB

After

Width:  |  Height:  |  Size: 1.7 KiB

View File

Before

Width:  |  Height:  |  Size: 4.3 KiB

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 122 B

After

Width:  |  Height:  |  Size: 122 B

View File

Before

Width:  |  Height:  |  Size: 956 B

After

Width:  |  Height:  |  Size: 956 B

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 1.0 KiB

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

Before

Width:  |  Height:  |  Size: 15 KiB

After

Width:  |  Height:  |  Size: 15 KiB

View File

Before

Width:  |  Height:  |  Size: 4.6 KiB

After

Width:  |  Height:  |  Size: 4.6 KiB