AI-powered 3D print failure detection system using Obico/Spaghetti Detective ML model with MQTT notifications and web UI.
π€ ML-Based Detection - Uses proven Obico/Spaghetti Detective model πΉ RTSP Support - Works with any RTSP camera stream π‘ MQTT Integration - Real-time notifications via MQTT π Web UI - Clean, lightweight monitoring dashboard β‘ GPU Accelerated - NVIDIA GPU support for ML inference π Smart Status - Distinguishes between idle, printing, and failures π€ Standby Mode (v2.0) - Automatically unload ML model to free VRAM when idle ποΈ MQTT/Web Control - Toggle standby mode remotely or via web interface β° Auto-Standby - Automatically enter standby after configurable timeout
- Docker & Docker Compose
- NVIDIA GPU (optional but recommended for better performance)
- NVIDIA Container Toolkit (if using GPU)
- RTSP camera pointed at your 3D printer
- MQTT broker (Mosquitto, etc.)
- Clone the repository
git clone <your-repo-url>
cd print-monitor- Configure your settings
cp .env.example .env
nano .envEdit the following in .env:
RTSP_STREAM_URL- Your camera's RTSP URLMQTT_BROKER_HOST- Your MQTT broker IP/hostnameMQTT_BROKER_PORT- MQTT port (default: 1883)MQTT_USERNAMEandMQTT_PASSWORD- MQTT credentialsMQTT_TOPIC_FAILURE,MQTT_TOPIC_HEARTBEAT,MQTT_TOPIC_CONTROL- Custom topicsSTANDBY_MODE_ENABLED- Enable/disable standby mode (default: true)STANDBY_AUTO_TIMEOUT- Auto-standby timeout in seconds (default: 300)
- Start the services
docker-compose up -d- Access the Web UI
http://your-server-ip:8090
| Variable | Description | Default |
|---|---|---|
RTSP_STREAM_URL |
Camera RTSP stream URL | Required |
MQTT_BROKER_HOST |
MQTT broker hostname/IP | Required |
MQTT_BROKER_PORT |
MQTT broker port | 1883 |
MQTT_USERNAME |
MQTT username (optional) | - |
MQTT_PASSWORD |
MQTT password (optional) | - |
MQTT_TOPIC_FAILURE |
Topic for failure alerts | printer/failure |
MQTT_TOPIC_HEARTBEAT |
Topic for status updates | printer/heartbeat |
MQTT_TOPIC_CONTROL |
Topic for control commands | printer/control |
CHECK_INTERVAL_SECONDS |
Frame check interval | 10 |
DETECTION_THRESHOLD |
Failure threshold (0.0-1.0) | 0.6 |
WEB_PORT |
Web UI port | 8090 |
MOTION_INTENSITY_THRESHOLD |
Min pixel intensity diff to count as changed | 30 |
MOTION_PIXEL_THRESHOLD |
Min changed pixels to register as motion | 500 |
IDLE_TIMEOUT |
Seconds without motion before going idle | 60 |
STANDBY_MODE_ENABLED |
Enable standby mode | true |
STANDBY_AUTO_TIMEOUT |
Auto-standby timeout (seconds) | 300 |
ML_API_CONTAINER_NAME |
ML container name | ml_api |
The DETECTION_THRESHOLD controls sensitivity:
- Lower (0.4-0.5): More sensitive, may have false positives
- Default (0.6): Balanced detection
- Higher (0.7-0.8): Less sensitive, fewer false alarms
The monitor uses frame-to-frame pixel differencing to determine whether the printer is actively printing or idle. This avoids the need for a printer API and works with any printer.
MOTION_INTENSITY_THRESHOLDβ Minimum pixel value difference (0-255) to count a pixel as "changed". Higher values ignore subtle lighting changes. Default:30MOTION_PIXEL_THRESHOLDβ Minimum number of changed pixels to consider motion detected. Higher values require more movement. Default:500IDLE_TIMEOUTβ How many seconds without motion before the status switches to idle. Default:60
When idle, ML failure checks are skipped. If motion is detected while in standby, the monitor automatically exits standby and resumes ML checks.
NEW in v2.0! Save GPU VRAM when not actively printing.
When enabled, standby mode stops the ML API container to free VRAM. Perfect for:
- Shared GPU systems running multiple services
- Saving power when printer is idle
- Reducing heat/noise from GPU
Features:
- Manual Control: Toggle via web UI or MQTT
- Auto-Standby: Automatically enter standby after no activity (default: 5 minutes)
- Quick Resume: ML container restarts in ~5-10 seconds when needed
Configuration:
STANDBY_MODE_ENABLED=true # Enable standby feature
STANDBY_AUTO_TIMEOUT=300 # Auto-standby after 300 seconds (5 min) of idle
ML_API_CONTAINER_NAME=ml_api # Container name to controlControl via MQTT:
# Enter standby mode
mosquitto_pub -h broker-ip -t "printer/control" -m '{"command":"standby"}'
# Resume monitoring
mosquitto_pub -h broker-ip -t "printer/control" -m '{"command":"active"}'Control via Web UI:
- Click "Enter Standby" button in the web dashboard
- Or "Resume Monitoring" to exit standby
Disable Standby Mode:
Set STANDBY_MODE_ENABLED=false to disable standby features entirely. ML container will always run.
| Status | Meaning | When |
|---|---|---|
| π΅ Starting | Initializing | First 5-10 seconds |
| β« Idle | No motion detected | Printer idle, ML checks skipped |
| π’ OK | Print running normally | Motion detected, no failure |
| π΄ Failure | Print failure detected | Failure confidence > threshold |
| π Error | System error | Camera/MQTT/ML API issue |
| π€ Standby | VRAM freed | ML container stopped to save resources |
Topic: MQTT_TOPIC_HEARTBEAT
{
"status": "ok",
"timestamp": "2026-02-02T12:00:00Z",
"mqtt_connected": true,
"ml_api_healthy": true,
"stream_connected": true,
"total_checks": 150,
"failed_checks": 0,
"detection_confidence": 0.25,
"standby_mode": false,
"standby_enabled": true,
"ml_container_running": true
}Topic: MQTT_TOPIC_FAILURE
{
"status": "failure",
"confidence": 0.85,
"timestamp": "2026-02-02T12:00:00Z",
"detections": [[0.85, [512, 384, 128, 96]]]
}Topic: MQTT_TOPIC_CONTROL
Send commands to control the monitor:
{"command": "standby"} // Enter standby mode (stop ML container)
{"command": "active"} // Exit standby mode (start ML container)mqtt:
sensor:
- name: "3D Printer Status"
state_topic: "printer/heartbeat"
value_template: "{{ value_json.status }}"
automation:
- alias: "Print Failure Alert"
trigger:
platform: mqtt
topic: "printer/failure"
action:
service: notify.mobile_app
data:
message: "Print failure! Confidence: {{ trigger.payload_json.confidence * 100 }}%"
title: "π¨ Printer Alert"Use MQTT In node to subscribe to topics and create custom flows.
βββββββββββββββ RTSP ββββββββββββββββ
β Camera βββββββββββββββββββ€Print Monitor β
βββββββββββββββ β Service β
ββββββββ¬ββββββββ
ββββββββββββββββββΌβββββββββββββββββ
β β β
βΌ βΌ βΌ
ββββββββββββ βββββββββββ ββββββββββββ
β ML API β β MQTT β β Web UI β
β (Obico) β β Broker β β :8090 β
ββββββββββββ βββββββββββ ββββββββββββ
- Verify RTSP URL is correct (test with VLC)
- Check network connectivity to camera
- Ensure camera supports RTSP
- Try different stream quality settings
- Verify NVIDIA runtime is available:
docker info | grep -i runtime - Check GPU is detected:
nvidia-smi - View ML API logs:
docker-compose logs ml_api
- Verify broker is running and accessible
- Check credentials are correct
- Test with mosquitto_pub/sub
- Check firewall rules
- Verify RTSP stream is working
- Check logs:
docker-compose logs print-monitor - Ensure sufficient network bandwidth
- CPU: Low usage for frame capture
- GPU: ML inference runs on NVIDIA GPU
- RAM: ~500MB per container
- Network: ~1 frame every 10 seconds
- Storage: Minimal (no video recording)
docker-compose build# All services
docker-compose logs -f
# Specific service
docker-compose logs -f print-monitordocker-compose restart print-monitorMIT License - See LICENSE file for details
- ML Model: Obico (formerly Spaghetti Detective)
- Inspired by the 3D printing community's need for automated monitoring
For issues, questions, or contributions, please open an issue on GitHub.
Built with:
- Obico ML API
- Python, Flask, OpenCV
- Docker, NVIDIA Container Toolkit
- MQTT (Paho)
Made with β€οΈ for the 3D printing community