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>
This commit is contained in:
co-authored by
Claude Sonnet 5
parent
13475cc4f3
commit
b09d00ab9f
@@ -1,64 +0,0 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../domain/telemetry/drone_event.dart';
|
||||
import '../../transport/flight_controller_link.dart';
|
||||
import 'telemetry_provider.dart';
|
||||
|
||||
/// Fuehrt das Ereignis-Log fuer den neuen Warnings-Tab (Doku:
|
||||
/// "log von kritischen ereignissen mit time stamp") - beobachtet
|
||||
/// [telemetryProvider] dauerhaft (bewusst KEIN autoDispose, siehe
|
||||
/// telemetry_provider.dart-Doku zur analogen Begruendung bei
|
||||
/// flightControllerLinkProvider), damit ein Ereignis auch dann protokolliert
|
||||
/// wird, wenn die Warnings-Ansicht selbst gerade nicht geoeffnet ist.
|
||||
/// Beginnt zu beobachten, sobald irgendein Widget diesen Provider erstmals
|
||||
/// liest (siehe FlyScreen) - vor diesem Zeitpunkt liegende Ereignisse
|
||||
/// erscheinen nicht im Log, das ist fuer ein Live-Log erwartbar.
|
||||
class DroneEventLogNotifier extends Notifier<List<DroneEvent>> {
|
||||
TelemetryFrame? _previousFrame;
|
||||
bool _hadData = false;
|
||||
|
||||
@override
|
||||
List<DroneEvent> build() {
|
||||
ref.listen<AsyncValue<TelemetryFrame>>(telemetryProvider, (previous, next) {
|
||||
next.when(
|
||||
data: (frame) {
|
||||
final events = detectDroneEvents(
|
||||
previous: _previousFrame,
|
||||
current: frame,
|
||||
now: DateTime.now(),
|
||||
);
|
||||
_previousFrame = frame;
|
||||
_hadData = true;
|
||||
if (events.isNotEmpty) {
|
||||
state = [...events.reversed, ...state];
|
||||
}
|
||||
},
|
||||
error: (error, stackTrace) {
|
||||
// Nur melden, wenn zuvor bereits Frames flossen - sonst wuerde
|
||||
// schon das (normale) Ausbleiben der allerersten Verbindung als
|
||||
// "Connection lost" auftauchen.
|
||||
if (_hadData) {
|
||||
state = [
|
||||
DroneEvent(
|
||||
timestamp: DateTime.now(),
|
||||
message: 'Connection lost',
|
||||
severity: DroneEventSeverity.critical,
|
||||
),
|
||||
...state,
|
||||
];
|
||||
}
|
||||
_previousFrame = null;
|
||||
_hadData = false;
|
||||
},
|
||||
loading: () {},
|
||||
);
|
||||
});
|
||||
return [];
|
||||
}
|
||||
|
||||
void clear() => state = [];
|
||||
}
|
||||
|
||||
final droneEventLogProvider =
|
||||
NotifierProvider<DroneEventLogNotifier, List<DroneEvent>>(
|
||||
DroneEventLogNotifier.new);
|
||||
@@ -0,0 +1,110 @@
|
||||
import 'package:flutter_riverpod/flutter_riverpod.dart';
|
||||
|
||||
import '../../domain/telemetry/system_message.dart';
|
||||
import '../../transport/connection_type.dart';
|
||||
import '../../transport/flight_controller_link.dart';
|
||||
import 'connection_settings_provider.dart';
|
||||
import 'telemetry_provider.dart';
|
||||
|
||||
/// Fuehrt das System-Messages-Log fuer den gleichnamigen Tab im
|
||||
/// Drohnen-Status-Menue (Doku: "aendere das warnings Menü in System
|
||||
/// Messages ... Verbindung hergestellt/verloren, Verbindungstyp geaendert,
|
||||
/// Wegpunkte uebertragen") - beobachtet [telemetryProvider] und
|
||||
/// [connectionSettingsProvider] dauerhaft (bewusst KEIN autoDispose, siehe
|
||||
/// telemetry_provider.dart-Doku zur analogen Begruendung bei
|
||||
/// flightControllerLinkProvider), damit ein Ereignis auch dann protokolliert
|
||||
/// wird, wenn die System-Messages-Ansicht selbst gerade nicht geoeffnet ist.
|
||||
/// Beginnt zu beobachten, sobald irgendein Widget diesen Provider erstmals
|
||||
/// liest (siehe FlyScreen) - vor diesem Zeitpunkt liegende Ereignisse
|
||||
/// erscheinen nicht im Log, das ist fuer ein Live-Log erwartbar.
|
||||
class SystemMessageLogNotifier extends Notifier<List<SystemMessage>> {
|
||||
TelemetryFrame? _previousFrame;
|
||||
bool _hadData = false;
|
||||
|
||||
@override
|
||||
List<SystemMessage> build() {
|
||||
ref.listen<AsyncValue<TelemetryFrame>>(telemetryProvider, (previous, next) {
|
||||
next.when(
|
||||
data: (frame) {
|
||||
// Flankengetriggert wie "Connection lost" unten, nur umgekehrt -
|
||||
// anders als dort ist hier kein Sonderfall fuer die allererste
|
||||
// Verbindung noetig: der Uebergang "noch keine Daten" -> "erste
|
||||
// Daten" ist immer ein echtes "Connected", auch beim allerersten
|
||||
// Mal.
|
||||
if (!_hadData) {
|
||||
_log('Connected', SystemMessageSeverity.info);
|
||||
}
|
||||
final events = detectSystemMessages(
|
||||
previous: _previousFrame,
|
||||
current: frame,
|
||||
now: DateTime.now(),
|
||||
);
|
||||
_previousFrame = frame;
|
||||
_hadData = true;
|
||||
if (events.isNotEmpty) {
|
||||
state = [...events.reversed, ...state];
|
||||
}
|
||||
},
|
||||
error: (error, stackTrace) {
|
||||
// Nur melden, wenn zuvor bereits Frames flossen - sonst wuerde
|
||||
// schon das (normale) Ausbleiben der allerersten Verbindung als
|
||||
// "Connection lost" auftauchen.
|
||||
if (_hadData) {
|
||||
_log('Connection lost', SystemMessageSeverity.critical);
|
||||
}
|
||||
_previousFrame = null;
|
||||
_hadData = false;
|
||||
},
|
||||
loading: () {},
|
||||
);
|
||||
});
|
||||
|
||||
// Verbindungsart-Wechsel (Doku: "Verbindungstyp geaendert") - nur ab dem
|
||||
// zweiten geladenen Wert protokollieren, sonst wuerde bereits das
|
||||
// erstmalige Laden der Einstellungen aus der DB als "Wechsel" erscheinen.
|
||||
ConnectionType? previousType;
|
||||
var sawFirstLoad = false;
|
||||
ref.listen(connectionSettingsProvider, (previous, next) {
|
||||
final type = next.value?.connectionType;
|
||||
if (type == null) return;
|
||||
if (!sawFirstLoad) {
|
||||
sawFirstLoad = true;
|
||||
previousType = type;
|
||||
return;
|
||||
}
|
||||
if (type != previousType) {
|
||||
_log('Connection type changed to ${_connectionTypeLabel(type)}',
|
||||
SystemMessageSeverity.info);
|
||||
previousType = type;
|
||||
}
|
||||
});
|
||||
|
||||
return [];
|
||||
}
|
||||
|
||||
String _connectionTypeLabel(ConnectionType type) => switch (type) {
|
||||
ConnectionType.wifi => 'WiFi mLRS UDP',
|
||||
ConnectionType.mock => 'Mock (Test)',
|
||||
};
|
||||
|
||||
/// Fuegt einen Eintrag manuell hinzu (Doku: "Wegpunkte uebertragen") - fuer
|
||||
/// Ereignisse, die nicht aus der Telemetrie/den Einstellungen ableitbar
|
||||
/// sind, sondern vom Aufloeser einer konkreten Aktion (z.B. FlyScreen nach
|
||||
/// einem Missions-Upload) gemeldet werden.
|
||||
void log(String message, {SystemMessageSeverity severity = SystemMessageSeverity.info}) {
|
||||
_log(message, severity);
|
||||
}
|
||||
|
||||
void _log(String message, SystemMessageSeverity severity) {
|
||||
state = [
|
||||
SystemMessage(timestamp: DateTime.now(), message: message, severity: severity),
|
||||
...state,
|
||||
];
|
||||
}
|
||||
|
||||
void clear() => state = [];
|
||||
}
|
||||
|
||||
final systemMessageLogProvider =
|
||||
NotifierProvider<SystemMessageLogNotifier, List<SystemMessage>>(
|
||||
SystemMessageLogNotifier.new);
|
||||
Reference in New Issue
Block a user