mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
Реализованы команды, ранее бывшие заглушками — функционал уже был в TRadioController, но не пробрасывался в CAT: - Split TX: ZZSP/FT/FR + split-байт в IF (новый RadioController.SetSplit) - FM Squelch: SQ (0–255), ZZSQ (0–100%), ZZSO (on/off) - FM CTCSS: CT/ZZTA (on), CN (1-based)/ZZTB (0-based тон) - FM-репитер: OF (offset), OS (направление, с трансляцией Kenwood↔RPT_*) - FM step: ZZST (00–03) - CTUN: ZZCN; AGC-T/RF gain: ZZAR - ANF: ZZNT (раньше ошибочно алиас NB) - Шаги VFO: ZZAU/ZZBP (исправлен баг — были алиасы ZZFA/ZZAP), ZZSU TCATContext расширен callback'ами (split, squelch, CTCSS, repeater, step, AGC-T, CTUN); CATAdapter — геттеры/сеттеры/sync с маршалингом через Invoke. Добавлен doc/CAT_STATUS.md — полный статус CAT и план работ. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
212 lines
13 KiB
Markdown
212 lines
13 KiB
Markdown
# CAT-система EWSDR — статус реализации
|
||
|
||
Ветка разработки: `feature/cat-commands-expansion`.
|
||
Дата последнего обновления: 2026-06-26.
|
||
|
||
Документ описывает текущее состояние 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` (~2270 строк) | Движок протокола: разбор `<PREFIX><SUFFIX>;`, формирование ответов, реализации всех команд Kenwood + `ZZ*`. Зависит только от RTL. |
|
||
| `CATAdapter.pas` (~445 строк) | Мост к `TRadioController`. Строит `TCATContext`: геттеры читают поля контроллера напрямую (CAT-поток, read-only), сеттеры/команды маршалятся в поток контроллера через `FController.Invoke`. Владеет движком + транспортами. |
|
||
| `CATSerial.pas` (~313 строк) | Менеджер до 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 | **98** |
|
||
| Заглушки (отвечают валидным dummy, функции нет) | ~211 |
|
||
| Совсем не обрабатываются (вернут `?;`) | 7 |
|
||
|
||
Большинство заглушек закрыть **нечем** — в EWSDR физически отсутствует
|
||
соответствующий тракт (см. §4).
|
||
|
||
---
|
||
|
||
## 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`,
|
||
диапазоны: `ZZBS ZZBU ZZBD ZZBA ZZBI ZZBM`,
|
||
AGC/громкость/мощность: `ZZGT ZZAG ZZPC ZZPD ZZAR`,
|
||
шумодав/нотч: `ZZNA ZZNB ZZNR ZZNS ZZNT ZZNL ZZNN`,
|
||
FM: `ZZSQ ZZSO ZZTA ZZTB ZZST`, CTUN: `ZZCN`,
|
||
S-метр/телеметрия: `ZZSM`, шаги VFO: `ZZAU ZZBP ZZSU ZZSA ZZSB`,
|
||
передача: `ZZTX ZZRX`, сервис: `ZZID ZZRV 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.
|
||
|
||
---
|
||
|
||
## 3. Что нужно сделать (актуально / есть чем закрыть)
|
||
|
||
Эти команды — заглушки, но соответствующая функция в EWSDR **уже есть** или
|
||
легко добавляется. Приоритетные кандидаты:
|
||
|
||
| Команда(ы) | Что | Чем закрыть | Сложность |
|
||
|---|---|---|---|
|
||
| `ZZCU` | загрузка CPU (read) | телеметрия процесса | низкая |
|
||
| `ZZMY` / `ZZQR` / `ZZQS` / `ZZQM` | память каналов (запись/чтение/quick) | `ChannelStore` уже есть | средняя |
|
||
| `ZZFD` | FM-девиация (radio button) | нужен публичный `SetFMDeviation` (сейчас только поле `FFMDeviation`) | низкая |
|
||
| `ZZDM` / `ZZDA` / `ZZPO` / `ZZDY` | режим/усреднение/пик/порог спектра | UI-параметры спектра | средняя |
|
||
| `ZZAS` | RX2 AGC-T | — только при появлении RX2 | — |
|
||
|
||
> Прежде чем реализовывать новую команду, сверяйся с форматом поля в
|
||
> `Thetis/.../CAT/CATStructs.xml` (`<nsetparms>` / `<ngetparms>`) и телом
|
||
> метода в `CATCommands.cs`, чтобы ширина/знак значения совпадали.
|
||
|
||
### 3.1 Совсем не обрабатываются (вернут `?;`)
|
||
|
||
`ZZCU` (CPU), `ZZDY` (DX threshold), `ZZPK`/`ZZPL` (речевой компрессор),
|
||
`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 ZZMB ZZOB`, ext `BF BG BR DO DQ DR OF OG OH OL SG SH SS` | один приёмник |
|
||
| **TX-DSP тракт** | mic gain `ZZMG`/`MG`, монитор `ZZMO`/`MO`, TX-EQ `ZZEB/ER/ET`, компрессор `ZZPK/ZZPL/CF CI CL CM`, two-tone `ZZUS`, VAC `ZZVB/ZZVF` | нет обработки передачи |
|
||
| **CW-кейер / CWX** | `ZZKM ZZKS ZZKY ZZCB ZZCD ZZCS`, `KY KS` | нет кейера |
|
||
| **RTTY / DIGI** | `ZZRA ZZRL`, ext `RF RH RM RS RY` | нет RTTY-движка |
|
||
| **RIT / XIT** | `RT XT RC RU RD` (как RIT), ext `RB RF RH` | нет смещения приёма |
|
||
| **Diversity** | `ZZDA(div) ZZDB`, ext `DA` | нет диверсити-приёма |
|
||
| **Спектр/водопад (внутр.)** | ext `SV SW SX SY SZ WT WU WV WW` | не управляется по CAT |
|
||
|
||
---
|
||
|
||
## 5. Транспорты
|
||
|
||
- **Serial** (`CATSerial.pas`): до 4 портов, параметры (порт/скорость/биты/
|
||
чётность/стоп) из `TGlobalSettings.CATSerial*`, применяются
|
||
`TCATAdapter.ApplySettings`. На текущей платформе сборки может быть
|
||
`{$DEFINE CAT_SERIAL_STUB}` (см. начало файла) — проверить перед релизом.
|
||
- **TCP** (`CATTcp.pas`): сервер на `CATTcpPort`, включается флагом
|
||
`CATTcpEnabled`. Клиенты идентифицируются GUID через `ZZGA`/`ZZGR`.
|
||
|
||
---
|
||
|
||
## 6. Как добавить новую CAT-команду (чек-лист)
|
||
|
||
1. **Сверить формат** в `CATStructs.xml` + `CATCommands.cs` (Thetis).
|
||
2. Если нужна новая возможность контроллера — есть ли публичный метод/поле
|
||
в `TRadioController`? Если нет — добавить (по образцу `SetSplit`).
|
||
3. В `CATEngine.pas`: добавить callback(и) в `TCATContext`, `SafeGet*`-хелпер
|
||
для GET, переписать тело команды (`CmdXX` или `ZZXX`).
|
||
4. В `CATAdapter.pas`: геттер (чтение `FController.F*`), сеттер + `SyncXX`
|
||
(через `Invoke`), регистрация в `TCATAdapter.Create`.
|
||
5. Если команда `ZZ*` ещё не в диспетчере — добавить ветку `else if ext = '..'`.
|
||
6. Сборка-проверка: `lazbuild -B --ws=qt6 ewsdr.lpr` (GUI-граф включает CAT;
|
||
headless-демон `ewsdrd` CAT **не** содержит).
|