You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
qDMR (and its CLI dmrconf) is the most prominent open-source, cross-vendor codeplug tool, and it stores codeplugs in a human-readable, device-independent YAML format. A meaningful share of OpenGD77 (and wider DMR) operators already keep their codeplugs as qDMR YAML, and qDMR can encode that YAML straight to the device binary.
Supporting qDMR YAML as an interchange format would let those users bring their existing codeplugs into this tool (to visualise / manage / report) and take them back out into a toolchain that can already write the radio — without going through a lossy vendor CSV round-trip.
This is not the same as #10. #10 defines our own native YAML that losslessly represents our internal models. This ticket treats qDMR YAML as a third-party (foreign) format — like a vendor CSV, but YAML — handled at the import/export adapter boundary and mapped to/from our internal models. It is lossy at the edges (qDMR models concepts we don't, and vice versa).
Intended outcome
Add qDMR YAML as a first-class import and export format alongside OpenGD77 CSV:
Import: parse a qDMR YAML codeplug and map it into the internal data models (feat: genericise CPS import via internal data models #7) — radios/general settings (as far as we model them), channels (analogue + digital), zones, contacts, group lists (RX group lists / TG lists), and talk groups.
Export: serialise the internal models back out to a valid qDMR YAML document that qDMR / dmrconf will accept and can encode to a device.
Round-trip friendly: import-then-export should reproduce an equivalent qDMR YAML codeplug (modulo documented lossy fields).
Adapter, not core: keep qDMR specifics behind the import/export adapter layer (mirroring src/lib/import/), so feature code only ever sees internal models.
qDMR YAML specifics to handle
The format uses anchors/explicit id: references to link objects (channels → contacts/group lists, zones → channels, group lists → contacts). Our internal models already use stable ids (feat: genericise CPS import via internal data models #7), so map qDMR ids ↔ our internal ids at the boundary; do not leak qDMR ids into the models.
Distinguish analogue (FM) vs digital (DMR) channel nodes and their differing fields (CTCSS/DCS, bandwidth vs colour code, timeslot, group list, TX contact).
Map qDMR group lists ↔ our TG lists, and qDMR contacts (group vs private call) ↔ our contacts / talk groups.
Frequencies in qDMR YAML are human-readable strings (e.g. 145.500 MHz) — normalise to our internal representation on import and re-emit in qDMR's expected form on export.
Capture/round-trip fields we don't model yet (best-effort) rather than silently dropping them where practical; document what is lossy.
Affected
Import: new adapter under src/lib/import/ + registration in the import registry (src/lib/import/index.ts).
Internal models (src/models/): no new vendor coupling — mapping stays at the edges. May surface gaps where qDMR carries data we don't yet model (e.g. talk groups / contacts / group lists, currently stubs).
A YAML parse/serialise dependency (e.g. yaml/js-yaml).
Reference material: qDMR's OpenGD77Codeplug and the qdmr manual document the YAML schema and the OpenGD77 mapping.
SPA (Vite + React + TS); all processing client-side. Privacy: operator codeplugs stay browser-local; never commit qDMR YAML exports — use gitignored sample-exports/ for local testing.
Out of scope
Writing the device binary or talking to the radio directly (qDMR/dmrconf already do this; native binary/Web Serial is a separate concern).
Bundling or shelling out to dmrconf (this is a native, in-browser YAML mapping only).
Full fidelity for qDMR features we don't model — best-effort + documented lossiness.
Workflow note (for whoever picks this up)
Likely multi-commit work: branch from origin/main, use atomic conventional commits per logical change (do not batch into one big end-of-plan commit), and open a PR linking Closes #. Pair with the docs/features / progress-tracking skills for the build log.
Problem
qDMR (and its CLI
dmrconf) is the most prominent open-source, cross-vendor codeplug tool, and it stores codeplugs in a human-readable, device-independent YAML format. A meaningful share of OpenGD77 (and wider DMR) operators already keep their codeplugs as qDMR YAML, and qDMR can encode that YAML straight to the device binary.Supporting qDMR YAML as an interchange format would let those users bring their existing codeplugs into this tool (to visualise / manage / report) and take them back out into a toolchain that can already write the radio — without going through a lossy vendor CSV round-trip.
Distinction from #10 (our native YAML)
This is not the same as #10. #10 defines our own native YAML that losslessly represents our internal models. This ticket treats qDMR YAML as a third-party (foreign) format — like a vendor CSV, but YAML — handled at the import/export adapter boundary and mapped to/from our internal models. It is lossy at the edges (qDMR models concepts we don't, and vice versa).
Intended outcome
Add qDMR YAML as a first-class import and export format alongside OpenGD77 CSV:
dmrconfwill accept and can encode to a device.src/lib/import/), so feature code only ever sees internal models.qDMR YAML specifics to handle
id:references to link objects (channels → contacts/group lists, zones → channels, group lists → contacts). Our internal models already use stable ids (feat: genericise CPS import via internal data models #7), so map qDMR ids ↔ our internal ids at the boundary; do not leak qDMR ids into the models.145.500 MHz) — normalise to our internal representation on import and re-emit in qDMR's expected form on export.Affected
src/lib/import/+ registration in the import registry (src/lib/import/index.ts).src/models/): no new vendor coupling — mapping stays at the edges. May surface gaps where qDMR carries data we don't yet model (e.g. talk groups / contacts / group lists, currently stubs).yaml/js-yaml).Notes / dependencies
OpenGD77Codeplugand the qdmr manual document the YAML schema and the OpenGD77 mapping.sample-exports/for local testing.Out of scope
dmrconfalready do this; native binary/Web Serial is a separate concern).dmrconf(this is a native, in-browser YAML mapping only).Workflow note (for whoever picks this up)
Likely multi-commit work: branch from
origin/main, use atomic conventional commits per logical change (do not batch into one big end-of-plan commit), and open a PR linkingCloses #. Pair with thedocs/features/ progress-tracking skills for the build log.