Add auxiliary monitor configuration and enhance trigger logic for KVM switching

This commit is contained in:
Lago
2026-03-27 15:36:37 +01:00
parent 208ad243a7
commit c8ab5ad9bc
7 changed files with 310 additions and 43 deletions
+53 -2
View File
@@ -266,7 +266,13 @@
<option value="HDMI">HDMI</option>
</select>
</label>
<p class="hint">The selected port is saved locally in <code>config.json</code>.</p>
<label class="field" for="aux-monitor">
<span>Auxiliary Trigger Monitor</span>
<select id="aux-monitor">
<option value="">Auto-detect</option>
</select>
</label>
<p class="hint">Port and auxiliary monitor are saved locally in <code>config.json</code>.</p>
<div class="actions">
<button id="save-btn" type="submit">Save Settings</button>
</div>
@@ -287,6 +293,7 @@
const els = {
form: document.getElementById("settings-form"),
port: document.getElementById("device-port"),
auxMonitor: document.getElementById("aux-monitor"),
saveBtn: document.getElementById("save-btn"),
msg: document.getElementById("form-message"),
stats: document.getElementById("stats"),
@@ -303,16 +310,55 @@
return `<div class="stat"><span class="k">${label}</span><span class="v">${safe(value)}</span></div>`;
}
function escapeHtml(text) {
return String(text)
.replaceAll("&", "&amp;")
.replaceAll("<", "&lt;")
.replaceAll(">", "&gt;")
.replaceAll("\"", "&quot;")
.replaceAll("'", "&#39;");
}
function renderAuxiliaryMonitorOptions(payloadCandidates, configuredAuxId) {
const candidates = Array.isArray(payloadCandidates) ? payloadCandidates : [];
const currentValue = els.auxMonitor.value || "";
const desiredValue = formDirty ? currentValue : (configuredAuxId || "");
const options = ['<option value="">Auto-detect</option>'];
for (const candidate of candidates) {
if (!candidate || !candidate.id) {
continue;
}
const label = candidate.label || candidate.id;
const inputCode = candidate.input_code === null || candidate.input_code === undefined
? "n/a"
: String(candidate.input_code);
options.push(
`<option value="${escapeHtml(candidate.id)}">${escapeHtml(label)} (input: ${escapeHtml(inputCode)})</option>`
);
}
els.auxMonitor.innerHTML = options.join("");
const desiredExists = [...els.auxMonitor.options].some((opt) => opt.value === desiredValue);
els.auxMonitor.value = desiredExists ? desiredValue : "";
}
function renderStatus(payload) {
const config = payload.config || {};
const portVal = config.device_port;
const auxMonitorVal = config.auxiliary_monitor_id;
if (!formDirty && document.activeElement !== els.port) {
els.port.value = portVal ?? "DP1";
}
if (document.activeElement !== els.auxMonitor || !formDirty) {
renderAuxiliaryMonitorOptions(payload.trigger_monitor_candidates, auxMonitorVal);
}
els.stats.innerHTML = [
stat("This Device Port", config.device_port),
stat("Configured Aux Monitor", config.auxiliary_monitor_id),
stat("Active Trigger Monitor", payload.active_trigger_monitor_id),
stat("Samsung Present", payload.samsung_present ? "Yes" : "No"),
stat("Trigger Input", payload.trigger_input_code),
stat("Trigger Target Port", payload.trigger_target_port),
@@ -359,6 +405,7 @@
event.preventDefault();
const port = els.port.value;
const auxiliaryMonitorId = els.auxMonitor.value || null;
if (!port) {
els.msg.className = "message error";
@@ -376,6 +423,7 @@
headers: { "Content-Type": "application/json" },
body: JSON.stringify({
device_port: port,
auxiliary_monitor_id: auxiliaryMonitorId,
}),
});
@@ -400,7 +448,7 @@
formDirty = false;
renderStatus(payload);
els.msg.className = "message ok";
els.msg.textContent = "Settings saved. Poller now uses this device port.";
els.msg.textContent = "Settings saved. Poller now uses this port and auxiliary monitor selection.";
} catch (error) {
els.msg.className = "message error";
els.msg.textContent = error.message;
@@ -412,6 +460,9 @@
els.port.addEventListener("change", () => {
formDirty = true;
});
els.auxMonitor.addEventListener("change", () => {
formDirty = true;
});
els.form.addEventListener("submit", saveSettings);
loadStatus(true);
setInterval(() => loadStatus(false), 1500);