mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 19:45:09 +00:00
Phase 5 (batch 25a): de-dup telemetry fields + push web-client-active to core
Prep for moving the HP-status callback into the controller:
- Remove the duplicate FLast{SMeter,FwdW,SWR,SupplyV,SupplyA,PLLLock}
fields from MainForm; the controller (which already declared them) is
now the sole owner. The UI-only S-meter ballistics (FSMeterPeak/Min/Avg)
stay in MainForm.
- TWebServer gains an OnClientActiveChanged event (fired via a
SetClientActive setter at the three client connect/disconnect points);
MainForm mirrors it into FController.FWebClientActive. The lazy mirror
in ApplyMOX/ApplyTUN is removed, so the flag is always current — needed
for the HWPTT->SetMOX path that moves into the controller next.
Behaviour-preserving (the flag held the same value at MOX time before).
Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
239ff54942
commit
9d2324cc6c
+65
-64
@@ -145,18 +145,11 @@ type
|
||||
FDUCPendingI: array[0..239] of Integer;
|
||||
FDUCPendingQ: array[0..239] of Integer;
|
||||
FDUCPendingCount: Integer;
|
||||
FLastSMeter: Double;
|
||||
FSMeterPeak: Double; // верхняя граница светлой зоны
|
||||
FSMeterMin: Double; // нижняя граница светлой зоны
|
||||
FSMeterAvg: Double; // сглаженное среднее (EMA)
|
||||
// RX/seq телеметрия переехала в TRadioController (пишется из OnDDCIQ).
|
||||
FLastFwdW: Double;
|
||||
FLastSWR: Double;
|
||||
// Эти значения приходят с HP Status пакетами (50..200 раз/с). UI обновляется
|
||||
// из MeterTimerTick (10 Гц), чтобы цифры/полоски не дёргались.
|
||||
FLastSupplyV: Double;
|
||||
FLastSupplyA: Double;
|
||||
FLastPLLLock: Boolean;
|
||||
// RX/seq + HP-телеметрия (FController.FLastSMeter/FwdW/SWR/SupplyV/SupplyA/PLLLock)
|
||||
// живут в TRadioController.
|
||||
|
||||
// ---- Spectrum / Waterfall view ----
|
||||
FSpecView: TSpectrumView;
|
||||
@@ -478,6 +471,7 @@ type
|
||||
procedure WebOnWfNF(On_: Boolean);
|
||||
procedure WebOnRun(On_: Boolean);
|
||||
procedure WebOnMute(On_: Boolean);
|
||||
procedure WebOnClientActiveChanged(Active: Boolean);
|
||||
procedure WebOnCtun(On_: Boolean);
|
||||
procedure WebOnNR(Mode: Integer);
|
||||
procedure WebOnNB(Mode: Integer);
|
||||
@@ -996,7 +990,7 @@ begin
|
||||
RestoreWindowBounds;
|
||||
// S-метр позиционируем после рестора размера окна
|
||||
// (будет пересчитан в первом тике SpectrumTimerTick)
|
||||
FLastSMeter := -130;
|
||||
FController.FLastSMeter := -130;
|
||||
|
||||
// Загружаем настройки веб-сервера из JSON и создаём сервер
|
||||
FController.FSettings.LoadWebSettings(WebCfg);
|
||||
@@ -1034,6 +1028,9 @@ begin
|
||||
FWebServer.OnFMStep := WebOnFMStep;
|
||||
FWebServer.OnWebMic := WebOnMic;
|
||||
FWebServer.OnXvtrBand := WebOnXvtrBand;
|
||||
// Web-слой держит FController.FWebClientActive актуальным (выбор mic-source
|
||||
// при TX, в т.ч. для HWPTT из контроллера) — больше не зеркалим лениво.
|
||||
FWebServer.OnClientActiveChanged := WebOnClientActiveChanged;
|
||||
if FWebEnabled then FWebServer.Start;
|
||||
PushXvtrToWeb;
|
||||
FillChar(FCATLastGlobal, SizeOf(FCATLastGlobal), 0);
|
||||
@@ -1066,11 +1063,11 @@ begin
|
||||
FController.FLastSeqErrorDDC := -1;
|
||||
FController.FLastSeqErrorDelta:= 0;
|
||||
FController.FSeqOkStreak := 0;
|
||||
FLastFwdW := 0;
|
||||
FLastSWR := 1;
|
||||
FLastSupplyV:= -1;
|
||||
FLastSupplyA:= -1;
|
||||
FLastPLLLock:= False;
|
||||
FController.FLastFwdW := 0;
|
||||
FController.FLastSWR := 1;
|
||||
FController.FLastSupplyV:= -1;
|
||||
FController.FLastSupplyA:= -1;
|
||||
FController.FLastPLLLock:= False;
|
||||
FDeviceCount := 0;
|
||||
FDeviceDialog := TDeviceDialog.Create(Self);
|
||||
FDeviceDialog.OnDiscover := BtnDiscoverFromDialog;
|
||||
@@ -2973,11 +2970,11 @@ begin
|
||||
|
||||
|
||||
// Сглаженное среднее (EMA)
|
||||
FSMeterAvg := FSMeterAvg * (1.0 - AVG_ALPHA) + FLastSMeter * AVG_ALPHA;
|
||||
FSMeterAvg := FSMeterAvg * (1.0 - AVG_ALPHA) + FController.FLastSMeter * AVG_ALPHA;
|
||||
|
||||
// Цели для Peak и Min
|
||||
PeakTarget := Max(FLastSMeter, FSMeterAvg + ZONE_DB);
|
||||
MinTarget := Min(FLastSMeter, FSMeterAvg - ZONE_DB);
|
||||
PeakTarget := Max(FController.FLastSMeter, FSMeterAvg + ZONE_DB);
|
||||
MinTarget := Min(FController.FLastSMeter, FSMeterAvg - ZONE_DB);
|
||||
|
||||
// Адаптивный alpha: чем дальше от цели — тем быстрее догоняем
|
||||
PeakDiff := Abs(PeakTarget - FSMeterPeak);
|
||||
@@ -2988,11 +2985,11 @@ begin
|
||||
FSMeterPeak := FSMeterPeak + PeakAlpha * (PeakTarget - FSMeterPeak);
|
||||
FSMeterMin := FSMeterMin + MinAlpha * (MinTarget - FSMeterMin);
|
||||
|
||||
FSpecView.LastSMeter := FLastSMeter;
|
||||
FSpecView.LastSMeter := FController.FLastSMeter;
|
||||
FSpecView.SMeterPeak := FSMeterPeak;
|
||||
FSpecView.SMeterMin := FSMeterMin;
|
||||
FSpecView.LastFwdW := FLastFwdW;
|
||||
FSpecView.LastSWR := FLastSWR;
|
||||
FSpecView.LastFwdW := FController.FLastFwdW;
|
||||
FSpecView.LastSWR := FController.FLastSWR;
|
||||
FSpecView.Transmitting := FController.FTransmitting;
|
||||
|
||||
if PbSMeterRight <> nil then PbSMeterRight.Invalidate;
|
||||
@@ -3080,7 +3077,7 @@ begin
|
||||
|
||||
if FController.FWDSPReady then
|
||||
begin
|
||||
FLastSMeter := FController.FDSPEngine.GetSMeterDBm;
|
||||
FController.FLastSMeter := FController.FDSPEngine.GetSMeterDBm;
|
||||
FController.FDSPEngine.SetSpectrumWidth(FSpectrumWidth);
|
||||
Inc(FAgcLineCounter);
|
||||
if FAgcLineCounter >= 6 then
|
||||
@@ -3095,7 +3092,7 @@ begin
|
||||
// Обновляем оверлей если видим
|
||||
if Assigned(FVfoOverlay) and FVfoOverlay.Visible then
|
||||
begin
|
||||
FVfoOverlay.UpdateSMeter(FLastSMeter);
|
||||
FVfoOverlay.UpdateSMeter(FController.FLastSMeter);
|
||||
FVfoOverlay.UpdateVfo(FController.FVfoA);
|
||||
PositionVfoOverlay;
|
||||
end;
|
||||
@@ -3187,19 +3184,19 @@ begin
|
||||
end
|
||||
else
|
||||
begin
|
||||
if FLastPLLLock then
|
||||
if FController.FLastPLLLock then
|
||||
WebPLLText := 'PLL OK'
|
||||
else
|
||||
WebPLLText := 'PLL?';
|
||||
|
||||
if not BoardSupportsSupplyVoltage(FController.FNetwork.Device.BoardType) then
|
||||
WebSupplyText := 'Supply n/a'
|
||||
else if FLastSupplyV >= 0 then
|
||||
else if FController.FLastSupplyV >= 0 then
|
||||
begin
|
||||
if FLastSupplyA >= 0 then
|
||||
WebSupplyText := Format('Supply %.1fV %.1fA', [FLastSupplyV, FLastSupplyA])
|
||||
if FController.FLastSupplyA >= 0 then
|
||||
WebSupplyText := Format('Supply %.1fV %.1fA', [FController.FLastSupplyV, FController.FLastSupplyA])
|
||||
else
|
||||
WebSupplyText := Format('Supply %.1fV', [FLastSupplyV]);
|
||||
WebSupplyText := Format('Supply %.1fV', [FController.FLastSupplyV]);
|
||||
end
|
||||
else
|
||||
WebSupplyText := 'Supply --';
|
||||
@@ -3227,7 +3224,7 @@ begin
|
||||
FWebServer.PushSpectrum(
|
||||
FSpectrumBuf, 1024,
|
||||
FWaterfallBuf,
|
||||
FLastSMeter,
|
||||
FController.FLastSMeter,
|
||||
FController.FVfoA, FController.FMode, FController.FFilterBW, FController.FAGCMode, FController.FAGCTop,
|
||||
FController.FSpanHz, FController.FVolume,
|
||||
FController.FWfAGCEnabled, FController.FWfNFEnabled,
|
||||
@@ -3239,7 +3236,7 @@ begin
|
||||
FController.FVfoB, FController.FActiveVfo,
|
||||
FController.FTransmitting, FController.FDrivePercent,
|
||||
FController.FAtten, FController.FTuning, FController.FDisplayDuplex,
|
||||
FLastFwdW, FLastSWR, FController.FPAMaxPower,
|
||||
FController.FLastFwdW, FController.FLastSWR, FController.FPAMaxPower,
|
||||
WebStatusText, WebBoardText, WebIPText, WebSupplyText,
|
||||
WebPLLText, WebRXText, WebTXText, WebSeqText);
|
||||
end;
|
||||
@@ -3322,7 +3319,7 @@ begin
|
||||
(Status.UserADC1Hi shl 8) or Status.UserADC1Lo,
|
||||
FController.FNetwork.Device.BoardType);
|
||||
end;
|
||||
// FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick —
|
||||
// FController.FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick —
|
||||
// ExciterPwr это мощность TX, не уровень принятого сигнала.
|
||||
FwdW := ADCToWatts100(FwdPwr);
|
||||
// FController.FTransmitting — наш программный флаг (MOX/TUN/HW-PTT через ApplyMOX).
|
||||
@@ -3377,35 +3374,35 @@ begin
|
||||
// FwdW=0 / SWRV=1 — это «не на передаче»: снапим без decay,
|
||||
// чтобы метры моментально падали при отпускании PTT.
|
||||
if FwdW <= 0 then
|
||||
FLastFwdW := 0
|
||||
else if FwdW > FLastFwdW then
|
||||
FLastFwdW := FwdW // attack: instant
|
||||
FController.FLastFwdW := 0
|
||||
else if FwdW > FController.FLastFwdW then
|
||||
FController.FLastFwdW := FwdW // attack: instant
|
||||
else
|
||||
FLastFwdW := DECAY_FWD * FwdW + (1.0 - DECAY_FWD) * FLastFwdW;
|
||||
FController.FLastFwdW := DECAY_FWD * FwdW + (1.0 - DECAY_FWD) * FController.FLastFwdW;
|
||||
if SWRV <= 1.0 then
|
||||
FLastSWR := 1.0
|
||||
else if SWRV > FLastSWR then
|
||||
FLastSWR := SWRV // attack: instant
|
||||
FController.FLastSWR := 1.0
|
||||
else if SWRV > FController.FLastSWR then
|
||||
FController.FLastSWR := SWRV // attack: instant
|
||||
else
|
||||
FLastSWR := DECAY_SWR * SWRV + (1.0 - DECAY_SWR) * FLastSWR;
|
||||
FController.FLastSWR := DECAY_SWR * SWRV + (1.0 - DECAY_SWR) * FController.FLastSWR;
|
||||
if SupplyV >= 0 then
|
||||
begin
|
||||
if FLastSupplyV < 0 then
|
||||
FLastSupplyV := SupplyV // первое значение — без сглаживания
|
||||
if FController.FLastSupplyV < 0 then
|
||||
FController.FLastSupplyV := SupplyV // первое значение — без сглаживания
|
||||
else
|
||||
FLastSupplyV := ALPHA_SUPPLY * SupplyV + (1.0 - ALPHA_SUPPLY) * FLastSupplyV;
|
||||
FController.FLastSupplyV := ALPHA_SUPPLY * SupplyV + (1.0 - ALPHA_SUPPLY) * FController.FLastSupplyV;
|
||||
end else
|
||||
FLastSupplyV := -1.0;
|
||||
FController.FLastSupplyV := -1.0;
|
||||
|
||||
if SupplyA >= 0 then
|
||||
begin
|
||||
if FLastSupplyA < 0 then
|
||||
FLastSupplyA := SupplyA
|
||||
if FController.FLastSupplyA < 0 then
|
||||
FController.FLastSupplyA := SupplyA
|
||||
else
|
||||
FLastSupplyA := ALPHA_SUPPLY * SupplyA + (1.0 - ALPHA_SUPPLY) * FLastSupplyA;
|
||||
FController.FLastSupplyA := ALPHA_SUPPLY * SupplyA + (1.0 - ALPHA_SUPPLY) * FController.FLastSupplyA;
|
||||
end else
|
||||
FLastSupplyA := -1.0;
|
||||
FLastPLLLock := PLLLock;
|
||||
FController.FLastSupplyA := -1.0;
|
||||
FController.FLastPLLLock := PLLLock;
|
||||
|
||||
if (FSpecView <> nil) and (FSpecView.ADCOverloadVisible <> (ADCOverload <> 0)) then
|
||||
begin
|
||||
@@ -3444,8 +3441,8 @@ begin
|
||||
end;
|
||||
|
||||
procedure TMainForm.UpdateTXMeters;
|
||||
// Вызывается из MeterTimerTick (10 Гц). Использует FLastFwdW/FLastSWR/
|
||||
// FLastSupplyV/FLastSupplyA обновляются на rate HP Status (~150/с)
|
||||
// Вызывается из MeterTimerTick (10 Гц). Использует FController.FLastFwdW/FController.FLastSWR/
|
||||
// FController.FLastSupplyV/FController.FLastSupplyA обновляются на rate HP Status (~150/с)
|
||||
// в DoUpdateStatus.
|
||||
begin
|
||||
if not FController.FRunning then
|
||||
@@ -3455,7 +3452,7 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if FLastPLLLock then
|
||||
if FController.FLastPLLLock then
|
||||
SetStatusText(7, 'PLL OK')
|
||||
else
|
||||
SetStatusText(7, 'PLL?');
|
||||
@@ -3466,14 +3463,14 @@ begin
|
||||
Exit;
|
||||
end;
|
||||
|
||||
if FLastSupplyV >= 0 then
|
||||
if FController.FLastSupplyV >= 0 then
|
||||
begin
|
||||
if FLastSupplyA >= 0 then
|
||||
if FController.FLastSupplyA >= 0 then
|
||||
SetStatusText(3,
|
||||
Format('Supply %.1fV %.1fA', [FLastSupplyV, FLastSupplyA]))
|
||||
Format('Supply %.1fV %.1fA', [FController.FLastSupplyV, FController.FLastSupplyA]))
|
||||
else
|
||||
SetStatusText(3,
|
||||
Format('Supply %.1fV', [FLastSupplyV]));
|
||||
Format('Supply %.1fV', [FController.FLastSupplyV]));
|
||||
end else
|
||||
SetStatusText(3, 'Supply --');
|
||||
end;
|
||||
@@ -4470,9 +4467,7 @@ end;
|
||||
// ---------------------------------------------------------------------------
|
||||
procedure TMainForm.ApplyTUN(Active: Boolean);
|
||||
begin
|
||||
// Web-слой пока не владеет своим флагом — зеркалим состояние клиента в
|
||||
// контроллер перед командой (SetTune зовёт SetMOX, который читает его).
|
||||
FController.FWebClientActive := Assigned(FWebServer) and FWebServer.WebClientActive;
|
||||
// FWebClientActive держит web-слой актуальным (OnClientActiveChanged).
|
||||
FController.SetTune(Active); // ядро TUN (safety/тон/drive/MOX) + рендер через rfTuning
|
||||
end;
|
||||
|
||||
@@ -5209,9 +5204,8 @@ end;
|
||||
|
||||
procedure TMainForm.ApplyMOX(Active: Boolean);
|
||||
begin
|
||||
// Web-слой пока не владеет своим флагом — зеркалим текущее состояние клиента
|
||||
// в контроллер перед командой (определяет mic-source при TX-on).
|
||||
FController.FWebClientActive := Assigned(FWebServer) and FWebServer.WebClientActive;
|
||||
// FWebClientActive держит web-слой актуальным (OnClientActiveChanged) —
|
||||
// определяет mic-source при TX-on.
|
||||
FController.SetMOX(Active); // ядро TX (safety/PTT/DSP) + рендер через rfTransmitting
|
||||
end;
|
||||
|
||||
@@ -5350,7 +5344,7 @@ begin
|
||||
PanelLeft.Width := 0;
|
||||
FVfoOverlay.Width := 260;
|
||||
FVfoOverlay.Height := 136; // OVL_H_NORM — расширяется сам при открытии AGC-пикера
|
||||
FVfoOverlay.SetState(FController.FMode, FController.FFilterBW, FController.FVfoA, FLastSMeter);
|
||||
FVfoOverlay.SetState(FController.FMode, FController.FFilterBW, FController.FVfoA, FController.FLastSMeter);
|
||||
FVfoOverlay.SetDSPState(FController.FNRMode, FController.FNBMode, FController.FSNB, FController.FANF, FController.FAGCMode);
|
||||
FVfoOverlay.Visible := True;
|
||||
PositionVfoOverlay;
|
||||
@@ -5435,7 +5429,7 @@ begin
|
||||
SyncSpecViewFreq;
|
||||
if Assigned(FVfoOverlay) and FVfoOverlay.Visible then
|
||||
begin
|
||||
FVfoOverlay.SetState(FController.FMode, FController.FFilterBW, FController.FVfoA, FLastSMeter);
|
||||
FVfoOverlay.SetState(FController.FMode, FController.FFilterBW, FController.FVfoA, FController.FLastSMeter);
|
||||
FVfoOverlay.SetDSPState(FController.FNRMode, FController.FNBMode, FController.FSNB, FController.FANF, FController.FAGCMode);
|
||||
PositionVfoOverlay; // перепозиционируем при смене LSB↔USB
|
||||
end;
|
||||
@@ -5682,6 +5676,13 @@ begin
|
||||
FController.SetMute(FWebSyncBool); // идемпотентно; OnControllerState обновит UI
|
||||
end;
|
||||
|
||||
procedure TMainForm.WebOnClientActiveChanged(Active: Boolean);
|
||||
// Вызывается из потока web-сервера при connect/disconnect клиента. Зеркалим в
|
||||
// ядро — SetMOX (включая HWPTT-путь в контроллере) выбирает по этому mic-source.
|
||||
begin
|
||||
FController.FWebClientActive := Active;
|
||||
end;
|
||||
|
||||
// ── CTUN ──────────────────────────────────────────────────────────────────
|
||||
|
||||
procedure TMainForm.WebOnCtun(On_: Boolean);
|
||||
@@ -6788,7 +6789,7 @@ function TMainForm.CATGetSNB: Boolean; begin Result := FController.FSNB; e
|
||||
function TMainForm.CATGetANF: Boolean; begin Result := FController.FANF; end;
|
||||
function TMainForm.CATGetTX: Boolean; begin Result := FController.FTransmitting; end;
|
||||
function TMainForm.CATGetRunning: Boolean; begin Result := FController.FRunning; end;
|
||||
function TMainForm.CATGetSMeter: Double; begin Result := FLastSMeter; end;
|
||||
function TMainForm.CATGetSMeter: Double; begin Result := FController.FLastSMeter; end;
|
||||
function TMainForm.CATGetBand: Integer; begin Result := FController.FCurrentBand; end;
|
||||
|
||||
// --- Setters ----------------------------------------------------------------
|
||||
|
||||
Reference in New Issue
Block a user