mirror of https://github.com/espruino/BangleApps
Merge pull request #2889 from joserebelo/activity
Implement API for activity fetchingpull/2962/head
commit
a6927fa603
|
@ -29,4 +29,5 @@
|
|||
0.28: Navigation messages no longer launch the Maps view unless they're new
|
||||
0.29: Support for http request xpath return format
|
||||
0.30: Send firmware and hardware versions on connection
|
||||
Allow alarm enable/disable
|
||||
Allow alarm enable/disable
|
||||
0.31: Implement API for activity fetching
|
||||
|
|
|
@ -193,10 +193,37 @@
|
|||
Bangle.on('HRM',actHRMHandler);
|
||||
actInterval = setInterval(function() {
|
||||
var steps = Bangle.getStepCount();
|
||||
gbSend({ t: "act", stp: steps-lastSteps, hrm: lastBPM });
|
||||
gbSend({ t: "act", stp: steps-lastSteps, hrm: lastBPM, rt:1 });
|
||||
lastSteps = steps;
|
||||
}, event.int*1000);
|
||||
},
|
||||
// {t:"actfetch", ts:long}
|
||||
"actfetch": function() {
|
||||
gbSend({t: "actfetch", state: "start"});
|
||||
var actCount = 0;
|
||||
var actCb = function(r) {
|
||||
// The health lib saves the samples at the start of the 10-minute block
|
||||
// However, GB expects them at the end of the block, so let's offset them
|
||||
// here to keep a consistent API in the health lib
|
||||
var sampleTs = r.date.getTime() + 600000;
|
||||
if (sampleTs >= event.ts) {
|
||||
gbSend({
|
||||
t: "act",
|
||||
ts: sampleTs,
|
||||
stp: r.steps,
|
||||
hrm: r.bpm,
|
||||
mov: r.movement
|
||||
});
|
||||
actCount++;
|
||||
}
|
||||
}
|
||||
if (event.ts != 0) {
|
||||
require("health").readAllRecordsSince(new Date(event.ts - 600000), actCb);
|
||||
} else {
|
||||
require("health").readFullDatabase(actCb);
|
||||
}
|
||||
gbSend({t: "actfetch", state: "end", count: actCount});
|
||||
},
|
||||
"nav": function() {
|
||||
event.id="nav";
|
||||
if (event.instr) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "android",
|
||||
"name": "Android Integration",
|
||||
"shortName": "Android",
|
||||
"version": "0.30",
|
||||
"version": "0.31",
|
||||
"description": "Display notifications/music/etc sent from the Gadgetbridge app on Android. This replaces the old 'Gadgetbridge' Bangle.js widget.",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,system,messages,notifications,gadgetbridge",
|
||||
|
|
|
@ -59,6 +59,26 @@ Send a response to a notification from phone
|
|||
* n can be one of "dismiss", "dismiss all", "open", "mute", "reply"
|
||||
* id, tel and message are optional
|
||||
|
||||
## activity data
|
||||
|
||||
```json
|
||||
{
|
||||
"t": "act",
|
||||
"ts": 1692226800000,
|
||||
"stp": 26,
|
||||
"hrm": 70,
|
||||
"mov": 10,
|
||||
"rt": 1
|
||||
}
|
||||
```
|
||||
|
||||
* `ts` is the sample timestamp, in milliseconds since the unix epoch
|
||||
* `stp` is the number of steps
|
||||
* `hrm` is heart rate, in bpm
|
||||
* `mov` is the movement intensity (todo: range?)
|
||||
* `rt` whether it is a real-time sample
|
||||
|
||||
|
||||
# Phone -> Watch
|
||||
|
||||
## show notification
|
||||
|
@ -177,3 +197,14 @@ n is the intensity
|
|||
* hum is the humidity
|
||||
* txt is the weather condition
|
||||
* loc is the location
|
||||
|
||||
## fetch activity data
|
||||
|
||||
```json
|
||||
{
|
||||
"t": "actfetch",
|
||||
"ts": 1692226800000
|
||||
}
|
||||
```
|
||||
|
||||
* `ts` is the start timestamp, in milliseconds since the unix epoch
|
||||
|
|
|
@ -263,7 +263,7 @@
|
|||
function sendActivity(hrm) {
|
||||
var steps = currentSteps - lastSentSteps;
|
||||
lastSentSteps = currentSteps;
|
||||
gbSend({ t: "act", stp: steps, hrm:hrm });
|
||||
gbSend({ t: "act", stp: steps, hrm:hrm, rt:1 });
|
||||
}
|
||||
|
||||
// Battery monitor
|
||||
|
|
|
@ -25,4 +25,5 @@
|
|||
0.24: Correct daily health summary for movement (some logic errors resulted in garbage data being written)
|
||||
0.25: lib.read* methods now return correctly scaled movement
|
||||
movement graph in app is now an average, not sum
|
||||
fix 11pm slot for daily HRM
|
||||
fix 11pm slot for daily HRM
|
||||
0.26: Implement API for activity fetching
|
||||
|
|
|
@ -37,7 +37,36 @@ exports.readAllRecords = function(d, cb) {
|
|||
}
|
||||
idx += DB_RECORD_LEN; // +1 because we have an extra record with totals for the end of the day
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Read the entire database. There is no guarantee that the months are read in order.
|
||||
exports.readFullDatabase = function(cb) {
|
||||
require("Storage").list(/health-[0-9]+-[0-9]+.raw/).forEach(val => {
|
||||
console.log(val);
|
||||
var parts = val.split('-');
|
||||
var y = parseInt(parts[1]);
|
||||
var mo = parseInt(parts[2].replace('.raw', ''));
|
||||
|
||||
exports.readAllRecords(new Date(y, mo, 1), (r) => {
|
||||
r.date = new Date(y, mo, r.day, r.hr, r.min);
|
||||
cb(r);
|
||||
});
|
||||
});
|
||||
};
|
||||
|
||||
// Read all records per day, until the current time.
|
||||
// There may be some records for the day of the timestamp previous to the timestamp
|
||||
exports.readAllRecordsSince = function(d, cb) {
|
||||
var currentDate = new Date().getTime();
|
||||
var di = d;
|
||||
while (di.getTime() <= currentDate) {
|
||||
exports.readDay(di, (r) => {
|
||||
r.date = new Date(di.getFullYear(), di.getMonth(), di.getDate(), r.hr, r.min);
|
||||
cb(r);
|
||||
});
|
||||
di.setDate(di.getDate() + 1);
|
||||
}
|
||||
};
|
||||
|
||||
// Read daily summaries from the given month
|
||||
exports.readDailySummaries = function(d, cb) {
|
||||
|
|
|
@ -2,7 +2,7 @@
|
|||
"id": "health",
|
||||
"name": "Health Tracking",
|
||||
"shortName": "Health",
|
||||
"version": "0.25",
|
||||
"version": "0.26",
|
||||
"description": "Logs health data and provides an app to view it",
|
||||
"icon": "app.png",
|
||||
"tags": "tool,system,health",
|
||||
|
|
Loading…
Reference in New Issue