разбор метрик HAE: фикстуры, канонизация, парсер

- tmp/research/fixtures.py собирает фикстуры из архива, вычищая измерения и
  сохраняя порядок ключей, форму литералов, выравнивание меток и невидимые
  символы; шесть фикстур в internal/hae/testdata
- internal/canon — общий дом канонической формы, полноты и хеша: числа читаются
  литералом через json.Number, округление до 12 значащих цифр
- internal/hae — разбор секции metrics, вывод слоя по метрике, разделение схем
  сна, координаты интервалом; recover внутри Parse, фаззинг
- миграция bucket и docs/database.md
This commit is contained in:
av
2026-08-01 17:31:41 +03:00
parent 3e93dd95b4
commit 01d0de59df
18 changed files with 3693 additions and 21 deletions
+281
View File
@@ -0,0 +1,281 @@
{
"data": {
"metrics": [
{
"units": "hr",
"data": [
{
"rem": 0.89195271872064281,
"inBed": 0,
"awake": 4.3396901109717361,
"deep": 0.68835541253715609,
"asleep": 0,
"totalSleep": 4.0716939170300220,
"source": "Device A  ",
"core": 6.2052788381114499,
"inBedStart": "2025-06-04 22:34:34 +0300",
"sleepEnd": "2025-06-05 05:22:26 +0300",
"inBedEnd": "2025-06-05 05:22:26 +0300",
"date": "2025-06-05 00:00:00 +0300",
"sleepStart": "2025-06-04 22:34:34 +0300"
},
{
"inBedStart": "2025-06-05 22:43:20 +0300",
"deep": 0.38341974910703597,
"rem": 0.43532011302795238,
"core": 5.152708504451071,
"date": "2025-06-06 00:00:00 +0300",
"inBed": 0,
"inBedEnd": "2025-06-06 07:57:39 +0300",
"asleep": 0,
"source": "Device A  ",
"sleepStart": "2025-06-05 22:43:20 +0300",
"awake": 9.638151247778914,
"sleepEnd": "2025-06-06 07:57:39 +0300",
"totalSleep": 4.4003075324079272
}
],
"name": "sleep_analysis"
},
{
"name": "apple_stand_hour",
"data": [
{
"source": "Device A",
"date": "2025-06-05 07:00:00 +0300",
"qty": 8
},
{
"source": "Device A",
"qty": 8,
"date": "2025-06-05 08:00:00 +0300"
},
{
"qty": 8,
"date": "2025-06-05 09:00:00 +0300",
"source": "Device A"
},
{
"qty": 8,
"source": "Device A",
"date": "2025-06-05 10:00:00 +0300"
},
{
"source": "Device A",
"date": "2025-06-05 12:00:00 +0300",
"qty": 8
},
{
"source": "Device A",
"date": "2025-06-05 13:00:00 +0300",
"qty": 8
},
{
"date": "2025-06-05 15:00:00 +0300",
"qty": 8,
"source": "Device A"
},
{
"source": "Device A",
"qty": 8,
"date": "2025-06-05 19:00:00 +0300"
},
{
"source": "Device A",
"qty": 8,
"date": "2025-06-05 20:00:00 +0300"
},
{
"source": "Device A",
"qty": 8,
"date": "2025-06-05 21:00:00 +0300"
},
{
"source": "Device A",
"qty": 8,
"date": "2025-06-06 02:00:00 +0300"
},
{
"source": "Device A",
"date": "2025-06-06 08:00:00 +0300",
"qty": 8
},
{
"qty": 8,
"date": "2025-06-06 09:00:00 +0300",
"source": "Device A"
},
{
"source": "Device A",
"date": "2025-06-06 10:00:00 +0300",
"qty": 8
}
],
"units": "count"
},
{
"units": "kJ",
"name": "active_energy",
"data": [
{
"qty": 0.94633004162661996,
"source": "Device A  ",
"date": "2025-06-05 00:24:00 +0300"
},
{
"source": "Device A  ",
"date": "2025-06-05 00:25:00 +0300",
"qty": 0.22385813552875930
},
{
"source": "Device A  ",
"date": "2025-06-05 00:26:00 +0300",
"qty": 0.22385813552875930
},
{
"source": "Device A  ",
"date": "2025-06-05 00:27:00 +0300",
"qty": 0.27046667301884517
},
{
"qty": 0.23659841288096517,
"date": "2025-06-05 00:28:00 +0300",
"source": "Device A  "
},
{
"qty": 0.23659841288096517,
"source": "Device A  ",
"date": "2025-06-05 00:29:00 +0300"
},
{
"source": "Device A  ",
"qty": 0.23659841288096517,
"date": "2025-06-05 00:30:00 +0300"
},
{
"qty": 4.3538077885409284,
"source": "Device A  ",
"date": "2025-06-06 11:47:00 +0300"
},
{
"date": "2025-06-06 11:48:00 +0300",
"qty": 4.3538077885409284,
"source": "Device A  "
},
{
"date": "2025-06-06 11:49:00 +0300",
"qty": 4.3538077885409284,
"source": "Device A  "
},
{
"date": "2025-06-06 11:50:00 +0300",
"source": "Device A  ",
"qty": 2.1847867270334114
},
{
"date": "2025-06-06 11:51:00 +0300",
"qty": 2.1847867270334114,
"source": "Device A  "
},
{
"source": "Device A  ",
"date": "2025-06-06 11:52:00 +0300",
"qty": 3.3347070079576802
},
{
"source": "Device A  ",
"date": "2025-06-06 11:53:00 +0300",
"qty": 0.96620370889283594
}
]
},
{
"data": [
{
"qty": 51.209189787471513,
"source": "Device A  ",
"date": "2025-06-05 00:16:00 +0300"
},
{
"date": "2025-06-05 02:16:00 +0300",
"source": "Device A  ",
"qty": 62.091594303847203
},
{
"qty": 496.11595771813635,
"date": "2025-06-05 04:16:00 +0300",
"source": "Device A  "
},
{
"date": "2025-06-05 06:16:00 +0300",
"qty": 89.502763665053950,
"source": "Device A  "
},
{
"date": "2025-06-05 08:16:00 +0300",
"source": "Device A  ",
"qty": 15.145830153758666
},
{
"date": "2025-06-05 10:16:00 +0300",
"source": "Device A  ",
"qty": 96.442927435831922
},
{
"date": "2025-06-05 12:20:00 +0300",
"qty": 16.490675484303301,
"source": "Device A  "
},
{
"date": "2025-06-05 22:19:00 +0300",
"qty": 25.801867024959922,
"source": "Device A  "
},
{
"qty": 23.750315211285474,
"source": "Device A  ",
"date": "2025-06-06 00:16:00 +0300"
},
{
"qty": 21.676280750344913,
"date": "2025-06-06 02:16:00 +0300",
"source": "Device A  "
},
{
"date": "2025-06-06 04:16:00 +0300",
"source": "Device A  ",
"qty": 108.159159427689
},
{
"date": "2025-06-06 06:16:00 +0300",
"qty": 14.548300046808019,
"source": "Device A  "
},
{
"source": "Device A  ",
"qty": 22.843350035832434,
"date": "2025-06-06 08:16:00 +0300"
},
{
"date": "2025-06-06 11:30:00 +0300",
"source": "Device A  ",
"qty": 90.14058990512054
}
],
"units": "ms",
"name": "heart_rate_variability"
},
{
"name": "six_minute_walking_test_distance",
"units": "m",
"data": [
{
"date": "2025-06-05 05:46:00 +0300",
"source": "Device A",
"qty": 745
}
]
}
]
}
}