mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
Phase 3 (batch 33+34): web device discovery/connect parity
Move discovery into the controller and add a full web device overlay (discovery + connect + saved-device CRUD), reaching parity with the desktop device dialog. - RadioController: OnDeviceFound/Discover/DiscoverFinishedNone + rfDeviceList; TDiscoverThread moved in from MainForm. - WebServer: device protocol (discover/connect/disconnect/dev_add/ dev_remove/dev_autostart) + "devices" in BuildStateJson. - MainForm: web handlers (marshalled), PushDeviceListToWeb, extracted DoStopAndDisconnect, detached WebOnRun from BtnStartStopClick; web connect resolves board type from discovered then saved by IP. - DeviceForm: RefreshFound renders the found list from the store. - WebPageHtml: DEV overlay; START opens it, STOP disconnects. Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 4.8
parent
9dec47a6ca
commit
c4981fcb19
+79
-2
@@ -70,7 +70,8 @@ type
|
||||
rfChannel,
|
||||
rfSMeter, rfPower, rfSWR, rfSupply, rfPLL, // телеметрия
|
||||
rfADCOverload, // ADC overload (рендер индикатора)
|
||||
rfDevice // подключённое устройство сменилось
|
||||
rfDevice, // подключённое устройство сменилось
|
||||
rfDeviceList // список discovered устройств обновился
|
||||
);
|
||||
|
||||
TRadioStateEvent = procedure(Sender: TObject; Field: TRadioField) of object;
|
||||
@@ -167,6 +168,7 @@ type
|
||||
FAudioOutDevName: string;
|
||||
FAudioInDevName: string;
|
||||
FDevConnected: Boolean;
|
||||
FDiscoverNoneFound: Boolean; // discovery завершился без устройств (для рендера)
|
||||
|
||||
// ---- DSP-фильтры шума / водопад ----
|
||||
FNRMode, FNBMode: Integer; // источник истины (раньше Btn*.Tag)
|
||||
@@ -244,6 +246,10 @@ type
|
||||
FHPpFwdW, FHPpSWR, FHPpSupplyV, FHPpSupplyA: Double;
|
||||
FHPpPLL, FHPpHWPTT: Boolean;
|
||||
FHPpOverload: Byte;
|
||||
// Pending discovered-устройство (сетевой поток discovery → ApplyDeviceFound
|
||||
// через Invoke; Synchronize блокирующий — устройства приходят по одному).
|
||||
FPendingFoundDev: THPSDRDevice;
|
||||
FPendingFoundEntry: string;
|
||||
|
||||
constructor Create;
|
||||
destructor Destroy; override;
|
||||
@@ -264,6 +270,9 @@ type
|
||||
procedure OnHPStatus(const Status: THighPriorityStatus);
|
||||
procedure ApplyHPStatus; // маршалится из OnHPStatus (сглаживание/overload/HWPTT)
|
||||
procedure OnTXIQ(const Buf: array of Double; Count: Integer);
|
||||
procedure OnDeviceFound(const Dev: THPSDRDevice); // сетевой поток discovery
|
||||
procedure ApplyDeviceFound; // маршалится из OnDeviceFound (store + rfDeviceList)
|
||||
procedure DiscoverFinishedNone; // маршалится из discover-потока: устройств нет
|
||||
|
||||
// Маршалинг команды в поток контроллера (GUI: TThread.Synchronize).
|
||||
procedure Invoke(M: TThreadMethod);
|
||||
@@ -2162,7 +2171,75 @@ begin
|
||||
Changed(rfDevice); // UI: полная синхронизация device-виджетов из состояния
|
||||
end;
|
||||
|
||||
// ---------------------------------------------------------------------------
|
||||
// Discovery — поиск устройств в фоновом потоке. Найденные приходят через
|
||||
// FNetwork.OnDeviceFound (=OnDeviceFound) и копятся в FDeviceStore.Discovered;
|
||||
// по завершении без устройств — DiscoverFinishedNone. UI слушает rfDeviceList.
|
||||
// ---------------------------------------------------------------------------
|
||||
type
|
||||
TDiscoverThread = class(TThread)
|
||||
private
|
||||
FCtrl: TRadioController;
|
||||
protected
|
||||
procedure Execute; override;
|
||||
public
|
||||
constructor Create(ACtrl: TRadioController);
|
||||
end;
|
||||
|
||||
constructor TDiscoverThread.Create(ACtrl: TRadioController);
|
||||
begin
|
||||
FCtrl := ACtrl;
|
||||
FreeOnTerminate := True;
|
||||
inherited Create(False);
|
||||
end;
|
||||
|
||||
procedure TDiscoverThread.Execute;
|
||||
var
|
||||
Devs: THPSDRDeviceArray;
|
||||
begin
|
||||
Devs := FCtrl.FNetwork.Discover(2000);
|
||||
// Найденные устройства сигналятся колбэком OnDeviceFound во время Discover().
|
||||
if Length(Devs) = 0 then
|
||||
FCtrl.Invoke(FCtrl.DiscoverFinishedNone);
|
||||
end;
|
||||
|
||||
procedure TRadioController.OnDeviceFound(const Dev: THPSDRDevice);
|
||||
// Сетевой поток: строим строку для списка → pending → маршалинг в ApplyDeviceFound.
|
||||
var
|
||||
BoardName: string;
|
||||
begin
|
||||
BoardName := BoardTypeName(Dev.BoardType);
|
||||
FPendingFoundDev := Dev;
|
||||
FPendingFoundEntry := Format('%s %s FW:%d DDC:%d',
|
||||
[Dev.IPAddress, BoardName,
|
||||
Dev.FirmwareVersion, Dev.NumDDCs]);
|
||||
Invoke(ApplyDeviceFound);
|
||||
end;
|
||||
|
||||
procedure TRadioController.ApplyDeviceFound;
|
||||
// Маршалится из OnDeviceFound (Synchronize). Дописываем в store и уведомляем UI.
|
||||
begin
|
||||
FDiscoverNoneFound := False;
|
||||
FDeviceStore.AddDiscovered(FPendingFoundDev.IPAddress, FPendingFoundEntry,
|
||||
FPendingFoundDev.BoardType, FPendingFoundDev.MAC);
|
||||
Changed(rfDeviceList);
|
||||
end;
|
||||
|
||||
procedure TRadioController.DiscoverFinishedNone;
|
||||
// Маршалится из discover-потока, когда устройств не найдено.
|
||||
begin
|
||||
FDiscoverNoneFound := True;
|
||||
Changed(rfDeviceList);
|
||||
end;
|
||||
|
||||
procedure TRadioController.Discover;
|
||||
begin { TODO wiring: FNetwork.Discover } end;
|
||||
// Старт поиска: чистим прошлый список, сбрасываем direct-IP, запускаем поток.
|
||||
begin
|
||||
FDeviceStore.ClearDiscovered;
|
||||
FDiscoverNoneFound := False;
|
||||
FNetwork.DirectIP := '';
|
||||
Changed(rfDeviceList);
|
||||
TDiscoverThread.Create(Self);
|
||||
end;
|
||||
|
||||
end.
|
||||
|
||||
Reference in New Issue
Block a user