feat(measurements): accept indoor CO2, temperature and humidity

Room climate from a home automation system gets three types of its own:
INDOOR_CO2 (ppm), INDOOR_TEMPERATURE (celsius, shown in Fahrenheit for
imperial readers) and INDOOR_HUMIDITY (percent). They arrive through the
existing ingest token (measurements:write, source EXTERNAL), sit in the
environment cluster beside daylight, and the daily rollup carries their
mean, low and high like any spot reading. They never mix with the body
temperatures or with the outdoor environment channels.

The Home Assistant page documents the three types, a rest_command that
sends a room as one request, a single-room automation, and an
importable blueprint (docs/integrations/blueprints) that skips sensors
reporting unknown or non-numeric states, converts Fahrenheit, and
stamps readings to the minute so a retried push is refused rather than
written twice.
This commit is contained in:
Marc-André Bombeck committed 2026-10-21 20:26:15 +02:00
1 parent b76826a5f8
commit cc8ea3dfbb
32 files changed
+463 -9

No files matched your search

@@ -0,0 +1,11 @@
-- Extend `measurement_type` with room-climate readings pushed through the
-- ingest token (source EXTERNAL), for example by a Home Assistant
-- automation: indoor CO2 (ppm), indoor temperature (celsius) and indoor
-- relative humidity (percent).
--
-- Purely additive. IF NOT EXISTS keeps a replay harmless; enum values cannot
-- be dropped in PostgreSQL, so there is no down path.
ALTER TYPE "measurement_type" ADD VALUE IF NOT EXISTS 'INDOOR_CO2';
ALTER TYPE "measurement_type" ADD VALUE IF NOT EXISTS 'INDOOR_TEMPERATURE';
ALTER TYPE "measurement_type" ADD VALUE IF NOT EXISTS 'INDOOR_HUMIDITY';
+8
View File
@@ -1718,6 +1718,14 @@ enum MeasurementType {
STAND_HOURS // count — HealthKit `HKCategoryTypeIdentifierAppleStandHour`. One row per hour in which the person stood (`stood` = 1; an `idle` hour is not stored); cumulative, daily SUM gives the stand-ring hours.
MINDFUL_MINUTES // minutes — HealthKit `HKCategoryTypeIdentifierMindfulSession`. Session length from the sample's own dates; cumulative, daily SUM.
STATE_OF_MIND_VALENCE // valence (−1..1) — HealthKit `HKStateOfMind.valence` (iOS 18+). How pleasant the logged emotion or mood felt, from very unpleasant (−1) to very pleasant (1). A self-report, not a measurement.
// ── v1.44 — room climate from a home automation system ──
// Pushed through the ingest token (`measurements:write`, source EXTERNAL),
// e.g. by a Home Assistant automation. Spot readings: the daily rollup
// carries mean, min and max. Indoor, so never mixed with the outdoor
// environment channels.
INDOOR_CO2 // ppm — indoor carbon dioxide concentration.
INDOOR_TEMPERATURE // celsius — indoor air temperature. Distinct from every body temperature type.
INDOOR_HUMIDITY // percent (0–100) — indoor relative humidity.
AFIB_BURDEN // percent (0–100, scaled ×100 from Apple's 0..1 fraction) — HealthKit `atrialFibrillationBurden` (iOS 16+, AFib History). The share of time the watch estimated in AFib over a week. AWARENESS ONLY — never a HealthLog diagnosis.
@@map("measurement_type")