171 lines
4.9 KiB
Bash
171 lines
4.9 KiB
Bash
#!/bin/bash
|
|
# capture-upload.sh - Capture from USB webcam and upload to PicUpper
|
|
# For Raspberry Pi 3 with Logitech USB webcam
|
|
|
|
set -euo pipefail
|
|
|
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
CONFIG_FILE="${SCRIPT_DIR}/picupper.conf"
|
|
|
|
# ==============================================================================
|
|
# Load Configuration
|
|
# ==============================================================================
|
|
|
|
if [[ ! -f "$CONFIG_FILE" ]]; then
|
|
echo "ERROR: Configuration file not found: $CONFIG_FILE"
|
|
echo "Please copy picupper.conf.example to picupper.conf and configure it."
|
|
exit 1
|
|
fi
|
|
|
|
# shellcheck source=/dev/null
|
|
source "$CONFIG_FILE"
|
|
|
|
# Validate required settings
|
|
if [[ -z "${API_KEY:-}" || "$API_KEY" == "your-api-key-here" ]]; then
|
|
echo "ERROR: API_KEY not configured in $CONFIG_FILE"
|
|
exit 1
|
|
fi
|
|
|
|
# Set defaults for optional settings
|
|
API_URL="${API_URL:-https://dev.seedheads.de/picUploadApi/upload}"
|
|
CAMERA_ID="${CAMERA_ID:-rpi-webcam}"
|
|
VIDEO_DEVICE="${VIDEO_DEVICE:-/dev/video0}"
|
|
RESOLUTION="${RESOLUTION:-1920x1080}"
|
|
SKIP_FRAMES="${SKIP_FRAMES:-5}"
|
|
TEMP_DIR="${TEMP_DIR:-/tmp}"
|
|
LOG_FILE="${LOG_FILE:-${SCRIPT_DIR}/picupper.log}"
|
|
TIMEOUT="${TIMEOUT:-30}"
|
|
MAX_RETRIES="${MAX_RETRIES:-3}"
|
|
RETRY_DELAY="${RETRY_DELAY:-5}"
|
|
|
|
# ==============================================================================
|
|
# Helper Functions
|
|
# ==============================================================================
|
|
|
|
log() {
|
|
local timestamp
|
|
timestamp=$(date '+%Y-%m-%d %H:%M:%S')
|
|
local msg="[$timestamp] $*"
|
|
echo "$msg"
|
|
echo "$msg" >> "$LOG_FILE" 2>/dev/null || true
|
|
}
|
|
|
|
log_error() {
|
|
log "ERROR: $*" >&2
|
|
}
|
|
|
|
cleanup() {
|
|
rm -f "${TEMP_FILE:-}" 2>/dev/null || true
|
|
}
|
|
|
|
trap cleanup EXIT
|
|
|
|
# ==============================================================================
|
|
# Test Mode
|
|
# ==============================================================================
|
|
|
|
if [[ "${1:-}" == "--test" ]]; then
|
|
echo "=== PicUpper Test Mode ==="
|
|
echo "Config file: $CONFIG_FILE"
|
|
echo "API URL: $API_URL"
|
|
echo "Camera ID: $CAMERA_ID"
|
|
echo "Video device: $VIDEO_DEVICE"
|
|
echo "Resolution: $RESOLUTION"
|
|
echo ""
|
|
|
|
# Check video device
|
|
if [[ ! -e "$VIDEO_DEVICE" ]]; then
|
|
echo "❌ Video device not found: $VIDEO_DEVICE"
|
|
echo " Available devices:"
|
|
ls -la /dev/video* 2>/dev/null || echo " No video devices found"
|
|
exit 1
|
|
fi
|
|
echo "✓ Video device exists: $VIDEO_DEVICE"
|
|
|
|
# Check fswebcam
|
|
if ! command -v fswebcam &>/dev/null; then
|
|
echo "❌ fswebcam not installed. Run: sudo apt install fswebcam"
|
|
exit 1
|
|
fi
|
|
echo "✓ fswebcam installed"
|
|
|
|
# Try capture
|
|
TEST_FILE="${TEMP_DIR}/picupper_test_$(date +%s).jpg"
|
|
echo "Capturing test image to: $TEST_FILE"
|
|
|
|
if fswebcam -d "$VIDEO_DEVICE" -r "$RESOLUTION" -S "$SKIP_FRAMES" --no-banner "$TEST_FILE" 2>/dev/null; then
|
|
FILE_SIZE=$(stat -f%z "$TEST_FILE" 2>/dev/null || stat -c%s "$TEST_FILE" 2>/dev/null)
|
|
echo "✓ Capture successful: $TEST_FILE (${FILE_SIZE} bytes)"
|
|
echo ""
|
|
echo "To view the image: gpicview $TEST_FILE"
|
|
else
|
|
echo "❌ Capture failed. Check webcam connection and permissions."
|
|
exit 1
|
|
fi
|
|
|
|
exit 0
|
|
fi
|
|
|
|
# ==============================================================================
|
|
# Main Capture & Upload
|
|
# ==============================================================================
|
|
|
|
TEMP_FILE="${TEMP_DIR}/picupper_${CAMERA_ID}_$(date +%s).jpg"
|
|
|
|
# Check video device
|
|
if [[ ! -e "$VIDEO_DEVICE" ]]; then
|
|
log_error "Video device not found: $VIDEO_DEVICE"
|
|
exit 1
|
|
fi
|
|
|
|
# Capture image
|
|
log "Capturing from $VIDEO_DEVICE ($RESOLUTION)"
|
|
if ! fswebcam -d "$VIDEO_DEVICE" -r "$RESOLUTION" -S "$SKIP_FRAMES" --no-banner "$TEMP_FILE" 2>/dev/null; then
|
|
log_error "Capture failed"
|
|
exit 1
|
|
fi
|
|
|
|
FILE_SIZE=$(stat -c%s "$TEMP_FILE" 2>/dev/null || echo "unknown")
|
|
log "Captured: $TEMP_FILE ($FILE_SIZE bytes)"
|
|
|
|
# Upload with retry
|
|
upload_success=false
|
|
attempt=1
|
|
|
|
while [[ $attempt -le $MAX_RETRIES ]]; do
|
|
log "Upload attempt $attempt/$MAX_RETRIES"
|
|
|
|
HTTP_RESPONSE=$(curl -s -w "\n%{http_code}" \
|
|
--max-time "$TIMEOUT" \
|
|
-X POST \
|
|
-H "X-API-Key: $API_KEY" \
|
|
-F "image=@$TEMP_FILE" \
|
|
-F "cameraId=$CAMERA_ID" \
|
|
"$API_URL" 2>/dev/null) || true
|
|
|
|
HTTP_CODE=$(echo "$HTTP_RESPONSE" | tail -n1)
|
|
RESPONSE_BODY=$(echo "$HTTP_RESPONSE" | sed '$d')
|
|
|
|
if [[ "$HTTP_CODE" == "200" ]]; then
|
|
log "Upload successful (HTTP $HTTP_CODE)"
|
|
upload_success=true
|
|
break
|
|
else
|
|
log_error "Upload failed (HTTP $HTTP_CODE): $RESPONSE_BODY"
|
|
|
|
if [[ $attempt -lt $MAX_RETRIES ]]; then
|
|
log "Retrying in $RETRY_DELAY seconds..."
|
|
sleep "$RETRY_DELAY"
|
|
fi
|
|
fi
|
|
|
|
((attempt++))
|
|
done
|
|
|
|
if [[ "$upload_success" != "true" ]]; then
|
|
log_error "All upload attempts failed"
|
|
exit 1
|
|
fi
|
|
|
|
log "Done"
|