mirror of
https://github.com/lumapu/ahoy.git
synced 2025-05-25 14:56:11 +02:00
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
This commit is contained in:
parent
9ef2df21fa
commit
4f0d365211
21 changed files with 279 additions and 377 deletions
1
.gitignore
vendored
1
.gitignore
vendored
|
@ -6,6 +6,7 @@
|
|||
.vscode/extensions.json
|
||||
src/config/config_override.h
|
||||
src/web/html/h/*
|
||||
src/web/html/tmp/*
|
||||
/**/Debug
|
||||
/**/v16/*
|
||||
*.db
|
||||
|
|
|
@ -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
|
||||
|
|
15
src/app.cpp
15
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()));
|
||||
}
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
|
|
|
@ -250,7 +250,7 @@ class settings {
|
|||
return false;
|
||||
}
|
||||
|
||||
DynamicJsonDocument json(4500);
|
||||
DynamicJsonDocument json(5500);
|
||||
JsonObject root = json.to<JsonObject>();
|
||||
jsonWifi(root.createNestedObject(F("wifi")), true);
|
||||
jsonNrf(root.createNestedObject(F("nrf")), true);
|
||||
|
|
|
@ -13,7 +13,7 @@
|
|||
//-------------------------------------
|
||||
#define VERSION_MAJOR 0
|
||||
#define VERSION_MINOR 5
|
||||
#define VERSION_PATCH 90
|
||||
#define VERSION_PATCH 91
|
||||
|
||||
//-------------------------------------
|
||||
typedef struct {
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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))
|
||||
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,6 +476,7 @@ class PubMqtt {
|
|||
char topic[7 + MQTT_TOPIC_LEN], val[40];
|
||||
record_t<> *rec = iv->getRecordStruct(curInfoCmd);
|
||||
|
||||
if (iv->getLastTs(rec) > 0) {
|
||||
for (uint8_t i = 0; i < rec->length; i++) {
|
||||
bool retained = false;
|
||||
if (curInfoCmd == RealTimeRunData_Debug) {
|
||||
|
@ -494,6 +497,7 @@ class PubMqtt {
|
|||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void sendIvData() {
|
||||
bool anyAvail = processIvStatus();
|
||||
|
@ -512,19 +516,25 @@ 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);
|
||||
|
||||
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) {
|
||||
|
@ -543,11 +553,12 @@ class PubMqtt {
|
|||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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);
|
||||
}
|
||||
|
|
|
@ -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("<a href=\"/factory\" class=\"btn\">Factory Reset</a><br/><br/><a href=\"/reboot\" class=\"btn\">Reboot</a>");
|
||||
|
@ -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;
|
||||
|
|
|
@ -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)
|
||||
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");
|
||||
e.appendChild(l);
|
||||
}
|
||||
|
||||
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");
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -2,10 +2,82 @@ import re
|
|||
import os
|
||||
import gzip
|
||||
import glob
|
||||
|
||||
import shutil
|
||||
import pkg_resources
|
||||
from datetime import date
|
||||
from pathlib import Path
|
||||
from dulwich import porcelain
|
||||
|
||||
def convert2Header(inFile):
|
||||
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();
|
||||
|
||||
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 = '<a target="_blank" href="https://github.com/lumapu/ahoy/commits/' + get_git_sha() + '">GIT SHA: ' + get_git_sha() + ' :: ' + version + '</a>'
|
||||
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,10 +89,15 @@ 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:
|
||||
if fileType == "html":
|
||||
data = htmlParts(inFile, "includes/header.html", "includes/nav.html", "includes/footer.html", version)
|
||||
else:
|
||||
f = open(inFile, "r")
|
||||
data = f.read()
|
||||
|
@ -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 @@ files_grabbed = []
|
|||
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)
|
||||
|
|
16
src/web/html/includes/footer.html
Normal file
16
src/web/html/includes/footer.html
Normal file
|
@ -0,0 +1,16 @@
|
|||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li>{#VERSION}</li>
|
||||
<li><span id="esp_type"></span></li>
|
||||
<li><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
3
src/web/html/includes/header.html
Normal file
3
src/web/html/includes/header.html
Normal file
|
@ -0,0 +1,3 @@
|
|||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript" src="api.js"></script>
|
27
src/web/html/includes/nav.html
Normal file
27
src/web/html/includes/nav.html
Normal file
|
@ -0,0 +1,27 @@
|
|||
<div class="topnav">
|
||||
<a href="/" class="title">AhoyDTU</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="topnav()">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</a>
|
||||
<div id="topnav" class="mobile">
|
||||
<div id="topnav" class="mobile">
|
||||
<a id="nav2" class="hide" href="/live">Live</a>
|
||||
<a id="nav3" class="hide" href="/serial">Serial / Control</a>
|
||||
<a id="nav4" class="hide" href="/setup">Settings</a>
|
||||
<span class="seperator"></span>
|
||||
<a id="nav5" class="hide" href="/update">Update</a>
|
||||
<a id="nav6" class="hide" href="/system">System</a>
|
||||
<span class="seperator"></span>
|
||||
<a id="nav7" href="/api" target="_blank">REST API</a>
|
||||
<a id="nav8" href="https://ahoydtu.de" target="_blank">Documentation</a>
|
||||
<span class="seperator"></span>
|
||||
<a id="nav0" class="hide" href="/login">Login</a>
|
||||
<a id="nav1" class="hide" href="/logout">Logout</a>
|
||||
</div>
|
||||
</div>
|
||||
<div id="wifiicon" class="info"></div>
|
||||
</div>
|
||||
|
||||
|
|
@ -2,36 +2,12 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Index</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript" src="api.js"></script>
|
||||
{#HTML_HEADER}
|
||||
</head>
|
||||
<body>
|
||||
<div class="topnav">
|
||||
<a href="/" class="title">AhoyDTU</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="topnav()">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</a>
|
||||
<div id="topnav" class="hide"></div>
|
||||
<div id="wifiicon" class="info"></div>
|
||||
</div>
|
||||
{#HTML_NAV}
|
||||
<div id="wrapper">
|
||||
<div id="content">
|
||||
<script>
|
||||
function promptFunction() {
|
||||
var Text = prompt("This project was started from https://www.mikrocontroller.net/topic/525778 this discussion.\n\n" +
|
||||
"The Hoymiles protocol was decrypted through the voluntary efforts of many participants. ahoy, among others, was developed based on this work.\n" +
|
||||
"The software was developed to the best of our knowledge and belief. Nevertheless, no liability can be accepted for a malfunction or guarantee loss of the inverter.\n\n" +
|
||||
"Ahoy is freely available. If you paid money for the software, you probably got ripped off.\n\nPlease type in 'YeS', you are accept our Disclaim. You should then save your config.", "");
|
||||
if (Text != "YeS")
|
||||
promptFunction();
|
||||
else
|
||||
return true;
|
||||
|
||||
}
|
||||
</script>
|
||||
<p>
|
||||
<span class="des">Uptime: </span><span id="uptime"></span><br/>
|
||||
<span class="des">ESP-Time: </span><span id="date"></span>
|
||||
|
@ -60,22 +36,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li><span id="version"></span></li>
|
||||
<li><span id="esp_type"></span></li>
|
||||
<li><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{#HTML_FOOTER}
|
||||
<script type="text/javascript">
|
||||
var exeOnce = true;
|
||||
var tickCnt = 0;
|
||||
|
@ -108,10 +69,10 @@
|
|||
function parseGeneric(obj) {
|
||||
// Disclaimer
|
||||
//if(obj["disclaimer"] == false) sessionStorage.setItem("gDisclaimer", promptFunction());
|
||||
if(exeOnce){
|
||||
/*if(exeOnce){
|
||||
parseVersion(obj);
|
||||
parseESP(obj);
|
||||
}
|
||||
}*/
|
||||
parseRssi(obj);
|
||||
}
|
||||
|
||||
|
@ -203,7 +164,7 @@
|
|||
document.getElementById("iv").replaceChildren(p);
|
||||
}
|
||||
|
||||
function parseWarnInfo(warn, success, version) {
|
||||
function parseWarnInfo(warn, success) {
|
||||
var p = div(["none"]);
|
||||
for(var w of warn) {
|
||||
p.append(svg(iconWarn, 20, 20, "#F70", "icon"), span(w), br());
|
||||
|
@ -216,10 +177,10 @@
|
|||
p.append(svg(iconInfo, 20, 20, "#00d", "icon"), span(commInfo), br());
|
||||
|
||||
if(null != release) {
|
||||
if(getVerInt(version) < getVerInt(release))
|
||||
if(getVerInt("{#VERSION}") < getVerInt(release))
|
||||
p.append(svg(iconInfo, 20, 20, "#00d", "icon"), span("Update available, current released version: " + release), br());
|
||||
else if(getVerInt(version) > getVerInt(release))
|
||||
p.append(svg(iconInfo, 20, 20, "#00d", "icon"), span("You are using development version " + version +". In case of issues you may want to try the current stable release: " + release), br());
|
||||
else if(getVerInt("{#VERSION}") > getVerInt(release))
|
||||
p.append(svg(iconInfo, 20, 20, "#00d", "icon"), span("You are using development version {#VERSION}. In case of issues you may want to try the current stable release: " + release), br());
|
||||
else
|
||||
p.append(svg(iconInfo, 20, 20, "#00d", "icon"), span("You are using the current stable release: " + release), br());
|
||||
}
|
||||
|
@ -239,11 +200,11 @@
|
|||
function parse(obj) {
|
||||
if(null != obj) {
|
||||
if(exeOnce)
|
||||
parseMenu(obj["menu"]);
|
||||
parseNav(obj["generic"]);
|
||||
parseGeneric(obj["generic"]);
|
||||
parseSys(obj);
|
||||
parseIv(obj["inverter"]);
|
||||
parseWarnInfo(obj["warnings"], obj["infos"], obj["generic"]["version"]);
|
||||
parseWarnInfo(obj["warnings"], obj["infos"]);
|
||||
if(exeOnce) {
|
||||
window.setInterval("tick()", 1000);
|
||||
exeOnce = false;
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Login</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript" src="api.js"></script>
|
||||
{#HTML_HEADER}
|
||||
</head>
|
||||
<body>
|
||||
<div id="wrapper">
|
||||
|
@ -18,25 +16,6 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<span id="version"></span><br/><br/>
|
||||
<a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/javascript">
|
||||
function parse(obj) {
|
||||
parseVersion(obj["general"]);
|
||||
}
|
||||
|
||||
getAjax("/api/generic", parse);
|
||||
</script>
|
||||
{#HTML_FOOTER}
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,21 +2,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Serial Console</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript" src="api.js"></script>
|
||||
{#HTML_HEADER}
|
||||
</head>
|
||||
<body>
|
||||
<div class="topnav">
|
||||
<a href="/" class="title">AhoyDTU</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="topnav()">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</a>
|
||||
<div id="topnav" class="hide"></div>
|
||||
<div id="wifiicon" class="info"></div>
|
||||
</div>
|
||||
{#HTML_NAV}
|
||||
<div id="wrapper">
|
||||
<div id="content">
|
||||
<div class="serial">
|
||||
|
@ -53,22 +42,7 @@
|
|||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li><span id="version"></span></li>
|
||||
<li><span id="esp_type"></span></li>
|
||||
<li><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{#HTML_FOOTER}
|
||||
<script type="text/javascript">
|
||||
var mAutoScroll = true;
|
||||
var con = document.getElementById("serial");
|
||||
|
@ -87,7 +61,7 @@
|
|||
|
||||
parseRssi(obj);
|
||||
if(true == exeOnce) {
|
||||
parseVersion(obj);
|
||||
parseNav(obj);
|
||||
parseESP(obj);
|
||||
window.setInterval("getAjax('/api/generic', parseGeneric)", 10000);
|
||||
exeOnce = false;
|
||||
|
@ -96,7 +70,6 @@
|
|||
}
|
||||
|
||||
function parse(root) {
|
||||
parseMenu(root["menu"]);
|
||||
select = document.getElementById('InvID');
|
||||
|
||||
if(null == root) return;
|
||||
|
|
|
@ -2,9 +2,7 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Setup</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript" src="api.js"></script>
|
||||
{#HTML_HEADER}
|
||||
<script type="text/javascript">
|
||||
function load() {
|
||||
for(it of document.getElementsByClassName("s_collapsible")) {
|
||||
|
@ -18,16 +16,7 @@
|
|||
</script>
|
||||
</head>
|
||||
<body onload="load()">
|
||||
<div class="topnav">
|
||||
<a href="/" class="title">AhoyDTU</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="topnav()">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</a>
|
||||
<div id="topnav" class="hide"></div>
|
||||
<div id="wifiicon" class="info"></div>
|
||||
</div>
|
||||
{#HTML_NAV}
|
||||
<div id="wrapper">
|
||||
<div id="content">
|
||||
<form method="post" action="/save">
|
||||
|
@ -224,22 +213,7 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li><span id="version"></span></li>
|
||||
<li><span id="esp_type"></span></li>
|
||||
<li><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{#HTML_FOOTER}
|
||||
<script type="text/javascript">
|
||||
var highestId = 0;
|
||||
var maxInv = 0;
|
||||
|
@ -426,7 +400,7 @@
|
|||
|
||||
iv.append(
|
||||
lbl(id + "Name", "Name*"),
|
||||
inp(id + "Name", obj["name"], 32, ["text"], null, "text", "[A-Za-z0-9./#$%&=+_-]+", "Invalid input")
|
||||
inp(id + "Name", obj["name"], 16, ["text"], null, "text", "[A-Za-z0-9./#$%&=+_-]+", "Invalid input")
|
||||
);
|
||||
|
||||
for(var j of [
|
||||
|
@ -479,7 +453,7 @@
|
|||
}
|
||||
|
||||
function parseGeneric(obj) {
|
||||
parseVersion(obj);
|
||||
parseNav(obj);
|
||||
parseESP(obj);
|
||||
parseRssi(obj);
|
||||
}
|
||||
|
@ -568,11 +542,9 @@
|
|||
|
||||
function parse(root) {
|
||||
if(null != root) {
|
||||
parseMenu(root["menu"]);
|
||||
parseSys(root["system"]);
|
||||
parseGeneric(root["generic"]);
|
||||
parseStaticIp(root["static_ip"]);
|
||||
parseIv(root["inverter"]);
|
||||
parseMqtt(root["mqtt"]);
|
||||
parseNtp(root["ntp"]);
|
||||
parseSun(root["sun"]);
|
||||
|
@ -580,6 +552,7 @@
|
|||
parseRadio(root["radio"]);
|
||||
parseSerial(root["serial"]);
|
||||
parseDisplay(root["display"], root["system"]["esp_type"]);
|
||||
getAjax("/api/inverter/list", parseIv);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -50,6 +50,10 @@ h2 {
|
|||
top: 5px;
|
||||
}
|
||||
|
||||
.topnav .mobile {
|
||||
display: none;
|
||||
}
|
||||
|
||||
svg.icon {
|
||||
vertical-align: middle;
|
||||
display: inline-block;
|
||||
|
@ -131,7 +135,7 @@ span.seperator {
|
|||
}
|
||||
|
||||
.hide {
|
||||
display: none;
|
||||
display: none !important;
|
||||
}
|
||||
|
||||
@media only screen and (min-width: 992px) {
|
||||
|
@ -152,7 +156,7 @@ span.seperator {
|
|||
padding-left: 24px !important;
|
||||
}
|
||||
|
||||
.topnav .hide {
|
||||
.topnav .mobile {
|
||||
display: block;
|
||||
}
|
||||
|
||||
|
|
|
@ -2,21 +2,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>System</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript" src="api.js"></script>
|
||||
{#HTML_HEADER}
|
||||
</head>
|
||||
<body>
|
||||
<div class="topnav">
|
||||
<a href="/" class="title">AhoyDTU</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="topnav()">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</a>
|
||||
<div id="topnav" class="hide"></div>
|
||||
<div id="wifiicon" class="info"></div>
|
||||
</div>
|
||||
{#HTML_NAV}
|
||||
<div id="wrapper">
|
||||
<div id="content">
|
||||
<pre id="stat"></pre>
|
||||
|
@ -26,25 +15,10 @@
|
|||
<div id="html" class="mt-3 mb-3"></div>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li><span id="version"></span></li>
|
||||
<li><span id="esp_type"></span></li>
|
||||
<li><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{#HTML_FOOTER}
|
||||
<script type="text/javascript">
|
||||
function parseGeneric(obj) {
|
||||
parseVersion(obj);
|
||||
parseNav(obj);
|
||||
parseESP(obj);
|
||||
parseRssi(obj);
|
||||
}
|
||||
|
@ -123,7 +97,6 @@
|
|||
|
||||
function parse(obj) {
|
||||
if(null != obj) {
|
||||
parseMenu(obj["menu"]);
|
||||
parseGeneric(obj["generic"]);
|
||||
|
||||
if(null != obj["refresh"]) {
|
||||
|
|
|
@ -2,21 +2,10 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Update</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
<script type="text/javascript" src="api.js"></script>
|
||||
{#HTML_HEADER}
|
||||
</head>
|
||||
<body>
|
||||
<div class="topnav">
|
||||
<a href="/" class="title">AhoyDTU</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="topnav()">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</a>
|
||||
<div id="topnav" class="hide"></div>
|
||||
<div id="wifiicon" class="info"></div>
|
||||
</div>
|
||||
{#HTML_NAV}
|
||||
<div id="wrapper">
|
||||
<div id="content">
|
||||
<form id="form" method="POST" action="/update" enctype="multipart/form-data" accept-charset="utf-8">
|
||||
|
@ -25,43 +14,21 @@
|
|||
</form>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li><span id="version"></span></li>
|
||||
<li><span id="esp_type"></span></li>
|
||||
<li><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{#HTML_FOOTER}
|
||||
<script type="text/javascript">
|
||||
function parseGeneric(obj) {
|
||||
parseVersion(obj);
|
||||
parseNav(obj);
|
||||
parseESP(obj);
|
||||
parseRssi(obj);
|
||||
}
|
||||
|
||||
function parse(obj) {
|
||||
if(null != obj) {
|
||||
parseMenu(obj["menu"]);
|
||||
parseGeneric(obj["generic"]);
|
||||
}
|
||||
}
|
||||
|
||||
function hide() {
|
||||
document.getElementById("form").submit();
|
||||
var e = document.getElementById("content");
|
||||
e.replaceChildren(span("update started"));
|
||||
}
|
||||
|
||||
getAjax("/api/index", parse);
|
||||
getAjax("/api/generic", parseGeneric);
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
||||
|
|
|
@ -2,50 +2,24 @@
|
|||
<html>
|
||||
<head>
|
||||
<title>Live</title>
|
||||
<link rel="stylesheet" type="text/css" href="style.css"/>
|
||||
<meta name="viewport" content="width=device-width, initial-scale=1">
|
||||
{#HTML_HEADER}
|
||||
<meta name="apple-mobile-web-app-capable" content="yes">
|
||||
<script type="text/javascript" src="api.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
<div class="topnav">
|
||||
<a href="/" class="title">AhoyDTU</a>
|
||||
<a href="javascript:void(0);" class="icon" onclick="topnav()">
|
||||
<span></span>
|
||||
<span></span>
|
||||
<span></span>
|
||||
</a>
|
||||
<div id="topnav" class="hide"></div>
|
||||
<div id="wifiicon" class="info"></div>
|
||||
</div>
|
||||
{#HTML_NAV}
|
||||
<div id="wrapper">
|
||||
<div id="content">
|
||||
<div id="live"></div>
|
||||
<p>Every <span id="refresh"></span> seconds the values are updated</p>
|
||||
</div>
|
||||
</div>
|
||||
<div id="footer">
|
||||
<div class="left">
|
||||
<a href="https://ahoydtu.de" target="_blank">AhoyDTU © 2023</a>
|
||||
<ul>
|
||||
<li><a href="https://discord.gg/WzhxEY62mB" target="_blank">Discord</a></li>
|
||||
<li><a href="https://github.com/lumapu/ahoy" target="_blank">Github</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
<div class="right">
|
||||
<ul>
|
||||
<li><span id="version"></span></li>
|
||||
<li><span id="esp_type"></span></li>
|
||||
<li><a href="https://creativecommons.org/licenses/by-nc-sa/3.0/de" target="_blank" >CC BY-NC-SA 3.0</a></li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
{#HTML_FOOTER}
|
||||
<script type="text/javascript">
|
||||
var exeOnce = true;
|
||||
|
||||
function parseGeneric(obj) {
|
||||
if(true == exeOnce){
|
||||
parseVersion(obj);
|
||||
parseNav(obj);
|
||||
parseESP(obj);
|
||||
}
|
||||
parseRssi(obj);
|
||||
|
@ -133,8 +107,6 @@
|
|||
|
||||
function parse(obj) {
|
||||
if(null != obj) {
|
||||
if(true == exeOnce)
|
||||
parseMenu(obj["menu"]);
|
||||
parseGeneric(obj["generic"]);
|
||||
parseIv(obj["inverter"], obj);
|
||||
document.getElementById("refresh").innerHTML = obj["refresh_interval"];
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue