// lib/services/gnss/gnss_service.dart import 'dart:async'; import 'package:get/get.dart'; import 'package:nmea/nmea.dart'; import '../../gnss_sentences/gngga.dart'; import 'gnss_connection.dart'; import 'bt_serial_gnss_connection.dart'; import 'ble_gnss_connection.dart'; class GnssService extends GetxService { static GnssService get to => Get.find(); GnssConnection? _connection; // Reaktív állapot — a controllerek Obx-szel figyelhetik final connectionState = GnssConnectionState.disconnected.obs; final activeConnectionType = Rxn(); // Parsed NMEA adatok final latitude = 0.0.obs; final longitude = 0.0.obs; final altitude = 0.0.obs; final geoidSeparation = 0.0.obs; final gpsQuality = 0.obs; final utcFix = ''.obs; final satelliteCount = 0.obs; final hdop = 0.0.obs; final NmeaDecoder _decoder = NmeaDecoder(); StreamSubscription? _nmeaSub; StreamSubscription? _stateSub; @override void onInit() { super.onInit(); _decoder.registerTalkerSentence('GGA', (l) => Gngga(raw: l)); } // ── Kapcsolódás ────────────────────────────────────────────────── Future connectBtSerial(String macAddress) async { await _disconnect(); _connection = BtSerialGnssConnection(); activeConnectionType.value = GnssConnectionType.btSerial; await _doConnect(macAddress); } Future connectBle( String deviceId, { String? serviceUuid, String? txCharUuid, }) async { await _disconnect(); _connection = BleGnssConnection( serviceUuid: serviceUuid ?? '6e400001-b5b3-f393-e0a9-e50e24dcca9e', txCharUuid: txCharUuid ?? '6e400003-b5b3-f393-e0a9-e50e24dcca9e', ); activeConnectionType.value = GnssConnectionType.ble; await _doConnect(deviceId); } Future _doConnect(String address) async { _stateSub = _connection!.connectionState.listen((s) { connectionState.value = s; }); _nmeaSub = _connection!.nmeaLines.listen(_parseNmea); await _connection!.connect(address); } Future _disconnect() async { await _nmeaSub?.cancel(); await _stateSub?.cancel(); await _connection?.disconnect(); _connection?.dispose(); _connection = null; } // ── NMEA parsing — egy helyen, nem háromban ────────────────────── void _parseNmea(String line) { if (!line.startsWith('\$GNGGA') && !line.startsWith('\$GPGGA')) return; try { final sentence = _decoder.decode(line); if (sentence == null || !sentence.valid || sentence is! Gngga) return; if (sentence.gpsQualityIndicator == 0) return; latitude.value = sentence.latitude; longitude.value = sentence.longitude; altitude.value = sentence.altitudeAboveMeanSeaLevel; geoidSeparation.value = sentence.geoidSeparation; gpsQuality.value = sentence.gpsQualityIndicator; utcFix.value = sentence.utcOfPositionFix; satelliteCount.value = sentence.numberOfSvsInUse; hdop.value = sentence.hdop; } catch (_) {} } @override void onClose() { _disconnect(); super.onClose(); } }