Skip to content

Releases: bakstaaj/N0JCG-SCANNER

N0JCG Scanner v5.0.0

Choose a tag to compare

@bakstaaj bakstaaj released this 08 Sep 18:48

Cleaned up the UI - added footer to the app with current installed version and links

N0JCG Scanner v4.2.7

Choose a tag to compare

@bakstaaj bakstaaj released this 19 Aug 16:17

N0JCG Scanner v4.2.7

Persistent P25 service recovery

The P25 decoder now remains owned by the radio service when the web backend is
restarted. The backend follows the persistent OP25 event log, reconnects to an
already-running decoder, and avoids starting a duplicate process. Decoder
process detection validates the actual command line so transient shell matches
cannot be mistaken for a healthy receiver.

Operator documentation and packaging

  • Documented backend-only restart behavior and the correct Stop workflow.
  • Refreshed the branded user manual to v4.2.7.
  • Published the reproducible N0JCG Scanner v4.2.7 release archive and checksum.

N0JCG Scanner v4.2.5

Choose a tag to compare

@bakstaaj bakstaaj released this 13 Aug 07:13

Updated N0JCG Scanner release including the guided new-Pi installation wizard, automatic required RTL-SDR serial assignment, first-run Radio Setup routing, and updated user documentation.

N0JCG Scanner v4.1.0

Choose a tag to compare

@bakstaaj bakstaaj released this 10 Aug 06:14

N0JCG Scanner v4.1.0

Release date: 2026-08-10

N0JCG Scanner v4.1.0 updates the v4 licensed scanner for the recombined
Raspberry Pi deployment model. The Pi is the complete scanner host; the ROC
provides navigation to the Pi service.

Highlights

  • Recombined the web application, API, audio fanout, P25 decoder, VHF FFT
    scanner, and UHF FFT scanner on the Pi runtime at /home/pi/n0jcg-scanner.
  • Updated deployment and operator documentation to reflect Pi-only runtime
    ownership and the direct scanner URL on port 8070.
  • Corrected production licensing activation payload and Cloudflare-safe client
    identification, including the exact scanner product binding.
  • Fixed dynamic return navigation and refreshed the N0JCG branded desktop and
    mobile assets.
  • Fixed registered-badge visibility and cache invalidation so registered
    installations do not show the registration pill on the main UI.

Validation

  • Full Python suite: 189 tests passed.
  • Browser asset and deployment checks passed.
  • Release archive and SHA-256 checksum generated from the current main
    commit.

N0JCG-SCANNER v3.0.0

Choose a tag to compare

@bakstaaj bakstaaj released this 06 Aug 22:28

PI-SCANNER v3.0.0

This major release separates the browser application from the radio runtime
and hardens continuous audio delivery for multiple simultaneous listeners.

Major changes

  • Hosts the browser application under the existing N0JCG ROC /pi-scanner/
    mount while retaining all RTL-SDR, OP25, FFT scanning, demodulation, and
    audio arbitration on the radio Pi.
  • Adds explicit ROC and radio deployment manifests with role-specific dry-run,
    backup, checksum, deployment, restart, and live-validation commands.
  • Uses relative browser navigation and base-path-aware API/audio requests, so
    the application does not depend on hardcoded browser-facing host addresses.
  • Restores the ROC-dashboard back control adjacent to the menu button.
  • Lets each desktop or mobile browser attach to an already-running scanner
    without restarting the P25, VHF, or UHF services.
  • Replaces per-frame browser playback nodes with a bounded continuous PCM ring
    buffer. The player resamples 8 kHz scanner audio to the browser device rate,
    corrects slow clock drift, and reports underrun and dropped-sample metrics.
  • Retains AudioWorklet support for secure deployments and supplies an
    HTTP-compatible continuous-node implementation for the current LAN ROC.
  • Adds a bounded radio-side jitter recovery window so slightly late decoder
    frames are recovered instead of immediately being replaced by silence.
  • Adds audio packet-gap, late-frame recovery, and active-gap counters to the
    arbitrator status contract.

Runtime ownership

  • ROC application host: static PI Scanner assets and reverse-proxy routes.
  • Radio Pi: P25 decoder, VHF and UHF FFT workers, RTL-SDR ownership, radio API,
    and unified PCM fanout.
  • VHF RTL-SDR serial: 00000144.
  • UHF RTL-SDR serial: 00000440.

Audio validation

  • ROC PCM proxy cadence: 500 consecutive 20 ms frames with zero gaps over
    100 ms and a measured maximum gap near 30 ms.
  • Chromium continuous-player validation: native 48 kHz output, clock-recovered
    queue settling near 110 ms, and no new underruns or dropped samples during
    the extended validation interval.
  • Controlled UHF input test: 750 frames received during a 15-second
    transmission with 749 forwarded by the unified arbitrator.
  • Operator acceptance after the bounded backend jitter update: longer messages
    reported improved.

Validation

  • PYTHONPATH=src python3 -m pytest -q: 169 tests passed.
  • JavaScript syntax checks pass for desktop, mobile, AudioWorklet, and
    HTTP-compatible ring-buffer players.
  • Split-host runtime validation passes ROC health, proxied radio status,
    proxied audio status, direct radio API, direct audio fanout, and served web
    asset checks.
  • Live deployments created recoverable, application-specific backups on both
    the ROC and radio Pi.

Upgrade

From MSYS2 UCRT64, configure the non-secret host and repository fields in
.env, then run:

./tools/deploy_application_to_roc.sh --dry-run
./tools/deploy_radio_to_pi.sh --dry-run
./tools/deploy_application_to_roc.sh --deploy --yes
./tools/deploy_radio_to_pi.sh --deploy --yes --restart
./tools/validate_split_runtime.sh

Deployment credentials remain local in the ignored .env file and are never
included in release artifacts.

N0JCG-SCANNER v2.0.0

Choose a tag to compare

@bakstaaj bakstaaj released this 28 Jul 06:39

PI-SCANNER v2.0.0

This major release replaces the retired v1.0.19 patched VHF path with a
single-owner FFT-directed NFM scanner validated on the deployed Raspberry Pi.

Major changes

  • Binds the VHF scanner to RTL-SDR serial 00000144 and the UHF scanner to
    serial 00000440; the VHF worker fails closed if its serial is reversed.
  • Replaces persistent_vhf_fft_scanner.py and the
    90-persistent-fft.conf service override with the maintained
    vhf_fft_scanner.py worker behind the stable analog_vhf_worker entry point.
  • Surveys only enabled uploaded VHF FM/NFM frequencies across grouped FFT
    spans, validates candidates away from the tuner DC spike, demodulates NFM
    in-process, and forwards 8 kHz mono PCM to the unified audio arbitrator on
    UDP port 23458.
  • Actively drains and discards queued rtl_tcp IQ after sample-rate and tuner
    changes so FFT and narrowband validation use samples from the requested RF
    center.
  • Rejects weak, off-frequency, silent, and noise-only candidates using
    multi-slice carrier and audio evidence while preserving complete calls
    through modulation-related metric dips.
  • Adds learned artifact baselines, signal-rise ranking, cooldown override,
    priority-channel short-circuiting, and separate strong-call carrier hang.
  • Preserves per-frequency validation history, the last successful lock, and a
    bounded vhf_last_call.wav diagnostic containing the exact PCM sent to the
    browser.
  • Makes the analog channel API honor PI_SCANNER_ANALOG_ROOT, keeping channel
    uploads and worker runtime configuration on the same checkout.
  • Updates deployment, service installation, role mapping, hardware smoke
    tests, tuning capture tools, and documentation for the corrected serial
    assignments and new VHF state machine.

Live acceptance

  • VHF receiver: serial 00000144
  • UHF receiver: serial 00000440
  • N0JCG simplex test: 146.600 MHz
  • Measured VHF carrier: approximately 50 dB narrowband SNR
  • Measured frequency error: approximately 27 Hz
  • Result: continuous NFM audio heard in the web application through key-down
  • Additional result: a complete live VHF fire-dispatch transmission was heard
  • Idle noise check: 44 FFT sweeps, 45 candidates rejected, zero false locks,
    and zero unwanted frames before final strong-call tuning
  • Unified audio arbitrator: VHF packets accepted and forwarded with zero
    rejected packets during acceptance testing

Validation

  • 17 focused VHF unit and regression tests pass.
  • Python compilation, JSON/schema checks, shell syntax, whitespace checks,
    isolated RTL hardware PCM smoke, UDP-to-HTTP bridge smoke, serial ownership,
    FFT sweep, service state, and web channel API checks pass.
  • The deployment workflow creates a recoverable Pi backup before replacing
    files. The final acceptance deployment backup is under
    /home/pi/PI-SCANNER/runtime/patch_backups/.

Upgrade note

Run tools/msys2_deploy_vhf_fft_scanner.sh from MSYS2 UCRT64. The deployment
backs up the current Pi files, removes the exact retired v1.0.19 systemd
override, installs the maintained worker, verifies serial ownership, runs the
isolated hardware/audio smoke tests, restarts the VHF and backend services, and
checks the live channel API.

N0JCG-SCANNER v1.0.19

Choose a tag to compare

@bakstaaj bakstaaj released this 28 Jul 04:36

PI-SCANNER v1.0.19

Current deployed Pi state

This release intentionally captures and commits the exact VHF implementation
currently deployed on the PI-SCANNER device.

No additional troubleshooting, runtime repair, tuning changes, or source
transformation was performed as part of this release.

Captured VHF implementation

  • Worker: persistent_vhf_fft_scanner.py
  • Service override: 90-persistent-fft.conf
  • VHF receiver serial: 00000144
  • VHF audio UDP port: 23458
  • Separate rtl_fm audio handoff
  • Generic candidate ranking by RF margin
  • Three PCM frames required before confirming a lock
  • No channel-specific priority behavior

Runtime state at release capture

  • VHF systemd service: active
  • UHF systemd service: active
  • VHF status: state=stopped, search_mode=persistent_fft_rtl_tcp, voice_demodulator=separate_vhf_rtl_fm_dc_deemp, locks=0, frames=0

The VHF status record reported state=stopped at capture time. This release
preserves that current state rather than claiming the VHF runtime is validated
or fully operational.

Included snapshots

  • Current analog receiver configuration
  • Current VHF runtime status JSON
  • Effective VHF systemd unit and overrides
  • Effective VHF ExecStart

N0JCG-SCANNER v1.0.0

Choose a tag to compare

@bakstaaj bakstaaj released this 26 Jul 04:57

PI-P25-SCANNER v1.0.0

PI-P25-SCANNER v1.0.0 is the first major stable release of the dedicated
Raspberry Pi P25 trunked-radio scanner. It establishes a validated
multi-receiver OP25 architecture with independent control and voice
demodulation, reliable browser audio, receiver-role protection, and truthful
runtime status.

Validated production architecture

  • Raspberry Pi 5 running the P25 scanner backend and web interface.
  • Dedicated control receiver:
    • RTL serial 00000251
    • CQPSK demodulation
    • LNA:40
  • Dedicated voice receiver:
    • RTL serial 00000252
    • FSK4 demodulation
    • LNA:49
  • OP25 multi_rx.py runtime with one protected control receiver and scalable
    dedicated voice receivers.
  • Backend and web interface on TCP port 8070.
  • Raw browser-audio endpoint on TCP port 8072.
  • OP25 per-receiver UDP audio pool on ports 23500 through 23509.
  • Selected audio forwarded to the existing browser bridge on UDP port 23456.

P25 control-channel behavior

  • Sticky control-channel operation tolerates consecutive framing timeouts before
    hunting fallback channels.
  • Tenderfoot II effective control-channel list:
    • 853.300000 MHz
    • 853.537500 MHz
    • 853.750000 MHz
  • 852.225000 MHz is excluded from control-channel scanning but remains
    available for dynamically assigned voice traffic.
  • The dedicated control receiver uses an impossible TGID whitelist entry so it
    cannot be consumed by a voice grant.

Voice and browser-audio behavior

  • Independent control and voice demodulator settings.
  • FSK4 voice decoding produces active, intelligible Phase I PCM where CQPSK
    voice produced effectively silent PCM.
  • Audio-pool minimum RMS threshold: 25.
  • Per-burst acquisition warm-up: eight 20 ms frames, approximately 160 ms.
  • OP25 DRAIN and DROP UDP flags are decoded as explicit audio-burst
    boundaries.
  • The selected voice source remains held through quiet speech while PCM packets
    continue arriving.
  • Lost-packet safety release occurs after 2.5 seconds without PCM.
  • Audio sources are selected without mixing.

Runtime and UI improvements

  • Receiver inventory and persistent receiver-role registry.
  • Scalable multi-receiver state and configuration telemetry.
  • Truthful control and voice frequency reporting.
  • Voice-assignment and audio-pool activity counters.
  • Balanced UI polling to avoid excessive backend load.
  • Rotating OP25 runtime log:
    • 8 MiB active log
    • five retained backups
  • Control-frequency parsing no longer misclassifies unqualified voice tuning
    messages as control-channel changes.

Hardware role registry

The validated seven-receiver inventory preserves these assignments:

Role RTL serial
P25 control 00000251
P25 voice 00000252
NOAA / airband 00000162
ADS-B 1090 00001090
UAT 978 00000978
Analog 2 m 00000440
Analog 70 cm 00000144

Only the P25 services are part of this release runtime. Other assigned receivers
remain reserved for their associated applications or later phases.

Final hardware validation

The v1.0.0 release state was validated on July 23, 2026 against Colorado DTRS
Tenderfoot II, RFSS 6, Site 017.

Final flag-aware audio validation observed:

  • three actual decoded audio bursts;
  • 216 PCM frames;
  • 64 active PCM frames;
  • 24 acquisition frames suppressed, exactly eight per audio burst;
  • 122 stabilized PCM frames forwarded;
  • 15 OP25 DRAIN flags;
  • three selected-stream boundary events;
  • zero timeout-driven source releases;
  • zero audio output errors.

The user confirmed that audio quality and continuity were substantially improved
after the flag-aware call-boundary and source-hold changes.

Important limitations

  • Encrypted P25 traffic cannot be decoded.
  • The first approximately 160 ms of each selected voice burst is intentionally
    suppressed to remove unstable acquisition audio.
  • v1.0.0 was hardware-validated with one dedicated voice receiver. The
    architecture supports adding more matching P25 voice receivers.
  • This source release does not contain site credentials, RadioReference
    credentials, runtime logs, generated local settings, or other device-specific
    secrets.

Release lineage

  • Recovery/main checkpoint:
    a83da5307636ebf32deece49b2ad9a2639837c44
  • Validated Phase 32 audio-boundary commit:
    1de841591071fb693f20aa40929cd707cb6d0d07
  • Release branch:
    feature/scalable-p25-multi-rx-v2