drone status menue: fixed empty display bug without active telemetry stream

This commit is contained in:
Constantin Leue
2026-08-05 21:23:43 +02:00
parent c7e4e5bf63
commit 5fa55ac67d
2 changed files with 78 additions and 57 deletions
@@ -110,65 +110,66 @@ class _DroneStatusWarningsPanelState extends ConsumerState<DroneStatusWarningsPa
// --- Status ---
// Zeigt die Statuszeilen unabhaengig davon, ob bereits ein Telemetrie-Frame
// vorliegt (Doku: "endloser Lade-Screen ohne die Datenfelder anzuzeigen" -
// z.B. WLAN gewaehlt, aber noch nicht verbunden) - `telemetry` bleibt dann
// dauerhaft AsyncLoading, .value ist einfach null. Analog zu FlyScreen.
// droneStatus (siehe dortige Doku) werden Platzhalterwerte verwendet, damit
// computeTelemetryFieldStatus trotzdem eine (dann durchgehend rote) Ampel
// liefert, statt hier zusaetzlich zwischen "noch nie verbunden" und
// "Verbindung verloren" zu unterscheiden. Einzelne Werte zeigen dennoch
// '—' statt eines erfundenen Messwerts (0 A/0 V saehe sonst wie ein echter,
// kritischer Messwert statt wie "keine Daten" aus).
Widget _statusTab() {
final telemetry = ref.watch(telemetryProvider);
final frame = ref.watch(telemetryProvider).value;
final droneProfile = ref.watch(activeDroneProfileProvider);
return telemetry.when(
data: (frame) {
final fieldStatus = computeTelemetryFieldStatus(
numSat: frame.numSat,
hasFix: frame.hasFix,
hdop: frame.hdop,
currentA: frame.currentA,
batteryVoltage: frame.batteryVoltage,
linkQuality: frame.linkQuality,
snrDb: frame.snrDb,
profile: droneProfile,
);
return ListView(
padding: const EdgeInsets.all(16),
children: _statusGrid([
// Farbcodierte Felder zuerst (Doku: "drone status felder im
// menue auch farblich kodieren", Schwellwerte je Drohnenprofil -
// siehe computeTelemetryFieldStatus), informelle Felder ohne
// Ampel-Bewertung (Koordinaten/Heading/Alt/Speed) danach. Je 2
// Felder pro Zeile (Doku: "platz effizienter nutzen").
_statusRow('GPS satellites', '${frame.numSat}', level: fieldStatus.numSat),
_statusRow(
'GPS precision (HDOP)',
frame.hasFix ? frame.hdop.toStringAsFixed(2) : '—',
level: fieldStatus.hdop,
),
_statusRow(
'Current draw',
'${frame.currentA.toStringAsFixed(1)} A',
level: fieldStatus.currentA,
),
_statusRow(
'Battery voltage',
'${frame.batteryVoltage.toStringAsFixed(2)} V',
level: fieldStatus.batteryVoltage,
),
_statusRow('RX quality', '${frame.linkQuality}%', level: fieldStatus.rxQuality),
_statusRow('RX SNR', '${frame.snrDb} dB', level: fieldStatus.rxSnr),
_statusRow(
'GPS coordinates',
frame.hasFix
? '${frame.lat.toStringAsFixed(6)}, ${frame.lon.toStringAsFixed(6)}'
: '—',
),
_statusRow('Heading', '${frame.headingDeg.round()}°'),
_statusRow('Altitude', '${frame.altitudeM.toStringAsFixed(0)} m'),
_statusRow('Speed', '${frame.speedMs.toStringAsFixed(1)} m/s'),
]),
);
},
loading: () => const Center(
child: CircularProgressIndicator(color: Color(0xFF4D9DFF)),
),
error: (err, st) => const Center(
child: Text('No telemetry', style: TextStyle(color: Colors.white60, fontSize: 15)),
),
final fieldStatus = computeTelemetryFieldStatus(
numSat: frame?.numSat ?? 0,
hasFix: frame?.hasFix ?? false,
hdop: frame?.hdop ?? 99.0,
currentA: frame?.currentA ?? 0,
batteryVoltage: frame?.batteryVoltage ?? 0,
linkQuality: frame?.linkQuality ?? 0,
snrDb: frame?.snrDb ?? -99,
profile: droneProfile,
hasData: frame != null,
);
return ListView(
padding: const EdgeInsets.all(16),
children: _statusGrid([
// Farbcodierte Felder zuerst (Doku: "drone status felder im menue
// auch farblich kodieren", Schwellwerte je Drohnenprofil - siehe
// computeTelemetryFieldStatus), informelle Felder ohne Ampel-
// Bewertung (Koordinaten/Heading/Alt/Speed) danach. Je 2 Felder pro
// Zeile (Doku: "platz effizienter nutzen").
_statusRow('GPS satellites', frame != null ? '${frame.numSat}' : '—', level: fieldStatus.numSat),
_statusRow(
'GPS precision (HDOP)',
frame != null && frame.hasFix ? frame.hdop.toStringAsFixed(2) : '—',
level: fieldStatus.hdop,
),
_statusRow(
'Current draw',
frame != null ? '${frame.currentA.toStringAsFixed(1)} A' : '—',
level: fieldStatus.currentA,
),
_statusRow(
'Battery voltage',
frame != null ? '${frame.batteryVoltage.toStringAsFixed(2)} V' : '—',
level: fieldStatus.batteryVoltage,
),
_statusRow('RX quality', frame != null ? '${frame.linkQuality}%' : '—', level: fieldStatus.rxQuality),
_statusRow('RX SNR', frame != null ? '${frame.snrDb} dB' : '—', level: fieldStatus.rxSnr),
_statusRow(
'GPS coordinates',
frame != null && frame.hasFix
? '${frame.lat.toStringAsFixed(6)}, ${frame.lon.toStringAsFixed(6)}'
: '—',
),
_statusRow('Heading', frame != null ? '${frame.headingDeg.round()}°' : '—'),
_statusRow('Altitude', frame != null ? '${frame.altitudeM.toStringAsFixed(0)} m' : '—'),
_statusRow('Speed', frame != null ? '${frame.speedMs.toStringAsFixed(1)} m/s' : '—'),
]),
);
}