drone status menue: fixed empty display bug without active telemetry stream
This commit is contained in:
@@ -43,6 +43,15 @@ SignalLevel _levelLowerIsBetter(double value, double greenMax, double redMax) {
|
||||
/// Reine Ableitung aus normalisierten Telemetriewerten + den
|
||||
/// Ampel-Schwellwerten des aktiven Drohnenprofils - kein MSP-/
|
||||
/// Protokollwissen, siehe computeDroneStatus-Doku.
|
||||
///
|
||||
/// [hasData] ist false, solange noch gar kein Telemetrie-Frame vorliegt
|
||||
/// (Doku: "Felder auch anzeigen koennen, bevor Daten empfangen wurden") -
|
||||
/// erzwingt dann fuer ALLE Felder rot, unabhaengig von den uebergebenen
|
||||
/// Platzhalterwerten. Ohne das wuerde z.B. "Current draw" (ein Feld, bei dem
|
||||
/// ein NIEDRIGER Wert gut ist) mit dem neutralen Platzhalter 0 faelschlich
|
||||
/// gruen erscheinen ("sehr niedriger Verbrauch" statt "keine Daten") - anders
|
||||
/// als bei den "hoeher ist besser"-Feldern, wo ein 0/negativer Platzhalter
|
||||
/// zufaellig schon unter der Rot-Schwelle liegt.
|
||||
TelemetryFieldStatus computeTelemetryFieldStatus({
|
||||
required int numSat,
|
||||
required bool hasFix,
|
||||
@@ -52,7 +61,18 @@ TelemetryFieldStatus computeTelemetryFieldStatus({
|
||||
required int linkQuality,
|
||||
required int snrDb,
|
||||
required DroneProfile profile,
|
||||
bool hasData = true,
|
||||
}) {
|
||||
if (!hasData) {
|
||||
return const TelemetryFieldStatus(
|
||||
numSat: SignalLevel.red,
|
||||
hdop: SignalLevel.red,
|
||||
currentA: SignalLevel.red,
|
||||
batteryVoltage: SignalLevel.red,
|
||||
rxQuality: SignalLevel.red,
|
||||
rxSnr: SignalLevel.red,
|
||||
);
|
||||
}
|
||||
return TelemetryFieldStatus(
|
||||
numSat: _levelHigherIsBetter(
|
||||
numSat.toDouble(),
|
||||
|
||||
@@ -110,66 +110,67 @@ 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,
|
||||
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.numSat}', level: fieldStatus.numSat),
|
||||
// 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.hasFix ? frame.hdop.toStringAsFixed(2) : '—',
|
||||
frame != null && frame.hasFix ? frame.hdop.toStringAsFixed(2) : '—',
|
||||
level: fieldStatus.hdop,
|
||||
),
|
||||
_statusRow(
|
||||
'Current draw',
|
||||
'${frame.currentA.toStringAsFixed(1)} A',
|
||||
frame != null ? '${frame.currentA.toStringAsFixed(1)} A' : '—',
|
||||
level: fieldStatus.currentA,
|
||||
),
|
||||
_statusRow(
|
||||
'Battery voltage',
|
||||
'${frame.batteryVoltage.toStringAsFixed(2)} V',
|
||||
frame != null ? '${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('RX quality', frame != null ? '${frame.linkQuality}%' : '—', level: fieldStatus.rxQuality),
|
||||
_statusRow('RX SNR', frame != null ? '${frame.snrDb} dB' : '—', level: fieldStatus.rxSnr),
|
||||
_statusRow(
|
||||
'GPS coordinates',
|
||||
frame.hasFix
|
||||
frame != null && 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'),
|
||||
_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' : '—'),
|
||||
]),
|
||||
);
|
||||
},
|
||||
loading: () => const Center(
|
||||
child: CircularProgressIndicator(color: Color(0xFF4D9DFF)),
|
||||
),
|
||||
error: (err, st) => const Center(
|
||||
child: Text('No telemetry', style: TextStyle(color: Colors.white60, fontSize: 15)),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
||||
/// Ordnet die Statuszeilen zu je 2 pro Zeile an (Doku: "2 felder pro zeile
|
||||
|
||||
Reference in New Issue
Block a user