Add comprehensive test suite for USDA Vision Camera System
- Implemented main test script to verify system components and functionality. - Added individual test scripts for camera exposure settings, API changes, camera recovery, maximum FPS, MQTT events, logging, and timezone functionality. - Created service file for system management and automatic startup. - Included detailed logging and error handling in test scripts for better diagnostics. - Ensured compatibility with existing camera SDK and API endpoints.
This commit is contained in:
4
.gitignore
vendored
4
.gitignore
vendored
@@ -59,8 +59,8 @@ config_production.json
|
|||||||
.DS_Store
|
.DS_Store
|
||||||
Thumbs.db
|
Thumbs.db
|
||||||
|
|
||||||
# Camera library cache
|
# Camera SDK cache
|
||||||
python demo/__pycache__/
|
camera_sdk/__pycache__/
|
||||||
|
|
||||||
# Test outputs
|
# Test outputs
|
||||||
test_output/
|
test_output/
|
||||||
|
|||||||
2
.vscode/settings.json
vendored
2
.vscode/settings.json
vendored
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"python.analysis.extraPaths": [
|
"python.analysis.extraPaths": [
|
||||||
"./python demo"
|
"./camera_sdk"
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
46
README.md
46
README.md
@@ -10,7 +10,7 @@ This system integrates MQTT machine monitoring with automated video recording fr
|
|||||||
|
|
||||||
- **🔄 MQTT Integration**: Listens to multiple machine state topics
|
- **🔄 MQTT Integration**: Listens to multiple machine state topics
|
||||||
- **📹 Automatic Recording**: Starts/stops recording based on machine states
|
- **📹 Automatic Recording**: Starts/stops recording based on machine states
|
||||||
- **📷 GigE Camera Support**: Uses python demo library (mvsdk) for camera control
|
- **📷 GigE Camera Support**: Uses camera SDK library (mvsdk) for camera control
|
||||||
- **⚡ Multi-threading**: Concurrent MQTT listening, camera monitoring, and recording
|
- **⚡ Multi-threading**: Concurrent MQTT listening, camera monitoring, and recording
|
||||||
- **🌐 REST API**: FastAPI server for dashboard integration
|
- **🌐 REST API**: FastAPI server for dashboard integration
|
||||||
- **📡 WebSocket Support**: Real-time status updates
|
- **📡 WebSocket Support**: Real-time status updates
|
||||||
@@ -19,6 +19,38 @@ This system integrates MQTT machine monitoring with automated video recording fr
|
|||||||
- **⚙️ Configuration Management**: JSON-based configuration system
|
- **⚙️ Configuration Management**: JSON-based configuration system
|
||||||
- **🕐 Timezone Sync**: Proper time synchronization for Atlanta, Georgia
|
- **🕐 Timezone Sync**: Proper time synchronization for Atlanta, Georgia
|
||||||
|
|
||||||
|
## 📁 Project Structure
|
||||||
|
|
||||||
|
```
|
||||||
|
USDA-Vision-Cameras/
|
||||||
|
├── README.md # Main documentation (this file)
|
||||||
|
├── main.py # System entry point
|
||||||
|
├── config.json # System configuration
|
||||||
|
├── requirements.txt # Python dependencies
|
||||||
|
├── pyproject.toml # UV package configuration
|
||||||
|
├── start_system.sh # Startup script
|
||||||
|
├── setup_timezone.sh # Time sync setup
|
||||||
|
├── usda_vision_system/ # Main application
|
||||||
|
│ ├── core/ # Core functionality
|
||||||
|
│ ├── mqtt/ # MQTT integration
|
||||||
|
│ ├── camera/ # Camera management
|
||||||
|
│ ├── storage/ # File management
|
||||||
|
│ ├── api/ # REST API server
|
||||||
|
│ └── main.py # Application coordinator
|
||||||
|
├── camera_sdk/ # GigE camera SDK library
|
||||||
|
├── demos/ # Demo and example code
|
||||||
|
│ ├── cv_grab*.py # Camera SDK usage examples
|
||||||
|
│ └── mqtt_*.py # MQTT demo scripts
|
||||||
|
├── tests/ # Test files
|
||||||
|
│ ├── test_*.py # System tests
|
||||||
|
│ └── legacy_tests/ # Archived development files
|
||||||
|
├── notebooks/ # Jupyter notebooks
|
||||||
|
├── docs/ # Documentation files
|
||||||
|
└── storage/ # Recording storage
|
||||||
|
├── camera1/ # Camera 1 recordings
|
||||||
|
└── camera2/ # Camera 2 recordings
|
||||||
|
```
|
||||||
|
|
||||||
## 🏗️ Architecture
|
## 🏗️ Architecture
|
||||||
|
|
||||||
```
|
```
|
||||||
@@ -46,7 +78,7 @@ This system integrates MQTT machine monitoring with automated video recording fr
|
|||||||
## 📋 Prerequisites
|
## 📋 Prerequisites
|
||||||
|
|
||||||
### Hardware Requirements
|
### Hardware Requirements
|
||||||
- GigE cameras compatible with python demo library
|
- GigE cameras compatible with camera SDK library
|
||||||
- Network connection to MQTT broker
|
- Network connection to MQTT broker
|
||||||
- Sufficient storage space for video recordings
|
- Sufficient storage space for video recordings
|
||||||
|
|
||||||
@@ -90,7 +122,7 @@ pip install -r requirements.txt
|
|||||||
```
|
```
|
||||||
|
|
||||||
### 3. Setup GigE Camera Library
|
### 3. Setup GigE Camera Library
|
||||||
Ensure the `python demo` directory contains the mvsdk library for your GigE cameras. This should include:
|
Ensure the `camera_sdk` directory contains the mvsdk library for your GigE cameras. This should include:
|
||||||
- `mvsdk.py` - Python SDK wrapper
|
- `mvsdk.py` - Python SDK wrapper
|
||||||
- Camera driver libraries
|
- Camera driver libraries
|
||||||
- Any camera-specific configuration files
|
- Any camera-specific configuration files
|
||||||
@@ -519,13 +551,13 @@ python check_time.py
|
|||||||
# Check camera connections
|
# Check camera connections
|
||||||
ping 192.168.1.165 # Replace with your camera IP
|
ping 192.168.1.165 # Replace with your camera IP
|
||||||
|
|
||||||
# Verify python demo library
|
# Verify camera SDK library
|
||||||
ls -la "python demo/"
|
ls -la "camera_sdk/"
|
||||||
# Should contain mvsdk.py and related files
|
# Should contain mvsdk.py and related files
|
||||||
|
|
||||||
# Test camera discovery manually
|
# Test camera discovery manually
|
||||||
python -c "
|
python -c "
|
||||||
import sys; sys.path.append('./python demo')
|
import sys; sys.path.append('./camera_sdk')
|
||||||
import mvsdk
|
import mvsdk
|
||||||
devices = mvsdk.CameraEnumerateDevice()
|
devices = mvsdk.CameraEnumerateDevice()
|
||||||
print(f'Found {len(devices)} cameras')
|
print(f'Found {len(devices)} cameras')
|
||||||
@@ -579,7 +611,7 @@ df -h storage/
|
|||||||
|
|
||||||
# Test camera initialization
|
# Test camera initialization
|
||||||
python -c "
|
python -c "
|
||||||
import sys; sys.path.append('./python demo')
|
import sys; sys.path.append('./camera_sdk')
|
||||||
import mvsdk
|
import mvsdk
|
||||||
devices = mvsdk.CameraEnumerateDevice()
|
devices = mvsdk.CameraEnumerateDevice()
|
||||||
if devices:
|
if devices:
|
||||||
|
|||||||
66
camera_sdk/README.md
Normal file
66
camera_sdk/README.md
Normal file
@@ -0,0 +1,66 @@
|
|||||||
|
# Camera SDK Library
|
||||||
|
|
||||||
|
This directory contains the core GigE camera SDK library required for the USDA Vision Camera System.
|
||||||
|
|
||||||
|
## Contents
|
||||||
|
|
||||||
|
### Core SDK Library
|
||||||
|
- **`mvsdk.py`** - Python wrapper for the GigE camera SDK
|
||||||
|
- Provides Python bindings for camera control functions
|
||||||
|
- Handles camera initialization, configuration, and image capture
|
||||||
|
- **Critical dependency** - Required for all camera operations
|
||||||
|
|
||||||
|
## Important Notes
|
||||||
|
|
||||||
|
⚠️ **This is NOT demo code** - This directory contains the core SDK library that the entire system depends on for camera functionality.
|
||||||
|
|
||||||
|
### SDK Library Details
|
||||||
|
- The `mvsdk.py` file is a Python wrapper around the native camera SDK
|
||||||
|
- It provides ctypes bindings to the underlying C/C++ camera library
|
||||||
|
- Contains all camera control functions, constants, and data structures
|
||||||
|
- Used by all camera modules in `usda_vision_system/camera/`
|
||||||
|
|
||||||
|
### Dependencies
|
||||||
|
- Requires the native camera SDK library (`libMVSDK.so` on Linux)
|
||||||
|
- The native library should be installed system-wide or available in the library path
|
||||||
|
|
||||||
|
## Usage
|
||||||
|
|
||||||
|
This SDK is automatically imported by the camera modules:
|
||||||
|
```python
|
||||||
|
# Imported by camera modules
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
|
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "camera_sdk"))
|
||||||
|
import mvsdk
|
||||||
|
```
|
||||||
|
|
||||||
|
## Demo Code
|
||||||
|
|
||||||
|
For camera usage examples and demo code, see the `../demos/` directory:
|
||||||
|
- `cv_grab.py` - Basic camera capture example
|
||||||
|
- `cv_grab2.py` - Multi-camera capture example
|
||||||
|
- `cv_grab_callback.py` - Callback-based capture example
|
||||||
|
- `grab.py` - Simple image capture example
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
If you encounter camera SDK issues:
|
||||||
|
|
||||||
|
1. **Check SDK Installation**:
|
||||||
|
```bash
|
||||||
|
ls -la camera_sdk/mvsdk.py
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Test SDK Import**:
|
||||||
|
```bash
|
||||||
|
python -c "import sys; sys.path.append('./camera_sdk'); import mvsdk; print('SDK imported successfully')"
|
||||||
|
```
|
||||||
|
|
||||||
|
3. **Check Native Library**:
|
||||||
|
```bash
|
||||||
|
# On Linux
|
||||||
|
ldconfig -p | grep MVSDK
|
||||||
|
```
|
||||||
|
|
||||||
|
For more troubleshooting, see the main [README.md](../README.md#troubleshooting).
|
||||||
29
container_init.sh
Executable file
29
container_init.sh
Executable file
@@ -0,0 +1,29 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# Container initialization script for USDA Vision Camera System
|
||||||
|
# This script sets up and starts the systemd service in a container environment
|
||||||
|
|
||||||
|
echo "🐳 Container Init - USDA Vision Camera System"
|
||||||
|
echo "============================================="
|
||||||
|
|
||||||
|
# Start systemd if not already running (for containers)
|
||||||
|
if ! pgrep systemd > /dev/null; then
|
||||||
|
echo "🔧 Starting systemd..."
|
||||||
|
exec /sbin/init &
|
||||||
|
sleep 5
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Setup the service if not already installed
|
||||||
|
if [ ! -f "/etc/systemd/system/usda-vision-camera.service" ]; then
|
||||||
|
echo "📦 Setting up USDA Vision Camera service..."
|
||||||
|
cd /home/alireza/USDA-vision-cameras
|
||||||
|
sudo ./setup_service.sh
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Start the service
|
||||||
|
echo "🚀 Starting USDA Vision Camera service..."
|
||||||
|
sudo systemctl start usda-vision-camera
|
||||||
|
|
||||||
|
# Follow the logs
|
||||||
|
echo "📋 Following service logs (Ctrl+C to exit)..."
|
||||||
|
sudo journalctl -u usda-vision-camera -f
|
||||||
@@ -9,7 +9,7 @@ The USDA Vision Camera System has been successfully implemented, tested, and doc
|
|||||||
### ✅ Core Functionality
|
### ✅ Core Functionality
|
||||||
- **MQTT Integration**: Dual topic listening for machine states
|
- **MQTT Integration**: Dual topic listening for machine states
|
||||||
- **Automatic Recording**: Camera recording triggered by machine on/off states
|
- **Automatic Recording**: Camera recording triggered by machine on/off states
|
||||||
- **GigE Camera Support**: Full integration with python demo library
|
- **GigE Camera Support**: Full integration with camera SDK library
|
||||||
- **Multi-threading**: Concurrent MQTT + camera monitoring + recording
|
- **Multi-threading**: Concurrent MQTT + camera monitoring + recording
|
||||||
- **File Management**: Timestamp-based naming in organized directories
|
- **File Management**: Timestamp-based naming in organized directories
|
||||||
|
|
||||||
@@ -50,11 +50,16 @@ USDA-Vision-Cameras/
|
|||||||
│ ├── storage/ # File management
|
│ ├── storage/ # File management
|
||||||
│ ├── api/ # REST API server
|
│ ├── api/ # REST API server
|
||||||
│ └── main.py # Application coordinator
|
│ └── main.py # Application coordinator
|
||||||
├── python demo/ # GigE camera library
|
├── camera_sdk/ # GigE camera SDK library
|
||||||
|
├── demos/ # Demo and example code
|
||||||
|
│ ├── cv_grab*.py # Camera SDK usage examples
|
||||||
|
│ └── mqtt_*.py # MQTT demo scripts
|
||||||
├── storage/ # Recording storage
|
├── storage/ # Recording storage
|
||||||
│ ├── camera1/ # Camera 1 recordings
|
│ ├── camera1/ # Camera 1 recordings
|
||||||
│ └── camera2/ # Camera 2 recordings
|
│ └── camera2/ # Camera 2 recordings
|
||||||
└── old tests/ # Archived development files
|
├── tests/ # Test files and legacy tests
|
||||||
|
├── notebooks/ # Jupyter notebooks
|
||||||
|
└── docs/ # Documentation files
|
||||||
```
|
```
|
||||||
|
|
||||||
## 🚀 How to Deploy
|
## 🚀 How to Deploy
|
||||||
49
docs/README.md
Normal file
49
docs/README.md
Normal file
@@ -0,0 +1,49 @@
|
|||||||
|
# USDA Vision Camera System - Documentation
|
||||||
|
|
||||||
|
This directory contains detailed documentation for the USDA Vision Camera System.
|
||||||
|
|
||||||
|
## Documentation Files
|
||||||
|
|
||||||
|
### 📋 [PROJECT_COMPLETE.md](PROJECT_COMPLETE.md)
|
||||||
|
Complete project overview and final status documentation. Contains:
|
||||||
|
- Project completion status
|
||||||
|
- Final system architecture
|
||||||
|
- Deployment instructions
|
||||||
|
- Production readiness checklist
|
||||||
|
|
||||||
|
### 🔧 [API_CHANGES_SUMMARY.md](API_CHANGES_SUMMARY.md)
|
||||||
|
Summary of API changes and enhancements made to the system.
|
||||||
|
|
||||||
|
### 📷 [CAMERA_RECOVERY_GUIDE.md](CAMERA_RECOVERY_GUIDE.md)
|
||||||
|
Guide for camera recovery procedures and troubleshooting camera-related issues.
|
||||||
|
|
||||||
|
### 📡 [MQTT_LOGGING_GUIDE.md](MQTT_LOGGING_GUIDE.md)
|
||||||
|
Comprehensive guide for MQTT logging configuration and troubleshooting.
|
||||||
|
|
||||||
|
## Main Documentation
|
||||||
|
|
||||||
|
The main system documentation is located in the root directory:
|
||||||
|
- **[../README.md](../README.md)** - Primary system documentation with installation, configuration, and usage instructions
|
||||||
|
|
||||||
|
## Additional Resources
|
||||||
|
|
||||||
|
### Demo Code
|
||||||
|
- **[../demos/](../demos/)** - Demo scripts and camera SDK examples
|
||||||
|
|
||||||
|
### Test Files
|
||||||
|
- **[../tests/](../tests/)** - Test scripts and legacy test files
|
||||||
|
|
||||||
|
### Jupyter Notebooks
|
||||||
|
- **[../notebooks/](../notebooks/)** - Interactive notebooks for system exploration and testing
|
||||||
|
|
||||||
|
## Quick Links
|
||||||
|
|
||||||
|
- [System Installation](../README.md#installation)
|
||||||
|
- [Configuration Guide](../README.md#configuration)
|
||||||
|
- [API Documentation](../README.md#api-reference)
|
||||||
|
- [Troubleshooting](../README.md#troubleshooting)
|
||||||
|
- [Camera SDK Examples](../demos/camera_sdk_examples/)
|
||||||
|
|
||||||
|
## Support
|
||||||
|
|
||||||
|
For technical support and questions, refer to the main [README.md](../README.md) troubleshooting section or check the system logs.
|
||||||
Binary file not shown.
Binary file not shown.
61
setup_service.sh
Executable file
61
setup_service.sh
Executable file
@@ -0,0 +1,61 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# USDA Vision Camera System Service Setup Script
|
||||||
|
|
||||||
|
echo "USDA Vision Camera System - Service Setup"
|
||||||
|
echo "========================================"
|
||||||
|
|
||||||
|
# Check if running as root
|
||||||
|
if [ "$EUID" -ne 0 ]; then
|
||||||
|
echo "❌ This script must be run as root (use sudo)"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Get the current directory (where the script is located)
|
||||||
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
|
SERVICE_FILE="$SCRIPT_DIR/usda-vision-camera.service"
|
||||||
|
|
||||||
|
echo "📁 Working directory: $SCRIPT_DIR"
|
||||||
|
|
||||||
|
# Check if service file exists
|
||||||
|
if [ ! -f "$SERVICE_FILE" ]; then
|
||||||
|
echo "❌ Service file not found: $SERVICE_FILE"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Make start_system.sh executable
|
||||||
|
echo "🔧 Making start_system.sh executable..."
|
||||||
|
chmod +x "$SCRIPT_DIR/start_system.sh"
|
||||||
|
|
||||||
|
# Update the service file with the correct path
|
||||||
|
echo "📝 Updating service file with correct paths..."
|
||||||
|
sed -i "s|WorkingDirectory=.*|WorkingDirectory=$SCRIPT_DIR|g" "$SERVICE_FILE"
|
||||||
|
sed -i "s|ExecStart=.*|ExecStart=/bin/bash $SCRIPT_DIR/start_system.sh|g" "$SERVICE_FILE"
|
||||||
|
|
||||||
|
# Copy service file to systemd directory
|
||||||
|
echo "📋 Installing service file..."
|
||||||
|
cp "$SERVICE_FILE" /etc/systemd/system/
|
||||||
|
|
||||||
|
# Reload systemd daemon
|
||||||
|
echo "🔄 Reloading systemd daemon..."
|
||||||
|
systemctl daemon-reload
|
||||||
|
|
||||||
|
# Enable the service
|
||||||
|
echo "✅ Enabling USDA Vision Camera service..."
|
||||||
|
systemctl enable usda-vision-camera.service
|
||||||
|
|
||||||
|
# Check service status
|
||||||
|
echo "📊 Service status:"
|
||||||
|
systemctl status usda-vision-camera.service --no-pager
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "🎉 Service setup complete!"
|
||||||
|
echo ""
|
||||||
|
echo "Available commands:"
|
||||||
|
echo " sudo systemctl start usda-vision-camera # Start the service"
|
||||||
|
echo " sudo systemctl stop usda-vision-camera # Stop the service"
|
||||||
|
echo " sudo systemctl restart usda-vision-camera # Restart the service"
|
||||||
|
echo " sudo systemctl status usda-vision-camera # Check service status"
|
||||||
|
echo " sudo journalctl -u usda-vision-camera -f # View live logs"
|
||||||
|
echo ""
|
||||||
|
echo "The service will automatically start when the container/system boots."
|
||||||
@@ -38,10 +38,18 @@ python test_system.py
|
|||||||
|
|
||||||
if [ $? -ne 0 ]; then
|
if [ $? -ne 0 ]; then
|
||||||
echo "❌ System tests failed. Please check the configuration."
|
echo "❌ System tests failed. Please check the configuration."
|
||||||
read -p "Do you want to continue anyway? (y/N): " -n 1 -r
|
# When running as a service, don't prompt for user input
|
||||||
echo
|
if [ -t 0 ]; then
|
||||||
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
# Interactive mode - prompt user
|
||||||
exit 1
|
read -p "Do you want to continue anyway? (y/N): " -n 1 -r
|
||||||
|
echo
|
||||||
|
if [[ ! $REPLY =~ ^[Yy]$ ]]; then
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
# Non-interactive mode (service) - continue with warning
|
||||||
|
echo "⚠️ Running in non-interactive mode. Continuing despite test failures..."
|
||||||
|
sleep 2
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
|||||||
BIN
tests/legacy_tests/Camera/Data/054012620023.mvdat
Normal file
BIN
tests/legacy_tests/Camera/Data/054012620023.mvdat
Normal file
Binary file not shown.
BIN
tests/legacy_tests/Camera/Data/054052320151.mvdat
Normal file
BIN
tests/legacy_tests/Camera/Data/054052320151.mvdat
Normal file
Binary file not shown.
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:32:15
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:32:15.057651 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:32:33
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:32:33.490923 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:32:34
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:32:34.649940 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:32:39
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:32:39.753448 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:32:45
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:32:45.492905 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:33:40
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:33:40.702630 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:34:18
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:34:18.442386 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:34:28
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:34:28.207051 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:34:53
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:34:53.315912 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:35:00
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:35:00.929268 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:35:32
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:35:32.169682 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
Log file created at: 2025/07/28 15:35:34
|
||||||
|
Running on machine: vision
|
||||||
|
Log line format: [IWEF]mmdd hh:mm:ss.uuuuuu threadid file:line] msg
|
||||||
|
E0728 15:35:34.519351 191852 MVCAMAPI.cpp:369] CameraInit Failed, err:32774,Version:2.1.0.49,FriendlyName:Blower-Yield-Cam,SN:054012620023
|
||||||
@@ -64,7 +64,7 @@ def test_camera_discovery():
|
|||||||
"""Test camera discovery"""
|
"""Test camera discovery"""
|
||||||
print("\nTesting camera discovery...")
|
print("\nTesting camera discovery...")
|
||||||
try:
|
try:
|
||||||
sys.path.append("./python demo")
|
sys.path.append("./camera_sdk")
|
||||||
import mvsdk
|
import mvsdk
|
||||||
|
|
||||||
devices = mvsdk.CameraEnumerateDevice()
|
devices = mvsdk.CameraEnumerateDevice()
|
||||||
@@ -82,7 +82,7 @@ def test_camera_discovery():
|
|||||||
return True
|
return True
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
print(f"❌ Camera discovery failed: {e}")
|
print(f"❌ Camera discovery failed: {e}")
|
||||||
print(" Make sure GigE cameras are connected and python demo library is available")
|
print(" Make sure GigE cameras are connected and camera SDK library is available")
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
|
||||||
26
usda-vision-camera.service
Normal file
26
usda-vision-camera.service
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
[Unit]
|
||||||
|
Description=USDA Vision Camera System
|
||||||
|
After=network.target
|
||||||
|
Wants=network.target
|
||||||
|
|
||||||
|
[Service]
|
||||||
|
Type=simple
|
||||||
|
User=root
|
||||||
|
Group=root
|
||||||
|
WorkingDirectory=/home/alireza/USDA-vision-cameras
|
||||||
|
ExecStart=/bin/bash /home/alireza/USDA-vision-cameras/start_system.sh
|
||||||
|
Restart=always
|
||||||
|
RestartSec=10
|
||||||
|
StandardOutput=journal
|
||||||
|
StandardError=journal
|
||||||
|
|
||||||
|
# Environment variables
|
||||||
|
Environment=PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
|
||||||
|
Environment=HOME=/root
|
||||||
|
|
||||||
|
# Security settings (adjust as needed)
|
||||||
|
NoNewPrivileges=false
|
||||||
|
PrivateTmp=false
|
||||||
|
|
||||||
|
[Install]
|
||||||
|
WantedBy=multi-user.target
|
||||||
@@ -2,7 +2,7 @@
|
|||||||
Camera module for the USDA Vision Camera System.
|
Camera module for the USDA Vision Camera System.
|
||||||
|
|
||||||
This module handles GigE camera discovery, management, monitoring, and recording
|
This module handles GigE camera discovery, management, monitoring, and recording
|
||||||
using the python demo library (mvsdk).
|
using the camera SDK library (mvsdk).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
from .manager import CameraManager
|
from .manager import CameraManager
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@@ -12,8 +12,8 @@ import logging
|
|||||||
from typing import Dict, List, Optional, Tuple, Any
|
from typing import Dict, List, Optional, Tuple, Any
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
|
|
||||||
# Add python demo to path
|
# Add camera SDK to path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "python demo"))
|
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "camera_sdk"))
|
||||||
import mvsdk
|
import mvsdk
|
||||||
|
|
||||||
from ..core.config import Config, CameraConfig
|
from ..core.config import Config, CameraConfig
|
||||||
|
|||||||
@@ -12,8 +12,8 @@ import logging
|
|||||||
import contextlib
|
import contextlib
|
||||||
from typing import Dict, List, Optional, Any
|
from typing import Dict, List, Optional, Any
|
||||||
|
|
||||||
# Add python demo to path
|
# Add camera SDK to path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "python demo"))
|
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "camera_sdk"))
|
||||||
import mvsdk
|
import mvsdk
|
||||||
|
|
||||||
from ..core.config import Config
|
from ..core.config import Config
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
"""
|
"""
|
||||||
Camera Recorder for the USDA Vision Camera System.
|
Camera Recorder for the USDA Vision Camera System.
|
||||||
|
|
||||||
This module handles video recording from GigE cameras using the python demo library (mvsdk).
|
This module handles video recording from GigE cameras using the camera SDK library (mvsdk).
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import sys
|
import sys
|
||||||
@@ -16,8 +16,8 @@ from typing import Optional, Dict, Any
|
|||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
|
||||||
# Add python demo to path
|
# Add camera SDK to path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "python demo"))
|
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "camera_sdk"))
|
||||||
import mvsdk
|
import mvsdk
|
||||||
|
|
||||||
from ..core.config import CameraConfig
|
from ..core.config import CameraConfig
|
||||||
|
|||||||
@@ -8,8 +8,8 @@ import sys
|
|||||||
import os
|
import os
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
# Add python demo to path
|
# Add camera SDK to path
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "python demo"))
|
sys.path.append(os.path.join(os.path.dirname(__file__), "..", "..", "camera_sdk"))
|
||||||
import mvsdk
|
import mvsdk
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|||||||
Binary file not shown.
@@ -16,23 +16,22 @@ from pathlib import Path
|
|||||||
@dataclass
|
@dataclass
|
||||||
class MQTTConfig:
|
class MQTTConfig:
|
||||||
"""MQTT broker configuration"""
|
"""MQTT broker configuration"""
|
||||||
|
|
||||||
broker_host: str = "192.168.1.110"
|
broker_host: str = "192.168.1.110"
|
||||||
broker_port: int = 1883
|
broker_port: int = 1883
|
||||||
username: Optional[str] = None
|
username: Optional[str] = None
|
||||||
password: Optional[str] = None
|
password: Optional[str] = None
|
||||||
topics: Dict[str, str] = None
|
topics: Optional[Dict[str, str]] = None
|
||||||
|
|
||||||
def __post_init__(self):
|
def __post_init__(self):
|
||||||
if self.topics is None:
|
if self.topics is None:
|
||||||
self.topics = {
|
self.topics = {"vibratory_conveyor": "vision/vibratory_conveyor/state", "blower_separator": "vision/blower_separator/state"}
|
||||||
"vibratory_conveyor": "vision/vibratory_conveyor/state",
|
|
||||||
"blower_separator": "vision/blower_separator/state"
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class CameraConfig:
|
class CameraConfig:
|
||||||
"""Individual camera configuration"""
|
"""Individual camera configuration"""
|
||||||
|
|
||||||
name: str
|
name: str
|
||||||
machine_topic: str # Which MQTT topic triggers this camera
|
machine_topic: str # Which MQTT topic triggers this camera
|
||||||
storage_path: str
|
storage_path: str
|
||||||
@@ -43,33 +42,34 @@ class CameraConfig:
|
|||||||
|
|
||||||
# Image Quality Settings
|
# Image Quality Settings
|
||||||
sharpness: int = 100 # 0-200, default 100 (no sharpening)
|
sharpness: int = 100 # 0-200, default 100 (no sharpening)
|
||||||
contrast: int = 100 # 0-200, default 100 (normal contrast)
|
contrast: int = 100 # 0-200, default 100 (normal contrast)
|
||||||
saturation: int = 100 # 0-200, default 100 (normal saturation, color cameras only)
|
saturation: int = 100 # 0-200, default 100 (normal saturation, color cameras only)
|
||||||
gamma: int = 100 # 0-300, default 100 (normal gamma)
|
gamma: int = 100 # 0-300, default 100 (normal gamma)
|
||||||
|
|
||||||
# Noise Reduction
|
# Noise Reduction
|
||||||
noise_filter_enabled: bool = True # Enable basic noise filtering
|
noise_filter_enabled: bool = True # Enable basic noise filtering
|
||||||
denoise_3d_enabled: bool = False # Enable advanced 3D denoising (may reduce FPS)
|
denoise_3d_enabled: bool = False # Enable advanced 3D denoising (may reduce FPS)
|
||||||
|
|
||||||
# Color Settings (for color cameras)
|
# Color Settings (for color cameras)
|
||||||
auto_white_balance: bool = True # Enable automatic white balance
|
auto_white_balance: bool = True # Enable automatic white balance
|
||||||
color_temperature_preset: int = 0 # 0=auto, 1=daylight, 2=fluorescent, etc.
|
color_temperature_preset: int = 0 # 0=auto, 1=daylight, 2=fluorescent, etc.
|
||||||
|
|
||||||
# Advanced Settings
|
# Advanced Settings
|
||||||
anti_flicker_enabled: bool = True # Reduce artificial lighting flicker
|
anti_flicker_enabled: bool = True # Reduce artificial lighting flicker
|
||||||
light_frequency: int = 1 # 0=50Hz, 1=60Hz (match local power frequency)
|
light_frequency: int = 1 # 0=50Hz, 1=60Hz (match local power frequency)
|
||||||
|
|
||||||
# Bit Depth & Format
|
# Bit Depth & Format
|
||||||
bit_depth: int = 8 # 8, 10, 12, or 16 bits per channel
|
bit_depth: int = 8 # 8, 10, 12, or 16 bits per channel
|
||||||
|
|
||||||
# HDR Settings
|
# HDR Settings
|
||||||
hdr_enabled: bool = False # Enable High Dynamic Range
|
hdr_enabled: bool = False # Enable High Dynamic Range
|
||||||
hdr_gain_mode: int = 0 # HDR processing mode
|
hdr_gain_mode: int = 0 # HDR processing mode
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
@dataclass
|
||||||
class StorageConfig:
|
class StorageConfig:
|
||||||
"""Storage configuration"""
|
"""Storage configuration"""
|
||||||
|
|
||||||
base_path: str = "/storage"
|
base_path: str = "/storage"
|
||||||
max_file_size_mb: int = 1000 # Max size per video file
|
max_file_size_mb: int = 1000 # Max size per video file
|
||||||
max_recording_duration_minutes: int = 60 # Max recording duration
|
max_recording_duration_minutes: int = 60 # Max recording duration
|
||||||
@@ -79,6 +79,7 @@ class StorageConfig:
|
|||||||
@dataclass
|
@dataclass
|
||||||
class SystemConfig:
|
class SystemConfig:
|
||||||
"""System-wide configuration"""
|
"""System-wide configuration"""
|
||||||
|
|
||||||
camera_check_interval_seconds: int = 2
|
camera_check_interval_seconds: int = 2
|
||||||
log_level: str = "INFO"
|
log_level: str = "INFO"
|
||||||
log_file: str = "usda_vision_system.log"
|
log_file: str = "usda_vision_system.log"
|
||||||
@@ -115,30 +116,27 @@ class Config:
|
|||||||
|
|
||||||
if config_path.exists():
|
if config_path.exists():
|
||||||
try:
|
try:
|
||||||
with open(config_path, 'r') as f:
|
with open(config_path, "r") as f:
|
||||||
config_data = json.load(f)
|
config_data = json.load(f)
|
||||||
|
|
||||||
# Load MQTT config
|
# Load MQTT config
|
||||||
if 'mqtt' in config_data:
|
if "mqtt" in config_data:
|
||||||
mqtt_data = config_data['mqtt']
|
mqtt_data = config_data["mqtt"]
|
||||||
self.mqtt = MQTTConfig(**mqtt_data)
|
self.mqtt = MQTTConfig(**mqtt_data)
|
||||||
|
|
||||||
# Load storage config
|
# Load storage config
|
||||||
if 'storage' in config_data:
|
if "storage" in config_data:
|
||||||
storage_data = config_data['storage']
|
storage_data = config_data["storage"]
|
||||||
self.storage = StorageConfig(**storage_data)
|
self.storage = StorageConfig(**storage_data)
|
||||||
|
|
||||||
# Load system config
|
# Load system config
|
||||||
if 'system' in config_data:
|
if "system" in config_data:
|
||||||
system_data = config_data['system']
|
system_data = config_data["system"]
|
||||||
self.system = SystemConfig(**system_data)
|
self.system = SystemConfig(**system_data)
|
||||||
|
|
||||||
# Load camera configs
|
# Load camera configs
|
||||||
if 'cameras' in config_data:
|
if "cameras" in config_data:
|
||||||
self.cameras = [
|
self.cameras = [CameraConfig(**cam_data) for cam_data in config_data["cameras"]]
|
||||||
CameraConfig(**cam_data)
|
|
||||||
for cam_data in config_data['cameras']
|
|
||||||
]
|
|
||||||
else:
|
else:
|
||||||
self._create_default_camera_configs()
|
self._create_default_camera_configs()
|
||||||
|
|
||||||
@@ -154,30 +152,14 @@ class Config:
|
|||||||
|
|
||||||
def _create_default_camera_configs(self) -> None:
|
def _create_default_camera_configs(self) -> None:
|
||||||
"""Create default camera configurations"""
|
"""Create default camera configurations"""
|
||||||
self.cameras = [
|
self.cameras = [CameraConfig(name="camera1", machine_topic="vibratory_conveyor", storage_path=os.path.join(self.storage.base_path, "camera1")), CameraConfig(name="camera2", machine_topic="blower_separator", storage_path=os.path.join(self.storage.base_path, "camera2"))]
|
||||||
CameraConfig(
|
|
||||||
name="camera1",
|
|
||||||
machine_topic="vibratory_conveyor",
|
|
||||||
storage_path=os.path.join(self.storage.base_path, "camera1")
|
|
||||||
),
|
|
||||||
CameraConfig(
|
|
||||||
name="camera2",
|
|
||||||
machine_topic="blower_separator",
|
|
||||||
storage_path=os.path.join(self.storage.base_path, "camera2")
|
|
||||||
)
|
|
||||||
]
|
|
||||||
|
|
||||||
def save_config(self) -> None:
|
def save_config(self) -> None:
|
||||||
"""Save current configuration to file"""
|
"""Save current configuration to file"""
|
||||||
config_data = {
|
config_data = {"mqtt": asdict(self.mqtt), "storage": asdict(self.storage), "system": asdict(self.system), "cameras": [asdict(cam) for cam in self.cameras]}
|
||||||
'mqtt': asdict(self.mqtt),
|
|
||||||
'storage': asdict(self.storage),
|
|
||||||
'system': asdict(self.system),
|
|
||||||
'cameras': [asdict(cam) for cam in self.cameras]
|
|
||||||
}
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.config_file, 'w') as f:
|
with open(self.config_file, "w") as f:
|
||||||
json.dump(config_data, f, indent=2)
|
json.dump(config_data, f, indent=2)
|
||||||
self.logger.info(f"Configuration saved to {self.config_file}")
|
self.logger.info(f"Configuration saved to {self.config_file}")
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@@ -224,9 +206,4 @@ class Config:
|
|||||||
|
|
||||||
def to_dict(self) -> Dict[str, Any]:
|
def to_dict(self) -> Dict[str, Any]:
|
||||||
"""Convert configuration to dictionary"""
|
"""Convert configuration to dictionary"""
|
||||||
return {
|
return {"mqtt": asdict(self.mqtt), "storage": asdict(self.storage), "system": asdict(self.system), "cameras": [asdict(cam) for cam in self.cameras]}
|
||||||
'mqtt': asdict(self.mqtt),
|
|
||||||
'storage': asdict(self.storage),
|
|
||||||
'system': asdict(self.system),
|
|
||||||
'cameras': [asdict(cam) for cam in self.cameras]
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user