You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Added v1.5.7 and v1.7 updates to the roadmap, detailing new features like the In-App File Viewer and the FIT Pipeline. Included changes to various modules and dependencies, along with pre-conditions for upcoming versions.
Third tab in the existing `QTabWidget` structure (Tab 1 "Actions", Tab 2 "Dashboards", Tab 3 "Files"). Renders Excel output directly inside the app via AG Grid Community (MIT licence). JSON output is intentionally excluded — Open Folder in Tab 1 is the intended path for JSON.
155
+
156
+
**What changes:**
157
+
-`garmin_app_base.py` — Tab 3 "Files" added to `QTabWidget`. `QComboBox` lists recent output files from `dashboards/` folder (`.xlsx` only), scanned on tab switch. `QWebEngineView` renders selected file via AG Grid. "Open File" button calls `os.startfile(path)` — opens in whatever the system has registered for `.xlsx` (Excel, LibreOffice, WPS).
158
+
-`app/panel_outputs.py` — after a successful dashboard build, Tab 3 file list is refreshed automatically (same pattern as Tab 2 dashboard rescan after build).
159
+
160
+
**What does not change:**
161
+
- Tab 1 and Tab 2 — unchanged
162
+
- Dashboard build pipeline — no changes to specialists or plotters
163
+
- JSON workflow — Open Folder remains the access path
164
+
165
+
**Dependencies:**
166
+
- AG Grid Community (MIT) — loaded via CDN into QWebEngineView. No new Python package. Requires internet on first load unless bundled locally.
167
+
- Offline fallback: if AG Grid fails to load, a plain HTML table is rendered from the XLSX data as fallback.
168
+
169
+
**Licence:** AG Grid Community is MIT-licenced without restrictions. Handsontable CE is explicitly excluded — Commons Clause makes it incompatible with redistribution.
170
+
171
+
---
172
+
152
173
## Planned — v1.6
153
174
154
175
### v1.6 — Dashboard Render Registry
@@ -264,16 +285,97 @@ A dialog in `panel_outputs.py` that replaces the fixed specialist list with free
264
285
265
286
## Planned — v1.7
266
287
267
-
-**Garmin FIT Pipeline & Plugin Architecture**
268
-
The existing Garmin Health pipeline is being rebuilt into a plugin model — `garmin_map.py` → `garmin_health_map.py`, new `garmin_fit_map.py` as a second Garmin source (activity data via API + bulk import). `field_map.py` is being extended to become a source-agnostic broker. Goal: both Garmin sources run as equal pipelines side by side.
288
+
### v1.7 — FIT Pipeline
289
+
290
+
Standalone plugin pipeline for Garmin activity data (.fit files). The existing
291
+
Health pipeline is not modified — the FIT pipeline runs as an independent,
292
+
parallel pipeline alongside it. Full concept in `docs/KONZEPT_fit_pipeline.md`.
Location-aware context collection extended with GPS data from FIT activities
345
+
and a formal state tracking layer (`quality_context.json`).
346
+
347
+
**Fallback chain (coordinates per day):**
348
+
1. GPS start point from .fit (only when GPS track present and bounding box < 50 km)
349
+
2.`quality_context.json` (travel block or home)
350
+
3.`local_config.csv` (manual)
351
+
4. GUI default (home location)
352
+
353
+
**`quality_context.json` — new module `context_quality.py`**
354
+
Single source of truth for which dates were fetched with which coordinates.
355
+
Travel entries imported from `local_config.csv` on sync — CSV cleared to
356
+
header-only after import. Removing a travel block triggers re-fetch of affected
357
+
dates with home coordinates. Sole write authority: `context_quality.py`,
358
+
symmetric to `garmin_quality.py`.
359
+
Validation at CSV import: multiple travel blocks → hard stop. Overlapping
360
+
date ranges → hard stop.
361
+
362
+
**Extreme Events**
363
+
Activity with GPS bounding box > 50 km flagged as `extreme_event: true` in
364
+
`fit_quality_log.json`. Two categories:
365
+
- Slow (< 50 km/h between any two GPS points) → context pull 1× per hour
366
+
- Fast (> 50 km/h between two points) → context pull every 50 km
367
+
368
+
Context pull runs automatically after merge confirmation (if merge candidate)
369
+
or on import. Weather data written directly into activity summary JSON —
370
+
not into `context_data/`. Implemented via `activity_context_plugin.py`
371
+
(same APIs as context pipeline, output only differs).
372
+
Historical data available without time limit (Open-Meteo) — no urgency.
373
+
374
+
*Pre-condition: v1.7.1 stable. FIT pipeline delivering GPS tracks reliably.*
273
375
274
376
---
275
377
276
-
### v1.7.1 — PDF Report
378
+
### v1.7.3 — PDF Report
277
379
278
380
A standalone workflow for generating a formatted health report as PDF — separate from the Create Reports pipeline. Triggered via a dedicated **PDF Report** button in the Outputs section of the GUI (not via the Create Reports dialog, to avoid collision with Daily Update and the existing report workflow).
279
381
@@ -294,8 +396,6 @@ A standalone workflow for generating a formatted health report as PDF — separa
294
396
295
397
**LLM step is fully optional** — report renders completely without it. No API calls, no cloud dependency, no model lock-in. User chooses their own LLM (Open WebUI, ChatGPT, anything).
296
398
297
-
*Pre-condition: v1.7 FIT Pipeline stable — Activity data available via `field_map.py` broker before PDF Report is built.*
Natural companion to `context_dataformat.json` (schema definition, analogous
340
440
to `garmin_dataformat.json`).
341
441
342
-
**`quality_context.json` — Context Location State Tracking**
343
-
344
-
Location-aware state tracking for the context pipeline — analogous to
345
-
`quality_log.json` for the Garmin pipeline.
346
-
347
-
Current problem: `context_writer.already_written()` is a file-existence check
348
-
only. If a travel period is entered in `local_config.csv` after the affected
349
-
days were already downloaded with home coordinates, the next sync silently
350
-
skips those days — wrong weather/pollen data remains without any warning.
351
-
352
-
Concept:
353
-
-`quality_context.json` is the single source of truth for which dates were
354
-
fetched with which coordinates. Home location is the implicit default for
355
-
all dates not explicitly listed.
356
-
- Travel entries are written into the JSON from `local_config.csv` on sync.
357
-
Each date in a travel block gets a `true`/`false` flag (fetched / pending).
358
-
After import, the CSV is cleared back to header-only.
359
-
- Removing a travel block from the JSON triggers a re-fetch of the affected
360
-
dates with home coordinates (old `/raw/` files deleted first).
361
-
- A backup of `quality_context.json` is written before every destructive
362
-
operation. Diff between backup and current JSON determines which dates need
363
-
correction.
364
-
- Validation at CSV import time: multiple travel blocks in one CSV → hard
365
-
stop, no import. Overlapping date ranges with existing JSON blocks → hard
366
-
stop, no import.
367
-
- Home coordinate changes → Schema 2 migration path (not in scope here).
368
-
- Sole write authority: new `context_quality.py` module, symmetric to
369
-
`garmin_quality.py`. `context_collector.py` remains orchestrator and calls
370
-
`context_quality` — it does not write the JSON directly.
371
-
372
-
---
373
-
374
442
**context_data/ Backup**
375
443
376
444
`context_data/` (weather, pollen, air quality, Brightsky) has no backup path and no restore workflow. The mirror covers it when configured, but the mirror is optional and manually triggered. Re-fetching from Open-Meteo is possible but not unlimited for historical ranges. Becomes a must-have once external sources with restricted backfill windows are added (v2.0 multi-source). Trigger: any new source that cannot freely re-fetch its history.
0 commit comments