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>
110 lines
3.8 KiB
Dart
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,
|
|
),
|
|
);
|
|
}
|