105 lines
3.2 KiB
Dart
105 lines
3.2 KiB
Dart
// 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<GnssConnectionType>();
|
|
|
|
// 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<void> connectBtSerial(String macAddress) async {
|
|
await _disconnect();
|
|
_connection = BtSerialGnssConnection();
|
|
activeConnectionType.value = GnssConnectionType.btSerial;
|
|
await _doConnect(macAddress);
|
|
}
|
|
|
|
Future<void> 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<void> _doConnect(String address) async {
|
|
_stateSub = _connection!.connectionState.listen((s) {
|
|
connectionState.value = s;
|
|
});
|
|
_nmeaSub = _connection!.nmeaLines.listen(_parseNmea);
|
|
await _connection!.connect(address);
|
|
}
|
|
|
|
Future<void> _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();
|
|
}
|
|
}
|