Datalog (#233)
* support for custom csv separator * simple datalog frameowrk * api strings * hide setfile * storage fixes * log seconds, not milliseconds
This commit is contained in:
parent
c992100a38
commit
21195e4abf
3
libs/datalog/README.md
Normal file
3
libs/datalog/README.md
Normal file
@ -0,0 +1,3 @@
|
|||||||
|
# Datalog
|
||||||
|
|
||||||
|
A tiny libraty to create CSV datalog files.
|
8
libs/datalog/_locales/datalog-jsdoc-strings.json
Normal file
8
libs/datalog/_locales/datalog-jsdoc-strings.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"datalog.addRow": "Starts a row of data",
|
||||||
|
"datalog.addValue": "Adds a cell to the row of data",
|
||||||
|
"datalog.addValue|param|name": "name of the cell, eg: \"x\"",
|
||||||
|
"datalog.addValue|param|value": "value of the cell, eg: 0",
|
||||||
|
"datalog.setFile": "Starts a new data logger for the given file",
|
||||||
|
"datalog.setStorage": "* @param storage custom storage solution"
|
||||||
|
}
|
6
libs/datalog/_locales/datalog-strings.json
Normal file
6
libs/datalog/_locales/datalog-strings.json
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
{
|
||||||
|
"datalog.addRow|block": "datalog add row",
|
||||||
|
"datalog.addValue|block": "datalog add %name|=%value",
|
||||||
|
"datalog|block": "datalog",
|
||||||
|
"{id:category}Datalog": "Datalog"
|
||||||
|
}
|
90
libs/datalog/datalog.ts
Normal file
90
libs/datalog/datalog.ts
Normal file
@ -0,0 +1,90 @@
|
|||||||
|
//% weight=100 color=#0fbc11 icon=""
|
||||||
|
namespace datalog {
|
||||||
|
let _headers: string[] = undefined;
|
||||||
|
let _headersLength: number;
|
||||||
|
let _values: number[];
|
||||||
|
let _start: number;
|
||||||
|
let _filename = "data.csv";
|
||||||
|
let _storage: storage.Storage = storage.temporary;
|
||||||
|
|
||||||
|
function clear() {
|
||||||
|
_headers = undefined;
|
||||||
|
_values = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
function init() {
|
||||||
|
if (!_headers) {
|
||||||
|
_headers = [];
|
||||||
|
_headersLength = 0;
|
||||||
|
_start = control.millis();
|
||||||
|
_storage.remove(_filename);
|
||||||
|
}
|
||||||
|
_values = [];
|
||||||
|
}
|
||||||
|
|
||||||
|
function commit() {
|
||||||
|
// write row if any data
|
||||||
|
if (_values && _values.length > 0) {
|
||||||
|
// write headers for the first row
|
||||||
|
if (!_headersLength) {
|
||||||
|
_storage.appendCSVHeaders(_filename, _headers);
|
||||||
|
_headersLength = _storage.size(_filename);
|
||||||
|
}
|
||||||
|
// commit row data
|
||||||
|
_storage.appendCSV(_filename, _values);
|
||||||
|
}
|
||||||
|
|
||||||
|
// clear values
|
||||||
|
_values = undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a row of data
|
||||||
|
*/
|
||||||
|
//% weight=100
|
||||||
|
//% blockId=datalogAddRow block="datalog add row"
|
||||||
|
export function addRow(): void {
|
||||||
|
commit();
|
||||||
|
init();
|
||||||
|
const s = (control.millis() - _start) / 1000;
|
||||||
|
addValue("time (s)", s);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds a cell to the row of data
|
||||||
|
* @param name name of the cell, eg: "x"
|
||||||
|
* @param value value of the cell, eg: 0
|
||||||
|
*/
|
||||||
|
//% weight=99
|
||||||
|
//% blockId=datalogAddValue block="datalog add %name|=%value"
|
||||||
|
export function addValue(name: string, value: number) {
|
||||||
|
if (!_values) return;
|
||||||
|
let i = _headers.indexOf(name);
|
||||||
|
if (i < 0) {
|
||||||
|
_headers.push(name);
|
||||||
|
i = _headers.length - 1;
|
||||||
|
}
|
||||||
|
_values[i] = value;
|
||||||
|
if (i > 0) // 0 is time
|
||||||
|
console.logValue(name, value)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts a new data logger for the given file
|
||||||
|
*/
|
||||||
|
//%
|
||||||
|
export function setFile(fn: string) {
|
||||||
|
_filename = fn;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @param storage custom storage solution
|
||||||
|
*/
|
||||||
|
//%
|
||||||
|
export function setStorage(storage: storage.Storage) {
|
||||||
|
_storage = storage;
|
||||||
|
clear();
|
||||||
|
}
|
||||||
|
}
|
16
libs/datalog/pxt.json
Normal file
16
libs/datalog/pxt.json
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
{
|
||||||
|
"name": "datalog",
|
||||||
|
"description": "Tiny data logging framework",
|
||||||
|
"files": [
|
||||||
|
"README.md",
|
||||||
|
"datalog.ts"
|
||||||
|
],
|
||||||
|
"testFiles": [
|
||||||
|
"test.ts"
|
||||||
|
],
|
||||||
|
"public": true,
|
||||||
|
"dependencies": {
|
||||||
|
"core": "file:../core",
|
||||||
|
"storage": "file:../storage"
|
||||||
|
}
|
||||||
|
}
|
6
libs/datalog/test.ts
Normal file
6
libs/datalog/test.ts
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
|
||||||
|
loops.forever(function () {
|
||||||
|
datalog.addRow()
|
||||||
|
datalog.addValue("x", Math.random())
|
||||||
|
datalog.addValue("y", Math.random())
|
||||||
|
})
|
@ -6,7 +6,10 @@ namespace storage {
|
|||||||
|
|
||||||
//% fixedInstances
|
//% fixedInstances
|
||||||
export class Storage {
|
export class Storage {
|
||||||
constructor() { }
|
csvSeparator: string;
|
||||||
|
constructor() {
|
||||||
|
this.csvSeparator = ",";
|
||||||
|
}
|
||||||
|
|
||||||
protected mapFilename(filename: string) {
|
protected mapFilename(filename: string) {
|
||||||
return filename;
|
return filename;
|
||||||
@ -69,23 +72,23 @@ namespace storage {
|
|||||||
appendCSVHeaders(filename: string, headers: string[]) {
|
appendCSVHeaders(filename: string, headers: string[]) {
|
||||||
let s = ""
|
let s = ""
|
||||||
for (const d of headers) {
|
for (const d of headers) {
|
||||||
if (s) s += "\t"
|
if (s) s += this.csvSeparator;
|
||||||
s = s + d;
|
s = s + d;
|
||||||
}
|
}
|
||||||
s += "\r\n"
|
s += "\r\n"
|
||||||
this.append(filename, s)
|
this.append(filename, s)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Append a row of CSV data
|
* Append a row of CSV data
|
||||||
* @param filename the file name to append data, eg: "data.csv"
|
* @param filename the file name to append data, eg: "data.csv"
|
||||||
* @param data the data to append
|
* @param data the data to append
|
||||||
*/
|
*/
|
||||||
//% blockId=storageAppendCSV block="storage %source|%filename|append CSV %data"
|
//% blockId=storageAppendCSV block="storage %source|%filename|append CSV %data"
|
||||||
appendCSV(filename: string, data: number[]) {
|
appendCSV(filename: string, data: number[]) {
|
||||||
let s = ""
|
let s = ""
|
||||||
for (const d of data) {
|
for (const d of data) {
|
||||||
if (s) s += "\t"
|
if (s) s += this.csvSeparator;
|
||||||
s = s + d;
|
s = s + d;
|
||||||
}
|
}
|
||||||
s += "\r\n"
|
s += "\r\n"
|
||||||
|
@ -16,8 +16,9 @@
|
|||||||
"libs/infrared-sensor",
|
"libs/infrared-sensor",
|
||||||
"libs/gyro-sensor",
|
"libs/gyro-sensor",
|
||||||
"libs/chassis",
|
"libs/chassis",
|
||||||
"libs/storage",
|
|
||||||
"libs/ev3",
|
"libs/ev3",
|
||||||
|
"libs/storage",
|
||||||
|
"libs/datalog",
|
||||||
"libs/tests",
|
"libs/tests",
|
||||||
"libs/behaviors"
|
"libs/behaviors"
|
||||||
],
|
],
|
||||||
|
Loading…
Reference in New Issue
Block a user