PrintBuddy is born
parent
912ef576c6
commit
21c08432cd
|
|
@ -10,8 +10,8 @@
|
||||||
/**
|
/**
|
||||||
* Basic software settings
|
* Basic software settings
|
||||||
*/
|
*/
|
||||||
#define VERSION "4.0"
|
#define VERSION "1.0"
|
||||||
#define HOSTNAME "PrintMon-"
|
#define HOSTNAME "PrintBuddy-"
|
||||||
#define CONFIG "/conf.txt"
|
#define CONFIG "/conf.txt"
|
||||||
// true = Enables debug message on terminal | false = disable all debug messages
|
// true = Enables debug message on terminal | false = disable all debug messages
|
||||||
#define DEBUG_MODE_ENABLE true
|
#define DEBUG_MODE_ENABLE true
|
||||||
|
|
|
||||||
|
|
@ -58,11 +58,11 @@ void OledDisplay::showBootScreen() {
|
||||||
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
|
this->oledDisplay->setTextAlignment(TEXT_ALIGN_CENTER);
|
||||||
this->oledDisplay->setContrast(255); // default is 255
|
this->oledDisplay->setContrast(255); // default is 255
|
||||||
this->oledDisplay->setFont(ArialMT_Plain_16);
|
this->oledDisplay->setFont(ArialMT_Plain_16);
|
||||||
this->oledDisplay->drawString(64, 1, "Printer Monitor");
|
this->oledDisplay->drawString(64, 1, "PrintBuddy");
|
||||||
this->oledDisplay->setFont(ArialMT_Plain_10);
|
this->oledDisplay->setFont(ArialMT_Plain_10);
|
||||||
this->oledDisplay->drawString(64, 18, "for " + this->globalDataController->getPrinterClient()->getPrinterType());
|
this->oledDisplay->drawString(64, 18, "for " + this->globalDataController->getPrinterClient()->getPrinterType());
|
||||||
this->oledDisplay->setFont(ArialMT_Plain_16);
|
this->oledDisplay->setFont(ArialMT_Plain_16);
|
||||||
this->oledDisplay->drawString(64, 30, "By Qrome");
|
this->oledDisplay->drawString(64, 30, "By XXXXXX");
|
||||||
this->oledDisplay->drawString(64, 46, "V" + this->globalDataController->getVersion());
|
this->oledDisplay->drawString(64, 46, "V" + this->globalDataController->getVersion());
|
||||||
this->oledDisplay->display();
|
this->oledDisplay->display();
|
||||||
}
|
}
|
||||||
|
|
@ -158,7 +158,7 @@ void OledDisplay::checkDisplay() {
|
||||||
this->ui->setOverlays(clockOverlay, 1);
|
this->ui->setOverlays(clockOverlay, 1);
|
||||||
this->isClockOn = true;
|
this->isClockOn = true;
|
||||||
} else if (printerClient->isPrinting() && !printerClient->isPSUoff() && this->isClockOn) {
|
} else if (printerClient->isPrinting() && !printerClient->isPSUoff() && this->isClockOn) {
|
||||||
this->debugController->printLn("Printer Monitor is active.");
|
this->debugController->printLn("PrintBuddy is active.");
|
||||||
this->ui->setFrames(frames, 3);
|
this->ui->setFrames(frames, 3);
|
||||||
this->ui->setOverlays(overlays, 1);
|
this->ui->setOverlays(overlays, 1);
|
||||||
this->ui->enableAutoTransition();
|
this->ui->enableAutoTransition();
|
||||||
|
|
|
||||||
|
|
@ -1,12 +1,6 @@
|
||||||
#include "WebServer.h"
|
#include "WebServer.h"
|
||||||
|
|
||||||
static const char WEB_ACTIONS[] PROGMEM = "<a class='w3-bar-item w3-button' href='/'><i class='fa fa-home'></i> Home</a>"
|
|
||||||
"<a class='w3-bar-item w3-button' href='/configure'><i class='fa fa-cog'></i> Configure</a>"
|
|
||||||
"<a class='w3-bar-item w3-button' href='/configureweather'><i class='fa fa-cloud'></i> Weather</a>"
|
|
||||||
"<a class='w3-bar-item w3-button' href='/systemreset' onclick='return confirm(\"Do you want to reset to default settings?\")'><i class='fa fa-undo'></i> Reset Settings</a>"
|
|
||||||
"<a class='w3-bar-item w3-button' href='/forgetwifi' onclick='return confirm(\"Do you want to forget to WiFi connection?\")'><i class='fa fa-wifi'></i> Forget WiFi</a>"
|
|
||||||
"<a class='w3-bar-item w3-button' href='/update'><i class='fa fa-wrench'></i> Firmware Update</a>"
|
|
||||||
"<a class='w3-bar-item w3-button' href='https://github.com/Qrome' target='_blank'><i class='fa fa-question-circle'></i> About</a>";
|
|
||||||
|
|
||||||
String CHANGE_FORM = ""; // moved to config to make it dynamic
|
String CHANGE_FORM = ""; // moved to config to make it dynamic
|
||||||
|
|
||||||
|
|
@ -111,8 +105,10 @@ void WebServer::setup() {
|
||||||
this->server->on("/updateweatherconfig", []() { obj->handleUpdateWeather(); });
|
this->server->on("/updateweatherconfig", []() { obj->handleUpdateWeather(); });
|
||||||
this->server->on("/configure", []() { obj->handleConfigure(); });
|
this->server->on("/configure", []() { obj->handleConfigure(); });
|
||||||
this->server->on("/configureweather", []() { obj->handleWeatherConfigure(); });
|
this->server->on("/configureweather", []() { obj->handleWeatherConfigure(); });
|
||||||
|
this->server->on("/update", HTTP_GET, []() { obj->handleUpdatePage(); });
|
||||||
this->server->onNotFound([]() { obj->redirectHome(); });
|
this->server->onNotFound([]() { obj->redirectHome(); });
|
||||||
this->serverUpdater->setup(this->server, "/update", this->globalDataController->getWebserverUsername(), this->globalDataController->getWebserverPassword());
|
this->serverUpdater->setup(this->server, "/update", this->globalDataController->getWebserverUsername(), this->globalDataController->getWebserverPassword());
|
||||||
|
|
||||||
|
|
||||||
// Start the server
|
// Start the server
|
||||||
this->server->begin();
|
this->server->begin();
|
||||||
|
|
@ -146,16 +142,10 @@ void WebServer::redirectHome() {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebServer::displayPrinterStatus() {
|
void WebServer::displayPrinterStatus() {
|
||||||
this->globalDataController->ledOnOff(true);
|
|
||||||
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
|
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
|
||||||
String html = "";
|
String html = "";
|
||||||
|
|
||||||
this->server->sendHeader("Cache-Control", "no-cache, no-store");
|
WebserverMemoryVariables::sendHeader(this->server, this->globalDataController, "Status", "Monitor", true);
|
||||||
this->server->sendHeader("Pragma", "no-cache");
|
|
||||||
this->server->sendHeader("Expires", "-1");
|
|
||||||
this->server->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
|
||||||
this->server->send(200, "text/html", "");
|
|
||||||
this->server->sendContent(String(getHeader(true)));
|
|
||||||
|
|
||||||
String displayTime =
|
String displayTime =
|
||||||
this->globalDataController->getTimeClient()->getAmPmHours() + ":" +
|
this->globalDataController->getTimeClient()->getAmPmHours() + ":" +
|
||||||
|
|
@ -259,10 +249,7 @@ void WebServer::displayPrinterStatus() {
|
||||||
html = ""; // fresh start
|
html = ""; // fresh start
|
||||||
}
|
}
|
||||||
|
|
||||||
this->server->sendContent(String(getFooter()));
|
WebserverMemoryVariables::sendFooter(this->server, this->globalDataController);
|
||||||
this->server->sendContent("");
|
|
||||||
this->server->client().stop();
|
|
||||||
this->globalDataController->ledOnOff(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void WebServer::handleSystemReset() {
|
void WebServer::handleSystemReset() {
|
||||||
|
|
@ -383,51 +370,76 @@ void WebServer::handleConfigure() {
|
||||||
if (!this->authentication()) {
|
if (!this->authentication()) {
|
||||||
return this->server->requestAuthentication();
|
return this->server->requestAuthentication();
|
||||||
}
|
}
|
||||||
this->globalDataController->ledOnOff(true);
|
|
||||||
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
|
BasePrinterClient *printerClient = this->globalDataController->getPrinterClient();
|
||||||
String html = "";
|
String html = "";
|
||||||
|
|
||||||
|
WebserverMemoryVariables::sendHeader(this->server, this->globalDataController, "Configure", "Station");
|
||||||
|
|
||||||
this->server->sendHeader("Cache-Control", "no-cache, no-store");
|
|
||||||
this->server->sendHeader("Pragma", "no-cache");
|
|
||||||
this->server->sendHeader("Expires", "-1");
|
|
||||||
this->server->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
|
||||||
this->server->send(200, "text/html", "");
|
|
||||||
|
|
||||||
html = this->getHeader();
|
// send javascript functions for repetier server test
|
||||||
|
html = "<script>function testRepetier(){var e=document.getElementById(\"RepetierTest\"),r=document.getElementById(\"PrinterAddress\").value,"
|
||||||
|
"t=document.getElementById(\"PrinterPort\").value;if(\"\"==r||\"\"==t)return e.innerHTML=\"* Address and Port are required\","
|
||||||
|
"void(e.style.background=\"\");var n=\"http://\"+r+\":\"+t;n+=\"/printer/api/?a=listPrinter&apikey=\"+document.getElementById(\"PrinterApiKey\").value,"
|
||||||
|
"console.log(n);var o=new XMLHttpRequest;o.open(\"GET\",n,!0),o.onload=function(){if(200===o.status){var r=JSON.parse(o.responseText);"
|
||||||
|
"if(!r.error&&r.length>0){var t=\"<label>Connected -- Select Printer</label> \";t+=\"<select class='w3-option w3-padding' name='printer'>\";"
|
||||||
|
"var n=document.getElementById(\"selectedPrinter\").value,i=\"\";for(printer in r)i=r[printer].slug==n?\"selected\":\"\","
|
||||||
|
"t+=\"<option value='\"+r[printer].slug+\"' \"+i+\">\"+r[printer].name+\"</option>\";t+=\"</select>\","
|
||||||
|
"e.innerHTML=t,e.style.background=\"lime\"}else e.innerHTML=\"Error invalid API Key: \"+r.error,"
|
||||||
|
"e.style.background=\"red\"}else e.innerHTML=\"Error: \"+o.statusText,e.style.background=\"red\"},"
|
||||||
|
"o.onerror=function(){e.innerHTML=\"Error connecting to server -- check IP and Port\",e.style.background=\"red\"},o.send(null)}</script>";
|
||||||
this->server->sendContent(html);
|
this->server->sendContent(html);
|
||||||
|
|
||||||
// send javascript functions
|
// send javascript functions for klipper test
|
||||||
if (printerClient->getPrinterType() == "Repetier") {
|
html = "<script>function testKlipper(){var e=document.getElementById(\"KlipperTest\"),t=document.getElementById(\"PrinterAddress\").value,"
|
||||||
html = "<script>function testRepetier(){var e=document.getElementById(\"RepetierTest\"),r=document.getElementById(\"PrinterAddress\").value,"
|
"n=document.getElementById(\"PrinterPort\").value;if(e.innerHTML=\"\",\"\"==t||\"\"==n)return e.innerHTML=\"* Address and Port are required\","
|
||||||
"t=document.getElementById(\"PrinterPort\").value;if(\"\"==r||\"\"==t)return e.innerHTML=\"* Address and Port are required\","
|
"void(e.style.background=\"\");var r=\"http://\"+t+\":\"+n;r+=\"/printer/info\",window.open(r,\"_blank\").focus()}</script>";
|
||||||
"void(e.style.background=\"\");var n=\"http://\"+r+\":\"+t;n+=\"/printer/api/?a=listPrinter&apikey=\"+document.getElementById(\"PrinterApiKey\").value,"
|
this->server->sendContent(html);
|
||||||
"console.log(n);var o=new XMLHttpRequest;o.open(\"GET\",n,!0),o.onload=function(){if(200===o.status){var r=JSON.parse(o.responseText);"
|
|
||||||
"if(!r.error&&r.length>0){var t=\"<label>Connected -- Select Printer</label> \";t+=\"<select class='w3-option w3-padding' name='printer'>\";"
|
// send javascript functions for octoprint test
|
||||||
"var n=document.getElementById(\"selectedPrinter\").value,i=\"\";for(printer in r)i=r[printer].slug==n?\"selected\":\"\","
|
html = "<script>function testOctoPrint(){var e=document.getElementById(\"OctoPrintTest\"),t=document.getElementById(\"PrinterAddress\").value,"
|
||||||
"t+=\"<option value='\"+r[printer].slug+\"' \"+i+\">\"+r[printer].name+\"</option>\";t+=\"</select>\","
|
"n=document.getElementById(\"PrinterPort\").value;if(e.innerHTML=\"\",\"\"==t||\"\"==n)return e.innerHTML=\"* Address and Port are required\","
|
||||||
"e.innerHTML=t,e.style.background=\"lime\"}else e.innerHTML=\"Error invalid API Key: \"+r.error,"
|
"void(e.style.background=\"\");var r=\"http://\"+t+\":\"+n;r+=\"/api/job?apikey=\"+document.getElementById(\"PrinterApiKey\").value,window.open(r,\"_blank\").focus()}</script>";
|
||||||
"e.style.background=\"red\"}else e.innerHTML=\"Error: \"+o.statusText,e.style.background=\"red\"},"
|
this->server->sendContent(html);
|
||||||
"o.onerror=function(){e.innerHTML=\"Error connecting to server -- check IP and Port\",e.style.background=\"red\"},o.send(null)}</script>";
|
|
||||||
|
// Let us create a form for all printers
|
||||||
this->server->sendContent(html);
|
html = "<form class='w3-container' action='/updateconfig' method='get'><h2>Station Config:</h2>";
|
||||||
}
|
html += "<table id='printerData' class='table table-striped table-condensed'></table><script>var target ='#printerData'; var customFields = { data: {";
|
||||||
else if (printerClient->getPrinterType() == "Klipper") {
|
this->server->sendContent(html);
|
||||||
html = "<script>function testKlipper(){var e=document.getElementById(\"KlipperTest\"),t=document.getElementById(\"PrinterAddress\").value,"
|
|
||||||
"n=document.getElementById(\"PrinterPort\").value;if(e.innerHTML=\"\",\"\"==t||\"\"==n)return e.innerHTML=\"* Address and Port are required\","
|
for (int i=0; i<10; i++) {
|
||||||
"void(e.style.background=\"\");var r=\"http://\"+t+\":\"+n;r+=\"/printer/info\",window.open(r,\"_blank\").focus()}</script>";
|
html = "";
|
||||||
this->server->sendContent(html);
|
if (i > 0) {
|
||||||
}
|
html = ",";
|
||||||
else {
|
}
|
||||||
html = "<script>function testOctoPrint(){var e=document.getElementById(\"OctoPrintTest\"),t=document.getElementById(\"PrinterAddress\").value,"
|
html += String(i + 1) + ": { enabled:true, fieldName:'COMPANYCODE',prettyName:'Company Name', fieldType:'OEM', fieldValue:'' }";
|
||||||
"n=document.getElementById(\"PrinterPort\").value;if(e.innerHTML=\"\",\"\"==t||\"\"==n)return e.innerHTML=\"* Address and Port are required\","
|
|
||||||
"void(e.style.background=\"\");var r=\"http://\"+t+\":\"+n;r+=\"/api/job?apikey=\"+document.getElementById(\"PrinterApiKey\").value,window.open(r,\"_blank\").focus()}</script>";
|
|
||||||
this->server->sendContent(html);
|
this->server->sendContent(html);
|
||||||
}
|
}
|
||||||
|
html = "},";
|
||||||
|
html += "xref: { // Key ['Label','column width',0|1] 1=admin only";
|
||||||
|
html += " custom: ['#','10%',0],";
|
||||||
|
html += " actions: ['Actions','5%',1],";
|
||||||
|
html += " enabled: ['Enabled','5%',0],";
|
||||||
|
html += " fieldName: ['Field','20%',0],";
|
||||||
|
html += " prettyName: ['Pretty Name','20%',0],";
|
||||||
|
html += " fieldType: ['Type','30%',0],";
|
||||||
|
html += " fieldValue: ['Value','10%',0]";
|
||||||
|
html += "},";
|
||||||
|
html += "fieldTypes: [";
|
||||||
|
html += " [' ',' '],";
|
||||||
|
html += " ['ENV','Environment (ENV)'],";
|
||||||
|
html += " ['REG','Registry (REG)'],";
|
||||||
|
html += " ['WMI','Windows Management Inst. (WMI)'],";
|
||||||
|
html += " ['OEM','Original Equipment Manuf.(OEM)']";
|
||||||
|
html += "],";
|
||||||
|
html += "admin:true,";
|
||||||
|
html += "multiedit:false";
|
||||||
|
html += "}";
|
||||||
|
html += "</script>";
|
||||||
|
this->server->sendContent(html);
|
||||||
|
|
||||||
|
|
||||||
String form = "<form class='w3-container' action='/updateconfig' method='get'><h2>Station Config:</h2>";
|
|
||||||
|
|
||||||
|
|
||||||
|
String form = "";
|
||||||
if (printerClient->getPrinterType() != "Klipper") {
|
if (printerClient->getPrinterType() != "Klipper") {
|
||||||
form += "<p><label>" + printerClient->getPrinterType() + " API Key (get from your server)</label>"
|
form += "<p><label>" + printerClient->getPrinterType() + " API Key (get from your server)</label>"
|
||||||
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='PrinterApiKey' id='PrinterApiKey' value='%PRINTERAPIKEY%' maxlength='60'></p>";
|
"<input class='w3-input w3-border w3-margin-bottom' type='text' name='PrinterApiKey' id='PrinterApiKey' value='%PRINTERAPIKEY%' maxlength='60'></p>";
|
||||||
|
|
@ -508,28 +520,36 @@ void WebServer::handleConfigure() {
|
||||||
|
|
||||||
this->server->sendContent(form);
|
this->server->sendContent(form);
|
||||||
|
|
||||||
html = this->getFooter();
|
WebserverMemoryVariables::sendFooter(this->server, this->globalDataController);
|
||||||
this->server->sendContent(html);
|
|
||||||
this->server->sendContent("");
|
|
||||||
this->server->client().stop();
|
|
||||||
this->globalDataController->ledOnOff(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send weather configuration page to client
|
||||||
|
*/
|
||||||
void WebServer::handleWeatherConfigure() {
|
void WebServer::handleWeatherConfigure() {
|
||||||
if (!this->authentication()) {
|
if (!this->authentication()) {
|
||||||
return this->server->requestAuthentication();
|
return this->server->requestAuthentication();
|
||||||
}
|
}
|
||||||
this->globalDataController->ledOnOff(true);
|
WebserverMemoryVariables::sendHeader(this->server, this->globalDataController, "Configure", "Weather");
|
||||||
|
|
||||||
String html = "";
|
String html = "";
|
||||||
|
|
||||||
this->server->sendHeader("Cache-Control", "no-cache, no-store");
|
|
||||||
this->server->sendHeader("Pragma", "no-cache");
|
|
||||||
this->server->sendHeader("Expires", "-1");
|
|
||||||
this->server->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
|
||||||
this->server->send(200, "text/html", "");
|
|
||||||
|
|
||||||
html = getHeader();
|
|
||||||
this->server->sendContent(html);
|
|
||||||
|
|
||||||
String form = FPSTR(WEATHER_FORM);
|
String form = FPSTR(WEATHER_FORM);
|
||||||
String isWeatherChecked = "";
|
String isWeatherChecked = "";
|
||||||
|
|
@ -550,61 +570,18 @@ void WebServer::handleWeatherConfigure() {
|
||||||
form.replace("%LANGUAGEOPTIONS%", options);
|
form.replace("%LANGUAGEOPTIONS%", options);
|
||||||
this->server->sendContent(form);
|
this->server->sendContent(form);
|
||||||
|
|
||||||
html = this->getFooter();
|
|
||||||
this->server->sendContent(html);
|
WebserverMemoryVariables::sendFooter(this->server, this->globalDataController);
|
||||||
this->server->sendContent("");
|
|
||||||
this->server->client().stop();
|
|
||||||
this->globalDataController->ledOnOff(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String WebServer::getHeader() {
|
/**
|
||||||
return this->getHeader(false);
|
* @brief Send firmware/filesystem update page to client
|
||||||
}
|
*/
|
||||||
|
void WebServer::handleUpdatePage() {
|
||||||
String WebServer::getHeader(boolean refresh) {
|
if (!this->authentication()) {
|
||||||
String menu = FPSTR(WEB_ACTIONS);
|
return this->server->requestAuthentication();
|
||||||
|
|
||||||
String html = "<!DOCTYPE HTML>";
|
|
||||||
html += "<html><head><title>Printer Monitor</title><link rel='icon' href='data:;base64,='>";
|
|
||||||
html += "<meta charset='UTF-8'>";
|
|
||||||
html += "<meta name='viewport' content='width=device-width, initial-scale=1'>";
|
|
||||||
if (refresh) {
|
|
||||||
html += "<meta http-equiv=\"refresh\" content=\"30\">";
|
|
||||||
}
|
}
|
||||||
html += "<link rel='stylesheet' href='https://www.w3schools.com/w3css/4/w3.css'>";
|
WebserverMemoryVariables::sendHeader(this->server, this->globalDataController, "Firmware", "Update");
|
||||||
html += "<link rel='stylesheet' href='https://www.w3schools.com/lib/w3-theme-" + this->globalDataController->getWebserverTheme() + ".css'>";
|
WebserverMemoryVariables::sendUpdateForm(this->server, this->globalDataController);
|
||||||
html += "<link rel='stylesheet' href='https://cdnjs.cloudflare.com/ajax/libs/font-awesome/4.7.0/css/font-awesome.min.css'>";
|
WebserverMemoryVariables::sendFooter(this->server, this->globalDataController);
|
||||||
html += "</head><body>";
|
|
||||||
html += "<nav class='w3-sidebar w3-bar-block w3-card' style='margin-top:88px' id='mySidebar'>";
|
|
||||||
html += "<div class='w3-container w3-theme-d2'>";
|
|
||||||
html += "<span onclick='closeSidebar()' class='w3-button w3-display-topright w3-large'><i class='fa fa-times'></i></span>";
|
|
||||||
html += "<div class='w3-cell w3-left w3-xxxlarge' style='width:60px'><i class='fa fa-cube'></i></div>";
|
|
||||||
html += "<div class='w3-padding'>Menu</div></div>";
|
|
||||||
html += menu;
|
|
||||||
html += "</nav>";
|
|
||||||
html += "<header class='w3-top w3-bar w3-theme'><button class='w3-bar-item w3-button w3-xxxlarge w3-hover-theme' onclick='openSidebar()'><i class='fa fa-bars'></i></button><h2 class='w3-bar-item'>Printer Monitor</h2></header>";
|
|
||||||
html += "<script>";
|
|
||||||
html += "function openSidebar(){document.getElementById('mySidebar').style.display='block'}function closeSidebar(){document.getElementById('mySidebar').style.display='none'}closeSidebar();";
|
|
||||||
html += "</script>";
|
|
||||||
html += "<br><div class='w3-container w3-large' style='margin-top:88px'>";
|
|
||||||
return html;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
String WebServer::getFooter() {
|
|
||||||
int8_t rssi = this->globalDataController->getWifiQuality();
|
|
||||||
Serial.print("Signal Strength (RSSI): ");
|
|
||||||
Serial.print(rssi);
|
|
||||||
this->debugController->printLn("%");
|
|
||||||
String html = "<br><br><br>";
|
|
||||||
html += "</div>";
|
|
||||||
html += "<footer class='w3-container w3-bottom w3-theme w3-margin-top'>";
|
|
||||||
if (this->globalDataController->getLastReportStatus() != "") {
|
|
||||||
html += "<i class='fa fa-external-link'></i> Report Status: " + this->globalDataController->getLastReportStatus() + "<br>";
|
|
||||||
}
|
|
||||||
html += "<i class='fa fa-paper-plane-o'></i> Version: " + String(VERSION) + "<br>";
|
|
||||||
html += "<i class='fa fa-rss'></i> Signal Strength: ";
|
|
||||||
html += String(rssi) + "%";
|
|
||||||
html += "</footer>";
|
|
||||||
html += "</body></html>";
|
|
||||||
return html;
|
|
||||||
}
|
|
||||||
|
|
@ -1,11 +1,11 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#include <Arduino.h>
|
#include <Arduino.h>
|
||||||
#include <ESP8266WiFi.h>
|
#include <ESP8266WiFi.h>
|
||||||
#include <ESP8266WebServer.h>
|
|
||||||
#include <ESP8266HTTPUpdateServer.h>
|
#include <ESP8266HTTPUpdateServer.h>
|
||||||
#include <WiFiManager.h>
|
#include <WiFiManager.h>
|
||||||
#include <ESP8266mDNS.h>
|
#include <ESP8266mDNS.h>
|
||||||
#include "../Global/GlobalDataController.h"
|
#include "../Global/GlobalDataController.h"
|
||||||
|
#include "WebserverMemoryVariables.h"
|
||||||
|
|
||||||
class WebServer {
|
class WebServer {
|
||||||
private:
|
private:
|
||||||
|
|
@ -29,7 +29,5 @@ public:
|
||||||
void handleUpdateWeather();
|
void handleUpdateWeather();
|
||||||
void handleConfigure();
|
void handleConfigure();
|
||||||
void handleWeatherConfigure();
|
void handleWeatherConfigure();
|
||||||
String getHeader();
|
void handleUpdatePage();
|
||||||
String getHeader(boolean refresh);
|
|
||||||
String getFooter();
|
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,111 @@
|
||||||
|
#include "WebserverMemoryVariables.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send out header for webpage
|
||||||
|
* @param server Send out instancce
|
||||||
|
* @param globalDataController Access to global data
|
||||||
|
*/
|
||||||
|
void WebserverMemoryVariables::sendHeader(ESP8266WebServer *server, GlobalDataController *globalDataController, String pageLabel, String pageTitle) {
|
||||||
|
WebserverMemoryVariables::sendHeader(server, globalDataController, pageLabel, pageTitle, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send out header for webpage
|
||||||
|
* @param server Send out instancce
|
||||||
|
* @param globalDataController Access to global data
|
||||||
|
* @param pageLabel Title label
|
||||||
|
* @param pageTitle Title
|
||||||
|
* @param refresh if true, auto refresh in header is set
|
||||||
|
*/
|
||||||
|
void WebserverMemoryVariables::sendHeader(
|
||||||
|
ESP8266WebServer *server,
|
||||||
|
GlobalDataController *globalDataController,
|
||||||
|
String pageLabel,
|
||||||
|
String pageTitle,
|
||||||
|
boolean refresh
|
||||||
|
) {
|
||||||
|
globalDataController->ledOnOff(true);
|
||||||
|
int8_t rssi = globalDataController->getWifiQuality();
|
||||||
|
|
||||||
|
server->sendHeader("Cache-Control", "no-cache, no-store");
|
||||||
|
server->sendHeader("Pragma", "no-cache");
|
||||||
|
server->sendHeader("Expires", "-1");
|
||||||
|
server->setContentLength(CONTENT_LENGTH_UNKNOWN);
|
||||||
|
server->send(200, "text/html", "");
|
||||||
|
|
||||||
|
server->sendContent("<!DOCTYPE HTML>"
|
||||||
|
"<html><head><title>PrintBuddy</title><link rel='icon' href='data:;base64,='>"
|
||||||
|
"<meta charset='UTF-8'>"
|
||||||
|
"<meta name='viewport' content='width=device-width, initial-scale=1'>"
|
||||||
|
);
|
||||||
|
if (refresh) {
|
||||||
|
server->sendContent("<meta http-equiv=\"refresh\" content=\"30\">");
|
||||||
|
}
|
||||||
|
server->sendContent("<link rel='stylesheet' href='https://www.w3schools.com/w3css/4/w3.css'>"
|
||||||
|
"<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'>"
|
||||||
|
"<script src='https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js'></script>"
|
||||||
|
"<style>.hidden{display:none}</style>"
|
||||||
|
"</head><body>"
|
||||||
|
"<header class='cv-header bx--header'>"
|
||||||
|
"<a href='/' class='cv-header-name bx--header__name'>"
|
||||||
|
);
|
||||||
|
server->sendContent("<span class='bx--header__name--prefix'>PrintBuddy </span>V" + String(VERSION));
|
||||||
|
server->sendContent("</a>"
|
||||||
|
"<nav class='cv-header-nav bx--header__nav'></nav>"
|
||||||
|
"<div class='bx--header__global'>"
|
||||||
|
"<button type='button' class='cv-header-global-action bx--header__action' onclick='openWifiInfo()'>"
|
||||||
|
"<i class='fas fa-wifi' style='color: white; font-size: 20px;'></i>"
|
||||||
|
"</button>"
|
||||||
|
"<button type='button' class='cv-header-global-action bx--header__action' onclick='openSidebar()'>"
|
||||||
|
"<svg focusable='false' preserveAspectRatio='xMidYMid meet' xmlns='http://www.w3.org/2000/svg' fill='currentColor' width='20' height='20' viewBox='0 0 32 32' aria-hidden='true'>"
|
||||||
|
"<path d='M14 4H18V8H14zM4 4H8V8H4zM24 4H28V8H24zM14 14H18V18H14zM4 14H8V18H4zM24 14H28V18H24zM14 24H18V28H14zM4 24H8V28H4zM24 24H28V28H24z'></path>"
|
||||||
|
"</svg>"
|
||||||
|
"</button>"
|
||||||
|
"</div>"
|
||||||
|
"<div id='sidebar' class='cv-header-panel bx--header-panel'>"
|
||||||
|
"<ul class='cv-switcher bx--switcher__item'>"
|
||||||
|
);
|
||||||
|
server->sendContent(String(FPSTR(MENUE_ITEMS)));
|
||||||
|
server->sendContent("</ul>"
|
||||||
|
"</div>"
|
||||||
|
"<div class='bx--toast-notification bx--toast-notification--info hidden' style='position: absolute; right: -16px; top: 40px;' id='wifiinfo'>"
|
||||||
|
"<div class='bx--toast-notification__details'>"
|
||||||
|
"<h3 class='bx--toast-notification__title'>WiFi Signal Strength</h3>"
|
||||||
|
"<div class='bx--toast-notification__subtitle'><span>"
|
||||||
|
);
|
||||||
|
server->sendContent(String(rssi) + "%");
|
||||||
|
server->sendContent("</span></div>"
|
||||||
|
"</div>"
|
||||||
|
"</div>"
|
||||||
|
"</header>"
|
||||||
|
"<script>function openSidebar(){document.getElementById('sidebar').classList.toggle('bx--header-panel--expanded');document.getElementById('wifiinfo').classList.add('hidden');};function openWifiInfo(){document.getElementById('sidebar').classList.remove('bx--header-panel--expanded');document.getElementById('wifiinfo').classList.toggle('hidden');}</script>"
|
||||||
|
"<br><div class='bx--grid bx--grid--full-width' style='margin-top:60px'>"
|
||||||
|
"<div class='page-header' style='margin-bottom:20px'><h4 class='page-header__label'>");
|
||||||
|
server->sendContent(pageLabel);
|
||||||
|
server->sendContent("</h4><h1 id='page-title' class='page-header__title'>");
|
||||||
|
server->sendContent(pageTitle);
|
||||||
|
server->sendContent("</h1></div><div class='bx--row'>");
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief send out footer content for webpage
|
||||||
|
* @param server Send out instancce
|
||||||
|
* @param globalDataController Access to global data
|
||||||
|
*/
|
||||||
|
void WebserverMemoryVariables::sendFooter(ESP8266WebServer *server, GlobalDataController *globalDataController) {
|
||||||
|
server->sendContent("<br><br><br></div></div>");
|
||||||
|
server->sendContent("<script src='https://unpkg.com/carbon-components/scripts/carbon-components.min.js'></script></body></html>");
|
||||||
|
server->sendContent("");
|
||||||
|
server->client().stop();
|
||||||
|
globalDataController->ledOnOff(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Send out upload form for updates
|
||||||
|
* @param server Send out instancce
|
||||||
|
* @param globalDataController Access to global data
|
||||||
|
*/
|
||||||
|
void WebserverMemoryVariables::sendUpdateForm(ESP8266WebServer *server, GlobalDataController *globalDataController) {
|
||||||
|
server->sendContent(FPSTR(UPDATE_FORM));
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,69 @@
|
||||||
|
#pragma once
|
||||||
|
#include <Arduino.h>
|
||||||
|
#include <ESP8266WiFi.h>
|
||||||
|
#include <ESP8266WebServer.h>
|
||||||
|
#include "../Global/GlobalDataController.h"
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Webpage side menu right for main items
|
||||||
|
*/
|
||||||
|
static const char MENUE_ITEMS[] PROGMEM =
|
||||||
|
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link' href='/'><i class='fa fa-home'></i> Home</a></li>"
|
||||||
|
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link' href='/configure'><i class='fa fa-cog'></i> Configure</a></li>"
|
||||||
|
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link' href='/configureweather'><i class='fa fa-cloud'></i> Weather</a></li>"
|
||||||
|
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link' href='/systemreset' onclick='return confirm(\"Do you want to reset to default settings?\")'><i class='fa fa-undo'></i> Reset Settings</a></li>"
|
||||||
|
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link' href='/forgetwifi' onclick='return confirm(\"Do you want to forget to WiFi connection?\")'><i class='fa fa-wifi'></i> Forget WiFi</a></li>"
|
||||||
|
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link' href='/update'><i class='fa fa-wrench'></i> Firmware Update</a></li>"
|
||||||
|
"<li class='cv-switcher-item bx--switcher__item'><a class='cv-switcher-item-link bx--switcher__item-link' href='https://github.com/Qrome' target='_blank'><i class='fa fa-question-circle'></i> About</a></li>";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Controls for update firmware/filesystem
|
||||||
|
*/
|
||||||
|
static const char UPDATE_FORM[] PROGMEM = "<div class='bx--col-md-4'>"
|
||||||
|
"<form method='POST' action='' enctype='multipart/form-data'>"
|
||||||
|
"<div class='cv-file-uploader cv-form-item bx--form-item'>"
|
||||||
|
"<strong class='bx--file--label'>Update Firmware</strong>"
|
||||||
|
"<p class='bx--label-description'>Select the firmware you want to upload</p>"
|
||||||
|
"<div data-file='' class='bx--file'>"
|
||||||
|
"<label for='firmware' role='button' tabindex='0' class='bx--file-browse-btn'>"
|
||||||
|
"<div data-file-drop-container='' class='bx--file__drop-container'>"
|
||||||
|
"Drag and drop file here or upload"
|
||||||
|
"<input type='file' id='firmware' accept='.bin,.bin.gz' class='bx--file-input' name='firmware' onchange='document.getElementById(\"ffile\").innerHTML = \"\"'>"
|
||||||
|
"</div>"
|
||||||
|
"</label>"
|
||||||
|
"<div data-file-container='' class='bx--file-container' id='ffile'></div>"
|
||||||
|
"</div>"
|
||||||
|
"</div>"
|
||||||
|
"<input type='submit' value='Update Firmware' class='bx--btn bx--btn--danger'>"
|
||||||
|
"</form>"
|
||||||
|
"</div>"
|
||||||
|
"<div class='bx--col-md-4'>"
|
||||||
|
"<form method='POST' action='' enctype='multipart/form-data'>"
|
||||||
|
"<div class='cv-file-uploader cv-form-item bx--form-item'>"
|
||||||
|
"<strong class='bx--file--label'>Update FileSystem</strong>"
|
||||||
|
"<p class='bx--label-description'>Select the filesystem you want to upload</p>"
|
||||||
|
"<div data-file='' class='bx--file'>"
|
||||||
|
"<label for='filesystem' role='button' tabindex='0' class='bx--file-browse-btn'>"
|
||||||
|
"<div data-file-drop-container='' class='bx--file__drop-container'>"
|
||||||
|
"Drag and drop file here or upload"
|
||||||
|
"<input type='file' id='filesystem' accept='.bin,.bin.gz' class='bx--file-input' name='filesystem' onchange='document.getElementById(\"fsys\").innerHTML = \"\"'>"
|
||||||
|
"</div>"
|
||||||
|
"</label>"
|
||||||
|
"<div data-file-container='' class='bx--file-container' id='fsys'></div>"
|
||||||
|
"</div>"
|
||||||
|
"</div>"
|
||||||
|
"<input type='submit' value='Update FileSystem' class='bx--btn bx--btn--danger'>"
|
||||||
|
"</form>"
|
||||||
|
"</div>";
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Class to generate HTML content from Memory
|
||||||
|
*/
|
||||||
|
class WebserverMemoryVariables {
|
||||||
|
public:
|
||||||
|
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 sendFooter(ESP8266WebServer *server, GlobalDataController *globalDataController);
|
||||||
|
|
||||||
|
static void sendUpdateForm(ESP8266WebServer *server, GlobalDataController *globalDataController);
|
||||||
|
};
|
||||||
Loading…
Reference in New Issue