连接蓝牙模块后丢失数据 [英] Losing data after connecting the bluetooth module

查看:99
本文介绍了连接蓝牙模块后丢失数据的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我试图在连接后从蓝牙设备返回数据,因为要使用读写功能,需要一些数据.示例数据名称,overflowServiceUUID,slicitedServiceUUID,mtu,rssi ... 等.因为如果我想读或写,我需要一些属性.我正在使用库 react-native-ble-plx .

I am trying to return data from the BlueTooth device after connected because to use the read and write function, need some data. Example data name, overflowServiceUUIDs, solicitedServiceUUIDs, mtu, rssi... and many others. Because if I want to read or write I need some attributes. I am using the library react-native-ble-plx.

连接设备后,我丢失了一些值.

After the device connected I lost some values.

type DeviceState = {
  connected: boolean;
  services: Service[];
  device: Device | null;
  characteristics: Record<string, Characteristic[]>;
};

const INITIAL_DEVICE_STATE = {
  connected: false,
  services: [],
  device: null,
  characteristics: {},
};

const [adapterState, setAdapterState] = useState(false);
const [bleDevices, setBleDevices] = useState<Device[]>([]);
const [isScanning, setIsScanning] = useState(false);
const [connectedDevice, setConnectedDevice] = useState<DeviceState>(
    INITIAL_DEVICE_STATE,
);

# The state isScaning is used to be if we are scanning devices.
# The connectedDevice state will be the connected device.

序列功能

toggleScanDevices()

将所有设备推到 bleDevices 状态.

  const toggleScanDevices = () => {
    setIsScanning(true);
    setBleDevices([]);

    bleManager.startDeviceScan(null, {}, (bleError, device) => {
      if (device && _.findIndex(bleDevices, { id: device.id }) < 0) {
        bleDevices.push(device);
        setBleDevices(bleDevices);
      }
    });

    setTimeout(() => {
      setIsScanning(false);
      bleManager.stopDeviceScan();
    }, 5000);
  };

toggleConnectDevice(device.name)

  const toggleConnectDevice = (name: string) => async () => {
    if (!connectedDevice.device) {
      await connectDevice(name);
    } else {
      const { device } = connectedDevice;

      if (!device) return;

      await device.cancelConnection();

      if (!(await device.isConnected())) {
        setConnectedDevice(INITIAL_DEVICE_STATE);
      }
    }
  };

connectDevice(名称)

  const connectDevice = async (name: string) => {
    let device = findDeviceWhereNameContains(name);

    if (device === null) {
      setConnectedDevice(INITIAL_DEVICE_STATE);
      return false;
    }

    let isConnected = await device.isConnected();

    if (!isConnected) {
      /* Testar aqui */
      device = await bleManager.connectToDevice(device.id);
      isConnected = await device.isConnected();
    }
    device = await device.discoverAllServicesAndCharacteristics();

    device.onDisconnected((error, device) => {
      setConnectedDevice(INITIAL_DEVICE_STATE);
    });

    const services = await device.services();
    const characteristics: Record<string, Characteristic[]> = {};
    const descriptors = {};

    _.forEach(services, async service => {
      const deviceCharacteristics = await device?.characteristicsForService(
        service.uuid,
      );
      characteristics[service.uuid] = deviceCharacteristics || [];
    });

    setConnectedDevice(state => ({
      ...state,
      services,
      characteristics,
      device,
    }));

    const newDevice = { ...connectedDevice, device };
    setConnectedDevice(newDevice);
    console.log('não atualizado', connectedDevice);
    console.log('novo valor', newDevice);
  };

findDeviceWhereNameContains(name)

  const findDeviceWhereNameContains = (name: string) => {
    const device = bleDevices.find(item => String(item.name).includes(name));
    if (device !== undefined) {
      return device;
    }
    return null;
  };

connectDevice 函数内部,我有一个 let设备,如果我记录此变量 device,则该设备会接收有关 findDeviceWhereNameContains 的值.我收到了很多非常重要的数据,但是我还没有连接.因此,当我在此处验证 if(!isConnected)时,我将进行连接,此后,如果再次登录 device 时,丢失了某些值.

Inside the connectDevice function I have a let device that receive the value about the findDeviceWhereNameContains, if I log this variable device I receive many data very important, but I'm not connected yet. So when I verify about the if (!isConnected) here I will connect, and after this, inside out this if when I log the device again I lost some values.

Device {overflowServiceUUIDs: null, solicitedServiceUUIDs: null, localName: null, isConnectable: null, txPowerLevel: null, …}
overflowServiceUUIDs: null
solicitedServiceUUIDs: null
localName: null
isConnectable: null
txPowerLevel: null
serviceUUIDs: null
serviceData: null
mtu: null
name: "MLT-BT05"
manufacturerData: null
rssi: null
id: "88:25:83:F0:30:BC"

推荐答案

检查正在使用的lib,替换您需要的值.由于它现在就可以正常工作,因此您可以复制将这些值删除之前将其保存到另一个对象

Checking the lib you're using, it creates another device object from the reponse it gets when calling the native module, it could be the case this new object comes with null values on those fields and replaces the values you need. Because it's just as it works by now, you could copy those values to another object before they get erased

import pick from 'lodash/pick';

const connectDevice = async (name: string) => {
    let device = findDeviceWhereNameContains(name);
    // according to the screenshot, the object still have the
    // information you want at this point
    
    // taking advantage taht you have lodash already you can use pick
    const valuesYouNeed = pick(device, ['serviceUUIDs', ...]);

    ...

    // here you merge them back with other device's attr that are present at this point
    const newDevice = { ...pick(device, ['connected', ...]), ...valuesYouNeed };
    setConnectedDevice(newDevice);
    console.log('não atualizado', connectedDevice);
    console.log('novo valor', newDevice);
  };

但是您要警惕,它们不会再次被替换.

But you have wary they don't get replaced again.

如果您认为这是 react-native-ble-plx 的错误行为,则可以使用 Device 构造函数中的更改打开PR,以免发生这种情况.

If you think this is a faulty behaviour of react-native-ble-plx you could open a PR with the changes in the Device constructor to avoid this happening.

由于您使用的是打字稿,因此您会对打字感到有些不满,您可以使用 react-native-ble-plx 设备类型和

Since you're using typescript, you'll have some complaints about typings, you could create a type from react-native-ble-plx device type and pick only the attributes part of it to omit methods and avoid storing complex object in your state.

import { Device } from 'react-native-ble-plx`;

type DeviceState = Pick<
    Device,
    | 'id'
    | 'name'
    | 'rssi'
    | 'mtu'
    | 'manufacturerData'
    | 'serviceData'
    | 'serviceUUIDs'
    | 'localName'
    | 'txPowerLevel'
    | 'solicitedServiceUUIDs'
    | 'isConnectable'
    | 'overflowServiceUUIDs'
  >

这篇关于连接蓝牙模块后丢失数据的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆