Add multi-decoder split and pit timing support
This commit is contained in:
@@ -43,7 +43,10 @@ export function renderSettings(deps) {
|
||||
} = deps;
|
||||
const ammcStatus = ammc.status || {};
|
||||
const ammcOutput = Array.isArray(ammcStatus.lastOutput) ? ammcStatus.lastOutput : [];
|
||||
const suggestedWsUrl = getManagedWsUrl();
|
||||
const suggestedWsUrl = getManagedWsUrl("main");
|
||||
const suggestedSplitWsUrl = getManagedWsUrl("split");
|
||||
const suggestedPitEntryWsUrl = getManagedWsUrl("pit_entry");
|
||||
const suggestedPitExitWsUrl = getManagedWsUrl("pit_exit");
|
||||
const running = Boolean(ammcStatus.running);
|
||||
const speechVoices = getSpeechVoices();
|
||||
const speechVoiceOptions = speechVoices
|
||||
@@ -54,7 +57,13 @@ export function renderSettings(deps) {
|
||||
<section class="panel">
|
||||
<div class="panel-header"><h3>${t("settings.decoder")}</h3></div>
|
||||
<form id="settingsForm" class="panel-body form-grid cols-3 settings-grid">
|
||||
<input name="wsUrl" value="${escapeHtml(state.settings.wsUrl)}" placeholder="ws://127.0.0.1:9000" />
|
||||
<p class="hint form-grid-full">${t("settings.decoder_roles_hint")}</p>
|
||||
<label><span>${t("settings.main_ws_url")}</span><input name="wsUrl" value="${escapeHtml(state.settings.wsUrl)}" placeholder="ws://127.0.0.1:9000" /></label>
|
||||
<label class="toggle"><input type="checkbox" name="splitDecoderEnabled" ${state.settings.splitDecoderEnabled ? "checked" : ""} /><span>${t("settings.enable_split_decoder")}</span></label>
|
||||
<label><span>${t("settings.split_ws_url")}</span><input name="splitWsUrl" value="${escapeHtml(state.settings.splitWsUrl || "")}" placeholder="ws://127.0.0.1:9001" /></label>
|
||||
<label class="toggle"><input type="checkbox" name="pitDecoderEnabled" ${state.settings.pitDecoderEnabled ? "checked" : ""} /><span>${t("settings.enable_pit_decoders")}</span></label>
|
||||
<label><span>${t("settings.pit_entry_ws_url")}</span><input name="pitEntryWsUrl" value="${escapeHtml(state.settings.pitEntryWsUrl || "")}" placeholder="ws://127.0.0.1:9002" /></label>
|
||||
<label><span>${t("settings.pit_exit_ws_url")}</span><input name="pitExitWsUrl" value="${escapeHtml(state.settings.pitExitWsUrl || "")}" placeholder="ws://127.0.0.1:9003" /></label>
|
||||
<input name="backendUrl" value="${escapeHtml(
|
||||
state.settings.backendUrl || getDefaultBackendUrl()
|
||||
)}" placeholder="http://127.0.0.1:8081" />
|
||||
@@ -217,6 +226,7 @@ export function renderSettings(deps) {
|
||||
<section class="panel mt-16">
|
||||
<div class="panel-header"><h3>${t("settings.managed_ammc")}</h3></div>
|
||||
<form id="ammcForm" class="panel-body form-grid cols-2 settings-grid">
|
||||
<p class="hint form-grid-full">${t("settings.managed_channels_hint")}</p>
|
||||
<label class="toggle">
|
||||
<input type="checkbox" name="managedEnabled" ${ammc.config.managedEnabled ? "checked" : ""} />
|
||||
<span>${t("settings.enable_managed")}</span>
|
||||
@@ -225,11 +235,21 @@ export function renderSettings(deps) {
|
||||
<input type="checkbox" name="autoStart" ${ammc.config.autoStart ? "checked" : ""} />
|
||||
<span>${t("settings.auto_start_ammc")}</span>
|
||||
</label>
|
||||
<input name="decoderHost" value="${escapeHtml(ammc.config.decoderHost || "")}" placeholder="${t("settings.decoder_host")}" />
|
||||
<input name="wsPort" value="${escapeHtml(String(ammc.config.wsPort || 9000))}" placeholder="9000" />
|
||||
<input name="executablePath" value="${escapeHtml(ammc.config.executablePath || "")}" placeholder="${t("settings.executable_path")}" />
|
||||
<input name="workingDirectory" value="${escapeHtml(ammc.config.workingDirectory || "")}" placeholder="${t("settings.working_dir")}" />
|
||||
<input name="extraArgs" value="${escapeHtml(ammc.config.extraArgs || "")}" placeholder="${t("settings.extra_args")}" />
|
||||
<label><span>${t("timing.main_decoder")} - ${t("settings.decoder_host")}</span><input name="decoderHost" value="${escapeHtml(ammc.config.decoderHost || "")}" placeholder="192.168.1.10" /></label>
|
||||
<label><span>${t("timing.main_decoder")} - ${t("settings.ws_port")}</span><input name="wsPort" value="${escapeHtml(String(ammc.config.wsPort || 9000))}" placeholder="9000" /></label>
|
||||
<label class="toggle"><input type="checkbox" name="splitEnabled" ${ammc.config.splitEnabled ? "checked" : ""} /><span>${t("settings.enable_split_decoder")}</span></label>
|
||||
<span></span>
|
||||
<label><span>${t("settings.split_decoder_host")}</span><input name="splitDecoderHost" value="${escapeHtml(ammc.config.splitDecoderHost || "")}" placeholder="192.168.1.11" /></label>
|
||||
<label><span>${t("timing.split_decoder")} - ${t("settings.ws_port")}</span><input name="splitWsPort" value="${escapeHtml(String(ammc.config.splitWsPort || 9001))}" placeholder="9001" /></label>
|
||||
<label class="toggle"><input type="checkbox" name="pitEnabled" ${ammc.config.pitEnabled ? "checked" : ""} /><span>${t("settings.enable_pit_decoders")}</span></label>
|
||||
<span></span>
|
||||
<label><span>${t("settings.pit_entry_decoder_host")}</span><input name="pitEntryDecoderHost" value="${escapeHtml(ammc.config.pitEntryDecoderHost || "")}" placeholder="192.168.1.12" /></label>
|
||||
<label><span>${t("timing.pit_entry_decoder")} - ${t("settings.ws_port")}</span><input name="pitEntryWsPort" value="${escapeHtml(String(ammc.config.pitEntryWsPort || 9002))}" placeholder="9002" /></label>
|
||||
<label><span>${t("settings.pit_exit_decoder_host")}</span><input name="pitExitDecoderHost" value="${escapeHtml(ammc.config.pitExitDecoderHost || "")}" placeholder="192.168.1.13" /></label>
|
||||
<label><span>${t("timing.pit_exit_decoder")} - ${t("settings.ws_port")}</span><input name="pitExitWsPort" value="${escapeHtml(String(ammc.config.pitExitWsPort || 9003))}" placeholder="9003" /></label>
|
||||
<label><span>${t("settings.executable_path")}</span><input name="executablePath" value="${escapeHtml(ammc.config.executablePath || "")}" placeholder="${t("settings.executable_path")}" /></label>
|
||||
<label><span>${t("settings.working_dir")}</span><input name="workingDirectory" value="${escapeHtml(ammc.config.workingDirectory || "")}" placeholder="${t("settings.working_dir")}" /></label>
|
||||
<label><span>${t("settings.extra_args")}</span><input name="extraArgs" value="${escapeHtml(ammc.config.extraArgs || "")}" placeholder="${t("settings.extra_args")}" /></label>
|
||||
<div class="actions">
|
||||
<button class="btn btn-primary" type="submit">${t("settings.save_ammc")}</button>
|
||||
<button id="ammcRefresh" class="btn" type="button">${t("settings.refresh_ammc")}</button>
|
||||
@@ -250,12 +270,14 @@ export function renderSettings(deps) {
|
||||
<p>${ammcStatus.executableExists ? t("settings.executable_found") : t("settings.executable_missing")}</p>
|
||||
<p>${t("settings.decoder_host")}: <strong>${escapeHtml(String(ammc.config.decoderHost || "-"))}</strong></p>
|
||||
<p>${t("settings.ws_port")}: <strong>${escapeHtml(String(ammc.config.wsPort || 9000))}</strong></p>
|
||||
${ammc.config.splitEnabled ? `<p>${t("timing.split_decoder")}: <strong>${ammcStatus.split?.running ? t("settings.running") : t("settings.stopped")}</strong> • ${escapeHtml(String(ammc.config.splitDecoderHost || "-"))}:${escapeHtml(String(ammc.config.splitWsPort || 9001))}${ammcStatus.split?.lastError ? ` • <span class="error">${escapeHtml(ammcStatus.split.lastError)}</span>` : ""}</p>` : ""}
|
||||
${ammc.config.pitEnabled ? `<p>${t("timing.pit_entry_decoder")}: <strong>${ammcStatus.pitEntry?.running ? t("settings.running") : t("settings.stopped")}</strong> • ${escapeHtml(String(ammc.config.pitEntryDecoderHost || "-"))}:${escapeHtml(String(ammc.config.pitEntryWsPort || 9002))}${ammcStatus.pitEntry?.lastError ? ` • <span class="error">${escapeHtml(ammcStatus.pitEntry.lastError)}</span>` : ""}</p><p>${t("timing.pit_exit_decoder")}: <strong>${ammcStatus.pitExit?.running ? t("settings.running") : t("settings.stopped")}</strong> • ${escapeHtml(String(ammc.config.pitExitDecoderHost || "-"))}:${escapeHtml(String(ammc.config.pitExitWsPort || 9003))}${ammcStatus.pitExit?.lastError ? ` • <span class="error">${escapeHtml(ammcStatus.pitExit.lastError)}</span>` : ""}</p>` : ""}
|
||||
<p>${t("settings.last_error")}: ${escapeHtml(ammc.lastError || ammcStatus.lastError || "-")}</p>
|
||||
<p>${t("settings.backend_url")}: <strong>${escapeHtml(getBackendUrl())}</strong></p>
|
||||
<p>WebSocket URL: <strong>${escapeHtml(suggestedWsUrl)}</strong></p>
|
||||
<pre class="log-box">${escapeHtml(
|
||||
ammcOutput.length
|
||||
? ammcOutput.map((entry) => `[${new Date(entry.ts).toLocaleTimeString()}] ${entry.stream}: ${entry.line}`).join("\n")
|
||||
? ammcOutput.map((entry) => `[${new Date(entry.ts).toLocaleTimeString()}] ${entry.role || "main"}/${entry.stream}: ${entry.line}`).join("\n")
|
||||
: "-"
|
||||
)}</pre>
|
||||
</div>
|
||||
@@ -328,6 +350,11 @@ export function renderSettings(deps) {
|
||||
e.preventDefault();
|
||||
const form = new FormData(e.currentTarget);
|
||||
state.settings.wsUrl = String(form.get("wsUrl") || "").trim();
|
||||
state.settings.splitDecoderEnabled = form.get("splitDecoderEnabled") === "on";
|
||||
state.settings.splitWsUrl = String(form.get("splitWsUrl") || "").trim();
|
||||
state.settings.pitDecoderEnabled = form.get("pitDecoderEnabled") === "on";
|
||||
state.settings.pitEntryWsUrl = String(form.get("pitEntryWsUrl") || "").trim();
|
||||
state.settings.pitExitWsUrl = String(form.get("pitExitWsUrl") || "").trim();
|
||||
state.settings.backendUrl = String(form.get("backendUrl") || "").trim();
|
||||
state.settings.autoReconnect = form.get("autoReconnect") === "on";
|
||||
applyAudioFormValues();
|
||||
@@ -543,6 +570,14 @@ export function renderSettings(deps) {
|
||||
autoStart: form.get("autoStart") === "on",
|
||||
decoderHost: String(form.get("decoderHost") || "").trim(),
|
||||
wsPort: Number(form.get("wsPort") || 9000),
|
||||
splitEnabled: form.get("splitEnabled") === "on",
|
||||
splitDecoderHost: String(form.get("splitDecoderHost") || "").trim(),
|
||||
splitWsPort: Number(form.get("splitWsPort") || 9001),
|
||||
pitEnabled: form.get("pitEnabled") === "on",
|
||||
pitEntryDecoderHost: String(form.get("pitEntryDecoderHost") || "").trim(),
|
||||
pitEntryWsPort: Number(form.get("pitEntryWsPort") || 9002),
|
||||
pitExitDecoderHost: String(form.get("pitExitDecoderHost") || "").trim(),
|
||||
pitExitWsPort: Number(form.get("pitExitWsPort") || 9003),
|
||||
executablePath: String(form.get("executablePath") || "").trim(),
|
||||
workingDirectory: String(form.get("workingDirectory") || "").trim(),
|
||||
extraArgs: String(form.get("extraArgs") || "").trim(),
|
||||
@@ -565,6 +600,14 @@ export function renderSettings(deps) {
|
||||
autoStart: form.get("autoStart") === "on",
|
||||
decoderHost: String(form.get("decoderHost") || "").trim(),
|
||||
wsPort: Number(form.get("wsPort") || 9000),
|
||||
splitEnabled: form.get("splitEnabled") === "on",
|
||||
splitDecoderHost: String(form.get("splitDecoderHost") || "").trim(),
|
||||
splitWsPort: Number(form.get("splitWsPort") || 9001),
|
||||
pitEnabled: form.get("pitEnabled") === "on",
|
||||
pitEntryDecoderHost: String(form.get("pitEntryDecoderHost") || "").trim(),
|
||||
pitEntryWsPort: Number(form.get("pitEntryWsPort") || 9002),
|
||||
pitExitDecoderHost: String(form.get("pitExitDecoderHost") || "").trim(),
|
||||
pitExitWsPort: Number(form.get("pitExitWsPort") || 9003),
|
||||
executablePath: String(form.get("executablePath") || "").trim(),
|
||||
workingDirectory: String(form.get("workingDirectory") || "").trim(),
|
||||
extraArgs: String(form.get("extraArgs") || "").trim(),
|
||||
@@ -580,7 +623,12 @@ export function renderSettings(deps) {
|
||||
});
|
||||
|
||||
document.getElementById("ammcUseServerWs")?.addEventListener("click", () => {
|
||||
state.settings.wsUrl = getManagedWsUrl();
|
||||
state.settings.wsUrl = suggestedWsUrl;
|
||||
state.settings.splitDecoderEnabled = Boolean(ammc.config.splitEnabled);
|
||||
state.settings.splitWsUrl = suggestedSplitWsUrl;
|
||||
state.settings.pitDecoderEnabled = Boolean(ammc.config.pitEnabled);
|
||||
state.settings.pitEntryWsUrl = suggestedPitEntryWsUrl;
|
||||
state.settings.pitExitWsUrl = suggestedPitExitWsUrl;
|
||||
saveState();
|
||||
renderView();
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user