Skip to content

RFC: Expand internal MQTT topic set for CW, radio state, and AX.25 #3388

Description

@K5PTB

Background

AetherSDR's existing MQTT support has two built-in subscription topics — aethersdr/antenna/name/+ and aethersdr/antenna/names — that allow external tools to push antenna label updates into the panadapter display. These are pure subscriptions: AetherSDR listens but publishes nothing, so they have zero impact unless a client is actively using them.

This RFC describes work in progress expanding that with additional internal topics covering CW decode, radio state, and AX.25 frames. We are soliciting feedback before proceeding further.

What was built

New publish topics (AetherSDR → broker → clients):

  • aethersdr/cw/decode — CW decoded text, one character per message, with speed and pitch in the payload
  • aethersdr/radio/state — frequency, mode, and TX state, published on any change
  • aethersdr/ax25/rx — decoded AX.25 frames as JSON

New subscribe topics (clients → broker → AetherSDR):

  • aethersdr/cw/transmit — send CW text to be keyed by AetherSDR
  • aethersdr/ax25/tx — transmit an AX.25 frame (TNC2 format)

Per-topic enable/disable: As the topic set grew it became clear that not every deployment needs every topic, and always-on publication is wasteful. All five new topics are individually enabled/disabled in the UI. The two original antenna alias subscriptions are unconditional and unchanged.

Why the AX.25 topics are here

Honestly: the ax25/rx and ax25/tx topics were added primarily to enable comparison testing between the MQTT and KISS TNC paths, validating that both decode the same frames (see related RFC #3387). They overlap with KISS functionality by design. Whether they belong in a stable upstream release is an open question — see below.

Value proposition

The pattern this enables is an async, event-driven interface for external tooling:

  • No polling — state changes push to subscribers; clients don't need to query
  • Decoupled — AetherSDR doesn't know or care how many clients are connected
  • Low barrier — every language has an MQTT client library; a working subscriber is five lines of Python
  • Composable — integrates naturally with Node-RED, Home Assistant, contest loggers, external displays, score trackers

This is not intended to replace or compete with CAT, rigctld, or TCI for radio control. The scope is specifically decoded-output events (CW text, AX.25 frames) and radio state notifications — things that are either unavailable or require polling in existing interfaces.

Concerns we're aware of

  • Broker requirement — an MQTT broker (typically Mosquitto) is an additional dependency. Not trivial for casual users.
  • Overlap with TCI — async radio state is also being discussed in the TCI context. We don't want to duplicate effort or create maintenance burden.
  • AX.25 / KISS overlap — the AX.25 topics duplicate KISS TNC functionality. They may be better kept as a local testing tool rather than a shipped feature.
  • Scope creep — we explicitly do not want to grow this into a full control interface mirroring every CAT or rigctld function.

Questions for the maintainer

  1. Which topics belong upstream? The CW and radio state topics feel broadly useful; the AX.25 topics feel more situational. Happy to split them or drop AX.25 entirely if KISS is the preferred TNC path.
  2. TCI coordination — is async radio state via MQTT redundant with what's planned for TCI? If so we'd narrow the scope.
  3. Broker as a dependency — is this acceptable for the target user base, or should MQTT remain firmly opt-in with no internal topics active by default?
  4. PR structure — should this arrive as one PR or split by topic group (CW / radio state / AX.25)?

Metadata

Metadata

Assignees

No one assigned

    Labels

    CWCW keying, decode, and operationexternal devicesFlexControl, MIDI, serial port, USB peripheralsmaintainer-reviewRequires maintainer review before any action is takenpriority: lowLow priorityprotocolSmartSDR protocolquestionFurther information is requestedrfc

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions