Frigate & Google Coral and Proxmox VM
Bought items:
Good Youtube Tutorial: https://www.youtube.com/watch?v=zKk9dnAp8FM
In Proxmox Node:
lsusb
root@orange:/etc/pve/lxc# lsusb
Bus 008 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 007 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 006 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 005 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 004 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 003 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 002 Device 003: ID 18d1:9302 Google Inc.
Bus 002 Device 001: ID 1d6b:0003 Linux Foundation 3.0 root hub
Bus 001 Device 002: ID 8087:0029 Intel Corp. AX200 Bluetooth
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Setup Ubuntu VM and Add USB device:
Restart VM
run lsusb to see if the vm has the USB
Install Docker and Portainer
Add this Docker Compose to install frigate
version: "3.9"
services:
frigate:
container_name: frigate
privileged: true # this may not be necessary for all setups
restart: unless-stopped
stop_grace_period: 30s # allow enough time to shut down the various services
image: ghcr.io/blakeblackshear/frigate:stable
shm_size: "512mb" # update for your cameras based on calculation above
devices:
- /dev/bus/usb:/dev/bus/usb # Passes the USB Coral, needs to be modified for other versions
- /dev/apex_0:/dev/apex_0 # Passes a PCIe Coral, follow driver instructions here https://coral.ai/docs/m2/get-started/#2a-on-linux
#- /dev/video11:/dev/video11 # For Raspberry Pi 4B
#- /dev/dri/renderD128:/dev/dri/renderD128 # For intel hwaccel, needs to be updated for your hardware
volumes:
- /etc/localtime:/etc/localtime:ro
- /mnt/portainer2/frigate/config:/config
- /mnt/portainer2/frigate/storage:/media/frigate
- type: tmpfs # Optional: 1GB of memory, reduces SSD/SD Card wear
target: /tmp/cache
tmpfs:
size: 1000000000
ports:
- "8971:8971"
- "5000:5000" # Internal unauthenticated access. Expose carefully.
- "8554:8554" # RTSP feeds
- "8555:8555/tcp" # WebRTC over tcp
- "8555:8555/udp" # WebRTC over udp
environment:
FRIGATE_RTSP_PASSWORD: "strong@pwd"
go to path VM IP:5000 to view the Frigate UI Configuration Editor
Twist your config like mine:
make sure to change username , password and ip address. Below is the 3 tapo c110 configuration url address
mqtt:
enabled: false
cameras:
tapo_username001: # <------ Name the camera
enabled: true
ffmpeg:
inputs:
- path: rtsp://tapo_username001:yourpassw@192.168.1.xxx:554/stream1 # <----- The stream you want to use for detection
roles:
- detect
- record
detect:
enabled: true # <---- disable detection until you have a working camera feed
width: 2304
height: 1296
fps: 5
motion:
threshold: 30
contour_area: 28
improve_contrast: true
record:
enabled: true
retain:
days: 30
mode: motion
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 30
tapo_username002: # <------ Name the camera
enabled: true
ffmpeg:
inputs:
- path: rtsp://tapo_username002:yourpassw@192.168.1.xxx:554/stream1 # <----- The stream you want to use for detection
roles:
- detect
- record
detect:
enabled: true # <---- disable detection until you have a working camera feed
width: 2304
height: 1296
fps: 5
motion:
threshold: 30
contour_area: 28
improve_contrast: true
record:
enabled: true
retain:
days: 30
mode: motion
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 30
tapo_username003: # <------ Name the camera
enabled: true
ffmpeg:
inputs:
- path: rtsp://tapo_username003:yourpassw@192.168.1.xxx:554/stream1 # <----- The stream you want to use for detection
roles:
- detect
- record
detect:
enabled: true # <---- disable detection until you have a working camera feed
width: 2304
height: 1296
fps: 5
motion:
threshold: 30
contour_area: 28
improve_contrast: true
record:
enabled: true
retain:
days: 30
mode: motion
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 30
record:
enabled: true
retain:
days: 30
mode: active_objects
alerts:
retain:
days: 30
mode: motion
detections:
retain:
days: 30
mode: motion
detectors:
coral:
type: edgetpu
device: usb
objects:
track:
- person
- face
- printer
- toy
- filament
- print_bed
- extruder
- tool
- wrench
- screw
- spaghetti
- failed_print
version: 0.15-1
camera_groups:
SonA1:
order: 1
icon: LuFingerprint
cameras:
- tapo_username001
- tapo_username002
- tapo_username003
Click save and restart button
Tips:
Make sure to disable detection on your tapo settings, disable the local recording ( we don't need to use sd card for storage )
Go to the UI > Settings > Motion Tuner to update the Threshold and Contour Area to match your needs.
If you have google coral, it should have red label around the images.
Well done.
PCI Devices mapping in Proxmox
if you restart your VM or Host, the usb address id could change so that you need to map your host usb into your vm usb. Here is a quick run:
Remove your PCI Device in your VM Hardware setting.
SSH into your host pc which has the coral usb plugged in, mine is Orange
lsusb -t
/: Bus 08.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
/: Bus 07.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
/: Bus 06.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
/: Bus 05.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
/: Bus 04.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 10000M
/: Bus 03.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/1p, 480M
/: Bus 02.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/2p, 10000M
|__ Port 2: Dev 3, If 0, Class=Vendor Specific Class, Driver=usbfs, 5000M << this is the one
/: Bus 01.Port 1: Dev 1, Class=root_hub, Driver=xhci_hcd/5p, 480M
|__ Port 5: Dev 2, If 0, Class=Wireless, Driver=btusb, 12M
|__ Port 5: Dev 2, If 1, Class=Wireless, Driver=btusb, 12M
Bus 02, Port 2 → Driver=xhci_hcd → PCIe USB controller
readlink -f /sys/bus/usb/devices/usb2
/sys/devices/pci0000:00/0000:00:08.1/0000:c5:00.3/usb2
PCI address: 0000:c5:00.3
Go to Data Center > Resource Mappings > Under PCI Devices Panel , click Add > Choose Mapping on Node: Orange
Scroll down and pick the id like the above, which is 0000:c5:00.3
give it a short Name: coralusb
click Create
Now go back to your VM and add your pci device into your vm hardware setting:
Pick your mapped device:
Done. Restart the VM.
Update on 29 May 2025, here is my frigate yaml configuration for both google coral and beelink ser7 gpu. This include go2rtc which will stream one connection to the camera and stream out to everything else.
mqtt:
enabled: false
go2rtc:
webrtc:
candidates:
- 192.168.1.114:8555
- portainer2.kyluat.lan:8555
- frigate:8555
streams:
son_user001:
- rtsp://user001:{FRIGATE_RTSP_PASSWORD}@192.168.1.100:554/stream2
- tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.100
- ffmpeg:son_user001#audio=opus
son_user001_record:
- ffmpeg:rtsp://user001:{FRIGATE_RTSP_PASSWORD}@192.168.1.100:554/stream2#video=copy
- tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.100
# son_user001_sub:
# - rtsp://user001:{{FRIGATE_RTSP_PASSWORD}}@192.168.1.100:554/stream2?timeout=92&rtsp_transport=tcp#video=copy
# - ffmpeg:son_user001#audio=opus
son_user002:
- rtsp://user002:{FRIGATE_RTSP_PASSWORD}@192.168.1.101:554/stream2
- tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.101
- ffmpeg:son_user002#audio=opus
son_user002_record:
- ffmpeg:rtsp://user002:{FRIGATE_RTSP_PASSWORD}@192.168.1.101:554/stream2#video=copy
- tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.101
# son_user002_sub:
# - rtsp://user002:{{FRIGATE_RTSP_PASSWORD}}@192.168.1.101:554/stream2?timeout=92&rtsp_transport=tcp#video=copy
# - ffmpeg:son_user002_sub#audio=opus
son_user003:
- rtsp://user003:{FRIGATE_RTSP_PASSWORD}@192.168.1.102:554/stream2
- tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.102
- ffmpeg:son_user003#audio=opus
son_user003_record:
- ffmpeg:rtsp://user003:{FRIGATE_RTSP_PASSWORD}@192.168.1.102:554/stream2#video=copy
- tapo://{FRIGATE_TAPO_PASSWORD}@192.168.1.102
# son_user003_sub:
# - rtsp://user003:{{FRIGATE_RTSP_PASSWORD}}@192.168.1.102:554/stream2?timeout=92&rtsp_transport=tcp#video=copy
# - ffmpeg:son_user003_sub#audio=opus
# son_user004:
# - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.190:554/cam/realmonitor?channel=1&subtype=0#video=copy
son_user004:
- rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.190:554/cam/realmonitor?channel=1&subtype=1#video=copy
- ffmpeg:son_user004_sub#audio=opus
# son_user005:
# - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.181:554/cam/realmonitor?channel=1&subtype=0#video=copy
son_user005:
- rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.181:554/cam/realmonitor?channel=1&subtype=1#video=copy
- ffmpeg:son_user005_sub#audio=opus
# son_user006:
# - rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.182:554/cam/realmonitor?channel=1&subtype=0#video=copy # L2C67C0F
son_user006:
- rtsp://admin:{FRIGATE_TAPO_PASSWORD}@192.168.1.182:554/cam/realmonitor?channel=1&subtype=1#video=copy # L2C67C0F
- ffmpeg:son_user006_sub#audio=opus
cameras:
son_user004: # <------ Name the camera
enabled: true
ffmpeg:
output_args:
record: preset-record-generic-audio-aac
inputs:
- path: rtsp://127.0.0.1:8554/son_user004 # <----- The stream you want to use for detection
input_args: preset-rtsp-restream
roles:
- record
# - path: rtsp://127.0.0.1:8554/son_user004_sub # <----- The stream you want to use for detection
# input_args: preset-rtsp-restream
# roles:
- detect
- audio
detect:
enabled: true # <---- disable detection until you have a working camera feed
fps: 5
motion:
threshold: 80
contour_area: 100
improve_contrast: false
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 90
zones:
person_zone:
coordinates: 0.997,0.902,0.255,0.746,0.322,0.009,0.77,0.004,0.68,0.191,0.996,0.071
loitering_time: 0
birdseye:
order: 1
review:
detections:
required_zones: person_zone
alerts:
required_zones: person_zone
objects: {}
son_user005: # <------ Name the camera
enabled: true
ffmpeg:
output_args:
record: preset-record-generic-audio-aac
inputs:
- path: rtsp://127.0.0.1:8554/son_user005 # <----- The stream you want to use for detection
input_args: preset-rtsp-restream
roles:
- record
# - path: rtsp://127.0.0.1:8554/son_user005_sub # <----- The stream you want to use for detection
# input_args: preset-rtsp-restream
# roles:
- detect
- audio
detect:
enabled: true # <---- disable detection until you have a working camera feed
fps: 5
motion:
threshold: 34
contour_area: 43
improve_contrast: false
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 90
zones:
person_zone:
coordinates: 0.229,0.03,0.217,1,0.415,0.991,0.96,0.957,0.982,0.004
loitering_time: 0
inertia: 3
birdseye:
order: 1
review:
alerts:
required_zones: person_zone
detections:
required_zones: person_zone
objects: {}
son_user006: # <------ Name the camera
enabled: true
ffmpeg:
output_args:
record: preset-record-generic-audio-aac
inputs:
- path: rtsp://127.0.0.1:8554/son_user006 # <----- The stream you want to use for detection
input_args: preset-rtsp-restream
roles:
- record
# - path: rtsp://127.0.0.1:8554/son_user006_sub # <----- The stream you want to use for detection
# input_args: preset-rtsp-restream
# roles:
- detect
- audio
detect:
enabled: true # <---- disable detection until you have a working camera feed
fps: 5
motion:
threshold: 80
contour_area: 100
improve_contrast: true
mask: 0.614,0.276,0.605,0.598,0.726,0.617,0.724,0.28
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 90
zones:
person_zone:
coordinates: 0.099,0.257,0.1,0.997,1,1,1,0.29
loitering_time: 0
birdseye:
order: 1
review:
alerts:
required_zones: person_zone
detections:
required_zones: person_zone
objects:
mask: 0.727,0.219,0.725,0.392,0.914,0.41,0.896,0.207
son_user001: # <------ Name the camera
enabled: true
ffmpeg:
output_args:
record: preset-record-generic-audio-aac
inputs:
- path: rtsp://127.0.0.1:8554/son_user001_record # <----- The stream you want to use for record
input_args: preset-rtsp-restream
roles:
- record
- path: rtsp://127.0.0.1:8554/son_user001 # <----- The stream you want to use for detect
input_args: preset-rtsp-restream
roles:
- detect
- audio
record:
enabled: true
retain:
days: 90 # Keep recordings for 7 days (adjust as needed)
mode: all # Options: motion | active_objects | all
detect:
enabled: true # <---- disable detection until you have a working camera feed
fps: 5
motion:
threshold: 80
contour_area: 100
improve_contrast: true
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 90
zones:
plate:
coordinates:
0.269,0,0.276,0.29,0,0.568,0.145,1,0.404,1,0.896,1,1,0.583,0.943,0.413,0.803,0.297,0.795,0
loitering_time: 0
inertia: 3
birdseye:
order: 1
review:
detections:
required_zones: plate
alerts:
required_zones: plate
objects: {}
son_user002: # <------ Name the camera
enabled: true
ffmpeg:
output_args:
record: preset-record-generic-audio-aac
inputs:
- path: rtsp://127.0.0.1:8554/son_user002_record # <----- The stream you want to use for detection
input_args: preset-rtsp-restream
roles:
- record
- path: rtsp://127.0.0.1:8554/son_user002 # <----- The stream you want to use for detection
input_args: preset-rtsp-restream
roles:
- detect
- audio
record:
enabled: true
retain:
days: 90 # Keep recordings for 7 days (adjust as needed)
mode: all # Options: motion | active_objects | all
detect:
enabled: true # <---- disable detection until you have a working camera feed
fps: 5
motion:
threshold: 80
contour_area: 100
improve_contrast: false
mask:
- 0,0,0.442,0,0.463,0.456,0.165,0.544,0,0.84
- 0.667,0,0.675,0.274,0.999,0.399,0.998,0
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 90
zones:
plate:
coordinates:
0.163,0.551,0.462,0.458,0.444,0.003,0.664,0,0.674,0.276,0.998,0.399,1,0.996,0,0.996,0.001,0.851
loitering_time: 0
birdseye:
order: 2
review:
detections:
required_zones: plate
alerts:
required_zones: plate
objects: {}
son_user003: # <------ Name the camera
enabled: true
ffmpeg:
output_args:
record: preset-record-generic-audio-aac
inputs:
- path: rtsp://127.0.0.1:8554/son_user003_record # <----- The stream you want to use for detection
input_args: preset-rtsp-restream
roles:
- record
- path: rtsp://127.0.0.1:8554/son_user003 # <----- The stream you want to use for detection
input_args: preset-rtsp-restream
roles:
- detect
- audio
record:
enabled: true
retain:
days: 90 # Keep recordings for 7 days (adjust as needed)
mode: all # Options: motion | active_objects | all
detect:
#enabled: false # <---- disable detection until you have a working camera feed
fps: 5
motion:
threshold: 30
contour_area: 10
improve_contrast: true
mask: 0.362,0.172,0.359,0.421,0.457,0.421,0.459,0.222
snapshots:
enabled: true
timestamp: true
bounding_box: true
retain:
default: 30
zones:
person_zone:
coordinates:
0.467,0.087,0.606,0.078,0.613,0.332,0.89,0.109,1,0.106,0.999,0.997,0.001,0.999,0.005,0.047,0.23,0.117,0.337,0.599,0.457,0.421
loitering_time: 0
objects: person
inertia: 3
birdseye:
order: 3
review:
alerts:
required_zones: person_zone
detections:
required_zones: person_zone
objects:
mask: 0.472,0.542,0.48,0.013,0.541,0.013,0.524,0.52
record:
enabled: true
export:
timelapse_args: -vf setpts=PTS/60 -r 25
sync_recordings: true
retain:
days: 90
mode: all
alerts:
retain:
days: 90
mode: motion
detections:
retain:
days: 90
mode: motion
detectors:
coral:
type: edgetpu
device: usb
objects:
track:
- person
- cat
- dog
audio:
enabled: false
listen:
- bark
- fire_alarm
- scream
- speech
- yell
- dog
- footsteps
- laughter
- pets
- cat
- meow
- electric_piano
- piano
- telephone
- television
birdseye:
enabled: true
width: 1280
height: 720
mode: continuous
inactivity_threshold: 15
layout:
max_cameras: 6
scaling_factor: 1.0
ffmpeg:
hwaccel_args: preset-vaapi
output_args:
record: preset-record-generic-audio-aac
version: 0.16-0
camera_groups:
SonA1:
order: 1
icon: LuFingerprint
cameras:
- son_user001
- son_user002
- son_user003
- son_user004
- son_user005
- son_user006
Bird:
order: 2
icon: LuBird
cameras: birdseye
semantic_search:
enabled: true
reindex: false
model_size: large
detect:
enabled: true
face_recognition:
enabled: true
model_size: large
lpr:
enabled: true
classification:
bird:
enabled: true
Firewall and Allow Ports for Dahua Cam:
When you first init setup your dahua cam, don't use pi hole dns, use 1.1.1.1 dns instead.
1.device that integrates only the P2P function.
To use UDP hole punch technology for remote access, the firewall output of the device must allow the following ports:
● UDP ports: 0-65535
● TCP ports: 9116, 9118, 12366, 12367
● Dahua servers use dynamic IP addresses, their domain names and functions are:
Domain Name | Function |
easy4ipcloud.com | Device login and registration |
easy4ip.com | Device login and registration |
2.Device supporting P2P and Cloud Business
To use UDP hole punch technology for remote access and normal operation of video surveillance services, the firewall output of the device must allow the following ports:
● UDP ports: 0-65535
● TCP ports: 443, 9112, 9113, 9116, 9118, 10000, 12367, 15100, 15101, 15301, 15600, 15900, 16759
● Dahua servers use dynamic IP addresses, their domain names and functions are:
Domain Name | Function |
easy4ipcloud.com | Device login and registration |
easy4ip.com | Device login and registration |
dms.easy4ipcloud.com | Device login and registration |
paas-dms-edge-fk.easy4ipcloud.com | Device login and registration |
smartdeviceproxy-edge-fk.easy4ipcloud.com | Device login and registration |
devaccess.easyipcloud.com | Device login and registration |
dus.easy4ipcloud.com | Cloud upgrade of device firmware |
aktualisieren.easy4ip.com | Cloud upgrade of device firmware |
update.easyviewercloud.com | Cloud upgrade of device firmware |
vrs.easy4ipcloud.com | Upload device images and videos |
pps.easy4ipcloud.com | Upload device messages |
das.easy4ipcloud.com | Upload device messages |
das-fk.easy4ipcloud.com | Upload device messages |
devicelogserver-fk.easy4ipcloud.com | Uploading device log |
No Comments