feat(display): Sprint 7 — USB serial link to AR-Concentrador via NMEA $PARP
- Add flutter_libserialport dependency (pubspec.yaml) - New ParpCodec: XOR-checksum NMEA parser + command builders for all PARP sentences - New ConcentradorService: manages two independent COM ports (RX-OUT broadcast, TX-IN commands) at 115200/8N1; auto-fires onConnectionChanged on link drop - AutopilotState: dual-mode operation (demo timer OR live serial); connectToSerial / disconnectSerial; command methods (engage/disengage/adjustSetpoint) forward to ConcentradorService when connected; falls back to demo on disconnect - New PortSettingsScreen (/settings/ports): RX+TX dropdowns populated from SerialPort.availablePorts, persisted in SharedPreferences; Connect/Disconnect buttons with error display and snackbar feedback - main.dart: auto-connect to saved ports on startup (silent fail → demo mode); registers /settings/ports route - CockpitScreen: gear icon replaced with PopupMenuButton (Puertos COM / Apariencia) AR_electronics — AR-Autopilot Project
This commit is contained in:
+31
-8
@@ -1,25 +1,48 @@
|
||||
import 'package:flutter/material.dart';
|
||||
import 'package:provider/provider.dart';
|
||||
import 'package:shared_preferences/shared_preferences.dart';
|
||||
|
||||
import 'data/autopilot_state.dart';
|
||||
import 'theme/theme_provider.dart';
|
||||
import 'screens/cockpit/cockpit_screen.dart';
|
||||
import 'screens/settings/appearance_settings.dart';
|
||||
import 'screens/settings/port_settings_screen.dart';
|
||||
|
||||
// SharedPreferences keys — must match port_settings_screen.dart
|
||||
const _kRxKey = 'port.rx';
|
||||
const _kTxKey = 'port.tx';
|
||||
|
||||
Future<void> main() async {
|
||||
WidgetsFlutterBinding.ensureInitialized();
|
||||
|
||||
// Load persisted theme before first frame.
|
||||
final themeProvider = await AutopilotThemeProvider.load();
|
||||
|
||||
// Create state object early so we can attempt auto-connect.
|
||||
final autopilotState = AutopilotState();
|
||||
|
||||
// Attempt to reconnect to the last-used COM ports silently.
|
||||
// If the ports are not available (hardware unplugged, different PC, etc.)
|
||||
// the exception is swallowed and the UI stays in demo mode.
|
||||
try {
|
||||
final prefs = await SharedPreferences.getInstance();
|
||||
final rxPort = prefs.getString(_kRxKey);
|
||||
final txPort = prefs.getString(_kTxKey);
|
||||
if (rxPort != null && txPort != null) {
|
||||
await autopilotState.connectToSerial(rxPort: rxPort, txPort: txPort);
|
||||
}
|
||||
} catch (_) {
|
||||
// Hardware not available — stay in demo mode.
|
||||
}
|
||||
|
||||
runApp(
|
||||
MultiProvider(
|
||||
providers: [
|
||||
ChangeNotifierProvider<AutopilotThemeProvider>.value(
|
||||
value: themeProvider,
|
||||
),
|
||||
// AutopilotState drives the cockpit UI.
|
||||
// Sprint 4: internal demo timer (vessel simulation).
|
||||
// Sprint 7: replace with AutopilotStateModbus or wire Modbus RTU here.
|
||||
ChangeNotifierProvider<AutopilotState>(
|
||||
create: (_) => AutopilotState(),
|
||||
ChangeNotifierProvider<AutopilotState>.value(
|
||||
value: autopilotState,
|
||||
),
|
||||
],
|
||||
child: const ArAutopilotApp(),
|
||||
@@ -38,9 +61,9 @@ class ArAutopilotApp extends StatelessWidget {
|
||||
theme: ThemeData(useMaterial3: true),
|
||||
initialRoute: CockpitScreen.routeName,
|
||||
routes: {
|
||||
CockpitScreen.routeName: (_) => const CockpitScreen(),
|
||||
AppearanceSettingsScreen.routeName: (_) =>
|
||||
const AppearanceSettingsScreen(),
|
||||
CockpitScreen.routeName: (_) => const CockpitScreen(),
|
||||
AppearanceSettingsScreen.routeName: (_) => const AppearanceSettingsScreen(),
|
||||
PortSettingsScreen.routeName: (_) => const PortSettingsScreen(),
|
||||
},
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user