diff --git a/data/index.html b/data/index.html index 3868839..19f0e35 100644 --- a/data/index.html +++ b/data/index.html @@ -31,6 +31,73 @@ + + RSSI: + Heap: % + PSRAM: % + Uptime: + + Mehr + + + + + + + + Signalstärke + + + + + Uptime + + + + + CPU-Taktfrequenz + MHz + + + + CPU Cycle Count + + + + + Heap + % + / + + + + + PSRAM + % + / + + + + + MAC-Adresse + + + + + SDK-Version + + + + + + Schließen + + + Konfiguration diff --git a/data/status.js b/data/status.js new file mode 100644 index 0000000..37da7ea --- /dev/null +++ b/data/status.js @@ -0,0 +1,88 @@ +const statusDialog = document.querySelector(".dialog-status"); +const expandButton = document.querySelector(".expand-status"); + +expandButton.addEventListener("click", () => { + statusDialog.showModal(); +}); + +async function loadStatus() { + try { + const res = await fetch("/status"); + if (!res.ok) { + throw new Error( + `Response status: ${res.status}\n${await res.text()}` + ); + } + + const data = await res.json(); + console.log(data); + + return data; + } catch (e) { + console.error(e); + return null; + } +} + +function setStatus(status) { + setValue("model", status.chip.model); + setValue("mac", status.chip.mac.toString(16).toUpperCase()); + setValue("sdk-version", status.sdkVersion); + + setValue("rssi", status.connection.signalStrength); + + setValue("cpu-freq", status.chip.cpuFreqMHz); + setValue("cpu-cycle-count", status.chip.cycleCount); + + const usedHeap = status.heap.total - status.heap.free; + setValue("heap-used", formatBytes(usedHeap)); + setValue("heap-total", formatBytes(status.heap.total)); + setValue( + "heap-percentage", + Math.round((usedHeap / status.heap.total) * 100) + ); + + const usedPsram = status.psram.total - status.psram.free; + setValue("psram-used", formatBytes(usedPsram)); + setValue("psram-total", formatBytes(status.psram.total)); + setValue( + "psram-percentage", + Math.round((usedPsram / status.psram.total) * 100) + ); + + setValue("uptime", parseDuration(status.uptime)); +} + +function setValue(className, value) { + document.querySelectorAll("." + className).forEach((element) => { + element.innerText = value; + }); +} + +function parseDuration(ms) { + const date = new Date(ms); + console.log(date); + const time = + date.getUTCHours().toString().padStart(2, "0") + + ":" + + date.getUTCMinutes().toString().padStart(2, "0") + + " h"; + const days = Math.floor(date.getTime() / (1000 * 60 * 60 * 24)); + + return days !== 0 ? `${days} Tage, ${time}` : time; +} + +function formatBytes(bytes) { + const units = ["Bytes", "KB", "MB", "GB"]; + + let value = bytes; + let index = 0; + while (value >= 1000) { + value /= 1000; + index++; + } + + return `${Math.round(value * 10) / 10} ${units[index]}`; +} + +setStatus(await loadStatus()); diff --git a/data/style.css b/data/style.css index a595e33..a664028 100644 --- a/data/style.css +++ b/data/style.css @@ -2,6 +2,7 @@ --color-primary: #087e8b; --color-on-primary: white; --color-background: #222; + --color-surface: #333; --color-danger: #fa2b58; --icon-button-size: 2.5rem; } @@ -141,6 +142,37 @@ label.switch input:checked + .slider::before { translate: -100% -50%; } +dialog { + width: 80%; + max-width: 500px; + max-height: 80%; + overflow: scroll; + background-color: var(--color-background); + color: white; + border: none; + border-radius: 8px; + padding: 16px; +} + +dialog::backdrop { + background-color: #000a; +} + +.card { + background-color: var(--color-surface); + padding: 8px; + border-radius: 8px; +} + +.card > * { + display: block; +} + +.card > :first-child { + color: var(--color-primary); + margin-bottom: 8px; +} + .buttons { display: flex; flex-direction: row; @@ -223,3 +255,27 @@ button.reload { animation-iteration-count: infinite; animation-timing-function: linear; } + +.status { + background-color: var(--color-surface); + padding: 8px; + border-radius: 8px; + + display: flex; + flex-wrap: wrap; + justify-content: space-between; + align-items: center; + gap: 16px; +} + +.dialog-status-content { + display: grid; + grid-template-columns: 1fr 1fr; + gap: 8px; +} + +.dialog-status button { + display: block; + margin: 0 auto; + margin-top: 32px; +}