Skip to content

bkahan/commute-optimizer

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

10 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Commute Optimizer

Tracks the real drive time between two places by polling the Google Routes API over a week, then tells you the best time to leave — with far tighter resolution than the wide ranges Google Maps shows.

No dependencies beyond Python 3.9+.

pip install commute-optimizer

That gives you the commute command used below. Running from a source checkout works too — substitute python -m commute for commute.

All data files (config.json, .env, commute.db, the reports, logs) live in the directory you run commute from, so each tracking project can have its own folder.

Example output

The report

commute report writes a self-contained report.html: one section per direction, a chart of median commute vs. departure time (one line per weekday), and tables ranking the best departure slot inside each rush window — including how many minutes it saves over the worst slot.

Example report with per-weekday commute charts and best-departure tables

(Generated from synthetic demo data — regenerate with python docs/_gen_example.py.)

The terminal

Preflight check before a long run:

> commute check
[ok] config: '1600 Amphitheatre Parkway, Mountain View, CA' -> '1 Market St, San Francisco, CA'
[ok] API key found (AIzaSy...XXXX)
[ok] database writable at C:\...\commute-optimizer\commute.db (0 existing samples)
[ok] live route -> 43.6 min now (free-flow 46.3 min, 58.5 km)
[ok] live route <- 43.1 min now (free-flow 46.5 min, 58.9 km)
[ok] estimated API usage: ~938/day, ~6566/week (free tier ~10,000/month)

All checks passed - ready for a long run.

Polling with the auto-stop timer:

> commute poll -d 7d
Polling '1600 Amphitheatre Parkway, Mountain View, CA' <-> '1 Market St, San Francisco, CA'
Rush interval 1 min, off-peak 10 min. Ctrl+C to stop.
Will stop automatically at 2026-07-12 22:59 and generate the report.
[Sun 22:59:28] -> 43.6 min (free-flow 46.3 min)
[Sun 22:59:28] <- 43.1 min (free-flow 46.5 min)
...

And when the report runs, it also prints the summary:

1600 Amphitheatre Parkway, Mountain View, CA -> 1 Market St, San Francisco, CA
  window 07:00-10:00:
    Monday     leave 09:45-10:00 (~28.7 min; worst 51.3 min, saves 22.6)
    Tuesday    leave 09:45-10:00 (~29.4 min; worst 51.5 min, saves 22.1)
    ...

Setup

  1. Get a Google Maps Platform API key with the Routes API enabled (Google Cloud console → APIs & Services → enable "Routes API" → create an API key).

  2. In the folder where you want the data to live, write the example config and edit your addresses:

    commute init
    
  3. Put your API key in a .env file in the same folder:

    GOOGLE_MAPS_API_KEY=your-key-here
    

Usage

Before a long run, verify everything works (config, API key, database, one live API call per direction, and a quota estimate for your poll schedule):

commute check

Start polling. With -d it stops automatically after the given duration and generates the report; without it, it runs until Ctrl+C:

commute poll -d 7d     # a full week, then auto-report
commute poll           # open-ended

Durations accept d/h/m and combinations: 7d, 24h, 90m, 1d12h. Add --no-report to skip the automatic report at the end.

Generate the report any time mid-run (opens report.html in your browser; --no-open to skip that):

commute report

Or watch the run continuously: this regenerates report.html and a day-by-day report (report-daily.html — one curve per calendar date plus a coverage table, so you can see the data filling in before the week is done). Run it in a second terminal alongside poll; refresh the browser to see updates:

commute watch            # updates every 15 minutes
commute watch -i 5m      # or your own interval

To preview the report without waiting a week, seed a synthetic week of two-direction data (refuses to run if the DB already has samples). In an empty folder:

commute init
commute demo
commute report

Surviving sleep and reboots

Instead of running poll in a terminal, register it with the OS so it stays alive for the whole run (run this from your data folder — that's where the scheduled poller will work):

commute schedule install -d 7d   # poll for a week, survive anything
commute schedule status          # is the task/poller alive?
commute schedule remove          # stop and unregister

This relaunches the poller every 5 minutes (a lock file makes that a no-op while one is already running) and resumes after a reboot once you log in. The stop time is stored as an absolute timestamp, so it survives reboots too; when it's reached, the report is generated as usual.

Per platform:

  • Windows — a Task Scheduler task; it can also wake the machine from sleep to poll. Output goes to poll.log (no console window).
  • Linux — a systemd user service + timer (commute-poll). Logs go to journalctl --user -u commute-poll. Runs from login onward; for before-login polling run loginctl enable-linger $USER. Linux can't wake itself from sleep for this; a missed tick fires right after wake.
  • macOS — a launchd LaunchAgent (com.commute-optimizer.poll) logging to poll.log. macOS won't wake for it either — to poll with the lid closed, plug in and run caffeinate -s.

Don't run schedule install while a manually-started poll from an older version is still running — stop that one first, or you'll get duplicate samples.

If you skip all this and the machine sleeps mid-run, collected data is still safe in commute.db — the report's Coverage section will show exactly which stretches were missed.

Config

{
  "origin": "home address",
  "destination": "work address",
  "travel_mode": "DRIVE",
  "track_both_directions": true,
  "poll": {
    "active_window": ["00:00", "23:59"],
    "rush_windows": [["07:00", "10:00"], ["16:00", "19:00"]],
    "rush_interval_min": 1,
    "offpeak_interval_min": 10
  }
}
  • track_both_directions — when true (the default), every tick samples both origin→destination and the reverse, so one run covers your morning and evening commutes.
  • active_window — only poll inside this local-time range (set e.g. ["06:00", "20:00"] to skip the night entirely).
  • rush_windows — during these windows the poller samples every rush_interval_min minutes; otherwise every offpeak_interval_min minutes. The report ranks departure times within these windows (otherwise 3 a.m. always wins).

Cost

The Routes API (traffic-aware) has ~10,000 free calls/month. The default adaptive schedule makes roughly 470 calls/day per direction — ~6,600/week with both directions on, still inside the free tier but without room for a second full week in the same month. Set track_both_directions to false or trim active_window to halve it. Run commute check to see the estimate for your exact schedule.

Samples land in commute.db (SQLite). Transient API failures (network blips, rate limits, 5xx) are retried with backoff (5s/15s/45s) before being recorded as an error row; permanent failures like a bad key fail fast without retries. The report ends each direction with a Coverage section flagging any stretch where sampling stopped (sleep, reboot, repeated errors) despite the schedule expecting data — so you know which medians to trust.

Known limitations (v1)

  • Multi-week data blends together. The report groups by weekday, so two Mondays from different weeks merge into one median curve. Intended use is a single week per commute.db; delete or rename the DB between runs.
  • Wake-from-sleep is Windows-only. On Linux/macOS the scheduled poller resumes right after wake but can't wake the machine itself.
  • No automated tests. The pieces are small and hand-verified, but there's no test suite yet.

About

Tracks the real drive time between two places by polling the Google Routes API over a week, then tells you the best time to leave.

Topics

Resources

License

Stars

0 stars

Watchers

0 watching

Forks

Contributors

Languages