97 lines
2.9 KiB
JavaScript
97 lines
2.9 KiB
JavaScript
const $ = (sel, root = document) => root.querySelector(sel);
|
|
const $$ = (sel, root = document) => [...root.querySelectorAll(sel)];
|
|
|
|
async function api(path, body) {
|
|
const opts = { method: body ? "POST" : "GET" };
|
|
if (body) {
|
|
opts.headers = { "Content-Type": "application/json" };
|
|
opts.body = JSON.stringify(body);
|
|
}
|
|
const res = await fetch(path, opts);
|
|
return res.json();
|
|
}
|
|
|
|
function formatLog(entries) {
|
|
return entries
|
|
.map((e) => {
|
|
const ts = new Date(e.t).toLocaleTimeString();
|
|
const arrow = e.direction === "out" ? "→" : e.direction === "in" ? "←" : e.direction === "err" ? "✖" : "·";
|
|
return `${ts} ${arrow} ${e.text}`;
|
|
})
|
|
.join("\n");
|
|
}
|
|
|
|
let lastKnownButtons = null;
|
|
|
|
async function refreshStatus() {
|
|
try {
|
|
const s = await api("/api/status");
|
|
$("#status").textContent = s.connected ? "online" : "offline";
|
|
$("#status").className = "status " + (s.connected ? "online" : "offline");
|
|
|
|
if (!lastKnownButtons) {
|
|
$("#brokerUrl").value = s.brokerUrl;
|
|
$("#hbEnabled").checked = s.heartbeatEnabled;
|
|
$("#hbInterval").value = s.heartbeatIntervalMs;
|
|
for (const key of ["start1", "stop1", "start2", "stop2"]) {
|
|
const card = $(`.button-card[data-button="${key}"]`);
|
|
card.querySelector(".mac").value = s.buttons[key].mac;
|
|
card.querySelector(".mv").value = s.buttons[key].voltage;
|
|
card.querySelector(".mv-value").textContent = s.buttons[key].voltage;
|
|
}
|
|
lastKnownButtons = s.buttons;
|
|
}
|
|
|
|
$("#log").textContent = formatLog(s.log);
|
|
$("#log").scrollTop = $("#log").scrollHeight;
|
|
} catch (err) {
|
|
console.error(err);
|
|
}
|
|
}
|
|
|
|
$("#btnConnect").addEventListener("click", async () => {
|
|
await api("/api/connect", { brokerUrl: $("#brokerUrl").value.trim() });
|
|
refreshStatus();
|
|
});
|
|
|
|
$("#btnDisconnect").addEventListener("click", async () => {
|
|
await api("/api/disconnect", {});
|
|
refreshStatus();
|
|
});
|
|
|
|
$("#btnHbApply").addEventListener("click", async () => {
|
|
await api("/api/heartbeat", {
|
|
enabled: $("#hbEnabled").checked,
|
|
intervalMs: parseInt($("#hbInterval").value, 10),
|
|
});
|
|
refreshStatus();
|
|
});
|
|
|
|
$$(".button-card").forEach((card) => {
|
|
const button = card.dataset.button;
|
|
const macInput = card.querySelector(".mac");
|
|
const mvInput = card.querySelector(".mv");
|
|
const mvValue = card.querySelector(".mv-value");
|
|
const pressBtn = card.querySelector(".press");
|
|
|
|
macInput.addEventListener("change", async () => {
|
|
await api("/api/config", { button, mac: macInput.value.trim() });
|
|
});
|
|
|
|
mvInput.addEventListener("input", () => {
|
|
mvValue.textContent = mvInput.value;
|
|
});
|
|
|
|
mvInput.addEventListener("change", async () => {
|
|
await api("/api/battery", { button, voltage: parseInt(mvInput.value, 10) });
|
|
});
|
|
|
|
pressBtn.addEventListener("click", async () => {
|
|
await api("/api/press", { button });
|
|
refreshStatus();
|
|
});
|
|
});
|
|
|
|
refreshStatus();
|
|
setInterval(refreshStatus, 1500);
|