Merge pull request #2015 from halemmerich/hrmaccevents

hrmaccevents - Allow downloads of logged data from Bangle
master
Gordon Williams 2022-07-04 11:06:11 +01:00 committed by GitHub
commit b402d77a9a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 95 additions and 24 deletions

View File

@ -1,3 +1,5 @@
0.01: New App!
0.02: Show status info on display
Allow recording to Bangle
0.03: Allow downloading recorded files
Make it work with more BTHRM configs

View File

@ -6,7 +6,7 @@ This app can use [BTHRM](https://banglejs.com/apps/#bthrm) as a reference.
## Steps for usage
* (Optional) Install [BTHRM](https://banglejs.com/apps/#bthrm) as reference (use ECG based sensor for best accuracy).
* Configure BTHRM to "Both"-Mode. This prevents data beeing lost because BTHRM can replace the HRM-events data with BTHRM data.
* Configure BTHRM to "Both"-Mode or use a version >= 0.12. This prevents data beeing lost because BTHRM can replace the HRM-events data with BTHRM data.
* Click "Start" in browser.
* Wait until the "Events" number starts to grow, that means there are events recorded.
* Record for some time, since BTHRM and HRM often need some seconds to start getting useful values. Consider 2000 events a useful minimum.

View File

@ -1,18 +1,42 @@
<html>
<head>
<title>Bangle.js Accelerometer streaming</title>
<link rel="stylesheet" href="../../css/spectre.min.css">
</head>
<body>
<script src="https://www.puck-js.com/puck.js"></script>
<p></div><input type="checkbox" id="chkLocal">Store on Bangle (file named log.csv, download with IDE)</input></p>
<p>
<button id="btnConnect">Start</button>
<button id="btnStop">Stop</button>
<button id="btnReset">Reset</button>
<button id="btnSave">Save CSV</button>
<div class="form-group">
<label class="form-switch">
<input type="checkbox" id="chkLocal">
<i class="form-icon"></i> Store on bangle (file named log.csv)
</label>
</div>
</p>
<p>
<button id="btnConnect" class="btn btn-primary">Start</button>
<button id="btnStop" class="btn btn-secondary">Stop</button>
<button id="btnReset" class="btn btn-secondary">Reset</button>
<button id="btnSave" class="btn btn-primary">Save CSV</button>
<button id="btnDownload" class="btn btn-primary">Download CSV</button>
</p>
<p id="result"></p>
<script>
function saveCSV(filename, csvData) {
let a = document.createElement("a"),
file = new Blob([csvData], {type: "Comma-separated value file"});
let url = URL.createObjectURL(file);
a.href = url;
a.download = filename+".csv";
document.body.appendChild(a);
a.click();
setTimeout(function() {
document.body.removeChild(a);
window.URL.revokeObjectURL(url);
}, 0);
}
function createCode(){
//modes: 1 BT, 2 File
return "var method=" + (document.getElementById("chkLocal").checked ? 2 : 1) + ";\n" + String.raw`
@ -32,7 +56,12 @@ function createCode(){
return gotBTHRM && gotHRM && gotHRMraw && gotAcc;
}
let bthrmSettings = (require("Storage").readJSON("bthrm.json",1) || {});
Bangle.setHRMPower(1);
if (bthrmSettings.replace) Bangle.origSetHRMPower(1);
if (Bangle.setBTHRMPower){
Bangle.setBTHRMPower(1);
} else {
@ -99,7 +128,11 @@ function createCode(){
Bangle.on("accel", writeAccDirect);
}
Bangle.on("HRM-raw", writeHRMraw);
Bangle.on("HRM", writeHRM);
if (bthrmSettings.replace){
Bangle.origOn("HRM", writeHRM);
} else {
Bangle.on("HRM", writeHRM);
}
Bangle.on("BTHRM", writeBTHRM);
g.clear();
@ -164,7 +197,6 @@ function createCode(){
var connection;
var lineCount=-1;
function stop (){
connection.reconnect((c)=>{
c.write("load();\n");
@ -173,32 +205,74 @@ function stop (){
});
}
document.getElementById("chkLocal").addEventListener("click", function() {
function updateButtons(){
document.getElementById("btnSave").disabled = document.getElementById("chkLocal").checked;
document.getElementById("btnDownload").disabled = !document.getElementById("chkLocal").checked;
document.getElementById("btnReset").disabled = document.getElementById("chkLocal").checked;
document.getElementById("btnStop").disabled = document.getElementById("chkLocal").checked;
}
updateButtons();
document.getElementById("chkLocal").addEventListener("click", function() {
reset();
updateButtons();
});
window.addEventListener("message", function(event) {
let msg = event.data;
if (msg.type=="readstoragefilersp") {
saveCSV("log.csv", msg.data);
}
}, false);
document.getElementById("btnDownload").addEventListener("click", function() {
if (connection) {
stop();
}
console.log("Loading data from BangleJs...");
try {
window.postMessage({type:"readstoragefile",data:"log.csv",id:0});
} catch(ex) {
console.log("(Warning) Could not load apikey from BangleJs.");
console.log(ex);
}
});
document.getElementById("btnSave").addEventListener("click", function() {
var h = document.createElement('a');
h.href = 'data:text/csv;charset=utf-8,' + encodeURI(localStorage.getItem("data"));
h.target = '_blank';
h.download = "DATA.csv";
h.click();
saveCSV("log.csv", localStorage.getItem("data"));
});
function reset(){
document.getElementById("result").innerText="";
}
document.getElementById("btnReset").addEventListener("click", function() {
if (connection) {
stop();
}
document.getElementById("result").innerText="";
lineCount=-1;
localStorage.removeItem("data");
reset();
});
document.getElementById("btnStop").addEventListener("click", function() {
if (connection) {
stop();
}
});
function connect(connectionHandler){
Puck.connect(function(c) {
if (!c) {
console.log("Couldn't connect!\n");
return;
}
connection = c;
connectionHandler(c);
});
}
document.getElementById("btnConnect").addEventListener("click", function() {
localStorage.setItem("data", "");
lineCount=-1;
@ -206,12 +280,7 @@ document.getElementById("btnConnect").addEventListener("click", function() {
stop();
document.getElementById("result").innerText="0";
}
Puck.connect(function(c) {
if (!c) {
console.log("Couldn't connect!\n");
return;
}
connection = c;
connect(function(connection) {
var buf = "";
connection.on("data", function(d) {
buf += d;
@ -220,7 +289,7 @@ document.getElementById("btnConnect").addEventListener("click", function() {
l.forEach(onLine);
});
connection.write("reset();\n", function() {
setTimeout(function() {
setTimeout(function() {
connection.write("\x03\x10if(1){"+createCode()+"}\n",
function() { console.log("Ready..."); });
}, 1500);

View File

@ -2,14 +2,14 @@
"id": "hrmaccevents",
"name": "HRM Accelerometer event recorder",
"shortName": "HRM ACC recorder",
"version": "0.02",
"version": "0.03",
"type": "RAM",
"description": "Record HRM and accelerometer events in high resolution to CSV files in your browser",
"icon": "app.png",
"tags": "debug",
"supports": ["BANGLEJS","BANGLEJS2"],
"custom": "custom.html",
"customConnect": false,
"customConnect": true,
"readme": "README.md",
"storage": [ ]
}