diff options
author | uvok | 2025-07-31 12:53:27 +0200 |
---|---|---|
committer | uvok | 2025-07-31 12:53:27 +0200 |
commit | 6bb96a3cb00982034c38895f499486a3f66628e0 (patch) | |
tree | 1cbc3222195c4bf3a148ce4c19a881a585533251 /lib/control | |
parent | fd926a55a0160d5c01ff7f05d3d0d4023d2a5be9 (diff) |
Add universal_ble scanner+device
Diffstat (limited to 'lib/control')
-rw-r--r-- | lib/control/universal_ble_scanner_controller.dart | 76 |
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; + } +} |