MobilApp/lib/pages/bleutooth/presentation/controllers/bluetooth_controller.dart

181 lines
5.2 KiB
Dart
Raw Permalink Normal View History

2025-02-21 08:26:27 +01:00
import 'dart:async';
import 'dart:convert';
import 'dart:typed_data';
import 'package:flutter_bluetooth_serial/flutter_bluetooth_serial.dart';
import 'package:get/get.dart';
import 'package:nmea/nmea.dart';
import 'package:terepi_seged/gnss_sentences/gngga.dart';
class BluetoothTestViewController extends GetxController {
Rx<BluetoothState> bluetoothState = BluetoothState.UNKNOWN.obs;
RxList<BluetoothDevice> devices = RxList<BluetoothDevice>([]);
Rx<BluetoothDevice>? selectedDevice;
final NmeaDecoder nmeaDecoder = NmeaDecoder();
BluetoothConnection? connection;
StreamSubscription<BluetoothDiscoveryResult>? _bluetoothDiscoveryStream;
RxList<BluetoothDiscoveryResult> bluetoothDiscoveryResults =
RxList<BluetoothDiscoveryResult>.empty(growable: true);
// bool get isConnected => connection != null && connection!.isConnected;
bool isConnected = false;
int count = 0;
String _messageBuffer = '';
bool hasGpsData = false;
DateTime lastGpsRefreshTime = DateTime.now();
RxString utcOfPositionFix = "".obs;
@override
void onInit() {
super.onInit();
print("Call BluetoothTestController.OnInit");
FlutterBluetoothSerial.instance.state.then((state) {
bluetoothState.value = state;
if (bluetoothState.value.isEnabled) {
//_listBoundedDevices();
_startDiscovery();
}
});
nmeaDecoder.registerTalkerSentence("GGA", (line) => Gngga(raw: line));
//Loading, Success, Error handle with 1 line of code
}
@override
void onClose() {
super.onClose();
FlutterBluetoothSerial.instance.setPairingRequestHandler(null);
if (isConnected) {
connection?.close();
// connection = null;
print("BluetoothTestController dispose ....");
}
}
_listBoundedDevices() {
FlutterBluetoothSerial.instance
.getBondedDevices()
.then((List<BluetoothDevice> boundedDevices) {
devices.value = boundedDevices;
devices.refresh();
});
}
void setSelectedDevice(BluetoothDevice device) {
selectedDevice = Rx<BluetoothDevice>(device);
if (!isConnected) {
BluetoothConnection.toAddress(selectedDevice?.value.address)
.then((value) {
connection = value;
isConnected = true;
print("Bleutooth device connected .... ${connection!.isConnected}");
connection!.input!.listen(_onDataReceived);
});
// connection!.input!.listen((data) {
// print("Data -> $data");
// });
}
}
void _startDiscovery() {
_bluetoothDiscoveryStream =
FlutterBluetoothSerial.instance.startDiscovery().listen((event) {
final existingIndex = bluetoothDiscoveryResults.indexWhere(
(element) => element.device.address == event.device.address);
if (existingIndex > 0) {
bluetoothDiscoveryResults[existingIndex] = event;
update();
} else {
bluetoothDiscoveryResults.add(event);
update();
}
});
_bluetoothDiscoveryStream!.onDone(() {});
}
void _onDataReceived(Uint8List data) {
// Allocate buffer for parsed data
int backspacesCounter = 0;
String sentence = '';
// print("Data: $data");
for (var byte in data) {
if (byte == 8 || byte == 127) {
backspacesCounter++;
}
}
Uint8List buffer = Uint8List(data.length - backspacesCounter);
int bufferIndex = buffer.length;
// Apply backspace control character
backspacesCounter = 0;
for (int i = data.length - 1; i >= 0; i--) {
if (data[i] == 8 || data[i] == 127) {
backspacesCounter++;
} else {
if (backspacesCounter > 0) {
backspacesCounter--;
} else {
buffer[--bufferIndex] = data[i];
}
}
}
// Create message if there is new line character
String dataString = String.fromCharCodes(buffer);
int index = buffer.indexOf(13);
if (~index != 0) {
sentence = backspacesCounter > 0
? _messageBuffer.substring(
0, _messageBuffer.length - backspacesCounter)
: _messageBuffer + dataString.substring(0, index);
_messageBuffer = dataString.substring(index);
} else {
_messageBuffer = (backspacesCounter > 0
? _messageBuffer.substring(
0, _messageBuffer.length - backspacesCounter)
: _messageBuffer + dataString);
}
count++;
// print("Message ($count): $sentence");
_processGnssMessage(sentence);
}
void _processGnssMessage(String message) {
LineSplitter lineSplitter = const LineSplitter();
List<String> lines = lineSplitter.convert(message);
if (lines.isEmpty) {
return;
}
for (String line in lines) {
if (line.trim().isEmpty) {
continue;
}
if (line.startsWith("\$GNGGA")) {
final sentence = nmeaDecoder.decode(line);
if (sentence!.valid && sentence is Gngga) {
hasGpsData = sentence.gpsQualityIndicator > 0;
if (hasGpsData) {
if (DateTime.now().difference(lastGpsRefreshTime).inSeconds >= 4) {
lastGpsRefreshTime = DateTime.now();
utcOfPositionFix.value = sentence.utcOfPositionFix;
}
print("Last update: $utcOfPositionFix");
}
}
}
}
}
}