My Home Assistant CCTV camera setup

3 minute read

ESPHome setup

First, we have to configure and install ESPHome on the camera.

Most ESP32-CAM modules do not have a USB-UART bridge onboard, so you will need an external adaptor. Those based on the CH340G chip are cheap and readily available from eBay, Aliexpress, etc, and perfectly suitable for flashing ESP8266/32 and various Arduino devices. Make sure that the adapter you use is set to 3V3, as 5V can kill the ESP.

I will not cover how to flash ESPHome firmware here, but the ESPHome wiki does quite a good job. If you still have questions, try asking in the ESPHome forums or on Discord.

Configure firmware

I have the Ai-Thinker ESP32-CAM module. You may have to edit the configuration below to fit your camera module. Also, be warned that some modules can get very hot, in particular the M5Stack.

  name: living-room-camera
  platform: ESP32
  # board: esp32cam
  board: esp32dev

  ssid: "WiFiNetwork"
  password: "WiFIPassword"

  # Enable fallback hotspot (captive portal) in case wifi connection fails
    ssid: "Living Room Camera"
    password: "FallbackPassword"

  power_save_mode: NONE


# Enable logging

# Enable Home Assistant API

# Enable over-the-air updates

# Camera
    pin: GPIO0
    frequency: 20MHz
    sda: GPIO26
    scl: GPIO27
  data_pins: [GPIO5, GPIO18, GPIO19, GPIO21, GPIO36, GPIO39, GPIO34, GPIO35]
  vsync_pin: GPIO25
  href_pin: GPIO23
  pixel_clock_pin: GPIO22
  power_down_pin: GPIO32
  name: "Living Room Camera"
  id: camera
  max_framerate: 10 fps
  idle_framerate: 0.2 fps
  resolution: 1600x1200
  jpeg_quality: 10
  contrast: 1
  brightness: 0
  saturation: 0
  vertical_flip: true
  horizontal_mirror: true

# Flash light (optional)
  - platform: gpio
    pin: GPIO4
    id: flash

# Light (optional)
  - platform: binary
    output: flash
    name: "Living Room Camera Flash"

# Restart switch (optional)
  - platform: restart
    name: "Living Room Camera Restart"

For more information on setting up various camera modules, see the ESPHome wiki.

Home Assistant setup

Create token

Click on your profile in the lower left corner of the Home Assistant web UI. Scroll down on this page all the way to the section titled “Long-Lived Access Tokens”.

Here, create a token. Name it anything you like, I recommend something like motioneye to easily differentiate it from any other long-lived tokens you may have.

Nginx Addon

Install the Nginx Proxy core addon via the addon store in Home Assistant settings, if you haven’t already.


On the addon page, in Configuration > Options > Customize, paste the following:

active: true
default: nginx_proxy_default*.conf
servers: nginx_proxy/*.conf

This allows you to add custom server configs in the /share/nginx_proxy/ directory. You can do so via the terminal addon, or samba.

On the same page, add a port for HTTP (non-SSL). This cannot be already in use by another addon, or by Home Assistant. I suggest 8080.

Extra config

Add a file in /share/nginx_proxy/motioneye.conf and copy the config below. Remember the following:

  • Replace Bearer xxxx with your own token. It should be the same length as shown below.
  • Replace the port 8080 in proxy_set_header Host $host:8080; with whatever port you chose earlier for HTTP.
server {
    server_name localhost;
    listen 80;

    location /api/camera_proxy {
        proxy_pass http://homeassistant:8123/api/camera_proxy;
        proxy_set_header Host $host:8080;
        proxy_http_version 1.1;
        proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
        proxy_set_header Authorization "Bearer rJeWKWcwvByeuuXTWdRyEtuKwfNWRJeRwtk6.QhF733CgyngaxlOPQH4aZdLURAG7ORUkTIUAlTmKT4x9pQMpevjiTR7fBwXnbzKS0pAzgNyvRS1LkOqEOBYD0AbcALu3VmTMfRIYRv.VhpZbpcNVbZKaT85-2dUSjXTTPBDzvcdjFYwVNeoIgB";

Once this is done, restart the Nginx addon to make sure the new config is loaded.


Install the motionEye addon via the addon store in Home Assistant settings, if you haven’t already.

Open the web UI and login with the default username admin and no password. From here, add a new camera of type “Network Camera”. In the URL field, paste http://localhost:8080/api/camera_proxy/camera.living_room_camera and replace the port with whatever you chose earlier, and the entity name (in this case camera.living_room_camera) with the entity name of your own camera.

You should now be able to see the camera stream from within motionEye, and configure motion detection, movies/stills and notifications as desired.

I will create a further guide for motion events, automations and push notifications via the Home Assistant app, later. Previously I used a series of webhooks to accomplish this, though in theory the new motionEye integration should vastly simplify the setup. However, I have not yet had time to test it.