Scanner manual entry uses validated /api/listen; drop Hold mock; flag analog as live-only (node-26#20)
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
10f7db0a2c
commit
797e14481b
@@ -182,6 +182,7 @@ def build_checks(f: Dict[str, Any]) -> List[Dict[str, str]]:
|
|||||||
freq = _mhz(chans[0].get("freq")) if chans else None
|
freq = _mhz(chans[0].get("freq")) if chans else None
|
||||||
checks.append(_check(
|
checks.append(_check(
|
||||||
"decode", "Decoding", OK, f"Tuned to {freq or 'the analog frequency'} (analog FM — no decoding needed).",
|
"decode", "Decoding", OK, f"Tuned to {freq or 'the analog frequency'} (analog FM — no decoding needed).",
|
||||||
|
"Live listening only: analog calls are not recorded or uploaded yet (node-26#20).",
|
||||||
))
|
))
|
||||||
else:
|
else:
|
||||||
trunk = console.get("trunk") or []
|
trunk = console.get("trunk") or []
|
||||||
|
|||||||
@@ -124,7 +124,7 @@
|
|||||||
}
|
}
|
||||||
.softkey:last-child { border-right: none; }
|
.softkey:last-child { border-right: none; }
|
||||||
|
|
||||||
/* Overlay UI (Volume, Hold) */
|
/* Overlay UI (Volume, status) */
|
||||||
.overlay {
|
.overlay {
|
||||||
position: absolute;
|
position: absolute;
|
||||||
top: 50%; left: 50%;
|
top: 50%; left: 50%;
|
||||||
@@ -153,7 +153,6 @@
|
|||||||
<ul>
|
<ul>
|
||||||
<li><span>Up Arrow</span> Volume Up</li>
|
<li><span>Up Arrow</span> Volume Up</li>
|
||||||
<li><span>Down Arrow</span> Volume Down</li>
|
<li><span>Down Arrow</span> Volume Down</li>
|
||||||
<li><span>Enter / H</span> Toggle Hold (UI mock)</li>
|
|
||||||
<li><span>P</span> Play/Pause Stream</li>
|
<li><span>P</span> Play/Pause Stream</li>
|
||||||
<li><span>S</span> Select System</li>
|
<li><span>S</span> Select System</li>
|
||||||
<li><span>R</span> Revert Override</li>
|
<li><span>R</span> Revert Override</li>
|
||||||
@@ -211,7 +210,7 @@
|
|||||||
<div class="softkey">PLAY (P)</div>
|
<div class="softkey">PLAY (P)</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="overlay" id="overlay">HOLD</div>
|
<div class="overlay" id="overlay"></div>
|
||||||
|
|
||||||
<!-- Audio element for local playback -->
|
<!-- Audio element for local playback -->
|
||||||
<audio id="audio-player" autoplay></audio>
|
<audio id="audio-player" autoplay></audio>
|
||||||
@@ -230,7 +229,6 @@
|
|||||||
const elOverlay = document.getElementById('overlay');
|
const elOverlay = document.getElementById('overlay');
|
||||||
|
|
||||||
let currentIcecastUrl = null;
|
let currentIcecastUrl = null;
|
||||||
let isHolding = false;
|
|
||||||
let volume = 1.0;
|
let volume = 1.0;
|
||||||
|
|
||||||
// Clock updater
|
// Clock updater
|
||||||
@@ -372,25 +370,20 @@
|
|||||||
}
|
}
|
||||||
closeSystemModal();
|
closeSystemModal();
|
||||||
showOverlay("APPLYING MANUAL", 3000);
|
showOverlay("APPLYING MANUAL", 3000);
|
||||||
const manualConfig = {
|
// Same validated path as the dashboard's "Listen locally" (MHz range check).
|
||||||
system_id: "manual-override",
|
const mode = typeVal === 'NBFM' ? 'analog' : 'p25';
|
||||||
name: `Freq ${freqVal} (${typeVal})`,
|
const freqs = freqVal.split(/[\s,;]+/).filter(Boolean).map(Number);
|
||||||
type: typeVal,
|
|
||||||
config: {
|
|
||||||
control_channels: [freqVal],
|
|
||||||
talkgroups: []
|
|
||||||
}
|
|
||||||
};
|
|
||||||
try {
|
try {
|
||||||
const res = await fetch('/api/config/override', {
|
const res = await fetch('/api/listen', {
|
||||||
method: 'POST',
|
method: 'POST',
|
||||||
headers: { 'Content-Type': 'application/json' },
|
headers: { 'Content-Type': 'application/json' },
|
||||||
body: JSON.stringify({ system_config: manualConfig })
|
body: JSON.stringify({ mode, frequencies: freqs })
|
||||||
});
|
});
|
||||||
if (res.ok) {
|
if (res.ok) {
|
||||||
showOverlay('MANUAL OVERRIDE OK', 1500);
|
showOverlay('MANUAL OK', 1500);
|
||||||
} else {
|
} else {
|
||||||
showOverlay('MANUAL OVERRIDE FAIL', 2000);
|
const d = await res.json().catch(() => ({}));
|
||||||
|
showOverlay((d.detail || 'MANUAL FAILED').slice(0, 60), 4000);
|
||||||
}
|
}
|
||||||
} catch (err) {
|
} catch (err) {
|
||||||
showOverlay('ERROR APPLYING', 2000);
|
showOverlay('ERROR APPLYING', 2000);
|
||||||
@@ -443,9 +436,6 @@
|
|||||||
audioPlayer.volume = volume;
|
audioPlayer.volume = volume;
|
||||||
elVol.textContent = `VOL: ${Math.round(volume * 100)}%`;
|
elVol.textContent = `VOL: ${Math.round(volume * 100)}%`;
|
||||||
showOverlay(`VOL: ${Math.round(volume * 100)}%`);
|
showOverlay(`VOL: ${Math.round(volume * 100)}%`);
|
||||||
} else if (e.key === 'Enter' || e.key === 'h' || e.key === 'H') {
|
|
||||||
isHolding = !isHolding;
|
|
||||||
showOverlay(isHolding ? 'HOLD ON' : 'HOLD OFF');
|
|
||||||
} else if (e.key === 'p' || e.key === 'P') {
|
} else if (e.key === 'p' || e.key === 'P') {
|
||||||
if (audioPlayer.paused) {
|
if (audioPlayer.paused) {
|
||||||
audioPlayer.play();
|
audioPlayer.play();
|
||||||
|
|||||||
@@ -126,6 +126,7 @@ def test_analog_needs_no_control_channel():
|
|||||||
console={"last_poll_epoch": now, "channels": [{"freq": 154430000}], "trunk": [], "last_heard": None},
|
console={"last_poll_epoch": now, "channels": [{"freq": 154430000}], "trunk": [], "last_heard": None},
|
||||||
)))
|
)))
|
||||||
assert c["decode"]["state"] == "ok" and "154.4300 MHz" in c["decode"]["summary"]
|
assert c["decode"]["state"] == "ok" and "154.4300 MHz" in c["decode"]["summary"]
|
||||||
|
assert "not recorded" in c["decode"]["action"]
|
||||||
assert "this dashboard" in c["source"]["summary"]
|
assert "this dashboard" in c["source"]["summary"]
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user