Skip to content

Releases: dcondrey/location-tracker

v2.1.3

17 Jun 14:47
c276a62

Choose a tag to compare

Fixed

  • Dashboard 500 error: _analyze_movement() in dashboard.py also had the timezone-naive vs timezone-aware datetime crash. All timestamp parsing in dashboard.py now uses _safe_parse_ts().
  • CUSTOM_URL includes port: Browser now opens http://tracker.local:7070 which works reliably without pf forwarding.
  • Bobby's data now visible: The API was returning 500 on every /api/locations request due to the timezone bug. Now returns data correctly.

v2.1.2

17 Jun 14:37
4ffc610

Choose a tag to compare

Fixed

  • Port 80 forwarding now actually works during setup: The pfctl -ef command had capture_output=True which silently swallowed the sudo password prompt, so the rules were never loaded. Removed capture_output so sudo can prompt the user.
  • Verification step: Setup now tests port 80 after starting the daemon and reports whether http://tracker.local is working. If not, it shows the fallback URL with the port number.
  • Cleanup on dns-remove: Also unloads and removes the pf LaunchDaemon.

v2.1.1

17 Jun 14:34
11192c2

Choose a tag to compare

Fixed

  • Timezone crash: Old location data without timezone info caused TypeError: can't subtract offset-naive and offset-aware datetimes in the intelligence engine. All timestamp parsing now normalizes to UTC.
  • Port 80 survives reboot: Setup now installs a LaunchDaemon (/Library/LaunchDaemons/com.locationtracker.pf.plist) that loads pfctl rules at boot. No more manual sudo pfctl after restart.
  • WSGI warning suppressed: The "do not use development server" Flask warning no longer appears in logs.

Upgrade

uv tool uninstall location-tracker && uv tool install location-tracker
location-tracker setup  # re-run to install the boot LaunchDaemon

v2.1.0 - Local Road Snapping + Geofencing

17 Jun 14:13
9508f24

Choose a tag to compare

v2.1.0 - Local Road Snapping, Geofencing, Route Corridors

Local Map Matching (replaces OSRM)

No more third-party API dependency. Road snapping now runs locally using OpenStreetMap data via osmnx + networkx:

  • Downloads the OSM road network for the tracking area on first use (~5 seconds)
  • Caches the graph locally (~5MB) for instant subsequent loads
  • Snaps GPS traces to actual roads using shortest-path routing between nearest nodes
  • Automatically expands coverage when tracking moves to new areas
  • Server-side /api/snap endpoint; frontend calls local API

Quality improvement: Shortest-path routing between GPS nodes produces more accurate road-following than OSRM's match API, especially at intersections and complex junctions.

Geofencing

Set up virtual boundaries around locations and get notified when people enter or leave:

# Add a geofence
location-tracker geofence add "Bob" "Home" 32.745 -117.155 --radius 200

# List active geofences
location-tracker geofence list

# View events
location-tracker geofence events

Also available via REST API: GET/POST /api/geofences, GET /api/geofence-events

Route Corridors

The learning engine now tracks complete trips between known places:

  • Records trip duration, distance, and speed profiles
  • Predicts route duration from weighted historical observations
  • Predicts likely destination when someone departs a known place
  • Speed profiles stored per trip for future turn-zone detection

DB Migration

Automatic migration to schema v4 adds: geofences, geofence_events, route_corridors, route_observations tables.

Upgrade

uv tool uninstall location-tracker && uv tool install location-tracker

v2.0.0 - Intelligent Tracking

17 Jun 07:26
fa61299

Choose a tag to compare

v2.0.0 - Intelligent Learning-Based Tracking

Major release: the polling system now learns from historical behavior and adapts automatically.

Distance-Based Polling

Replaces fixed time-based tiers with distance-aware intervals. At city speeds (~30 km/h), points are captured every ~50 meters (~6 seconds), ensuring paths follow actual roads and capture every turn.

Speed Point Spacing Interval
Walking (5 km/h) 20m ~14s
City (25 km/h) 50m ~7s
Suburban (50 km/h) 100m ~7s
Highway (100 km/h) 150m ~5s

Learning Engine

New intelligence.py module that learns from tracking history:

  • Known Places: Clusters repeated stops within 100m into identified locations
  • Dwell Patterns: Learns how long someone typically stays at each place by day-of-week
  • Departure Prediction: Computes P(departs in next 10 min) and starts aggressive polling before movement begins
  • Speed Zones: Learns turn/deceleration regions and polls more aggressively when approaching them
  • Statistical Weighting: All predictions require 3+ observations with exponential decay (14-day half-life)
  • Cold Start: Automatically backfills from existing location history on first run

Road Snapping

Dashboard now uses OSRM map-matching API to snap GPS traces to actual roads. Raw points shown immediately at low opacity; road-snapped path replaces them async.

Battery-Aware Throttling

Reduces polling frequency when the tracked phone's battery is low (1.5x at 15-30%, 2.5x at 5-15%, 5x below 5%).

Stats

  • 51 tests passing
  • 3 new DB tables (known_places, dwell_observations, speed_zones)
  • Automatic migration from v1.x databases

Upgrade

uv tool uninstall location-tracker && uv tool install location-tracker
location-tracker on  # DB auto-migrates, backfills intelligence

v1.7.0

17 Jun 04:05
068aa94

Choose a tag to compare

v1.7.0 - Intelligent Adaptive Polling

New Movement Analysis Engine

Replaced the simple 4-tier speed check with multi-signal movement analysis that examines up to 10 recent points per person:

State Interval How it's detected
Departing 10s Speed <10 km/h but accelerating (catches the moment someone leaves)
Highway 15s Speed >60 km/h
Arriving 20s Speed <10 km/h and decelerating (catches the moment someone arrives)
Driving 30s Speed 10-60 km/h
Just stopped 30s <2 min stationary (might resume)
Walking 45s Speed 1-10 km/h, steady pace
Recently stopped 2 min 2-10 min stationary (probably parked)
Stationary 5 min 10-30 min stationary (settled in)
Long stationary 10 min >30 min stationary (not going anywhere)

Key improvements

  • Acceleration detection: Compares first-half vs second-half speeds across recent points
  • Progressive stationary backoff: 30s → 2min → 5min → 10min based on how long someone has been still
  • Per-person analysis: Each tracked person is analyzed independently; the fastest-moving person determines the interval
  • Departure/arrival detection: Catches transitions with aggressive polling when movement starts or stops

Upgrade

uv tool uninstall location-tracker && uv tool install location-tracker

v1.6.2

17 Jun 04:01
ef954aa

Choose a tag to compare

Fixed

  • location-tracker on no longer needs sudo: All networking (DNS + pf) is configured once during setup with interactive sudo. The on command just starts Flask on port 7070. macOS loads pf rules from /etc/pf.conf automatically at boot via com.apple.pfctl, so port 80 forwarding persists across reboots without re-running setup.

How it works

  • setup (run once): sudo writes /etc/hosts + /etc/pf.conf + loads rules
  • on (run anytime): starts Flask on 7070, no sudo needed
  • Reboot: macOS auto-loads pf rules → http://tracker.local works immediately

v1.6.1

17 Jun 03:58
d89c965

Choose a tag to compare

Fixed

  • http://tracker.local now actually works: Root cause was stale port: 80 in saved config from v1.4.x, and pf rules not being reloaded on each start
  • Config migration: Old configs with port: 80 automatically corrected to 7070
  • Relative paths fixed: data_file and cookies_file in config are now resolved to absolute paths under ~/.local/share/location-tracker/
  • pf reload on every start: Uses sudo -n (non-interactive) so it works silently when credentials are cached and prints a fallback command when they're not
  • SQLite WAL files excluded from git

How it works now

  1. setup runs sudo for DNS + pf configuration (prompts for password once)
  2. on starts Flask on port 7070 (no sudo needed) and silently reloads pf if sudo is cached
  3. macOS pf transparently redirects tracker.local:80localhost:7070
  4. If pf isn't loaded (e.g. after reboot before running setup), http://tracker.local:7070 still works directly

v1.6.0

17 Jun 03:50
21a4b4a

Choose a tag to compare

v1.6.0 - Quality Audit

Fixed

  • Missing cookies guard: Provider now fails fast with a clear message if cookies.enc doesn't exist, instead of crashing with a cryptic error
  • Cookie validation order: Cookies are now validated before encrypting; previously invalid cookies could be silently encrypted
  • Dead code removed: Removed unused save_history() no-op method

Docs

  • Added Data Directory section documenting where all files are stored (~/.local/share/location-tracker/)
  • Added Troubleshooting section for common issues (DNS, port forwarding, cookies)
  • Fixed stale port references (was "port 80 via sudo", now correctly documents pfctl forwarding)
  • Updated CONTRIBUTING.md import check to include all modules

Upgrade

uv tool uninstall location-tracker && uv tool install location-tracker

v1.5.2

17 Jun 03:31
182a7a4

Choose a tag to compare

Faster startup

  • Lazy imports: pandas and folium are no longer imported at startup. Flask starts in ~200ms instead of ~3s.
  • No wait loop: Browser opens immediately after daemon launch. The browser's own DNS resolution + connection time is enough for Flask to be ready.