diff --git a/src/lib/withings/__tests__/client.test.ts b/src/lib/withings/__tests__/client.test.ts index e61b8ca49..4335b9e9a 100644 --- a/src/lib/withings/__tests__/client.test.ts +++ b/src/lib/withings/__tests__/client.test.ts @@ -64,6 +64,20 @@ describe("MEASURE_TYPE_MAP", () => { it("maps Withings meastype 35 (legacy SpO2) → OXYGEN_SATURATION", () => { expect(MEASURE_TYPE_MAP[35]).toEqual({ type: "OXYGEN_SATURATION" }); }); + + it("maps Withings meastype 123 (VO2 max) → VO2_MAX", () => { + expect(MEASURE_TYPE_MAP[123]).toEqual({ type: "VO2_MAX" }); + }); +}); + +describe("fetchMeasurements — VO2 max (meastype 123)", () => { + it("decodes a ScanWatch VO2 max reading into VO2_MAX mL/(kg·min)", async () => { + // 42.5 mL/(kg·min) as Withings exponent encoding: value=425, unit=-1. + installFetchMock(fakeGetmeasPayload([{ type: 123, value: 425, unit: -1 }])); + const out = await fetchMeasurements("token"); + expect(out).toHaveLength(1); + expect(out[0]).toMatchObject({ type: "VO2_MAX", value: 42.5 }); + }); }); describe("fetchMeasurements — SpO2 alt code (meastype 35)", () => { diff --git a/src/lib/withings/client.ts b/src/lib/withings/client.ts index 7c1b67ce6..dc9ab3baf 100644 --- a/src/lib/withings/client.ts +++ b/src/lib/withings/client.ts @@ -142,6 +142,9 @@ export const MEASURE_TYPE_MAP: Record // SpO2 under meastype 35 instead of 54. Both target OXYGEN_SATURATION // in percent; the exponent decode handles 0.97 vs 97 transparently. 35: { type: "OXYGEN_SATURATION" }, + // v1.4.25 — VO2 max from the ScanWatch family. Withings reports + // mL/(kg·min) directly, matching the canonical DB unit. + 123: { type: "VO2_MAX" }, }; export interface WithingsMeasure {