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:
		
							
								
								
									
										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
 | 
			
		||||
    export class Storage {
 | 
			
		||||
        constructor() { }
 | 
			
		||||
        csvSeparator: string;
 | 
			
		||||
        constructor() { 
 | 
			
		||||
            this.csvSeparator = ",";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        protected mapFilename(filename: string) {
 | 
			
		||||
            return filename;
 | 
			
		||||
@@ -69,23 +72,23 @@ namespace storage {
 | 
			
		||||
        appendCSVHeaders(filename: string, headers: string[]) {
 | 
			
		||||
            let s = ""
 | 
			
		||||
            for (const d of headers) {
 | 
			
		||||
                if (s) s += "\t"
 | 
			
		||||
                if (s) s += this.csvSeparator;
 | 
			
		||||
                s = s + d;
 | 
			
		||||
            }
 | 
			
		||||
            s += "\r\n"
 | 
			
		||||
            this.append(filename, s)
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
                /**
 | 
			
		||||
         * Append a row of CSV data
 | 
			
		||||
         * @param filename the file name to append data, eg: "data.csv"
 | 
			
		||||
         * @param data the data to append
 | 
			
		||||
         */
 | 
			
		||||
        /**
 | 
			
		||||
 * Append a row of CSV data
 | 
			
		||||
 * @param filename the file name to append data, eg: "data.csv"
 | 
			
		||||
 * @param data the data to append
 | 
			
		||||
 */
 | 
			
		||||
        //% blockId=storageAppendCSV block="storage %source|%filename|append CSV %data"
 | 
			
		||||
        appendCSV(filename: string, data: number[]) {
 | 
			
		||||
            let s = ""
 | 
			
		||||
            for (const d of data) {
 | 
			
		||||
                if (s) s += "\t"
 | 
			
		||||
                if (s) s += this.csvSeparator;
 | 
			
		||||
                s = s + d;
 | 
			
		||||
            }
 | 
			
		||||
            s += "\r\n"
 | 
			
		||||
 
 | 
			
		||||
@@ -16,8 +16,9 @@
 | 
			
		||||
        "libs/infrared-sensor",
 | 
			
		||||
        "libs/gyro-sensor",
 | 
			
		||||
        "libs/chassis",
 | 
			
		||||
        "libs/storage",
 | 
			
		||||
        "libs/ev3",
 | 
			
		||||
        "libs/storage",
 | 
			
		||||
        "libs/datalog",
 | 
			
		||||
        "libs/tests",
 | 
			
		||||
        "libs/behaviors"
 | 
			
		||||
    ],
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user