mirror of
https://git.vladimir.cc/vladimir/ewsdr.git
synced 2026-08-25 20:37:33 +00:00
feat: Pluto board name + hardware telemetry in status bar
- Status bar / web now show Pluto/LibreSDR model + serial instead of "Unknown Board" (BoardDisplayName in controller; UI just renders it). - Field 3 shows AD936x chip temperature + RX RSSI for Pluto (no PA → Supply only for openHPSDR). Polled via backend.ReadTelemetry (~2 Hz), filtered for sensor glitches (plausibility window + slew-limit, with anti-stick) — fixes rare bogus -15°C readings. - Add libiio binding iio_channel_attr_read_double. - Remove stale root pluto_integration.MD (superseded by doc/PLUTO_INTEGRATION_PLAN.md). Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
@@ -272,6 +272,11 @@ type
|
||||
// ---- Телеметрия (наполняется в Фазе 3/4 вместе с сетевыми колбэками) ----
|
||||
FLastSMeter, FLastFwdW, FLastSWR, FLastSupplyV, FLastSupplyA: Double;
|
||||
FLastPLLLock: Boolean;
|
||||
// Pluto-телеметрия (нет HP-status): температура чипа °C / RSSI приёмника дБ.
|
||||
// Опрашиваются ServicePlutoTelemetry с UI-таймера; TELEMETRY_NONE = нет данных.
|
||||
FLastPlutoTempC, FLastPlutoRSSIdB: Double;
|
||||
FPlutoTeleTick: QWord; // GetTickCount64 последнего опроса (троттлинг)
|
||||
FPlutoTempBad: Integer; // подряд отброшенных выбросов температуры (анти-залипание)
|
||||
|
||||
// ---- RX/seq телеметрия data-path (пишется из сетевого колбэка OnDDCIQ) ----
|
||||
FRXPacketCount: LongWord; // счётчик принятых IQ пакетов
|
||||
@@ -515,6 +520,13 @@ type
|
||||
function BackendCaps: TBackendCaps;
|
||||
// True если активный бэкенд — Pluto (VHF/UHF band-план вместо HF).
|
||||
function IsPluto: Boolean;
|
||||
// Человекочитаемое имя подключённой платы для статус-строки (UI/Web).
|
||||
// HPSDR → тип платы; Pluto/LibreSDR → hw_model + серийник (если есть).
|
||||
function BoardDisplayName: string;
|
||||
// Опрос аппаратной телеметрии Pluto (температура/RSSI) с троттлингом — зовётся
|
||||
// с UI-таймера (MeterTimer @10 Гц), как ServiceBeaconLock. No-op для HPSDR.
|
||||
// Результат — в FLastPlutoTempC/FLastPlutoRSSIdB (UI читает и форматирует).
|
||||
procedure ServicePlutoTelemetry;
|
||||
// Список URI для probe сетевых Pluto (mDNS недоступен) — задаёт фронтенд
|
||||
// перед Discover (сохранённые Pluto + ручной ввод IP).
|
||||
procedure SetPlutoProbeURIs(const URIs: array of string);
|
||||
@@ -551,6 +563,8 @@ begin
|
||||
FWfAGCEnabled := True; FDitherEnabled := True; FRandomEnabled := True;
|
||||
FFMStepOn := True;
|
||||
FLastSMeter := -130; FLastSWR := 1; FLastSupplyV := -1; FLastSupplyA := -1;
|
||||
FLastPlutoTempC := TELEMETRY_NONE; FLastPlutoRSSIdB := TELEMETRY_NONE;
|
||||
FPlutoTeleTick := 0; FPlutoTempBad := 0;
|
||||
FillChar(FDevMAC, SizeOf(FDevMAC), 0);
|
||||
end;
|
||||
|
||||
@@ -2727,6 +2741,8 @@ begin
|
||||
end;
|
||||
FRXPacketCount := 0;
|
||||
FActiveDDC := 0;
|
||||
FLastPlutoTempC := TELEMETRY_NONE; FLastPlutoRSSIdB := TELEMETRY_NONE;
|
||||
FPlutoTeleTick := 0; FPlutoTempBad := 0;
|
||||
Changed(rfRunning); // безусловный сброс run-кнопки/MOX.Enabled/sleep (как старый хвост STOP)
|
||||
end;
|
||||
|
||||
@@ -3021,6 +3037,70 @@ begin
|
||||
Result := (FNetwork <> nil) and (FNetwork.Caps.Kind = bkPluto);
|
||||
end;
|
||||
|
||||
function TRadioController.BoardDisplayName: string;
|
||||
var
|
||||
Dev: THPSDRDevice;
|
||||
begin
|
||||
if FNetwork = nil then Exit('');
|
||||
Dev := FNetwork.Device;
|
||||
if Dev.Kind = bkPluto then
|
||||
begin
|
||||
Result := PlutoModelName(Dev.Model);
|
||||
// Серийник дописываем, только если это реальный hw_serial, а не URI-fallback
|
||||
// ('usb:1.5.5' / 'ip:…'), который PlutoBackend кладёт при отсутствии серийника.
|
||||
if (Dev.Serial <> '') and (Pos('usb:', Dev.Serial) = 0)
|
||||
and (Pos('ip:', Dev.Serial) = 0) then
|
||||
Result := Result + ' SN:' + Dev.Serial;
|
||||
end
|
||||
else
|
||||
Result := BoardTypeName(Dev.BoardType);
|
||||
end;
|
||||
|
||||
procedure TRadioController.ServicePlutoTelemetry;
|
||||
const
|
||||
POLL_MS = 500; // опрос ~2 Гц: чтение attr — USB round-trip, чаще ни к чему
|
||||
TEMP_MIN_C = 0.0; // работающий AD936x всегда теплее окружающей (само-нагрев)
|
||||
TEMP_MAX_C = 120.0; // абсолютный потолок (датчик исправен)
|
||||
TEMP_STEP_C = 12.0; // макс. физичный шаг между опросами (тепловая инерция чипа)
|
||||
TEMP_FORCE = 3; // принять «выброс», если держится N раз подряд (не залипаем)
|
||||
var
|
||||
t, r: Double;
|
||||
now_: QWord;
|
||||
begin
|
||||
if (FNetwork = nil) or (not FRunning) or (FNetwork.Caps.Kind <> bkPluto) then Exit;
|
||||
now_ := GetTickCount64;
|
||||
if (FPlutoTeleTick <> 0) and (now_ - FPlutoTeleTick < POLL_MS) then Exit;
|
||||
FPlutoTeleTick := now_;
|
||||
if not FNetwork.ReadTelemetry(t, r) then Exit;
|
||||
|
||||
// Температура: датчик AD9361 иногда отдаёт мусор (мид-конверсия / контеншн на
|
||||
// USB-контексте с RX-потоком) — наблюдалось редкое -15 °C. Фильтруем: жёсткое
|
||||
// окно правдоподобия + slew-limit по тепловой инерции; устойчивый «выброс»
|
||||
// (реальный скачок) всё же принимаем через TEMP_FORCE опросов, чтобы не залипнуть.
|
||||
if t > TELEMETRY_NONE then
|
||||
begin
|
||||
if (t >= TEMP_MIN_C) and (t <= TEMP_MAX_C) then
|
||||
begin
|
||||
if (FLastPlutoTempC <= TELEMETRY_NONE) or (Abs(t - FLastPlutoTempC) <= TEMP_STEP_C) then
|
||||
begin
|
||||
FLastPlutoTempC := t; FPlutoTempBad := 0;
|
||||
end
|
||||
else
|
||||
begin
|
||||
Inc(FPlutoTempBad);
|
||||
if FPlutoTempBad >= TEMP_FORCE then
|
||||
begin FLastPlutoTempC := t; FPlutoTempBad := 0; end;
|
||||
end;
|
||||
end;
|
||||
// вне окна правдоподобия — молча отбрасываем, держим прошлое валидное значение
|
||||
end;
|
||||
|
||||
// RSSI быстро меняется с сигналом — без сглаживания; обновляем, только если валиден.
|
||||
if r > TELEMETRY_NONE then FLastPlutoRSSIdB := r;
|
||||
|
||||
Changed(rfSupply); // поле телеметрии статус-бара (поле 3); web-адаптер тоже
|
||||
end;
|
||||
|
||||
procedure TRadioController.SetPlutoProbeURIs(const URIs: array of string);
|
||||
var i: Integer;
|
||||
begin
|
||||
|
||||
Reference in New Issue
Block a user