Browse Source

0.8.134

* redesigned `/system`
main
lumapu 2 months ago
parent
commit
5b6ffcc07b
  1. 1
      src/CHANGES.md
  2. 4
      src/app.h
  3. 1
      src/appInterface.h
  4. 7
      src/network/AhoyEthernet.h
  5. 1
      src/network/AhoyNetwork.h
  6. 24
      src/network/AhoyWifiEsp32.h
  7. 4
      src/network/AhoyWifiEsp8266.h
  8. 198
      src/web/RestApi.h
  9. 4
      src/web/html/api.js
  10. 13
      src/web/html/style.css
  11. 113
      src/web/html/system.html
  12. 50
      src/web/lang.json

1
src/CHANGES.md

@ -3,6 +3,7 @@
## 0.8.134 - 2024-08-10 ## 0.8.134 - 2024-08-10
* combined Ethernet and WiFi variants - Ethernet is now always included, but needs to be enabled if needed * combined Ethernet and WiFi variants - Ethernet is now always included, but needs to be enabled if needed
* improved statistic data in `/system` * improved statistic data in `/system`
* redesigned `/system`
## 0.8.133 - 2024-08-10 ## 0.8.133 - 2024-08-10
* Ethernet variants now support WiFi as fall back / configuration * Ethernet variants now support WiFi as fall back / configuration

4
src/app.h

@ -187,6 +187,10 @@ class app : public IApp, public ah::Scheduler {
return mNetwork->getIp(); return mNetwork->getIp();
} }
String getMac(void) override {
return mNetwork->getMac();
}
bool isApActive(void) override { bool isApActive(void) override {
return mNetwork->isApActive(); return mNetwork->isApActive();
} }

1
src/appInterface.h

@ -32,6 +32,7 @@ class IApp {
virtual void setupStation(void) = 0; virtual void setupStation(void) = 0;
virtual bool getWasInCh12to14(void) const = 0; virtual bool getWasInCh12to14(void) const = 0;
virtual String getIp(void) = 0; virtual String getIp(void) = 0;
virtual String getMac(void) = 0;
virtual bool isApActive(void) = 0; virtual bool isApActive(void) = 0;
virtual uint32_t getUptime() = 0; virtual uint32_t getUptime() = 0;

7
src/network/AhoyEthernet.h

@ -41,6 +41,13 @@ class AhoyEthernet : public AhoyWifi {
return ETH.localIP().toString(); return ETH.localIP().toString();
} }
String getMac(void) {
if(Mode::WIRELESS == mMode)
return AhoyWifi::getMac();
else
return ETH.macAddress();
}
bool isWiredConnection() { bool isWiredConnection() {
return (Mode::WIRED == mMode); return (Mode::WIRED == mMode);
} }

1
src/network/AhoyNetwork.h

@ -79,6 +79,7 @@ class AhoyNetwork {
virtual void begin() = 0; virtual void begin() = 0;
virtual void tickNetworkLoop() = 0; virtual void tickNetworkLoop() = 0;
virtual String getIp(void) = 0; virtual String getIp(void) = 0;
virtual String getMac(void) = 0;
virtual bool getWasInCh12to14() { virtual bool getWasInCh12to14() {
return false; return false;

24
src/network/AhoyWifiEsp32.h

@ -36,6 +36,20 @@ class AhoyWifi : public AhoyNetwork {
#endif #endif
} }
void tickNetworkLoop() override {
if(mAp.isEnabled())
mAp.tickLoop();
}
String getIp(void) override {
return WiFi.localIP().toString();
}
String getMac(void) override {
return WiFi.macAddress();
}
private:
virtual void OnEvent(WiFiEvent_t event) override { virtual void OnEvent(WiFiEvent_t event) override {
switch(event) { switch(event) {
case SYSTEM_EVENT_STA_CONNECTED: case SYSTEM_EVENT_STA_CONNECTED:
@ -78,16 +92,6 @@ class AhoyWifi : public AhoyNetwork {
} }
} }
void tickNetworkLoop() override {
if(mAp.isEnabled())
mAp.tickLoop();
}
String getIp(void) override {
return WiFi.localIP().toString();
}
private:
virtual void setStaticIp() override { virtual void setStaticIp() override {
setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool { setupIp([this](IPAddress ip, IPAddress gateway, IPAddress mask, IPAddress dns1, IPAddress dns2) -> bool {
return WiFi.config(ip, gateway, mask, dns1, dns2); return WiFi.config(ip, gateway, mask, dns1, dns2);

4
src/network/AhoyWifiEsp8266.h

@ -111,6 +111,10 @@ class AhoyWifi : public AhoyNetwork {
return WiFi.localIP().toString(); return WiFi.localIP().toString();
} }
String getMac(void) override {
return WiFi.macAddress();
}
bool getWasInCh12to14() override { bool getWasInCh12to14() override {
return mWasInCh12to14; return mWasInCh12to14;
} }

198
src/web/RestApi.h

@ -413,11 +413,6 @@ class RestApi {
} }
void getSysInfo(AsyncWebServerRequest *request, JsonObject obj) { void getSysInfo(AsyncWebServerRequest *request, JsonObject obj) {
obj[F("ap_pwd")] = mConfig->sys.apPwd;
obj[F("ssid")] = mConfig->sys.stationSsid;
obj[F("hidd")] = mConfig->sys.isHidden;
obj[F("mac")] = WiFi.macAddress();
obj[F("wifi_channel")] = WiFi.channel();
obj[F("device_name")] = mConfig->sys.deviceName; obj[F("device_name")] = mConfig->sys.deviceName;
obj[F("dark_mode")] = (bool)mConfig->sys.darkMode; obj[F("dark_mode")] = (bool)mConfig->sys.darkMode;
obj[F("sched_reboot")] = (bool)mConfig->sys.schedReboot; obj[F("sched_reboot")] = (bool)mConfig->sys.schedReboot;
@ -425,97 +420,15 @@ class RestApi {
obj[F("pwd_set")] = (strlen(mConfig->sys.adminPwd) > 0); obj[F("pwd_set")] = (strlen(mConfig->sys.adminPwd) > 0);
obj[F("prot_mask")] = mConfig->sys.protectionMask; obj[F("prot_mask")] = mConfig->sys.protectionMask;
obj[F("sdk")] = ESP.getSdkVersion(); getGeneric(request, obj.createNestedObject(F("generic")));
obj[F("cpu_freq")] = ESP.getCpuFreqMHz(); getChipInfo(obj.createNestedObject(F("chip")));
obj[F("heap_free")] = mHeapFree;
getGeneric(request, obj);
getRadioNrf(obj.createNestedObject(F("radioNrf"))); getRadioNrf(obj.createNestedObject(F("radioNrf")));
getMqttInfo(obj.createNestedObject(F("mqtt")));
getNetworkInfo(obj.createNestedObject(F("network")));
getMemoryInfo(obj.createNestedObject(F("memory")));
#if defined(ESP32) #if defined(ESP32)
getRadioCmtInfo(obj.createNestedObject(F("radioCmt"))); getRadioCmtInfo(obj.createNestedObject(F("radioCmt")));
#endif #endif
getMqttInfo(obj.createNestedObject(F("mqtt")));
#if defined(ETHERNET)
getEthernetInfo(obj.createNestedObject(F("eth")));
#endif
obj[F("heap_frag")] = mHeapFrag;
obj[F("max_free_blk")] = mHeapFreeBlk;
#if defined(ESP32)
obj[F("chip_revision")] = ESP.getChipRevision();
obj[F("chip_model")] = ESP.getChipModel();
obj[F("chip_cores")] = ESP.getChipCores();
obj[F("heap_total")] = ESP.getHeapSize();
//obj[F("core_version")] = F("n/a");
esp_reset_reason_t reason = esp_reset_reason();
// Reboot-Grund ausgeben
switch (reason) {
default:
[[fallthrough]];
case ESP_RST_UNKNOWN:
obj[F("reboot_reason")] = F("Unknown");
break;
case ESP_RST_POWERON:
obj[F("reboot_reason")] = F("Power on");
break;
case ESP_RST_EXT:
obj[F("reboot_reason")] = F("External");
break;
case ESP_RST_SW:
obj[F("reboot_reason")] = F("Software");
break;
case ESP_RST_PANIC:
obj[F("reboot_reason")] = F("Panic");
break;
case ESP_RST_INT_WDT:
obj[F("reboot_reason")] = F("Interrupt Watchdog");
break;
case ESP_RST_TASK_WDT:
obj[F("reboot_reason")] = F("Task Watchdog");
break;
case ESP_RST_WDT:
obj[F("reboot_reason")] = F("Watchdog");
break;
case ESP_RST_DEEPSLEEP:
obj[F("reboot_reason")] = F("Deepsleep");
break;
case ESP_RST_BROWNOUT:
obj[F("reboot_reason")] = F("Brownout");
break;
case ESP_RST_SDIO:
obj[F("reboot_reason")] = F("SDIO");
break;
}
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, "coredump");
if (partition != NULL)
obj[F("flash_size")] = partition->address + partition->size;
#else
//obj[F("heap_total")] = F("n/a");
//obj[F("chip_revision")] = F("n/a");
//obj[F("chip_model")] = F("n/a");
//obj[F("chip_cores")] = F("n/a");
obj[F("core_version")] = ESP.getCoreVersion();
obj[F("flash_size")] = ESP.getFlashChipRealSize() / 1024; // in kb
obj[F("reboot_reason")] = ESP.getResetReason();
#endif
#if !defined(ESP32)
FSInfo info;
LittleFS.info(info);
obj[F("par_used_spiffs")] = info.usedBytes;
obj[F("par_size_spiffs")] = info.totalBytes;
#else
obj[F("par_size_spiffs")] = LittleFS.totalBytes();
obj[F("par_used_spiffs")] = LittleFS.usedBytes();
#endif
obj[F("par_size_app0")] = ESP.getFreeSketchSpace();
obj[F("par_used_app0")] = ESP.getSketchSize();
/*uint8_t max; /*uint8_t max;
mApp->getSchedulerInfo(&max); mApp->getSchedulerInfo(&max);
@ -885,11 +798,106 @@ class RestApi {
obj[F("irq")] = mConfig->sys.eth.pinIrq; obj[F("irq")] = mConfig->sys.eth.pinIrq;
obj[F("reset")] = mConfig->sys.eth.pinRst; obj[F("reset")] = mConfig->sys.eth.pinRst;
} }
#endif
void getNetworkInfo(JsonObject obj) {
#if defined(ESP32)
bool isWired = mApp->isWiredConnection();
if(!isWired)
obj[F("wifi_channel")] = WiFi.channel();
#else
obj[F("wifi_channel")] = WiFi.channel();
#endif
void getEthernetInfo(JsonObject obj) { obj[F("ap_pwd")] = mConfig->sys.apPwd;
obj[F("wired")] = (bool)mApp->isWiredConnection(); obj[F("ssid")] = mConfig->sys.stationSsid;
obj[F("hidd")] = mConfig->sys.isHidden;
obj[F("mac")] = mApp->getMac();
obj[F("ip")] = mApp->getIp();
#if defined(ESP32)
obj[F("wired")] = isWired;
#endif
}
void getChipInfo(JsonObject obj) {
obj[F("cpu_freq")] = ESP.getCpuFreqMHz();
obj[F("sdk")] = ESP.getSdkVersion();
#if defined(ESP32)
obj[F("revision")] = ESP.getChipRevision();
obj[F("model")] = ESP.getChipModel();
obj[F("cores")] = ESP.getChipCores();
switch (esp_reset_reason()) {
default:
[[fallthrough]];
case ESP_RST_UNKNOWN:
obj[F("reboot_reason")] = F("Unknown");
break;
case ESP_RST_POWERON:
obj[F("reboot_reason")] = F("Power on");
break;
case ESP_RST_EXT:
obj[F("reboot_reason")] = F("External");
break;
case ESP_RST_SW:
obj[F("reboot_reason")] = F("Software");
break;
case ESP_RST_PANIC:
obj[F("reboot_reason")] = F("Panic");
break;
case ESP_RST_INT_WDT:
obj[F("reboot_reason")] = F("Interrupt Watchdog");
break;
case ESP_RST_TASK_WDT:
obj[F("reboot_reason")] = F("Task Watchdog");
break;
case ESP_RST_WDT:
obj[F("reboot_reason")] = F("Watchdog");
break;
case ESP_RST_DEEPSLEEP:
obj[F("reboot_reason")] = F("Deepsleep");
break;
case ESP_RST_BROWNOUT:
obj[F("reboot_reason")] = F("Brownout");
break;
case ESP_RST_SDIO:
obj[F("reboot_reason")] = F("SDIO");
break;
}
#else
obj[F("core_version")] = ESP.getCoreVersion();
obj[F("reboot_reason")] = ESP.getResetReason();
#endif
}
void getMemoryInfo(JsonObject obj) {
obj[F("heap_frag")] = mHeapFrag;
obj[F("heap_max_free_blk")] = mHeapFreeBlk;
obj[F("heap_free")] = mHeapFree;
obj[F("par_size_app0")] = ESP.getFreeSketchSpace();
obj[F("par_used_app0")] = ESP.getSketchSize();
#if defined(ESP32)
obj[F("heap_total")] = ESP.getHeapSize();
const esp_partition_t *partition = esp_partition_find_first(ESP_PARTITION_TYPE_DATA, ESP_PARTITION_SUBTYPE_DATA_COREDUMP, "coredump");
if (partition != NULL)
obj[F("flash_size")] = partition->address + partition->size;
obj[F("par_size_spiffs")] = LittleFS.totalBytes();
obj[F("par_used_spiffs")] = LittleFS.usedBytes();
#else
obj[F("flash_size")] = ESP.getFlashChipRealSize();
FSInfo info;
LittleFS.info(info);
obj[F("par_used_spiffs")] = info.usedBytes;
obj[F("par_size_spiffs")] = info.totalBytes;
obj[F("heap_total")] = 24*1014; // FIXME: don't know correct value
#endif
} }
#endif
void getRadioNrf(JsonObject obj) { void getRadioNrf(JsonObject obj) {
obj[F("en")] = (bool) mConfig->nrf.enabled; obj[F("en")] = (bool) mConfig->nrf.enabled;

4
src/web/html/api.js

@ -244,6 +244,10 @@ function badge(success, text, second="error") {
return ml("span", {class: "badge badge-" + ((success) ? "success" : second)}, text); return ml("span", {class: "badge badge-" + ((success) ? "success" : second)}, text);
} }
function progress(val) {
return ml("div", {class: "progress"}, ml("div", {class: "progress-bar", style: "width: " + val + "%"}, null))
}
function tabChange(id) { function tabChange(id) {
var els = document.getElementsByClassName("nav-link"); var els = document.getElementsByClassName("nav-link");
[].forEach.call(els, function(e) { [].forEach.call(els, function(e) {

13
src/web/html/style.css

@ -859,3 +859,16 @@ ul {
height: 100%; height: 100%;
overflow: auto; overflow: auto;
} }
.progress {
display: flex;
height: 1rem;
overflow: hidden;
background-color: #e9ecef;
border-radius: .25rem;
}
.progress-bar {
display: flex;
background-color: var(--primary);
}

113
src/web/html/system.html

@ -8,7 +8,7 @@
{#HTML_NAV} {#HTML_NAV}
<div id="wrapper"> <div id="wrapper">
<div id="content"> <div id="content">
<div id="info" class="col-sm-12 col-md-6 mt-3"></div> <div id="info" class="col-sm-12 col-md-10 mt-3"></div>
<div id="html" class="mt-3 mb-3"></div> <div id="html" class="mt-3 mb-3"></div>
</div> </div>
</div> </div>
@ -21,17 +21,31 @@
parseTitle(obj) parseTitle(obj)
} }
function parseUptime(up) {
var days = parseInt(up / 86400) % 365
var hrs = parseInt(up / 3600) % 24
var min = parseInt(up / 60) % 60
var sec = up % 60
var str = days + " day"
if(1 != days)
str += "s"
str += ", " + ("0"+hrs).substr(-2) + ":"
+ ("0"+min).substr(-2) + ":"
+ ("0"+sec).substr(-2)
return ml("span", {}, str)
}
function parseSysInfo(obj) { function parseSysInfo(obj) {
const data = ["sdk", "cpu_freq", "chip_revision", "device_name", lines = [
"chip_model", "chip_cores", "esp_type", "mac", "wifi_rssi", "wifi_channel", "ts_uptime", tr("{#DEVICE_NAME}", obj.device_name),
"flash_size", "sketch_used", "heap_total", "heap_free", "heap_frag", tr("{#UPTIME}", parseUptime(obj.generic.ts_uptime)),
"max_free_blk", "version", "modules", "env", "core_version", "reboot_reason", "is_eth_con"]; tr("{#REBOOT_REASON}", obj.chip.reboot_reason),
tr("{#ENVIRONMENT}", obj.generic.env + " ({#BUILD_OPTIONS}: " + obj.generic.modules + ")"),
lines = []; tr("Version", obj.generic.version + " - " + obj.generic.build),
for (const [key, value] of Object.entries(obj)) { tr("Chip", "CPU: " + obj.chip.cpu_freq + "MHz, " + obj.chip.cores + " Core(s)"),
if(!data.includes(key) || (typeof value == 'undefined')) continue; tr("Chip Model", obj.chip.model)
lines.push(tr(key.replace('_', ' '), value)); ]
}
document.getElementById("info").append( document.getElementById("info").append(
headline("System Information"), headline("System Information"),
@ -47,9 +61,9 @@
function irqBadge(state) { function irqBadge(state) {
switch(state) { switch(state) {
case 0: return badge(false, "{#UNKNOWN}", "warning"); break; case 0: return badge(false, "unknown", "warning"); break;
case 1: return badge(true, "{#TRUE}"); break; case 1: return badge(true, "true"); break;
default: return badge(false, "{#FALSE}"); break; default: return badge(false, "false"); break;
} }
} }
@ -58,16 +72,16 @@
if(obj.radioNrf.en) { if(obj.radioNrf.en) {
lines = [ lines = [
tr("NRF24L01", badge(obj.radioNrf.isconnected, ((obj.radioNrf.isconnected) ? "" : "{#NOT} ") + "{#CONNECTED}")), tr("NRF24L01", badge(obj.radioNrf.isconnected, ((obj.radioNrf.isconnected) ? "" : "not ") + "connected")),
tr("{#IRQ_WORKING}", irqBadge(obj.radioNrf.irqOk)), tr("Interrupt Pin working", irqBadge(obj.radioNrf.irqOk)),
tr("{#NRF24_DATA_RATE}", dr[obj.radioNrf.dataRate] + "bps"), tr("NRF24 Data Rate", dr[obj.radioNrf.dataRate] + "bps"),
tr("DTU Radio ID", obj.radioNrf.sn) tr("DTU Radio ID", obj.radioNrf.sn)
]; ];
} else } else
lines = [tr("NRF24L01", badge(false, "{#NOT_ENABLED}"))]; lines = [tr("NRF24L01", badge(false, "not enabled"))];
document.getElementById("info").append( document.getElementById("info").append(
headline("{#NRF24_RADIO}"), headline("Radio NRF24"),
ml("table", {class: "table"}, ml("table", {class: "table"},
ml("tbody", {}, lines) ml("tbody", {}, lines)
) )
@ -76,15 +90,15 @@
/*IF_ESP32*/ /*IF_ESP32*/
if(obj.radioCmt.en) { if(obj.radioCmt.en) {
cmt = [ cmt = [
tr("CMT2300A", badge(obj.radioCmt.isconnected, ((obj.radioCmt.isconnected) ? "" : "{#NOT} ") + "{#CONNECTED}")), tr("CMT2300A", badge(obj.radioCmt.isconnected, ((obj.radioCmt.isconnected) ? "" : "not ") + "connected")),
tr("{#IRQ_WORKING}", irqBadge(obj.radioCmt.irqOk)), tr("Interrupt Pin working", irqBadge(obj.radioCmt.irqOk)),
tr("DTU Radio ID", obj.radioCmt.sn) tr("DTU Radio ID", obj.radioCmt.sn)
]; ];
} else } else
cmt = [tr("CMT2300A", badge(false, "{#NOT_ENABLED}"))]; cmt = [tr("CMT2300A", badge(false, "not enabled"))];
document.getElementById("info").append( document.getElementById("info").append(
headline("{#CMT_RADIO}"), headline("Radio CMT"),
ml("table", {class: "table"}, ml("table", {class: "table"},
ml("tbody", {}, cmt) ml("tbody", {}, cmt)
) )
@ -92,16 +106,32 @@
/*ENDIF_ESP32*/ /*ENDIF_ESP32*/
} }
function parseNetwork(obj, gen) {
lines = [
tr("connection", ((obj.wired) ? "{#WIRED}" : "{#WIFI} (SSID: " + obj.ssid + ", RSSI: " + gen.wifi_rssi + ", CH: " + obj.wifi_channel + ")")),
tr("Hostname", gen.host),
tr("IP {#ADDRESS}", obj.ip),
tr("MAC {#ADDRESS}", obj.mac)
]
document.getElementById("info").append(
headline("{#NETWORK}"),
ml("table", {class: "table"},
ml("tbody", {}, lines)
)
);
}
function parseMqtt(obj) { function parseMqtt(obj) {
if(obj.enabled) { if(obj.enabled) {
lines = [ lines = [
tr("{#CONNECTED}", badge(obj.connected, ((obj.connected) ? "{#TRUE}" : "{#FALSE}"))), tr("connected", badge(obj.connected, ((obj.connected) ? "true" : "false"))),
tr("#TX", obj.tx_cnt), tr("#TX", obj.tx_cnt),
tr("#RX", obj.rx_cnt) tr("#RX", obj.rx_cnt)
]; ]
} else } else
lines = tr("{#ENABLED}", badge(false, "{#FALSE}")); lines = tr("enabled", badge(false, "false"));
document.getElementById("info").append( document.getElementById("info").append(
headline("MqTT"), headline("MqTT"),
@ -111,30 +141,34 @@
); );
} }
/*IF_ETHERNET*/ function parseMemory(obj) {
function parseEthernet(obj) { lines = [
lines = tr("{#CONNECTION_TYPE}", ((obj.wired) ? "{#WIRED}" : "{#WIFI}")); tr("Flash size", obj.flash_size / 1024 / 1024 + "MB"),
tr("{#CONFIG_PARTITION} (" + Math.round(obj.par_used_spiffs / 1024) + "kB of " + obj.par_size_spiffs / 1024 + "kB)", progress(obj.par_used_spiffs / obj.par_size_spiffs * 100)),
tr("{#FIRMWARE_PARTITION} (" + Math.round(obj.par_used_app0 / 1024) + "kB of " + obj.par_size_app0 / 1024 + "kB)", progress(obj.par_used_app0 / obj.par_size_app0 * 100)),
tr("Heap (" + Math.round(obj.heap_free / 1024) + "kB of " + Math.round(obj.heap_total / 1024) + "kB)", progress(obj.heap_free / obj.heap_total * 100)),
tr("Heap max free block", Math.round(obj.heap_max_free_blk / 1024) + "kB (Fragmentation: " + obj.heap_frag + ")")
]
document.getElementById("info").append( document.getElementById("info").append(
headline("{#NETWORK}"), headline("{#MEMORY}"),
ml("table", {class: "table"}, ml("table", {class: "table"},
ml("tbody", {}, lines) ml("tbody", {}, lines)
) )
); );
} }
/*ENDIF_ETHERNET*/
function parseIndex(obj) { function parseIndex(obj) {
if(obj.ts_sunrise > 0) { if(obj.ts_sunrise > 0) {
document.getElementById("info").append( document.getElementById("info").append(
headline("{#SUN}"), headline("Sun"),
ml("table", {class: "table"}, ml("table", {class: "table"},
ml("tbody", {}, [ ml("tbody", {}, [
tr("{#SUNRISE}", new Date(obj.ts_sunrise * 1000).toLocaleString('de-DE')), tr("sunrise", new Date(obj.ts_sunrise * 1000).toLocaleString('de-DE')),
tr("{#SUNSET}", new Date(obj.ts_sunset * 1000).toLocaleString('de-DE')), tr("sunset", new Date(obj.ts_sunset * 1000).toLocaleString('de-DE')),
tr("{#COMMUNICATION_START}", new Date((obj.ts_sunrise + obj.ts_offsSr) * 1000).toLocaleString('de-DE')), tr("Communication start", new Date((obj.ts_sunrise + obj.ts_offsSr) * 1000).toLocaleString('de-DE')),
tr("{#COMMUNICATION_STOP}", new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE')), tr("Communication stop", new Date((obj.ts_sunset + obj.ts_offsSs) * 1000).toLocaleString('de-DE')),
tr("{#NIGHT_BEHAVE}", badge(obj.disNightComm, ((obj.disNightComm) ? "{#NOT}" : "") + " {#COMMUNICATING}", "warning")) tr("Night behaviour", badge(obj.disNightComm, ((obj.disNightComm) ? "not" : "") + " communicating", "warning"))
]) ])
) )
); );
@ -152,10 +186,9 @@
document.getElementsByTagName('head')[0].appendChild(meta); document.getElementsByTagName('head')[0].appendChild(meta);
} else if(null != obj.system) { } else if(null != obj.system) {
parseRadio(obj.system) parseRadio(obj.system)
parseNetwork(obj.system.network, obj.system.generic)
parseMqtt(obj.system.mqtt) parseMqtt(obj.system.mqtt)
/*IF_ETHERNET*/ parseMemory(obj.system.memory)
parseEthernet(obj.system.eth)
/*ENDIF_ETHERNET*/
parseSysInfo(obj.system) parseSysInfo(obj.system)
getAjax('/api/index', parseIndex) getAjax('/api/index', parseIndex)
} }

50
src/web/lang.json

@ -927,6 +927,56 @@
"token": "WIFI", "token": "WIFI",
"en": "WiFi", "en": "WiFi",
"de": "WiFi" "de": "WiFi"
},
{
"token": "DEVICE_NAME",
"en": "Device name",
"de": "Ger&auml;tename"
},
{
"token": "UPTIME",
"en": "Uptime",
"de": "Laufzeit"
},
{
"token": "REBOOT_REASON",
"en": "Reboot reason",
"de": "Grund des Neustarts"
},
{
"token": "ENVIRONMENT",
"en": "Environment",
"de": "Umgebung"
},
{
"token": "BUILD_OPTIONS",
"en": "build options",
"de": "Module"
},
{
"token": "ADDRESS",
"en": "Address",
"de": "Adresse"
},
{
"token": "NETWORK",
"en": "Network",
"de": "Netzwerk"
},
{
"token": "MEMORY",
"en": "Memory",
"de": "Speicher"
},
{
"token": "CONFIG_PARTITION",
"en": "Config Partition",
"de": "Konfiguration"
},
{
"token": "FIRMWARE_PARTITION",
"en": "Firmware Partition",
"de": "Firmware"
} }
] ]
}, },

Loading…
Cancel
Save