fix: use Scriptable Health API (new Health with string units)

This commit is contained in:
Anthony Merlo 2026-08-21 00:05:56 +01:00
parent 191f5f473b
commit c65affc66c

View file

@ -1,34 +1,24 @@
// Health Sync — reads Apple Health and POSTs to nutrition-mcp server
// Run via Scriptable/Scripting automation at 9:30am daily
// Run via Scriptable automation at 9:30am daily
// Server: http://chronos:9432/ingest
//
// Uses Health.queryQuantitySamples() (current Scripting API).
// The old Health.read() / Health.Types.* / .quantity API was removed.
// Uses Scriptable's Health API: new Health() instance with string units.
const SERVER_URL = "http://chronos:9432/ingest";
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()
};
// --- Helpers ---
// Read the most recent sample of a type. Returns { value, startDate } or null.
async function readLatest(type, unit) {
try {
const samples = await Health.queryQuantitySamples(type, {
limit: 1,
sortDescriptors: [{ key: "startDate", order: "reverse" }]
});
const h = new Health();
h.setTypeIdentifier(type);
h.setUnit(unit);
h.setLimit(1);
h.setDescendingSorting();
const samples = await h.quantitySamples();
if (!samples || samples.length === 0) return null;
const s = samples[0];
return { value: s.quantityValue(unit), startDate: s.startDate };
return { value: s.value, startDate: new Date(s.startDate) };
} catch (e) {
return null;
}
@ -39,14 +29,15 @@ async function readTodaySum(type, unit) {
try {
const start = new Date();
start.setHours(0, 0, 0, 0);
const samples = await Health.queryQuantitySamples(type, {
startDate: start,
endDate: new Date()
});
const h = new Health();
h.setTypeIdentifier(type);
h.setUnit(unit);
const samples = await h.quantitySamples();
if (!samples || samples.length === 0) return null;
let total = 0;
for (const s of samples) {
total += s.quantityValue(unit);
const sd = new Date(s.startDate);
if (sd >= start) total += s.value;
}
return total;
} catch (e) {
@ -54,10 +45,6 @@ async function readTodaySum(type, unit) {
}
}
function isoNow() {
return new Date().toISOString();
}
function todayDate() {
return new Date().toISOString().slice(0, 10);
}
@ -70,13 +57,13 @@ function notify(body) {
}
// --- Read all health metrics ---
const weight = await readLatest("bodyMass", U.kg);
const bpSys = await readLatest("bloodPressureSystolic", U.mmHg);
const bpDia = await readLatest("bloodPressureDiastolic", U.mmHg);
const hr = await readLatest("heartRate", U.bpm);
const restingHr = await readLatest("restingHeartRate", U.bpm);
const steps = await readTodaySum("stepCount", U.count);
const spo2 = await readLatest("oxygenSaturation", U.percent);
const weight = await readLatest("bodyMass", "kg");
const bpSys = await readLatest("bloodPressureSystolic", "mmHg");
const bpDia = await readLatest("bloodPressureDiastolic", "mmHg");
const hr = await readLatest("heartRate", "count/min");
const restingHr = await readLatest("restingHeartRate", "count/min");
const steps = await readTodaySum("stepCount", "count");
const spo2 = await readLatest("oxygenSaturation", "%");
// --- Build samples array — only include metrics that have data ---
const samples = [];