frigate-top (1.2.0)
Installation
pip install --index-url frigate-topAbout this package
Real-time terminal dashboard for Frigate NVR/CCTV servers
frigate-top
htop for your Frigate NVR box — a real-time terminal dashboard for Frigate CCTV hosts
frigate-top is a real-time, interactive terminal dashboard for Frigate
NVR/CCTV hosts — htop for your Frigate box. It shows host-level metrics (CPU, memory, disk I/O,
network I/O + errors, NVIDIA GPU, CPU iowait, load) and Frigate-specific metrics (skipped frames,
detector inference time, detection FPS, camera FPS, online/offline cameras, estimated supported
cameras) across a grid of block-bar graphs (one GPU set per detected GPU). Each graph fills the full
width over the configured timeframe, carries a -span … now time axis, colours its fill and current
value green/amber/red by warn/crit thresholds, and marks the newest sample with a bright endpoint.
It is stdlib-only Python in a single file — no pip, no required dependencies, no build step.
The dashboard — SYSTEM / NETWORK / FRIGATE bands, live block-bar graphs, and a boxed header table.
What it does
- Draws a live, auto-refreshing dashboard grouped into SYSTEM / NETWORK / FRIGATE bands with colour-coded graph borders (blue = system, yellow = network, orange = Frigate).
- Shows a header table grouped into identity (hostname, uptime, OS, kernel), hardware (CPU, memory, GPU model + driver), Frigate (version, camera counts, supported-camera estimate, detector), and streams/storage (resolution, retention, interface, disk) — plus a status line of active warnings.
- Summarises tracked-object activity for the selected timeframe in the header (
Detections 1m 4 person 2 vehicle 1 animal 2 face 1 plate), pulled from/api/events— a fixed category breakdown (person / vehicle / animal / recognised face / recognised plate, plusother) so the structure is visible even at zero. The API is polled at most every few seconds and cached. - Collapsible sections — press
s/w/f/g/tto fold the System / Network / Frigate / GPU / Thermal groups; everything except Frigate starts collapsed so it fits smaller terminals. Handles live terminal resizing without dropping graphs. - Auto-fit (
--auto-fit) expands as many sections as fit the terminal, in a fixed priority order (Frigate → System → GPU → Thermal → Network), recomputed on resize; it yields to manual control the moment you toggle a section. - Detects multiple GPUs and draws a labelled
GPU0 / GPU1 …util/mem/temp set for each, in their own GPU band (shown only when a GPU is present). - Auto-detects thermal sensors (AMD
k10temp, Intelcoretemp/PCH, ARM, and super-I/O boards) and draws a THERMAL band with CPU temperature, system/board temperature, and one graph per active fan — read from/sys/class/hwmonwith no dependency, falling back tolm-sensorswhen needed. The first spinning fan is labelledCPU, the restSYS1 / SYS2 …; rename them with--fan-labels. Chassis-intrusion reporting is opt-in via--chassis-intrusion(many boards latch a spurious alarm). - Graphs Frigate skipped frames and NET errors in red on any nonzero value — these should always be zero, so they catch the eye immediately.
- Renders block-bar graphs by default (
--braillefor dense Braille area charts,--asciifor plain ASCII). Fills always span the full width and scroll left over the true timeframe; the x-axis reports how much history is currently shown. - Encodes health in colour: bars and the title value turn amber past the warn threshold and red past crit, with a dashed guide line at each threshold and a
▲/▼/→trend arrow versus the window start. - Marks absent sensors (no GPU, no Frigate) with a dimmed
no sensorpanel instead of a misleading flat line. - Estimates how many cameras the detector(s) can keep up with — a throughput bound (
detector inferences/sec × headroom ÷ configured detect fps), which is the real limit on a Frigate box. It is motion-independent (uses the configured detect fps, not the noisy live rate); a single Coral at 5 fps works out to ~18 cameras. Tune the safety margin with--detector-headroom(default0.75). - Auto-detects the Frigate API at common ports (
5000,8971,80,443) and protocols (HTTP/HTTPS) (override with--frigate-url); tracks disk and the busiest network interface (pin with--disk/--net-iface). - Lets you switch history timeframe on the fly (
1,5,pfor 15m,cfor custom) and export samples to CSV (--csv). - Graphs the things an NVR actually cares about: Disk usage % and Frigate Recordings % (a filling disk is the classic failure), NVMe drive temperatures, GPU encoder/decoder utilization (Frigate's ffmpeg hwaccel), Frigate's own CPU/memory footprint, and host Swap %.
- Per-box settings file — an INI config (
--settings,$FRIGATE_TOP_CONFIG,~/.config/frigate-top/config.ini,/etc/frigate-top/config.ini) with precedence CLI › env › file › default;--write-configprints a commented starter. Every threshold, fan label, and toggle lives here. - Health-check mode (
--check) samples once and exits non-zero on any critical condition — drop it in cron / systemd / Uptime-Kuma.--fahrenheitshows °F. - Aggregates all network interfaces by default (pin one with
--net-iface); the NETWORK header shows which.
Install
frigate-top is stdlib-only, so the simplest install is a single self-contained file — a
zipapp bundle you drop on PATH: no pip, no
dependencies, and it sidesteps the externally-managed-environment (PEP 668) error on modern
Debian/Ubuntu entirely.
Single file — recommended (no pip, no dependencies):
# fetch the zipapp bundle from the latest release and drop it on PATH
sudo curl -fsSL https://git.jdneer.com/jd/frigate-top/releases/download/v1.2.0/frigate-top.pyz \
-o /usr/local/bin/frigate-top
sudo chmod +x /usr/local/bin/frigate-top
frigate-top
It's one file with a #!/usr/bin/env python3 shebang — Python 3.7+ and the standard library only,
no install step. (Optional: apt install python3-yaml for richer Frigate config parsing — a regex
fallback is used without it.) From a clone you can build the same file with
python3 scripts/build_pyz.py (→ dist/frigate-top.pyz).
As a managed command with pipx (isolated venv, PEP 668-friendly):
sudo apt install pipx # if not already present
PIP_INDEX_URL=https://git.jdneer.com/api/packages/jd/pypi/simple/ pipx install frigate-top
From the Forgejo package registry with pip:
pip install --index-url https://git.jdneer.com/api/packages/jd/pypi/simple/ frigate-top
# optional extra for richer YAML config parsing:
pip install --index-url https://git.jdneer.com/api/packages/jd/pypi/simple/ 'frigate-top[yaml]'
On a PEP 668 system (recent Debian/Ubuntu),
pipwon't touch the system Python — use the single file orpipxabove, install into apython3 -m venvfirst, or append--break-system-packagesif you accept the consequences.
From source:
git clone https://git.jdneer.com/jd/frigate-top.git
cd frigate-top
pip install . # or: pip install '.[yaml]'
Usage
Run frigate-top (installed or the .pyz on PATH) or python3 -m frigate_top (from a source checkout).
Controls (keyboard):
m— toggle memory graph between percentage and bytes (used / cached / free)n— toggle network graphs between Mbps and MB/ss/w/f/g/t— collapse or expand the System / Network / Frigate / GPU / Thermal sections (only Frigate starts expanded)1/5/p— set history to 1 / 5 / 15 minutesc— set a custom history timeframe (in minutes)q— quit
Examples:
# Default 1-minute history, 1-second refresh
frigate-top
# 10-minute history
frigate-top --timeframe 10
# Point to a Frigate API and config
frigate-top --frigate-url http://localhost:5000 --config /config/config.yml
# Pin a specific network interface / disk device
frigate-top --net-iface eth0 --disk nvme0n1
# Write samples to CSV
frigate-top --csv /tmp/frigate-top.csv
# Dense Braille area charts, or plain ASCII with no colour
frigate-top --braille
frigate-top --ascii --no-color
# One-off snapshot for cron or health checks (works headless)
frigate-top --snapshot
# Thermal: name the fans to match the case and enable intrusion reporting
frigate-top --fan-labels "CPU,Rear,Top" --chassis-intrusion
# Generate a starter settings file, then edit it
mkdir -p ~/.config/frigate-top
frigate-top --write-config > ~/.config/frigate-top/config.ini
# Health check for cron / systemd / Uptime-Kuma (exit code != 0 on any CRIT)
frigate-top --check
# Fahrenheit, and pin one interface instead of the aggregate
frigate-top --fahrenheit --net-iface eth0
Per-host launcher (shell alias)
Thermal auto-detection is generic, but fan positions and sensor quirks are
board-specific. Bake the host's specifics into a shell alias so ft always
launches a tuned view. Add this to ~/.bashrc (Bash) or ~/.zshrc (Zsh) —
the syntax is identical:
# ~/.bashrc or ~/.zshrc — "frigate top, this box"
alias ft='frigate-top \
--frigate-url http://localhost:5000 \
--fan-labels "CPU,Rear Exhaust,Top,GPU" \
--chassis-intrusion \
--net-iface enp42s0 --disk sda \
--cpu-temp-warn 90 --sys-temp-warn 70 \
--timeframe 5'
Then just run ft. The --fan-labels list maps in detection order (first
spinning fan first), so the graph titles become CPU fan RPM,
Rear Exhaust fan RPM, and so on. Everything is also settable via environment
variables (see below), which is often cleaner for a systemd unit or a container:
export FAN_LABELS="CPU,Rear Exhaust,Top,GPU"
export CHASSIS_INTRUSION=1
export CPU_TEMP_WARN=90 SYS_TEMP_WARN=70
frigate-top
Requirements
- Python 3.7+ (Linux — reads
/procand/sys) - No required dependencies.
frigate-topruns on the standard library alone. - Optional, detected at runtime:
- PyYAML (
frigate-top[yaml]) — richer Frigate config parsing; a minimal regex fallback is used without it nvidia-smi— NVIDIA GPU statsdockerorpodman— Frigate container status- A reachable Frigate API — camera/detector stats and the detections summary
lm-sensors(sensors) — only a fallback for the Thermal band;/sys/class/hwmonis read first and covers most boxes without it
- PyYAML (
Configuration
Every option can be set three ways, in order of precedence: command-line flag › environment variable › settings file › built-in default.
Settings file
For per-box configuration, use an INI settings file instead of a long alias. Generate a commented starter with frigate-top --write-config, then save it to one of (first found wins): the path given to --settings, $FRIGATE_TOP_CONFIG, ~/.config/frigate-top/config.ini, or /etc/frigate-top/config.ini.
[frigate-top]
frigate_url = http://localhost:5000
fan_labels = CPU, Rear Exhaust, Top
fan_max_rpm = 4000, 2000, 2000
chassis_intrusion = true
auto_fit = true
fahrenheit = false
cpu_temp_crit = 90
disk_full_crit = 90
Keys are the lowercased environment-variable names from the table below. A CLI flag or env var still overrides the file, so the same file works across hosts with per-host tweaks layered on top.
Environment variables
| Variable | Default | Description |
|---|---|---|
TIMEFRAME |
1 |
Graph history in minutes |
REFRESH |
1.0 |
Refresh interval in seconds |
MAX_TIMEFRAME |
60 |
Maximum allowed history in minutes |
FRIGATE_CONFIG |
"" |
Path to Frigate config.yml |
FRIGATE_URL |
"" |
Frigate API URL, e.g. http://localhost:5000 |
INSECURE |
0 |
Set to 1 to skip TLS verification for a remote HTTPS Frigate (loopback always allowed) |
NET_IFACE |
"" |
Network interface to monitor (auto-detected if empty) |
DISK_DEVICE |
"" |
Disk device to monitor, e.g. sda / nvme0n1 (auto-detected if empty) |
CSV_FILE |
"" |
Append samples to CSV |
ASCII |
0 |
Set to 1 for ASCII graph characters |
BRAILLE |
0 |
Set to 1 for dense Braille area charts instead of block bars |
NO_COLOR |
0 |
Set to 1 to disable colors |
AUTO_FIT |
0 |
Set to 1 to expand as many sections as fit the terminal (priority: frigate, system, gpu, thermal, network) |
FRIGATE_TOP_CONFIG |
"" |
Path to an INI settings file (see above) |
FAHRENHEIT |
0 |
Set to 1 to display temperatures in °F |
NO_THERMAL |
0 |
Set to 1 to disable thermal detection and the THERMAL section |
FAN_MAX_RPM |
"" |
Fixed fan-graph max RPM: one value for all, or comma-separated per fan (blank = auto-scale) |
LOAD_WARN |
0 |
Load-average warning threshold (0 = off) |
CPU_TEMP_CRIT |
95 |
CPU temperature critical °C |
SYS_TEMP_CRIT |
95 |
System/board temperature critical °C |
NVME_TEMP_WARN |
70 |
NVMe temperature warning °C |
NVME_TEMP_CRIT |
85 |
NVMe temperature critical °C |
DISK_FULL_WARN |
80 |
Storage full warning threshold |
CPU_WARN |
80 |
CPU warning threshold |
CPU_CRIT |
95 |
CPU critical threshold |
MEM_WARN |
80 |
Memory warning threshold |
MEM_CRIT |
95 |
Memory critical threshold |
GPU_WARN |
80 |
GPU utilization warning threshold |
GPU_CRIT |
95 |
GPU utilization critical threshold |
GPU_TEMP_WARN |
80 |
GPU temperature warning °C |
CPU_TEMP_WARN |
85 |
CPU temperature warning °C (Thermal band) |
SYS_TEMP_WARN |
85 |
System/board temperature warning °C (Thermal band) |
CHASSIS_INTRUSION |
0 |
Set to 1 to enable chassis-intrusion detection (off by default) |
FAN_LABELS |
"" |
Comma-separated fan names applied in detection order, e.g. CPU,Rear,Top |
DISK_IOWAIT_WARN |
20 |
I/O wait warning threshold |
DISK_FULL_CRIT |
85 |
Storage full critical threshold |
NET_WARN |
1000 |
Network throughput warning Mbps |
FRIGATE_SKIPPED_WARN |
1.0 |
Skipped FPS warning threshold |
FRIGATE_INFERENCE_WARN |
100 |
Detector inference time warning ms |
DETECTOR_HEADROOM |
0.75 |
Fraction of detector throughput used to size the supported-cameras estimate |
Files
| File | Description |
|---|---|
frigate_top/ |
The dashboard — a stdlib-only package (sampler, graphs, tui, cli, …) |
scripts/build_pyz.py |
Bundles the package into the single-file frigate-top.pyz |
pyproject.toml |
Package metadata (version read from __version__) |
requirements.in / requirements.txt |
Optional pinned + hash-verified PyYAML (see below) |
VERSION.md / CHANGELOG.md |
Versioning and release notes |
LICENSE / NOTICE / DISCLAIMER.md |
Apache-2.0 licence and terms |
Optional supply-chain hardening
PyYAML is optional. If you want it hash-verified, requirements.txt pins it with SHA-256 hashes:
pip install --require-hashes -r requirements.txt
Regenerate after changing requirements.in:
pip install pip-tools && pip-compile --generate-hashes requirements.in -o requirements.txt
Versioning
frigate-top follows Semantic Versioning. The version lives once in
frigate_top/_version.py as __version__ and flows to the header title and the built package — see
VERSION.md for the release process and CHANGELOG.md for history.
Notes
- If the terminal is too small or not a TTY, use
--snapshotfor a one-off reading. - The first sample is used as a baseline and is not shown in the graphs, so deltas are meaningful.
- Frigate config auto-detection tries
/config/config.yml,/config/config.yaml,/etc/frigate/config.yml,/opt/frigate/config/config.yml, and~/frigate/config/config.yml. - MQTT broker monitoring is intentionally not included because the broker is optional and containerized; the Frigate API provides the same health signals.
- Security posture: the tool is read-only — it shells out only to fixed commands (
nvidia-smi,docker/podman ps,df) with no shell or user-interpolated arguments, parses YAML withsafe_load, and writes its optional--debuglog to a per-user directory ($XDG_RUNTIME_DIR) opened withO_NOFOLLOW. TLS certificates are verified for remote HTTPS Frigate instances; verification is relaxed only for loopback hosts (where self-signed certs are the norm) or when--insecureis passed.
License
Licensed under the Apache License 2.0. See NOTICE for attribution and DISCLAIMER.md for terms regarding use, third-party trademarks, warranty, and liability.
frigate-top is an independent project and is not affiliated with or endorsed by the Frigate NVR project, NVIDIA, Google, or Docker.