MobilApp/lib/services/gnss/gnss_service.dart

126 lines
3.9 KiB
Dart
Raw Normal View History

// 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';
import 'gnss_device_service.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();
}
// ── Eszközváltás — a GnssDevicePickerDialog hívja ───────────────
Future<void> onDeviceChanged(GnssDevice device) async {
switch (device.type) {
case GnssConnectionType.btSerial:
await connectBtSerial(device.address);
case GnssConnectionType.ble:
await connectBle(device.address);
case GnssConnectionType.phoneGps:
// Külső GPS kapcsolat lezárása ha volt
await _disconnect();
connectionState.value = GnssConnectionState.disconnected;
activeConnectionType.value = GnssConnectionType.phoneGps;
// A telefon GPS kezelése a map_controller _startPhoneGps()-ben van
// itt csak jelezzük hogy phone módra váltottunk
}
}
}