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:
- If there are multiple arrays (like in /Meas/IMU9), they all must be of same length
- no string support
- optional data still takes space even if it has null value
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/
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: /{serial}/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