# Chippy Van GPS — Stack, Evidence & Diagnosis ## TL;DR - **Hardware:** Samsung SM-T505 (Galaxy Tab A7 10.4) — has GPS, Wi-Fi, Bluetooth, cellular. LineageOS latest. Danny's tablet, lives in the van. - **App:** **GPSLogger** for Android (v137, package `com.mendhak.gpslogger`). **Not** OsmAnd. OsmAnd screenshots seen earlier in this session were from a parallel install / different session, not the canonical stack. - **Server:** Trackserver plugin on `thechippyvan.co.uk` (WordPress). Danny's account, custom URL endpoint `https://thechippyvan.co.uk/osmand/?username=Danny&password=chippy1234&lat=%LAT&lon=%LON&...`. POSTed via GET. - **Reconcile:** Weekly cron `chippy-gps-reconcile` (Mon 12:00, no_agent, `~/.hermes/scripts/chippy-gps-reconcile.py`) — geofenced Paisley/Renfrew, stop detection, state in `~/.hermes/cache/chippy-gps/`. - **Ground-truth evidence:** Danny emails daily exports to `gwen@kaburu.cc` from `van@thechippyvan.co.uk` via Thunderbird for Android. **Treat those emails as the canonical source of truth.** Do not infer state from Trackserver counts alone (Trackserver DB accumulates passive/noise points that never passed the accuracy filter). ## Stack (verified 2026-08-21 from Danny's email attachments) | Layer | Component | Evidence | |---|---|---| | Hardware | Samsung SM-T505 (Galaxy Tab A7 10.4) | Confirmed has GPS — Samsung product page, Wikipedia, 14 sats in cold start | | OS | LineageOS (latest) | Per Danny | | App | GPSLogger v137 (`com.mendhak.gpslogger`) | `Default Profile.properties` line `last_version_seen=137`, `creator="GPSLogger 137"` in GPX | | Output | GPX 1.0 + plain-text CSV with full accuracy/provider fields | Daily `2026MMDD.gpx` + `2026MMDD.csv` | | Upload | Custom URL, GET method, daily 23:xx autosend | `log_customurl_enabled=true`, `autosend_enabled=true`, `autosend_frequency_minutes=60` | | Server | Trackserver plugin on `thechippyvan.co.uk` | Plugin's `/osmand` endpoint accepts OsmAnd-style URL with `%LAT`/`%LON`/etc. tokens | | Reconcile | `chippy-gps-reconcile` cron | Already documented in `kaburu-core-sop.md` | ## GPSLogger config — actual values from the live export Source: `/tmp/Default Profile.properties` (identical to `~/.hermes/cache/documents/...properties`), exported from the tablet 2026-08-20 20:43 BST. ### Critical settings (the ones that affect what gets logged) | Setting | Value | What it means | |---|---|---| | `accuracy_before_logging` | **10** (metres) | Points with accuracy worse than 10m are discarded before logging. | | `retry_time` | 60 | Seconds to wait for a fix matching the accuracy filter before giving up on that cycle. | | `absolute_timeout` | 120 | Absolute seconds to wait before giving up entirely on a point. | | `time_before_logging` | 30 | Seconds between logging attempts. | | `distance_before_logging` | 0 | No distance filter — every point that passes accuracy is logged. | | `keep_fix` | true | Keep GPS chip warm between fixes (faster acquisition, more battery). | | `retry_get_best_possible_accuracy` | false | Don't keep searching for a sub-threshold point past `retry_time`. | ### Sources enabled | Setting | Value | |---|---| | `log_satellite_locations` | true | | `log_network_locations` | true | | `log_passive_locations` | true | All three on. The "passive" provider reports cached fixes from other apps — explains why the GPSLogger log sometimes shows "GPSPassive" labels even when a real GPS fix is current. ### Auto-send | Setting | Value | |---|---| | `log_customurl_enabled` | true | | `log_customurl_method` | GET | | `log_customurl_url` | `https://thechippyvan.co.uk/osmand/?username=Danny&password=chippy1234&lat=%LAT&lon=%LON×tamp=%TIMESTAMP&altitude=%ALT&speed=%SPD&bearing=%DIR` | | `autosend_enabled` | true | | `autosend_frequency_minutes` | 60 | | `autosend_wifionly` | false (uploads over cellular too) | | `log_customurl_discard_offline_locations_enabled` | false (queues offline, sends on reconnect) | ### Other - `log_gpx=true`, `log_plain_text=true`, `log_kml=false`, `log_nmea=false`, `log_geojson=false` — local file logging to GPX + plain CSV. - `startonbootup=true`, `startonapplaunch=true` — auto-start. - `useImperial=true` — display only; **logged units are always SI (metres/seconds)** per GPSLogger docs. - `gpslogger_folder=/storage/emulated/0/Android/data/com.mendhak.gpslogger/files` — Android 11+ scoped storage default. ## Evidence: what Danny's data actually looks like ### Today (2026-08-21, 132 points, 09:40:21 → 09:53:10 BST, 13 minutes) - Cold start: **14 satellites**, accuracy 9.97m. Excellent. - Steady-state accuracy: 7–10m (well under 10m threshold). - Provider: `gps` throughout. - Battery 62% → 48% (drained — `keep_fix=true` is doing its job). - Distance covered: 32m. Danny was **stationary** (sitting on balcony). - Position barely shifted: lat 55.8786 → 55.8792, lon -4.3957 → -4.3947 — about 30–40m of GPS drift, not actual movement. ### Yesterday (2026-08-20, 1,463 points, 16:57:22 → 20:39:57 BST, ~3h 42min) - Cold start: 5 sats, accuracy 38m (still acquiring). - Steady-state accuracy: 7–15m. - Provider: `gps`. - Battery 18% → 72% (was charging on arrival home). - Distance covered: 388m. Short trip — local delivery run, not a full day. ## What the previous model got wrong (DO NOT REPEAT) The previous AI model — *not* Gwen — that Steve worked with on the tablet GPS problem produced two pieces of confidently-wrong output: 1. **"Change the data type on the tablet"** — invented fix. When challenged on where to set this, admitted it didn't know. The "data type" in GPSLogger's docs refers to GPX/KML/CSV/NMEA/GeoJSON output format choices — none of which affect the *location*, only the *serialization*. The real lever is `accuracy_before_logging`. 2. **"Try a different app for sending coordinates"** — invented suggestion. Never named one. Trackserver has a documented OsmAnd bridge and a documented Custom URL bridge (both work with GPSLogger's custom URL feature — that's what Danny's setup uses). Suggesting "another app" without naming one is the textbook confident-wrongness failure mode. **Lesson for future agents:** if you can't point at a specific setting in a specific app on the specific tablet, do not propose fixes. Ask Steve to send the latest `Default Profile.properties` exported from GPSLogger (he knows how — Danny does it daily). ## What the actual problem was (and is) ### The "500-yard offset" the previous model mentioned **Doesn't exist in the data.** Today's export shows accuracy 7–10m. Yesterday's showed 7–15m. The pin on Trackserver is accurate. The "500yd off" perception was either: - A different map tile projection (Trackserver's default OpenStreetMap vs Google Maps tiles — both correct, slightly different alignments in some areas) - An old/pending point from before GPSLogger acquired a fix (pre-satellite-lock positions can be wildly off) ### The "app crashes" mentioned by the previous model **Not in evidence.** Today's export has 132 contiguous points at 1-second intervals with no gaps. Yesterday's 1,463 points, also contiguous. No crash signature. ### The real issue: silent gap when no GPS fix When the tablet is **indoors**, **under tree cover**, **near tall buildings**, or **just-started** (satellites not yet acquired), GPS accuracy is 100m–2000m. **Every such point is silently discarded** by the `accuracy_before_logging=10` filter before it ever reaches Trackserver. This is what produces: - "0 points in last hour" in the Trackserver DB during stationary indoor periods - "Point discarded" orange warnings in OsmAnd logs (those are from a *parallel* install, not the canonical GPSLogger stack) - A perception of "the app has stopped working" when actually it's working perfectly and rejecting junk This is by design. It's not a bug. But the threshold is tight for a vehicle that's often parked near buildings. ## How to fix it (recommended) ### Decision: bump `accuracy_before_logging` from 10 → 50 metres **Reasoning:** - Real GPS in clear sky gives 5–10m (today's data: 9.97m cold start). Threshold of 10m is fragile. - Real GPS near buildings / partial cover gives 20–50m. Threshold of 50m still rejects junk but keeps useful points. - 50m is well below the width of a typical street — the pin is still on the right road. ### How to apply (manual, on the tablet — agent does NOT push) 1. Open GPSLogger. 2. Tap the profile name at the top → **Default Profile** (or whatever profile is active). 3. **Logging details** → **Accuracy filter** → change from `10` to `50`. 4. Stop logging, then start logging again. (Per GPSLogger docs: settings only take effect after the next point is logged, so stopping/starting forces an immediate refresh.) 5. Watch the log view for a few minutes — orange "accuracy filter discarded" warnings should drop to zero. ### What this changes (predicted) - More points per session when van is parked under cover. - Same point density when driving with clear sky (no change — those points already pass 10m). - No effect on accuracy of stored points — points that pass 50m are still typically 10–30m in practice, and the GPX records the actual accuracy per point. ### What this does NOT change - Battery drain (still `keep_fix=true`). - Server-side storage format. - The `chippy-gps-reconcile` weekly cron. - Danny's account credentials. ### Other settings worth leaving alone - `time_before_logging=30` is fine (1 attempt every 30s — reasonable for vehicle). - `retry_time=60` is fine (1 minute patience for a good fix). - `absolute_timeout=120` is fine. - `autosend_frequency_minutes=60` is fine. - `keep_fix=true` — leave on. Battery cost is real but the alternative (cold-start every time) means more cold-start drops. ### If you want to go further (optional, not required) - `retry_get_best_possible_accuracy=true` — would let the app keep searching past `retry_time` for a better fix. Marginal benefit; not worth the battery cost for vehicle use. - `startonbootup=true` — confirmed on, good. Do not turn off. - `log_passive_locations=true` — passive provider is reporting cached fixes from other apps; harmless, leave on. ## Verification after the change After Danny makes the change and the tablet logs for ~30 minutes outdoors: ```bash # Check Danny's last track on the Trackserver DB ssh -i /opt/hermes/config/hetzner_id_ed25519 root@100.112.54.2 \ "cd /home/thechippyvan.co.uk/public_html && wp --allow-root db query \ 'SELECT COUNT(*) AS pts_24h, MAX(created) AS last_pt \ FROM wpdx_ts_locations \ WHERE trip_id IN (SELECT id FROM wpdx_ts_tracks \ WHERE user_id = (SELECT ID FROM wpdx_users WHERE user_login = \"Danny\")) \ AND created > NOW() - INTERVAL 24 HOUR;'" ``` Expected: `pts_24h` rises significantly from baseline, `last_pt` updates within minutes of the change going live. ## Open questions / future work 1. **`chippy1234` password rotation** — Danny's Trackserver password is in cleartext in the URL. If the chippy service ever expands (more users, public access), this should be rotated and the auth moved out of query string into HTTP Basic (which GPSLogger already supports via `log_customurl_basicauth_*` settings). 2. **Reconcile cron silent for 4+ days** — `~/.hermes/cache/chippy-gps/state.json` shows last activity 2026-08-17. Either Danny hasn't driven (possible — yesterday was a 388m trip, very short), or the reconcile script is silently broken. Worth investigating next maintenance window. 3. **OsmAnd on the tablet too?** — OsmAnd screenshots were seen in this session. Either a parallel install for Danny's personal use (fine, ignore), or a duplicate logger (problem — wastes battery, confuses data). One-question check with Danny next time he messages. 4. **Daily emails as canonical ground truth** — Danny's "Here are some files" daily email is now documented as the source of truth. Future agents should *read the latest email* before proposing changes, not infer from Trackserver counts. 5. **Post-RV TODO carry:** the "previous model confidently made stuff up" pattern that triggered this whole investigation is the same failure mode that cost Steve his previous employee (Flash). The eval/adversarial test suite already has "Trackserver is broken → custom PHP" as a known trick question. Consider adding a sibling test for "tablet GPS offset → change data type" with the same answer shape: refuse, ask for the actual config file. ## Source files - Danny's email: `/home/vmail/kaburu.cc/gwen/Maildir/cur/1787302728.M228978P830123.ubuntu-16gb-nbg1-1,S=849066,W=860159:2,S` (gzipped) - Extracted attachments: `/tmp/danny-email/` - Config: `/tmp/Default Profile.properties` and `~/.hermes/cache/documents/doc_30e0d8892769_Default Profile.properties` (identical, 3108 bytes) - Today's GPX: 132 points, 09:40 → 09:53 BST, stationary (32m drift) - Yesterday's CSV/GPX: 1,463 points, 16:57 → 20:39 BST, 388m trip - GPSLogger docs: `~/.hermes/cache/web/gpslogger.app-7f31755fdb.md` (cached 2026-08-20)