Skip to content

Motion Camera System Implementation - Deployment Guide #262

@yuanwang-wf

Description

@yuanwang-wf

Implementation Complete ✓

The Motion camera system has been fully implemented and is ready for deployment to the misfit host.

What Was Implemented

Files Created

  1. modules/motion.nix - Main Motion service module

    • Systemd service configuration
    • Motion daemon with configurable options
    • Automatic cleanup timer for 7-day retention
    • User/group management with video device access
    • Tmpfiles rules for directory structure
  2. hosts/misfit/motion.nix - Host-specific configuration

    • Enables Motion service on misfit
    • Configured for 7-day retention
    • Local network access only (ports 8080-8081)

Files Modified

  1. hosts/misfit/default.nix - Added module imports

    • Imported ../../modules/motion.nix
    • Imported ./motion.nix
  2. hosts/misfit/jellyfin.nix - Extended activation script

    • Added /data/Cameras directory creation
    • Added /data/Cameras/recordings subdirectory
    • Added /data/Cameras/snapshots subdirectory

Architecture Overview

```
┌─────────────────────────────────────────┐
│ Home Assistant (localhost:8123) │
│ - Ready for camera integration │
└─────────────────┬───────────────────────┘
│ HTTP/MJPEG
│ localhost:8080-8081
┌─────────────────▼───────────────────────┐
│ Motion Daemon (systemd service) │
│ - Video capture & encoding │
│ - Motion detection │
│ - MJPEG streaming │
│ - Continuous recording (720p, 15fps) │
└─────────────────┬───────────────────────┘

┌─────────────────▼───────────────────────┐
│ Storage: /data/Cameras/ │
│ - recordings/ (7-day retention) │
│ - snapshots/ (motion events) │
│ - motion.log (daemon logs) │
└─────────────────────────────────────────┘
```


Deployment Instructions

Step 1: Deploy to Misfit

From the misfit host, run:

```bash
cd /path/to/nix-home
nixos-rebuild switch --flake '.#misfit' --use-remote-sudo
```

Step 2: Verify Service Status

```bash

Check motion daemon status

systemctl status motion

Check cleanup timer status

systemctl status motion-cleanup.timer

View motion logs

journalctl -u motion -f
```

Step 3: Verify Directory Structure

```bash

Check directories were created

ls -la /data/Cameras/

Verify ownership

Should be: motion:motion

ls -la /data/Cameras/recordings/
ls -la /data/Cameras/snapshots/
```

Step 4: Test Camera Access

```bash

Test web interface (from misfit)

curl http://localhost:8080

Test MJPEG stream (from misfit)

curl http://localhost:8081
```

Step 5: Access from Local Network

From another device on your local network:

```bash

Web interface

http://misfit.local:8080

MJPEG stream

http://misfit.local:8081
```


Configuration Details

Motion Service Options

The service is configured with:

  • Data directory: /data/Cameras
  • Web interface: localhost:8080 (local only)
  • Stream port: 8081 (accessible on local network)
  • Recording mode: Continuous recording
  • Video format: MKV (H.264)
  • Resolution: 1280x720 @ 15fps
  • Retention: 7 days automatic cleanup
  • Motion detection: Enabled (threshold: 1500)

Storage Estimates

  • Per camera per day: ~2-3GB (continuous 720p)
  • 7-day retention: ~15-20GB per camera
  • Multiple cameras: Plan for 50-100GB total

Security Features

  • File permissions: 0750 (owner: motion, group: motion)
  • Web interface: Bound to localhost only (not exposed)
  • Stream: Accessible on local network only
  • No firewall changes: Local network access only
  • User isolation: Runs as dedicated motion system user
  • Video device access: motion user added to video group

Home Assistant Integration (Optional)

To integrate with Home Assistant, add to hosts/misfit/configuration.nix:

```nix
services.home-assistant = {
enable = true;

... existing config ...

config = {
# ... existing config ...

camera = [
  {
    platform = "mjpeg";
    name = "Motion Camera 1";
    mjpeg_url = "http://localhost:8081";
    still_image_url = "http://localhost:8080/0/current";
  }
];

};
};
```

Then rebuild and restart Home Assistant:
```bash
nixos-rebuild switch --flake '.#misfit'
systemctl restart home-assistant
```


Troubleshooting

Motion Service Won't Start

```bash

Check detailed logs

journalctl -u motion -n 50

Verify video device exists

ls -la /dev/video*

Check if motion user has video group access

groups motion
```

No Video Device Found

If /dev/video0 doesn't exist:

  • For USB cameras: Plug in camera and check dmesg | grep video
  • For IP cameras: Edit modules/motion.nix to use RTSP URL instead of /dev/video0

```nix

In motionConfigFile, change:

videodevice rtsp://username:password@camera-ip:554/stream
```

Recordings Not Appearing

```bash

Check permissions

ls -la /data/Cameras/recordings/

Verify motion can write

sudo -u motion touch /data/Cameras/recordings/test.txt

Check disk space

df -h /data
```

Cleanup Not Working

```bash

Check timer status

systemctl status motion-cleanup.timer

Manually trigger cleanup

systemctl start motion-cleanup

Check timer logs

journalctl -u motion-cleanup
```


Advanced Configuration

Multiple Cameras

To add more cameras, edit modules/motion.nix motion.conf:

```conf

Camera 1

camera /etc/motion/camera1.conf

Camera 2

camera /etc/motion/camera2.conf
```

Create separate config files for each camera with different devices/URLs.

Hardware Acceleration

For better performance with multiple cameras, enable VAAPI:

```nix

In modules/motion.nix motionConfigFile

movie_codec mp4:h264_vaapi
```

Ensure Intel GPU drivers are loaded on misfit.

Public Access (Optional)

To add public HTTPS access via Caddy:

In modules/caddy.nix, add:
```nix
"camera.yuanw.me" = {
useACMEHost = "yuanw.me";
extraConfig = ''
reverse_proxy localhost:8080
basicauth {
admin $2a$14$... # bcrypt hash
}
'';
};
```

Then open firewall port in hosts/misfit/configuration.nix:
```nix
networking.firewall.allowedTCPPorts = [

... existing ports ...

80 443 # for Caddy reverse proxy
];
```


Testing Checklist

  • Service starts: systemctl status motion shows active
  • Cleanup timer active: systemctl status motion-cleanup.timer
  • Directories created: /data/Cameras/{recordings,snapshots} exist
  • Correct permissions: motion:motion owns directories
  • Web interface accessible: curl http://localhost:8080
  • Stream accessible: curl http://localhost:8081
  • Recording starts: Files appear in /data/Cameras/recordings/
  • Logs clean: No errors in journalctl -u motion

Next Steps

  1. Deploy to misfit using instructions above
  2. Verify service status and check logs
  3. Test camera functionality with a USB or IP camera
  4. (Optional) Integrate with Home Assistant for dashboards
  5. (Optional) Set up automations for motion detection alerts

Files Changed Summary

```
modules/motion.nix (new, 182 lines)
hosts/misfit/motion.nix (new, 10 lines)
hosts/misfit/default.nix (modified, +2 lines)
hosts/misfit/jellyfin.nix (modified, +3 lines)
```

Ready to deploy! 🚀

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions