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:
Uladzimir Karpenka
2026-06-08 15:30:03 +03:00
co-authored by Claude Opus 4.8
parent 9dec47a6ca
commit c4981fcb19
5 changed files with 488 additions and 135 deletions
+20 -14
View File
@@ -76,9 +76,8 @@ type
procedure SetTheme(const T: TAppTheme);
// Добавить найденное устройство (вызывается из MainForm при discovery)
procedure AddDiscovered(const IP, DisplayName: string; BoardType: Integer;
const MAC: array of Byte);
// Перерисовать список найденных из store (вызывается по rfDeviceList)
procedure RefreshFound;
procedure ClearDiscovered;
procedure NoDevicesFound; // UI-сообщение «нет устройств» в список найденных
@@ -383,21 +382,28 @@ begin
LstFound.Items.Clear;
end;
procedure TDeviceDialog.AddDiscovered(const IP, DisplayName: string; BoardType: Integer;
const MAC: array of Byte);
procedure TDeviceDialog.RefreshFound;
// Рендер списка найденных из store. Пустой store во время поиска → 'Searching...'.
var
I: Integer;
S: string;
D: TDiscoveredDevice;
begin
if FStore = nil then Exit;
if (LstFound.Items.Count = 1) and (LstFound.Items[0] = 'Searching...') then
LstFound.Items.Clear;
FStore.AddDiscovered(IP, DisplayName, BoardType, MAC);
S := DisplayName;
if BoardType > 0 then
S := S + ' ' + BoardTypeName(BoardType);
LstFound.Items.Add(S);
LstFound.Items.Clear;
if FStore.DiscoveredCount = 0 then
begin
LstFound.Items.Add('Searching...');
Exit;
end;
for I := 0 to FStore.DiscoveredCount - 1 do
begin
D := FStore.Discovered(I);
S := D.DisplayName;
if D.BoardType > 0 then
S := S + ' ' + BoardTypeName(D.BoardType);
LstFound.Items.Add(S);
end;
end;
procedure TDeviceDialog.NoDevicesFound;