mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +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;
|
FDUCPendingI: array[0..239] of Integer;
|
||||||
FDUCPendingQ: array[0..239] of Integer;
|
FDUCPendingQ: array[0..239] of Integer;
|
||||||
FDUCPendingCount: Integer;
|
FDUCPendingCount: Integer;
|
||||||
FLastSMeter: Double;
|
|
||||||
FSMeterPeak: Double; // верхняя граница светлой зоны
|
FSMeterPeak: Double; // верхняя граница светлой зоны
|
||||||
FSMeterMin: Double; // нижняя граница светлой зоны
|
FSMeterMin: Double; // нижняя граница светлой зоны
|
||||||
FSMeterAvg: Double; // сглаженное среднее (EMA)
|
FSMeterAvg: Double; // сглаженное среднее (EMA)
|
||||||
// RX/seq телеметрия переехала в TRadioController (пишется из OnDDCIQ).
|
// RX/seq + HP-телеметрия (FController.FLastSMeter/FwdW/SWR/SupplyV/SupplyA/PLLLock)
|
||||||
FLastFwdW: Double;
|
// живут в TRadioController.
|
||||||
FLastSWR: Double;
|
|
||||||
// Эти значения приходят с HP Status пакетами (50..200 раз/с). UI обновляется
|
|
||||||
// из MeterTimerTick (10 Гц), чтобы цифры/полоски не дёргались.
|
|
||||||
FLastSupplyV: Double;
|
|
||||||
FLastSupplyA: Double;
|
|
||||||
FLastPLLLock: Boolean;
|
|
||||||
|
|
||||||
// ---- Spectrum / Waterfall view ----
|
// ---- Spectrum / Waterfall view ----
|
||||||
FSpecView: TSpectrumView;
|
FSpecView: TSpectrumView;
|
||||||
@@ -478,6 +471,7 @@ type
|
|||||||
procedure WebOnWfNF(On_: Boolean);
|
procedure WebOnWfNF(On_: Boolean);
|
||||||
procedure WebOnRun(On_: Boolean);
|
procedure WebOnRun(On_: Boolean);
|
||||||
procedure WebOnMute(On_: Boolean);
|
procedure WebOnMute(On_: Boolean);
|
||||||
|
procedure WebOnClientActiveChanged(Active: Boolean);
|
||||||
procedure WebOnCtun(On_: Boolean);
|
procedure WebOnCtun(On_: Boolean);
|
||||||
procedure WebOnNR(Mode: Integer);
|
procedure WebOnNR(Mode: Integer);
|
||||||
procedure WebOnNB(Mode: Integer);
|
procedure WebOnNB(Mode: Integer);
|
||||||
@@ -996,7 +990,7 @@ begin
|
|||||||
RestoreWindowBounds;
|
RestoreWindowBounds;
|
||||||
// S-метр позиционируем после рестора размера окна
|
// S-метр позиционируем после рестора размера окна
|
||||||
// (будет пересчитан в первом тике SpectrumTimerTick)
|
// (будет пересчитан в первом тике SpectrumTimerTick)
|
||||||
FLastSMeter := -130;
|
FController.FLastSMeter := -130;
|
||||||
|
|
||||||
// Загружаем настройки веб-сервера из JSON и создаём сервер
|
// Загружаем настройки веб-сервера из JSON и создаём сервер
|
||||||
FController.FSettings.LoadWebSettings(WebCfg);
|
FController.FSettings.LoadWebSettings(WebCfg);
|
||||||
@@ -1034,6 +1028,9 @@ begin
|
|||||||
FWebServer.OnFMStep := WebOnFMStep;
|
FWebServer.OnFMStep := WebOnFMStep;
|
||||||
FWebServer.OnWebMic := WebOnMic;
|
FWebServer.OnWebMic := WebOnMic;
|
||||||
FWebServer.OnXvtrBand := WebOnXvtrBand;
|
FWebServer.OnXvtrBand := WebOnXvtrBand;
|
||||||
|
// Web-слой держит FController.FWebClientActive актуальным (выбор mic-source
|
||||||
|
// при TX, в т.ч. для HWPTT из контроллера) — больше не зеркалим лениво.
|
||||||
|
FWebServer.OnClientActiveChanged := WebOnClientActiveChanged;
|
||||||
if FWebEnabled then FWebServer.Start;
|
if FWebEnabled then FWebServer.Start;
|
||||||
PushXvtrToWeb;
|
PushXvtrToWeb;
|
||||||
FillChar(FCATLastGlobal, SizeOf(FCATLastGlobal), 0);
|
FillChar(FCATLastGlobal, SizeOf(FCATLastGlobal), 0);
|
||||||
@@ -1066,11 +1063,11 @@ begin
|
|||||||
FController.FLastSeqErrorDDC := -1;
|
FController.FLastSeqErrorDDC := -1;
|
||||||
FController.FLastSeqErrorDelta:= 0;
|
FController.FLastSeqErrorDelta:= 0;
|
||||||
FController.FSeqOkStreak := 0;
|
FController.FSeqOkStreak := 0;
|
||||||
FLastFwdW := 0;
|
FController.FLastFwdW := 0;
|
||||||
FLastSWR := 1;
|
FController.FLastSWR := 1;
|
||||||
FLastSupplyV:= -1;
|
FController.FLastSupplyV:= -1;
|
||||||
FLastSupplyA:= -1;
|
FController.FLastSupplyA:= -1;
|
||||||
FLastPLLLock:= False;
|
FController.FLastPLLLock:= False;
|
||||||
FDeviceCount := 0;
|
FDeviceCount := 0;
|
||||||
FDeviceDialog := TDeviceDialog.Create(Self);
|
FDeviceDialog := TDeviceDialog.Create(Self);
|
||||||
FDeviceDialog.OnDiscover := BtnDiscoverFromDialog;
|
FDeviceDialog.OnDiscover := BtnDiscoverFromDialog;
|
||||||
@@ -2973,11 +2970,11 @@ begin
|
|||||||
|
|
||||||
|
|
||||||
// Сглаженное среднее (EMA)
|
// Сглаженное среднее (EMA)
|
||||||
FSMeterAvg := FSMeterAvg * (1.0 - AVG_ALPHA) + FLastSMeter * AVG_ALPHA;
|
FSMeterAvg := FSMeterAvg * (1.0 - AVG_ALPHA) + FController.FLastSMeter * AVG_ALPHA;
|
||||||
|
|
||||||
// Цели для Peak и Min
|
// Цели для Peak и Min
|
||||||
PeakTarget := Max(FLastSMeter, FSMeterAvg + ZONE_DB);
|
PeakTarget := Max(FController.FLastSMeter, FSMeterAvg + ZONE_DB);
|
||||||
MinTarget := Min(FLastSMeter, FSMeterAvg - ZONE_DB);
|
MinTarget := Min(FController.FLastSMeter, FSMeterAvg - ZONE_DB);
|
||||||
|
|
||||||
// Адаптивный alpha: чем дальше от цели — тем быстрее догоняем
|
// Адаптивный alpha: чем дальше от цели — тем быстрее догоняем
|
||||||
PeakDiff := Abs(PeakTarget - FSMeterPeak);
|
PeakDiff := Abs(PeakTarget - FSMeterPeak);
|
||||||
@@ -2988,11 +2985,11 @@ begin
|
|||||||
FSMeterPeak := FSMeterPeak + PeakAlpha * (PeakTarget - FSMeterPeak);
|
FSMeterPeak := FSMeterPeak + PeakAlpha * (PeakTarget - FSMeterPeak);
|
||||||
FSMeterMin := FSMeterMin + MinAlpha * (MinTarget - FSMeterMin);
|
FSMeterMin := FSMeterMin + MinAlpha * (MinTarget - FSMeterMin);
|
||||||
|
|
||||||
FSpecView.LastSMeter := FLastSMeter;
|
FSpecView.LastSMeter := FController.FLastSMeter;
|
||||||
FSpecView.SMeterPeak := FSMeterPeak;
|
FSpecView.SMeterPeak := FSMeterPeak;
|
||||||
FSpecView.SMeterMin := FSMeterMin;
|
FSpecView.SMeterMin := FSMeterMin;
|
||||||
FSpecView.LastFwdW := FLastFwdW;
|
FSpecView.LastFwdW := FController.FLastFwdW;
|
||||||
FSpecView.LastSWR := FLastSWR;
|
FSpecView.LastSWR := FController.FLastSWR;
|
||||||
FSpecView.Transmitting := FController.FTransmitting;
|
FSpecView.Transmitting := FController.FTransmitting;
|
||||||
|
|
||||||
if PbSMeterRight <> nil then PbSMeterRight.Invalidate;
|
if PbSMeterRight <> nil then PbSMeterRight.Invalidate;
|
||||||
@@ -3080,7 +3077,7 @@ begin
|
|||||||
|
|
||||||
if FController.FWDSPReady then
|
if FController.FWDSPReady then
|
||||||
begin
|
begin
|
||||||
FLastSMeter := FController.FDSPEngine.GetSMeterDBm;
|
FController.FLastSMeter := FController.FDSPEngine.GetSMeterDBm;
|
||||||
FController.FDSPEngine.SetSpectrumWidth(FSpectrumWidth);
|
FController.FDSPEngine.SetSpectrumWidth(FSpectrumWidth);
|
||||||
Inc(FAgcLineCounter);
|
Inc(FAgcLineCounter);
|
||||||
if FAgcLineCounter >= 6 then
|
if FAgcLineCounter >= 6 then
|
||||||
@@ -3095,7 +3092,7 @@ begin
|
|||||||
// Обновляем оверлей если видим
|
// Обновляем оверлей если видим
|
||||||
if Assigned(FVfoOverlay) and FVfoOverlay.Visible then
|
if Assigned(FVfoOverlay) and FVfoOverlay.Visible then
|
||||||
begin
|
begin
|
||||||
FVfoOverlay.UpdateSMeter(FLastSMeter);
|
FVfoOverlay.UpdateSMeter(FController.FLastSMeter);
|
||||||
FVfoOverlay.UpdateVfo(FController.FVfoA);
|
FVfoOverlay.UpdateVfo(FController.FVfoA);
|
||||||
PositionVfoOverlay;
|
PositionVfoOverlay;
|
||||||
end;
|
end;
|
||||||
@@ -3187,19 +3184,19 @@ begin
|
|||||||
end
|
end
|
||||||
else
|
else
|
||||||
begin
|
begin
|
||||||
if FLastPLLLock then
|
if FController.FLastPLLLock then
|
||||||
WebPLLText := 'PLL OK'
|
WebPLLText := 'PLL OK'
|
||||||
else
|
else
|
||||||
WebPLLText := 'PLL?';
|
WebPLLText := 'PLL?';
|
||||||
|
|
||||||
if not BoardSupportsSupplyVoltage(FController.FNetwork.Device.BoardType) then
|
if not BoardSupportsSupplyVoltage(FController.FNetwork.Device.BoardType) then
|
||||||
WebSupplyText := 'Supply n/a'
|
WebSupplyText := 'Supply n/a'
|
||||||
else if FLastSupplyV >= 0 then
|
else if FController.FLastSupplyV >= 0 then
|
||||||
begin
|
begin
|
||||||
if FLastSupplyA >= 0 then
|
if FController.FLastSupplyA >= 0 then
|
||||||
WebSupplyText := Format('Supply %.1fV %.1fA', [FLastSupplyV, FLastSupplyA])
|
WebSupplyText := Format('Supply %.1fV %.1fA', [FController.FLastSupplyV, FController.FLastSupplyA])
|
||||||
else
|
else
|
||||||
WebSupplyText := Format('Supply %.1fV', [FLastSupplyV]);
|
WebSupplyText := Format('Supply %.1fV', [FController.FLastSupplyV]);
|
||||||
end
|
end
|
||||||
else
|
else
|
||||||
WebSupplyText := 'Supply --';
|
WebSupplyText := 'Supply --';
|
||||||
@@ -3227,7 +3224,7 @@ begin
|
|||||||
FWebServer.PushSpectrum(
|
FWebServer.PushSpectrum(
|
||||||
FSpectrumBuf, 1024,
|
FSpectrumBuf, 1024,
|
||||||
FWaterfallBuf,
|
FWaterfallBuf,
|
||||||
FLastSMeter,
|
FController.FLastSMeter,
|
||||||
FController.FVfoA, FController.FMode, FController.FFilterBW, FController.FAGCMode, FController.FAGCTop,
|
FController.FVfoA, FController.FMode, FController.FFilterBW, FController.FAGCMode, FController.FAGCTop,
|
||||||
FController.FSpanHz, FController.FVolume,
|
FController.FSpanHz, FController.FVolume,
|
||||||
FController.FWfAGCEnabled, FController.FWfNFEnabled,
|
FController.FWfAGCEnabled, FController.FWfNFEnabled,
|
||||||
@@ -3239,7 +3236,7 @@ begin
|
|||||||
FController.FVfoB, FController.FActiveVfo,
|
FController.FVfoB, FController.FActiveVfo,
|
||||||
FController.FTransmitting, FController.FDrivePercent,
|
FController.FTransmitting, FController.FDrivePercent,
|
||||||
FController.FAtten, FController.FTuning, FController.FDisplayDuplex,
|
FController.FAtten, FController.FTuning, FController.FDisplayDuplex,
|
||||||
FLastFwdW, FLastSWR, FController.FPAMaxPower,
|
FController.FLastFwdW, FController.FLastSWR, FController.FPAMaxPower,
|
||||||
WebStatusText, WebBoardText, WebIPText, WebSupplyText,
|
WebStatusText, WebBoardText, WebIPText, WebSupplyText,
|
||||||
WebPLLText, WebRXText, WebTXText, WebSeqText);
|
WebPLLText, WebRXText, WebTXText, WebSeqText);
|
||||||
end;
|
end;
|
||||||
@@ -3322,7 +3319,7 @@ begin
|
|||||||
(Status.UserADC1Hi shl 8) or Status.UserADC1Lo,
|
(Status.UserADC1Hi shl 8) or Status.UserADC1Lo,
|
||||||
FController.FNetwork.Device.BoardType);
|
FController.FNetwork.Device.BoardType);
|
||||||
end;
|
end;
|
||||||
// FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick —
|
// FController.FLastSMeter обновляется только из WDSP (GetSMeterDBm) в SpectrumTimerTick —
|
||||||
// ExciterPwr это мощность TX, не уровень принятого сигнала.
|
// ExciterPwr это мощность TX, не уровень принятого сигнала.
|
||||||
FwdW := ADCToWatts100(FwdPwr);
|
FwdW := ADCToWatts100(FwdPwr);
|
||||||
// FController.FTransmitting — наш программный флаг (MOX/TUN/HW-PTT через ApplyMOX).
|
// FController.FTransmitting — наш программный флаг (MOX/TUN/HW-PTT через ApplyMOX).
|
||||||
@@ -3377,35 +3374,35 @@ begin
|
|||||||
// FwdW=0 / SWRV=1 — это «не на передаче»: снапим без decay,
|
// FwdW=0 / SWRV=1 — это «не на передаче»: снапим без decay,
|
||||||
// чтобы метры моментально падали при отпускании PTT.
|
// чтобы метры моментально падали при отпускании PTT.
|
||||||
if FwdW <= 0 then
|
if FwdW <= 0 then
|
||||||
FLastFwdW := 0
|
FController.FLastFwdW := 0
|
||||||
else if FwdW > FLastFwdW then
|
else if FwdW > FController.FLastFwdW then
|
||||||
FLastFwdW := FwdW // attack: instant
|
FController.FLastFwdW := FwdW // attack: instant
|
||||||
else
|
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
|
if SWRV <= 1.0 then
|
||||||
FLastSWR := 1.0
|
FController.FLastSWR := 1.0
|
||||||
else if SWRV > FLastSWR then
|
else if SWRV > FController.FLastSWR then
|
||||||
FLastSWR := SWRV // attack: instant
|
FController.FLastSWR := SWRV // attack: instant
|
||||||
else
|
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
|
if SupplyV >= 0 then
|
||||||
begin
|
begin
|
||||||
if FLastSupplyV < 0 then
|
if FController.FLastSupplyV < 0 then
|
||||||
FLastSupplyV := SupplyV // первое значение — без сглаживания
|
FController.FLastSupplyV := SupplyV // первое значение — без сглаживания
|
||||||
else
|
else
|
||||||
FLastSupplyV := ALPHA_SUPPLY * SupplyV + (1.0 - ALPHA_SUPPLY) * FLastSupplyV;
|
FController.FLastSupplyV := ALPHA_SUPPLY * SupplyV + (1.0 - ALPHA_SUPPLY) * FController.FLastSupplyV;
|
||||||
end else
|
end else
|
||||||
FLastSupplyV := -1.0;
|
FController.FLastSupplyV := -1.0;
|
||||||
|
|
||||||
if SupplyA >= 0 then
|
if SupplyA >= 0 then
|
||||||
begin
|
begin
|
||||||
if FLastSupplyA < 0 then
|
if FController.FLastSupplyA < 0 then
|
||||||
FLastSupplyA := SupplyA
|
FController.FLastSupplyA := SupplyA
|
||||||
else
|
else
|
||||||
FLastSupplyA := ALPHA_SUPPLY * SupplyA + (1.0 - ALPHA_SUPPLY) * FLastSupplyA;
|
FController.FLastSupplyA := ALPHA_SUPPLY * SupplyA + (1.0 - ALPHA_SUPPLY) * FController.FLastSupplyA;
|
||||||
end else
|
end else
|
||||||
FLastSupplyA := -1.0;
|
FController.FLastSupplyA := -1.0;
|
||||||
FLastPLLLock := PLLLock;
|
FController.FLastPLLLock := PLLLock;
|
||||||
|
|
||||||
if (FSpecView <> nil) and (FSpecView.ADCOverloadVisible <> (ADCOverload <> 0)) then
|
if (FSpecView <> nil) and (FSpecView.ADCOverloadVisible <> (ADCOverload <> 0)) then
|
||||||
begin
|
begin
|
||||||
@@ -3444,8 +3441,8 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
procedure TMainForm.UpdateTXMeters;
|
procedure TMainForm.UpdateTXMeters;
|
||||||
// Вызывается из MeterTimerTick (10 Гц). Использует FLastFwdW/FLastSWR/
|
// Вызывается из MeterTimerTick (10 Гц). Использует FController.FLastFwdW/FController.FLastSWR/
|
||||||
// FLastSupplyV/FLastSupplyA обновляются на rate HP Status (~150/с)
|
// FController.FLastSupplyV/FController.FLastSupplyA обновляются на rate HP Status (~150/с)
|
||||||
// в DoUpdateStatus.
|
// в DoUpdateStatus.
|
||||||
begin
|
begin
|
||||||
if not FController.FRunning then
|
if not FController.FRunning then
|
||||||
@@ -3455,7 +3452,7 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FLastPLLLock then
|
if FController.FLastPLLLock then
|
||||||
SetStatusText(7, 'PLL OK')
|
SetStatusText(7, 'PLL OK')
|
||||||
else
|
else
|
||||||
SetStatusText(7, 'PLL?');
|
SetStatusText(7, 'PLL?');
|
||||||
@@ -3466,14 +3463,14 @@ begin
|
|||||||
Exit;
|
Exit;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
if FLastSupplyV >= 0 then
|
if FController.FLastSupplyV >= 0 then
|
||||||
begin
|
begin
|
||||||
if FLastSupplyA >= 0 then
|
if FController.FLastSupplyA >= 0 then
|
||||||
SetStatusText(3,
|
SetStatusText(3,
|
||||||
Format('Supply %.1fV %.1fA', [FLastSupplyV, FLastSupplyA]))
|
Format('Supply %.1fV %.1fA', [FController.FLastSupplyV, FController.FLastSupplyA]))
|
||||||
else
|
else
|
||||||
SetStatusText(3,
|
SetStatusText(3,
|
||||||
Format('Supply %.1fV', [FLastSupplyV]));
|
Format('Supply %.1fV', [FController.FLastSupplyV]));
|
||||||
end else
|
end else
|
||||||
SetStatusText(3, 'Supply --');
|
SetStatusText(3, 'Supply --');
|
||||||
end;
|
end;
|
||||||
@@ -4470,9 +4467,7 @@ end;
|
|||||||
// ---------------------------------------------------------------------------
|
// ---------------------------------------------------------------------------
|
||||||
procedure TMainForm.ApplyTUN(Active: Boolean);
|
procedure TMainForm.ApplyTUN(Active: Boolean);
|
||||||
begin
|
begin
|
||||||
// Web-слой пока не владеет своим флагом — зеркалим состояние клиента в
|
// FWebClientActive держит web-слой актуальным (OnClientActiveChanged).
|
||||||
// контроллер перед командой (SetTune зовёт SetMOX, который читает его).
|
|
||||||
FController.FWebClientActive := Assigned(FWebServer) and FWebServer.WebClientActive;
|
|
||||||
FController.SetTune(Active); // ядро TUN (safety/тон/drive/MOX) + рендер через rfTuning
|
FController.SetTune(Active); // ядро TUN (safety/тон/drive/MOX) + рендер через rfTuning
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -5209,9 +5204,8 @@ end;
|
|||||||
|
|
||||||
procedure TMainForm.ApplyMOX(Active: Boolean);
|
procedure TMainForm.ApplyMOX(Active: Boolean);
|
||||||
begin
|
begin
|
||||||
// Web-слой пока не владеет своим флагом — зеркалим текущее состояние клиента
|
// FWebClientActive держит web-слой актуальным (OnClientActiveChanged) —
|
||||||
// в контроллер перед командой (определяет mic-source при TX-on).
|
// определяет mic-source при TX-on.
|
||||||
FController.FWebClientActive := Assigned(FWebServer) and FWebServer.WebClientActive;
|
|
||||||
FController.SetMOX(Active); // ядро TX (safety/PTT/DSP) + рендер через rfTransmitting
|
FController.SetMOX(Active); // ядро TX (safety/PTT/DSP) + рендер через rfTransmitting
|
||||||
end;
|
end;
|
||||||
|
|
||||||
@@ -5350,7 +5344,7 @@ begin
|
|||||||
PanelLeft.Width := 0;
|
PanelLeft.Width := 0;
|
||||||
FVfoOverlay.Width := 260;
|
FVfoOverlay.Width := 260;
|
||||||
FVfoOverlay.Height := 136; // OVL_H_NORM — расширяется сам при открытии AGC-пикера
|
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.SetDSPState(FController.FNRMode, FController.FNBMode, FController.FSNB, FController.FANF, FController.FAGCMode);
|
||||||
FVfoOverlay.Visible := True;
|
FVfoOverlay.Visible := True;
|
||||||
PositionVfoOverlay;
|
PositionVfoOverlay;
|
||||||
@@ -5435,7 +5429,7 @@ begin
|
|||||||
SyncSpecViewFreq;
|
SyncSpecViewFreq;
|
||||||
if Assigned(FVfoOverlay) and FVfoOverlay.Visible then
|
if Assigned(FVfoOverlay) and FVfoOverlay.Visible then
|
||||||
begin
|
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);
|
FVfoOverlay.SetDSPState(FController.FNRMode, FController.FNBMode, FController.FSNB, FController.FANF, FController.FAGCMode);
|
||||||
PositionVfoOverlay; // перепозиционируем при смене LSB↔USB
|
PositionVfoOverlay; // перепозиционируем при смене LSB↔USB
|
||||||
end;
|
end;
|
||||||
@@ -5682,6 +5676,13 @@ begin
|
|||||||
FController.SetMute(FWebSyncBool); // идемпотентно; OnControllerState обновит UI
|
FController.SetMute(FWebSyncBool); // идемпотентно; OnControllerState обновит UI
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TMainForm.WebOnClientActiveChanged(Active: Boolean);
|
||||||
|
// Вызывается из потока web-сервера при connect/disconnect клиента. Зеркалим в
|
||||||
|
// ядро — SetMOX (включая HWPTT-путь в контроллере) выбирает по этому mic-source.
|
||||||
|
begin
|
||||||
|
FController.FWebClientActive := Active;
|
||||||
|
end;
|
||||||
|
|
||||||
// ── CTUN ──────────────────────────────────────────────────────────────────
|
// ── CTUN ──────────────────────────────────────────────────────────────────
|
||||||
|
|
||||||
procedure TMainForm.WebOnCtun(On_: Boolean);
|
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.CATGetANF: Boolean; begin Result := FController.FANF; end;
|
||||||
function TMainForm.CATGetTX: Boolean; begin Result := FController.FTransmitting; end;
|
function TMainForm.CATGetTX: Boolean; begin Result := FController.FTransmitting; end;
|
||||||
function TMainForm.CATGetRunning: Boolean; begin Result := FController.FRunning; 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;
|
function TMainForm.CATGetBand: Integer; begin Result := FController.FCurrentBand; end;
|
||||||
|
|
||||||
// --- Setters ----------------------------------------------------------------
|
// --- Setters ----------------------------------------------------------------
|
||||||
|
|||||||
+23
-5
@@ -151,6 +151,9 @@ type
|
|||||||
// XVTR-band: web клиент кликнул кнопку трансвертера (Idx 0..CFG_XVTR_COUNT-1).
|
// XVTR-band: web клиент кликнул кнопку трансвертера (Idx 0..CFG_XVTR_COUNT-1).
|
||||||
// Idx=-1 — выход в HF.
|
// Idx=-1 — выход в HF.
|
||||||
TWebCmdXvtrBand = procedure(Idx: Integer) of object;
|
TWebCmdXvtrBand = procedure(Idx: Integer) of object;
|
||||||
|
// Активность web-клиента изменилась (подключился/отключился последний клиент).
|
||||||
|
// Хозяин зеркалит это в ядро (FController.FWebClientActive) для выбора mic-source.
|
||||||
|
TWebClientActiveEvent = procedure(Active: Boolean) of object;
|
||||||
// Один XVTR-слот для статуса (для отображения в web-bandSel).
|
// Один XVTR-слот для статуса (для отображения в web-bandSel).
|
||||||
TWebXvtrInfo = record
|
TWebXvtrInfo = record
|
||||||
Idx: Integer;
|
Idx: Integer;
|
||||||
@@ -294,6 +297,11 @@ type
|
|||||||
FSeqText: string;
|
FSeqText: string;
|
||||||
|
|
||||||
FWebClientActive: Boolean;
|
FWebClientActive: Boolean;
|
||||||
|
FOnClientActiveChanged: TWebClientActiveEvent;
|
||||||
|
|
||||||
|
// Обновляет FWebClientActive и при изменении уведомляет хозяина. Вызывать
|
||||||
|
// под уже взятой блокировкой поля (FStateLock/FClientLock) — сам не лочит.
|
||||||
|
procedure SetClientActive(Value: Boolean);
|
||||||
|
|
||||||
// ── Внутренние методы ──
|
// ── Внутренние методы ──
|
||||||
function LoadOpus: Boolean;
|
function LoadOpus: Boolean;
|
||||||
@@ -346,6 +354,8 @@ type
|
|||||||
RXText, TXText, SeqText: string);
|
RXText, TXText, SeqText: string);
|
||||||
|
|
||||||
property WebClientActive: Boolean read FWebClientActive;
|
property WebClientActive: Boolean read FWebClientActive;
|
||||||
|
property OnClientActiveChanged: TWebClientActiveEvent
|
||||||
|
read FOnClientActiveChanged write FOnClientActiveChanged;
|
||||||
property FreqMhzDigits: Integer read FFreqMhzDigits write FFreqMhzDigits;
|
property FreqMhzDigits: Integer read FFreqMhzDigits write FFreqMhzDigits;
|
||||||
property FMStepIdx: Integer read FFMStepIdx write FFMStepIdx;
|
property FMStepIdx: Integer read FFMStepIdx write FFMStepIdx;
|
||||||
|
|
||||||
@@ -980,7 +990,7 @@ begin
|
|||||||
Client.State := wsOpen;
|
Client.State := wsOpen;
|
||||||
|
|
||||||
FStateLock.Enter;
|
FStateLock.Enter;
|
||||||
FWebClientActive := True;
|
SetClientActive(True);
|
||||||
FStateLock.Leave;
|
FStateLock.Leave;
|
||||||
|
|
||||||
Client.SendText(BuildStateJson);
|
Client.SendText(BuildStateJson);
|
||||||
@@ -1114,14 +1124,21 @@ begin
|
|||||||
end;
|
end;
|
||||||
|
|
||||||
FStateLock.Enter;
|
FStateLock.Enter;
|
||||||
FWebClientActive := (FClientCount > 1);
|
SetClientActive(FClientCount > 1);
|
||||||
FStateLock.Leave;
|
FStateLock.Leave;
|
||||||
|
|
||||||
RemoveClient(Client);
|
RemoveClient(Client);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
procedure TWebServer.SetClientActive(Value: Boolean);
|
||||||
|
begin
|
||||||
|
if FWebClientActive = Value then Exit;
|
||||||
|
FWebClientActive := Value;
|
||||||
|
if Assigned(FOnClientActiveChanged) then FOnClientActiveChanged(Value);
|
||||||
|
end;
|
||||||
|
|
||||||
procedure TWebServer.RemoveClient(Client: TWsClient);
|
procedure TWebServer.RemoveClient(Client: TWsClient);
|
||||||
var i, j: Integer;
|
var i, j: Integer; NewActive: Boolean;
|
||||||
begin
|
begin
|
||||||
FClientLock.Enter;
|
FClientLock.Enter;
|
||||||
try
|
try
|
||||||
@@ -1134,10 +1151,11 @@ begin
|
|||||||
Dec(FClientCount);
|
Dec(FClientCount);
|
||||||
Break;
|
Break;
|
||||||
end;
|
end;
|
||||||
FWebClientActive := False;
|
NewActive := False;
|
||||||
for i := 0 to FClientCount - 1 do
|
for i := 0 to FClientCount - 1 do
|
||||||
if (FClients[i] <> nil) and (FClients[i].State = wsOpen) then
|
if (FClients[i] <> nil) and (FClients[i].State = wsOpen) then
|
||||||
begin FWebClientActive := True; Break; end;
|
begin NewActive := True; Break; end;
|
||||||
|
SetClientActive(NewActive);
|
||||||
finally
|
finally
|
||||||
FClientLock.Leave;
|
FClientLock.Leave;
|
||||||
end;
|
end;
|
||||||
|
|||||||
Reference in New Issue
Block a user