разбор метрик 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
+163
View File
@@ -0,0 +1,163 @@
{
"data": {
"metrics": [
{
"data": [
{
"source": "Device A  ",
"qty": 60,
"date": "2025-06-06 00:02:07 +0300",
"start": "2025-06-06 00:02:07 +0300",
"end": "2025-06-06 11:51:40 +0300"
}
],
"name": "resting_heart_rate",
"units": "count/min"
},
{
"name": "heart_rate",
"units": "count/min",
"data": [
{
"Min": 71,
"source": "Device A  ",
"Avg": 71,
"date": "2025-06-06 00:02:07 +0300",
"start": "2025-06-06 00:02:07 +0300",
"context": "Не задано",
"Max": 71,
"end": "2025-06-06 00:02:07 +0300"
},
{
"start": "2025-06-06 00:05:48 +0300",
"date": "2025-06-06 00:05:48 +0300",
"end": "2025-06-06 00:05:48 +0300",
"Max": 31,
"source": "Device A",
"Min": 31,
"Avg": 31
},
{
"source": "Device A  ",
"Min": 18,
"Max": 18,
"end": "2025-06-06 00:06:54 +0300",
"start": "2025-06-06 00:06:54 +0300",
"Avg": 18,
"date": "2025-06-06 00:06:54 +0300",
"context": "Не задано"
},
{
"context": "Не задано",
"Avg": 67,
"Max": 67,
"start": "2025-06-06 00:13:52 +0300",
"end": "2025-06-06 00:13:52 +0300",
"Min": 67,
"source": "Device A  ",
"date": "2025-06-06 00:13:52 +0300"
},
{
"source": "Device A  ",
"start": "2025-06-06 00:16:29 +0300",
"Min": 57.120105773170690,
"context": "Не задано",
"Max": 57.120105773170690,
"Avg": 57.120105773170690,
"date": "2025-06-06 00:16:29 +0300",
"end": "2025-06-06 00:16:29 +0300"
},
{
"Avg": 67,
"start": "2025-06-06 00:18:17 +0300",
"Min": 67,
"date": "2025-06-06 00:18:17 +0300",
"Max": 67,
"source": "Device A  ",
"end": "2025-06-06 00:18:17 +0300",
"context": "Не задано"
},
{
"Avg": 18,
"end": "2025-06-06 00:26:32 +0300",
"date": "2025-06-06 00:26:32 +0300",
"context": "Не задано",
"start": "2025-06-06 00:26:32 +0300",
"source": "Device A  ",
"Max": 18,
"Min": 18
},
{
"Avg": 33,
"Max": 33,
"Min": 33,
"context": "Сидячий образ жизни",
"date": "2025-06-06 11:30:12 +0300",
"start": "2025-06-06 11:30:12 +0300",
"source": "Device A  ",
"end": "2025-06-06 11:30:12 +0300"
},
{
"start": "2025-06-06 11:30:20 +0300",
"source": "Device A",
"Min": 88,
"Avg": 88,
"end": "2025-06-06 11:30:20 +0300",
"Max": 88,
"date": "2025-06-06 11:30:20 +0300"
},
{
"date": "2025-06-06 11:30:35 +0300",
"end": "2025-06-06 11:30:35 +0300",
"Avg": 37.044306705474884,
"Max": 37.044306705474884,
"start": "2025-06-06 11:30:35 +0300",
"source": "Device A  ",
"context": "Не задано",
"Min": 37.044306705474884
},
{
"source": "Device A  ",
"context": "Сидячий образ жизни",
"date": "2025-06-06 11:33:33 +0300",
"Max": 33,
"Min": 33,
"end": "2025-06-06 11:33:33 +0300",
"Avg": 33,
"start": "2025-06-06 11:33:33 +0300"
},
{
"date": "2025-06-06 11:36:55 +0300",
"start": "2025-06-06 11:36:55 +0300",
"Avg": 16,
"Max": 16,
"Min": 16,
"context": "Сидячий образ жизни",
"source": "Device A  ",
"end": "2025-06-06 11:36:55 +0300"
},
{
"Min": 45,
"Avg": 45,
"context": "Сидячий образ жизни",
"source": "Device A  ",
"Max": 45,
"start": "2025-06-06 11:44:45 +0300",
"end": "2025-06-06 11:44:45 +0300",
"date": "2025-06-06 11:44:45 +0300"
},
{
"source": "Device A  ",
"Avg": 64,
"context": "Сидячий образ жизни",
"Max": 64,
"Min": 64,
"end": "2025-06-06 11:51:40 +0300",
"start": "2025-06-06 11:51:40 +0300",
"date": "2025-06-06 11:51:40 +0300"
}
]
}
]
}
}