Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
34 changes: 21 additions & 13 deletions mobile/lib/src/application/device/device_selector_cubit.dart
Original file line number Diff line number Diff line change
Expand Up @@ -3,46 +3,54 @@ import 'dart:async';
import 'package:bloc/bloc.dart';
import 'package:flutter_bloc/flutter_bloc.dart';
import 'package:polydodo/src/domain/acquisition_device/acquisition_device.dart';
import 'package:polydodo/src/domain/acquisition_device/i_acquisition_device_repository.dart';
import 'package:polydodo/src/domain/acquisition_device/device_locator_service.dart';
import 'device_selector_state.dart';

class DeviceSelectorCubit extends Cubit<DeviceState> {
final IAcquisitionDeviceRepository _deviceRepository;
final DeviceLocatorService _deviceLocatorService;
final List<AcquisitionDevice> _scannedDevices = [];

StreamSubscription<List<AcquisitionDevice>> _acquisitionDeviceStream;
Stream _deviceLocatorStream;
StreamSubscription<AcquisitionDevice> _deviceLocatorStreamSubscription;

DeviceSelectorCubit(this._deviceRepository) : super(DeviceInitial()) {
DeviceSelectorCubit(this._deviceLocatorService) : super(DeviceInitial()) {
startSearching();
}

void startSearching() {
_deviceRepository.initializeRepository();
_deviceLocatorStream = _deviceLocatorService.scan();

_acquisitionDeviceStream ??= _deviceRepository
.watch()
.asBroadcastStream()
.listen((devices) => emit(DeviceSearchInProgress(devices)),
onError: (e) => emit(DeviceSearchFailure(e)));
_deviceLocatorStreamSubscription ??= _deviceLocatorStream.listen((device) {
_addDevice(device);
});
}

Future<void> connect(AcquisitionDevice device) async {
emit(DeviceConnectionInProgress());

_deviceRepository.connect(device, connectionCallback);
_deviceLocatorService.connect(device, connectionCallback);
}

void connectionCallback(bool connected, [Exception e]) {
if (e != null) {
emit(DeviceConnectionFailure(e));
resetSearch();
} else if (connected) {
_acquisitionDeviceStream.cancel();
_deviceLocatorStreamSubscription.cancel();
emit(DeviceConnectionSuccess());
}
}

void resetSearch() {
_deviceRepository.disconnect();
_deviceLocatorService.disconnect();
startSearching();
}

void _addDevice(AcquisitionDevice device) {
if (!_scannedDevices.contains(device)) {
_scannedDevices.add(device);

emit(DeviceSearchInProgress(_scannedDevices));
}
}
}
Original file line number Diff line number Diff line change
@@ -1,10 +1,8 @@
import 'package:polydodo/src/domain/acquisition_device/device_type.dart';
import 'package:polydodo/src/domain/entity.dart';

class AcquisitionDevice extends Entity {
final String name;

AcquisitionDevice(
id,
this.name,
) : super(id);
final DeviceType deviceType;
AcquisitionDevice(id, this.name, this.deviceType) : super(id);
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
import 'dart:async';

import 'package:polydodo/src/domain/acquisition_device/acquisition_device.dart';
import 'package:polydodo/src/domain/acquisition_device/device_type.dart';
import 'package:polydodo/src/domain/acquisition_device/i_acquisition_device_repository.dart';

class DeviceLocatorService {
final IAcquisitionDeviceRepository _bluetoothRepository;
final IAcquisitionDeviceRepository _serialRepository;

IAcquisitionDeviceRepository _currentRepository;

StreamSubscription _serialStreamSubscription;
StreamSubscription _bluetoothStreamSubscription;
StreamController<AcquisitionDevice> _acquisitionDeviceController;

DeviceLocatorService(this._bluetoothRepository, this._serialRepository) {
_currentRepository = _serialRepository;
_acquisitionDeviceController = StreamController();
}

Stream<AcquisitionDevice> scan() {
var bluetoothStream = _bluetoothRepository.scan();
var serialStream = _serialRepository.scan();

_serialStreamSubscription ??= bluetoothStream.listen((event) {
_acquisitionDeviceController.add(event);
});
_bluetoothStreamSubscription ??= serialStream.listen((event) {
_acquisitionDeviceController.add(event);
});

return _acquisitionDeviceController.stream;
}

void connect(AcquisitionDevice device, Function(bool, Exception) callback) {
_bluetoothRepository.pauseScan();

_currentRepository = (device.deviceType == DeviceType.bluetooth)
? _bluetoothRepository
: _serialRepository;

_currentRepository.connect(device, callback);
}

void disconnect() {
_currentRepository.disconnect();
}

Future<Stream<List<int>>> startDataStream() {
return _currentRepository.startDataStream();
}

void stopDataStream() {
_currentRepository.stopDataStream();
}
}
1 change: 1 addition & 0 deletions mobile/lib/src/domain/acquisition_device/device_type.dart
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
enum DeviceType { serial, bluetooth }
Original file line number Diff line number Diff line change
@@ -1,13 +1,12 @@
import 'acquisition_device.dart';

abstract class IAcquisitionDeviceRepository {
void initializeRepository();
Stream<AcquisitionDevice> scan();
void pauseScan();

void connect(AcquisitionDevice device, Function(bool, [Exception]) callback);
void disconnect();

Future<Stream<List<int>>> startDataStream();
void stopDataStream();

Stream<List<AcquisitionDevice>> watch();
}

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import 'dart:async';

import 'package:flutter_reactive_ble/flutter_reactive_ble.dart';
import 'package:polydodo/src/domain/acquisition_device/acquisition_device.dart';
import 'package:polydodo/src/domain/acquisition_device/device_type.dart';
import 'package:polydodo/src/domain/acquisition_device/i_acquisition_device_repository.dart';
import 'package:polydodo/src/infrastructure/constants.dart';
import 'package:polydodo/src/domain/unique_id.dart';
Expand All @@ -19,43 +20,42 @@ class BluetoothRepository implements IAcquisitionDeviceRepository {
FlutterReactiveBle flutterReactiveBle;
StreamSubscription<ConnectionStateUpdate> _connectedDeviceStream;
StreamSubscription<DiscoveredDevice> _bluetoothScanSubscription;
final List<AcquisitionDevice> _acquisitionDevicePersistency = [];
final streamController = StreamController<List<AcquisitionDevice>>();
Stream<AcquisitionDevice> bluetoothStream;

@override
void initializeRepository() {
Stream<AcquisitionDevice> scan() {
if (_bluetoothScanSubscription == null) {
flutterReactiveBle = FlutterReactiveBle();

_bluetoothScanSubscription = flutterReactiveBle.scanForDevices(
withServices: []).listen((device) => addDevice(device));
_initScan();
} else {
_bluetoothScanSubscription.resume();
_acquisitionDevicePersistency.clear();
resumeScan();
}

return bluetoothStream;
}

void addDevice(DiscoveredDevice bluetoothDevice) {
var device = AcquisitionDevice(
UniqueId.from(bluetoothDevice.id.toString()), bluetoothDevice.name);
void _initScan() {
flutterReactiveBle = FlutterReactiveBle();

final idx = _acquisitionDevicePersistency.indexOf(device);
bluetoothStream = flutterReactiveBle.scanForDevices(withServices: []).map(
(device) => AcquisitionDevice(
UniqueId.from(device.id),
(device.name.isEmpty) ? 'Unknown' : device.name,
DeviceType.bluetooth));
}

if (idx == -1) {
_acquisitionDevicePersistency.add(device);
} else {
_acquisitionDevicePersistency[idx] = device;
}
@override
void pauseScan() {
_bluetoothScanSubscription.pause();
}

streamController.add(_acquisitionDevicePersistency);
void resumeScan() {
_bluetoothScanSubscription.resume();
}

@override
void connect(
AcquisitionDevice device, Function(bool, [Exception]) callback) async {
_selectedDevice = device;
_acquisitionDevicePersistency.clear();
_bluetoothScanSubscription.pause();

_connectedDeviceStream = flutterReactiveBle
.connectToDevice(
Expand Down Expand Up @@ -112,7 +112,4 @@ class BluetoothRepository implements IAcquisitionDeviceRepository {
_sendCharacteristic,
value: STOP_STREAM_CHAR.codeUnits));
}

@override
Stream<List<AcquisitionDevice>> watch() => streamController.stream;
}
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import 'dart:async';
import 'dart:typed_data';

import 'package:polydodo/src/domain/acquisition_device/device_type.dart';
import 'package:polydodo/src/domain/unique_id.dart';
import 'package:polydodo/src/domain/acquisition_device/acquisition_device.dart';
import 'package:polydodo/src/domain/acquisition_device/i_acquisition_device_repository.dart';
Expand All @@ -12,34 +13,48 @@ class SerialRepository implements IAcquisitionDeviceRepository {
UsbDevice _selectedDevice;
UsbPort _serialPort;
StreamSubscription _inputStreamSubscription;
final List<AcquisitionDevice> _acquisitionDevicePersistency = [];
final List<UsbDevice> _serialDevices = [];
final streamController = StreamController<List<AcquisitionDevice>>();
StreamSubscription _usbEventSubscription;
final Map _serialDevices = <String, UsbDevice>{};
final streamController = StreamController<AcquisitionDevice>();

@override
void initializeRepository() {
_acquisitionDevicePersistency.clear();
Stream<AcquisitionDevice> scan() {
_serialDevices.clear();
UsbSerial.listDevices().then((devices) => addDevices(devices));
_usbEventSubscription ??= UsbSerial.usbEventStream.listen((event) {
if (event.event == UsbEvent.ACTION_USB_ATTACHED) {
_addDevices([event.device]);
}
});

UsbSerial.listDevices().then((devices) => _addDevices(devices));

return streamController.stream;
}

void addDevices(List<UsbDevice> serialDevices) {
@override
void pauseScan() {}

void _addDevices(List<UsbDevice> serialDevices) {
for (var serialDevice in serialDevices) {
if (_serialDevices.containsKey(serialDevice.deviceId.toString())) {
continue;
}

var device = AcquisitionDevice(
UniqueId.from(serialDevice.deviceId.toString()),
serialDevice.productName);
serialDevice.productName,
DeviceType.serial);

streamController.add(device);

_acquisitionDevicePersistency.add(device);
_serialDevices.add(serialDevice);
_serialDevices[serialDevice.deviceId.toString()] = serialDevice;
}
streamController.add(_acquisitionDevicePersistency);
}

@override
Future<void> connect(
AcquisitionDevice device, Function(bool, Exception) callback) async {
_selectedDevice =
_serialDevices[_acquisitionDevicePersistency.indexOf(device)];
_selectedDevice = _serialDevices[device.id.toString()];
_serialPort = await _selectedDevice.create();
var openSuccessful = await _serialPort.open();

Expand Down Expand Up @@ -100,7 +115,4 @@ class SerialRepository implements IAcquisitionDeviceRepository {
Future<void> stopDataStream() async {
await _serialPort.write(Uint8List.fromList(STOP_STREAM_CHAR.codeUnits));
}

@override
Stream<List<AcquisitionDevice>> watch() => streamController.stream;
}
Loading