Флаттер, подключающийся к нескольким устройствам BLE Синхронно - PullRequest
0 голосов
/ 13 февраля 2019

Я использую flutter для работы над приложением Bluetooth с низким энергопотреблением через библиотеку flutterBlue, в которой мы потенциально можем подключаться к нескольким периферийным устройствам одновременно.Я могу подключаться к нескольким периферийным устройствам, если я подключаюсь к ним индивидуально и посылаю команды всем им одновременно.Для управления состоянием мой BluetoothHelper является моделью для моей модели ScopedModel.

class BluetoothHelper extends Model {

  bool isProcessing = false; 
  int val = 0;

  FlutterBlue flutterBlue = FlutterBlue.instance; //bluetooth library instance

  StreamSubscription scanSubscription;
  Map<DeviceIdentifier, ScanResult> scanResults = new Map();

  /// State
  StreamSubscription stateSubscription;
  BluetoothState state = BluetoothState.unknown;

  /// Device
  List<BluetoothDevice> devicesList = new List(); //todo

  bool get isConnected => (deviceList.size != 0);
  StreamSubscription deviceConnection;
  StreamSubscription deviceStateSubscription;
  List<BluetoothService> services = new List();
  Map<Guid, StreamSubscription> valueChangedSubscriptions = {};
  BluetoothDeviceState deviceState = BluetoothDeviceState.disconnected;

  Future startScan(String uuid) async {
    isProcessing = true;
    if (val == 0) {
      Future.delayed(Duration(milliseconds: 25), () => scanAndConnect(uuid));
      val++;
    } else {
      Future.delayed(Duration(seconds: 4), () => scanAndConnect(uuid));
    }
  }

  scanAndConnect(String uuid){
    scanSubscription =
        flutterBlue.scan(timeout: const Duration(seconds: 120), withServices: [
          //new Guid('FB755D40-8DE5-481E-A369-21C0B3F39664')]
        ]).listen((scanResult) {
          if (scanResult.device.id.toString() == uuid) {
            scanResults[scanResult.device.id] = scanResult;

            print("found! Attempting to connect" + scanResult.device.id.toString());
            device = scanResult.device;

            //connect(device);
            connect(device);
          }
        }, onDone: stopScan);
  }

  Future connect(BluetoothDevice d) {

    deviceConnection = flutterBlue.connect(d).listen(
          null,
        );

    deviceStateSubscription = d.onStateChanged().listen((s) {
      if (s == BluetoothDeviceState.connected) {
        stopScan();
        d.discoverServices().then((s) {
          print("connected to ${device.id.toString()}");
          services = s;
          services.forEach((service) {
            var characteristics = service.characteristics;
            for (BluetoothCharacteristic c in characteristics) {
              if (c.uuid.toString() == '') {//we look for the uuid we want to write to
                String handshakeValue ; //value is initiliazed here in code
                List<int> bytes = utf8.encode(handshakeValue);
                d.writeCharacteristic(c, bytes,
                    type: CharacteristicWriteType.withResponse);
                     devicesList.add(d);
              }
            }
          });
        });
      }
    });

  }
}

Я пытаюсь закинуть все периферийные уникальные идентификаторы (UID) и затем программно подключить их один за другим.

Это не сработало.Это всегда будет заканчиваться подключением к самому последнему периферийному устройству.Похоже, что экземпляр flutterblue может сканировать только один uid за раз, и если он получает другой запрос, он немедленно отбрасывает последний запрос и переходит на новый.

Я применил эту же логику к соединениюиндивидуальная периферийная логика, в которой я бы сразу подключал одну периферию и вторую, и она соединялась со второй.(В настоящее время я не блокирую пользовательский интерфейс или что-либо еще во время процесса подключения) Мне нужно подождать, пока первое периферийное устройство не будет подключено, прежде чем перейти к следующему.

Приведенный выше код - единственный способ получить мои периферийные устройства, но с этим кодом возникают огромные проблемы.В настоящее время он может подключаться только к 2 устройствам.Он использует задержки вместо обратных вызовов для установления соединения, давая достаточно времени для сканирования и соединения, прежде чем переходить на второе периферийное устройство.

Моим первым инстинктом было преобразовать методы startScan и connect в асинхронные методы, ноэто работает не так хорошо, как я надеюсь.

{ожидание соединения (устройство);} => дает «встроенный Идентификатор« await »нельзя использовать как тип. Я мог бы просто неправильно настроить асинхронные.

Я искал альтернативы и натолкнулся на Completers and IsolatesЯ не уверен, насколько это может быть актуально.

СТОРОНА ПЕРЕДАЧИ:

У меня установлен следующий метод для нажатия кнопки, обернутой в потомка модели с областью действия.надежно загружайте список периферийных устройств с помощью нескольких идентификаторов, а затем подключайтесь к ним один за другим.

connectAllPeripherals(BluetoothHelper model, List<String> peripheralUIDs) {
    for(var uuid in peripheralUIDs) { //list of strings containing the uuids for the peripherals I want to connect to
      model.startScan(uuid);
    }
}

1 Ответ

0 голосов
/ 08 мая 2019

Не знаю, является ли эта точка все еще проблемой.

Предполагается, что ваша проблема не была исправлена.Я думаю, что проблема, с которой вы столкнулись, заключается в том, что вы пытаетесь поддерживать соединения внутри Flutter (а не просто подключаете несколько устройств и позволяете Flutter_Blue / аппаратному обеспечению управлять соединениями).

Я успешно подключился к нескольким устройствам;после того, как вы настроите экземпляр, поддерживающий список нескольких атрибутов устройства.

т.е. я создал класс ble-device, который содержал каждое из следующего:

StreamSubscription deviceConnection;
StreamSubscription deviceStateSubscription;
List<BluetoothService> services = new List();
Map<Guid, StreamSubscription> valueChangedSubscriptions = {};
BluetoothDeviceState deviceState = BluetoothDeviceState.disconnected;

Поддержание LinkedHashMap сНовый объект, инициализированный из класса выше для каждого подключенного устройства, работает хорошо.

Кроме этого - Flutter_Blue будет разрешать только 1 одновременный вызов запроса за раз (как чтение характеристики), но вы можете довольно легко сложить их с помощью

 await

с учетом вышесказанного, я могу опрашивать несколько устройств в течение нескольких миллисекунд друг от друга.

Не знаю, поможет ли это - но, если повезет, кто-то тоженатолкнувшись на мою проблему, ударит и сэкономит время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...