Datalogger & Logbook

This document describes how to use Dataloger & Logbook data storage features of the Movesense sensor on Android side.

Technical capabilities

The Movesense sensor contains 384kB EEPROM memory for storing data. To assist software developer to utilize this memory the Movesense Core Library contains two services /DataLogger and /Logbook that make it effortless to store and retrieve the data from the sensor. The EEPROM memory does not have a filesystem, but it is instead organized as a circular buffer ChunkStorage, which means that as the memory gets full, the old data gets overwritten. To distinguish between recordings the ChunkStorage uses a SessionID that is incremented every time that the ChunkStorage is restarted (at the moment this only happens every time that the sensor is reset).

/DataLogger service

To help logging data from Whiteboard ResourceProviders the Movesense Core Library contains a DataLogger service. This is a simple service that can be configured to subscribe to any whiteboard resources (even the ones you create in the application!) and record all the data (notifications) they provide. /DataLogger has two resources: /DataLogger/Config and /DataLogger/State. Config contains the current configuration of the logger (what data to log), and state describes the state of the logger (see: DataLoggerState in datalogger.yaml)

The DataLogger service stores the data using the ChunkStorage class. The data is stored in binary format that is deduced automatically from the yaml files as a part of the application build process. The generated code has some limitations, such as:

The ChunkStorage stores data one entry at the time until the internal buffer for the resource is full and then synchronizes the data to the EEPROM memory. If the memory gets full the ChuckStorage starts over from the beginning and begins overwriting the old data.

/Logbook service

Logbook service is used to access the data stored in the EEPROM memory. The yaml file contains lots of different things, but Movesense sensor only supports a small subset of that API (see below). The Logbook service can enumerate the contents of the EEPROM memory (/Logbook/Entries resource) and provide the data of the made recordings.

The recordings are returned in Suunto Oy:s SBEM-format which is converted automatically to json by mobile-lib's Logbook proxy service (MDS path "suunto://MDS/Logbook//..."). For more info see movesense-mobile-lib/android/samples/DataLoggerSample.

How to use

1. Create DataLogger config

Example for config with Accelerometer and Gyroscope logs.

{
    "dataEntries" : {
        "dataEntry" : [{
                "path" : "/Meas/Acc/13"
            }, {
                "path" : "/Meas/Gyro/13"
            }
        ]
    }
}

Creating config in Android example:

PATH: {serial}/Mem/DataLogger/Config/ REQUEST: PUT

 Mds.builder().build(context).put("suunto://" + movesenseSerial + "/Mem/DataLogger/Config/",
                jsonConfig, new MdsResponseListener() {
                    @Override
                    public void onSuccess(String s) {
                    }

                    @Override
                    public void onError(MdsException e) {
                    }
                });

Example response:

{"Content": {"dataEntries": {"dataEntry": [{"path": "/Meas/Acc/13"}, {"path": "/Meas/Gyro/13"}]}}}

2. Start logging

To start logging, PUT value DATALOGGER_LOGGING (=3) to Mem/DataLogger/State resource

Android start logging example:

PATH: {serial}/Mem/DataLogger/State/ REQUEST: PUT

        Mds.builder().build(context).put("suunto://" + movesenseSerial + /Mem/DataLogger/State/,
                    "{\"newState\":3}", new MdsResponseListener() {
                        @Override
                        public void onSuccess(String data) {
                        }
                        @Override
                        public void onError(MdsException error) {
                        }
                    });

Example response:

{"Content": 3}

3. Stop logging

To stop logging, PUT value DATALOGGER_READY (=2) to Mem/DataLogger/State resource

Android stop logging example:

PATH: {serial}/Mem/DataLogger/State/ REQUEST: PUT

        Mds.builder().build(context).put("suunto://" + movesenseSerial + /Mem/DataLogger/State/,
                    "{\"newState\":2}", new MdsResponseListener() {
                        @Override
                        public void onSuccess(String data) {
                        }
                        @Override
                        public void onError(MdsException error) {
                        }
                    });

Example response:

{"Content": 2}

4. Fetch all entries / logs from the device

PATH: /MDS/Logbook/{serial}/Entries REQUEST: GET

 Mds.builder().build(context).get("suunto://" + movesenseSerial + "/Mem/Logbook/Entries/",
                        null, new MdsResponseListener() {
                            @Override
                            public void onSuccess(String data) {
                            }

                            @Override
                            public void onError(MdsException error) {
                            }
                        });

Example response:

{"elements": [{"Id": 1, "ModificationTimestamp": 536927972, "Size": null}, {"Id": 5, "ModificationTimestamp": 4446227, "Size": null}]}

5. Read the log data

PATH: /MDS/Logbook/{serial}/byId/{LogId}/Data REQUEST: GET

 Mds.builder().build(context).get("suunto://MDS/Logbook/" + movesenseSerial + "/byId/" + entryId + "/Data",
                        null, new MdsResponseListener() {
                            @Override
                            public void onSuccess(String data) {
                            }

                            @Override
                            public void onError(MdsException error) {
                            }
                        });

Example response: TBD

6. Remove all stored entries from memory

PATH: //Mem/Logbook/Entries/ REQUEST: DELETE

 Mds.builder().build(context).delete("suunto://" + movesenseSerial + "/Mem/Logbook/Entries/",
                        null, new MdsResponseListener() {
                            @Override
                            public void onSuccess(String data) {
                            }

                            @Override
                            public void onError(MdsException error) {
                            }
                        });

Example response: TBD