{"id":51221306,"url":"https://github.com/philipf/gotta-go","last_synced_at":"2026-06-28T07:31:03.948Z","repository":{"id":367698852,"uuid":"1241111161","full_name":"philipf/gotta-go","owner":"philipf","description":"Person Real Time Information (RTI) e-ink display for busses and trains services in Wellington NZ","archived":false,"fork":false,"pushed_at":"2026-06-27T06:53:09.000Z","size":2255,"stargazers_count":0,"open_issues_count":3,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-06-27T08:13:33.521Z","etag":null,"topics":["eink","esp32","lilygo","metlink"],"latest_commit_sha":null,"homepage":"","language":"C","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"apache-2.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/philipf.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":"NOTICE","maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-05-17T01:08:45.000Z","updated_at":"2026-06-27T06:52:57.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/philipf/gotta-go","commit_stats":null,"previous_names":["philipf/gotta-go"],"tags_count":1,"template":false,"template_full_name":null,"purl":"pkg:github/philipf/gotta-go","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philipf%2Fgotta-go","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philipf%2Fgotta-go/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philipf%2Fgotta-go/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philipf%2Fgotta-go/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/philipf","download_url":"https://codeload.github.com/philipf/gotta-go/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/philipf%2Fgotta-go/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34881384,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-28T02:00:05.809Z","response_time":54,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["eink","esp32","lilygo","metlink"],"created_at":"2026-06-28T07:31:02.238Z","updated_at":"2026-06-28T07:31:03.934Z","avatar_url":"https://github.com/philipf.png","language":"C","funding_links":[],"categories":[],"sub_categories":[],"readme":"# GottaGo\n\n\u003e You're half-awake, crossing the kitchen at 7am. The bus leaves in four minutes. **Do you know that yet?**\n\nGottaGo is a network of ambient e-ink transit radiators that answer the only question that matters in the morning rush: **when do I need to leave the house?**\n\nStandard transit apps tell you when the bus *arrives*. That forces you to subtract your walk time, subtract how long you've been standing there, and decide whether to move — all before your first coffee. GottaGo removes that maths entirely. It tells you **LEAVE IN 7 MIN** and nothing else, glanceable from across the room, with zero taps, zero unlocking, zero squinting.\n\n---\n\n## What it looks like\n\n*The screenshots below are live frames rendered straight off the Worker — real Metlink data, real battery telemetry, no mock-ups.*\n\n### The morning commute — bus and train, side by side\n\n![Commute screen — dual countdown, bus and train](docs/UI/GottaGo_Commute.png)\n\nThe left column tracks the bus. The right tracks the train. The hero number is **LEAVE IN** — not arrival time — so there's no maths to do at 7am.\n\nThis frame also shows what happens when things go sideways, because reality rarely cooperates. The train's next departure is **cancelled**, struck through in place so the change is explained rather than silently dropped. Delayed and early departures wear `DELAYED` / `EARLY` chips, and the `RUN`/`MISSED` tags on the top row tell you whether the imminent service is still catchable. The unaffected column stays untouched, so the contrast itself tells you which side has the problem.\n\n### Off-peak — a glanceable two-month calendar\n\n![Calendar screen — current and next month, side by side](docs/UI/GottaGo_Calendar.png)\n\nOutside commute hours the radiator stops being a transit board and becomes ambient furniture. The dual-month calendar highlights today and shades weekends and New Zealand public holidays — here, King's Birthday (Mon 1 Jun) and Matariki (Fri 10 Jul) — a quiet, useful default for the hours when no bus matters.\n\n### Idle — a dad joke to fill the gap\n\n![Idle screen — a dad joke](docs/UI/GottaGo_IdleJoke.png)\n\nWhen there's genuinely nothing to show, the panel rotates through dad jokes rather than sitting blank. It's e-ink, so a joke costs zero power to keep on the wall.\n\nThe small battery indicator in the corner of every frame is rendered server-side from the voltage each radiator reports, so you can read the charge from across the room too.\n\n---\n\n## How it works\n\nThe architecture follows a single principle: **Dumb Radiator, Smart Edge**.\n\n![GottaGo solution architecture — radiator, Cloudflare Worker, KV, Metlink and public holidays](docs/architecture/gotta-go-solution-architecture.png)\n\nEach radiator — a 4.7\" e-ink panel running on a LiPo battery, flush-mounted on a fridge or bedside surface — does exactly one thing: wake up, fetch a frame from the cloud, flush the raw pixels to the screen, and go back to sleep for 2–3 minutes.\n\nAll the work happens at the edge:\n\n- A **Cloudflare Worker** (TypeScript) determines the active profile phase from server time, queries the Metlink Stop Predictions API, computes leave countdowns with walk time and comfort buffers, renders the full layout using [Satori](https://github.com/vercel/satori) and the DejaVu Sans Bold typeface, and encodes the result as a gzip-compressed 1-bit 960×540 BMP.\n- The radiator receives the compressed frame, decompresses it, and flushes the raw byte array directly to the EPD panel buffer — no JSON parsing, no schedule logic, no maths.\n- The Worker also returns the next sleep duration in an `X-Sleep-Seconds` header, so every scheduling decision lives at the edge — the firmware never evaluates a timetable. Metlink is queried uncached per frame, comfortably within its rate limit at household scale.\n\nWhen Wi-Fi fails or the Worker is unreachable, the panel holds its last good frame indefinitely — e-ink consumes zero power to maintain an image.\n\n### Hardware\n\nEach radiator is built from three components (~$83 NZD total):\n\n![LilyGO T5 4.7\" e-paper display with ESP32-S3](docs/UI/lilygo-t5-47-device.jpg)\n\n| Component | Part |\n| --- | --- |\n| Panel \u0026 board | [LilyGO T5 4.7\" e-paper with ESP32-S3](https://github.com/Xinyuan-LilyGO/LilyGo-EPD47) |\n| Power | 2000 mAh LiPo battery |\n| Enclosure | Custom 3D-printed chassis with rear neodymium magnet slots |\n\nThe panel renders at native **960×540, 1-bit monochrome**, landscape. No backlight, no glow, no notification sounds. It blends into the room.\n\n---\n\n## Documentation\n\n| Document | Description |\n| --- | --- |\n| [PRD](docs/PRD/GottaGo%20PRD.md) | Full product requirements, screen layout spec, functional \u0026 non-functional requirements |\n| [UI/UX Design Reference](docs/UI/GottaGo%20-%20UI_UX%20Design%20Reference.md) | Screen scenarios, design rationale, do/don't build guidance |\n| [OpenAPI 3.1 spec](docs/api/openapi.yaml) | Authoritative radiator ↔ Worker wire contract |\n| [Glossary](docs/glossary.md) | Ubiquitous language — every term used in conversation, config, code, and docs |\n| [Worker Architecture](docs/worker-architecture.md) | Canonical guide to how Worker code is built — pillars, gateway/feature/endpoint patterns, conventions, and the reasoning behind them |\n| [Architecture Decision Records](docs/adr/README.md) | The *why* behind contested choices — indexed, with the lean-ADR style for new records |\n| [Reference](docs/reference/) | External-contract detail too granular for an ADR — e.g. [Metlink stop predictions](docs/reference/metlink-stop-predictions.md) (field maps, sample payloads, verified stop IDs) |\n\n---\n\n## Built with an AI-assisted workflow\n\nThis project is developed using an AI-assisted engineering workflow powered by [Claude Code](https://claude.ai/code). Design decisions are captured as ADRs, the domain language is formalised in a living glossary, and the implementation is driven by vertical slices from the PRD — all in close collaboration with an AI agent.\n\n---\n\n## License\n\nLicensed under the [Apache License 2.0](LICENSE). You're free to use, modify, and distribute this — including commercially — provided you retain the copyright and license notices. The software is provided \"as is\", without warranty of any kind.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilipf%2Fgotta-go","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fphilipf%2Fgotta-go","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fphilipf%2Fgotta-go/lists"}