fix: use Scripting app API (Health.queryQuantitySamples + HealthUnit)
This commit is contained in:
parent
e01c0b92e3
commit
51b864438b
1 changed files with 30 additions and 23 deletions
|
|
@ -1,28 +1,36 @@
|
||||||
// Health Sync — reads Apple Health and POSTs to nutrition-mcp server
|
// Health Sync — reads Apple Health and POSTs to nutrition-mcp server
|
||||||
// Run via Scriptable automation at 9:30am daily
|
// Run via Scripting app automation at 9:30am daily
|
||||||
// Server: http://chronos:9432/ingest
|
// Server: http://chronos:9432/ingest
|
||||||
//
|
//
|
||||||
// Uses Scriptable's Health API: new Health() instance with string units.
|
// Uses Scripting app's Health API: Health.queryQuantitySamples() with HealthUnit.
|
||||||
|
|
||||||
const SERVER_URL = "http://chronos:9432/ingest";
|
const SERVER_URL = "http://chronos:9432/ingest";
|
||||||
const API_KEY = "333f09ce904e9cbbe3b578fda393be92869122c7222dbccd";
|
const API_KEY = "333f09ce904e9cbbe3b578fda393be92869122c7222dbccd";
|
||||||
|
|
||||||
|
// --- Units for each quantity type ---
|
||||||
|
const U = {
|
||||||
|
kg: HealthUnit.gram(HealthMetricPrefix.kilo),
|
||||||
|
mmHg: HealthUnit.millimeterOfMercury(),
|
||||||
|
bpm: HealthUnit.count().divided(HealthUnit.minute()),
|
||||||
|
count: HealthUnit.count(),
|
||||||
|
percent: HealthUnit.percent()
|
||||||
|
};
|
||||||
|
|
||||||
// Read the most recent sample of a type. Returns { value, startDate } or null.
|
// Read the most recent sample of a type. Returns { value, startDate } or null.
|
||||||
async function readLatest(type, unit) {
|
async function readLatest(type, unit) {
|
||||||
try {
|
try {
|
||||||
const h = new Health();
|
const samples = await Health.queryQuantitySamples(type, {
|
||||||
h.setTypeIdentifier(type);
|
limit: 1,
|
||||||
h.setUnit(unit);
|
sortDescriptors: [{ key: "startDate", order: "reverse" }]
|
||||||
h.setLimit(1);
|
});
|
||||||
h.setDescendingSorting();
|
|
||||||
const samples = await h.quantitySamples();
|
|
||||||
if (!samples || samples.length === 0) {
|
if (!samples || samples.length === 0) {
|
||||||
console.log(`readLatest(${type}): no samples`);
|
console.log(`readLatest(${type}): no samples`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
const s = samples[0];
|
const s = samples[0];
|
||||||
console.log(`readLatest(${type}): value=${s.value} date=${s.startDate}`);
|
const value = s.quantityValue(unit);
|
||||||
return { value: s.value, startDate: new Date(s.startDate) };
|
console.log(`readLatest(${type}): value=${value} date=${s.startDate}`);
|
||||||
|
return { value, startDate: s.startDate };
|
||||||
} catch (e) {
|
} catch (e) {
|
||||||
console.log(`readLatest(${type}): error ${e}`);
|
console.log(`readLatest(${type}): error ${e}`);
|
||||||
return null;
|
return null;
|
||||||
|
|
@ -34,18 +42,17 @@ async function readTodaySum(type, unit) {
|
||||||
try {
|
try {
|
||||||
const start = new Date();
|
const start = new Date();
|
||||||
start.setHours(0, 0, 0, 0);
|
start.setHours(0, 0, 0, 0);
|
||||||
const h = new Health();
|
const samples = await Health.queryQuantitySamples(type, {
|
||||||
h.setTypeIdentifier(type);
|
startDate: start,
|
||||||
h.setUnit(unit);
|
endDate: new Date()
|
||||||
const samples = await h.quantitySamples();
|
});
|
||||||
if (!samples || samples.length === 0) {
|
if (!samples || samples.length === 0) {
|
||||||
console.log(`readTodaySum(${type}): no samples`);
|
console.log(`readTodaySum(${type}): no samples`);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
let total = 0;
|
let total = 0;
|
||||||
for (const s of samples) {
|
for (const s of samples) {
|
||||||
const sd = new Date(s.startDate);
|
total += s.quantityValue(unit);
|
||||||
if (sd >= start) total += s.value;
|
|
||||||
}
|
}
|
||||||
console.log(`readTodaySum(${type}): total=${total}`);
|
console.log(`readTodaySum(${type}): total=${total}`);
|
||||||
return total;
|
return total;
|
||||||
|
|
@ -70,13 +77,13 @@ async function notify(body) {
|
||||||
// --- Read all health metrics ---
|
// --- Read all health metrics ---
|
||||||
console.log("=== Health Sync starting ===");
|
console.log("=== Health Sync starting ===");
|
||||||
|
|
||||||
const weight = await readLatest("bodyMass", "kg");
|
const weight = await readLatest("bodyMass", U.kg);
|
||||||
const bpSys = await readLatest("bloodPressureSystolic", "mmHg");
|
const bpSys = await readLatest("bloodPressureSystolic", U.mmHg);
|
||||||
const bpDia = await readLatest("bloodPressureDiastolic", "mmHg");
|
const bpDia = await readLatest("bloodPressureDiastolic", U.mmHg);
|
||||||
const hr = await readLatest("heartRate", "count/min");
|
const hr = await readLatest("heartRate", U.bpm);
|
||||||
const restingHr = await readLatest("restingHeartRate", "count/min");
|
const restingHr = await readLatest("restingHeartRate", U.bpm);
|
||||||
const steps = await readTodaySum("stepCount", "count");
|
const steps = await readTodaySum("stepCount", U.count);
|
||||||
const spo2 = await readLatest("oxygenSaturation", "%");
|
const spo2 = await readLatest("oxygenSaturation", U.percent);
|
||||||
|
|
||||||
console.log(`Results: weight=${weight?.value} bpSys=${bpSys?.value} bpDia=${bpDia?.value} hr=${hr?.value} rhr=${restingHr?.value} steps=${steps} spo2=${spo2?.value}`);
|
console.log(`Results: weight=${weight?.value} bpSys=${bpSys?.value} bpDia=${bpDia?.value} hr=${hr?.value} rhr=${restingHr?.value} steps=${steps} spo2=${spo2?.value}`);
|
||||||
|
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue