Skip to content

Commit

Permalink
React: Finding device from list on application
Browse files Browse the repository at this point in the history
  • Loading branch information
cjoshmartin committed May 23, 2024
1 parent 6a3ba65 commit e1d3389
Showing 1 changed file with 91 additions and 24 deletions.
115 changes: 91 additions & 24 deletions App.tsx
Original file line number Diff line number Diff line change
@@ -1,20 +1,30 @@
import { StatusBar } from 'expo-status-bar';
import { useEffect, useState } from 'react';
import { Button, Platform, Text, View } from 'react-native';
import { useEffect, useRef, useState } from 'react';
import {
Button,
Platform,
Pressable,
SafeAreaView,
ScrollView,
Text,
View,
} from "react-native";
import { BleManager, Device } from 'react-native-ble-plx';
import { useAndroidPermissions } from './useAndroidPermissions';
import { atob, btoa } from "react-native-quick-base64";

const bleManager = new BleManager();

const DEVICE_NAME = "MyESP32";
const SERVICE_UUID = "ab49b033-1163-48db-931c-9c2a3002ee1d";
const STEPCOUNT_CHARACTERISTIC_UUID = "fbb6411e-26a7-44fb-b7a3-a343e2b011fe";
const HEARTRATE_CHARACTERISTIC_UUID = "c58b67c8-f685-40d2-af4c-84bcdaf3b22e";

export default function App() {
const [hasPermissions, setHasPermissions] = useState<boolean>(Platform.OS == 'ios');
const [waitingPerm, grantedPerm] = useAndroidPermissions();
const [devices, setDevices] = useState({});
const devicesRef = useRef({});
const devicesRefreshIntervalRef = useRef(0);

const [connectionStatus, setConnectionStatus] = useState("Searching...");
const [isConnected, setIsConnected] = useState<boolean>(false);
Expand Down Expand Up @@ -43,31 +53,48 @@ export default function App() {
}, [grantedPerm])

useEffect(() => {
if(hasPermissions){
if(hasPermissions && !isConnected){
searchAndConnectToDevice();
}
}, [hasPermissions]);
}, [hasPermissions, isConnected]);



const searchAndConnectToDevice = () => {
bleManager.startDeviceScan([], {allowDuplicates: false}, (error, device) => {

const searchAndConnectToDevice = () =>
bleManager.startDeviceScan(null, null, (error, device) => {
if (error) {
console.error(error);
setIsConnected(false);
setConnectionStatus("Error searching for devices");
return;
}
if (device?.name === DEVICE_NAME) {
bleManager.stopDeviceScan();
setConnectionStatus("Connecting...");
connectToDevice(device);
if (device?.name){
devicesRef.current
if(!devicesRef.current) {
devicesRef.current = {};
}
else {
//@ts-ignore
devicesRef.current[device.name] = device
}
}
});



const id = setInterval(() => {
console.log('refreshing list to be: ', Object.keys(devicesRef?.current))
setDevices(devicesRef?.current);
}, 3000)
//@ts-ignore
devicesRefreshIntervalRef.current = id;
}

const connectToDevice = async (device: Device) => {
bleManager.stopDeviceScan();
clearInterval(devicesRefreshIntervalRef.current);
devicesRefreshIntervalRef.current = 0;
try {
const _device = await device.connect();
const _device = await bleManager.connectToDevice(device.id, undefined);
// require to make all services and Characteristics accessable
await _device.discoverAllServicesAndCharacteristics();
setConnectionStatus("Connected");
Expand All @@ -80,8 +107,6 @@ export default function App() {
}
};



useEffect(() => {
if (!device) {
return;
Expand Down Expand Up @@ -135,6 +160,30 @@ export default function App() {
return () => sub.remove()
}, [device])

function Item (props: Device){
return (
<Pressable key={props.id}
onPress={() =>{
setConnectionStatus("Connecting...");
connectToDevice(props);
}}
style={{
backgroundColor: '#2596be',
padding: 16,
marginBottom: 10,
borderRadius: 20
}}
>
<Text
style={{
color: 'white',
fontWeight: '500',
fontSize: 16
}}
>{props.name} // {props.rssi}</Text>
</Pressable>
);
}

return (
<View style={{ flex: 1, alignItems: "center", justifyContent: "center" }}>
Expand All @@ -143,21 +192,39 @@ export default function App() {
<Text>Looks like you have not enabled Permission for BLE</Text>
</View>
)}
{hasPermissions && (
{hasPermissions && !isConnected && (
<SafeAreaView
style={{
flex: 1,
//@ts-ignore
marginTop: 50,
}}
>
<Text style={{ fontWeight: "600", fontSize: 24, marginBottom: 14 }}>
Device connection list
</Text>
<ScrollView>
{Object.values(devices)
//@ts-ignore
.sort((a, b) => Number(b.rssi) - Number(a.rssi))
.filter((value, i) => i < 20)
.map((item: any) => (
<Item key={item.id + (item.rssi ?? "")} {...item} />
))}
</ScrollView>
</SafeAreaView>
)}
{hasPermissions && isConnected && (
<View>
<Text>BLE Premissions enabled!</Text>
<Text>The connection status is: {connectionStatus}</Text>
<Button
disabled={!isConnected}
onPress={() => {}}
title={`The button is ${isConnected ? "enabled" : "disabled"}`}
/>
<Button onPress={() => {}} title={`The button is enabled`} />

<View style={{margin: 10}}>
<View style={{ margin: 10 }}>
<Text>The current Step count is: {stepCount}</Text>
</View>

<View style={{margin: 10}}>
<View style={{ margin: 10 }}>
<Text style={{ fontWeight: "500", margin: 5 }}>
Heart Rate value is: {heartRate}
</Text>
Expand Down

0 comments on commit e1d3389

Please sign in to comment.