Files
dmc/app/lib/domain/telemetry/telemetry_field_status.dart
T
Constantin LeueandClaude Sonnet 5 b09d00ab9f Rename the Fly-mode Warnings tab to System Messages, log connection/upload events
Renames DroneEvent/DroneEventSeverity/droneEventLogProvider/
DroneStatusWarningsPanel to SystemMessage/SystemMessageSeverity/
systemMessageLogProvider/DroneStatusMessagesPanel throughout, matching
what the tab now actually shows - general system messages, not just
drone-health warnings.

Adds a new SystemMessageSeverity.info level (blue) for messages that
aren't a warning/error, and three new message sources on top of the
existing battery/failsafe detection:
- "Connected", logged the first time telemetryProvider produces a frame
  after having none - the mirror image of the existing "Connection lost"
  detection (which already fires on the first stream error after having
  had data), so no new transport-specific dependency was needed.
- "Connection type changed to X", from watching connectionSettingsProvider
  (skips the initial load so it doesn't fire on every app start).
- "Mission sent (N waypoints)" / "Mission upload failed: ...", logged
  from FlyScreen's send handler via a new public log() method on the
  notifier, alongside the existing snackbar.

Verified on the Pixel_10a emulator: entering Fly mode logs "Connected"
once the mock telemetry starts, and tapping the send button logs
"Mission sent (3 waypoints)" right after the snackbar.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
2026-08-06 10:47:38 +02:00

110 lines
3.8 KiB
Dart

import '../mission/drone_profile.dart';
import 'drone_status.dart';
/// Ampel-Farbcodierung je einzelnem Telemetriefeld im Drohnen-Status-Menue
/// (Doku: "drone status felder im menue auch farblich kodieren") - anders
/// als [computeDroneStatus] (das Verbindungs-/Positionsqualitaet je zu einem
/// kombinierten Signal fuer die Fusszeilen-Pille zusammenfasst) bewertet
/// dies jedes Feld einzeln anhand der Schwellwerte im aktiven [DroneProfile].
class TelemetryFieldStatus {
const TelemetryFieldStatus({
required this.numSat,
required this.hdop,
required this.currentA,
required this.batteryVoltage,
required this.rxQuality,
required this.rxSnr,
});
final SignalLevel numSat;
final SignalLevel hdop;
final SignalLevel currentA;
final SignalLevel batteryVoltage;
final SignalLevel rxQuality;
final SignalLevel rxSnr;
}
/// Fuer Felder, bei denen ein HOHER Wert gut ist (Satelliten, RX-Qualitaet/
/// -SNR): rot unterhalb [redMin], gruen ab [greenMin], dazwischen gelb.
SignalLevel _levelHigherIsBetter(double value, double greenMin, double redMin) {
if (value < redMin) return SignalLevel.red;
if (value < greenMin) return SignalLevel.yellow;
return SignalLevel.green;
}
/// Fuer Felder, bei denen ein NIEDRIGER Wert gut ist (HDOP): rot oberhalb
/// [redMax], gruen bis [greenMax], dazwischen gelb.
SignalLevel _levelLowerIsBetter(double value, double greenMax, double redMax) {
if (value > redMax) return SignalLevel.red;
if (value > greenMax) return SignalLevel.yellow;
return SignalLevel.green;
}
/// 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,
required double hdop,
required double currentA,
required double batteryVoltage,
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(),
profile.gpsSatGreenMin,
profile.gpsSatRedMin,
),
// Ohne Fix ist der HDOP-Wert bedeutungslos/veraltet (siehe Anzeige in
// drone_status_messages_panel.dart, die dafuer bereits '—' zeigt) - dann
// unabhaengig vom Zahlenwert rot statt eines irrefuehrend guten Signals.
hdop: hasFix
? _levelLowerIsBetter(hdop, profile.hdopGreenMax, profile.hdopRedMax)
: SignalLevel.red,
currentA: _levelLowerIsBetter(
currentA,
profile.currentGreenMaxA,
profile.currentRedMaxA,
),
batteryVoltage: _levelHigherIsBetter(
batteryVoltage,
profile.batteryVoltageGreenMinV,
profile.batteryVoltageRedMinV,
),
rxQuality: _levelHigherIsBetter(
linkQuality.toDouble(),
profile.rxQualityGreenMin,
profile.rxQualityRedMin,
),
rxSnr: _levelHigherIsBetter(
snrDb.toDouble(),
profile.rxSnrGreenMinDb,
profile.rxSnrRedMinDb,
),
);
}