Skip to content

meorajrul/dslr2cloud-client

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

17 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

DSLR2Cloud Client

Real-time Canon EOS and Sony Alpha photo sync to cloud storage, running on Raspberry Pi 4.

Captures photos from your Canon or Sony camera (USB or WiFi) and uploads them to Google Photos, Google Drive, S3, or other cloud targets — configured remotely from the dslr2cloud-server dashboard.

How It Works

  1. The client runs on a Raspberry Pi 4 connected to your Canon or Sony camera
  2. It detects new photos as you shoot (via gphoto2 over USB, or Canon CCAPI over WiFi)
  3. Photos are queued locally in SQLite and uploaded to your configured cloud connectors
  4. The server dashboard manages which cloud targets to use, folder paths, and project settings
  5. Everything works offline — photos queue locally and upload when connectivity returns

Requirements

  • Raspberry Pi 4 (2GB+ RAM recommended) or any Linux machine
  • Python 3.11+
  • Canon EOS camera (USB cable or WiFi-enabled model for CCAPI), or Sony Alpha camera (USB cable)
  • Network connection (WiFi, Ethernet, or phone hotspot) for cloud uploads
  • A running dslr2cloud-server instance

Step-by-Step Setup on Raspberry Pi 4

1. Update your Pi

sudo apt-get update && sudo apt-get upgrade -y

2. Install system dependencies

sudo apt-get install -y git python3 python3-pip python3-venv gphoto2 libgphoto2-dev

3. Clone the repository

cd ~
git clone https://github.com/yourusername/dslr2cloud-client.git
cd dslr2cloud-client

4. Create Python virtual environment

python3 -m venv .venv
source .venv/bin/activate

5. Install the client

pip install -e ".[dev]"

6. Configure environment

cp .env.example .env
nano .env

Update these values:

# Point to your dslr2cloud server
SERVER_URL=https://your-server.example.com

# Camera interface: gphoto2 (USB) or ccapi (WiFi)
CAMERA_INTERFACE=gphoto2

# For WiFi cameras using CCAPI, uncomment and set:
# CAMERA_IP=192.168.1.100

7. Connect your camera

USB connection (Canon & Sony):

  • Plug your camera into any USB port on the Pi
  • Turn the camera on
  • Canon: Set USB mode to PTP/PC Connection in the camera menu
  • Sony: Set USB Connection to PC Remote or Mass Storage (Settings → USB → USB Connection)
  • Verify the camera is detected:
gphoto2 --auto-detect

You should see your camera model listed (e.g., Canon EOS R6 or Sony Alpha-A7 IV (ILCE-7M4)). If not, check the USB cable and camera USB settings.

WiFi connection (Canon CCAPI only):

  • Enable CCAPI on your camera (requires Canon's CCAPI activation tool — see Canon developer docs)
  • Connect the Pi and camera to the same WiFi network
  • Set CAMERA_INTERFACE=ccapi and CAMERA_IP=<camera IP> in .env

8. Run the client

./scripts/run.sh

The script activates the venv automatically and starts the web dashboard and photo sync pipeline. Open http://<pi-ip>:8080 in any browser on the same network.

To also launch a Tkinter desktop window (if a display is attached to the Pi):

./scripts/run.sh --desktop

First time only: make the script executable with chmod +x scripts/run.sh

9. Pair with the server

On the server dashboard, register a new device and copy the pairing code (e.g. ABCD-1234).

Then open the web dashboard at http://<pi-ip>:8080 — the pairing card is shown at the top when the device is unpaired. Enter the code and click Pair Device.

This reads the Pi's MAC address, sends it to the server, and stores the API key locally. You only need to do this once — the pairing persists in ~/.dslr2cloud/device.db.

10. Set up auto-start on boot (systemd service)

Create the service file:

sudo nano /etc/systemd/system/dslr2cloud.service

Paste this content:

[Unit]
Description=DSLR2Cloud Client — Real-time photo sync
After=network-online.target
Wants=network-online.target

[Service]
Type=simple
User=pi
WorkingDirectory=/home/pi/dslr2cloud-client
ExecStart=/home/pi/dslr2cloud-client/.venv/bin/python src/main.py
Restart=always
RestartSec=10
Environment=PYTHONUNBUFFERED=1

[Install]
WantedBy=multi-user.target

Note: If your username is not pi, replace /home/pi with your actual home directory.

Enable and start the service:

sudo systemctl daemon-reload
sudo systemctl enable dslr2cloud
sudo systemctl start dslr2cloud

12. Verify it's running

sudo systemctl status dslr2cloud

You should see active (running). On the server dashboard, your device should show as online. The web dashboard is accessible at http://<pi-ip>:8080.

Web Dashboard

The client includes a built-in web dashboard accessible from any device on the same network at http://<pi-ip>:8080.

Features:

  • Live status — service state, camera connection, server reachability, queue depth (polls every 2s)
  • Device pairing — enter pairing code directly in the browser
  • Service controls — start/stop the photo sync pipeline
  • Upload statistics — today's uploads, success rate, recent upload history
  • Queue monitor — pending jobs per connector, recent failures
  • Configuration — view server-synced config, connectors, and local settings

Configuration:

Variable Default Description
GUI_PORT 8080 Web dashboard port
GUI_HOST 0.0.0.0 Bind address (0.0.0.0 = all interfaces, 127.0.0.1 = local only)

Desktop GUI (Optional)

For Raspberry Pi units with a touchscreen or monitor attached, a Tkinter desktop window is available:

python src/main.py --desktop
# or set GUI_DESKTOP=true in .env

The desktop GUI shows a compact status display with service controls and an "Open Web Dashboard" button. It polls the same local API as the web dashboard.

Managing the Service

# Check status
sudo systemctl status dslr2cloud

# View live logs
journalctl -u dslr2cloud -f

# Restart (e.g., after a config change)
sudo systemctl restart dslr2cloud

# Stop
sudo systemctl stop dslr2cloud

# Disable auto-start
sudo systemctl disable dslr2cloud

Development

Run tests

source .venv/bin/activate
python -m pytest tests/ -v

Format code

black src/ tests/
isort src/ tests/
ruff check src/ tests/

Test camera connection manually

python scripts/test_camera.py

Configuration Reference

All configuration is in .env. The server can override most settings remotely — local .env values are used as defaults and for bootstrap (server URL, camera interface).

Variable Default Description
SERVER_URL http://localhost:8000 URL of the dslr2cloud server
LOG_LEVEL INFO Logging level (DEBUG, INFO, WARNING, ERROR)
STAGING_DIR /tmp/dslr2cloud/staging Temp directory for photos before upload
DB_PATH ~/.dslr2cloud/device.db SQLite database path
PHOTO_CHECK_INTERVAL 5 Seconds between camera polls
CONFIG_SYNC_INTERVAL 300 Seconds between server config syncs
HEARTBEAT_INTERVAL 60 Seconds between heartbeats to server
CAMERA_INTERFACE gphoto2 Camera interface: gphoto2 or ccapi
CAMERA_IP (empty) IP address for CCAPI WiFi cameras
MAX_CONCURRENT_UPLOADS 2 Parallel uploads per connector
UPLOAD_TIMEOUT 300 Upload timeout in seconds
MAX_RETRIES 3 Max upload retry attempts
RETRY_DELAY 30 Initial retry delay (exponential backoff)
GUI_PORT 8080 Web dashboard port
GUI_HOST 0.0.0.0 Dashboard bind address

Hardware Tips

  • Powered USB hub: The Pi 4 provides 1.2A total across USB ports. Canon and Sony cameras can draw 500mA+. Use a powered hub for long shoots to avoid disconnects.
  • Heat management: The Pi can throttle under sustained load. A heatsink or fan case helps during continuous uploads.
  • SD card: Use a high-endurance microSD (32GB+). The SQLite database and staging directory write frequently.
  • WiFi vs Ethernet: Ethernet is more reliable for uploads. WiFi works but may drop during large RAW file transfers (50MB+ per file).
  • Battery: For outdoor shoots, a USB-C power bank (10000mAh+, 5V/3A) can run the Pi for several hours.

Troubleshooting

Camera not detected (gphoto2)

# Kill any process holding the camera
sudo killall gvfs-gphoto2-volume-monitor 2>/dev/null
gphoto2 --auto-detect

Sony camera not detected

  • Set USB Connection to PC Remote (Settings → USB → USB Connection)
  • Some Sony models need USB LUN Setting set to Multi
  • Try a different USB cable — some cables are charge-only

Permission denied on USB

# Add your user to the plugdev group
sudo usermod -aG plugdev $USER
# Then log out and back in

Pairing fails

  • Check that the server is reachable: curl https://your-server.com/api/v1/pair
  • Verify the pairing code hasn't expired (15-minute TTL)
  • Check if the MAC address is already paired to another device on the server

Uploads stuck in queue

# Check queue status in the database
sqlite3 ~/.dslr2cloud/device.db "SELECT connector_id, status, COUNT(*) FROM upload_queue GROUP BY connector_id, status;"

Service won't start

# Check for errors
journalctl -u dslr2cloud --no-pager -n 50

Project Structure

dslr2cloud-client/
├── README.md               # This file
├── CLAUDE.md               # Agent context
├── pyproject.toml           # Project config + dependencies
├── .env.example             # Configuration template
├── src/
│   ├── main.py              # Entry point
│   ├── config.py            # Config loading
│   ├── database.py          # SQLite setup + helpers
│   ├── identity.py          # MAC address + device identity
│   ├── service_state.py     # Shared runtime state
│   ├── camera/              # Camera adapters (gphoto2 for Canon/Sony/Nikon, CCAPI for Canon WiFi)
│   ├── pipeline/            # Photo watcher, staging, upload queue
│   ├── connectors/          # Cloud upload targets
│   ├── server/              # Server communication (config, heartbeat, pairing)
│   └── gui/                 # Web dashboard (FastAPI) + desktop GUI (Tkinter)
│       ├── app.py           # FastAPI app factory
│       ├── desktop.py       # Tkinter desktop window
│       ├── routes/          # API endpoints + dashboard route
│       ├── static/          # CSS + JS
│       └── templates/       # Jinja2 HTML templates
├── tests/                   # pytest test suite
└── scripts/
    ├── run.sh               # Start the client (auto-detects venv)
    ├── install.sh           # Automated Pi setup
    └── test_camera.py       # Manual camera test

License

MIT

About

No description, website, or topics provided.

Resources

Stars

Watchers

Forks

Releases

No releases published

Sponsor this project

Packages

 
 
 

Contributors