- name
- lifetract
- description
- Query personal life-tracking data: Samsung Health (sleep, steps, heart rate, stress, exercise, weight) + aTimeLogger (18 time categories) + Home Assistant REST (live sensors via ha.junghanacs.com). All records use Denote IDs (YYYYMMDDTHHMMSS) for cross-referencing with denotecli. DB mode (lifetract.db) for instant queries, individual Samsung commands have CSV fallback, and today's DB gaps can use Home Assistant.
# lifetract โ Life Tracking CLI
Query and analyze personal health and time-tracking data.
All records carry Denote IDs (`YYYYMMDDTHHMMSS`) โ same axis as denotecli.
Binary is bundled in the skill directory. Invoke via `{baseDir}/lifetract`.
All output is JSON.
## Why This Exists (not sqlite3/pandas)
Do NOT open lifetract.db or CSV files directly with Python/sqlite3/pandas.
1. **Denote ID mapping** โ Raw CSVs use Samsung's epoch timestamps. The CLI converts them to `YYYYMMDDTHHMMSS` Denote IDs for cross-referencing with denotecli/gitcli.
2. **Multi-source join** โ Sleep, heart rate, steps, stress, exercise, time tracking from different tables/sources, unified per-day. Manual SQL gets this wrong.
3. **JSON for agents** โ Structured output ready for reasoning. No parsing needed.
## When to Use
- "์ค๋ ๋ชธ ์ํ" โ `lifetract today`
- "์ด์ ๋ญ ํ์ง?" โ `lifetract read 2026-03-09`
- "์ต๊ทผ ์๋ฉด ํจํด" โ `lifetract sleep --days 30 --summary`
- "์ด๋ฒ ์ฃผ ์๊ฐ ์ฌ์ฉ" โ `lifetract time --days 7`
- "์ด๋ ๊ธฐ๋ก" โ `lifetract exercise --days 30`
- "30์ผ ์ถ์ด" โ `lifetract timeline --days 30`
## Quick Start
```bash
lifetract status # ๋ฐ์ดํฐ ์์ค + DB ์ํ
lifetract import --exec # CSV+aTimeLogger โ lifetract.db (1.5์ด)
lifetract today # ์ค๋ ํตํฉ ์์ฝ
lifetract read 2025-10-04 # ํน์ ๋ ์ง ์ข
ํฉ (๊ฑด๊ฐ+์๊ฐ์ถ์ )
lifetract timeline --days 30 # 30์ผ ํก๋จ ๋ทฐ
```
## Architecture
```
lifetract.db ์์ โ ๋ชจ๋ ๋ช
๋ น: DB ์ฟผ๋ฆฌ (~90ms) โ JSON
lifetract.db ์์ โ sleep/steps/heart/stress/exercise: CSV ํ์ฑ (~300ms) โ JSON
โ time/timeline/today/read: exit 1
```
- `lifetract import --exec` ์คํ ํ ๋ชจ๋ ์กฐํ๊ฐ DB ๋ชจ๋
- DB ์์ผ๋ฉด ๊ฐ๋ณ Samsung ๋ช
๋ น(`sleep`/`steps`/`heart`/`stress`/`exercise`)๋ง CSV ์ง์ ํ์ฑ
- `time`๊ณผ ์๊ฐ์ถ์ ํฉ์น๋ `timeline`/`today`/`read`๋ DB๊ฐ ์์ผ๋ฉด **exit 1** โ aTimeLogger๋ฅผ ๋ชป ์ฝ์ ๊ตฌ๋ฉ์ 0์ผ๋ก ๋ด๋ณด๋ด์ง ์๋๋ค
## Commands
### status โ ๋ฐ์ดํฐ ์์ค ํ์ธ
```bash
lifetract status
```
```json
{
"samsung_health": {"path": "...", "available": true, "csv_count": 78},
"atimelogger": {"path": "...", "available": true, "size_mb": 5.0},
"database": {
"path": "...", "available": true, "size_mb": 37.3, "mode": "db",
"last_time_block": "2026-07-13", "last_sleep": "2026-07-13", "last_steps": "2026-07-13",
"stale_days": 1, "freshness_checked": true, "warnings": []
}
}
```
**`last_*` / `stale_days` / `warnings` ๊ฐ ์ด ๋ช
๋ น์ ์์ ์ด๋ค.** Samsung export ๋ ์ฌ๋์ด
ํฐ์์ ์์ผ๋ก ๋ด๋ณด๋ด์ผ ํ๋ฅธ๋ค โ ์ ๋ฃ์ด์ฃผ๋ฉด ์กฐ์ฉํ ๋ก๋๋ค. ์ซ์๋ฅผ ์ ๋์ ์ฌ์ค๋ก ๋ฐ๊ธฐ
์ ์ ์ฌ๊ธฐ๋ถํฐ ๋ด๋ผ (ยง์๊ฐ ๊ณ์ฝ 4ํญ).
**`warnings: []` ๋ `freshness_checked: true` ์ผ ๋๋ง "์ฑํ๋ค"๋ ๋ป์ด๋ค.** DB ๊ฐ ์๊ฑฐ๋
๊ฒ์ฌ ์์ฒด๊ฐ ์คํจํ๋ฉด `freshness_checked: false` ์ด๊ณ , ๊ทธ๋์ ๋น ๋ชฉ๋ก์ "์ด์ ์์"์ด ์๋๋ผ
**"๋ณด์ง ์์์"** ์ด๋ค. ๊ฒ์ฌํ์ง ์์ ๊ฒ์ด ํฉ๊ฒฉ์ผ๋ก ๋ณด์ด๋ฉด ๊ทธ๊ฑด ๊ฒ์ฌ๊ฐ ์๋๋ค.
### import โ DB ์์ฑ
```bash
lifetract import # dry-run: ๋งค๋ํ์คํธ ํ์ธ
lifetract import --exec # ์คํ: CSV+aTimeLogger โ lifetract.db
```
202,479 rows, ~38MB, ~2s. Active tables: sleep, sleep_stage, heart_rate, steps_daily,
stress, exercise, weight, atl_category, atl_interval. HRV๋ ์ํดํ๋ค: Samsung export 1,058ํ์
`rmssd`๊ฐ ์๊ณ `binning_data`๋ง ์์ด, ์์ importer๊ฐ ์ ๋ถ `0.0`์ผ๋ก ๋ฃ๋ ๋น ๊ป๋ฐ๊ธฐ์๋ค.
**import ๋ ์๊ธฐ๊ฐ ๋ญ ์์๋์ง ๋งํ๋ค.** `total_rows` ๋ง๊ณ **`status` ๋ฅผ ๋จผ์ ๋ด๋ผ.**
```json
{
"status": "warning",
"warnings": ["stress: 27,598 rows (2026-07-14 12:25) โ 0 โ stream lost [empty]"],
"total_rows": 175941,
"prev_total_rows": 203539,
"tables": [
{"name": "stress", "rows": 0, "status": "empty", "prev_rows": 27598, "delta": -27598}
]
}
```
| ๋ฑ๋ง | ๋ป |
|---|---|
| `ok` | ์ฝ์๊ณ , ์ง๋๋ฒ๋ณด๋ค ์ค์ง ์์๋ค |
| `empty` | ์ฝํ๊ธด ํ๋๋ฐ **0 ํ**. ์ง๋๋ฒ์ ํ์ด ์์๋ค๋ฉด **์์ ๊ฒ** |
| `shrunk` | ์ง๋ import ๋ณด๋ค **์ ๋ค** โ Samsung export ๋ ๋์ ๋คํ๋ผ ์ค๋ฉด ์ด์ํ๋ค |
์ง์ ํ์๋ DB ์ `import_log` ์์ฅ์ ์ฐ๋ค (import ๊ฐ DB ๋ฅผ ์ง์๋ ์ด์๋๋ค).
**์ฒซ import ๋ ๋น๊ต ๋์์ด ์์ผ๋ ๊ฒฝ๊ณ ํ์ง ์๋๋ค** โ `note` ๊ฐ ๊ทธ๋ ๊ฒ ๋งํ๋ค.
์์ฅ์ ์ง์ ์ฝ๋๋ค๋ฉด **`GROUP BY import_id`** ๋ฅผ ์จ๋ผ. `imported_at` ์ ํ import ๋ฅผ
๋ฌถ์ง ๋ชปํ๋ค (์ ํ๋ค์ ์ด ๊ฒฝ๊ณ๋ฅผ ๋์ด 2~3 ๊ฐ๋ก ์ชผ๊ฐ์ ธ ์๋ค).
**`rows` ๋ DB ์ ์ค์ ๋ก ์์ ํ์๋ค** โ ์ฐ๋ฆฌ๊ฐ ๊ฑด๋จ ํ์๊ฐ ์๋๋ผ. ์์ ์ `INSERT` ๊ฒฐ๊ณผ๋ฅผ
์ ๋ณด๊ณ ์ธ์, DB ๊ฐ ๊ฑฐ๋ถํ ํ๋ "imported" ๋ก ์์ฅ์ ๋ฐํ๋ค. **์์ค ๊ฐ๋๊ฐ ๊ทธ ๊ฐ์ง ์ซ์๋ฅผ
๊ธฐ์ค์ผ๋ก ์ผ๊ณ ์์๋ค.**
**`rejected` ๋ ์น๊ฒฉ์ ๋ง์ง ์์ง๋ง ๋ฐ๋์ ๋ณด๊ณ ๋๋ค.** ์ฌ๋ณธ ์ ์๋ ์๊ฐ(1970-01-01 epoch,
2000-01-01)์ ์ค์ ํ๊ณผ, Samsung ์ด ๊ฐ์ ๋ ์ ๋ค์ ๋๊ธฐํํด ์ต์ ๊ฐ์ ํ์ผ๋ก ๋์ฒด๋ ํ์ด๋ค.
์กฐ์ฉํ ๋ฒ๋ฆฌ๋ ๋๊ตฌ๋ ์กฐ์ฉํ ์๋ ๋๊ตฌ์ ๊ฐ์ ์นจ๋ฌต์ด๋ผ ๋งค run ์ด ์ด์ ๋ณ ๊ฐ์๋ฅผ ๋งํ๋ค.
๊ฑฐ์ ์ ์๊ตฌ์ ์ธ ์์ค ์์ฐ์ด ์๋๋ค. ์ ์ baseline ๋ค์๋ accepted rows ๊ฐ ํ๋๋ผ๋ ์ค๋ฉด
ํ์ฌ rejected ๊ฐ ๋ช ๊ฐ๋ `shrunk` ๋ค. ์ ๊ฑฐ์ ์ ์ฑ
์ ์ ์ ๋์กฐํ ๋ช
์์ baseline ์ ํ์ผ๋ก๋ง
๋ค์ด์ค๋ฉฐ, ์ฐ์ ํ์ฉ๋์ ์์ ์ด์ด๋์ง ์๋๋ค.
**๊ฒฝ๊ณ ๊ฐ ํ๋๋ผ๋ ์์ผ๋ฉด ์น๊ฒฉ๋์ง ์๋๋ค โ ์ฒซ import ๋ ์์ธ๊ฐ ์๋๋ค. ์ฐํ ํ๋๊ทธ๋ ์๋ค.**
์์ ์ "๋น ๊ฒ๋ง" ๋ง์๋๋ฐ, Samsung ์ฌ๋ฌ ์คํธ๋ฆผ ์ฑ๊ณต + aTimeLogger ์คํจ ๊ฐ์ **๋ถ๋ถ ์ฑ๊ณต**์ ๊ทธ๋๋ก
์ด์ DB ๊ฐ ๋๋ค. ๊ทธ ์๊ฐ "๋ชป ๋ดค๋ค"๋ฅผ ๋งํ ์๋ฌ ๊ฒฝ๋ก๊ฐ ์ฌ๋ผ์ง๋ค โ DB ๊ฐ ์์ผ๋ ์ดํ๋ก๋ ๊ทธ๋ฅ
`[]` ๋ค. **๋ถ์์ ํ DB ๋ ์ด์ ์๋ฆฌ์ ์ค์ง ์๋๋ค.** ์คํธ๋ฆผ ํ๋๊ฐ ๋น ์ง DB ๋ ๊ทธ ์คํธ๋ฆผ์
๋ํด ์์ํ `[]` ๋ฅผ ๋ตํ๊ณ , ์๋น์(๊ด์ธก์)๋ ๊ทธ ๊ตฌ๋ฉ์ 0 ์ผ๋ก ๊ธฐ๋กํ๋ค.
**`rows` ์์ `invalid` ๋ฅผ ๋ด๋ผ.** ํ์ผ์ ํ์ ์๋๋ฐ ํ์ ํ๋๊ฐ ์๊ฑฐ๋ ์๊ฐยทํ์ ์์น๊ฐ
ํ์ฑ ์ ๋๋ ํ ์๋ค. Samsung ์ด ํค๋ ํ๋๋ง ๊ฐ๋ช
ํ๊ฑฐ๋ ์ซ์ ์๋ฆฌ์ garbage๋ฅผ ๋ฃ์ด๋ ์์ ์
`empty` ๋๋ ์ธก์ ๊ฐ 0์ผ๋ก ๋ณด์๋ค (์ฒซ import ๋ baseline ์ด ์์ด ๊ฒฝ๊ณ ์กฐ์ฐจ ์์๋ค).
**`invalid > 0` ์ด๋ฉด ์น๊ฒฉ์ด ๋งํ๋ค.** ๋น ์ ํ ํ๋๋ 0์ผ๋ก ๋ ์ ์์ง๋ง, ๊ฐ์ด ์๋๋ฐ ์ฝํ์ง
์๋ ๊ฒ์ 0์ด ์๋๋ค.
**`atl_category` ๋ ๋
๋ฆฝ ์คํธ๋ฆผ์ด๋ค.** `time` ์กฐํ๋ ์นดํ
๊ณ ๋ฆฌ๋ฅผ INNER JOIN ํ๋ฏ๋ก,
์นดํ
๊ณ ๋ฆฌ๊ฐ ์ฌ๋ผ์ง๋ฉด ๋ธ๋ก ์๊ฐ ๊ทธ๋๋ก์ฌ๋ **์๊ฐ์ถ์ด ์ ๋ฉธํ๋ค.** ์์ ์์ฅ์ interval ๋ง
์ธ์ ์ด ์์ค์ ๋ชป ๋ดค๋ค (`status: ok`, `warnings: []`, time 30์ผ โ 0). ์ธ์ง ์๋ ์คํธ๋ฆผ์
์์ด๋ ๋ชจ๋ฅธ๋ค. ๊ณ ์ ๋ธ๋ก(์๋ ์นดํ
๊ณ ๋ฆฌ๋ฅผ ๊ฐ๋ฆฌํค๋ ๋ธ๋ก) ๊ฒ์ฌ๋ ํจ๊ป ๋๋ค.
*์ ์๋: 2026-07-14, ๊ธ๋กญ ํ๋๊ฐ 7MB stress ๋์ 1KB histogram ์ ์ง์ด 27,598 ํ์ด
ํต์งธ๋ก 0 ์ด ๋๋๋ฐ import ๋ `"ok"` ๋ผ๊ณ ํ๋ค. ํ
์คํธ๋ ์ด๋ก๋ถ์ด์๋ค. ์ก์ ๊ฑด ์ด ํ์๊ฐ
203,539 โ 175,941 ๋ก ๋จ์ด์ง ๊ฑธ **์ฌ๋์ด ๋์ผ๋ก ๋ณธ ๊ฒ**๋ฟ์ด์๋ค. ์ด์ ๋๊ตฌ๊ฐ ๋งํ๋ค.*
### read โ Denote ID๋ก ์กฐํ
```bash
lifetract read 20250115T000000 # Day ID โ ๊ทธ๋ ์ข
ํฉ
lifetract read 2025-01-15 # ๊ฐ์ ๊ฒฐ๊ณผ (๋ ์ง ๋จ์ถํ)
lifetract read 20250115T233000 # Event ID โ ๊ฐ๋ณ ์๋ฉด/์ด๋
```
Day ์กฐํ ์ ๊ฑด๊ฐ ๋ฉํธ๋ฆญ + aTimeLogger ์๊ฐ ์นดํ
๊ณ ๋ฆฌ + ์๋ฉด ์ธ์
+ ์ด๋ ๋ชจ๋ ํฌํจ.
### today โ ์ค๋ ์์ฝ
```bash
lifetract today
```
```json
// ๋ฐ์ดํฐ ์๋ ๋ (read 2025-10-04 ํํ)
{"date": "2025-10-04", "steps": 41382, "sleep_hours": 1.5, "avg_hr": 93.1, "stress_avg": 20.9, "time_categories": [...], "source": "db"}
// ๋ฐ์ดํฐ ์๋ ๋ โ DB ๊ฐ ๋น ์๋ฆฌ๋ ์๋์ผ๋ก HA ๊ฐ ์ฑ์ (phase 7 read-only fallback)
{"date": "2026-05-26", "steps": 7099, "sleep_hours": 4.8, "avg_hr": 137, "stress_avg": 0, "source": "db+ha", "ha_sources": ["steps","heart_rate","sleep"]}
```
`time_categories` ๊ฐ ๋น๋ฉด JSON ์์ ํค ์์ฒด๊ฐ ๋น ์ง๋ค (omitempty). ๋ฐ์ดํฐ ์๋ ๋ vs ์๋ ๋ ๋ ๋ค ์ ์ ์ถ๋ ฅ.
**์๋ HA fallback (์ค๋ ์๋ฆฌ์ ํ์ )**: DB ๊ฐ ์ค๋ ์๋ฆฌ๋ฅผ ๋น์ ์ผ๋ฉด (Samsung CSV ๊ฐ ์์ง ์ ๋ค์ด์์ผ๋ฉด) `today` ์ `read <์ค๋>` ์ด ์๋์ผ๋ก HA ๋ผ์ด๋ธ ๊ฐ์ผ๋ก ์ฑ์ด๋ค. `source` ๊ฐ `"db+ha"` ๋ก ๋ฐ๋๊ณ , `ha_sources` ๊ฐ ์ด๋ค ํ๋๊ฐ HA ์์ ์๋์ง ์๋ ค์ค๋ค. *๊ณผ๊ฑฐ ๋ ์ง๋ enrichment ์ ๋จ* โ HA recorder ๋ backfill ์๋ฆฌ๊ฐ ์๋๋ค. ๋๋ ค๋ฉด `LIFETRACT_NO_HA=1`. Sleep ์ *์ row ๊ฐ ์ค๋๋ก ์กํ๋ stale* ์๋ฆฌ๋ ๊ฐ์งํด์ HA ๋ก ๋ฎ์ด์ด๋ค (์ต๊ทผ 36h ์ sleep_duration history ๋ฅผ ํฉ์ฐ โ main sleep + nap ๋ ๋ค ์ก์).
### timeline โ ๋ ์ง๋ณ ํก๋จ ๋ทฐ
```bash
lifetract timeline --days 7
lifetract timeline --days 30
```
denotecli ์ ๋๊ณผ ๊ฐ์ ๋ ์ง ํค(`YYYYMMDDT000000`)๋ก ์ ๋ ฌ. ๊ฑด๊ฐ+์๊ฐ+์ด๋ ํตํฉ.
### sleep / steps / heart / stress / exercise
```bash
lifetract sleep --days 7
lifetract sleep --days 30 --summary
lifetract steps --days 7
lifetract heart --days 7
lifetract stress --days 7
lifetract exercise --days 30
```
**๊ฑธ์ ์ ๊ณ์ฝ:** `steps_daily` ๋ ์ธก์ ์ผ๋ง๋ค ์ ํํ ํ ํ์ด๋ค. ๋ ์ง๋ Samsung์
`day_time` ๋ง ์ฝ์ผ๋ฉฐ `create_time` ์ผ๋ก ๋์ ํ์ง ์๋๋ค. `day_time` ์ epoch-ms์
๋ฒฝ์๊ณ ๋ฌธ์์ด ์์ชฝ์ ์ง์ํ๊ณ , ๋ชป ์ฝ๊ฑฐ๋ ๋ฏธ๋๋ฉด invalid๋ก ์น๊ฒฉ์ ๋ง๋๋ค. ๊ฐ์ ๋ ์
์ฌ๋๊ธฐํ ํ์ ์ต์ `update_time` ํ ๊ฑด๋ง ๋จ๊ธฐ๋ฉฐ, ๋์๊ฐ์ ๊ฐ์ด ์ถฉ๋ํ๋ฉด ์์๋ก ๊ณ ๋ฅด์ง
์๊ณ invalid๋ค. DB๋ ๋ ์ง UNIQUE๋ก ๊ฐ์ ๋ถ๋ณ์์ ๊ฐ์ ํ๋ค.
### time โ aTimeLogger ์๊ฐ ์ถ์
```bash
lifetract time --days 7
lifetract time --days 30 --category ๋ณธ์ง
```
์นดํ
๊ณ ๋ฆฌ: ๋ณธ์ง, ์๋ฉด, ๊ฐ์กฑ, ์์ฌ, ๋
์, ์ด๋, ๊ฑท๊ธฐ, ์ํ, ์
ํํ ํฌ, ๋ฎ์ , ์ค๋น, ์ง์์ผ, ์ด๋, ์ผํ, ๋ด์ง, ์ ํ๋ธ, ์งง์ํด์, ์ฌ๊ฐํ๋ (18์ข
)
### export โ ๊ณต๊ฐ์ฉ ๋ด๋ณด๋ด๊ธฐ ๊ณํ
```bash
lifetract export
```
### ha โ Home Assistant REST (live sensors)
```bash
lifetract ha ping # ์ฐ๊ฒฐ ํ์ธ
lifetract ha state heart_rate # ๋๋ฉ์ธ ์ด๋ฆ์ผ๋ก ํ sensor ๊ฐ์ ธ์ค๊ธฐ
lifetract ha state sleep_duration # (๋๋ literal entity_id ๋ OK)
lifetract ha states # ๋ฑ๋ก๋ 24๊ฐ known sensor ์ผ๊ด ์กฐํ
lifetract ha entities # HA ๊ฐ ๋
ธ์ถํ๋ ๋ชจ๋ entity (raw, known ํ๋๊ทธ ํ์)
lifetract ha history sleep_duration --days 7 # 7์ผ์น state ๋ณํ (HA recorder)
```
```json
// ha state heart_rate
{
"entity_id": "sensor.sm_s942n_s26_glgman_heart_rate",
"kind": "heart_rate",
"state": "111.0",
"value": 111,
"unit": "bpm",
"last_changed": "2026-05-17T22:34:11Z",
"attributes": {...}
}
```
**ํ ํฐ**: `pass show 2fa/totp/ha/junghanacs` (primary) โ env `HA_TOKEN` (fallback) โ `~/.lifetract/ha.env`. ํ ํฐ๊ฐ ์์ฒด๋ ์ ๋ commit/push ๊ธ์ง.
**๋๋ฉ์ธ kind**: `sleep_duration`, `steps_daily`, `distance_daily`, `floors_daily`, `heart_rate`, `resting_heart_rate`, `heart_rate_variability`, `weight`, `body_fat`, `height`, `calories_burned`, `active_calories_burned`, `basal_metabolic_rate`, `hydration`, `detected_activity`, `geocoded_location`, `battery`, `sleep_confidence`, `respiratory_rate`, `oxygen_saturation`, `body_temperature`, `blood_glucose`, `systolic_blood_pressure`, `diastolic_blood_pressure` (24์ข
).
์ sensor ์ถ๊ฐ = `lifetract/ha_entities.go` ์ `KnownEntities` ์ ํ ์ค.
**`ha history` ๋์**: HA recorder ๋ *state ๋ณํ ์์ ์๋ง* row ์ ์ฅ. recorder 30์ผ ๋ณด๊ด์ "์๋ ๋ฐ์ดํฐ ๋ณด์กด" ์ด์ง "์๋ ๋ฐ์ดํฐ ์ฑ์์ค" ์ด ์๋. HA ์ธํ๋ผ๊ฐ ๋์์ง ์์ ์ด์ ๋ฐ์ดํฐ๋ ์์ํ ์ ์กํ. ๊ณผ๊ฑฐ๋ Samsung CSV export ๊ฐ ์ ์ผํ ๊ธธ. HA history = *๋ด์ผ๋ถํฐ์ ์ ๋ฆฝ* ์๋ฆฌ.
```json
// ha history sleep_duration --days 7
{
"entity_id": "sensor.sm_s942n_s26_glgman_sleep_duration",
"kind": "sleep_duration",
"unit": "min",
"days": 7,
"from": "2026-05-11T...+09:00",
"to": "2026-05-18T...+09:00",
"count": 2,
"points": [
{"last_changed": "...", "value": 427, "unit": "min", "attributes": {"endTime": "..."}},
...
]
}
```
**ํ์ฌ ์ํ (phase 7 read-only)**: `cmdToday` / `cmdRead <์ค๋>` ์ด DB miss ๋๋ stale sleep ์๋ฆฌ์์ ์๋์ผ๋ก HA `GetState` + `GetHistory` ๋ฅผ ํธ์ถํด ์๋ต์ ์ฑ์์ค๋ค (`source: "db+ha"`, `ha_sources: [...]`). DB upsert ๋ ์๋์ ์ผ๋ก ํ์ง ์๋๋ค. Samsung export ๊ฐ ์๊ตฌ SSOT์ด๊ณ HA recorder ๋ 30์ผ ๋ณด์กฐ๋ฉด์ด๋ผ, ๋ ์๋ ๊ฐ์ ๋ณธ DB์ ํก์ํ์ง ์๋๋ค.
## Flags
| Flag | Default | ์ค๋ช
|
|------|---------|------|
| `--days N` | 7 | ์ฐฝ ๊ธธ์ด (**๋ฌด์๋์ง ์๋๋ค** โ ์๋ ์กฐํฉํ) |
| `--from YYYY-MM-DD` | โ | ์ฐฝ ์์ (ํฌํจ) |
| `--to YYYY-MM-DD` | โ | ์ฐฝ ๋ (**๋ฐฐํ์ **) |
| `--data-dir DIR` | `~/repos/gh/self-tracking-data` | ๋ฐ์ดํฐ ๋ฃจํธ |
| `--shealth-dir DIR` | ์ต์ ์๋๊ฐ์ง | Samsung Health ๋๋ ํ ๋ฆฌ |
| `--summary` | false | ์์ฝ ๋ชจ๋ |
| `--category CAT` | ์ ์ฒด | ์๊ฐ ์นดํ
๊ณ ๋ฆฌ ํํฐ |
| `--exec` | false | import ์คํ ๋ชจ๋ |
### ์ฐฝ ์กฐํฉ โ ๋ชจ๋ ์กฐํฉ์ด ๋ป์ ๊ฐ๋๋ค
| ์กฐํฉ | ์ฐฝ |
|------|-----|
| `--days N` | `[๋ด์ผ-N, ๋ด์ผ)` โ **์ค๋ ํฌํจ ์ ํํ N์ผ** (`1`=์ค๋) |
| `--days N --to T` | `[T-N, T)` โ **T ์ ๋๋๋ N์ผ** |
| `--days N --from F` | `[F, F+N)` โ **F ์ ์์ํ๋ N์ผ** |
| `--from F --to T` | `[F, T)` |
| `--from F` | `[F, ๋ด์ผ)` |
Auf GitHub ansehen