xiao_pet_tracker/lib/home/view/home_page.dart

285 lines
7.7 KiB
Dart
Raw Normal View History

2024-10-28 20:10:55 +01:00
import 'dart:async';
import 'package:flutter/foundation.dart';
import 'package:flutter/material.dart';
import 'package:flutter_blue_plus_windows/flutter_blue_plus_windows.dart';
import 'package:shadcn_ui/shadcn_ui.dart';
class HomePage extends StatelessWidget {
const HomePage({super.key});
@override
Widget build(BuildContext context) {
return const HomeScreen();
}
}
class HomeScreen extends StatefulWidget {
const HomeScreen({super.key});
@override
State<HomeScreen> createState() => _HomeScreenState();
}
class _HomeScreenState extends State<HomeScreen> {
List<BluetoothDevice> _systemDevices = [];
List<ScanResult> _scanResults = [];
bool _isScanning = false;
late StreamSubscription<List<ScanResult>> _scanResultsSubscription;
late StreamSubscription<bool> _isScanningSubscription;
bool _connected = false;
bool _found = false;
BluetoothDevice? device;
List<BluetoothService> _services = [];
Future<void> scanDevices() async {
if (await FlutterBluePlus.isSupported == false) {
print("Bluetooth not supported by this device");
return;
}
final scannedDevices = <ScanResult>{};
const timeout = Duration(seconds: 3);
await FlutterBluePlus.startScan(timeout: timeout);
final sub =
FlutterBluePlus.scanResults.expand((e) => e).listen(scannedDevices.add);
// await Future.delayed(timeout);
sub.cancel();
scannedDevices.forEach(print);
print('Scanned devices: ${scannedDevices.length}');
}
@override
void initState() {
super.initState();
_scanResultsSubscription = FlutterBluePlus.scanResults.listen((results) {
_scanResults = results;
if (mounted) {
setState(() {});
}
}, onError: (e) {
print('Scan Results Subscription Error: $e');
});
_isScanningSubscription = FlutterBluePlus.isScanning.listen((state) {
_isScanning = state;
if (mounted) {
setState(() {});
}
});
}
@override
void dispose() {
_scanResultsSubscription.cancel();
_isScanningSubscription.cancel();
super.dispose();
}
Future onScanPressed() async {
try {
_systemDevices = await FlutterBluePlus.systemDevices([]);
} catch (e) {
print('System Devices Error: $e');
}
try {
await FlutterBluePlus.startScan(timeout: const Duration(seconds: 15));
} catch (e) {
print('Start Scan Error: $e');
}
if (mounted) {
setState(() {});
}
}
Future onConnectPressed() async {
try {
_systemDevices = await FlutterBluePlus.systemDevices([]);
} catch (e) {
print('System Devices Error: $e');
}
try {
await FlutterBluePlus.startScan(timeout: const Duration(seconds: 15));
} catch (e) {
print('Start Scan Error: $e');
}
FlutterBluePlus.scanResults.listen((results) async {
for (ScanResult r in results) {
if (kDebugMode) {
print(r);
}
if (r.device.advName == "Go Bluetooth") {
await FlutterBluePlus.stopScan();
device = r.device;
print("FOUND BLUETOOTH DEVICE");
await device?.connect();
try {
_services = await device?.discoverServices() ?? [];
} catch (e) {
print("Discover Services Error: $e");
}
if (mounted) {
setState(() {
_connected = true;
});
}
}
}
});
}
Future onStopPressed() async {
try {
FlutterBluePlus.stopScan();
} catch (e) {
print('Stop Scan Error: $e');
}
}
Future onRefresh() {
if (_isScanning == false) {
FlutterBluePlus.startScan(timeout: const Duration(seconds: 15));
}
if (mounted) {
setState(() {});
}
return Future.delayed(const Duration(milliseconds: 500));
}
Future<void> handleDisconnect() async {
await device?.disconnect();
}
Future onDisconnectPressed() async {
await handleDisconnect();
setState(() {
_connected = false;
});
}
@override
Future<void> deactivate() async {
super.deactivate();
await handleDisconnect();
}
@override
Widget build(BuildContext context) {
return Scaffold(
appBar: AppBar(
title: const Text('XIAO Sense'),
),
body: SingleChildScrollView(
child: Column(
children: [
// ListView.builder(
// shrinkWrap: true,
// physics: const NeverScrollableScrollPhysics(),
// itemCount: _scanResults.length,
// itemBuilder: (context, index) {
// return ListTile(
// title: Text(_scanResults[index].device.remoteId.toString()),
// subtitle: Text(_scanResults[index].device.advName),
// );
// },
// ),
if (_connected) Text('Connected!'),
ShadButton(
enabled: !_isScanning,
onPressed: () async {
// await Future<void>.delayed(const Duration(seconds: 2));
// onScanPressed();
if (_connected) {
onDisconnectPressed();
} else {
onConnectPressed();
}
},
icon: _isScanning
? const SizedBox.square(
dimension: 16,
child: CircularProgressIndicator(),
)
: null,
child: _isScanning
? const Text('Please wait')
: _connected
? const Text('Disconnect')
: const Text('Connect'),
),
ShadButton(
onPressed: () async {
print('Toggle LED');
print(_services);
final ledService = _services
.where(
(s) =>
s.serviceUuid ==
Guid('a0b40001-926d-4d61-98df-8c5c62ee53b3'),
)
.first
.characteristics
.where((c) =>
c.characteristicUuid ==
Guid('a0b40002-926d-4d61-98df-8c5c62ee53b3'))
.first;
ledService.write([
0,
1,
0,
]);
// await Future.delayed(Duration(seconds: 2));
List<int> ledServiceValue = await ledService.read();
print("READ LED SERVICE: $ledServiceValue");
},
child: Text('Toggle LED'),
),
ShadButton(
onPressed: () async {
print('Toggle LED');
print(_services);
final ledService = _services
.where(
(s) =>
s.serviceUuid ==
Guid('a0b40003-926d-4d61-98df-8c5c62ee53b3'),
)
.first
.characteristics
.where((c) =>
c.characteristicUuid ==
Guid('a0b40004-926d-4d61-98df-8c5c62ee53b3'))
.first;
// await ledService.write([1, 2, 3]);
// await Future.delayed(Duration(seconds: 2));
List<int> ledServiceValue = await ledService.read();
print("READ Sense SERVICE: $ledServiceValue");
print(
"READ Sense SERVICE: ${String.fromCharCodes(ledServiceValue)}");
},
child: Text('Read Sense'),
)
],
),
),
);
}
}