Page Menu
Home
c4science
Search
Configure Global Search
Log In
Files
F83491079
MetaMotionManager.java
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Award Token
Subscribers
None
File Metadata
Details
File Info
Storage
Attached
Created
Tue, Sep 17, 10:39
Size
22 KB
Mime Type
text/x-java
Expires
Thu, Sep 19, 10:39 (1 d, 23 h)
Engine
blob
Format
Raw Data
Handle
20847086
Attached To
R9555 Android app for multimodal data acquisition from wearables
MetaMotionManager.java
View Options
package
ch.epfl.esl.elevatedmonitor.Devices.MetaMotionR
;
import
android.bluetooth.BluetoothDevice
;
import
android.content.Context
;
import
android.os.Build
;
import
android.support.v4.util.Pair
;
import
android.util.Log
;
import
com.mbientlab.metawear.MetaWearBoard
;
import
com.mbientlab.metawear.Route
;
import
com.mbientlab.metawear.Subscriber
;
import
com.mbientlab.metawear.data.Quaternion
;
import
com.mbientlab.metawear.module.Settings
;
import
com.mbientlab.metawear.module.Timer
;
import
java.util.ArrayList
;
import
java.util.Arrays
;
import
bolts.Continuation
;
import
bolts.Task
;
import
ch.epfl.esl.elevatedmonitor.Devices.MetaMotionR.Sensors.SensorFusion
;
import
ch.epfl.esl.elevatedmonitor.Devices.MetaMotionR.Sensors.Temperature
;
import
ch.epfl.esl.elevatedmonitor.Interfaces.InterfaceManager
;
import
ch.epfl.esl.elevatedmonitor.ServiceManager
;
import
ch.epfl.esl.elevatedmonitor.SuperClasses.Device
;
import
ch.epfl.esl.elevatedmonitor.SuperClasses.Manager
;
public
class
MetaMotionManager
extends
Manager
implements
InterfaceManager
{
private
static
final
String
TAG
=
"MetaWear Man SQUINCI"
;
//--------- Flags
private
Boolean
scanAllowed
=
true
;
private
ArrayList
<
ConnBool
>
connectings
=
new
ArrayList
<>();
private
ArrayList
<
DisconBool
>
disconnectings
=
new
ArrayList
<>();
private
ArrayList
<
MetaWearBoard
>
boards
=
new
ArrayList
<>();
private
ArrayList
<
MetaWear
>
metaWears
=
new
ArrayList
<>();
private
ArrayList
<
Pair
<
String
,
Timer
.
ScheduledTask
>>
scheduledTasks
=
new
ArrayList
<>();
public
MetaMotionManager
(
Context
context
)
{
super
(
context
,
TAG
);
}
//--- Interface Manager
@Override
public
void
scan
()
{
if
(
scanAllowed
)
{
ServiceManager
.
scanBluetooth
();
}
}
private
class
ConnBool
{
private
String
id
;
private
Boolean
bool
;
ConnBool
(
String
id
,
Boolean
bool
){
this
.
id
=
id
;
this
.
bool
=
bool
;
}
Boolean
getBool
(){
return
bool
;
}
void
setBool
(
Boolean
bool
){
this
.
bool
=
bool
;
}
public
String
getId
(){
return
id
;
}
}
private
class
DisconBool
{
private
String
id
;
private
Boolean
bool
;
DisconBool
(
String
id
,
Boolean
bool
){
this
.
id
=
id
;
this
.
bool
=
bool
;
}
Boolean
getBool
(){
return
bool
;
}
void
setBool
(
Boolean
bool
){
this
.
bool
=
bool
;
}
public
String
getId
(){
return
id
;
}
}
@Override
public
void
isDevice
(
String
name
,
String
address
)
{
boolean
alreadyThere
=
false
;
ArrayList
<
String
>
deviceNames
=
new
ArrayList
<>(
Arrays
.
asList
(
"MetaWear 0"
,
"MetaWear 1"
,
"MetaWear 2"
));
for
(
Device
device
:
getScannedDevices
())
{
if
(
device
.
getId
().
equals
(
address
))
{
alreadyThere
=
true
;
}
deviceNames
.
remove
(
device
.
getName
());
}
if
(!
deviceNames
.
isEmpty
()
&&
!
alreadyThere
)
{
if
(
name
!=
null
&&
name
.
equals
(
MetaWear
.
NAME
))
{
Log
.
d
(
TAG
,
"found device: "
+
name
+
" "
+
address
);
MetaWear
metaWear
=
new
MetaWear
(
managerContext
,
deviceNames
.
get
(
0
),
address
);
Log
.
d
(
TAG
,
"Found this one: "
+
deviceNames
.
get
(
0
)
+
": "
+
address
);
addScannedDevice
(
metaWear
);
ServiceManager
.
startActionScanned
(
managerContext
);
connectings
.
add
(
new
ConnBool
(
address
,
false
));
disconnectings
.
add
(
new
DisconBool
(
address
,
false
));
}
}
}
@Override
public
void
stopScan
()
{
scanAllowed
=
false
;
ServiceManager
.
stopScanBluetooth
();
//Stop the process
Log
.
d
(
TAG
,
"Scan stopped"
);
}
private
void
connected
(
String
deviceID
)
{
for
(
ConnBool
conn
:
connectings
){
if
(
conn
.
getId
().
equals
(
deviceID
)){
conn
.
setBool
(
false
);
}
}
boolean
alreadyThere
=
false
;
for
(
Device
cd
:
getConnectedDevice
())
{
if
(
cd
.
getId
().
equals
(
deviceID
))
{
alreadyThere
=
true
;
}
}
if
(!
alreadyThere
)
{
for
(
Device
device
:
getScannedDevices
())
{
if
(
deviceID
.
equals
(
device
.
getId
()))
{
for
(
MetaWearBoard
board
:
boards
)
{
if
(
board
.
getMacAddress
().
equals
(
deviceID
))
{
stopScan
();
device
.
setConnected
(
true
);
MetaWear
metaWear
=
new
MetaWear
(
managerContext
,
device
.
getName
(),
device
.
getId
(),
board
);
metaWear
.
setConnected
(
true
);
metaWears
.
add
(
metaWear
);
addConnectedDevice
(
metaWear
);
//Insert into file memory connected device
// saveConnectedFile();
Log
.
d
(
TAG
,
"Device Connected"
);
// Notify the Service Manager that there is a new connection
ServiceManager
.
startActionConnected
(
managerContext
);
startStreaming
(
deviceID
);
configureBatteryRoute
(
deviceID
);
break
;
}
}
}
}
}
}
private
void
configureBatteryRoute
(
String
id
){
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
Settings
settings
=
metaWear
.
getSettings
();
settings
.
battery
().
addRouteAsync
(
source
->
source
.
limit
(
1
).
stream
((
Subscriber
)
(
data
,
env
)
->
{
for
(
Device
cd
:
getConnectedDevice
())
{
if
(
cd
.
getId
().
equals
(
id
))
{
cd
.
setBatteryLevel
((
int
)
data
.
value
(
Settings
.
BatteryState
.
class
).
charge
);
break
;
}
}
ServiceManager
.
startActionBatteryRead
(
managerContext
);
Log
.
d
(
TAG
,
"battery state = "
+
data
.
value
(
Settings
.
BatteryState
.
class
));
})).
continueWith
((
Continuation
<
Route
,
Void
>)
task
->
{
settings
.
battery
().
read
();
return
null
;
});
break
;
}
}
}
@Override
public
void
readBatteryLevel
(
String
id
)
{
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
Settings
settings
=
metaWear
.
getSettings
();
settings
.
battery
().
read
();
break
;
}
}
}
private
void
startStreaming
(
String
id
){
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
com
.
mbientlab
.
metawear
.
module
.
SensorFusionBosch
sensorFusionBosch
=
metaWear
.
getSensorFusion
();
sensorFusionBosch
.
quaternion
().
addRouteAsync
(
source
->
source
.
limit
(
33
).
stream
((
Subscriber
)
(
data
,
env
)
->
{
for
(
Device
device
:
getConnectedDevice
())
{
if
(
id
.
equals
(
device
.
getId
()))
{
device
.
getSensor
(
MetaWear
.
SENSOR_FUSION
)
.
getData
(
SensorFusion
.
W
)
.
set
(
data
.
value
(
Quaternion
.
class
).
w
());
device
.
getSensor
(
MetaWear
.
SENSOR_FUSION
)
.
getData
(
SensorFusion
.
X
)
.
set
(
data
.
value
(
Quaternion
.
class
).
x
());
device
.
getSensor
(
MetaWear
.
SENSOR_FUSION
)
.
getData
(
SensorFusion
.
Y
)
.
set
(
data
.
value
(
Quaternion
.
class
).
y
());
device
.
getSensor
(
MetaWear
.
SENSOR_FUSION
)
.
getData
(
SensorFusion
.
Z
)
.
set
(
data
.
value
(
Quaternion
.
class
).
z
());
device
.
getSensor
(
MetaWear
.
SENSOR_FUSION
)
.
getTimeStamp
()
.
set
(
data
.
timestamp
());
ServiceManager
.
save
(
device
.
getId
());
// Log.d("TIME", data.formattedTimestamp());
}
}
})).
continueWith
((
Continuation
<
Route
,
Void
>)
ignored
->
{
sensorFusionBosch
.
quaternion
().
start
();
sensorFusionBosch
.
start
();
return
null
;
});
}
}
}
private
void
scheduleTask
(
String
id
){
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
metaWear
.
getTimer
().
scheduleAsync
(
60000
,
false
,
()
->
metaWear
.
getTemperatureSensor
().
read
()).
continueWith
(
task
->
{
Timer
.
ScheduledTask
scheduledTask
;
scheduledTask
=
task
.
getResult
();
scheduledTask
.
start
();
scheduledTasks
.
add
(
new
Pair
<>(
id
,
scheduledTask
));
return
null
;
});
}
}
}
private
void
setTimer
(
String
id
){
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
metaWear
.
getTemperatureSensor
().
addRouteAsync
(
source
->
source
.
limit
(
1
).
stream
((
Subscriber
)
(
data
,
env
)
->
{
Log
.
i
(
TAG
,
metaWear
.
getName
()
+
" Temperature (C) = "
+
data
.
value
(
Float
.
class
));
for
(
Device
device
:
getConnectedDevice
())
{
if
(
id
.
equals
(
device
.
getId
()))
{
device
.
getSensor
(
MetaWear
.
TEMPERATURE
)
.
getData
(
Temperature
.
TEMP
)
.
set
(
data
.
value
(
Float
.
class
));
device
.
getSensor
(
MetaWear
.
TEMPERATURE
)
.
getTimeStamp
()
.
set
(
data
.
timestamp
());
ServiceManager
.
save
(
device
.
getId
());
break
;
}
}
})).
continueWith
(
task
->
{
scheduleTask
(
id
);
return
null
;
});
}
}
}
@Override
public
void
connect
(
String
id
)
{
// Look if we are already connected to it
boolean
connecting
=
false
;
boolean
alreadyThere
=
false
;
for
(
Device
cd
:
getConnectedDevice
())
{
if
(
cd
.
getId
().
equals
(
id
))
{
alreadyThere
=
true
;
}
}
for
(
ConnBool
conn
:
connectings
){
if
(
conn
.
getId
().
equals
(
id
)){
connecting
=
conn
.
getBool
();
}
}
if
(!
alreadyThere
&&
!
connecting
)
{
// Inform that we have to connect.
for
(
ConnBool
conn
:
connectings
){
if
(
conn
.
getId
().
equals
(
id
)){
conn
.
setBool
(
true
);
}
}
for
(
Device
device
:
getScannedDevices
())
{
if
(
device
.
getId
().
equals
(
id
))
{
// get BLE device
BluetoothDevice
_device
=
ServiceManager
.
getBLEDevice
(
id
);
if
(
ServiceManager
.
getMetawearBinder
()
!=
null
)
{
// Create a MetaWear board object for the Bluetooth Device
MetaWearBoard
board
;
board
=
ServiceManager
.
getMetawearBinder
().
getMetaWearBoard
(
_device
);
boards
.
add
(
board
);
board
.
onUnexpectedDisconnect
(
status
->
{
Log
.
d
(
TAG
,
"Unexpected disconnection"
);
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
if
(
board
!=
null
)
{
for
(
Device
cd
:
getConnectedDevice
())
{
if
(
cd
.
getId
().
equals
(
metaWear
.
getId
()))
{
cd
.
setConnected
(
false
);
cd
.
setScanned
(
false
);
break
;
}
}
for
(
Device
sc
:
getScannedDevices
())
{
if
(
sc
.
getId
().
equals
(
metaWear
.
getId
()))
{
sc
.
setConnected
(
false
);
sc
.
setScanned
(
false
);
break
;
}
}
deleteDisconnectedDevice
();
board
.
tearDown
();
ServiceManager
.
startActionDisconnect
(
managerContext
,
metaWear
.
getName
());
// If a saving has already been started, stop that saving
if
(
ServiceManager
.
saving
())
{
ServiceManager
.
startActionStopOneSave
(
managerContext
,
metaWear
.
getId
(),
metaWear
.
getName
());
}
board
.
connectAsync
().
continueWithTask
(
task
->
{
if
(
task
.
isCancelled
())
{
return
task
;
}
return
task
.
isFaulted
()
?
reconnect
(
board
)
:
task
;
}).
continueWith
(
task
->
{
if
(!
task
.
isCancelled
())
{
addScannedDevice
(
metaWear
);
connected
(
id
);
}
else
{
board
.
tearDown
();
disconnected
(
id
);
Log
.
d
(
TAG
,
"MetaWear Disconnected"
);
}
return
null
;
});
}
}
}
});
board
.
connectAsync
().
continueWithTask
(
task
->
{
if
(
task
.
isCancelled
())
{
return
task
;
}
return
task
.
isFaulted
()
?
reconnect
(
board
)
:
task
;
}).
continueWith
(
task
->
{
if
(!
task
.
isCancelled
())
{
board
.
getModule
(
Settings
.
class
).
editBleConnParams
()
.
maxConnectionInterval
(
Build
.
VERSION
.
SDK_INT
>=
Build
.
VERSION_CODES
.
M
?
11.25f
:
7.5f
)
.
commit
();
connected
(
id
);
setTimer
(
id
);
}
return
null
;
});
}
else
{
ServiceManager
.
startActionScanned
(
managerContext
);
Log
.
d
(
TAG
,
"I have to notify another action scan because I was not ready to connect yet, the service has not given me the reference to the board"
);
for
(
ConnBool
conn
:
connectings
){
if
(
conn
.
getId
().
equals
(
id
)){
conn
.
setBool
(
false
);
}
}
}
break
;
}
}
}
}
private
void
disconnected
(
String
id
){
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
for
(
Device
device
:
getConnectedDevice
())
{
if
(
device
.
getId
().
equals
(
id
))
{
device
.
setConnected
(
false
);
device
.
setScanned
(
false
);
break
;
}
}
for
(
Device
device
:
getScannedDevices
())
{
if
(
device
.
getId
().
equals
(
id
))
{
device
.
setConnected
(
false
);
device
.
setScanned
(
false
);
break
;
}
}
ServiceManager
.
stopScanBluetooth
();
for
(
DisconBool
discon
:
disconnectings
){
if
(
discon
.
getId
().
equals
(
id
)){
discon
.
setBool
(
false
);
}
}
deleteDisconnectedDevice
();
// If a saving has already been started, stop that saving
if
(
ServiceManager
.
saving
())
{
ServiceManager
.
startActionStopOneSave
(
managerContext
,
metaWear
.
getId
(),
metaWear
.
getName
());
}
ServiceManager
.
startActionDisconnect
(
managerContext
,
metaWear
.
getName
());
scanAllowed
=
true
;
}
}
}
@Override
public
void
disconnect
(
String
id
)
{
boolean
disconnecting
=
false
;
for
(
DisconBool
discon
:
disconnectings
){
if
(
discon
.
getId
().
equals
(
id
)){
disconnecting
=
discon
.
getBool
();
}
}
for
(
MetaWear
metaWear
:
metaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
))
{
for
(
MetaWearBoard
board
:
boards
)
{
if
(
board
.
getMacAddress
().
equals
(
id
))
{
if
(
metaWear
.
isConnected
()
&&
!
disconnecting
)
{
for
(
DisconBool
discon
:
disconnectings
){
if
(
discon
.
getId
().
equals
(
id
)){
discon
.
setBool
(
true
);
}
}
metaWear
.
getSensorFusion
().
stop
();
metaWear
.
getSensorFusion
().
quaternion
().
stop
();
ArrayList
<
Pair
<
String
,
Timer
.
ScheduledTask
>>
iterScheduledTasks
=
new
ArrayList
<>(
scheduledTasks
);
for
(
Pair
<
String
,
Timer
.
ScheduledTask
>
pair
:
iterScheduledTasks
){
if
(
pair
.
first
!=
null
&&
pair
.
first
.
equals
(
id
)){
if
(
pair
.
second
!=
null
){
pair
.
second
.
stop
();
pair
.
second
.
remove
();
}
}
}
board
.
tearDown
();
// When you are done using your board, call tearDown to remove resources allocated by the firmware and API such as routes,
// loggers, and data processors. this method does not reset the board so any configuration changes are preserved.
board
.
disconnectAsync
().
continueWithTask
(
task
->
task
.
isCancelled
()
||
!
task
.
isFaulted
()
?
task
:
disconnect
(
board
))
.
continueWith
((
Continuation
<
Void
,
Void
>)
task
->
{
if
(!
task
.
isCancelled
())
{
disconnected
(
id
);
removeResources
(
id
);
Log
.
d
(
TAG
,
"MetaWear Disconnected"
);
}
return
null
;
});
break
;
}
}
}
}
}
}
private
void
removeResources
(
String
id
)
{
ArrayList
<
ConnBool
>
iterConnectings
=
new
ArrayList
<>(
connectings
);
ArrayList
<
DisconBool
>
iterDisconnectings
=
new
ArrayList
<>(
disconnectings
);
ArrayList
<
MetaWearBoard
>
iterBoards
=
new
ArrayList
<>(
boards
);
ArrayList
<
MetaWear
>
iterMetaWears
=
new
ArrayList
<>(
metaWears
);
ArrayList
<
Pair
<
String
,
Timer
.
ScheduledTask
>>
iterscheduledTasks
=
new
ArrayList
<>(
scheduledTasks
);
for
(
MetaWearBoard
board
:
iterBoards
)
{
if
(
board
.
getMacAddress
().
equals
(
id
)){
boards
.
remove
(
board
);
}
}
for
(
MetaWear
metaWear
:
iterMetaWears
)
{
if
(
metaWear
.
getId
().
equals
(
id
)){
metaWears
.
remove
(
metaWear
);
}
}
for
(
Pair
<
String
,
Timer
.
ScheduledTask
>
pair
:
iterscheduledTasks
)
{
if
(
pair
.
first
!=
null
&&
pair
.
first
.
equals
(
id
)){
scheduledTasks
.
remove
(
pair
);
}
}
for
(
ConnBool
connBool
:
iterConnectings
){
if
(
connBool
.
getId
().
equals
(
id
)){
connectings
.
remove
(
connBool
);
}
}
for
(
DisconBool
disconBool
:
iterDisconnectings
){
if
(
disconBool
.
getId
().
equals
(
id
)){
disconnectings
.
remove
(
disconBool
);
}
}
}
@Override
public
void
onActivityResult
(
String
requestCode
,
int
resultCode
)
{
}
private
static
Task
<
Void
>
disconnect
(
final
MetaWearBoard
board
)
{
Log
.
d
(
TAG
,
"I'm trying to disconnect"
);
return
board
.
disconnectAsync
().
continueWithTask
(
task
->
task
.
isFaulted
()
?
disconnect
(
board
)
:
task
);
}
private
static
Task
<
Void
>
reconnect
(
final
MetaWearBoard
board
)
{
return
board
.
connectAsync
()
.
continueWithTask
(
task
->
{
if
(
task
.
isFaulted
())
{
Log
.
d
(
TAG
,
"I'm trying to reconnect, task faulted"
);
return
reconnect
(
board
);
}
else
if
(
task
.
isCancelled
())
{
Log
.
d
(
TAG
,
"Task cancelled."
);
return
task
;
}
return
Task
.
forResult
(
null
);
});
}
}
Event Timeline
Log In to Comment