Objective
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
.
What is happening?
After the device connected I lost some values.
Important
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.
The sequence functions
toggleScanDevices()
Will push all devices to the bleDevices
state.
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(name)
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; };
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.
The log before connect
The log after connect
Device {overflowServiceUUIDs: null, solicitedServiceUUIDs: null, localName: null, isConnectable: null, txPowerLevel: null, …}overflowServiceUUIDs: nullsolicitedServiceUUIDs: nulllocalName: nullisConnectable: nulltxPowerLevel: nullserviceUUIDs: nullserviceData: nullmtu: nullname: "MLT-BT05"manufacturerData: nullrssi: nullid: "88:25:83:F0:30:BC"