Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/Kr-Yogsa/ECE-BOT/llms.txt

Use this file to discover all available pages before exploring further.

ECE-BOT can display a live MJPEG video feed from a Raspberry Pi camera directly in the operator machine view. The Pi runs a local Flask stream server and a Cloudflare Tunnel that exposes it to the internet. A helper script detects the tunnel’s public URL and posts it to ECE-BOT automatically so the dashboard always points to the current address — no manual environment variable updates required on each restart.

Architecture overview

Raspberry Pi camera


raspberry_pi_camera_stream.py   ←  Flask MJPEG server on :8080


http://localhost:8080/stream


publish_cloudflare_live_url.py  ←  starts cloudflared, detects URL, POSTs to ECE-BOT


https://<random>.trycloudflare.com/stream


ECE-BOT live machine view dashboard
Two Python scripts run concurrently on the Pi: one serves the stream and one manages the tunnel and URL registration.

Requirements

On the Raspberry Pi:
RequirementNotes
Raspberry Pi OS (Bookworm or Bullseye)Camera stack must be enabled
Camera Module (v1, v2, v3, or HQ)Connected and detected by libcamera
picamera2Python camera library
python3-opencvJPEG encoding for MJPEG frames
flaskHTTP server for the stream endpoint
cloudflaredCloudflare Tunnel client binary
requestsPython HTTP client for the publish helper
In ECE-BOT:
VariableValue
MACHINE_LIVE_UPDATE_TOKENA long random secret token shared with the Pi

Setup

1

Enable and verify the camera

Update the Pi and confirm the camera is detected by libcamera:
sudo apt update && sudo apt upgrade -y
libcamera-hello
A preview window should open briefly. If it fails, check that the camera cable is seated correctly and the camera interface is enabled in raspi-config.
2

Install stream dependencies

sudo apt install -y python3-picamera2 python3-opencv
python3 -m pip install flask requests
3

Install cloudflared

Download and install the cloudflared binary for your Pi’s architecture. The official packages are available at https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/downloads/.For a 64-bit Pi OS:
curl -L https://github.com/cloudflare/cloudflared/releases/latest/download/cloudflared-linux-arm64 \
  -o cloudflared
chmod +x cloudflared
sudo mv cloudflared /usr/local/bin/
Verify the install:
cloudflared --version
4

Copy the scripts to the Pi

Copy raspberry_pi_camera_stream.py and publish_cloudflare_live_url.py from the iot/ directory of the ECE-BOT repository to the same directory on the Raspberry Pi.
5

Set the update token in ECE-BOT

In your ECE-BOT deployment environment, set:
MACHINE_LIVE_UPDATE_TOKEN=use-a-long-random-token
Generate a strong token with:
python3 -c "import secrets; print(secrets.token_urlsafe(32))"
The token value you set in ECE-BOT must exactly match the value you pass to publish_cloudflare_live_url.py via --update-token. A mismatch causes the Pi to receive a 401 error when it tries to register the stream URL.
6

Start the camera stream server

In Terminal 1 on the Pi, start the MJPEG stream server:
python3 raspberry_pi_camera_stream.py
The server starts on port 8080. You can verify the local stream from another device on the same network:
http://RASPBERRY_PI_IP:8080/stream
The server also exposes /health (returns {"status": "ok"}) and / (returns route info).
7

Start the Cloudflare tunnel and publish the URL

In Terminal 2 on the Pi, run the publish helper:
python3 publish_cloudflare_live_url.py \
  --app-base-url https://your-ece-bot-app.onrender.com \
  --machine-id cnc \
  --update-token your-live-update-token
The script:
  1. Spawns cloudflared tunnel --url http://localhost:8080.
  2. Watches the cloudflared output for a trycloudflare.com URL.
  3. Appends /stream to form the full stream URL.
  4. POSTs the URL to POST /api/machine-live/<machine-id>/url on ECE-BOT with the update token in the X-Live-Update-Token header.
A successful registration prints:
Published live stream URL: https://example-name.trycloudflare.com/stream

How URL priority works

ECE-BOT resolves the live stream URL in this order:
  1. Database-stored URL — set by the publish_cloudflare_live_url.py script via the API. Takes priority over all environment variables.
  2. Machine-specific env var — e.g. CNC_LIVE_STREAM_URL for machine ID cnc.
  3. Shared fallback env varLIVE_STREAM_URL applied to all machines.
Static environment variables (CNC_LIVE_STREAM_URL, LIVE_STREAM_URL) are still fully supported for deployments with a stable, permanent stream URL. Set them and skip the publish helper entirely if your tunnel URL does not change.

Why auto-update matters

Cloudflare quick tunnel (trycloudflare.com) URLs are ephemeral. Every time cloudflared restarts — including after a Pi reboot — Cloudflare assigns a new random subdomain. Without the publish helper, you would need to manually update an environment variable and redeploy ECE-BOT after every restart. The publish_cloudflare_live_url.py script eliminates that by registering the new URL automatically at startup. ECE-BOT stores it in the database and serves it immediately, with no redeploy needed.
For a stable, permanent URL that does not change on restart, create a named Cloudflare Tunnel (not a quick tunnel) and route it to a domain or subdomain you control. See the Cloudflare Tunnel documentation for setup details.

Script reference

raspberry_pi_camera_stream.py

Starts a Flask HTTP server that captures frames from the Pi camera using picamera2 at 1280×720, encodes them as JPEG at quality 80, and serves them as an MJPEG stream at /stream.
EndpointDescription
GET /Returns JSON route info
GET /healthReturns {"status": "ok"}
GET /streamMJPEG video stream (multipart/x-mixed-replace)

publish_cloudflare_live_url.py

Wraps cloudflared tunnel --url http://localhost:8080, parses its stderr/stdout for the trycloudflare.com URL, and registers it with ECE-BOT.
ArgumentDefaultDescription
--app-base-url(required)ECE-BOT public base URL
--machine-idcncMachine ID to register the stream against
--update-token(required)Must match MACHINE_LIVE_UPDATE_TOKEN in ECE-BOT
--local-service-urlhttp://localhost:8080Local server the tunnel points to
--stream-path/streamPath appended to the tunnel URL
--cloudflared-pathcloudflaredPath to the cloudflared binary
--publish-attempts5Number of retry attempts if the POST fails
--publish-retry-seconds5Seconds to wait between retry attempts

Build docs developers (and LLMs) love