====== TIMI ====== //TAMI Inventory Management Interface// //"timi is always at ~/"// TIMI is the combined weekend-hackathon brainchild of TAMI folks building an **audio-visual inventory dataset** for the space — and eventually a **space-aware inventory tagging, logging and querying system**. It is critical infrastructure. It is also complete and utter bullshit. This is a hackerspace. ===== What is TIMI? ===== At its core TIMI is four things: * **SciCam** — an Android camera app that snaps photos (and videos), writes JSON sidecars with EXIF + metadata, exposes a NanoHTTPD REST API, and auto-captures via QR codes. * **GoPro Bridge** — a Flask server that talks to a GoPro over USB WiFi, pulls captures, runs a live preview stream, and does **motion-based auto-capture** with an ROI editor. Writes the same SciCam-compatible sidecars. * **Dashboard** — a Rust TUI that discovers devices via UDP multicast, monitors them, and one-way mirrors captures to a local archive. * **Dataset** — a growing folder of ''images'', ''videos'', and ''.json'' sidecars that describe stuff in the space. The long-term dream: walk into a room, point a camera at an object (or let a fixed camera see it), and have the system know what it is, where it lives, and how many we have. ===== Architecture ===== +-------------+ UDP multicast +-----------------+ | SciCam | <-- 239.255.0.1:9876 -->| Rust Dashboard | | (Android) | | (TUI) | | :8080/api |<------- HTTP/SSE ------> | ~/timi/capture | +-------------+ +-----------------+ | ^ v | MediaStore (Pictures/SciCam...) | | +-------------+ HTTP/Preview | | GoPro Bridge| -------------------------------+ | (Flask) | SciCam sidecars (.json) | USB+WiFi | +-------------+ ==== Components ==== === SciCam Android App === * **REST API** on port 8080 — see the [[timi:api|API Spec]]. * **Photo capture** with CameraX, saved to ''Pictures/SciCam/''. * **Video recording** — toggle with ''POST /record'', saved to ''Movies/SciCam/''. * **JSON sidecars** — every capture gets a ''.json'' buddy with EXIF, camera settings, item ID, tags, and timestamp. Stored in ''Documents/SciCam/''. * **QR auto-capture** — point the camera at a QR code, the app snaps automatically. Great for rapid inventory sweeps. * **SSE stream** — live events at ''/events'' so the dashboard sees captures in real-time. === GoPro Bridge (gopro-scicam) === * **Flask server** connecting to GoPro HERO12 (and compatible) via the **Open GoPro USB WiFi API**. * **Full web UI** — capture button, live MJPEG preview, gallery, sidecar viewer, and a **table-boundary ROI editor**. * **Motion-based auto-capture** — monitors the live preview stream for structural change inside a masked region. Only fires when something actually stays on the table (ignores hands passing through). Adjustable motion and structural thresholds. * **Background sync** — on startup, pulls every photo/video from the GoPro SD card that hasn't been downloaded yet. Persists sync history so clearing local files doesn't cause re-downloads. * **SciCam-compatible sidecars** — writes the same ''*.json'' format as the Android app (item_id, tags, timestamp, camera settings, origin, source="gopro"). Includes a background QR-retry hunter that tries ZBar, CLAHE, adaptive threshold, and morphological close to read tricky codes. * **Live QR detection** — scans preview frames and downloaded images; updates ''item_id'' automatically when a code is found. * **Multicast beacons** — broadcasts UDP presence just like SciCam, so the Rust dashboard can discover it. === Dashboard === * Rust terminal UI. * Auto-discovers devices every 5 s via UDP beacons. * Hotkeys: ''r/R'' refresh, ''s/S'' sync, ''w'' watch SSE, ''a'' add, ''d'' delete, ''q'' quit. * Mirrors ''*.jpg'', ''*.mp4'', and ''*.json'' from devices to ''~/timi/capture''. * Config lives in repo-root ''timi.conf''. === API Clients === * **Go CLI** (''clients/go-scicam'') — curl-friendly wrapper. * **Web client** (''clients/web-scicam'') — vanilla JS, static HTML. ===== Capture Sources ===== Not just one camera — the idea is everything that can see should feed TIMI. ^ Source ^ Status ^ Notes ^ | Mobile (SciCam app) | Working | Primary capture device. CameraX + NanoHTTPD. | | GoPro (gopro-scicam) | Working | Flask bridge over USB WiFi. Preview, auto-capture, ROI mask, background sync, SciCam sidecars. | | Canon 70D | In space | Uses [[https://gitlab.com/entangle/entangle|Entangle]] (libgphoto2 frontend). Could script captures to same sidecar format. | | Lixel 2 Pro | TBD | 3D scanner with cameras. Needs research. | ===== Weekend Hackathon Results ===== The first TIMI sprint produced a working end-to-end pipeline in about 48 hours: * Android app rewritten as API-first: fullscreen preview with IP overlay. * QR detection switched from ZXing to BoofCV — runs on preview frames, no Activity hop. * REST API with OpenAPI 3 spec. * Dashboard built in Rust with auto-discovery and sync. * Go and web clients consuming the API. * Full test suite in ''scicam_api_test.sh''. * **GoPro bridge** added later — brings a rugged wide-angle camera into the TIMI pipeline with motion auto-capture and the same sidecar format. ===== API Quick Reference ===== The SciCam API lives at ''http://:8080''. Critical rule: **''POST'' only for state-changing endpoints; ''GET'' returns 404.** | Method | Endpoint | Purpose | | POST | /capture | Trigger photo | | POST | /record | Toggle video recording | | POST | /settings | Set item_id, tags, lock, debug, capture_alert | | POST | /auto-capture | Enable/disable QR auto-capture | | GET | /status | Current state (item_id, tags, locked, last_qr, ...) | | GET | /captures | List all images/videos with sidecar status | | GET | /photo/last | Download latest JPEG | | GET | /photo/ | Download specific JPEG | | GET | /video/last | Download latest MP4 | | GET | /video/ | Download specific MP4 | | GET | /sidecar/ | Download JSON sidecar | | GET | /events | SSE stream | Full spec: [[https://git.telavivmakers.space/tami/timi/src/branch/master/api_spec.yaml|api_spec.yaml]] ===== Git Repository ===== * **Origin:** [[https://git.telavivmakers.space/tami/timi|git.telavivmakers.space/tami/timi]] * **Local dev desk:** ''~/timi/'' The repo is a multi-component monorepo: timi/ ├── scicam/ # Android app (Kotlin + Gradle Groovy DSL) ├── dashboard/ # Rust TUI ├── clients/ │ ├── go-scicam/ # Go CLI (submodule) │ ├── web-scicam/ # Vanilla JS static client (submodule) │ └── gopro-scicam/ # Flask GoPro bridge (submodule) — KEY PLAYER ├── api_spec.yaml # OpenAPI 3 source of truth ├── timi.conf # Dashboard registry & config └── capture/ # Default local archive (gitignored) ===== Roadmap / Dreams ===== * [ ] Prototype ''PreviewView'' overlay for QR region feedback in SciCam. * [ ] Camera calibration data in sidecars (lens distortion via BoofCV). * [ ] Database sync — non-destructive to existing images/sidecars. * [ ] Canon 70D scripted capture producing TIMI-compatible sidecars. * [ ] Lixel 2 Pro research and integration. * [ ] Space-aware querying: "what's in the CNC room?" "how many stepper motors?" ===== Philosophy ===== * **Treat captures as immutable** — this is an archive and dataset. Don't mess with existing files. * **API-first UI** — the app is primarily a remote-controlled camera. The dashboard and CLI are the main interfaces. * **Bullshit acceptable** — it is a hackerspace. It should work well enough to be useful and broken enough to be fun. ===== Contact / Hacking ===== Ping the usual suspects on Matrix/Discord/Telegram, or just show up at the space and break things. The code is all there in ''~/timi'' on the dev desk. If you improve it, push to Gitea. # Quick start on the dev desk cd ~/timi # Build and install the Android app cd scicam && ./gradlew assembleDebug && adb install app/build/outputs/apk/debug/app-debug.apk # Start the GoPro bridge (needs GoPro in USB Connect mode) cd clients/gopro-scicam && python3 app.py # Start the dashboard cd ~/timi/dashboard && cargo build --release && ./target/release/scicam-dashboard # Test against a device on the network cd ~/timi && ./scicam_api_test.sh