Downloading Logged Sensor Data

Hi Eric,
I have been trying to set the board to log sensor data and then download the logged data
exploring the Logging API in the metawear api.
I got the board logModule= mwBoard.getModule(Logging.class);
got the 
long logCapacity=logModule.getLogCapacity(); 
Log.i("TAG","Log Capacity= "+logCapacity);which returns 
Log Capacity= 11136
Now when I try to download as,
com.mbientlab.metawear.AsyncOperation<Integer>
i= logModule.downloadLog(0.1f,new Logging.DownloadHandler() {
@Override
public void onProgressUpdate(int nEntriesLeft, int totalEntries) {
Log.i("MainActivity", String.format("Progress= %d / %d", nEntriesLeft,
totalEntries));
if (nEntriesLeft == 0) {
mwBoard.disconnect();
}
}

});
further when I do a ,Log.i("TAG","Res:"+i.result());
I get a Task Not Yet complete Exception.

So my question is,
1) How do you fetch the data logged in the board memory.
2) How do you configure (as in the Metabase App) which sensor data to be logged and at what interval.

Comments

  • Setting up a data route to log data is covered here and the following section, and controlling the logger is covered here.
  • The logger module just says , 
    logModule.startLogging(); but how will I know how to log from a specific sensor?

  • I guess this would be an example to log data from an accelerometer, 
    but I don't know why this is not working.
    public void startDataLogging(){
    try {

    mwBoard.getModule(Accelerometer.class).routeData().fromAxes().log("accel_log_key").commit()
    .onComplete(new AsyncOperation.CompletionHandler<RouteManager>() {
    @Override
    public void success(RouteManager result) {
    super.success(result);
    Log.i("TAG","Started Data Logging");
    Collection<String> res= result.getLogKeys();
    for(String k:res){
    Log.i("TAG","Res: "+k);
    }
    result.subscribe("accel_log_key", new RouteManager.MessageHandler() {
    @Override
    public void process(Message msg) {
    Log.i("TAG","Result: "+msg.getData().toString());
    }
    });
    }
  • edited August 2016
    For logging, you use setLogMessageHandler instead of subscribe. You still need to start the accelerometer and logger to log data.

    An easy way to check if you have the accelerometer properly configured is to stream data to your device first before using the logger.
  • Dear Eric,

    Thanks , we went extensively through the API docs and are now able to
    1.  fetch streaming data,
    2. configure sensor to log  data.
    However, we are still not able to get the earlier logged entries, can you show us to  a way how do we pass the logging key and get the logged data from the board.

    Point 2 was tested , as we are getting some entries using,
    Logging.DownloadHandler(){
    @Override
    public void receivedUnknownLogEntry(byte logId, Calendar timestamp, byte[] data) {
    super.receivedUnknownLogEntry(logId, timestamp, data);
    Log.i("TAG", "Log ID: " + logId + " " + new String(data));
    Log.i("TAG", mwBoard.getMacAddress());
    }

    Can you suggest us what method or api we need to implement as we could not find a suitable sample 
    source code to retrieve the logged entries.

    Thanks ,
    Dush
  • What does your data route code currently look like?  Also, does the onFailure function return an exception when you create a date route?
  • Initially tried with this:
    but not getting any data,
    onFailure function does not return any error.

    accModule.routeData().fromAxes().log("log_stream")
    .commit().onComplete(new AsyncOperation.CompletionHandler<RouteManager>() {
    @Override
    public void success(RouteManager result) {
    result.setLogMessageHandler("log_stream", new RouteManager.MessageHandler() {
    @Override
    public void process(Message msg) {
    CartesianFloat axes = msg.getData(CartesianFloat.class);
    Log.i("MainActivity", axes.toString());
    }
    });
    logModule.startLogging();

    logModule.downloadLog((float)0.1, new Logging.DownloadHandler() {
    @Override
    public void onProgressUpdate(int nEntriesLeft, int totalEntries) {
    Log.i("TAG", String.format("Progress= %d / %d", nEntriesLeft,
    totalEntries));
    if(nEntriesLeft == 0) {
    mwBoard.disconnect();
    }
    }
    });
    }

    @Override
    public void failure(Throwable error) {
    super.failure(error);
    Log.i("TAG", "Failed to retrieve data");
    error.printStackTrace();
    }
    });
  • Further tried using ,
    but getting a null pointer exception on the RouteManager obj route
    RouteManager route= mwBoard.getRouteManager(0);
     // here 0 is the value of result.id from ,
    // RouteManager result while setting the board to start logging the sensor data.
     route.setLogMessageHandler("log_stream", new RouteManager.MessageHandler() {
    @Override
    public void process(Message msg) {
    CartesianFloat axes = msg.getData(CartesianFloat.class);
    Log.i("MainActivity", axes.toString());
    }
    });

    logModule.downloadLog((float)0.1, new Logging.DownloadHandler() {
    @Override
    public void onProgressUpdate(int nEntriesLeft, int totalEntries) {
    Log.i("Thermistor", String.format("Progress= %d / %d", nEntriesLeft,
    totalEntries));
    if(nEntriesLeft == 0) {
    }
    }
    });
  • I don't see any code that starts the accelerometer so what you have provided effectively starts the logger and then immediately attempts a download before any data is recorded.  Your CompletionHandler should only start the logger and accelerometer.  Downloading the logged data should happen elsewhere, triggered by a button press for example.
  • Can you share with us a code snippet how we do a download of the logged sesnsor data.

    How we define the route and then initiate the download process.

    Been going through the API and documentation but in vain.
    Even tried to replicate the TemperatureTracker app , the snippet of which I have tried to replicate above.
  • Have a look at the android fitness tracker or temperature tracker apps in the mbient-projects repo.  They should point you in the right direction.
  • You already have the correct code, it's just not placed in the correct location as detailed in my previous post.
  • Hi lgleasain
    we tried implementing those apps, and were successful upto a certain extent.
    the problem arises when we try to create a RouteManager object to establish the route for downloading the logged data.

    I am specifically talking about this line of code:
    even when we store the result.id key from the previous log request in the android shared pref, we get this null object for route manager as below.
    Suggestion on this is what we are looking at.
    RouteManager route = mwBoard.getRouteManager(settings.getInt(mwBoard.getMacAddress() + "_log_stream", 0));
  • Did you save the serialized the MetaWearBoard state and subsequently deserialize it?
  • At first glance it does sound like a serialize/deserialize thing.  Were you following the suggestions I had in this blog post http://www.polyglotprogramminginc.com/logging-thermistor-data-with-the-metawear/ ?  
  • Thanks Igleasain,

    The link you provided has a good information and helped us answer  a couple of questions that we were having.
    Now post serialization of the board we are being able to download from it.

    The only problem that arises is after a few rounds of interaction with the board the board freezes and a timeout exception or 133 state exception arises.

    Any suggestions how you are handling this or is it that we need to live with it until a new firmware update is provided? 
  • Did you clean up the board before adding new routes?
This discussion has been closed.