Skip to content

Aether-gate v0.5.1 — true bin width, per-device dBm, and a gate that admits when the radio is gone

Latest

Choose a tag to compare

@nigelfenton nigelfenton released this 06 Sep 18:01
· 1 commit to main since this release

Aether-gate presents any radio to AetherSDR as a Flex 6000. This release makes the panadapter's
advertised bin width true, replaces one global dBm guess with per-device calibration, exposes the
SDR controls the Flex protocol has no verb for — and stops a gate with no radio from advertising
one anyway.

This is the first published release since 0.4.3. 0.5.0 was tagged but never released here, so
everything from both tags is below.

If you are running 0.4.3, take this one

A gate whose radio was absent advertised a FLEX-6700 regardless. With a Radioberry powered off,
the gate came up, logged board=0x00, advertised a radio, and AetherSDR connected and sat on
"Connecting to radio…" — black waterfall, and a full TX surface on a radio that was not there.
device_lost was declared on RadioAdapter but only ever set by soapy.py, so the two guards in
core/engine.py that exist to prevent exactly this were dead code for every other adapter; both
read it through getattr(..., False) and silently did nothing. Fixed by promoting the signalling
into the base class, with the clock measured from the last evidence of life rather than the first
silent call. open() also no longer trusts --radio-ip blindly — that flag short-circuited the
discovery check in the exact configuration every systemd unit ships.

Panadapter and levels

  • The advertised bin width is now true. The FFT was given a sample count that did not match the
    bin width being claimed.
  • dBm calibration is per-driver, not one global guess — the dBFS→dBm anchor is keyed by driver,
    with --dbm-base to override and --dbm-trim so a found calibration survives a restart. The
    panadapter and the S meter share one calibration instead of disagreeing.
  • The S meter measures the demodulator's passband, not total passband power, and reports the
    noise floor and SNR rather than signal alone.
  • Level tracking follows the hardware — gain changes made through a device setting are
    followed, and an LNA-state change warns instead of silently miscorrecting.
  • Wide frames segment across datagrams instead of being capped at one, and bin width is
    dialable from the control panel. AE's pan zoom drives the SDR's sample rate.

Radio control

  • /device exposes the SDR controls the Flex protocol has no verb for, including a setting's
    ArgInfo range.
  • RF gain is in dB, not 0..100 — AE sends dB, and rfgain_info is now answered.
  • A dropped stream restarts instead of going off the air, a device that stops producing samples
    without erroring is detected, and adapter.close() is bounded so a wedged driver cannot hold the
    exit open.
  • Radio dossiers: schema v0.1, a runtime loader (the IC-9700 adapter reads its facts from data),
    the IC-9700 and RTL-SDR v4 dossiers, and a validator. The gate is a pinned consumer of
    shack-experiments/radio-dossiers.

Project

CONSTITUTION.md and AGENTS.md write down the rules the project already ran on. CI now runs the
numpy suites and the __main__-less modules under pytest; segmentation is exercised on every
platform, with SIGTERM skipped where it cannot land.

Most of the levels and resolution work came in via #40, an RSPdx-R2 bring-up from @crypticpy.

Full diff: v0.4.3...v0.5.1