Со времён прошлой правки CAT в EWSDR появились TX-профили со всей «звуковой» цепью и телеграф — команды, которые doc/CAT_STATUS.md объявлял незакрываемыми, стали рабочими. TX-тракт: MG/ZZMG (усиление микрофона), MO/ZZMO + ZZTM (монитор передачи и его уровень), ZZTL/ZZTH (кромки TX-фильтра), PR/ZZPK + ZZPL (речевой компрессор), ZZET + ZZEB (эквалайзер), ZZTO + ZZTU (мощность и кнопка настройки), ZZUT (2TON), ZZLI + ZZUS (PureSignal), ZZTP (выбор профиля), ZZFD (девиация). Телеграф (были проброшены только KS/KY/ZZKS/ZZKY): ZZCS скорость, ZZCL тон, ZZCI иамбик, ZZCB/ZZCD break-in и hang-time, ZZCM сайдтон. Ревизия подписей. Комментарии у заглушек писались по буквам кода, а не по Thetis, и врали примерно в 150 местах. Хуже: часть РАБОТАЮЩИХ команд была привязана не к своей функции — внешний софт получал осмысленный, но неверный ответ, что хуже честной заглушки. Всё сверено с CATCommands.cs: ZZMA режим -> кнопка MUT ZZNN заглушка -> SNB ZZRX переход в RX -> аттенюатор RX1 ZZNS SNB -> кнопка NR2 ZZRV версия ПО -> напряжение питания ZZVS алиас ZZSP -> операции с VFO ZZMV индекс режима-> счётчик памяти ZZBM режим -> VFO B вниз на nn ZZKM режим кейера -> запуск CW-макроса ZZFT всегда A -> TX-частота (split) ZZFI/ZZBS были алиасами -> сами держат фильтр и диапазон Ошибочные алиасы на громкость/мощность сняты (ZZAA ZZVG ZZOA ZZAP ZZDN ZZAC ZZBI ZZMB ZZVA ZZPD ZZPO ZZQM ZZSR ZZRD ZZRU) — теперь честные заглушки с указанием, где функция живёт на самом деле. Кенвудовские команды сверены отдельно, покрытие полное (все 40 из Thetis), ширины полей совпадают с CATStructs.xml. Исправлено: SM отдавал 4 цифры вместо 5; RD/RU перестраивали VFO, хотя это RIT; KY не срезал набивку поля пробелами и гнал её в эфир паузами; CT принимала любой символ и «CT9;» молча гасил тон; OF/OS несли реализацию сами, а ZZOT/ZZOS были заглушками — клиент Thetis обращается как раз к ZZ* и не получал ничего. Валидация. Команды без параметров не проверяли суффикс: «TXanything;» доходил до CmdTX и ПОДНИМАЛ ПЕРЕДАЧУ (так же RX UP DN BD BU QI RC ID IF) — эталон отбраковывает лишний суффикс в парсере, у нас теперь список в IsParamless. ZZTX поднимал передачу на любом значении кроме нуля («2=TUNE» — выдумка). ZZFL/ZZFH принимали поле любой длины от 4 символов и через StrToIntDef молча схлопывали кромку в ноль. ZZMG принимал 1-2 символа. KY/ZZKY не ограничивали текст 25 символами, и очередь передачи могла расти произвольно. Осознанные отклонения от эталона сведены в отдельную таблицу документа: ZZBS (индекс диапазона вместо кода), ZZMN (имя режима вместо пресетов фильтров), ZZST (шаг FM вместо размера шага настройки), ZZCD (потолок 2000 мс — наш предел, он же в поле HangDelay пакета DUC Specific). Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
30 KiB
CAT-система EWSDR — статус реализации
Ветка разработки: feature/cat-tx-cw.
Дата последнего обновления: 2026-08-17.
Документ описывает текущее состояние CAT-подсистемы EWSDR: архитектуру,
полный перечень реализованных команд, осознанные заглушки и план дальнейших
работ. За эталон протокола взят Thetis / PowerSDR (CATParser.cs,
CATCommands.cs, CATStructs.xml) — диалект Kenwood TS-2000 + расширения ZZ*.
1. Архитектура
CAT-транспорты ──► TCATEngine (парсер протокола) ──► TCATContext ──► TCATAdapter ──► TRadioController
serial (4×) CATEngine.pas (callbacks) CATAdapter.pas (ядро)
TCP-сервер разбор/формат команд мост, маршалинг
| Файл | Назначение |
|---|---|
CATEngine.pas (~2740 строк) |
Движок протокола: разбор <PREFIX><SUFFIX>;, формирование ответов, реализации всех команд Kenwood + ZZ*. Зависит только от RTL. |
CATAdapter.pas (~910 строк) |
Мост к TRadioController. Строит TCATContext: геттеры читают поля контроллера напрямую (CAT-поток, read-only), сеттеры/команды маршалятся в поток контроллера через FController.Invoke. Владеет движком + транспортами. |
CATSerial.pas (~330 строк) |
Менеджер до 4 последовательных портов (виртуальные COM-пары для rigctld/N1MM/WSJT-X). |
CATTcp.pas (~507 строк) |
TCP-сервер (Thetis-совместимый), управление клиентами по GUID (ZZGA/ZZGR). |
1.1 Принципы
- CAT — равноправный клиент контроллера наряду с
WebAdapterи GUI. Никаких обращений кMainForm. ТолькоTRadioController. - Потокобезопасность. Геттеры читают поля контроллера напрямую (атомарное
чтение в CAT-потоке). Сеттеры пишут параметр в scratch-поля
(
FSyncFreq/FSyncInt/FSyncBool) и зовутFController.Invoke(@SyncXxx)— GUI исполняет черезTThread.Synchronize, демон — своей очередью. TCATContext— плоская запись callback'ов (Get*/Set*/Do*). Чтобы пробросить новую возможность контроллера в CAT, достаточно: (1) добавить callback в запись, (2) реализовать в адаптере геттер/сеттер/sync, (3) зарегистрировать вTCATAdapter.Create, (4) переписать тело команды в движке.- Формат команд:
Расширенные
SET: <PREFIX><SUFFIX>; (suffix = значение) GET: <PREFIX>; (suffix пустой) Resp: <PREFIX><VALUE>; Err: ?; (неверный формат) | E; (ошибка выполнения)ZZ*дублируют Kenwood-команды и добавляют то, чего в Kenwood нет.
1.2 Статистика покрытия (ZZ-команды)
| Кол-во | |
|---|---|
Всего ZZ* в Thetis |
315 |
| Реально реализовано в EWSDR | ~120 |
| Заглушки (отвечают валидным dummy, функции нет) | ~190 |
Совсем не обрабатываются (вернут ?;) |
5 |
Подписи всех 315 команд сверены с CATCommands.cs (см. §2.5) — комментарию у
заглушки теперь можно верить. Оставшиеся заглушки в большинстве закрыть
нечем: в EWSDR физически отсутствует соответствующий тракт (см. §4).
1.3 Осознанные отклонения от Thetis
Три места, где EWSDR намеренно расходится с эталоном. Больше таких нет.
| Команда | У Thetis | У нас | Почему |
|---|---|---|---|
ZZBS |
код диапазона, 3 символа (160/040/WWV) |
индекс диапазона, 2 цифры | формат заложен давно, на нём уже сидят клиенты |
ZZMN |
пресеты DSP-фильтров, 180 символов | имя режима по номеру | имён режимов в протоколе нет вовсе, а ZZML опирается на эту команду |
ZZST |
размер шага настройки (read-only) | индекс шага FM (00..03) | глобального шага у EWSDR нет, слот иначе мёртв; у шага FM своей команды в протоколе нет |
Плюс одно ограничение диапазона, не формата: ZZCD (hang-time break-in)
эталон принимает в 150..5000 мс, у нас потолок 2000 — столько же стоит в
настройках телеграфа и уходит в поле HangDelay пакета DUC Specific. Значения
выше подрезаются, как и всё прочее у Thetis.
2. Что сделано
2.1 Реализованные команды Kenwood (одиночный префикс)
| Команда | Функция | Маппинг на контроллер |
|---|---|---|
FA / FB |
VFO A / B частота (11 цифр, Гц) | Set/GetVfoA, Set/GetVfoB |
FR |
приёмный VFO (0/1) | Set/GetActiveVfo |
FT |
передающий VFO / split | → ZZSP |
FW / SH / SL |
ширина фильтра (индекс пресета) | Set/GetFilterIdx |
MD |
режим (Kenwood-код) | Set/GetMode |
GT |
режим AGC (0=FAST…4=OFF) | Set/GetAGCMode |
AG |
громкость AF | Set/GetVolume |
PC |
мощность TX 0–100 % | Set/GetDriveLevel |
NB |
шумоподавитель (NB) | Set/GetNBMode |
NT |
автонотч (ANF) | Set/GetANFEnabled |
SM |
S-метр (шкала Kenwood 0000–0030) | GetSMeter |
IF |
составной статус (37 байт) | freq/mode/tx/split |
ID |
идентификатор (TS-2000 = 019) | const |
PS |
питание/состояние | GetRunning |
TX / RX |
передача / приём | SetTransmitting |
BU / BD |
смена диапазона ±1 | DoBandUp/Down |
UP / DN / RU / RD |
шаг настройки ±1 | DoTuneUp/Down |
SQ |
шумоподавитель FM (шкала 0–255) | Set/GetSquelchLevel+On |
CN / CT |
CTCSS тон / вкл | Set/GetCTCSSTone, …On |
OF / OS |
репитер: offset / направление | Set/GetFMRptOffset, …Dir |
2.2 Реализованные расширенные ZZ* (выборочно, наиболее значимые)
VFO/режим/фильтр: ZZFA ZZFB ZZFI ZZFL ZZFH ZZFM ZZMD ZZFT ZZSP ZZVS,
диапазоны: ZZBS ZZBU ZZBD,
AGC/громкость/мощность/аттенюатор: ZZGT ZZAG ZZMA ZZPC ZZAR ZZRX,
шумодав/нотч: ZZNA ZZNB ZZNR ZZNS ZZNT ZZNN,
FM: ZZSQ ZZSO ZZTA ZZTB ZZST, CTUN: ZZCN,
S-метр/телеметрия: ZZSM ZZRV, память: ZZMV,
шаги VFO: ZZAU ZZBP ZZBM ZZSU ZZSA ZZSB,
передача: ZZTX, сервис: ZZID ZZGA ZZGR.
2.3 Сделано в ветке feature/cat-commands-expansion
Все команды ниже были заглушками и стали рабочими — функционал в
TRadioController уже существовал, но не был проброшен в CAT.
Группа 1 — Split TX
ZZSP,FT— split (TX на VFO-B),FR— выбор приёмного VFO, split-байт в составномIF.- В
TRadioControllerдобавлен публичный методSetSplit(TxOnB)(флагFSplitTxB+PushNetworkState+Changed(rfActiveVfo)). TX-частоту радио берёт изActiveTXFreqHz(учитывает split).
Группа 2 — FM Squelch
SQ(шкала Kenwood 0–255),ZZSQ(0–100 %),ZZSO(вкл/выкл).- Маппинг:
SetFMSquelch/SetFMSquelchLevel. Уровень>0 включает шумоподавитель.
Группа 3 — FM CTCSS
CT/ZZTA(вкл/выкл),CN(1-based тон 01–38),ZZTB(0-based 00–37).- Маппинг:
SetFMCTCSS/SetFMCTCSSTone, таблицаCTCSS_TONES[38].
Группа 4 — FM-репитер
OF(offset, 9 цифр Гц),OS(направление).- Трансляция направлений Kenwood (0=simplex,1=+,2=−) ↔ внутренние
RPT_NONE/MINUS/PLUS. Маппинг:SetFMRpt/SetFMRptOffset.
Группа 5 — FM tuning step
ZZST(индекс 00–03: 6.25/12.5/20/25 кГц). Маппинг:SetFMStep.
Доп. команды (вторая итерация)
| Команда | Что | Примечание |
|---|---|---|
ZZSO |
Squelch on/off | завершает группу squelch |
ZZNT |
ANF on/off | раньше ошибочно был алиасом NB |
ZZCN |
CTUN (click-tune) RX1 | новый callback Get/SetCTun → SetCTun |
ZZAR |
RX1 AGC-T / RF gain (±nnn) |
новый callback Get/SetAGCTop → SetAGCTop (кламп 20–120 dB) |
ZZAU/ZZBP |
сдвиг VFO A/B вверх на шаг nn (00–14) |
исправлен баг: были заалиашены на ZZFA/ZZAP |
ZZSU |
шаг активного VFO вверх | DoTuneUp |
Шкала шагов ZZAU/ZZBP — StepIdxToHz (зеркало Thetis Step2Freq):
1 Гц, 10, 25, 50, 100, 250, 500, 1к, 5к, 9к, 10к, 100к, 250к, 500к, 1 МГц.
Новые callback'и в TCATContext (этой ветки): split, squelch on/level,
CTCSS on/tone, FM repeater dir/offset, FM step, AGC-T, CTUN.
2.4 Сделано в ветке feature/cat-tx-cw
К этому моменту в EWSDR появились TX-профили со всей «звуковой» цепью и телеграф (кейер, сайдтон, break-in) — команды, которые §4 когда-то объявил незакрываемыми, стали рабочими.
TX-тракт (правки уезжают в активный TX-профиль):
| Команда | Что | Маппинг |
|---|---|---|
MG / ZZMG |
усиление микрофона | MicGainDB; MG — шкала Kenwood 100:70, ZZMG — дБ со знаком |
MO / ZZMO |
кнопка MON | self-monitor даунлинка: SetRxMuteOnTx (инверсия) |
ZZTM |
громкость монитора | SetTXMonVolume (новый метод контроллера) |
ZZTL / ZZTH |
кромки TX-фильтра, Гц | FilterLow / FilterHigh |
PR / ZZPK |
речевой компрессор вкл/выкл | CompressorOn |
ZZPL |
усиление компрессора, дБ | CompressorGain (0..20) |
ZZET |
кнопка TXEQ | EQOn |
ZZEB |
значения TX-эквалайзера | EQNumBands + EQGains (формат Thetis, 36 символов) |
ZZTO |
мощность настройки | TUNLevel |
ZZTU |
кнопка TUN | SetTune |
ZZUT |
двухтональник 2TON | SetTwoTone |
ZZLI |
кнопка PS-A | SetPureSignal |
ZZUS |
одиночная калибровка PS | PSSingleCal (write-only) |
ZZTP |
активный TX-профиль | SelectTXProfile / TXProfileCount |
ZZFD |
девиация передачи (2.5/5 кГц) | TTXSettings.FMDeviation |
Телеграф (раньше были проброшены только KS/KY/ZZKM/ZZKS/ZZKY):
| Команда | Что | Маппинг (TCWSettings) |
|---|---|---|
ZZCS |
скорость кейера, WPM (2 разряда) | .Speed — та же величина, что у KS |
ZZCL |
тон приёма/сайдтона, Гц | .Pitch |
ZZCI |
иамбик вкл/выкл | .KeyerMode (вкл выбирает iambic B, если стоял прямой ключ) |
ZZCB |
break-in прошивки | .BreakIn |
ZZCD |
hang-time break-in, мс | .HangTimeMS |
ZZCM |
сайдтон (у Thetis — «monitor disable», значение инвертировано) | .SidetoneSW или .SidetoneHW — тот, что отвечает за текущий источник манипуляции |
Новое в контроллере. Правка TX-настроек получила одну публичную дверь —
SetTXSettings(const T; Notify), по образцу SetCWSettings: применение к WDSP,
перепосыл DUC Specific, живой TUN, запись в активный профиль и персист теперь
там, а не в обработчике MainForm (тот делегирует с Notify=False, иначе
rfTXProfile перезагрузил бы вкладку Transmit под руками у правящего).
Добавлен SetTXMonVolume — громкость self-monitor'а адресно, вне TX-контекста.
Новое в движке. Хелперы OnOff и NumField — разбор двухпозиционных и
числовых полей в одном месте, чтобы тела команд остались про смысл. Границы
значений (MIC_GAIN_MIN… в шапке юнита) повторяют контролы вкладок Transmit и
CW: по CAT прилетает что угодно, а контроллер принимает запись целиком и уже не
знает, кто её правил.
Команды слайсов (
CATSliceEndpoint) этих callback'ов не получают: TX-тракт один на радио, а профиль слайса переключается своим путём (SetSliceTXProfile). Все новые команды nil-безопасны и на слайс-порту отвечают дефолтом.
2.5 Ревизия алиасов и подписей
Подписи писались по буквам кода, а не по Thetis, и врали примерно в 150
местах. Хуже: часть работающих команд была привязана не к своей функции —
внешний софт получал осмысленный, но неверный ответ, что хуже честной
заглушки. Всё сверено с CATCommands.cs и исправлено.
Команда делала не своё дело — теперь делает своё:
| Команда | Было | Стало |
|---|---|---|
ZZMA |
режим (алиас ZZMD) |
кнопка MUT → SetMute |
ZZRX |
переход на приём | шаговый аттенюатор RX1 0..31 дБ → SetAtten |
ZZRV |
версия ПО | напряжение питания PA (телеметрия) |
ZZMV |
индекс текущего режима | число записей памяти каналов |
ZZNN |
заглушка «ручной нотч» | SNB (спектральный бланкер) |
ZZNS |
SNB | кнопка NR2 (режим NR 2) |
ZZVS |
алиас ZZSP (split) |
операции с парой VFO: 0=A→B, 1=B→A, 2=обмен, 3=IF→VFO |
ZZBM |
режим (алиас ZZMD) |
VFO B вниз на nn шагов (пара к ZZBP) |
ZZFI |
алиас ZZBI |
сам индекс фильтра |
ZZBS |
алиас ZZAC |
сам выбор диапазона |
ZZKM |
режим кейера | запуск CW-макроса (ячейка памяти сообщений) |
ZZFT |
всегда VFO A | TX-частота с учётом split |
ZZTX |
любое значение ≠ 0 поднимало передачу («2=TUNE» — выдумка) |
строго 0/1, иначе ?; и передача НЕ включается (настройка — ZZTU) |
Ошибочные алиасы сняты — теперь честные заглушки (в скобках — где эта
функция живёт на самом деле): ZZAA, ZZVG (громкость — ZZAG) · ZZOA
(антенна RX1) · ZZAP (мощность — ZZPC) · ZZDN (мощность — ZZPC; сам
ZZDN = низ водопада) · ZZAC (диапазон — ZZBS) · ZZBI (фильтр — ZZFI)
· ZZMB (режим — ZZMD) · ZZVA (обмен VFO — ZZVS) · ZZPD, ZZPO
(мощность и питание — ZZPC/ZZPS) · ZZQM (режим — ZZMD) · ZZSR
(опорный уровень спектра) · ZZRD/ZZRU (RIT; шаг настройки — ZZSA/ZZSB).
Что заметят внешние клиенты:
ZZRX;больше не уводит в приём (для этого естьZZTX0;и кенвудовскаяRX;),ZZVA;больше не меняет VFO местами (теперьZZVS0;),ZZKMне выставляет режим кейера (иамбик вкл/выкл —ZZCI),RD/RUбольше не перестраивают VFO (шаг —UP/DN). Во всех случаях старое поведение было отсебятиной.
Кенвудовские команды. Сверены отдельно: все 40 команд, реализованных в
Thetis, у нас есть, ширины полей совпадают с CATStructs.xml. Исправлено:
| Команда | Что было не так |
|---|---|
SM |
ответ был 4 цифры вместо 5 (SM0015; → SM00019;) — парсеры логгеров ждут пять; заодно принимаем селектор 2, как шлёт Thetis |
RD / RU |
перестраивали VFO, хотя это RIT (его у нас нет) — стали заглушками, принимающими 5-значный аргумент |
KY |
поле текста у Kenwood фиксированной ширины и добито пробелами — хвост уходил в эфир словесными паузами, теперь срезается |
IF |
в комментарии значилось «37 байт», реальная и правильная длина ответа — 35 |
SH / SL |
обе крутят один и тот же индекс пресета; раздельных «сторон» у главного приёмника нет — оговорка добавлена в код |
CT |
принимала любой символ: CT9; молча ГАСИЛ тон вместо ответа ?;. Теперь обёртка над ZZTA, как в эталоне, и сама ZZTA проверяет значение строго |
OF / OS |
несли реализацию сами, а ZZOT/ZZOS были заглушками — клиент Thetis обращается как раз к ZZ* и не получал ничего. Реализация переехала в ZZOT/ZZOS, кенвудовские стали обёртками. Заодно OF с нечисловым полем больше не обнуляет сдвиг молча |
Разбор и транспорты. Отдельный проход по валидации и вводу-выводу:
| Где | Что было не так |
|---|---|
TCATEngine.Parse |
команды без параметров не проверяли суффикс: TXanything; доходил до CmdTX и поднимал передачу; так же вели себя RX UP DN BD BU QI RC ID IF. Эталон отбраковывает лишний суффикс в парсере, по таблице ширин; у нас таблицы нет — список безаргументных команд теперь в IsParamless |
ZZFL / ZZFH |
принимали поле любой длины от 4 символов и гнали его через StrToIntDef: ZZFLabcd; молча схлопывал кромку в ноль. Поле фиксированное — ровно 5 символов со знаком, разбор строгий |
KY / ZZKY |
текст не ограничивался; поле у Kenwood фиксированное, 25 символов. Длиннее — ?;: очередь передачи не должна расти произвольно, иначе один пакет уводит станцию в эфир на неопределённое время |
CATTcp.SendStr |
один send на ответ. TCP не обязан отдать весь буфер за раз — длинный ответ (IF, ZZEB, список режимов) мог уехать обрезанным, и молча: усечение здесь не ошибка. Теперь дописываем остаток в цикле |
CATSerial |
порт помечался активным ДО SerOpen; при отказе он навсегда оставался «работающим» в ActiveCount и UI, а причина нигде не оседала. Открытие переехало из потока в TCATSerialPort.Start (синхронно), появилось свойство LastError, поток теперь только читает, а закрывает владелец в Stop. Заодно Andromeda-порт назначается только на реально поднявшийся порт |
Формат ZZOT сверен отдельно: эталон читает 9 цифр как МГц с шестью знаками
после запятой (вставляет точку после третьего разряда) — численно это ровно те
же герцы, что пишем мы, поле совместимо. Мусор в ZZOS эталон трактует как
симплекс (default в String2OffsetDirection), и мы намеренно повторяем это,
а не отвечаем ошибкой.
Формат ответа на ZZ* (ZZ + код + эхо суффикса запроса + значение) сверен
с CATParser.ParseExtended — совпадает; это важно для ZZSM0;, где запрос
несёт селектор приёмника.
3. Что нужно сделать (актуально / есть чем закрыть)
Эти команды — заглушки, но соответствующая функция в EWSDR уже есть или легко добавляется. Приоритетные кандидаты:
| Команда(ы) | Что | Чем закрыть | Сложность |
|---|---|---|---|
ZZVL, ZZUX/ZZUY |
блокировка VFO (общая и раздельная) | SetVfoLock |
низкая |
ZZSW, ZZZW |
обмен VFO A/B | VfoSwap |
низкая |
ZZAD ZZAE ZZAF ZZBE ZZBF, ZZSG/ZZSH |
сдвиг VFO на nn шагов | StepIdxToHz + DoTuneUp/Down, как у ZZAU/ZZBP |
низкая |
ZZCU |
загрузка CPU (read) | телеметрия процесса | низкая |
ZZSF |
фильтр «центр + ширина» одной командой | SetFilterEdges |
низкая |
ZZSG/ZZSH, ZZSD |
шаг VFO B и колеса — по одному шагу | те же SetVfoB/DoTune* |
низкая |
ZZMY ZZMZ ZZMW ZZMX ZZQR ZZQS ZZQM |
запись/чтение памяти каналов (счётчик ZZMV уже есть) |
ChannelStore / ChannelController |
средняя |
ZZDN/ZZDO, ZZDP/ZZDQ/ZZDR |
низ/верх водопада, сетка спектра | FSpecRefLevel/FSpecRange, per-pan дисплей |
средняя |
ZZPD/ZZPE, ZZPY/ZZPZ |
пан и зум дисплея | SetPanZoomPan |
средняя |
ZZSN, ZZZM, ZZZV |
серийник, модель, версия железа | BoardUtils |
низкая |
ZZXN / ZZXV |
составные статусы RX1/VFO | сборка из готовых геттеров | средняя |
ZZOC/ZZOD/ZZOE |
антенны | SetAnt936x (порты AD936x) |
средняя |
ZZDX / ZZDY |
кнопка DX и порог спотов | флаг ShowSpots живёт в MainForm — сперва поднять в контроллер |
средняя |
ZZAS |
RX2 AGC-T | — только при появлении RX2 | — |
Прежде чем реализовывать новую команду, сверяйся с форматом поля в
Thetis/.../CAT/CATStructs.xml(<nsetparms>/<ngetparms>) и телом метода вCATCommands.cs, чтобы ширина/знак значения совпадали. И проверяй смысл: подпись у заглушки в диспетчере может врать (см. §1.2).
3.1 Совсем не обрабатываются (вернут ?;)
ZZCU (CPU), ZZDY (DX threshold), ZZQA/ZZQB (Quick Play/Rec),
ZZVF (VAC stereo). Из них реалистично добавить только ZZCU и ZZDY.
4. Осознанные заглушки (закрывать нечем)
Команды отвечают валидным dummy-значением для совместимости с управляющим ПО (rigctld, N1MM, WSJT-X, Log4OM), но функции в EWSDR нет. Это ~70 % всех заглушек.
| Область | Команды (примеры) | Причина |
|---|---|---|
| Второй приёмник RX2 / sub-RX | ZZAB ZZAS ZZBA ZZBB ZZBT ZZMB ZZOB ZZRS ZZSV ZZSX ZZNC ZZND ZZNF ZZNO ZZNU ZZNW ZZFJ ZZFR ZZFS ZZGU ZZLE ZZLF ZZPB ZZRY ZZXO |
один приёмник |
| VAC / VAC2 | ZZVC ZZVD ZZVF ZZVI ZZVK ZZVM ZZVO ZZVQ ZZVR ZZVT ZZVU ZZVV ZZVX ZZVY ZZVZ ZZYA ZZYB |
нет виртуального аудиокабеля |
| RTTY / DIGI-офсеты | ZZRA ZZRB ZZRH ZZRL |
нет RTTY-движка |
| RIT / XIT | RT XT RC, ZZRF ZZRT ZZXC ZZXD ZZXF ZZXS ZZXU |
нет тракта смещения приёма (CTUN — не замена) |
| Diversity | ZZDB ZZDC ZZDD ZZDE ZZDF ZZDG ZZDH (но не ZZDA — это усреднение спектра) |
нет диверсити-приёма |
| Компандер, noise gate, APF, VOX | ZZCP ZZCT, ZZGE ZZGL, ZZAA ZZAB ZZAT ZZAY, ZZVE ZZXH |
таких блоков в тракте нет (речевой компрессор — есть, это ZZPK/ZZPL) |
| Микшер Flex 5000 / F1500, FlexWire | ZZWA…ZZWS, ZZWT…ZZWW, ZZFV ZZFW ZZFX ZZFY |
железо другого вендора |
| ATU (Aries/Ganymede) | ZZOV ZZOW ZZOX ZZOZ ZZZA |
нет тюнера |
| DSP-буферы, JSON-команды | ZZHA ZZHR ZZHT ZZHU ZZHV ZZHW ZZHX, ZZJP ZZJQ ZZJR ZZJS |
внутренние крутилки Thetis |
5. Транспорты
CAT дополнительных слайсов (свой TCP-порт на слайс B..G + Auto TX) вынесен в отдельный документ:
CAT_SLICES.md. Тот же движок, другой контекст; транспорты ниже принадлежат главному приёмнику (слайс A).
- Serial (
CATSerial.pas): до 4 портов, параметры (порт/скорость/биты/ чётность/стоп) изTGlobalSettings.CATSerial*, применяютсяTCATAdapter.ApplySettings. На текущей платформе сборки может быть{$DEFINE CAT_SERIAL_STUB}(см. начало файла) — проверить перед релизом. - TCP (
CATTcp.pas): сервер наCATTcpPort, включается флагомCATTcpEnabled. Клиенты идентифицируются GUID черезZZGA/ZZGR.
6. Как добавить новую CAT-команду (чек-лист)
- Сверить формат в
CATStructs.xml+CATCommands.cs(Thetis). - Если нужна новая возможность контроллера — есть ли публичный метод/поле
в
TRadioController? Если нет — добавить (по образцуSetSplit). - В
CATEngine.pas: добавить callback(и) вTCATContext,SafeGet*-хелпер для GET, переписать тело команды (CmdXXилиZZXX). - В
CATAdapter.pas: геттер (чтениеFController.F*), сеттер +SyncXX(черезInvoke), регистрация вTCATAdapter.Create. - Если команда
ZZ*ещё не в диспетчере — добавить веткуelse if ext = '..'. - Сборка-проверка:
lazbuild -B --ws=qt6 ewsdr.lpr(GUI-граф включает CAT; headless-демонewsdrdCAT не содержит).