add Alex setup

This commit is contained in:
2026-05-14 18:52:50 +03:00
parent ec596bb0c8
commit aea9f02df8
4 changed files with 559 additions and 52 deletions
+80
View File
@@ -103,6 +103,23 @@ type
TXSpecGridStep: Double; // grid step in dB, e.g. 10
end;
// Alex (Antenna + Filter board) settings per-device.
// Хранятся в JSON-секции "alex" под MAC.
// Безопасные дефолты: ANT1 для всех диапазонов, вторичный вход выключен.
TAlexSettings = record
// Per-band (11 bands: 0=160m..10=6m)
RxAnt: array[0..CFG_BAND_COUNT-1] of Byte; // 1..3 (ANT1/2/3)
TxAnt: array[0..CFG_BAND_COUNT-1] of Byte; // 1..3 (ANT1/2/3)
// Вторичный RX вход: 0=выкл, 1=BYPS(Ext1+Bypass), 2=EXT1(Ext2+Bypass), 3=XVTR(XvtrDDC+Bypass)
RxOnly: array[0..CFG_BAND_COUNT-1] of Byte;
DoNotTx: array[0..CFG_BAND_COUNT-1] of Boolean; // программный запрет TX на диапазоне
// Глобальные флаги в режиме TX
RxBypassOnTx: Boolean; // бит 11 (Bypass relay) во время TX
Ext1OnTx: Boolean; // бит 9 (Ext1) + бит 11 во время TX
GndBpf2OnTx: Boolean; // заземление BPF2/RX2 во время TX (Alex1 бит 8, ANAN-8000DLE)
EnableXvtrHf: Boolean; // режим XVTR HF
end;
TGlobalSettings = record
Volume: Integer;
DriveLevel: Integer;
@@ -210,6 +227,10 @@ type
// CAT settings — не привязаны к MAC, хранятся в корне JSON (доступны до подключения)
procedure SaveCATSettings(const G: TGlobalSettings);
procedure LoadCATSettings(var G: TGlobalSettings);
// Alex (antenna) settings per-device (JSON-секция "alex" под MAC).
class procedure DefaultAlex(out A: TAlexSettings);
function LoadAlex(const MAC: array of Byte; out A: TAlexSettings): Boolean;
procedure SaveAlex(const MAC: array of Byte; const A: TAlexSettings);
// Тема — глобальная настройка, не привязана к устройству
procedure SaveTheme(ALightTheme: Boolean);
function LoadTheme: Boolean;
@@ -914,6 +935,65 @@ begin
JW(O,'tx_spec_grid_step', T.TXSpecGridStep);
end;
class procedure TSettingsManager.DefaultAlex(out A: TAlexSettings);
var i: Integer;
begin
FillChar(A, SizeOf(A), 0);
for i := 0 to CFG_BAND_COUNT - 1 do
begin
A.RxAnt[i] := 1; // ANT1 — безопасный дефолт
A.TxAnt[i] := 1; // ANT1
A.RxOnly[i] := 0; // вторичный вход выключен
A.DoNotTx[i] := False;
end;
A.RxBypassOnTx := False;
A.Ext1OnTx := False;
A.GndBpf2OnTx := False;
A.EnableXvtrHf := False;
end;
function TSettingsManager.LoadAlex(const MAC: array of Byte;
out A: TAlexSettings): Boolean;
var MacStr: string; DevObj, O: TJSONObject; i: Integer;
begin
DefaultAlex(A);
MacStr := MacToStr(MAC);
Result := FRoot.Find(MacStr) <> nil;
if not Result then Exit;
DevObj := GetDevObj(MacStr);
if DevObj.Find('alex') = nil then Exit;
O := EnsureObj(DevObj, 'alex');
for i := 0 to CFG_BAND_COUNT - 1 do
begin
A.RxAnt[i] := EnsureRange(JI(O, 'rx_ant_' + IntToStr(i), 1), 1, 3);
A.TxAnt[i] := EnsureRange(JI(O, 'tx_ant_' + IntToStr(i), 1), 1, 3);
A.RxOnly[i] := EnsureRange(JI(O, 'rx_only_' + IntToStr(i), 0), 0, 3);
A.DoNotTx[i] := JB(O, 'do_not_tx_' + IntToStr(i), False);
end;
A.RxBypassOnTx := JB(O, 'rx_bypass_on_tx', False);
A.Ext1OnTx := JB(O, 'ext1_on_tx', False);
A.GndBpf2OnTx := JB(O, 'gnd_bpf2_on_tx', False);
A.EnableXvtrHf := JB(O, 'enable_xvtr_hf', False);
end;
procedure TSettingsManager.SaveAlex(const MAC: array of Byte;
const A: TAlexSettings);
var O: TJSONObject; i: Integer;
begin
O := EnsureObj(GetDevObj(MacToStr(MAC)), 'alex');
for i := 0 to CFG_BAND_COUNT - 1 do
begin
JW(O, 'rx_ant_' + IntToStr(i), Integer(A.RxAnt[i]));
JW(O, 'tx_ant_' + IntToStr(i), Integer(A.TxAnt[i]));
JW(O, 'rx_only_' + IntToStr(i), Integer(A.RxOnly[i]));
JW(O, 'do_not_tx_' + IntToStr(i), A.DoNotTx[i]);
end;
JW(O, 'rx_bypass_on_tx', A.RxBypassOnTx);
JW(O, 'ext1_on_tx', A.Ext1OnTx);
JW(O, 'gnd_bpf2_on_tx', A.GndBpf2OnTx);
JW(O, 'enable_xvtr_hf', A.EnableXvtrHf);
end;
procedure TSettingsManager.SaveTheme(ALightTheme: Boolean);
var O: TJSONObject;
begin