mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 18:43:51 +00:00
feat: QO-100 beacon lock in web UI + headless daemon
Mirror the desktop QO-100 beacon lock into the web interface and make it work in the headless daemon. Backend: - WebServer: set_beacon/beacon_seed commands (+OnBeacon/OnBeaconSeed events), beacon state fields, SetBeaconStatus, and beacon_visible/on/ text/ref_hz/track_hz in BuildStateJson. beacon_seed carries 'frac' (0..1 click position); absolute Hz is computed controller-side from live FCenterFreq/FSpanHz (mirrors desktop PixelToFreq). - WebAdapter: OnBeacon->SetBeaconLock, OnBeaconSeed->BeaconSeedAtHz; PushState mirrors compact status (matches MainForm.BeaconStatusText) into the PLL status cell when visible (Pluto + active XVTR). - MainForm/ewsdrd: wire the two callbacks. - ewsdrd: call ServiceBeaconLock in the main loop @~10Hz (FRunning+ FWDSPReady gated). Without this the lock loop never ran headless. Frontend (WebPageHtml): - BCN button (visible only on Pluto+XVTR), highlighted while locked. - Seed-on-mousedown with immediate return (like desktop FormMouseDown): no drag/set_center so the gesture never moves the center / tears IQ. Armed (first click after BCN) or Shift, mirroring desktop arm/Shift. - PLL status cell shows beacon status (field-7 parity with desktop). - Ref (green) + tracked (orange) beacon markers on spectrum/waterfall. Known issue (unresolved): after lock the beacon can slowly drift off and drop to "BCN sync". Suspected residual-sign anti-drift or retune-timing on the web/daemon path; needs on-air diagnostics. See memory project_web_beacon for the investigation state. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
+11
-1
@@ -167,6 +167,7 @@ begin
|
||||
FWeb.OnCtun := @FWebAd.OnCtun; FWeb.OnActiveVfo := @FWebAd.OnActiveVfo;
|
||||
FWeb.OnMOX := @FWebAd.OnMOX; FWeb.OnTun := @FWebAd.OnTun;
|
||||
FWeb.OnFMStep := @FWebAd.OnFMStep; FWeb.OnXvtrBand := @FWebAd.OnXvtrBand;
|
||||
FWeb.OnBeacon := @FWebAd.OnBeacon; FWeb.OnBeaconSeed := @FWebAd.OnBeaconSeed;
|
||||
FWeb.OnWebMic := @FWebAd.OnMic;
|
||||
FWeb.OnClientActiveChanged := @FWebAd.OnClientActiveChanged;
|
||||
// Host-coupled (lifecycle) — на демон-хост (маршалит в главный поток).
|
||||
@@ -409,7 +410,7 @@ var
|
||||
WebCfg: TWebSettings;
|
||||
Dev: THPSDRDevice;
|
||||
AutoDev: TSavedDevice;
|
||||
lastPush, nowMs: QWord;
|
||||
lastPush, lastBeacon, nowMs: QWord;
|
||||
begin
|
||||
FCtrl.FSettings.LoadWebSettings(WebCfg);
|
||||
if not FWeb.Start then
|
||||
@@ -444,10 +445,19 @@ begin
|
||||
Log('No autostart device — waiting for web connect.');
|
||||
|
||||
lastPush := GetTickCount64;
|
||||
lastBeacon := lastPush;
|
||||
while FRunning do
|
||||
begin
|
||||
CheckSynchronize(PUSH_INTERVAL_MS); // исполняет очередь Invoke + ждёт до 50мс
|
||||
nowMs := GetTickCount64;
|
||||
// QO-100 beacon lock — одна итерация контура @~10 Гц (как GUI MeterTimer). No-op
|
||||
// если лок выключен. Без этого лок маяка не работал бы в headless-демоне.
|
||||
if nowMs - lastBeacon >= 100 then
|
||||
begin
|
||||
if FCtrl.FRunning and FCtrl.FWDSPReady then
|
||||
FCtrl.ServiceBeaconLock;
|
||||
lastBeacon := nowMs;
|
||||
end;
|
||||
if nowMs - lastPush >= PUSH_INTERVAL_MS then
|
||||
begin
|
||||
// S-метр приходит из WDSP (не из сетевого HP-статуса), поэтому его никто
|
||||
|
||||
Reference in New Issue
Block a user