Skip to content

Support a radio_instance registry for physical-radio facts (profile-0.2) #8

Description

@emuehlstein

Summary

radio_instance identifies a specific physical radio, but there is nowhere in
the repo to record facts about that physical radio. Proposing first-class
support for an instance registry as a profile-0.2 concern.

Motivation

The README already establishes the concept:

radio identifies the radio model and radio_instance identifies the specific
physical radio receiving the generated codeplug. The instance ID is arbitrary
but stable, such as dm32_green_01 or d01.

And resolved.py carries it through to ResolvedCodeplug.radio_instance_id. So
the identity exists and is threaded through the pipeline — but there is no
declared home for the attributes of that identity.

Concretely: two DM-32s on the same bench, same model, same capabilities.json,
same assignments. Distinguishing them means reading a serial off the case
sticker. Today that fact has nowhere to live.

What went wrong in practice

Attempting the obvious thing fails. Adding to a profile:

radio_instance: "dm32_white_01"
radio_case_sn: "25DM32UV04222"
radio_case_fcc_id: "2AJGM-NA32UV"
INVALID: Additional properties are not allowed
('radio_case_fcc_id', 'radio_case_sn' were unexpected)

profile-0.1.schema.json sets additionalProperties: false at the root and
profile.py validates with Draft202012Validator, so this is a hard reject.
Correct behaviour by the schema — but it leaves users with no sanctioned path,
and the failure only surfaces at validation time.

Why not just relax the schema

Inline instance facts are the wrong shape regardless of whether validation
allows them. A profile is a selection document — which assignments, in what
zone order. A serial number is a fact about an object on a shelf. Different
lifetimes: profiles get forked, retargeted and copied between radios, while the
case sticker never changes. An inline serial starts lying on the first
cp white.yml blue.yml, and nothing catches it.

Proposed shape

A separate registry keyed on radio_instance, so the profile stays a pure
selection document:

version: "0.1"
instances:
  dm32_white_01:
    radio: baofeng_dm32
    profile: muehlstein_dm32_white
    label: "White DM-32"
    owner: jess
    case_serial: "25DM32UV04222"
    fcc_id: "2AJGM-NA32UV"
    hardware_family: row
    firmware: "DM32.01.L01.048"
    sk_buttons: null

Useful properties:

  • Validation. Cross-check that every radio_instance in a profile resolves
    to a registry entry, and that instances.<id>.radio matches the profile's
    radio. Catches a retargeted-profile mistake mechanically.
  • Provenance in output. ResolvedCodeplug could carry instance metadata so
    a generated codeplug records which physical radio it was built for.
  • Optional and back-compatible. Absent registry behaves exactly as today.

Deliberate non-goal: DMR identities

Tempting to put radio IDs here, but they are radio-agnostic and want a
separate home (cf. identities/dmr_ids.yml in the private overlay). Putting
them in an instance registry would duplicate them per physical radio and create
a competing source of truth. Recommend keeping identities out of this proposal.

A safety-adjacent note

For the DM-32 specifically, an instance registry is where the hardware-family
determination belongs. DM-32UV is three hardware lines (ROW DM32.01.*,
Taiwan DM32.NRF.*, HR Vocoder DM32.00.*) that all report DP570UV, and
cross-flashing soft-bricks the radio. The firmware string does not identify the
hardware; the reliable no-disassembly tell is ridged vs smooth SK1/SK2.

That is a per-physical-radio fact, verified once with the battery out, and it
currently lives only in scattered notes. Worth noting this is reference data
by the repo's own boundary rule (it does not affect a channel byte), so if the
registry is considered out of scope here, that is a reasonable call — but the
join key radio_instance lives in this repo, which is what motivates filing it
here.

Prior art

Implemented locally as instances.yml in a private profiles repo
(emuehlstein/muehlstein-codeplugger-profiles, branch add-instance-registry)
to see whether the shape holds up. It does, but it is unvalidated and unread by
the generator — pure documentation. Happy to upstream a schema + validation hook
if the direction is agreeable.

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions