Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Device List #18

Closed
wants to merge 13 commits into from
Closed
84 changes: 69 additions & 15 deletions components/Initiate.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,10 @@ import {
Text,
Image,
Animated,
ListView,
StyleSheet,
NativeModules,
NativeEventEmitter,
TouchableHighlight,
} from 'react-native';

Expand Down Expand Up @@ -38,14 +40,27 @@ const styles = StyleSheet.create({
fontWeight: 'bold',
alignSelf: 'center',
},
list: {
marginTop: -200,
},
listItem: {
paddingTop: 10,
paddingBottom: 20,
borderBottomWidth: 1,
borderBottomColor: 'black',
},
listItemText: {
fontSize: 12,
},
});

class Initiate extends Component {
constructor() {
super();

this.state = {
connected: false,
devices: false,
dataSource: null,
logoAnimValue: 300,
logoAnim: new Animated.Value(300),
buttonAnim: new Animated.ValueXY(),
Expand All @@ -54,6 +69,8 @@ class Initiate extends Component {
this.initiateConnect = this.initiateConnect.bind(this);
this.connectAnimation = this.connectAnimation.bind(this);
this.buttonEnterAnimation = this.buttonEnterAnimation.bind(this);
this.renderRowData = this.renderRowData.bind(this);
this.metaWearCallback = this.metaWearCallback.bind(this);
}

componentDidMount() {
Expand All @@ -62,35 +79,40 @@ class Initiate extends Component {

initiateConnect() {
this.connectAnimation();

this.state.logoAnim.addListener((value) => {
this.setState({
logoAnimValue: value.value,
});
const listenToDevices = new NativeEventEmitter(NativeModules.MetaWearAPI);
MetaWearAPI.initiateConnection(this.metaWearCallback);
this.state.buttonAnim.addListener((value) => {
if (value.y === -225) {
this.setState({
devices: true,
});
}
});

MetaWearAPI.searchForMetaWear(() => {
listenToDevices.addListener('Scan', (collection) => {
const ds = new ListView.DataSource({ rowHasChanged: (r1, r2) => r1 !== r2 });
this.setState({
connected: true,
}, () => {
this.props.navigator.push({
name: 'main',
component: Main,
passProps: { MetaWearAPI },
});
dataSource: ds.cloneWithRows(collection),
});
});
}

connectAnimation() {
const context = this;

Animated.sequence([
Animated.delay(200),
Animated.timing(
context.state.logoAnim,
{ toValue: 0 }),
]).start();

Animated.sequence([
Animated.spring(this.state.buttonAnim, {
tension: 5,
friction: 2,
toValue: { x: 0, y: -225 },
}),
]).start();
}

buttonEnterAnimation() {
Expand All @@ -103,6 +125,30 @@ class Initiate extends Component {
]).start();
}

metaWearCallback() {
this.props.navigator.push({
name: 'main',
component: Main,
passProps: { MetaWearAPI },
});
}

connectToMetaWear(id) {
MetaWearAPI.connectToMetaWear(id, this.metaWearCallback);
}

renderRowData(rowData) {
return (
<TouchableHighlight onPress={() => { this.connectToMetaWear(rowData.id); }}>
<View style={styles.listItem}>
<Text style={styles.listItemText}>Name: {rowData.name}</Text>
<Text style={styles.listItemText}>RSSI: {rowData.RSSI}</Text>
<Text style={styles.listItemText}>Identifier: {rowData.id}</Text>
</View>
</TouchableHighlight>
);
}

render() {
const logoDimensions = {
height: this.state.logoAnim,
Expand All @@ -117,6 +163,14 @@ class Initiate extends Component {
<Text style={styles.buttonText}>CONNECT</Text>
</TouchableHighlight>
</Animated.View>
{this.state.devices ?
<ListView
style={styles.list}
dataSource={this.state.dataSource}
renderRow={this.renderRowData}
/> :
<View />
}
</View>
);
}
Expand Down
24 changes: 11 additions & 13 deletions components/Posture.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ import {
View,
StyleSheet,
NativeModules,
NativeAppEventEmitter,
NativeEventEmitter,
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Do you know what's the difference between NativeAppEventEmitter and NativeEventEmitter? How come we use one over the other?

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Yup! Before, when we were using NativeAppEventEmitter (the docs told us to do this), Xcode had a warning that said that what we were using was deprecated. I found this: facebook/react-native#8714.

} from 'react-native';

const MetaWearAPI = NativeModules.MetaWearAPI;
Expand Down Expand Up @@ -35,20 +35,18 @@ class Posture extends Component {
}

componentWillMount() {
const context = this;
this.listenToTilt = new NativeEventEmitter(NativeModules.MetaWearAPI);

this.listenToTilt = NativeAppEventEmitter.addListener(
'Tilt', (event) => {
let tiltDirection = 'forward';
if (event.tilt < 0) {
tiltDirection = 'backward';
}
context.setState({
tiltDirection,
tilt: Math.abs(event.tilt),
});
this.listenToTilt.addListener('Tilt', (event) => {
let tiltDirection = 'forward';
if (event < 0) {
tiltDirection = 'backward';
}
);
this.setState({
tiltDirection,
tilt: Math.abs(event),
});
});
}

componentWillUnmount() {
Expand Down
7 changes: 7 additions & 0 deletions ios/backbone.xcodeproj/project.pbxproj
Original file line number Diff line number Diff line change
Expand Up @@ -433,6 +433,7 @@
TestTargetID = 13B07F861A680F5B00A75B9A;
};
13B07F861A680F5B00A75B9A = {
DevelopmentTeam = FK7Z2C5Q2Q;
SystemCapabilities = {
com.apple.BackgroundModes = {
enabled = 1;
Expand Down Expand Up @@ -791,6 +792,8 @@
baseConfigurationReference = 3CDC5737A23EFE2050430BB6 /* Pods-backbone.debug.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
DEAD_CODE_STRIPPING = NO;
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
Expand All @@ -811,6 +814,7 @@
"$(inherited)",
);
PRODUCT_NAME = backbone;
PROVISIONING_PROFILE = "";
};
name = Debug;
};
Expand All @@ -819,6 +823,8 @@
baseConfigurationReference = FA82F51D47DD3D3714546443 /* Pods-backbone.release.xcconfig */;
buildSettings = {
ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon;
CODE_SIGN_IDENTITY = "iPhone Developer";
"CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer";
ENABLE_BITCODE = NO;
FRAMEWORK_SEARCH_PATHS = (
"$(inherited)",
Expand All @@ -838,6 +844,7 @@
"$(inherited)",
);
PRODUCT_NAME = backbone;
PROVISIONING_PROFILE = "";
};
name = Release;
};
Expand Down
10 changes: 6 additions & 4 deletions ios/backbone/MetaWearAPI.h
Original file line number Diff line number Diff line change
@@ -1,16 +1,18 @@
#import "RCTEventEmitter.h"
#import "RCTBridgeModule.h"
#import <MetaWear/MetaWear.h>

@interface MetaWearAPI : NSObject <RCTBridgeModule>
@property (nonatomic, strong) RCTBridge *bridge;
@interface MetaWearAPI : RCTEventEmitter <RCTBridgeModule>
@property MBLMetaWear *device;
@property MBLMetaWearManager * manager;
@property MBLAccelerometerMMA8452Q *accelerometer;
@property MBLAccelerometer *accelerometer;
@property NSMutableDictionary *deviceCollection;
@property BOOL calibrated;
@property float controlAngle;
@property float currentAngle;
@property float tilt;
- (void) connectToMetaWear :(MBLMetaWear *)device :(RCTResponseSenderBlock)callback;
- (void) scanForMetaWear;
- (void) handleTilt;
- (void) tiltEventEmitter;
- (void) scanEventEmitter:(NSMutableArray *)collection;
@end
68 changes: 42 additions & 26 deletions ios/backbone/MetaWearAPI.m
Original file line number Diff line number Diff line change
@@ -1,41 +1,49 @@
#import "MetaWearAPI.h"
#import "RCTBridge.h"
#import "RCTEventDispatcher.h"
#define RADIANS_TO_DEGREES(radians) ((radians) * (180.0 / M_PI))

@implementation MetaWearAPI

@synthesize bridge = _bridge;

RCT_EXPORT_MODULE();

RCT_EXPORT_METHOD(searchForMetaWear: (RCTResponseSenderBlock)callback) {

RCT_EXPORT_METHOD(initiateConnection:(RCTResponseSenderBlock)callback) {
self.manager = [MBLMetaWearManager sharedManager];

[[self.manager retrieveSavedMetaWearsAsync] continueWithBlock:^id(BFTask *task) {
if ([task.result count]) {
if (![task.result count]) {
MBLMetaWear *device = task.result[0];
self.device = device;
[self connectToMetaWear:self.device:callback];
} else {
[self.manager startScanForMetaWearsAllowDuplicates:NO handler:^(NSArray *array) {
self.device = 0;

for (MBLMetaWear *device in array) {
if (!self.device || self.device.discoveryTimeRSSI.integerValue > device.discoveryTimeRSSI.integerValue) {
self.device = device;
}
[device connectWithHandler:^(NSError *error) {
if (device.state == MBLConnectionStateConnected) {
[device.led flashLEDColorAsync:[UIColor greenColor] withIntensity:1.0 numberOfFlashes:1];
callback(@[[NSNull null], @YES]);
}
[self connectToMetaWear:self.device:callback];
[self.device rememberDevice];
}];
} else {
[self scanForMetaWear];
}
return nil;
}];
}

- (void)connectToMetaWear :(MBLMetaWear *)device :(RCTResponseSenderBlock)callback {
- (void)scanForMetaWear {
self.deviceCollection = [[NSMutableDictionary alloc]initWithCapacity:10];
[self.manager startScanForMetaWearsAllowDuplicates:YES handler:^(NSArray * _Nonnull array) {
NSMutableArray *deviceDetailsCollection = [NSMutableArray new];
for (MBLMetaWear *device in array) {
NSString *idString = [device.identifier UUIDString];
self.deviceCollection[idString] = device;
NSDictionary *deviceDetails = @{
@"name": device.name,
@"RSSI": device.discoveryTimeRSSI,
@"id": idString
};
[deviceDetailsCollection addObject:deviceDetails];
}
[self scanEventEmitter:deviceDetailsCollection];
}];
}

RCT_EXPORT_METHOD(connectToMetaWear:(NSString *)deviceID reactCallback:(RCTResponseSenderBlock)callback) {
[self.manager stopScanForMetaWears];
self.device = self.deviceCollection[deviceID];
[self.device connectWithHandler:^(NSError *error) {
if (self.device.state == MBLConnectionStateConnected) {
[self.device.led flashLEDColorAsync:[UIColor greenColor] withIntensity:1.0 numberOfFlashes:1];
Expand All @@ -45,13 +53,13 @@ - (void)connectToMetaWear :(MBLMetaWear *)device :(RCTResponseSenderBlock)callba
}

RCT_EXPORT_METHOD(startPostureMonitoring) {
self.accelerometer = (MBLAccelerometerMMA8452Q *)self.device.accelerometer;
self.accelerometer = (MBLAccelerometer *)self.device.accelerometer;
self.accelerometer.sampleFrequency = 1.56;

self.calibrated = false;

[self.accelerometer.dataReadyEvent startNotificationsWithHandlerAsync:^(MBLAccelerometerData * _Nullable obj, NSError * _Nullable error) {
self.currentAngle = RADIANS_TO_DEGREES(atan(obj.z / obj.x));
self.currentAngle = RADIANS_TO_DEGREES(atan(obj.z / obj.x));
if (!self.calibrated) {
float xControl = obj.x;
float zControl = obj.z;
Expand All @@ -75,13 +83,21 @@ - (void)connectToMetaWear :(MBLMetaWear *)device :(RCTResponseSenderBlock)callba
}

- (void) handleTilt {
if (self.tilt > 10) {
[self.device.led flashLEDColorAsync:[UIColor greenColor] withIntensity:1.0 numberOfFlashes:5];
if (self.tilt > 20) {
[self.device.led flashLEDColorAsync:[UIColor greenColor] withIntensity:1.0 numberOfFlashes:1];
}
}

- (NSArray<NSString *> *)supportedEvents {
return @[@"Tilt", @"Scan"];
}

- (void) tiltEventEmitter {
[self.bridge.eventDispatcher sendAppEventWithName:@"Tilt" body: @{@"tilt": [NSNumber numberWithFloat:self.tilt]}];
[self sendEventWithName:@"Tilt" body:@{@"tilt":[NSNumber numberWithFloat:self.tilt]}];
}

- (void) scanEventEmitter:(NSMutableArray *)collection {
[self sendEventWithName:@"Scan" body:collection];
}

//RCT_EXPORT_METHOD(startPostureMonitoring) {
Expand Down