Skip to content

Commit

Permalink
Added scan stop, color to indicate beacon status
Browse files Browse the repository at this point in the history
- The color of beacon cards will now change depending
on whether or not they are within range
- Refactored scan button
- Added ability to stop scanning for BLE Beacons
  • Loading branch information
the-bay-kay committed Mar 23, 2024
1 parent 678d1c3 commit a11b6c1
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 36 deletions.
3 changes: 2 additions & 1 deletion www/i18n/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -238,7 +238,8 @@
},
"scan": {
"for-ble": "Scan for BLE Beacons",
"for-bluetooth": "Scan for Classic Devices"
"for-bluetooth": "Scan for Classic Devices",
"stop": "Stop Scanning"
},
"is-scanning": "Scanning...",
"device-info": {
Expand Down
13 changes: 10 additions & 3 deletions www/js/bluetooth/BluetoothCard.tsx
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import React from 'react';
import { Card, List } from 'react-native-paper';
import { Card, List, useTheme } from 'react-native-paper';
import { StyleSheet } from 'react-native';

type Props = any;
const BluetoothCard = ({ device, isClassic }: Props) => {
const BluetoothCard = ({ device, isClassic, isScanningBLE }: Props) => {
const { colors } = useTheme();
if (isClassic) {
return (
<Card style={cardStyles.card}>
Expand All @@ -16,8 +17,14 @@ const BluetoothCard = ({ device, isClassic }: Props) => {
</Card>
);
}

let bgColor = colors.onPrimary; // 'rgba(225,225,225,1)'
if (isScanningBLE) {
bgColor = device.in_range ? `rgba(200,250,200,1)` : `rgba(250,200,200,1)`;
}

return (
<Card style={cardStyles.card}>
<Card style={{ backgroundColor: bgColor, ...cardStyles.card }}>
<Card.Title
title={`Name: ${device.identifier}`}
titleVariant="titleLarge"
Expand Down
101 changes: 69 additions & 32 deletions www/js/bluetooth/BluetoothScanPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -37,8 +37,8 @@ const BluetoothScanPage = ({ ...props }: any) => {
in_range: false,
},
});

const [isScanningClassic, setIsScanningClassic] = useState(false);
const [isScanningBLE, setIsScanningBLE] = useState(false);
const [isClassic, setIsClassic] = useState(false);
const { colors } = useTheme();

Expand All @@ -49,8 +49,9 @@ const BluetoothScanPage = ({ ...props }: any) => {
...device,
}));
}

// Function to run Bluetooth Classic test and update logs
const runBluetoothClassicTest = async () => {
async function runBluetoothClassicTest() {
// Classic not currently supported on iOS
if (window['cordova'].platformId == 'ios') {
displayErrorMsg('Sorry, iOS is not supported!', 'OSError');
Expand All @@ -77,23 +78,22 @@ const BluetoothScanPage = ({ ...props }: any) => {
} finally {
setIsScanningClassic(false);
}
};

const runBLETest = async () => {
//await startBLEScanning();
BeaconMonitor(); // Will combine BeaconMonitor & StartBLE Scanning, if possible
};
}

function setRangeStatus(uuid: string, status: boolean) {
setSampleBLEDevices((prevDevices) => {
const newList = prevDevices;
newList[uuid].in_range = status;
return newList;
});
setSampleBLEDevices((prevDevices) => ({
...prevDevices,
[uuid]: {
...prevDevices[uuid],
in_range: status,
},
}));
}

// BLE LOGIC
const BeaconMonitor = () => {
async function startBeaconScanning() {
setIsScanningBLE(true);

let delegate = new window['cordova'].plugins.locationManager.Delegate();

delegate.didDetermineStateForRegion = function (pluginResult: BLEPluginCallback) {
Expand Down Expand Up @@ -147,7 +147,27 @@ const BluetoothScanPage = ({ ...props }: any) => {
})
.done();
});
};
}

async function stopBeaconScanning() {
setIsScanningBLE(false);

beaconsToArray().forEach((sampleBeacon: BLEBeaconDevice) => {
setRangeStatus(sampleBeacon.uuid, false); // "zero out" the beacons
const beaconRegion = new window['cordova'].plugins.locationManager.BeaconRegion(
sampleBeacon.identifier,
sampleBeacon.uuid,
sampleBeacon.major,
sampleBeacon.minor,
);
window['cordova'].plugins.locationManager
.stopMonitoringForRegion(beaconRegion)
.fail(function (e) {
logWarn(e);
})
.done();
});
}

const switchMode = () => {
setIsClassic(!isClassic);
Expand All @@ -172,13 +192,43 @@ const BluetoothScanPage = ({ ...props }: any) => {
<div>
{beaconsAsArray.map((beacon) => {
if (beacon) {
return <BluetoothCard device={beacon} />;
return <BluetoothCard device={beacon} isScanningBLE={isScanningBLE} />;
}
})}
</div>
);
};

const ScanButton = () => {
if (isClassic) {
return (
<View style={s.btnContainer}>
<Button
mode="elevated"
onPress={runBluetoothClassicTest}
textColor={isScanningClassic ? colors.onPrimary : colors.primary}
buttonColor={isScanningClassic ? colors.primary : colors.onPrimary}
style={s.btn}>
{isScanningClassic ? t('bluetooth.is-scanning') : t('bluetooth.scan.for-bluetooth')}
</Button>
</View>
);
}
// else, if BLE
return (
<View style={s.btnContainer}>
<Button
mode="elevated"
onPress={isScanningBLE ? stopBeaconScanning : startBeaconScanning}
textColor={isScanningBLE ? colors.onPrimary : colors.primary}
buttonColor={isScanningBLE ? colors.primary : colors.onPrimary}
style={s.btn}>
{isScanningBLE ? t('bluetooth.scan.stop') : t('bluetooth.scan.for-ble')}
</Button>
</View>
);
};

const BlueScanContent = () => (
<div style={{ height: '100%' }}>
<Appbar.Header
Expand All @@ -199,26 +249,13 @@ const BluetoothScanPage = ({ ...props }: any) => {
<Button
mode="elevated"
onPress={switchMode}
textColor={isClassic ? colors.onPrimary : colors.primary}
textColor={colors.primary}
style={s.btn}
buttonColor={isClassic ? colors.primary : colors.onPrimary}>
buttonColor={colors.onPrimary}>
{isClassic ? t('bluetooth.switch-to.ble') : t('bluetooth.switch-to.classic')}
</Button>
</View>
<View style={s.btnContainer}>
<Button
mode="elevated"
onPress={isClassic ? runBluetoothClassicTest : runBLETest}
textColor={isScanningClassic ? colors.onPrimary : colors.primary}
buttonColor={isScanningClassic ? colors.primary : colors.onPrimary}
style={s.btn}>
{isScanningClassic
? t('bluetooth.is-scanning')
: isClassic
? t('bluetooth.scan.for-bluetooth')
: t('bluetooth.scan.for-ble')}
</Button>
</View>
<ScanButton />
<BluetoothCardList devices={isClassic ? bluetoothClassicList : sampleBLEDevices} />
</div>
);
Expand Down

0 comments on commit a11b6c1

Please sign in to comment.