Systems: P25 trunked / P25 conventional / analog as one choice (node-26#24)

- system_config.normalize(): a P25 system with config.mode "conventional"
  carries config.channels [{freq MHz, name, nac?}] (1-2, within 1.5 MHz) and
  can no longer carry control channels (422). A missing mode is trunked and
  passes through untouched, so there is no migration. An analog channel is
  mirrored into control_channels for older nodes.
- talkgroups.name_from_system resolves the edge node's synthetic per-channel
  id (freq in 100 Hz units) to the channel name.
- The checkin persists radio_channels (conventional channels + encryption).
- Systems editor: Type = P25 trunked / P25 conventional / Analog (NBFM) /
  DMR, plus a channel-row editor for conventional and a one-frequency form for
  analog. The node page shows conventional channels and an encryption notice.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Logan Cusano
2026-10-04 15:55:34 -04:00
co-authored by Claude Opus 5.5
parent ae0ece9d2c
commit 23860eb31b
9 changed files with 649 additions and 41 deletions
+16
View File
@@ -43,6 +43,20 @@ export interface AuditEntry {
timestamp: string;
}
/** One conventional channel as the node reports it (node-26#24). */
export interface RadioChannel {
name: string;
freq: number | null; // Hz
nac: number | null;
encrypted: boolean; // the channel's most recent call was encrypted
encrypted_now: boolean;
enc_calls: number;
clear_calls: number;
algid: number | null;
keyid: number | null;
voice: boolean;
}
export interface NodeRecord {
node_id: string;
name: string;
@@ -68,6 +82,8 @@ export interface NodeRecord {
/** The dongle OP25 is actually using, per the node. */
op25_sdr_serial?: string | null;
sdr_count?: number | null; // null = never reported
/** node-26#24: conventional channels from the last checkin; [] on a trunked system. */
radio_channels?: RadioChannel[] | null;
enforce_override_timeout?: boolean;
is_overridden?: boolean;
override_system_id?: string | null;