mirror of https://github.com/espruino/BangleApps
first add of 1button
parent
7b59f2f821
commit
223668faa0
16
apps.json
16
apps.json
|
@ -1958,5 +1958,21 @@
|
|||
{"name":"miclock2.app.js","url":"clock-mixed.js"},
|
||||
{"name":"miclock2.img","url":"clock-mixed-icon.js","evaluate":true}
|
||||
]
|
||||
},
|
||||
{ "id": "1button",
|
||||
"name": "One-Button-Tracker",
|
||||
"icon": "widget.png",
|
||||
"version":"0.01",
|
||||
"interface": "interface.html",
|
||||
"description": "A widget that turns BTN1 into a tracker, records time of button press/release.",
|
||||
"tags": "tool,quantifiedself,widget",
|
||||
"type": "widget",
|
||||
"readme": "README.md",
|
||||
"storage": [
|
||||
{"name":"1button.wid.js","url":"widget.js"}
|
||||
],
|
||||
"data": [
|
||||
{"name":"one_button_presses.csv","storageFile": true}
|
||||
]
|
||||
}
|
||||
]
|
||||
|
|
|
@ -0,0 +1 @@
|
|||
0.01: New Widget!
|
|
@ -0,0 +1,25 @@
|
|||
# Widget Name
|
||||
|
||||
Describe the app...
|
||||
|
||||
Add screen shots (if possible) to the app folder and link then into this file with 
|
||||
|
||||
## Usage
|
||||
|
||||
Describe how to use it
|
||||
|
||||
## Features
|
||||
|
||||
Name the function
|
||||
|
||||
## Controls
|
||||
|
||||
Name the buttons and what they are used for
|
||||
|
||||
## Requests
|
||||
|
||||
Name who should be contacted for support/update requests
|
||||
|
||||
## Creator
|
||||
|
||||
Your name
|
|
@ -0,0 +1,107 @@
|
|||
<html>
|
||||
<head>
|
||||
<link rel="stylesheet" href="../../css/spectre.min.css">
|
||||
</head>
|
||||
<body>
|
||||
<div id="records"></div>
|
||||
|
||||
<script src="../../lib/interface.js"></script>
|
||||
<script>
|
||||
var domRecords = document.getElementById("records");
|
||||
|
||||
function saveRecord(record,name) {
|
||||
var csv = `${record.map(rec=>[rec.time, rec.bpm, rec.confidence].join(",")).join("\n")}`;
|
||||
Util.saveCSV(name, csv);
|
||||
}
|
||||
|
||||
|
||||
function recordLineToObject(l, hasRecordNbr) {
|
||||
var t = l.trim().split(",");
|
||||
var n = hasRecordNbr?1:0;
|
||||
var o = {
|
||||
start_time: parseFloat(t[n+0]),
|
||||
end_time: parseFloat(t[n+1]),
|
||||
};
|
||||
if (hasRecordNbr)
|
||||
o.number = t[0];
|
||||
return o;
|
||||
}
|
||||
|
||||
function downloadRecord(recordNbr, callback) {
|
||||
Util.showModal("Downloading one-button tracker data...");
|
||||
Util.readStorageFile(`one_button_presses.csv`,data=>{
|
||||
Util.hideModal();
|
||||
var record = data.trim().split("\n").map(l=>recordLineToObject(l,false));
|
||||
callback(record);
|
||||
});
|
||||
}
|
||||
|
||||
function getRecordList() {
|
||||
Util.showModal("Loading one button tracker records...");
|
||||
domRecords.innerHTML = "";
|
||||
Puck.write(`\x10(function() {
|
||||
var f = require("Storage").open("one_button_presses.csv,"r");
|
||||
var l = f.readLine();
|
||||
})()\n`,recordList=>{
|
||||
var recordLines = recordList.trim().split("\n");
|
||||
var html = `<div class="container">
|
||||
<div class="columns">\n`;
|
||||
recordLines.forEach(l => {
|
||||
var record = recordLineToObject(l, true /*has record number*/);
|
||||
html += `
|
||||
<div class="column col-12">
|
||||
<div class="card-header">
|
||||
<div class="card-title h5">Heart Rate Record ${record.number}</div>
|
||||
<div class="card-subtitle text-gray">${(new Date(record.time*1000)).toString().substr(0,24)}</div>
|
||||
</div>
|
||||
<div class="card-body"></div>
|
||||
<div class="card-footer">
|
||||
<button class="btn btn-primary" recordNbr="${record.number}" task="download">Download</button>
|
||||
<button class="btn btn-default" recordNbr="${record.number}" task="delete">Delete</button>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
});
|
||||
if (recordLines.length==0) {
|
||||
html += `
|
||||
<div class="column col-12">
|
||||
<div class="card-header">
|
||||
<div class="card-title h5">No record</div>
|
||||
<div class="card-subtitle text-gray">No heart rate record found</div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
html += `
|
||||
</div>
|
||||
</div>`;
|
||||
domRecords.innerHTML = html;
|
||||
Util.hideModal();
|
||||
var buttons = domRecords.querySelectorAll("button");
|
||||
for (var i=0;i<buttons.length;i++) {
|
||||
buttons[i].addEventListener("click",event => {
|
||||
var button = event.currentTarget;
|
||||
var recordNbr = parseInt(button.getAttribute("recordNbr"));
|
||||
var task = button.getAttribute("task");
|
||||
if (task=="delete") {
|
||||
Util.showModal("Deleting record...");
|
||||
Util.eraseStorageFile(`.heart${recordNbr.toString(36)}`,()=>{
|
||||
Util.hideModal();
|
||||
getRecordList();
|
||||
});
|
||||
}
|
||||
if (task=="download") {
|
||||
downloadRecord(recordNbr, record => saveRecord(record, `HeartRateRecord${recordNbr}`));
|
||||
}
|
||||
});
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
function onInit() {
|
||||
getRecordList();
|
||||
}
|
||||
|
||||
</script>
|
||||
</body>
|
||||
</html>
|
|
@ -0,0 +1,36 @@
|
|||
(() => {
|
||||
var press_time = new Date();
|
||||
recFile = require("Storage").open("one_button_presses.csv","a");
|
||||
|
||||
// set widget text
|
||||
function draw() {
|
||||
g.reset(); // reset the graphics context to defaults (color/font/etc)
|
||||
// add your code
|
||||
g.fillCircle(this.x+6,this.y+6,4);
|
||||
g.drawString("1BUTTON", this.x+13, this.y+4);
|
||||
}
|
||||
|
||||
// listen to button press to get start time
|
||||
setWatch(function(e) {
|
||||
console.log("Button pressed");
|
||||
digitalWrite(LED2,1);
|
||||
press_time = new Date();
|
||||
Bangle.buzz();
|
||||
}, BTN1, { repeat: true, edge: 'rising', debounce: 50 });
|
||||
|
||||
// listen to button go to get end time & write data
|
||||
setWatch(function(e) {
|
||||
console.log("Button let go");
|
||||
digitalWrite(LED2,0);
|
||||
var unpress_time = new Date();
|
||||
recFile.write([press_time.getTime(),unpress_time.getTime()].join(",")+"\n");
|
||||
}, BTN1, { repeat: true, edge: 'falling', debounce: 50 });
|
||||
|
||||
|
||||
// add your widget
|
||||
WIDGETS["1button"]={
|
||||
area:"tl", // tl (top left), tr (top right), bl (bottom left), br (bottom right)
|
||||
width: 100, // how wide is the widget? You can change this and call Bangle.drawWidgets() to re-layout
|
||||
draw:draw // called to draw the widget
|
||||
};
|
||||
})()
|
Binary file not shown.
After Width: | Height: | Size: 4.3 KiB |
Loading…
Reference in New Issue