MotorSignal-App/lib/models/field_test_event.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>?,
);
}
}