Skip to content

Instantly share code, notes, and snippets.

@JpEncausse
Created July 13, 2015 09:35
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save JpEncausse/b9f526cf853be3829034 to your computer and use it in GitHub Desktop.
Save JpEncausse/b9f526cf853be3829034 to your computer and use it in GitHub Desktop.
MetaWear Logging JSON values
package fr.whatshome.metawear;
import android.app.Activity;
import android.app.ProgressDialog;
import android.content.Intent;
import android.content.pm.ActivityInfo;
import android.net.Uri;
import android.os.Bundle;
import android.support.v4.content.FileProvider;
import android.util.Log;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.Button;
import android.widget.Toast;
import com.mbientlab.metawear.api.MetaWearController;
import com.mbientlab.metawear.api.Module;
import com.mbientlab.metawear.api.Register;
import com.mbientlab.metawear.api.controller.Accelerometer;
import com.mbientlab.metawear.api.controller.Logging;
import com.mbientlab.metawear.api.controller.MechanicalSwitch;
import com.mbientlab.metawear.api.util.BytesInterpreter;
import com.mbientlab.metawear.api.util.LoggingTrigger;
import com.mbientlab.metawear.app.ModuleFragment;
import com.mbientlab.metawear.app.R;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.Locale;
public class WhatsHomeFragment extends ModuleFragment {
private Logging loggingController;
// ====================================================================================
// INNERCLASS: SENSOR
// ====================================================================================
private ProgressDialog logDLProgress = null;
public abstract class WHSensor extends Logging.Callbacks {
private boolean ready;
private int totalEntries;
protected Logging.LogEntry firstEntry;
protected Logging.ReferenceTick refTick;
public boolean dataReady() { return ready; }
public void setupLogger() {
ready = false;
}
public abstract void stopSensors();
public abstract void processData(double offset, Logging.LogEntry entry);
public abstract File[] saveDataToFile() throws IOException;
@Override
public void receivedReferenceTick(Logging.ReferenceTick reference) {
refTick = reference;
loggingController.readTotalEntryCount();
}
@Override
public void receivedTriggerId(byte triggerId) {
loggingController.startLogging();
Toast.makeText(getActivity(), R.string.label_lob_start_message, Toast.LENGTH_SHORT).show();
}
@Override
public void receivedLogEntry(Logging.LogEntry entry) {
if (firstEntry == null) {
firstEntry = entry;
}
processData(entry.offset(firstEntry) / 1000.0, entry);
}
@Override
public void receivedTotalEntryCount(int totalEntries) {
if (logDLProgress == null || !logDLProgress.isShowing()) {
this.totalEntries= totalEntries;
logDLProgress= new ProgressDialog(getActivity());
logDLProgress.setOwnerActivity(getActivity());
logDLProgress.setTitle("Log Download");
logDLProgress.setMessage("Downloading log...");
logDLProgress.setProgressStyle(ProgressDialog.STYLE_HORIZONTAL);
logDLProgress.setProgress(0);
logDLProgress.setMax(totalEntries);
logDLProgress.show();
loggingController.downloadLog(totalEntries, (int) (totalEntries * 0.01));
}
}
@Override
public void receivedDownloadProgress(int nEntriesLeft) {
logDLProgress.setProgress(totalEntries - nEntriesLeft);
}
@Override
public void downloadCompleted() {
if (logDLProgress.isShowing()) {
logDLProgress.dismiss();
}
firstEntry = null;
ready = true;
loggingController.removeAllTriggers();
startEmailIntent();
}
}
// ====================================================================================
// CLASS: MODULE FRAGMENT
// ====================================================================================
@Override
public void controllerReady(MetaWearController mwController) {
loggingController = (Logging) mwController.getModuleController(Module.LOGGING);
}
@Override
public void onAttach(Activity activity) {
activity.setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_LOCKED);
super.onAttach(activity);
}
@Override
public void onPause() {
getActivity().setRequestedOrientation(ActivityInfo.SCREEN_ORIENTATION_FULL_SENSOR);
super.onPause();
}
@Override
public View onCreateView(LayoutInflater inflater, ViewGroup container, Bundle savedInstanceState) {
return inflater.inflate(R.layout.fragment_whatshome, container, false);
}
@Override
public void onViewCreated(final View view, Bundle savedInstanceState) {
((Button) view.findViewById(R.id.button1)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mwMnger.controllerReady()) {
mwMnger.getCurrentController().addModuleCallback(sensor);
sensor.setupLogger();
} else {
Toast.makeText(getActivity(), R.string.error_connect_board, Toast.LENGTH_LONG).show();
}
}
});
((Button) view.findViewById(R.id.button2)).setOnClickListener(new View.OnClickListener() {
@Override
public void onClick(View v) {
if (mwMnger.controllerReady()) {
mwMnger.getCurrentController().addModuleCallback(sensor);
sensor.stopSensors();
if (sensor.dataReady()) {
startEmailIntent();
} else {
loggingController.stopLogging();
startLogDownload();
}
} else {
Toast.makeText(getActivity(), R.string.error_connect_board, Toast.LENGTH_LONG).show();
}
}
});
}
// ------------------------------------------
// LOGGER
// ------------------------------------------
private WHSensor sensor = new WHSensor(){
private byte orientId = -1, switchId = -1, fallId = -1;
private ArrayList<String> whData = null;
@Override
public void stopSensors() {
final Accelerometer accelController= (Accelerometer) mwMnger.getCurrentController().getModuleController(Module.ACCELEROMETER);
accelController.stopComponents();
}
@Override
public void setupLogger() {
super.setupLogger();
whData= new ArrayList<>();
orientId = -1; switchId = -1; fallId = -1;
loggingController.addTrigger(LoggingTrigger.ACCELEROMETER_ORIENTATION);
loggingController.addTrigger(LoggingTrigger.SWITCH);
loggingController.addTrigger(new Logging.Trigger() {
@Override public Register register() { return Accelerometer.Register.FREE_FALL_VALUE; }
@Override public byte index() { return (byte) 0xff; }
@Override public byte offset() { return 0; }
@Override public byte length() { return 1; }
});
final Accelerometer accelController = (Accelerometer) mwMnger.getCurrentController().getModuleController(Module.ACCELEROMETER);
Accelerometer.AccelerometerConfig orientation = accelController.enableOrientationDetection().withSilentMode();
Accelerometer.ThresholdConfig threshold = accelController.enableMotionDetection(Accelerometer.Axis.values());
Accelerometer.ThresholdConfig shakeX = accelController.enableShakeDetection(Accelerometer.Axis.X);
Accelerometer.ThresholdConfig shakeY = accelController.enableShakeDetection(Accelerometer.Axis.Y);
Accelerometer.ThresholdConfig shakeZ = accelController.enableShakeDetection(Accelerometer.Axis.Z);
final MechanicalSwitch switchController = (MechanicalSwitch) mwMnger.getCurrentController().getModuleController(Module.MECHANICAL_SWITCH);
switchController.enableNotification();
accelController.startComponents();
}
@Override
public void receivedTriggerId(byte triggerId) {
if (orientId == -1) { orientId = triggerId; Log.i("TriggerId", "Orient: "+orientId); super.receivedTriggerId(triggerId); }
else if (switchId == -1) { switchId = triggerId; Log.i("TriggerId", "Switch: "+switchId); super.receivedTriggerId(triggerId); }
else if (fallId == -1) { fallId = triggerId; Log.i("TriggerId", "Fall: "+fallId); super.receivedTriggerId(triggerId); }
}
@Override
public void processData(double offset, Logging.LogEntry entry) {
String record = "";
byte[] data = entry.data();
Date d = entry.timestamp(refTick).getTime();
if (entry.triggerId() == orientId) {
Accelerometer.Orientation o = BytesInterpreter.byteToOrientation(data[0]);
record = String.format("\"date\" : \"%tY%<tm%<td-%<tH:%<tM:%<tS\", \"orientation\" : \"%s\"", d, o.toString());
} else if (entry.triggerId() == switchId) {
boolean on = BytesInterpreter.bytesToSwitchState(data);
record = String.format("\"date\" : \"%tY%<tm%<td-%<tH:%<tM:%<tS\", \"switch\" : \"%s\"", d, (on?1:0));
} else if (entry.triggerId() == fallId) {
record = String.format("\"date\" : \"%tY%<tm%<td-%<tH:%<tM:%<tS\", \"activity\" : \"%s\"", d, "1");
}
record = "{" + record + "},\n";
whData.add(record);
Log.i("ProcessData", entry.triggerId() + " : " + record);
}
@Override
public File[] saveDataToFile() throws IOException {
File file = getActivity().getFileStreamPath("whatshome_data.json");
FileOutputStream fos = new FileOutputStream(file);
fos.write("{\n".getBytes());
for (String it : whData) { fos.write(it.getBytes()); }
fos.write("}".getBytes());
fos.close();
return new File[]{ file, file};
}
};
// ------------------------------------------
// UTILITY
// ------------------------------------------
private void startLogDownload() {
/*
Before actually calling the downloadLog method, we will first gather the required
data to compute the log timestamps and setup progress notifications.
This means we will call downloadLog in one of the logging callback functions, and
will start the callback chain here
*/
loggingController.readReferenceTick();
}
private void startEmailIntent() {
mwMnger.getCurrentController().removeModuleCallback(sensor);
ArrayList<Uri> fileUris= new ArrayList<>();
try {
for(File it: sensor.saveDataToFile()) {
fileUris.add(FileProvider.getUriForFile(getActivity(), "com.mbientlab.metawear.app.fileprovider", it));
}
Intent intent = new Intent(Intent.ACTION_SEND_MULTIPLE);
intent.setType("text/plain");
intent.putExtra(Intent.EXTRA_SUBJECT, String.format(Locale.FRANCE, "Logged %s data - %tY-%<tm-%<tdT%<tH-%<tM-%<tS", sensor.toString(), Calendar.getInstance().getTime()));
intent.putParcelableArrayListExtra(Intent.EXTRA_STREAM, fileUris);
startActivity(Intent.createChooser(intent, "Send email..."));
} catch (IOException e) {
e.printStackTrace();
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment