# USDA Vision Camera System A comprehensive system for monitoring machines via MQTT and automatically recording video from GigE cameras when machines are active. Designed for Atlanta, Georgia operations with proper timezone synchronization. ## 🎯 Overview This system integrates MQTT machine monitoring with automated video recording from GigE cameras. When a machine turns on (detected via MQTT), the system automatically starts recording from the associated camera. When the machine turns off, recording stops and the video is saved with an Atlanta timezone timestamp. ### Key Features - **🔄 MQTT Integration**: Listens to multiple machine state topics - **📹 Automatic Recording**: Starts/stops recording based on machine states - **📷 GigE Camera Support**: Uses python demo library (mvsdk) for camera control - **⚡ Multi-threading**: Concurrent MQTT listening, camera monitoring, and recording - **🌐 REST API**: FastAPI server for dashboard integration - **📡 WebSocket Support**: Real-time status updates - **💾 Storage Management**: Organized file storage with cleanup capabilities - **📝 Comprehensive Logging**: Detailed logging with rotation and error tracking - **⚙️ Configuration Management**: JSON-based configuration system - **🕐 Timezone Sync**: Proper time synchronization for Atlanta, Georgia ## 🏗️ Architecture ``` ┌─────────────────┐ ┌─────────────────┐ ┌─────────────────┐ │ MQTT Broker │ │ GigE Camera │ │ Dashboard │ │ │ │ │ │ (React) │ └─────────┬───────┘ └─────────┬───────┘ └─────────┬───────┘ │ │ │ │ Machine States │ Video Streams │ API Calls │ │ │ ┌─────────▼──────────────────────▼──────────────────────▼───────┐ │ USDA Vision Camera System │ ├───────────────────────────────────────────────────────────────┤ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ MQTT Client │ │ Camera │ │ API Server │ │ │ │ │ │ Manager │ │ │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ │ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │ │ │ State │ │ Storage │ │ Event │ │ │ │ Manager │ │ Manager │ │ System │ │ │ └─────────────┘ └─────────────┘ └─────────────┘ │ └───────────────────────────────────────────────────────────────┘ ``` ## 📋 Prerequisites ### Hardware Requirements - GigE cameras compatible with python demo library - Network connection to MQTT broker - Sufficient storage space for video recordings ### Software Requirements - **Python 3.11+** - **uv package manager** (recommended) or pip - **MQTT broker** (e.g., Mosquitto, Home Assistant) - **Linux system** (tested on Ubuntu/Debian) ### Network Requirements - Access to MQTT broker - GigE cameras on network - Internet access for time synchronization (optional but recommended) ## 🚀 Installation ### 1. Clone the Repository ```bash git clone https://github.com/your-username/USDA-Vision-Cameras.git cd USDA-Vision-Cameras ``` ### 2. Install Dependencies Using uv (recommended): ```bash # Install uv if not already installed curl -LsSf https://astral.sh/uv/install.sh | sh # Install dependencies uv sync ``` Using pip: ```bash # Create virtual environment python -m venv .venv source .venv/bin/activate # On Windows: .venv\Scripts\activate # Install dependencies pip install -r requirements.txt ``` ### 3. Setup GigE Camera Library Ensure the `python demo` directory contains the mvsdk library for your GigE cameras. This should include: - `mvsdk.py` - Python SDK wrapper - Camera driver libraries - Any camera-specific configuration files ### 4. Configure Storage Directory ```bash # Create storage directory (adjust path as needed) mkdir -p ./storage # Or for system-wide storage: # sudo mkdir -p /storage && sudo chown $USER:$USER /storage ``` ### 5. Setup Time Synchronization (Recommended) ```bash # Run timezone setup for Atlanta, Georgia ./setup_timezone.sh ``` ### 6. Configure the System Edit `config.json` to match your setup: ```json { "mqtt": { "broker_host": "192.168.1.110", "broker_port": 1883, "topics": { "machine1": "vision/machine1/state", "machine2": "vision/machine2/state" } }, "cameras": [ { "name": "camera1", "machine_topic": "machine1", "storage_path": "./storage/camera1", "enabled": true } ] } ``` ## 🔧 Configuration ### MQTT Configuration ```json { "mqtt": { "broker_host": "192.168.1.110", "broker_port": 1883, "username": null, "password": null, "topics": { "vibratory_conveyor": "vision/vibratory_conveyor/state", "blower_separator": "vision/blower_separator/state" } } } ``` ### Camera Configuration ```json { "cameras": [ { "name": "camera1", "machine_topic": "vibratory_conveyor", "storage_path": "./storage/camera1", "exposure_ms": 1.0, "gain": 3.5, "target_fps": 3.0, "enabled": true } ] } ``` ### System Configuration ```json { "system": { "camera_check_interval_seconds": 2, "log_level": "INFO", "api_host": "0.0.0.0", "api_port": 8000, "enable_api": true, "timezone": "America/New_York" } } ``` ## 🎮 Usage ### Quick Start ```bash # Test the system python test_system.py # Start the system python main.py # Or use the startup script ./start_system.sh ``` ### Command Line Options ```bash # Custom configuration file python main.py --config my_config.json # Debug mode python main.py --log-level DEBUG # Help python main.py --help ``` ### Verify Installation ```bash # Run system tests python test_system.py # Check time synchronization python check_time.py # Test timezone functions python test_timezone.py ``` ## 🌐 API Usage The system provides a comprehensive REST API for monitoring and control. ### Starting the API Server The API server starts automatically with the main system on port 8000: ```bash python main.py # API available at: http://localhost:8000 ``` ### Core Endpoints #### System Status ```bash # Get overall system status curl http://localhost:8000/system/status # Response example: { "system_started": true, "mqtt_connected": true, "machines": { "vibratory_conveyor": {"state": "on", "last_updated": "2025-07-25T21:30:00-04:00"} }, "cameras": { "camera1": {"status": "available", "is_recording": true} }, "active_recordings": 1, "uptime_seconds": 3600 } ``` #### Machine Status ```bash # Get all machine states curl http://localhost:8000/machines # Response example: { "vibratory_conveyor": { "name": "vibratory_conveyor", "state": "on", "last_updated": "2025-07-25T21:30:00-04:00", "mqtt_topic": "vision/vibratory_conveyor/state" } } ``` #### Camera Status ```bash # Get all camera statuses curl http://localhost:8000/cameras # Get specific camera status curl http://localhost:8000/cameras/camera1 # Response example: { "name": "camera1", "status": "available", "is_recording": false, "last_checked": "2025-07-25T21:30:00-04:00", "device_info": { "friendly_name": "Blower-Yield-Cam", "serial_number": "054012620023" } } ``` #### Manual Recording Control ```bash # Start recording manually curl -X POST http://localhost:8000/cameras/camera1/start-recording \ -H "Content-Type: application/json" \ -d '{"camera_name": "camera1", "filename": "manual_test.avi"}' # Stop recording manually curl -X POST http://localhost:8000/cameras/camera1/stop-recording # Response example: { "success": true, "message": "Recording started for camera1", "filename": "camera1_manual_20250725_213000.avi" } ``` #### Storage Management ```bash # Get storage statistics curl http://localhost:8000/storage/stats # Get recording files list curl -X POST http://localhost:8000/storage/files \ -H "Content-Type: application/json" \ -d '{"camera_name": "camera1", "limit": 10}' # Cleanup old files curl -X POST http://localhost:8000/storage/cleanup \ -H "Content-Type: application/json" \ -d '{"max_age_days": 30}' ``` ### WebSocket Real-time Updates ```javascript // Connect to WebSocket for real-time updates const ws = new WebSocket('ws://localhost:8000/ws'); ws.onmessage = function(event) { const update = JSON.parse(event.data); console.log('Real-time update:', update); // Handle different event types if (update.event_type === 'machine_state_changed') { console.log(`Machine ${update.data.machine_name} is now ${update.data.state}`); } else if (update.event_type === 'recording_started') { console.log(`Recording started: ${update.data.filename}`); } }; ``` ### Integration Examples #### Python Integration ```python import requests import json # System status check response = requests.get('http://localhost:8000/system/status') status = response.json() print(f"System running: {status['system_started']}") # Start recording recording_data = {"camera_name": "camera1"} response = requests.post( 'http://localhost:8000/cameras/camera1/start-recording', headers={'Content-Type': 'application/json'}, data=json.dumps(recording_data) ) result = response.json() print(f"Recording started: {result['success']}") ``` #### JavaScript/React Integration ```javascript // React hook for system status import { useState, useEffect } from 'react'; function useSystemStatus() { const [status, setStatus] = useState(null); useEffect(() => { const fetchStatus = async () => { try { const response = await fetch('http://localhost:8000/system/status'); const data = await response.json(); setStatus(data); } catch (error) { console.error('Failed to fetch status:', error); } }; fetchStatus(); const interval = setInterval(fetchStatus, 5000); // Update every 5 seconds return () => clearInterval(interval); }, []); return status; } // Usage in component function Dashboard() { const systemStatus = useSystemStatus(); return (
Status: {systemStatus.system_started ? 'Running' : 'Stopped'}
MQTT: {systemStatus.mqtt_connected ? 'Connected' : 'Disconnected'}
Active Recordings: {systemStatus.active_recordings}