Change video storage directory from /storage to /mnt/nfs_share
- Update StorageConfig default base_path in core/config.py - Update base_path and camera storage_paths in config.json and config.compose.json - Update Docker Compose volume mounts to use /mnt/nfs_share - Update start_system.sh to create /mnt/nfs_share directory - Update convert_avi_to_mp4.sh to use new NFS path - Update all documentation files to reflect new storage paths - Videos now stored on NFS server at 192.168.1.249:/mnt/nfs_share/
This commit is contained in:
@@ -142,9 +142,9 @@ Ensure the `camera_sdk` directory contains the mvsdk library for your GigE camer
|
||||
### 4. Configure Storage Directory
|
||||
```bash
|
||||
# Create storage directory (adjust path as needed)
|
||||
mkdir -p ./storage
|
||||
mkdir -p ./mnt/nfs_share
|
||||
# Or for system-wide storage:
|
||||
# sudo mkdir -p /storage && sudo chown $USER:$USER /storage
|
||||
# sudo mkdir -p /mnt/nfs_share && sudo chown $USER:$USER /mnt/nfs_share
|
||||
```
|
||||
|
||||
### 5. Setup Time Synchronization (Recommended)
|
||||
@@ -169,7 +169,7 @@ Edit `config.json` to match your setup:
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "machine1",
|
||||
"storage_path": "./storage/camera1",
|
||||
"storage_path": "./mnt/nfs_share/camera1",
|
||||
"enabled": true
|
||||
}
|
||||
]
|
||||
@@ -201,7 +201,7 @@ Edit `config.json` to match your setup:
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "vibratory_conveyor",
|
||||
"storage_path": "./storage/camera1",
|
||||
"storage_path": "./mnt/nfs_share/camera1",
|
||||
"exposure_ms": 1.0,
|
||||
"gain": 3.5,
|
||||
"target_fps": 3.0,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
}
|
||||
},
|
||||
"storage": {
|
||||
"base_path": "/storage",
|
||||
"base_path": "/mnt/nfs_share",
|
||||
"max_file_size_mb": 1000,
|
||||
"max_recording_duration_minutes": 60,
|
||||
"cleanup_older_than_days": 30
|
||||
@@ -29,7 +29,7 @@
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 0.3,
|
||||
"gain": 4.0,
|
||||
"target_fps": 0,
|
||||
@@ -60,7 +60,7 @@
|
||||
{
|
||||
"name": "camera2",
|
||||
"machine_topic": "vibratory_conveyor",
|
||||
"storage_path": "/storage/camera2",
|
||||
"storage_path": "/mnt/nfs_share/camera2",
|
||||
"exposure_ms": 0.2,
|
||||
"gain": 2.0,
|
||||
"target_fps": 0,
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
}
|
||||
},
|
||||
"storage": {
|
||||
"base_path": "/storage",
|
||||
"base_path": "/mnt/nfs_share",
|
||||
"max_file_size_mb": 1000,
|
||||
"max_recording_duration_minutes": 60,
|
||||
"cleanup_older_than_days": 30
|
||||
@@ -29,7 +29,7 @@
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 0.3,
|
||||
"gain": 4.0,
|
||||
"target_fps": 0,
|
||||
@@ -60,7 +60,7 @@
|
||||
{
|
||||
"name": "camera2",
|
||||
"machine_topic": "vibratory_conveyor",
|
||||
"storage_path": "/storage/camera2",
|
||||
"storage_path": "/mnt/nfs_share/camera2",
|
||||
"exposure_ms": 0.2,
|
||||
"gain": 2.0,
|
||||
"target_fps": 0,
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#!/bin/bash
|
||||
|
||||
# Script to convert AVI files to MP4 using H.264 codec
|
||||
# Converts files in /storage directory and saves them in the same location
|
||||
# Converts files in /mnt/nfs_share directory and saves them in the same location
|
||||
|
||||
# Colors for output
|
||||
RED='\033[0;31m'
|
||||
@@ -54,19 +54,19 @@ if ! command -v ffmpeg &> /dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if /storage directory exists
|
||||
if [ ! -d "/storage" ]; then
|
||||
print_error "/storage directory does not exist."
|
||||
# Check if /mnt/nfs_share directory exists
|
||||
if [ ! -d "/mnt/nfs_share" ]; then
|
||||
print_error "/mnt/nfs_share directory does not exist."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if we have read/write permissions to /storage
|
||||
if [ ! -r "/storage" ] || [ ! -w "/storage" ]; then
|
||||
print_error "No read/write permissions for /storage directory."
|
||||
# Check if we have read/write permissions to /mnt/nfs_share
|
||||
if [ ! -r "/mnt/nfs_share" ] || [ ! -w "/mnt/nfs_share" ]; then
|
||||
print_error "No read/write permissions for /mnt/nfs_share directory."
|
||||
exit 1
|
||||
fi
|
||||
|
||||
print_status "Starting AVI to MP4 conversion in /storage directory..."
|
||||
print_status "Starting AVI to MP4 conversion in /mnt/nfs_share directory..."
|
||||
|
||||
# Counter variables
|
||||
total_files=0
|
||||
@@ -74,7 +74,7 @@ converted_files=0
|
||||
skipped_files=0
|
||||
failed_files=0
|
||||
|
||||
# Find all AVI files in /storage directory (including subdirectories)
|
||||
# Find all AVI files in /mnt/nfs_share directory (including subdirectories)
|
||||
while IFS= read -r -d '' avi_file; do
|
||||
total_files=$((total_files + 1))
|
||||
|
||||
@@ -163,7 +163,7 @@ while IFS= read -r -d '' avi_file; do
|
||||
|
||||
echo # Add blank line between files
|
||||
|
||||
done < <(find /storage -name "*.avi" -type f -print0)
|
||||
done < <(find /mnt/nfs_share -name "*.avi" -type f -print0)
|
||||
|
||||
# Print summary
|
||||
echo
|
||||
@@ -174,7 +174,7 @@ echo "Skipped (MP4 exists): $skipped_files"
|
||||
echo "Failed conversions: $failed_files"
|
||||
|
||||
if [ $total_files -eq 0 ]; then
|
||||
print_warning "No AVI files found in /storage directory."
|
||||
print_warning "No AVI files found in /mnt/nfs_share directory."
|
||||
elif [ $failed_files -eq 0 ] && [ $converted_files -gt 0 ]; then
|
||||
print_success "All conversions completed successfully!"
|
||||
elif [ $failed_files -gt 0 ]; then
|
||||
|
||||
@@ -196,7 +196,7 @@ GET /cameras/{camera_name}/config
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 0.3,
|
||||
"gain": 4.0,
|
||||
"target_fps": 0,
|
||||
@@ -306,7 +306,7 @@ GET /storage/stats
|
||||
**Response**: `StorageStatsResponse`
|
||||
```json
|
||||
{
|
||||
"base_path": "/storage",
|
||||
"base_path": "/mnt/nfs_share",
|
||||
"total_files": 150,
|
||||
"total_size_bytes": 5368709120,
|
||||
"cameras": {
|
||||
|
||||
@@ -20,7 +20,7 @@ This document shows the exact current configuration structure of the USDA Vision
|
||||
}
|
||||
},
|
||||
"storage": {
|
||||
"base_path": "/storage",
|
||||
"base_path": "/mnt/nfs_share",
|
||||
"max_file_size_mb": 1000,
|
||||
"max_recording_duration_minutes": 60,
|
||||
"cleanup_older_than_days": 30
|
||||
@@ -39,7 +39,7 @@ This document shows the exact current configuration structure of the USDA Vision
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 0.3,
|
||||
"gain": 4.0,
|
||||
"target_fps": 0,
|
||||
@@ -70,7 +70,7 @@ This document shows the exact current configuration structure of the USDA Vision
|
||||
{
|
||||
"name": "camera2",
|
||||
"machine_topic": "vibratory_conveyor",
|
||||
"storage_path": "/storage/camera2",
|
||||
"storage_path": "/mnt/nfs_share/camera2",
|
||||
"exposure_ms": 0.2,
|
||||
"gain": 2.0,
|
||||
"target_fps": 0,
|
||||
@@ -121,7 +121,7 @@ This document shows the exact current configuration structure of the USDA Vision
|
||||
### Storage Settings
|
||||
| Field | Value | Description |
|
||||
|-------|-------|-------------|
|
||||
| `base_path` | `"/storage"` | Root storage directory |
|
||||
| `base_path` | `"/mnt/nfs_share"` | Root storage directory |
|
||||
| `max_file_size_mb` | `1000` | Maximum file size (1GB) |
|
||||
| `max_recording_duration_minutes` | `60` | Maximum recording duration |
|
||||
| `cleanup_older_than_days` | `30` | Auto-cleanup threshold |
|
||||
@@ -144,7 +144,7 @@ This document shows the exact current configuration structure of the USDA Vision
|
||||
| **Basic Settings** | | |
|
||||
| `name` | `"camera1"` | Camera identifier |
|
||||
| `machine_topic` | `"blower_separator"` | MQTT topic to monitor |
|
||||
| `storage_path` | `"/storage/camera1"` | Video storage location |
|
||||
| `storage_path` | `"/mnt/nfs_share/camera1"` | Video storage location |
|
||||
| `exposure_ms` | `0.3` | Exposure time (milliseconds) |
|
||||
| `gain` | `4.0` | Camera gain multiplier |
|
||||
| `target_fps` | `0` | Target FPS (0 = unlimited) |
|
||||
@@ -176,7 +176,7 @@ This document shows the exact current configuration structure of the USDA Vision
|
||||
|---------|-------|--------------------------|
|
||||
| `name` | `"camera2"` | Different identifier |
|
||||
| `machine_topic` | `"vibratory_conveyor"` | Different MQTT topic |
|
||||
| `storage_path` | `"/storage/camera2"` | Different storage path |
|
||||
| `storage_path` | `"/mnt/nfs_share/camera2"` | Different storage path |
|
||||
| `exposure_ms` | `0.2` | Faster exposure (0.2 vs 0.3) |
|
||||
| `gain` | `2.0` | Lower gain (2.0 vs 4.0) |
|
||||
| `wb_red_gain` | `1.01` | Different red balance (1.01 vs 0.94) |
|
||||
|
||||
@@ -78,7 +78,7 @@ const videoUrl = `/api/videos/${videoId}/stream`;
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 0.3,
|
||||
"gain": 4.0,
|
||||
"target_fps": 0,
|
||||
|
||||
@@ -100,7 +100,7 @@ const CameraConfigForm = () => {
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 0.3,
|
||||
"gain": 4.0,
|
||||
"target_fps": 0,
|
||||
|
||||
@@ -41,7 +41,7 @@ GET /cameras/{camera_name}/config
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 0.3,
|
||||
"gain": 4.0,
|
||||
"target_fps": 0,
|
||||
|
||||
@@ -65,7 +65,7 @@ The current config.json for camera1 includes:
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "blower_separator",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 1.0,
|
||||
"gain": 3.5,
|
||||
"target_fps": 0,
|
||||
|
||||
@@ -61,7 +61,7 @@ The current config.json for camera2 includes:
|
||||
{
|
||||
"name": "camera2",
|
||||
"machine_topic": "vibratory_conveyor",
|
||||
"storage_path": "/storage/camera2",
|
||||
"storage_path": "/mnt/nfs_share/camera2",
|
||||
"exposure_ms": 0.5,
|
||||
"gain": 0.3,
|
||||
"target_fps": 0,
|
||||
|
||||
@@ -57,8 +57,8 @@ This system integrates MQTT machine monitoring with automated video recording fr
|
||||
|
||||
3. **Setup Storage Directory**:
|
||||
```bash
|
||||
sudo mkdir -p /storage
|
||||
sudo chown $USER:$USER /storage
|
||||
sudo mkdir -p /mnt/nfs_share
|
||||
sudo chown $USER:$USER /mnt/nfs_share
|
||||
```
|
||||
|
||||
## Configuration
|
||||
@@ -79,7 +79,7 @@ Edit `config.json` to configure your system:
|
||||
{
|
||||
"name": "camera1",
|
||||
"machine_topic": "vibratory_conveyor",
|
||||
"storage_path": "/storage/camera1",
|
||||
"storage_path": "/mnt/nfs_share/camera1",
|
||||
"exposure_ms": 1.0,
|
||||
"gain": 3.5,
|
||||
"target_fps": 3.0,
|
||||
@@ -117,7 +117,7 @@ The system provides a REST API on port 8000:
|
||||
- `GET /machines` - All machine states
|
||||
- `POST /cameras/{name}/start-recording` - Manual recording start
|
||||
- `POST /cameras/{name}/stop-recording` - Manual recording stop
|
||||
- `GET /storage/stats` - Storage statistics
|
||||
- `GET /mnt/nfs_share/stats` - Storage statistics
|
||||
- `WebSocket /ws` - Real-time updates
|
||||
|
||||
### Dashboard Integration
|
||||
@@ -131,7 +131,7 @@ The system is designed to integrate with your existing React + Vite + Tailwind +
|
||||
## File Organization
|
||||
|
||||
```
|
||||
/storage/
|
||||
/mnt/nfs_share/
|
||||
├── camera1/
|
||||
│ ├── camera1_recording_20250726_143022.avi
|
||||
│ └── camera1_recording_20250726_143155.avi
|
||||
|
||||
@@ -29,11 +29,11 @@ if [ ! -f "config.json" ]; then
|
||||
fi
|
||||
|
||||
# Check storage directory
|
||||
if [ ! -d "/storage" ]; then
|
||||
if [ ! -d "/mnt/nfs_share" ]; then
|
||||
echo "📁 Creating storage directory..."
|
||||
sudo mkdir -p /storage
|
||||
sudo chown $USER:$USER /storage
|
||||
echo "✅ Storage directory created at /storage"
|
||||
sudo mkdir -p /mnt/nfs_share
|
||||
sudo chown $USER:$USER /mnt/nfs_share
|
||||
echo "✅ Storage directory created at /mnt/nfs_share"
|
||||
fi
|
||||
|
||||
# Check time synchronization
|
||||
|
||||
@@ -85,7 +85,7 @@ class CameraConfig:
|
||||
class StorageConfig:
|
||||
"""Storage configuration"""
|
||||
|
||||
base_path: str = "/storage"
|
||||
base_path: str = "/mnt/nfs_share"
|
||||
max_file_size_mb: int = 1000 # Max size per video file
|
||||
max_recording_duration_minutes: int = 60 # Max recording duration
|
||||
cleanup_older_than_days: int = 30 # Auto cleanup old files
|
||||
|
||||
Reference in New Issue
Block a user