summaryrefslogtreecommitdiff
path: root/lib/control
diff options
context:
space:
mode:
authoruvok2025-07-31 12:53:27 +0200
committeruvok2025-07-31 12:53:27 +0200
commit6bb96a3cb00982034c38895f499486a3f66628e0 (patch)
tree1cbc3222195c4bf3a148ce4c19a881a585533251 /lib/control
parentfd926a55a0160d5c01ff7f05d3d0d4023d2a5be9 (diff)
Add universal_ble scanner+device
Diffstat (limited to 'lib/control')
-rw-r--r--lib/control/universal_ble_scanner_controller.dart76
1 files changed, 76 insertions, 0 deletions
diff --git a/lib/control/universal_ble_scanner_controller.dart b/lib/control/universal_ble_scanner_controller.dart
new file mode 100644
index 0000000..dd447bd
--- /dev/null
+++ b/lib/control/universal_ble_scanner_controller.dart
@@ -0,0 +1,76 @@
+import 'dart:async';
+
+import 'package:logger/logger.dart';
+import 'package:universal_ble/universal_ble.dart';
+import 'package:uvok_epaper_badge/control/scanner_controller.dart';
+import 'package:uvok_epaper_badge/control/scanner_controller_impl.dart';
+import 'package:uvok_epaper_badge/model/device/universal_ble_device.dart';
+
+Logger logger = Logger();
+
+class UniversalBleScannerController extends ScannerControllerImpl {
+ StreamSubscription<BleDevice>? _subscription;
+ final List<BleDevice> _devices = [];
+
+ UniversalBleScannerController() {
+ // fuck this limitation, I want an instance method to be called, which doesn't
+ // work in an initializer.
+ _subscription = UniversalBle.scanStream.listen(_newDeviceAction);
+ }
+
+ void _newDeviceAction(BleDevice dev) {
+ //logger.i("Found device: ${dev.toString()}");
+ bool added = _devices.addIf(dev, (exDev) => exDev.deviceId != dev.deviceId);
+ if (added) {
+ super.setDevices(
+ _devices
+ .map((d) => UniversalBleDevice.fromDevice(d))
+ .toList(growable: false),
+ );
+ }
+ }
+
+ @override
+ Future<void> startScan({
+ Duration timeout = const Duration(seconds: 5),
+ }) async {
+ AvailabilityState state =
+ await UniversalBle.getBluetoothAvailabilityState();
+ if (state != AvailabilityState.poweredOn) return;
+
+ _devices.clear();
+ super.setDevices([]);
+ super.setStatus(ScanStatus.scanning);
+
+ await UniversalBle.startScan();
+ await Future.delayed(timeout);
+ await UniversalBle.stopScan();
+ super.setStatus(ScanStatus.finished);
+
+ logger.i("Found ${_devices.length} devices");
+ }
+
+ @override
+ Future<void> stopScan() async {
+ await UniversalBle.stopScan();
+ }
+
+ @override
+ void dispose() {
+ super.dispose();
+ stopScan().ignore();
+ _subscription?.cancel();
+ }
+}
+
+extension ListAddExt<T> on List<T> {
+ /// An element if the predicate is true only for all elements.
+ /// predicate is passed all existing elements.
+ bool addIf(T dev, bool Function(T exDev) predicate) {
+ if (every(predicate)) {
+ add(dev);
+ return true;
+ }
+ return false;
+ }
+}