# celesteinter/heartwatch architecture

> Architecture diagram of the GitHub repository celesteinter/heartwatch, generated by GitDiagram from its file tree, README and a sample of source files (last updated 2026-09-29). It is an AI-made overview: check details against the source.

- Interactive diagram: https://gitdiagram.com/celesteinter/heartwatch
- Repository: https://github.com/celesteinter/heartwatch

## Overview

HeartWatch combines an ESP32-S3 wearable prototype with a desktop monitoring and session-analysis app. The documented firmware workflow initializes the OLED and MAX30102, polls optical samples, derives beats per minute, and displays the result. The host app presents live monitoring, persists session samples, and supports history, statistics, activity-classification scaffolding, and optional local-LLM summaries. The live monitor currently uses generated demo data; the ML inference module is explicitly unfinished. Some UI and firmware wiring is inferred only where sampled source supports it.

Main entry points: [`heartwatchapp/data/db.py`](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/db.py) (Database operations), [`heartwatchapp/main.py`](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/main.py) (App entry), [`heartwatchapp/ui/main_window.py`](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/main_window.py) (Main window), [`heartwatchapp/llm/worker.py`](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/worker.py) (LLM worker)

## Diagram (Mermaid)

```mermaid
flowchart TD

subgraph group_firmware["Wearable firmware"]
  node_esp_app["Device app<br/>[main.c]"]
  node_pulse_driver["Pulse driver<br/>[max30102.c]"]
  node_oled_driver["OLED driver<br/>[sh1107.c]"]
end

subgraph group_host_ui["Desktop interface"]
  node_app_entry["App entry<br/>[main.py]"]
  node_main_window["Main window<br/>[main_window.py]"]
  node_live_view["Live monitor<br/>[live_monitor.py]"]
  node_dashboard["Dashboard<br/>[dashboard.py]"]
  node_sessions_view["Session history<br/>[sessions.py]"]
  node_ml_view["ML view<br/>[ml_view.py]"]
end

subgraph group_persistence["Session data"]
  node_writer["Write worker<br/>[writer.py]"]
  node_db_ops["Database operations<br/>[db.py]"]
  node_schema["SQLite schema<br/>[schema.sql]"]
  node_sqlite[("Session database")]
end

subgraph group_analysis["Analysis features"]
  node_stats["Session statistics<br/>[stats.py]"]
  node_classifier["Activity classifier<br/>[inference.py]"]
end

subgraph group_language_model["Local summaries"]
  node_llm_worker["LLM worker<br/>[worker.py]"]
  node_llm_client["Ollama client<br/>[client.py]"]
  node_prompts["Summary prompts<br/>[prompts.py]"]
  node_validation["Summary checks<br/>[validate.py]"]
end

node_wearer(("Wearer"))
node_pulse_sensor{{"MAX30102"}}
node_imu_sensor{{"MPU sensor"}}
node_oled["SH1107 display"]
node_desktop_user(("Desktop user"))
node_ollama["Ollama runtime"]

node_wearer -->|"wears device"| node_esp_app
node_esp_app -->|"initializes, reads"| node_pulse_driver
node_pulse_sensor -->|"optical signal"| node_pulse_driver
node_esp_app -.->|"configures I2C"| node_imu_sensor
node_esp_app -->|"prints BPM"| node_oled_driver
node_oled_driver -->|"updates display"| node_oled
node_desktop_user -->|"starts app"| node_app_entry
node_app_entry -->|"initializes database"| node_db_ops
node_app_entry -->|"starts worker"| node_writer
node_app_entry -->|"starts worker"| node_llm_worker
node_app_entry -->|"opens interface"| node_main_window
node_main_window -->|"shows view"| node_live_view
node_main_window -->|"shows view"| node_dashboard
node_main_window -->|"shows view"| node_sessions_view
node_main_window -->|"shows view"| node_ml_view
node_live_view -->|"queues samples"| node_writer
node_writer -->|"executes writes"| node_db_ops
node_db_ops -->|"reads and writes"| node_sqlite
node_schema -->|"defines tables"| node_sqlite
node_sessions_view -->|"loads session data"| node_db_ops
node_sessions_view -->|"computes summary"| node_stats
node_stats -->|"queries aggregates"| node_db_ops
node_db_ops -->|"exports training CSV"| node_classifier
node_sessions_view -->|"requests summary"| node_llm_worker
node_llm_worker -->|"builds messages"| node_prompts
node_llm_worker -->|"checks and chats"| node_llm_client
node_llm_worker -->|"screens reply"| node_validation
node_llm_client -->|"calls local model"| node_ollama

click node_esp_app "https://github.com/celesteinter/heartwatch/blob/main/HeartWatch/src/main.c"
click node_pulse_driver "https://github.com/celesteinter/heartwatch/blob/main/HeartWatch/src/max30102.c"
click node_oled_driver "https://github.com/celesteinter/heartwatch/blob/main/HeartWatch/src/sh1107.c"
click node_app_entry "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/main.py"
click node_main_window "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/main_window.py"
click node_live_view "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/live_monitor.py"
click node_dashboard "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/dashboard.py"
click node_sessions_view "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/sessions.py"
click node_ml_view "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/ml_view.py"
click node_writer "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/writer.py"
click node_db_ops "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/db.py"
click node_schema "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/schema.sql"
click node_stats "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/stats.py"
click node_classifier "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ml/inference.py"
click node_llm_worker "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/worker.py"
click node_llm_client "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/client.py"
click node_prompts "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/prompts.py"
click node_validation "https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/validate.py"

classDef toneNeutral fill:#f8fafc,stroke:#334155,stroke-width:1.5px,color:#0f172a
classDef toneBlue fill:#dbeafe,stroke:#2563eb,stroke-width:1.5px,color:#172554
classDef toneAmber fill:#fef3c7,stroke:#d97706,stroke-width:1.5px,color:#78350f
classDef toneMint fill:#dcfce7,stroke:#16a34a,stroke-width:1.5px,color:#14532d
classDef toneRose fill:#ffe4e6,stroke:#e11d48,stroke-width:1.5px,color:#881337
classDef toneIndigo fill:#e0e7ff,stroke:#4f46e5,stroke-width:1.5px,color:#312e81
classDef toneTeal fill:#ccfbf1,stroke:#0f766e,stroke-width:1.5px,color:#134e4a
class node_esp_app,node_pulse_driver,node_oled_driver,node_desktop_user toneBlue
class node_app_entry,node_main_window,node_live_view,node_dashboard,node_sessions_view,node_ml_view toneAmber
class node_writer,node_db_ops,node_schema,node_sqlite toneMint
class node_stats,node_classifier toneRose
class node_llm_worker,node_llm_client,node_prompts,node_validation,node_wearer,node_pulse_sensor,node_imu_sensor,node_oled,node_ollama toneIndigo
```

## Components

### Wearable firmware

- [Device app](https://github.com/celesteinter/heartwatch/blob/main/HeartWatch/src/main.c): `HeartWatch/src/main.c`
- [Pulse driver](https://github.com/celesteinter/heartwatch/blob/main/HeartWatch/src/max30102.c): `HeartWatch/src/max30102.c`
- [OLED driver](https://github.com/celesteinter/heartwatch/blob/main/HeartWatch/src/sh1107.c): `HeartWatch/src/sh1107.c`

### Desktop interface

- [App entry](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/main.py): `heartwatchapp/main.py`
- [Main window](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/main_window.py): `heartwatchapp/ui/main_window.py`
- [Live monitor](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/live_monitor.py): `heartwatchapp/ui/live_monitor.py`
- [Dashboard](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/dashboard.py): `heartwatchapp/ui/dashboard.py`
- [Session history](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/sessions.py): `heartwatchapp/ui/sessions.py`
- [ML view](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ui/ml_view.py): `heartwatchapp/ui/ml_view.py`

### Session data

- [Write worker](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/writer.py): `heartwatchapp/data/writer.py`
- [Database operations](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/db.py): `heartwatchapp/data/db.py`
- [SQLite schema](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/schema.sql): `heartwatchapp/data/schema.sql`
- **Session database**

### Analysis features

- [Session statistics](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/data/stats.py): `heartwatchapp/data/stats.py`
- [Activity classifier](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/ml/inference.py): `heartwatchapp/ml/inference.py`

### Local summaries

- [LLM worker](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/worker.py): `heartwatchapp/llm/worker.py`
- [Ollama client](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/client.py): `heartwatchapp/llm/client.py`
- [Summary prompts](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/prompts.py): `heartwatchapp/llm/prompts.py`
- [Summary checks](https://github.com/celesteinter/heartwatch/blob/main/heartwatchapp/llm/validate.py): `heartwatchapp/llm/validate.py`

### Other components

- **Wearer**
- **MAX30102**
- **MPU sensor**
- **SH1107 display**
- **Desktop user**
- **Ollama runtime**

## Connections

- Wearer → Device app: wears device
- Device app → Pulse driver: initializes, reads
- MAX30102 → Pulse driver: optical signal
- Device app → MPU sensor: configures I2C
- Device app → OLED driver: prints BPM
- OLED driver → SH1107 display: updates display
- Desktop user → App entry: starts app
- App entry → Database operations: initializes database
- App entry → Write worker: starts worker
- App entry → LLM worker: starts worker
- App entry → Main window: opens interface
- Main window → Live monitor: shows view
- Main window → Dashboard: shows view
- Main window → Session history: shows view
- Main window → ML view: shows view
- Live monitor → Write worker: queues samples
- Write worker → Database operations: executes writes
- Database operations → Session database: reads and writes
- SQLite schema → Session database: defines tables
- Session history → Database operations: loads session data
- Session history → Session statistics: computes summary
- Session statistics → Database operations: queries aggregates
- Database operations → Activity classifier: exports training CSV
- Session history → LLM worker: requests summary
- LLM worker → Summary prompts: builds messages
- LLM worker → Ollama client: checks and chats
- LLM worker → Summary checks: screens reply
- Ollama client → Ollama runtime: calls local model
