feat: Add Raspberry Pi webcam capture and upload demo with install/uninstall scripts, config, and README.

This commit is contained in:
sebseb7
2025-12-18 14:14:38 +01:00
parent c1f9c689b7
commit a8e1da9559
5 changed files with 469 additions and 0 deletions

131
demo/README.md Normal file
View File

@@ -0,0 +1,131 @@
# Raspberry Pi Webcam Capture Demo
Automated picture capture and upload for Raspberry Pi 3 with a USB webcam (Logitech 1080p).
## Quick Setup (5 minutes)
### 1. Install Required Packages
```bash
sudo apt update && sudo apt install -y fswebcam curl
```
### 2. Configure the Script
```bash
# Copy the config template
cp picupper.conf.example picupper.conf
# Edit with your settings
nano picupper.conf
```
Update `picupper.conf` with your API key and camera settings.
### 3. Install & Enable
```bash
# Make scripts executable
chmod +x capture-upload.sh install.sh
# Run installer (sets up cron job)
./install.sh
```
That's it! Your Pi will now capture and upload one picture per minute.
---
## Files Included
| File | Purpose |
|------|---------|
| `capture-upload.sh` | Main script - captures photo and uploads |
| `picupper.conf.example` | Configuration template |
| `install.sh` | Installer script (sets up cron) |
| `uninstall.sh` | Removes cron job |
## Configuration Options
Edit `picupper.conf`:
```bash
# PicUpper server URL
API_URL="https://dev.seedheads.de/picUploadApi/upload"
# Your API key (from server admin)
API_KEY="your-api-key-here"
# Camera identifier (unique name for this Pi)
CAMERA_ID="rpi-webcam-1"
# Resolution (1920x1080 for full HD)
RESOLUTION="1920x1080"
# Video device (usually /dev/video0)
VIDEO_DEVICE="/dev/video0"
```
## Manual Testing
```bash
# Test capture only (saves to /tmp)
./capture-upload.sh --test
# Run full capture and upload once
./capture-upload.sh
```
## Troubleshooting
### Check if webcam is detected
```bash
ls /dev/video*
v4l2-ctl --list-devices
```
### Test capture manually
```bash
fswebcam -d /dev/video0 -r 1920x1080 --no-banner test.jpg
```
### Check logs
```bash
# View recent capture logs
tail -f /var/log/picupper.log
```
### Common Issues
| Problem | Solution |
|---------|----------|
| "No video device" | Replug USB webcam, check `dmesg` |
| "Permission denied" | Add user to video group: `sudo usermod -aG video $USER` |
| "Upload failed" | Check API key and network connection |
## Changing Capture Frequency
Default is 1 picture per minute. To change:
```bash
# Edit cron job
crontab -e
```
Examples:
- Every 5 minutes: `*/5 * * * * /home/pi/picupper-demo/capture-upload.sh`
- Every 30 seconds: Use the included systemd timer (see advanced setup)
## Hardware Requirements
- Raspberry Pi 3 (any model)
- USB webcam (Logitech C920/C922/C270 recommended)
- SD card with Raspberry Pi OS
- Network connection (WiFi or Ethernet)
## Network Notes
The script retries failed uploads and logs all attempts. If your Pi loses network, captures continue and uploads resume when connectivity returns.

168
demo/capture-upload.sh Normal file
View File

@@ -0,0 +1,168 @@
#!/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:-/var/log/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')
echo "[$timestamp] $*" | tee -a "$LOG_FILE" 2>/dev/null || echo "[$timestamp] $*"
}
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"

94
demo/install.sh Normal file
View File

@@ -0,0 +1,94 @@
#!/bin/bash
# install.sh - Set up PicUpper webcam capture on Raspberry Pi
# Creates cron job for 1 picture per minute
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CAPTURE_SCRIPT="${SCRIPT_DIR}/capture-upload.sh"
CONFIG_FILE="${SCRIPT_DIR}/picupper.conf"
LOG_FILE="/var/log/picupper.log"
echo "=== PicUpper Installer ==="
echo ""
# Check dependencies
echo "Checking dependencies..."
if ! command -v fswebcam &>/dev/null; then
echo "❌ fswebcam not installed"
echo " Run: sudo apt update && sudo apt install -y fswebcam"
exit 1
fi
echo "✓ fswebcam"
if ! command -v curl &>/dev/null; then
echo "❌ curl not installed"
echo " Run: sudo apt update && sudo apt install -y curl"
exit 1
fi
echo "✓ curl"
# Check config
if [[ ! -f "$CONFIG_FILE" ]]; then
echo ""
echo "❌ Configuration file not found!"
echo " Please create it first:"
echo " cp picupper.conf.example picupper.conf"
echo " nano picupper.conf"
exit 1
fi
echo "✓ Config file exists"
# Check API key is configured
# shellcheck source=/dev/null
source "$CONFIG_FILE"
if [[ -z "${API_KEY:-}" || "$API_KEY" == "your-api-key-here" ]]; then
echo ""
echo "❌ API key not configured in picupper.conf"
echo " Edit the file and set your API key"
exit 1
fi
echo "✓ API key configured"
# Make scripts executable
chmod +x "$CAPTURE_SCRIPT"
chmod +x "${SCRIPT_DIR}/uninstall.sh" 2>/dev/null || true
echo "✓ Scripts are executable"
# Create log file if needed
if [[ ! -f "$LOG_FILE" ]]; then
sudo touch "$LOG_FILE"
sudo chown "$USER:$USER" "$LOG_FILE"
echo "✓ Log file created: $LOG_FILE"
else
echo "✓ Log file exists: $LOG_FILE"
fi
# Set up cron job
CRON_JOB="* * * * * $CAPTURE_SCRIPT >> $LOG_FILE 2>&1"
echo ""
echo "Setting up cron job for 1 picture per minute..."
# Check if cron job already exists
if crontab -l 2>/dev/null | grep -q "$CAPTURE_SCRIPT"; then
echo "⚠ Cron job already exists, skipping"
else
# Add to crontab
(crontab -l 2>/dev/null || true; echo "$CRON_JOB") | crontab -
echo "✓ Cron job added"
fi
echo ""
echo "=== Installation Complete ==="
echo ""
echo "Your Raspberry Pi will now capture a picture every minute."
echo ""
echo "Useful commands:"
echo " View logs: tail -f $LOG_FILE"
echo " Test capture: $CAPTURE_SCRIPT --test"
echo " Run manually: $CAPTURE_SCRIPT"
echo " Uninstall: ${SCRIPT_DIR}/uninstall.sh"
echo ""
echo "To change frequency, edit crontab: crontab -e"

View File

@@ -0,0 +1,47 @@
# PicUpper Configuration
# Copy this file to picupper.conf and update with your settings
# ==============================================================================
# SERVER SETTINGS
# ==============================================================================
# API endpoint URL
API_URL="https://dev.seedheads.de/picUploadApi/upload"
# Your API key (get this from the PicUpper server admin)
API_KEY="your-api-key-here"
# ==============================================================================
# CAMERA SETTINGS
# ==============================================================================
# Unique identifier for this camera (no spaces, use hyphens)
CAMERA_ID="rpi-webcam-1"
# Video device path (run 'ls /dev/video*' to find yours)
VIDEO_DEVICE="/dev/video0"
# Capture resolution (common options: 1920x1080, 1280x720, 640x480)
RESOLUTION="1920x1080"
# Skip first N frames (helps camera adjust exposure, default 5)
SKIP_FRAMES=5
# ==============================================================================
# ADVANCED SETTINGS (usually don't need to change)
# ==============================================================================
# Temporary file location
TEMP_DIR="/tmp"
# Log file location
LOG_FILE="/var/log/picupper.log"
# Connection timeout in seconds
TIMEOUT=30
# Retry failed uploads (0 = no retry)
MAX_RETRIES=3
# Delay between retries in seconds
RETRY_DELAY=5

29
demo/uninstall.sh Normal file
View File

@@ -0,0 +1,29 @@
#!/bin/bash
# uninstall.sh - Remove PicUpper cron job
set -euo pipefail
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
CAPTURE_SCRIPT="${SCRIPT_DIR}/capture-upload.sh"
echo "=== PicUpper Uninstaller ==="
echo ""
# Remove cron job
if crontab -l 2>/dev/null | grep -q "$CAPTURE_SCRIPT"; then
crontab -l | grep -v "$CAPTURE_SCRIPT" | crontab -
echo "✓ Cron job removed"
else
echo "⚠ No cron job found"
fi
echo ""
echo "Uninstall complete."
echo ""
echo "Note: Log file and configuration are preserved."
echo " Config: ${SCRIPT_DIR}/picupper.conf"
echo " Logs: /var/log/picupper.log"
echo ""
echo "To completely remove, also delete:"
echo " rm -rf ${SCRIPT_DIR}"
echo " sudo rm /var/log/picupper.log"