Real-time kite monitoring: when2fly, where2fly.
![]() Dashboard Stream cards, live count, suggest a source |
![]() Notifications Subscriptions per source, threshold, channel |
![]() Admin — Dashboard Pending sources, broadcast |
![]() Admin — Sources Source list, manage streams |
Every time you want to fly, you check the weather and wind, drive to the beach—and the wind’s gone. If someone’s already flying, you know it’s flyable. KiteScope watches live video from various streaming platforms, detects how many kites are in the frame, and when the count hits your threshold, notifies you via LINE or Telegram.
— Made by SCX, a robotics nerd who loves stunt kites.
- Docker and Docker Compose
- (Optional) LINE Channel and/or Telegram Bot for login and notifications
-
Clone and enter the repo:
git clone https://github.com/SeanChangX/KiteScope.git cd KiteScope -
Copy the example env file and edit if needed:
cp env.example .env
-
Start all services:
docker compose up -d
-
Set the admin password first. Open http://localhost:3000/admin. If no admin exists yet, the app shows a setup form: choose a username and password and submit. Then log in with those credentials. All other use (sources, bots, users) depends on having an admin account.
-
Use the app:
- http://localhost:3000 — Dashboard (streams and counts), suggest a source, link to History and Notifications.
- http://localhost:3000/login — Sign in with LINE or Telegram.
- http://localhost:3000/notifications — Manage your alert subscriptions (after login).
[ Browser ] ---- [ Frontend ] ---- [ Backend ]
| |
| Auth, DB, notification worker
|
[ go2rtc ] ---- [ Vision: ingest + detect ] ---- counts + frames
Docker runs four services: frontend (port 3000), backend, vision, and go2rtc. Data is stored in a single SQLite volume; the detection model is in a separate volume or uploaded via the admin UI.
Sources are added by an admin (or approved from user suggestions). You provide a URL and optional location (for weather in notifications). The system detects the type from the URL.
| Type | Description |
|---|---|
| HTTP snapshot | A single image URL (JPEG/PNG). |
| MJPEG | MJPEG stream URL. |
| RTSP | rtsp:// URL. |
| go2rtc | Stream added in go2rtc (container on port 1984). Use the go2rtc snapshot or stream URL. |
| YouTube Live | youtube.com / youtu.be live URLs. Servers may be rate-limited by YouTube. |
Credentials stay on the backend and are not exposed to the frontend.
The vision service needs a detection model to report kite counts. Without a model, counts stay at 0.
- CPU path (default): upload an ONNX model where class 0 is kite.
- Coral Edge TPU (optional): upload a compiled Edge TPU TFLite model. When a
.tflitemodel is selected and a Coral TPU is available, inference runs on the TPU.
In the admin UI go to Settings → Model settings: upload the model file (.onnx for CPU, .tflite for Coral) or place it in the vision model volume and select it there. Confidence and other options can be set in the same page.
For the full export, quantization, and Coral compilation workflow, see vision/scripts/README.md.
KiteScope can offload detection to a Google Coral Edge TPU:
- Model: use a YOLO-style Edge TPU model where class 0 is kite.
- Docker mapping (USB Coral example, vision service):
- Uncomment in
docker-compose.yml/docker-compose.dev.yml:- /dev/bus/usb:/dev/bus/usb
- Uncomment in
- Environment:
DETECT_DEVICE=auto(default): use Coral when detected, otherwise CPU.DETECT_DEVICE=cpu: force CPU ONNX backend.DETECT_DEVICE=edgetpu: force Coral (falls back to CPU if no TPU).
To confirm which backend is used, open Admin → Dashboard and check the System status card: it shows whether the detector is running on CPU (ONNX) or Coral Edge TPU, and whether a TPU was detected.
Users subscribe per source: threshold, optional release threshold (hysteresis), channel (LINE or Telegram), and cooldown. When the smoothed count reaches the threshold and stays above until the release level, one notification is sent (count, weather for the source location, and a snapshot on Telegram). LINE and Telegram credentials are configured in Admin → Settings → Bot settings. Admins can also send a one-off broadcast to all or selected users from the admin dashboard.
Use the dev Compose file for local work with hot reload:
docker compose -f docker-compose.dev.yml up| Service | URL |
|---|---|
| Frontend | http://localhost:5173 |
| Backend | http://localhost:8000 |
| Vision | http://localhost:9000 |
| go2rtc | http://localhost:1984 |
The frontend dev server proxies /api to the backend. For LINE or Telegram login locally, expose the app via a tunnel (e.g. ngrok or cloudflared) and set the callback/domain to that URL.
This project is licensed under the MIT License - see the LICENSE file for details.



