Vision system for the jailbroken Rabbit R1 (CipherOS + Magisk root). A PC drives everything via ADB over WiFi — no server on the device, no API keys on the R1.
Two modes: Roast Sentinel monitors coffee roasts with Artisan integration, and AI Eye handles general-purpose vision queries.
Start the sentinel, then roast normally in Artisan. It captures photos synced to your roast events and analyzes bean color via Claude Vision.
run_r1-eye eye.py sentinel start --bean "Ethiopia Yirgacheffe"
run_r1-eye eye.py sentinel start --bean "Ethiopia Yirgacheffe" --stream # with live video
run_r1-eye eye.py sentinel start --bean "Test" --debug # raw WebSocket logsWorkflow:
- Start sentinel — WebSocket server starts on port 8765
- Press ON in Artisan — connection established, camera opens
- Press CHARGE — capture loop starts (T=0 reference); stream window opens if
--stream - Captures fire on each event (CHARGE, DRY, FCs, FCe) plus timed intervals (30s/20s/10s by phase)
- Press COOL END — sends DROP, session ends, log saved to
captures/ - Press OFF — sentinel reads the saved
.alogand linksroast_uuidandbatch_nrinto the session log
Session logs land in captures/sentinel_YYYY-MM-DD_HHMM.json and are picked up by the coffee-roasting analysis pipeline.
Artisan WebSocket configuration: see CLAUDE.md.
run_r1-eye eye.py sentinel status # last session summary
run_r1-eye eye.py sentinel log # last session full logGeneral-purpose vision queries — point the R1 camera at anything and ask about it.
run_r1-eye eye.py ask "What's on my desk?"
run_r1-eye eye.py look # capture only (no AI query)
run_r1-eye eye.py status # check device connectivity| Command | Description |
|---|---|
eye.py ask <question> |
Capture + Claude Vision query |
eye.py look |
Capture image only (camera test) |
eye.py deploy |
Push device scripts to R1 |
eye.py status |
Check R1 device connectivity |
eye.py sentinel start [--bean NAME] [--port PORT] [--stream] [--crack] [--debug] |
Start roast sentinel |
eye.py sentinel status |
Last session summary |
eye.py sentinel log |
Last session full log |
eye.py stream start [--resolution RES] [--bitrate RATE] |
Standalone live stream (blocks until Enter) |
eye.py stream stop |
Kill running stream |
eye.py stream status |
Check if stream is running |
All commands are run via run_r1-eye eye.py <command>.
r1-eye is designed to run on a dedicated machine next to the roaster. Deploy via rsync (no git needed on the roaster):
./deploy.sh # quick: .py files + device scripts (~1s)
./deploy.sh --full # full: everything + reinstall depsConfigure SSH alias roaster in ~/.ssh/config for the deploy scripts.
Captures sync automatically at session end (via R1_PUSH_ADDRESS env var). Fallback:
./sync_captures.sh # pull missing JSONs/images from roaster
./sync_captures.sh --dry-run # preview only- Rabbit R1 with CipherOS + Magisk root, connected via WiFi ADB
- grab_power3 running on device
adbinstalled on PC- uv for Python package management
- Artisan 4.0 for roast sentinel integration
- scrcpy 3.x for live streaming (apt version too old — build from source, see CLAUDE.md)
# Clone and enter
git clone https://github.com/frogmoses/r1-eye.git
cd r1-eye
# Create venv and install deps
uv venv .venv --seed
uv pip install anthropic websockets numpy pillow
# Configure secrets
mkdir -p ~/.config/code-projects/r1-eye
cp .env.example ~/.config/code-projects/r1-eye/.env
chmod 700 ~/.config/code-projects/r1-eye
chmod 600 ~/.config/code-projects/r1-eye/.env
# Edit .env — fill in ANTHROPIC_API_KEY and R1_ADB_ADDRESS
# Create wrapper script (injects env vars from .env at runtime)
cat > ~/.local/bin/run_r1-eye << 'WRAPPER'
#!/usr/bin/env bash
set -euo pipefail
set -a
source ~/.config/code-projects/r1-eye/.env
set +a
exec "$PWD/.venv/bin/python" "$@"
WRAPPER
chmod +x ~/.local/bin/run_r1-eye
# Deploy capture scripts to R1
run_r1-eye eye.py deploySee .env.example for the full list. Required:
| Variable | Purpose |
|---|---|
ANTHROPIC_API_KEY |
Claude Vision API key |
R1_ADB_ADDRESS |
R1 WiFi ADB address (e.g. 192.168.1.100:5555) |
R1_PUSH_ADDRESS |
Rsync target for session log push (e.g. user@devbox:~/r1-eye/captures/) |
ARTISAN_SAVE_DIR |
Artisan .alog save directory (default: ~/coffee-roasts) |
For testing without the R1 or real Artisan:
.venv/bin/python fake_artisan.py # simulated 10-min roast timeline
.venv/bin/python fake_artisan.py --fast # compressed 30s timeline
run_r1-eye sim_sentinel.py # full simulation with reference images + real Vision API
run_r1-eye test_artisan_ws.py # raw WebSocket debug server- DROP button unavailable via WebSocket — Artisan's DROP action slot is used by Hottop safety commands. COOL END button sends DROP instead. Ctrl+C also works.
- scrcpy apt package too old — v1.25 doesn't support this device's Android version. Build v3.x from source (see CLAUDE.md).
For architecture, image pipeline details, device internals, and file-level documentation, see CLAUDE.md.