From c65affc66cfd5c2a858ccd9a6df23bb9625a9138 Mon Sep 17 00:00:00 2001 From: Anthony Merlo Date: Fri, 21 Aug 2026 00:05:56 +0100 Subject: [PATCH] fix: use Scriptable Health API (new Health with string units) --- scripts/health-sync.js | 57 ++++++++++++++++-------------------------- 1 file changed, 22 insertions(+), 35 deletions(-) diff --git a/scripts/health-sync.js b/scripts/health-sync.js index 7315461..32041c0 100644 --- a/scripts/health-sync.js +++ b/scripts/health-sync.js @@ -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 = [];