CCTV Upgrade Plan
Two architectures: one for existing sites with Swann NVRs, one for new sites going full Linux.
Architecture A: Existing Sites (Swann Hybrid)
Keep Swann NVR for PoE power and local HDD recording. Add Linux box for brains.
┌─────────────────────────────────────────────────────────────────┐
│ Existing Site │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ Swann NVR │ │ Linux Box │ │
│ │ │ RTSP │ │ │
│ │ • PoE ports │─────────────►│ • Frigate │ │
│ │ • HDD record │ (pull) │ • OME │ │
│ │ • Local view │ │ • Capture │ │
│ │ • RTSP server │ │ • API │ │
│ └───────┬────────┘ └───────┬────────┘ │
│ │ │ │
│ Cameras WireGuard │
│ (existing) to Central │
│ │ │
└───────────────────────────────────────────┼──────────────────────┘
│
▼
┌───────────────┐
│ Central │
│ Admin App │
│ │
│ • All sites │
│ • All cams │
│ • Scrubber │
│ • AI alerts │
└───────────────┘
What Swann NVR Does (Dumb Mode)
- Powers cameras via PoE
- Records to local HDD (backup/compliance)
- Serves RTSP streams
- That's it. No app, no cloud, no interaction.
What Linux Box Does (Smart Mode)
- Frigate: AI detection (person, car, animal)
- OME: WebRTC streaming to admin app
- Capture: Frame snapshots for scrubber
- API: Unified access for admin app
- WireGuard: Secure tunnel to central
Hardware per Site (Hybrid)
| Item | Purpose | ~Cost |
|---|---|---|
| Linux mini PC | Intel N100 or i3/i5 | $150-300 |
| Google Coral USB | AI acceleration | $60 |
| SSD 256GB+ | OS + Frigate clips | included |
| (Optional) HDD | Extended clip storage | $50-100 |
Total: ~$250-400 per site (cameras & NVR already exist)
Benefits
- No recabling
- No camera replacement
- Swann HDD = local backup
- All brains in Linux box
- Unified admin app access
Architecture B: New Sites (Full Linux)
No Swann. Linux box does everything.
┌─────────────────────────────────────────────────────────────────┐
│ New Site │
│ │
│ ┌────────────────┐ ┌────────────────┐ │
│ │ PoE Switch │ │ Linux Box │ │
│ │ │ RTSP │ │ │
│ │ • 8-16 ports │─────────────►│ • Frigate │ │
│ │ • Powers cams │ (direct) │ • OME │ │
│ │ │ │ • Capture │ │
│ │ │ │ • Recording │ ◄── NEW │
│ └───────┬────────┘ │ • API │ │
│ │ └───────┬────────┘ │
│ IP Cameras │ │
│ (standard) WireGuard │
│ to Central │
│ │ │
└───────────────────────────────────────────┼──────────────────────┘
│
▼
┌───────────────┐
│ Central │
│ Admin App │
└───────────────┘
What Linux Box Does (Everything)
- Frigate: AI detection + continuous recording
- OME: WebRTC streaming
- Capture: Frame snapshots for scrubber
- Recording: 24/7 video to local HDD
- API: Unified access
- WireGuard: Tunnel to central
Can One Box Handle It All?
YES. Here's why:
| Task | CPU Load | Notes |
|---|---|---|
| Recording 16 cameras | ~5% | Just writing RTSP to disk |
| Frigate detection | ~10% | With Coral TPU (80%+ without) |
| OME streaming | ~15% | Per active viewer |
| Capture snapshots | ~2% | Periodic ffmpeg |
Total baseline: ~20-30% CPU with Coral TPU
The Swann NVR's "recording" job is actually trivial - it's just copying streams to disk. The hard work is:
- AI detection (solved by Coral TPU)
- Transcoding for WebRTC (OME handles efficiently)
Hardware per Site (Full Linux)
| Item | Purpose | ~Cost |
|---|---|---|
| PoE Switch 8-port | Power cameras | $80-120 |
| Linux PC | i5/Ryzen 5, 16GB RAM | $300-500 |
| Google Coral USB | AI acceleration | $60 |
| HDD 4-8TB | Video storage | $100-150 |
| SSD 256GB | OS + Frigate DB | $30 |
| IP Cameras | Standard RTSP/ONVIF | $50-150 each |
Total: ~$600-900 + cameras
Recommended PC Specs (Full Linux)
| Component | Minimum | Recommended |
|---|---|---|
| CPU | Intel N100 / i3 | i5 / Ryzen 5 |
| RAM | 8GB | 16GB |
| OS Drive | 128GB SSD | 256GB NVMe |
| Storage | 2TB HDD | 4-8TB HDD |
| Coral TPU | Required | Required |
Storage Calculator
| Cameras | Bitrate | Hours | Daily | 30 Days |
|---|---|---|---|---|
| 8 | 4 Mbps | 24h | 173 GB | 5.2 TB |
| 16 | 4 Mbps | 24h | 346 GB | 10.4 TB |
| 8 | 2 Mbps | 24h | 86 GB | 2.6 TB |
| 16 | 2 Mbps | 24h | 173 GB | 5.2 TB |
Tip: Use sub-streams (lower res) for detection, main stream for recording.
Frigate Configuration (Both Architectures)
# frigate.yml
mqtt:
enabled: false # Or true if using Home Assistant
detectors:
coral:
type: edgetpu
device: usb
cameras:
driveway:
ffmpeg:
inputs:
# Hybrid: Pull from Swann NVR
- path: rtsp://admin:password@192.168.1.9:554/ip1/0
roles: [detect, record]
# Full Linux: Pull from camera directly
# - path: rtsp://admin:password@192.168.1.101:554/stream1
# roles: [detect, record]
detect:
width: 1280
height: 720
fps: 5
record:
enabled: true
retain:
days: 7
mode: motion # Only keep motion events
snapshots:
enabled: true
retain:
default: 7
Network Architecture (Starlink/CGNAT Sites)
Sites without fixed IP connect OUT to central hub.
┌─────────────────────────────────────────────────────────────────┐
│ Central Hub (DizHaus) │
│ │
│ ┌──────────────┐ ┌──────────────┐ ┌──────────────┐ │
│ │ nginx │ │ WireGuard │ │ Bazzite │ │
│ │ (admin) │ │ Server │ │ (local OME) │ │
│ └──────────────┘ └──────┬───────┘ └──────────────┘ │
│ │ │
│ VPN Subnet │
│ 10.200.200.0/24 │
│ │ │
└──────────────────────────────┼───────────────────────────────────┘
│
┌─────────────────────┼─────────────────────┐
│ │ │
▼ ▼ ▼
┌───────────┐ ┌───────────┐ ┌───────────┐
│ Site A │ │ Site B │ │ Site C │
│ 10.200. │ │ 10.200. │ │ 10.200. │
│ 200.2 │ │ 200.3 │ │ 200.4 │
│ │ │ │ │ │
│ Starlink │ │ Fixed IP │ │ Starlink │
│ (no port │ │ (can port │ │ (no port │
│ forward) │ │ forward) │ │ forward) │
└───────────┘ └───────────┘ └───────────┘
All sites connect to central WireGuard. Admin app accesses sites via VPN IPs.
Rollout Plan
Phase 1: DizHaus (Done ✓)
- OME streaming
- Capture + scrubber
- Replay with actual timestamps
Phase 1.5: Add Frigate to DizHaus (Recommended Next Step)
Why: Our current capture script hammers the NVR with connection churn. Frigate holds persistent connections and re-serves locally.
Current architecture (problematic):
NVR ←──┬── OME (14 persistent connections - OK)
│
└── Capture (14 cameras × open/close every 4-20 sec = churn)
With Frigate (better):
NVR ←── Frigate (14 persistent connections, stable)
│
├── OME pulls from Frigate (local, free)
├── Capture pulls from Frigate (local, free)
├── AI detection (bonus)
└── 48-hour video buffer (bonus)
What we gain:
- Stable NVR load - No more DDOS risk from capture
- Faster snapshots - Pull from local Frigate, not remote NVR
- AI detection - Person/car/animal alerts
- 48-hour video buffer - Request clips on demand
New feature: Video Clip Requests
With Frigate recording a rolling 48-hour window, users could:
- Use replay scrubber to find incident
- Click "Request Video" with time range
- Frigate exports MP4 clip
- Download from admin app
No more thumbstick trips. No more Swann app.
Hardware needed:
- Google Coral USB TPU (~$60)
- HDD for 48-hour buffer (~2TB, ~$50)
Implementation:
- Install Frigate on bazzite (Docker)
- Point Frigate at NVR RTSP streams
- Update OME to pull from Frigate re-stream
- Update capture to use Frigate snapshots API
- Add video request endpoint to admin API
- Add "Request Video" button to replay UI
Phase 2: Existing Sites (Hybrid)
For each site:
- Ship pre-configured Linux box
- Connect to network, plug into NVR RTSP
- Configure WireGuard
- Add to admin app
Phase 3: New Sites (Full Linux)
- Install PoE switch + IP cameras
- Configure Linux box with Frigate recording
- WireGuard to central
- Add to admin app
Admin App Integration
CCTV Page Features
| Feature | Status | Notes |
|---|---|---|
| Live streaming | ✓ | Via OME/WebRTC |
| Replay scrubber | ✓ | Frame capture |
| Actual timestamps | ✓ | Shows "2h 15m ago" not frame count |
| Site selector | ✓ | DizHaus only currently |
| Multi-site | Planned | Add site configs |
| AI alerts | Planned | Frigate integration |
| Event search | Planned | "Show all people today" |
| Video clip request | Planned | Select time range → download MP4 |
| 48-hour buffer | Planned | Rolling video window via Frigate |
API Endpoints (per site)
# Frigate API
GET /api/events # AI detection events
GET /api/events/{id}/clip # Download event clip
GET /api/events/{id}/snapshot # Event thumbnail
GET /api/{camera}/latest.jpg # Current snapshot
# Existing (OME + Capture)
WS /ws-ome/{site}/{camera} # Live WebRTC
GET /api/v1/cctv/replay/... # Scrubber frames
Cost Comparison
Per Site
| Approach | Hardware | Recurring | Total Y1 |
|---|---|---|---|
| Swann NVR only | $500-800 | $0 | $500-800 |
| Hybrid (keep Swann + Linux) | $250-400 | $0 | $250-400 |
| Full Linux (replace Swann) | $600-900 | $0 | $600-900 |
| Cloud NVR (Verkada etc) | $300-500/cam | $200/cam/yr | $$$$ |
Winner: Hybrid for existing sites, Full Linux for new sites.
Summary
Existing 6 sites: Add ~$300 Linux box each. Keep Swann as dumb PoE + backup recorder.
New sites: Skip Swann entirely. PoE switch + beefier Linux box + IP cameras.
All sites unified in admin app with live view, AI detection, scrubber, and clip export.
No more Swann app. No more thumbstick trips. No more daylight savings nightmares.
Created: December 2025