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:
2026-06-23 16:53:02 +03:00
co-authored by Claude Opus 4.8
parent 8472c8e7b8
commit 0fbe5d5edd
5 changed files with 144 additions and 7 deletions
+2
View File
@@ -872,6 +872,8 @@ begin
FWebServer.OnFreqA := FWebAdapter.OnFreqA;
FWebServer.OnWebMic := FWebAdapter.OnMic;
FWebServer.OnXvtrBand := FWebAdapter.OnXvtrBand;
FWebServer.OnBeacon := FWebAdapter.OnBeacon;
FWebServer.OnBeaconSeed := FWebAdapter.OnBeaconSeed;
FWebServer.OnConnect := WebOnConnect;
FWebServer.OnDiscoverDev := WebOnDiscover;
FWebServer.OnDisconnectDev := WebOnDisconnect;