/// A MAVLink severity value retained exactly as it appeared on the wire. /// /// Known values follow MAVLink's numeric severity semantics. Unknown values /// remain displayable so a newer vehicle cannot silently lose diagnostic /// meaning before Ground Suite has been updated. final class MavSeverity { const MavSeverity(this.wireValue); static const emergency = MavSeverity(0); static const alert = MavSeverity(1); static const critical = MavSeverity(2); static const error = MavSeverity(3); static const warning = MavSeverity(4); static const notice = MavSeverity(5); static const info = MavSeverity(6); static const debug = MavSeverity(7); final int wireValue; String get label => switch (wireValue) { 0 => 'Emergency', 1 => 'Alert', 2 => 'Critical', 3 => 'Error', 4 => 'Warning', 5 => 'Notice', 6 => 'Info', 7 => 'Debug', _ => 'Unknown ($wireValue)', }; } /// A KAPTAN_SHUTDOWN reason retained exactly as it appeared on the wire. final class KaptanShutdownReason { const KaptanShutdownReason(this.wireValue); static const operator = KaptanShutdownReason(1); static const safety = KaptanShutdownReason(2); final int wireValue; String get label => switch (wireValue) { 1 => 'Operator', 2 => 'Safety', _ => 'Unknown ($wireValue)', }; } enum TelemetryKind { rawImu, distanceSensor, opticalFlow; String get label => switch (this) { TelemetryKind.rawImu => 'Raw IMU', TelemetryKind.distanceSensor => 'Distance sensor', TelemetryKind.opticalFlow => 'Optical flow', }; } sealed class ObservedEvent { const ObservedEvent({required this.receivedAt}); final DateTime receivedAt; } final class HeartbeatEvent extends ObservedEvent { const HeartbeatEvent({ required super.receivedAt, required this.systemId, required this.componentId, required this.armed, required this.vehicleState, }); final int systemId; final int componentId; final bool armed; final String vehicleState; } final class TelemetryEvent extends ObservedEvent { const TelemetryEvent({required super.receivedAt, required this.kind}); final TelemetryKind kind; } final class LogEvent extends ObservedEvent { const LogEvent({ required super.receivedAt, required this.level, required this.message, this.flags = 0, }); static const traceFlag = 1; static const truncatedFlag = 2; static const coalescedFlag = 4; static const knownFlags = traceFlag | truncatedFlag | coalescedFlag; final MavSeverity level; final String message; final int flags; bool get isTrace => flags & traceFlag != 0; bool get isTruncated => flags & truncatedFlag != 0; bool get isCoalesced => flags & coalescedFlag != 0; int get unknownFlags => flags & ~knownFlags; } final class ErrorEvent extends ObservedEvent { const ErrorEvent({ required super.receivedAt, required this.path, this.additionalInformation = '', this.flags = 0, }); static const truncatedFlag = 2; static const coalescedFlag = 4; static const knownFlags = truncatedFlag | coalescedFlag; final String path; final String additionalInformation; final int flags; bool get isTruncated => flags & truncatedFlag != 0; bool get isCoalesced => flags & coalescedFlag != 0; int get unknownFlags => flags & ~knownFlags; } final class ShutdownEvent extends ObservedEvent { const ShutdownEvent({required super.receivedAt, required this.reason}); final KaptanShutdownReason reason; }