Last active
January 31, 2020 14:11
-
-
Save drewandre/4c865d35e51fd6567d3fdf66c7eec28c to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
export class App extends Component { | |
constructor(props) { | |
super(props) | |
this.BLEManager = new BleManager({ | |
restoreStateIdentifier: 'bleManagerRestoredState', | |
restoreStateFunction: bleRestoredState => this.handleBLEManagerStateRestoration(bleRestoredState) | |
}) | |
this.BLEManager.setLogLevel(LogLevel.Verbose) | |
this.BLEManager.onDeviceDisconnected(() => console.log('hey, device disconnected')) | |
this.props.actions.saveBLEManager(this.BLEManager) | |
} | |
handleBLEManagerStateRestoration = state => { | |
console.log('BLE manager state restoration', state) | |
state && this.connectToBLEDevice(state.connectedPeripherals[0]) | |
} | |
componentDidMount() { | |
this.initializeBluetooth() | |
} | |
componentWillUnmount() { | |
this.characteristicListener.remove() | |
this.subscription.remove() | |
this.BLEManager.detroy() | |
} | |
initializeBluetooth = () => { | |
this.props.actions.resetBLERequests() | |
this.subscription = this.BLEManager.onStateChange(state => { | |
this.props.actions.setBluetoothManagerState(state) | |
if (state === 'PoweredOn') this.beginBLEScan() | |
}, true) | |
} | |
beginBLEScan = () => { | |
this.props.actions.setBleDeviceConnecting(true) | |
this.BLEManager.startDeviceScan(null, null, async (error, device) => { | |
if (error /* && error === 'Error: BluetoothLE is powered off' */) { | |
console.warn('Bluetooth scan error', error) | |
return this.props.actions.setBluetoothError(error) | |
} | |
if (POSSIBLE_DEVICE_NAMES.includes(device.name)) { | |
this.BLEManager.stopDeviceScan() | |
this.connectToBLEDevice(device) | |
} | |
}) | |
} | |
connectToBLEDevice = async device => { | |
console.log('Connecting to BLE device') | |
// Connect to our BLE device and save it to redux state | |
let connectedBLEDevice = await device.connect() | |
connectedBLEDevice.onDisconnected(this.handleBLEDeviceDisconnect) | |
this.props.actions.setConnectedBLEDevice(connectedBLEDevice) | |
this.props.actions.setConnectedBLEDeviceStatus(true) | |
// Discover all services and characteristics of our BLE device | |
await connectedBLEDevice.discoverAllServicesAndCharacteristics() | |
// Save all BLE device services to state | |
let connectedBLEDeviceServices = await connectedBLEDevice.services() | |
connectedBLEDeviceServices = connectedBLEDeviceServices.map(service => new Service(service, this.BLEManager)) | |
this.props.actions.setConnectedBLEDeviceServices(connectedBLEDeviceServices) | |
// Save all BLE device characteristics to state | |
let connectedBLEDeviceCharacteristics = await connectedBLEDeviceServices[0].characteristics() | |
connectedBLEDeviceCharacteristics = connectedBLEDeviceCharacteristics.map(characteristic => new Characteristic(characteristic, this.BLEManager)) | |
this.props.actions.setConnectedBLEDeviceCharacteristics(connectedBLEDeviceCharacteristics) | |
// Handle a base64 encoded message from our BLE device's writable characteristic | |
this.characteristicWithResponseListener = connectedBLEDeviceCharacteristics[0].monitor(this.handleCharacteristicWithResponse) | |
this.characteristicWithoutResponseListener = connectedBLEDeviceCharacteristics[1].monitor(this.handleCharacteristicWithoutResponse) | |
// Send a base64 encoded message to our BLE device's writable characteristic | |
this.props.actions.writeWithResponseToBLEDevice(`Hello from ${Platform.OS === 'ios' ? 'iPhone' : 'Android'}!`) | |
} | |
handleCharacteristicWithResponse = (error, characteristic) => { | |
if (error && error.code !== 201) { // 201 means device was disconnected | |
console.warn('BLE receive error', error) | |
this.handleBLEDeviceDisconnect(); | |
return this.props.actions.setBluetoothError(error) | |
} | |
// Read our BLE device's writable characteristic's base64 encoded value | |
let response = JSON.parse(base64.decode(characteristic.value)) | |
if (response.ok) { | |
this.handleBLEResponse(response, true) | |
} | |
this.props.actions.concatBLEWriteWithResponseResponse(response.value) | |
} | |
handleCharacteristicWithoutResponse = (error, characteristic) => { | |
if (error && error.code !== 201) { // 201 means device was disconnected | |
console.warn('BLE receive error', error) | |
this.handleBLEDeviceDisconnect(); | |
return this.props.actions.setBluetoothError(error) | |
} | |
// Read our BLE device's writable characteristic's base64 encoded value | |
let response = JSON.parse(base64.decode(characteristic.value)) | |
if (response.ok) { | |
this.handleBLEResponse(response, false) | |
} | |
this.props.actions.concatBLEWriteWithoutResponseResponse(response.value) | |
} | |
handleBLEDeviceDisconnect = () => { | |
console.warn("BLE device disconnected! Resetting bluetooth state and restarting scan.") | |
this.characteristicWithResponseListener.remove() | |
this.characteristicWithoutResponseListener.remove() | |
this.props.actions.resetBLEState() | |
this.beginBLEScan() | |
} | |
handleBLEResponse = (response, withResponse) => { | |
switch (response.type) { | |
default: | |
return console.log(`👋🏻 from BLE device with${!withResponse ? 'out' : ''} response:`, response) | |
} | |
} | |
render() { | |
return ( | |
<View style={{ flex: 1, backgroundColor: Colors.blurredBlack }}> | |
<Header /> | |
<AppNavigator /> | |
</View> | |
) | |
} | |
} | |
const mapStateToProps = state => ({ | |
bluetooth: state.bluetooth | |
}) | |
const mapDispatchToProps = dispatch => { | |
return { | |
actions: bindActionCreators({ | |
resolveBLERequest, | |
resetBLEState, | |
resetBLERequests, | |
saveBLEManager, | |
writeWithResponseToBLEDevice, | |
writeWithoutResponseToBLEDevice, | |
setBluetoothError, | |
concatBLEWriteWithResponseCommand, | |
concatBLEWriteWithoutResponseCommand, | |
concatBLEWriteWithResponseResponse, | |
concatBLEWriteWithoutResponseResponse, | |
setBleDeviceConnecting, | |
setConnectedBLEDevice, | |
setConnectedBLEDeviceStatus, | |
setConnectedBLEDeviceServices, | |
setConnectedBLEDeviceCharacteristics, | |
setBluetoothManagerState, | |
}, dispatch) | |
} | |
} | |
export default connect(mapStateToProps, mapDispatchToProps)(App) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment