214 lines
7.3 KiB
Dart
214 lines
7.3 KiB
Dart
import 'package:flutter/material.dart';
|
|
|
|
enum FieldTestEventType {
|
|
rideStarted,
|
|
rideStopped,
|
|
gpsStale,
|
|
gpsRecovered,
|
|
gpsJumpRejected,
|
|
gpsAccuracyDegraded,
|
|
imuSaturation,
|
|
imuRecovered,
|
|
telemetryGap,
|
|
telemetryRecovered,
|
|
timestampError,
|
|
sampleAccepted,
|
|
sampleSuspect,
|
|
sampleRejected,
|
|
accelerationEvent,
|
|
brakingEvent,
|
|
performanceRunStarted,
|
|
performanceRunCompleted,
|
|
performanceRunRejected,
|
|
appPaused,
|
|
appResumed,
|
|
foregroundServiceStarted,
|
|
foregroundServiceStopped,
|
|
databaseFlush,
|
|
databaseQueueWarning,
|
|
databaseQueueOverflow,
|
|
databaseRecovery,
|
|
exportStarted,
|
|
exportCompleted,
|
|
exportFailed,
|
|
sensorInitialized,
|
|
sensorError,
|
|
gpsInitialized,
|
|
gpsError,
|
|
calibrationStarted,
|
|
calibrationCompleted,
|
|
roadAlertReceived,
|
|
ttsAnnounced,
|
|
audioFailure,
|
|
networkError;
|
|
|
|
String get displayName {
|
|
switch (this) {
|
|
case FieldTestEventType.rideStarted: return 'RIDE_STARTED';
|
|
case FieldTestEventType.rideStopped: return 'RIDE_STOPPED';
|
|
case FieldTestEventType.gpsStale: return 'GPS_STALE';
|
|
case FieldTestEventType.gpsRecovered: return 'GPS_RECOVERED';
|
|
case FieldTestEventType.gpsJumpRejected: return 'GPS_JUMP_REJECTED';
|
|
case FieldTestEventType.gpsAccuracyDegraded: return 'GPS_ACCURACY_DEGRADED';
|
|
case FieldTestEventType.imuSaturation: return 'IMU_SATURATION';
|
|
case FieldTestEventType.imuRecovered: return 'IMU_RECOVERED';
|
|
case FieldTestEventType.telemetryGap: return 'TELEMETRY_GAP';
|
|
case FieldTestEventType.telemetryRecovered: return 'TELEMETRY_RECOVERED';
|
|
case FieldTestEventType.timestampError: return 'TIMESTAMP_ERROR';
|
|
case FieldTestEventType.sampleAccepted: return 'SAMPLE_ACCEPTED';
|
|
case FieldTestEventType.sampleSuspect: return 'SAMPLE_SUSPECT';
|
|
case FieldTestEventType.sampleRejected: return 'SAMPLE_REJECTED';
|
|
case FieldTestEventType.accelerationEvent: return 'ACCELERATION_EVENT';
|
|
case FieldTestEventType.brakingEvent: return 'BRAKING_EVENT';
|
|
case FieldTestEventType.performanceRunStarted: return 'PERFORMANCE_RUN_STARTED';
|
|
case FieldTestEventType.performanceRunCompleted: return 'PERFORMANCE_RUN_COMPLETED';
|
|
case FieldTestEventType.performanceRunRejected: return 'PERFORMANCE_RUN_REJECTED';
|
|
case FieldTestEventType.appPaused: return 'APP_PAUSED';
|
|
case FieldTestEventType.appResumed: return 'APP_RESUMED';
|
|
case FieldTestEventType.foregroundServiceStarted: return 'FOREGROUND_SERVICE_STARTED';
|
|
case FieldTestEventType.foregroundServiceStopped: return 'FOREGROUND_SERVICE_STOPPED';
|
|
case FieldTestEventType.databaseFlush: return 'DATABASE_FLUSH';
|
|
case FieldTestEventType.databaseQueueWarning: return 'DATABASE_QUEUE_WARNING';
|
|
case FieldTestEventType.databaseQueueOverflow: return 'DATABASE_QUEUE_OVERFLOW';
|
|
case FieldTestEventType.databaseRecovery: return 'DATABASE_RECOVERY';
|
|
case FieldTestEventType.exportStarted: return 'EXPORT_STARTED';
|
|
case FieldTestEventType.exportCompleted: return 'EXPORT_COMPLETED';
|
|
case FieldTestEventType.exportFailed: return 'EXPORT_FAILED';
|
|
case FieldTestEventType.sensorInitialized: return 'SENSOR_INITIALIZED';
|
|
case FieldTestEventType.sensorError: return 'SENSOR_ERROR';
|
|
case FieldTestEventType.gpsInitialized: return 'GPS_INITIALIZED';
|
|
case FieldTestEventType.gpsError: return 'GPS_ERROR';
|
|
case FieldTestEventType.calibrationStarted: return 'CALIBRATION_STARTED';
|
|
case FieldTestEventType.calibrationCompleted: return 'CALIBRATION_COMPLETED';
|
|
case FieldTestEventType.roadAlertReceived: return 'ROAD_ALERT_RECEIVED';
|
|
case FieldTestEventType.ttsAnnounced: return 'TTS_ANNOUNCED';
|
|
case FieldTestEventType.audioFailure: return 'AUDIO_FAILURE';
|
|
case FieldTestEventType.networkError: return 'NETWORK_ERROR';
|
|
}
|
|
}
|
|
|
|
static FieldTestEventType fromString(String val) {
|
|
final clean = val.toUpperCase().replaceAll('-', '_');
|
|
for (final e in FieldTestEventType.values) {
|
|
if (e.displayName == clean || e.name.toUpperCase() == clean) {
|
|
return e;
|
|
}
|
|
}
|
|
return FieldTestEventType.sampleAccepted;
|
|
}
|
|
}
|
|
|
|
enum EventSeverity {
|
|
info,
|
|
warning,
|
|
error,
|
|
critical;
|
|
|
|
String get displayName => name.toUpperCase();
|
|
|
|
Color get color {
|
|
switch (this) {
|
|
case EventSeverity.info: return Colors.cyanAccent;
|
|
case EventSeverity.warning: return Colors.amberAccent;
|
|
case EventSeverity.error: return Colors.orangeAccent;
|
|
case EventSeverity.critical: return Colors.redAccent;
|
|
}
|
|
}
|
|
|
|
static EventSeverity fromString(String val) {
|
|
final clean = val.toLowerCase();
|
|
for (final s in EventSeverity.values) {
|
|
if (s.name.toLowerCase() == clean) {
|
|
return s;
|
|
}
|
|
}
|
|
return EventSeverity.info;
|
|
}
|
|
}
|
|
|
|
class FieldTestEvent {
|
|
final int? id;
|
|
final DateTime timestamp;
|
|
final FieldTestEventType eventType;
|
|
final int? rideId;
|
|
final EventSeverity severity;
|
|
final String message;
|
|
final DateTime? telemetryTimestamp;
|
|
final int? gpsAgeMs;
|
|
final double? speed;
|
|
final double? latitude;
|
|
final double? longitude;
|
|
final double? gpsAccuracy;
|
|
final double? leanAngle;
|
|
final double? longitudinalG;
|
|
final double? lateralG;
|
|
final double? overallConfidence;
|
|
final Map<String, dynamic>? metadata;
|
|
|
|
const FieldTestEvent({
|
|
this.id,
|
|
required this.timestamp,
|
|
required this.eventType,
|
|
this.rideId,
|
|
required this.severity,
|
|
required this.message,
|
|
this.telemetryTimestamp,
|
|
this.gpsAgeMs,
|
|
this.speed,
|
|
this.latitude,
|
|
this.longitude,
|
|
this.gpsAccuracy,
|
|
this.leanAngle,
|
|
this.longitudinalG,
|
|
this.lateralG,
|
|
this.overallConfidence,
|
|
this.metadata,
|
|
});
|
|
|
|
Map<String, dynamic> toJson() {
|
|
return {
|
|
'id': id,
|
|
'timestamp': timestamp.toIso8601String(),
|
|
'eventType': eventType.displayName,
|
|
'rideId': rideId,
|
|
'severity': severity.displayName,
|
|
'message': message,
|
|
'telemetryTimestamp': telemetryTimestamp?.toIso8601String(),
|
|
'gpsAgeMs': gpsAgeMs,
|
|
'speed': speed,
|
|
'latitude': latitude,
|
|
'longitude': longitude,
|
|
'gpsAccuracy': gpsAccuracy,
|
|
'leanAngle': leanAngle,
|
|
'longitudinalG': longitudinalG,
|
|
'lateralG': lateralG,
|
|
'overallConfidence': overallConfidence,
|
|
'metadata': metadata,
|
|
};
|
|
}
|
|
|
|
factory FieldTestEvent.fromJson(Map<String, dynamic> json) {
|
|
return FieldTestEvent(
|
|
id: json['id'] as int?,
|
|
timestamp: DateTime.parse(json['timestamp'] as String),
|
|
eventType: FieldTestEventType.fromString(json['eventType'] as String),
|
|
rideId: json['rideId'] as int?,
|
|
severity: EventSeverity.fromString(json['severity'] as String),
|
|
message: json['message'] as String? ?? '',
|
|
telemetryTimestamp: json['telemetryTimestamp'] != null
|
|
? DateTime.parse(json['telemetryTimestamp'] as String)
|
|
: null,
|
|
gpsAgeMs: json['gpsAgeMs'] as int?,
|
|
speed: (json['speed'] as num?)?.toDouble(),
|
|
latitude: (json['latitude'] as num?)?.toDouble(),
|
|
longitude: (json['longitude'] as num?)?.toDouble(),
|
|
gpsAccuracy: (json['gpsAccuracy'] as num?)?.toDouble(),
|
|
leanAngle: (json['leanAngle'] as num?)?.toDouble(),
|
|
longitudinalG: (json['longitudinalG'] as num?)?.toDouble(),
|
|
lateralG: (json['lateralG'] as num?)?.toDouble(),
|
|
overallConfidence: (json['overallConfidence'] as num?)?.toDouble(),
|
|
metadata: json['metadata'] as Map<String, dynamic>?,
|
|
);
|
|
}
|
|
}
|