From 4f0d365211af8d8b8afc7b83bb1158e6e14e4cd2 Mon Sep 17 00:00:00 2001 From: lumapu Date: Sat, 25 Feb 2023 01:40:25 +0100 Subject: [PATCH] improved html and navi, navi is visible even when API dies #660 reduced maximum allowed JSON size for API to 6000Bytes #660 small fix: output command at `prepareDevInformCmd` #692 improved inverter handling for MQTT #671 --- .gitignore | 1 + src/CHANGES.md | 6 ++ src/app.cpp | 15 ++-- src/config/settings.h | 2 +- src/defines.h | 2 +- src/hm/hmPayload.h | 3 +- src/publisher/pubMqtt.h | 99 +++++++++++++++------------ src/web/RestApi.h | 61 ++--------------- src/web/html/api.js | 27 ++++---- src/web/html/convert.py | 110 ++++++++++++++++++++++++++---- src/web/html/includes/footer.html | 16 +++++ src/web/html/includes/header.html | 3 + src/web/html/includes/nav.html | 27 ++++++++ src/web/html/index.html | 61 +++-------------- src/web/html/login.html | 25 +------ src/web/html/serial.html | 35 ++-------- src/web/html/setup.html | 39 ++--------- src/web/html/style.css | 8 ++- src/web/html/system.html | 35 ++-------- src/web/html/update.html | 43 ++---------- src/web/html/visualization.html | 36 ++-------- 21 files changed, 278 insertions(+), 376 deletions(-) create mode 100644 src/web/html/includes/footer.html create mode 100644 src/web/html/includes/header.html create mode 100644 src/web/html/includes/nav.html diff --git a/.gitignore b/.gitignore index ed5e95383..d6a358600 100644 --- a/.gitignore +++ b/.gitignore @@ -6,6 +6,7 @@ .vscode/extensions.json src/config/config_override.h src/web/html/h/* +src/web/html/tmp/* /**/Debug /**/v16/* *.db diff --git a/src/CHANGES.md b/src/CHANGES.md index 38f7a57e7..678e872c6 100644 --- a/src/CHANGES.md +++ b/src/CHANGES.md @@ -2,6 +2,12 @@ (starting from release version `0.5.66`) +## 0.5.91 +* improved html and navi, navi is visible even when API dies #660 +* reduced maximum allowed JSON size for API to 6000Bytes #660 +* small fix: output command at `prepareDevInformCmd` #692 +* improved inverter handling #671 + ## 0.5.90 * merged PR #684, #698, #705 * webserial minor overflow fix #660 diff --git a/src/app.cpp b/src/app.cpp index f3b175b6b..4847b512a 100644 --- a/src/app.cpp +++ b/src/app.cpp @@ -21,12 +21,6 @@ void app::setup() { resetSystem(); - /*DBGPRINTLN("--- start"); - DBGPRINTLN(String(ESP.getFreeHeap())); - DBGPRINTLN(String(ESP.getHeapFragmentation())); - DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/ - - mSettings.setup(); mSettings.getPtr(mConfig); DPRINT(DBG_INFO, F("Settings valid: ")); @@ -50,6 +44,7 @@ void app::setup() { #endif mSys.addInverters(&mConfig->inst); + mPayload.setup(this, &mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mPayload.enableSerialDebug(mConfig->serial.debug); mPayload.addPayloadListener(std::bind(&app::payloadEventListener, this, std::placeholders::_1)); @@ -57,10 +52,10 @@ void app::setup() { mMiPayload.setup(this, &mSys, &mStat, mConfig->nrf.maxRetransPerPyld, &mTimestamp); mMiPayload.enableSerialDebug(mConfig->serial.debug); - /*DBGPRINTLN("--- after payload"); + DBGPRINTLN("--- after payload"); DBGPRINTLN(String(ESP.getFreeHeap())); DBGPRINTLN(String(ESP.getHeapFragmentation())); - DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/ + DBGPRINTLN(String(ESP.getMaxFreeBlockSize())); if(!mSys.Radio.isChipConnected()) DPRINTLN(DBG_WARN, F("WARNING! your NRF24 module can't be reached, check the wiring")); @@ -90,10 +85,10 @@ void app::setup() { regularTickers(); - /*DBGPRINTLN("--- end setup"); + DBGPRINTLN("--- end setup"); DBGPRINTLN(String(ESP.getFreeHeap())); DBGPRINTLN(String(ESP.getHeapFragmentation())); - DBGPRINTLN(String(ESP.getMaxFreeBlockSize()));*/ + DBGPRINTLN(String(ESP.getMaxFreeBlockSize())); } //----------------------------------------------------------------------------- diff --git a/src/config/settings.h b/src/config/settings.h index 527dea72b..0528a9028 100644 --- a/src/config/settings.h +++ b/src/config/settings.h @@ -250,7 +250,7 @@ class settings { return false; } - DynamicJsonDocument json(4500); + DynamicJsonDocument json(5500); JsonObject root = json.to(); jsonWifi(root.createNestedObject(F("wifi")), true); jsonNrf(root.createNestedObject(F("nrf")), true); diff --git a/src/defines.h b/src/defines.h index 36471ae09..8bd4a04a4 100644 --- a/src/defines.h +++ b/src/defines.h @@ -13,7 +13,7 @@ //------------------------------------- #define VERSION_MAJOR 0 #define VERSION_MINOR 5 -#define VERSION_PATCH 90 +#define VERSION_PATCH 91 //------------------------------------- typedef struct { diff --git a/src/hm/hmPayload.h b/src/hm/hmPayload.h index 7a05bee36..245a769e6 100644 --- a/src/hm/hmPayload.h +++ b/src/hm/hmPayload.h @@ -157,7 +157,8 @@ class HmPayload { uint8_t cmd = iv->getQueuedCmd(); DPRINT(DBG_INFO, F("(#")); DBGPRINT(String(iv->id)); - DBGPRINT(F(") prepareDevInformCmd")); // + String(cmd, HEX)); + DBGPRINT(F(") prepareDevInformCmd 0x")); + DBGPRINTLN(String(cmd, HEX)); mSys->Radio.prepareDevInformCmd(iv->radioId.u64, cmd, mPayload[iv->id].ts, iv->alarmMesIndex, false); mPayload[iv->id].txCmd = cmd; } diff --git a/src/publisher/pubMqtt.h b/src/publisher/pubMqtt.h index 113292b8d..784785363 100644 --- a/src/publisher/pubMqtt.h +++ b/src/publisher/pubMqtt.h @@ -406,7 +406,7 @@ class PubMqtt { return (pos >= DEVICE_CLS_ASSIGN_LIST_LEN) ? NULL : stateClasses[deviceFieldAssignment[pos].stateClsId]; } - bool processIvStatus() { + bool processIvStatus() { // returns true if any inverter is available bool allAvail = true; // shows if all enabled inverters are available bool anyAvail = false; // shows if at least one enabled inverter is available @@ -419,17 +419,19 @@ class PubMqtt { iv = mSys->getInverterByPos(id); if (NULL == iv) continue; // skip to next inverter + if (!iv->config->enabled) + continue; // skip to next inverter rec = iv->getRecordStruct(RealTimeRunData_Debug); // inverter status uint8_t status = MQTT_STATUS_NOT_AVAIL_NOT_PROD; - if (iv->config->enabled) { - if (iv->isAvailable(*mUtcTimestamp)) - status = (iv->isProducing(*mUtcTimestamp)) ? MQTT_STATUS_AVAIL_PROD : MQTT_STATUS_AVAIL_NOT_PROD; - else // inverter is enabled but not available - allAvail = false; + if (iv->isAvailable(*mUtcTimestamp)) { + anyAvail = true; + status = (iv->isProducing(*mUtcTimestamp)) ? MQTT_STATUS_AVAIL_PROD : MQTT_STATUS_AVAIL_NOT_PROD; } + else // inverter is enabled but not available + allAvail = false; if(mLastIvState[id] != status) { // if status changed from producing to not producing send last data immediately @@ -439,11 +441,11 @@ class PubMqtt { mLastIvState[id] = status; changed = true; - snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, mqttStr[MQTT_STR_AVAILABLE]); + snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/available", iv->config->name); snprintf(val, 40, "%d", status); publish(topic, val, true); - snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", iv->config->name, mqttStr[MQTT_STR_LAST_SUCCESS]); + snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/last_success", iv->config->name); snprintf(val, 40, "%d", iv->getLastTs(rec)); publish(topic, val, true); } @@ -451,7 +453,7 @@ class PubMqtt { if(changed) { snprintf(val, 32, "%d", ((allAvail) ? MQTT_STATUS_ONLINE : ((anyAvail) ? MQTT_STATUS_PARTIAL : MQTT_STATUS_OFFLINE))); - publish(subtopics[MQTT_STATUS], val, true); + publish("status", val, true); } return anyAvail; @@ -474,24 +476,26 @@ class PubMqtt { char topic[7 + MQTT_TOPIC_LEN], val[40]; record_t<> *rec = iv->getRecordStruct(curInfoCmd); - for (uint8_t i = 0; i < rec->length; i++) { - bool retained = false; - if (curInfoCmd == RealTimeRunData_Debug) { - switch (rec->assign[i].fieldId) { - case FLD_YT: - case FLD_YD: - if ((rec->assign[i].ch == CH0) && (!iv->isProducing(*mUtcTimestamp))) // avoids returns to 0 on restart - continue; - retained = true; - break; + if (iv->getLastTs(rec) > 0) { + for (uint8_t i = 0; i < rec->length; i++) { + bool retained = false; + if (curInfoCmd == RealTimeRunData_Debug) { + switch (rec->assign[i].fieldId) { + case FLD_YT: + case FLD_YD: + if ((rec->assign[i].ch == CH0) && (!iv->isProducing(*mUtcTimestamp))) // avoids returns to 0 on restart + continue; + retained = true; + break; + } } - } - snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]); - snprintf(val, 40, "%g", ah::round3(iv->getValue(i, rec))); - publish(topic, val, retained); + snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/ch%d/%s", iv->config->name, rec->assign[i].ch, fields[rec->assign[i].fieldId]); + snprintf(val, 40, "%g", ah::round3(iv->getValue(i, rec))); + publish(topic, val, retained); - yield(); + yield(); + } } } @@ -512,42 +516,49 @@ class PubMqtt { uint8_t curInfoCmd = mSendList.front(); if ((curInfoCmd != RealTimeRunData_Debug) || !RTRDataHasBeenSent) { // send RTR Data only once + bool sendTotals = (curInfoCmd == RealTimeRunData_Debug); + for (uint8_t id = 0; id < mSys->getNumInverters(); id++) { Inverter<> *iv = mSys->getInverterByPos(id); if (NULL == iv) continue; // skip to next inverter + if (!iv->config->enabled) + continue; // skip to next inverter // send RTR Data only if status is available - if ((curInfoCmd != RealTimeRunData_Debug) || (MQTT_STATUS_AVAIL_PROD == mLastIvState[id])) + if ((curInfoCmd != RealTimeRunData_Debug) || (MQTT_STATUS_NOT_AVAIL_NOT_PROD != mLastIvState[id])) sendData(iv, curInfoCmd); // calculate total values for RealTimeRunData_Debug - if (curInfoCmd == RealTimeRunData_Debug) { + if (sendTotals) { record_t<> *rec = iv->getRecordStruct(curInfoCmd); - for (uint8_t i = 0; i < rec->length; i++) { - if (CH0 == rec->assign[i].ch) { - switch (rec->assign[i].fieldId) { - case FLD_PAC: - total[0] += iv->getValue(i, rec); - break; - case FLD_YT: - total[1] += iv->getValue(i, rec); - break; - case FLD_YD: - total[2] += iv->getValue(i, rec); - break; - case FLD_PDC: - total[3] += iv->getValue(i, rec); - break; + sendTotals &= (iv->getLastTs(rec) > 0); + if (sendTotals) { + for (uint8_t i = 0; i < rec->length; i++) { + if (CH0 == rec->assign[i].ch) { + switch (rec->assign[i].fieldId) { + case FLD_PAC: + total[0] += iv->getValue(i, rec); + break; + case FLD_YT: + total[1] += iv->getValue(i, rec); + break; + case FLD_YD: + total[2] += iv->getValue(i, rec); + break; + case FLD_PDC: + total[3] += iv->getValue(i, rec); + break; + } } } } - yield(); } + yield(); } - if (curInfoCmd == RealTimeRunData_Debug) { + if (sendTotals) { uint8_t fieldId; for (uint8_t i = 0; i < 4; i++) { switch (i) { @@ -565,7 +576,7 @@ class PubMqtt { fieldId = FLD_PDC; break; } - snprintf(topic, 32 + MAX_NAME_LENGTH, "%s/%s", mqttStr[MQTT_STR_TOTAL], fields[fieldId]); + snprintf(topic, 32 + MAX_NAME_LENGTH, "total/%s", fields[fieldId]); snprintf(val, 40, "%g", ah::round3(total[i])); publish(topic, val, true); } diff --git a/src/web/RestApi.h b/src/web/RestApi.h index 3dcbc481a..1193116f6 100644 --- a/src/web/RestApi.h +++ b/src/web/RestApi.h @@ -71,7 +71,7 @@ class RestApi { mHeapFrag = ESP.getHeapFragmentation(); #endif - AsyncJsonResponse* response = new AsyncJsonResponse(false, 8192); + AsyncJsonResponse* response = new AsyncJsonResponse(false, 6000); JsonObject root = response->getRoot(); String path = request->url().substring(5); @@ -83,7 +83,6 @@ class RestApi { else if(path == "reboot") getReboot(root); else if(path == "statistics") getStatistics(root); else if(path == "inverter/list") getInverterList(root); - else if(path == "menu") getMenu(root); else if(path == "index") getIndex(root); else if(path == "setup") getSetup(root); else if(path == "setup/networks") getNetworks(root); @@ -183,10 +182,13 @@ class RestApi { } void getGeneric(JsonObject obj) { - obj[F("version")] = String(mApp->getVersion()); obj[F("build")] = String(AUTO_GIT_HASH); obj[F("wifi_rssi")] = (WiFi.status() != WL_CONNECTED) ? 0 : WiFi.RSSI(); obj[F("ts_uptime")] = mApp->getUptime(); + obj[F("menu_prot")] = mApp->getProtection(); + obj[F("menu_maskH")] = ((mConfig->sys.protectionMask >> 8) & 0xff); + obj[F("menu_maskL")] = ((mConfig->sys.protectionMask ) & 0xff); + obj[F("menu_protEn")] = (bool) (strlen(mConfig->sys.adminPwd) > 0); #if defined(ESP32) obj[F("esp_type")] = F("ESP32"); @@ -244,7 +246,6 @@ class RestApi { } void getHtmlSystem(JsonObject obj) { - getMenu(obj.createNestedObject(F("menu"))); getSysInfo(obj.createNestedObject(F("system"))); getGeneric(obj.createNestedObject(F("generic"))); obj[F("html")] = F("Factory Reset

Reboot"); @@ -252,7 +253,6 @@ class RestApi { } void getHtmlLogout(JsonObject obj) { - getMenu(obj.createNestedObject(F("menu"))); getGeneric(obj.createNestedObject(F("generic"))); obj[F("refresh")] = 3; obj[F("refresh_url")] = "/"; @@ -260,7 +260,6 @@ class RestApi { } void getHtmlSave(JsonObject obj) { - getMenu(obj.createNestedObject(F("menu"))); getGeneric(obj.createNestedObject(F("generic"))); obj[F("refresh")] = 2; obj[F("refresh_url")] = "/setup"; @@ -268,7 +267,6 @@ class RestApi { } void getReboot(JsonObject obj) { - getMenu(obj.createNestedObject(F("menu"))); getGeneric(obj.createNestedObject(F("generic"))); obj[F("refresh")] = 10; obj[F("refresh_url")] = "/"; @@ -377,54 +375,9 @@ class RestApi { obj[F("pinDisp1")] = mConfig->plugin.display.pin1; } - void getMenu(JsonObject obj) { - uint8_t i = 0; - uint16_t mask = (mApp->getProtection()) ? mConfig->sys.protectionMask : 0; - if(!CHECK_MASK(mask, PROT_MASK_LIVE)) { - obj[F("name")][i] = "Live"; - obj[F("link")][i++] = "/live"; - } - if(!CHECK_MASK(mask, PROT_MASK_SERIAL)) { - obj[F("name")][i] = "Serial / Control"; - obj[F("link")][i++] = "/serial"; - } - if(!CHECK_MASK(mask, PROT_MASK_SETUP)) { - obj[F("name")][i] = "Settings"; - obj[F("link")][i++] = "/setup"; - } - obj[F("name")][i++] = "-"; - obj[F("name")][i] = "REST API"; - obj[F("link")][i] = "/api"; - obj[F("trgt")][i++] = "_blank"; - obj[F("name")][i++] = "-"; - if(!CHECK_MASK(mask, PROT_MASK_UPDATE)) { - obj[F("name")][i] = "Update"; - obj[F("link")][i++] = "/update"; - } - if(!CHECK_MASK(mask, PROT_MASK_SYSTEM)) { - obj[F("name")][i] = "System"; - obj[F("link")][i++] = "/system"; - } - obj[F("name")][i++] = "-"; - obj[F("name")][i] = "Documentation"; - obj[F("link")][i] = "https://ahoydtu.de"; - obj[F("trgt")][i++] = "_blank"; - if(strlen(mConfig->sys.adminPwd) > 0) { - obj[F("name")][i++] = "-"; - if(mApp->getProtection()) { - obj[F("name")][i] = "Login"; - obj[F("link")][i++] = "/login"; - } else { - obj[F("name")][i] = "Logout"; - obj[F("link")][i++] = "/logout"; - } - } - } void getIndex(JsonObject obj) { - getMenu(obj.createNestedObject(F("menu"))); getGeneric(obj.createNestedObject(F("generic"))); - obj[F("ts_now")] = mApp->getTimestamp(); obj[F("ts_sunrise")] = mApp->getSunrise(); obj[F("ts_sunset")] = mApp->getSunset(); @@ -473,10 +426,9 @@ class RestApi { } void getSetup(JsonObject obj) { - getMenu(obj.createNestedObject(F("menu"))); getGeneric(obj.createNestedObject(F("generic"))); getSysInfo(obj.createNestedObject(F("system"))); - getInverterList(obj.createNestedObject(F("inverter"))); + //getInverterList(obj.createNestedObject(F("inverter"))); getMqtt(obj.createNestedObject(F("mqtt"))); getNtp(obj.createNestedObject(F("ntp"))); getSun(obj.createNestedObject(F("sun"))); @@ -492,7 +444,6 @@ class RestApi { } void getLive(JsonObject obj) { - getMenu(obj.createNestedObject(F("menu"))); getGeneric(obj.createNestedObject(F("generic"))); JsonArray invArr = obj.createNestedArray(F("inverter")); obj["refresh_interval"] = mConfig->nrf.sendInterval; diff --git a/src/web/html/api.js b/src/web/html/api.js index 2e1ffb2bc..0da4e094b 100644 --- a/src/web/html/api.js +++ b/src/web/html/api.js @@ -38,18 +38,21 @@ function topnav() { toggle("topnav"); } -function parseMenu(obj) { - var e = document.getElementById("topnav"); - e.innerHTML = ""; - for(var i = 0; i < obj["name"].length; i ++) { - if(obj["name"][i] == "-") - e.appendChild(span("", ["seperator"])); - else { - var l = link(obj["link"][i], obj["name"][i], obj["trgt"][i]); - if(obj["link"][i] == window.location.pathname) - l.classList.add("active"); - e.appendChild(l); - } +function parseNav(obj) { + for(i = 0; i < 7; i++) { + var l = document.getElementById("nav"+i); + if(window.location.pathname == "/" + l.href.split('/').pop()) + l.classList.add("active"); + + if(obj["menu_protEn"]) { + if(obj["menu_prot"]) { + if((((obj["menu_mask"] >> i) & 0x01) == 0x01) || (1 == i)) + l.classList.remove("hide"); + + } else if(0 == i) + l.classList.remove("hide"); + } else if(i > 1) + l.classList.remove("hide"); } } diff --git a/src/web/html/convert.py b/src/web/html/convert.py index 4a8f1f324..22a600ce2 100644 --- a/src/web/html/convert.py +++ b/src/web/html/convert.py @@ -2,10 +2,82 @@ import os import gzip import glob - +import shutil +import pkg_resources +from datetime import date from pathlib import Path +from dulwich import porcelain + +required_pkgs = {'dulwich'} +installed_pkgs = {pkg.key for pkg in pkg_resources.working_set} +missing_pkgs = required_pkgs - installed_pkgs + +if missing_pkgs: + env.Execute('"$PYTHONEXE" -m pip install dulwich') + + +def get_git_sha(): + try: + build_version = porcelain.describe('../../../') # refers to the repository root dir + except: + build_version = "g0000000" + + build_flag = "-D AUTO_GIT_HASH=\\\"" + build_version[1:] + "\\\"" + #print ("Firmware Revision: " + build_version) + return (build_flag) + +def readVersion(path): + f = open(path, "r") + lines = f.readlines() + f.close() + + today = date.today() + search = ["_MAJOR", "_MINOR", "_PATCH"] + version = today.strftime("%y%m%d") + "_ahoy_" + ver = "" + for line in lines: + if(line.find("VERSION_") != -1): + for s in search: + p = line.find(s) + if(p != -1): + version += line[p+13:].rstrip() + "." + ver += line[p+13:].rstrip() + "." + return ver[:-1] + +def htmlParts(file, header, nav, footer, version): + p = ""; + f = open(file, "r") + lines = f.readlines() + f.close(); -def convert2Header(inFile): + f = open(header, "r") + h = f.read().strip() + f.close() + + f = open(nav, "r") + n = f.read().strip() + f.close() + + f = open(footer, "r") + fo = f.read().strip() + f.close() + + for line in lines: + line = line.replace("{#HTML_HEADER}", h) + line = line.replace("{#HTML_NAV}", n) + line = line.replace("{#HTML_FOOTER}", fo) + p += line + + #placeholders + link = 'GIT SHA: ' + get_git_sha() + ' :: ' + version + '' + p = p.replace("{#VERSION}", version) + p = p.replace("{#VERSION_GIT}", link) + f = open("tmp/" + file, "w") + f.write(p); + f.close(); + return p + +def convert2Header(inFile, version): fileType = inFile.split(".")[1] define = inFile.split(".")[0].upper() define2 = inFile.split(".")[1].upper() @@ -17,14 +89,19 @@ def convert2Header(inFile): Path("html/h").mkdir(exist_ok=True) else: outName = "h/" + inFileVarName + ".h" - Path("h").mkdir(exist_ok=True) + data = "" if fileType == "ico": f = open(inFile, "rb") + data = f.read() + f.close() else: - f = open(inFile, "r") - data = f.read() - f.close() + if fileType == "html": + data = htmlParts(inFile, "includes/header.html", "includes/nav.html", "includes/footer.html", version) + else: + f = open(inFile, "r") + data = f.read() + f.close() if fileType == "css": data = data.replace('\n', '') @@ -53,13 +130,17 @@ def convert2Header(inFile): f.close() # delete all files in the 'h' dir -dir = 'h' +wd = 'h' if os.getcwd()[-4:] != "html": - dir = "web/html/" + dir + wd = "web/html/" + wd -if os.path.exists(dir): - for f in os.listdir(dir): - os.remove(os.path.join(dir, f)) +if os.path.exists(wd): + for f in os.listdir(wd): + os.remove(os.path.join(wd, f)) +wd += "/tmp" +if os.path.exists(wd): + for f in os.listdir(wd): + os.remove(os.path.join(wd, f)) # grab all files with following extensions if os.getcwd()[-4:] != "html": @@ -69,6 +150,11 @@ def convert2Header(inFile): for files in types: files_grabbed.extend(glob.glob(files)) +Path("h").mkdir(exist_ok=True) +Path("tmp").mkdir(exist_ok=True) # created to check if webpages are valid with all replacements +shutil.copyfile("style.css", "tmp/style.css") +version = readVersion("../../defines.h") + # go throw the array for val in files_grabbed: - convert2Header(val) + convert2Header(val, version) diff --git a/src/web/html/includes/footer.html b/src/web/html/includes/footer.html new file mode 100644 index 000000000..9aa1cf3cf --- /dev/null +++ b/src/web/html/includes/footer.html @@ -0,0 +1,16 @@ + diff --git a/src/web/html/includes/header.html b/src/web/html/includes/header.html new file mode 100644 index 000000000..0531efb6e --- /dev/null +++ b/src/web/html/includes/header.html @@ -0,0 +1,3 @@ + + + diff --git a/src/web/html/includes/nav.html b/src/web/html/includes/nav.html new file mode 100644 index 000000000..97d05e74a --- /dev/null +++ b/src/web/html/includes/nav.html @@ -0,0 +1,27 @@ + + + diff --git a/src/web/html/index.html b/src/web/html/index.html index 6bb584329..1c9973407 100644 --- a/src/web/html/index.html +++ b/src/web/html/index.html @@ -2,36 +2,12 @@ Index - - - + {#HTML_HEADER} -
- AhoyDTU - - - - - -
-
-
+ {#HTML_NAV}
-

Uptime:
ESP-Time: @@ -60,22 +36,7 @@

Support this project:

- + {#HTML_FOOTER} + {#HTML_HEADER}
@@ -18,25 +16,6 @@

AhoyDTU

- - + {#HTML_FOOTER} diff --git a/src/web/html/serial.html b/src/web/html/serial.html index 71388c00a..b158d1704 100644 --- a/src/web/html/serial.html +++ b/src/web/html/serial.html @@ -2,21 +2,10 @@ Serial Console - - - + {#HTML_HEADER} -
- AhoyDTU - - - - - -
-
-
+ {#HTML_NAV}
@@ -53,22 +42,7 @@

Commands

- + {#HTML_FOOTER} + {#HTML_HEADER} -
- AhoyDTU - - - - - -
-
-
+ {#HTML_NAV}
@@ -224,22 +213,7 @@
- + {#HTML_FOOTER} + {#HTML_HEADER} -
- AhoyDTU - - - - - -
-
-
+ {#HTML_NAV}

@@ -26,25 +15,10 @@
                 
- + {#HTML_FOOTER} + {#HTML_HEADER} -
- AhoyDTU - - - - - -
-
-
+ {#HTML_NAV}
@@ -25,43 +14,21 @@
- + {#HTML_FOOTER} diff --git a/src/web/html/visualization.html b/src/web/html/visualization.html index c278dd25d..a1d11bcc1 100644 --- a/src/web/html/visualization.html +++ b/src/web/html/visualization.html @@ -2,50 +2,24 @@ Live - - + {#HTML_HEADER} - -
- AhoyDTU - - - - - -
-
-
+ {#HTML_NAV}

Every seconds the values are updated

- + {#HTML_FOOTER}