2024-10-14 04:36:49 +03:00
|
|
|
import { useEmbeddingsReindexProgress } from "@/api/ws";
|
2024-04-22 17:20:23 +03:00
|
|
|
import {
|
|
|
|
|
StatusBarMessagesContext,
|
|
|
|
|
StatusMessage,
|
|
|
|
|
} from "@/context/statusbar-provider";
|
2024-05-27 00:49:12 +03:00
|
|
|
import useStats, { useAutoFrigateStats } from "@/hooks/use-stats";
|
Camera profile support (#22482)
* add CameraProfileConfig model for named config overrides
* add profiles field to CameraConfig
* add active_profile field to FrigateConfig
Runtime-only field excluded from YAML serialization, tracks which
profile is currently active.
* add ProfileManager for profile activation and persistence
Handles snapshotting base configs, applying profile overrides via
deep_merge + apply_section_update, publishing ZMQ updates, and
persisting active profile to /config/.active_profile.
* add profile API endpoints (GET /profiles, GET/PUT /profile)
* add MQTT and dispatcher integration for profiles
- Subscribe to frigate/profile/set MQTT topic
- Publish profile/state and profiles/available on connect
- Add _on_profile_command handler to dispatcher
- Broadcast active profile state on WebSocket connect
* wire ProfileManager into app startup and FastAPI
- Create ProfileManager after dispatcher init
- Restore persisted profile on startup
- Pass dispatcher and profile_manager to FastAPI app
* add tests for invalid profile values and keys
Tests that Pydantic rejects: invalid field values (fps: "not_a_number"),
unknown section keys (ffmpeg in profile), invalid nested values, and
invalid profiles in full config parsing.
* formatting
* fix CameraLiveConfig JSON serialization error on profile activation
refactor _publish_updates to only publish ZMQ updates for
sections that actually changed, not all sections on affected cameras.
* consolidate
* add enabled field to camera profiles for enabling/disabling cameras
* add zones support to camera profiles
* add frontend profile types, color utility, and config save support
* add profile state management and save preview support
* add profileName prop to BaseSection for profile-aware config editing
* add profile section dropdown and wire into camera settings pages
* add per-profile camera enable/disable to Camera Management view
* add profiles summary page with card-based layout and fix backend zone comparison bug
* add active profile badge to settings toolbar
* i18n
* add red dot for any pending changes including profiles
* profile support for mask and zone editor
* fix hidden field validation errors caused by lodash wildcard and schema gaps
lodash unset does not support wildcard (*) segments, so hidden fields like
filters.*.mask were never stripped from form data, leaving null raw_coordinates
that fail RJSF anyOf validation. Add unsetWithWildcard helper and also strip
hidden fields from the JSON schema itself as defense-in-depth.
* add face_recognition and lpr to profile-eligible sections
* move profile dropdown from section panes to settings header
* add profiles enable toggle and improve empty state
* formatting
* tweaks
* tweak colors and switch
* fix profile save diff, masksAndZones delete, and config sync
* ui tweaks
* ensure profile manager gets updated config
* rename profile settings to ui settings
* refactor profilesview and add dots/border colors when overridden
* implement an update_config method for profile manager
* fix mask deletion
* more unique colors
* add top-level profiles config section with friendly names
* implement profile friendly names and improve profile UI
- Add ProfileDefinitionConfig type and profiles field to FrigateConfig
- Use ProfilesApiResponse type with friendly_name support throughout
- Replace Record<string, unknown> with proper JsonObject/JsonValue types
- Add profile creation form matching zone pattern (Zod + NameAndIdFields)
- Add pencil icon for renaming profile friendly names in ProfilesView
- Move Profiles menu item to first under Camera Configuration
- Add activity indicators on save/rename/delete buttons
- Display friendly names in CameraManagementView profile selector
- Fix duplicate colored dots in management profile dropdown
- Fix i18n namespace for overridden base config tooltips
- Move profile override deletion from dropdown trash icon to footer
button with confirmation dialog, matching Reset to Global pattern
- Remove Add Profile from section header dropdown to prevent saving
camera overrides before top-level profile definition exists
- Clean up newProfiles state after API profile deletion
- Refresh profiles SWR cache after saving profile definitions
* remove profile badge in settings and add profiles to main menu
* use icon only on mobile
* change color order
* docs
* show activity indicator on trash icon while deleting a profile
* tweak language
* immediately create profiles on backend instead of deferring to Save All
* hide restart-required fields when editing a profile section
fields that require a restart cannot take effect via profile switching,
so they are merged into hiddenFields when profileName is set
* show active profile indicator in desktop status bar
* fix profile config inheritance bug where Pydantic defaults override base values
The /config API was dumping profile overrides with model_dump() which included
all Pydantic defaults. When the frontend merged these over
the camera's base config, explicitly-set base values were
lost. Now profile overrides are re-dumped with exclude_unset=True so only
user-specified fields are returned.
Also fixes the Save All path generating spurious deletion markers for
restart-required fields that are hidden during profile
editing but not excluded from the raw data sanitization in
prepareSectionSavePayload.
* docs tweaks
* docs tweak
* formatting
* formatting
* fix typing
* fix test pollution
test_maintainer was injecting MagicMock() into sys.modules["frigate.config.camera.updater"] at module load time and never restoring it. When the profile tests later imported CameraConfigUpdateEnum and CameraConfigUpdateTopic from that module, they got mock objects instead of the real dataclass/enum, so equality comparisons always failed
* remove
* fix settings showing profile-merged values when editing base config
When a profile is active, the in-memory config contains effective
(profile-merged) values. The settings UI was displaying these merged
values even when the "Base Config" view was selected.
Backend: snapshot pre-profile base configs in ProfileManager and expose
them via a `base_config` key in the /api/config camera response when a
profile is active. The top-level sections continue to reflect the
effective running config.
Frontend: read from `base_config` when available in BaseSection,
useConfigOverride, useAllCameraOverrides, and prepareSectionSavePayload.
Include formData labels in Object/Audio switches widgets so that labels
added only by a profile override remain visible when editing that profile.
* use rasterized_mask as field
makes it easier to exclude from the schema with exclude=True
prevents leaking of the field when using model_dump for profiles
* fix zones
- Fix zone colors not matching across profiles by falling back to base zone color when profile zone data lacks a color field
- Use base_config for base-layer values in masks/zones view so profile-merged values don't pollute the base config editing view
- Handle zones separately in profile manager snapshot/restore since ZoneConfig requires special serialization (color as private attr, contour generation)
- Inherit base zone color and generate contours for profile zone overrides in profile manager
* formatting
* don't require restart for camera enabled change for profiles
* publish camera state when changing profiles
* formatting
* remove available profiles from mqtt
* improve typing
2026-03-19 17:47:57 +03:00
|
|
|
import { cn } from "@/lib/utils";
|
|
|
|
|
import type { ProfilesApiResponse } from "@/types/profile";
|
|
|
|
|
import { getProfileColor } from "@/utils/profileColors";
|
2024-04-22 17:20:23 +03:00
|
|
|
import { useContext, useEffect, useMemo } from "react";
|
2025-03-16 18:36:20 +03:00
|
|
|
import { useTranslation } from "react-i18next";
|
Camera profile support (#22482)
* add CameraProfileConfig model for named config overrides
* add profiles field to CameraConfig
* add active_profile field to FrigateConfig
Runtime-only field excluded from YAML serialization, tracks which
profile is currently active.
* add ProfileManager for profile activation and persistence
Handles snapshotting base configs, applying profile overrides via
deep_merge + apply_section_update, publishing ZMQ updates, and
persisting active profile to /config/.active_profile.
* add profile API endpoints (GET /profiles, GET/PUT /profile)
* add MQTT and dispatcher integration for profiles
- Subscribe to frigate/profile/set MQTT topic
- Publish profile/state and profiles/available on connect
- Add _on_profile_command handler to dispatcher
- Broadcast active profile state on WebSocket connect
* wire ProfileManager into app startup and FastAPI
- Create ProfileManager after dispatcher init
- Restore persisted profile on startup
- Pass dispatcher and profile_manager to FastAPI app
* add tests for invalid profile values and keys
Tests that Pydantic rejects: invalid field values (fps: "not_a_number"),
unknown section keys (ffmpeg in profile), invalid nested values, and
invalid profiles in full config parsing.
* formatting
* fix CameraLiveConfig JSON serialization error on profile activation
refactor _publish_updates to only publish ZMQ updates for
sections that actually changed, not all sections on affected cameras.
* consolidate
* add enabled field to camera profiles for enabling/disabling cameras
* add zones support to camera profiles
* add frontend profile types, color utility, and config save support
* add profile state management and save preview support
* add profileName prop to BaseSection for profile-aware config editing
* add profile section dropdown and wire into camera settings pages
* add per-profile camera enable/disable to Camera Management view
* add profiles summary page with card-based layout and fix backend zone comparison bug
* add active profile badge to settings toolbar
* i18n
* add red dot for any pending changes including profiles
* profile support for mask and zone editor
* fix hidden field validation errors caused by lodash wildcard and schema gaps
lodash unset does not support wildcard (*) segments, so hidden fields like
filters.*.mask were never stripped from form data, leaving null raw_coordinates
that fail RJSF anyOf validation. Add unsetWithWildcard helper and also strip
hidden fields from the JSON schema itself as defense-in-depth.
* add face_recognition and lpr to profile-eligible sections
* move profile dropdown from section panes to settings header
* add profiles enable toggle and improve empty state
* formatting
* tweaks
* tweak colors and switch
* fix profile save diff, masksAndZones delete, and config sync
* ui tweaks
* ensure profile manager gets updated config
* rename profile settings to ui settings
* refactor profilesview and add dots/border colors when overridden
* implement an update_config method for profile manager
* fix mask deletion
* more unique colors
* add top-level profiles config section with friendly names
* implement profile friendly names and improve profile UI
- Add ProfileDefinitionConfig type and profiles field to FrigateConfig
- Use ProfilesApiResponse type with friendly_name support throughout
- Replace Record<string, unknown> with proper JsonObject/JsonValue types
- Add profile creation form matching zone pattern (Zod + NameAndIdFields)
- Add pencil icon for renaming profile friendly names in ProfilesView
- Move Profiles menu item to first under Camera Configuration
- Add activity indicators on save/rename/delete buttons
- Display friendly names in CameraManagementView profile selector
- Fix duplicate colored dots in management profile dropdown
- Fix i18n namespace for overridden base config tooltips
- Move profile override deletion from dropdown trash icon to footer
button with confirmation dialog, matching Reset to Global pattern
- Remove Add Profile from section header dropdown to prevent saving
camera overrides before top-level profile definition exists
- Clean up newProfiles state after API profile deletion
- Refresh profiles SWR cache after saving profile definitions
* remove profile badge in settings and add profiles to main menu
* use icon only on mobile
* change color order
* docs
* show activity indicator on trash icon while deleting a profile
* tweak language
* immediately create profiles on backend instead of deferring to Save All
* hide restart-required fields when editing a profile section
fields that require a restart cannot take effect via profile switching,
so they are merged into hiddenFields when profileName is set
* show active profile indicator in desktop status bar
* fix profile config inheritance bug where Pydantic defaults override base values
The /config API was dumping profile overrides with model_dump() which included
all Pydantic defaults. When the frontend merged these over
the camera's base config, explicitly-set base values were
lost. Now profile overrides are re-dumped with exclude_unset=True so only
user-specified fields are returned.
Also fixes the Save All path generating spurious deletion markers for
restart-required fields that are hidden during profile
editing but not excluded from the raw data sanitization in
prepareSectionSavePayload.
* docs tweaks
* docs tweak
* formatting
* formatting
* fix typing
* fix test pollution
test_maintainer was injecting MagicMock() into sys.modules["frigate.config.camera.updater"] at module load time and never restoring it. When the profile tests later imported CameraConfigUpdateEnum and CameraConfigUpdateTopic from that module, they got mock objects instead of the real dataclass/enum, so equality comparisons always failed
* remove
* fix settings showing profile-merged values when editing base config
When a profile is active, the in-memory config contains effective
(profile-merged) values. The settings UI was displaying these merged
values even when the "Base Config" view was selected.
Backend: snapshot pre-profile base configs in ProfileManager and expose
them via a `base_config` key in the /api/config camera response when a
profile is active. The top-level sections continue to reflect the
effective running config.
Frontend: read from `base_config` when available in BaseSection,
useConfigOverride, useAllCameraOverrides, and prepareSectionSavePayload.
Include formData labels in Object/Audio switches widgets so that labels
added only by a profile override remain visible when editing that profile.
* use rasterized_mask as field
makes it easier to exclude from the schema with exclude=True
prevents leaking of the field when using model_dump for profiles
* fix zones
- Fix zone colors not matching across profiles by falling back to base zone color when profile zone data lacks a color field
- Use base_config for base-layer values in masks/zones view so profile-merged values don't pollute the base config editing view
- Handle zones separately in profile manager snapshot/restore since ZoneConfig requires special serialization (color as private attr, contour generation)
- Inherit base zone color and generate contours for profile zone overrides in profile manager
* formatting
* don't require restart for camera enabled change for profiles
* publish camera state when changing profiles
* formatting
* remove available profiles from mqtt
* improve typing
2026-03-19 17:47:57 +03:00
|
|
|
import useSWR from "swr";
|
2025-03-16 18:36:20 +03:00
|
|
|
|
2024-04-22 17:20:23 +03:00
|
|
|
import { FaCheck } from "react-icons/fa";
|
2024-03-30 21:45:13 +03:00
|
|
|
import { IoIosWarning } from "react-icons/io";
|
2024-02-22 05:27:02 +03:00
|
|
|
import { MdCircle } from "react-icons/md";
|
2024-04-29 01:59:03 +03:00
|
|
|
import { Link } from "react-router-dom";
|
2024-02-22 05:27:02 +03:00
|
|
|
|
2024-02-29 01:23:56 +03:00
|
|
|
export default function Statusbar() {
|
2025-03-16 18:36:20 +03:00
|
|
|
const { t } = useTranslation(["views/system"]);
|
|
|
|
|
|
2024-04-22 17:20:23 +03:00
|
|
|
const { messages, addMessage, clearMessages } = useContext(
|
|
|
|
|
StatusBarMessagesContext,
|
|
|
|
|
)!;
|
|
|
|
|
|
2024-05-27 00:49:12 +03:00
|
|
|
const stats = useAutoFrigateStats();
|
2024-02-22 05:27:02 +03:00
|
|
|
|
|
|
|
|
const cpuPercent = useMemo(() => {
|
|
|
|
|
const systemCpu = stats?.cpu_usages["frigate.full_system"]?.cpu;
|
|
|
|
|
|
|
|
|
|
if (!systemCpu || systemCpu == "0.0") {
|
|
|
|
|
return null;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
return parseInt(systemCpu);
|
|
|
|
|
}, [stats]);
|
|
|
|
|
|
2024-03-30 21:45:13 +03:00
|
|
|
const { potentialProblems } = useStats(stats);
|
2024-02-22 05:27:02 +03:00
|
|
|
|
2024-04-22 17:20:23 +03:00
|
|
|
useEffect(() => {
|
|
|
|
|
clearMessages("stats");
|
|
|
|
|
potentialProblems.forEach((problem) => {
|
2024-04-29 01:59:03 +03:00
|
|
|
addMessage(
|
|
|
|
|
"stats",
|
|
|
|
|
problem.text,
|
|
|
|
|
problem.color,
|
|
|
|
|
undefined,
|
|
|
|
|
problem.relevantLink,
|
|
|
|
|
);
|
2024-04-22 17:20:23 +03:00
|
|
|
});
|
|
|
|
|
}, [potentialProblems, addMessage, clearMessages]);
|
|
|
|
|
|
Camera profile support (#22482)
* add CameraProfileConfig model for named config overrides
* add profiles field to CameraConfig
* add active_profile field to FrigateConfig
Runtime-only field excluded from YAML serialization, tracks which
profile is currently active.
* add ProfileManager for profile activation and persistence
Handles snapshotting base configs, applying profile overrides via
deep_merge + apply_section_update, publishing ZMQ updates, and
persisting active profile to /config/.active_profile.
* add profile API endpoints (GET /profiles, GET/PUT /profile)
* add MQTT and dispatcher integration for profiles
- Subscribe to frigate/profile/set MQTT topic
- Publish profile/state and profiles/available on connect
- Add _on_profile_command handler to dispatcher
- Broadcast active profile state on WebSocket connect
* wire ProfileManager into app startup and FastAPI
- Create ProfileManager after dispatcher init
- Restore persisted profile on startup
- Pass dispatcher and profile_manager to FastAPI app
* add tests for invalid profile values and keys
Tests that Pydantic rejects: invalid field values (fps: "not_a_number"),
unknown section keys (ffmpeg in profile), invalid nested values, and
invalid profiles in full config parsing.
* formatting
* fix CameraLiveConfig JSON serialization error on profile activation
refactor _publish_updates to only publish ZMQ updates for
sections that actually changed, not all sections on affected cameras.
* consolidate
* add enabled field to camera profiles for enabling/disabling cameras
* add zones support to camera profiles
* add frontend profile types, color utility, and config save support
* add profile state management and save preview support
* add profileName prop to BaseSection for profile-aware config editing
* add profile section dropdown and wire into camera settings pages
* add per-profile camera enable/disable to Camera Management view
* add profiles summary page with card-based layout and fix backend zone comparison bug
* add active profile badge to settings toolbar
* i18n
* add red dot for any pending changes including profiles
* profile support for mask and zone editor
* fix hidden field validation errors caused by lodash wildcard and schema gaps
lodash unset does not support wildcard (*) segments, so hidden fields like
filters.*.mask were never stripped from form data, leaving null raw_coordinates
that fail RJSF anyOf validation. Add unsetWithWildcard helper and also strip
hidden fields from the JSON schema itself as defense-in-depth.
* add face_recognition and lpr to profile-eligible sections
* move profile dropdown from section panes to settings header
* add profiles enable toggle and improve empty state
* formatting
* tweaks
* tweak colors and switch
* fix profile save diff, masksAndZones delete, and config sync
* ui tweaks
* ensure profile manager gets updated config
* rename profile settings to ui settings
* refactor profilesview and add dots/border colors when overridden
* implement an update_config method for profile manager
* fix mask deletion
* more unique colors
* add top-level profiles config section with friendly names
* implement profile friendly names and improve profile UI
- Add ProfileDefinitionConfig type and profiles field to FrigateConfig
- Use ProfilesApiResponse type with friendly_name support throughout
- Replace Record<string, unknown> with proper JsonObject/JsonValue types
- Add profile creation form matching zone pattern (Zod + NameAndIdFields)
- Add pencil icon for renaming profile friendly names in ProfilesView
- Move Profiles menu item to first under Camera Configuration
- Add activity indicators on save/rename/delete buttons
- Display friendly names in CameraManagementView profile selector
- Fix duplicate colored dots in management profile dropdown
- Fix i18n namespace for overridden base config tooltips
- Move profile override deletion from dropdown trash icon to footer
button with confirmation dialog, matching Reset to Global pattern
- Remove Add Profile from section header dropdown to prevent saving
camera overrides before top-level profile definition exists
- Clean up newProfiles state after API profile deletion
- Refresh profiles SWR cache after saving profile definitions
* remove profile badge in settings and add profiles to main menu
* use icon only on mobile
* change color order
* docs
* show activity indicator on trash icon while deleting a profile
* tweak language
* immediately create profiles on backend instead of deferring to Save All
* hide restart-required fields when editing a profile section
fields that require a restart cannot take effect via profile switching,
so they are merged into hiddenFields when profileName is set
* show active profile indicator in desktop status bar
* fix profile config inheritance bug where Pydantic defaults override base values
The /config API was dumping profile overrides with model_dump() which included
all Pydantic defaults. When the frontend merged these over
the camera's base config, explicitly-set base values were
lost. Now profile overrides are re-dumped with exclude_unset=True so only
user-specified fields are returned.
Also fixes the Save All path generating spurious deletion markers for
restart-required fields that are hidden during profile
editing but not excluded from the raw data sanitization in
prepareSectionSavePayload.
* docs tweaks
* docs tweak
* formatting
* formatting
* fix typing
* fix test pollution
test_maintainer was injecting MagicMock() into sys.modules["frigate.config.camera.updater"] at module load time and never restoring it. When the profile tests later imported CameraConfigUpdateEnum and CameraConfigUpdateTopic from that module, they got mock objects instead of the real dataclass/enum, so equality comparisons always failed
* remove
* fix settings showing profile-merged values when editing base config
When a profile is active, the in-memory config contains effective
(profile-merged) values. The settings UI was displaying these merged
values even when the "Base Config" view was selected.
Backend: snapshot pre-profile base configs in ProfileManager and expose
them via a `base_config` key in the /api/config camera response when a
profile is active. The top-level sections continue to reflect the
effective running config.
Frontend: read from `base_config` when available in BaseSection,
useConfigOverride, useAllCameraOverrides, and prepareSectionSavePayload.
Include formData labels in Object/Audio switches widgets so that labels
added only by a profile override remain visible when editing that profile.
* use rasterized_mask as field
makes it easier to exclude from the schema with exclude=True
prevents leaking of the field when using model_dump for profiles
* fix zones
- Fix zone colors not matching across profiles by falling back to base zone color when profile zone data lacks a color field
- Use base_config for base-layer values in masks/zones view so profile-merged values don't pollute the base config editing view
- Handle zones separately in profile manager snapshot/restore since ZoneConfig requires special serialization (color as private attr, contour generation)
- Inherit base zone color and generate contours for profile zone overrides in profile manager
* formatting
* don't require restart for camera enabled change for profiles
* publish camera state when changing profiles
* formatting
* remove available profiles from mqtt
* improve typing
2026-03-19 17:47:57 +03:00
|
|
|
const { data: profilesData } = useSWR<ProfilesApiResponse>("profiles");
|
|
|
|
|
|
|
|
|
|
const activeProfile = useMemo(() => {
|
|
|
|
|
if (!profilesData?.active_profile || !profilesData.profiles) return null;
|
|
|
|
|
const info = profilesData.profiles.find(
|
|
|
|
|
(p) => p.name === profilesData.active_profile,
|
|
|
|
|
);
|
|
|
|
|
const allNames = profilesData.profiles.map((p) => p.name).sort();
|
|
|
|
|
return {
|
|
|
|
|
name: profilesData.active_profile,
|
|
|
|
|
friendlyName: info?.friendly_name ?? profilesData.active_profile,
|
|
|
|
|
color: getProfileColor(profilesData.active_profile, allNames),
|
|
|
|
|
};
|
|
|
|
|
}, [profilesData]);
|
|
|
|
|
|
2024-10-14 04:36:49 +03:00
|
|
|
const { payload: reindexState } = useEmbeddingsReindexProgress();
|
|
|
|
|
|
|
|
|
|
useEffect(() => {
|
|
|
|
|
if (reindexState) {
|
|
|
|
|
if (reindexState.status == "indexing") {
|
|
|
|
|
clearMessages("embeddings-reindex");
|
|
|
|
|
addMessage(
|
|
|
|
|
"embeddings-reindex",
|
2025-03-16 18:36:20 +03:00
|
|
|
t("stats.reindexingEmbeddings", {
|
|
|
|
|
processed: Math.floor(
|
|
|
|
|
(reindexState.processed_objects / reindexState.total_objects) *
|
|
|
|
|
100,
|
|
|
|
|
),
|
|
|
|
|
}),
|
2024-10-14 04:36:49 +03:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
if (reindexState.status === "completed") {
|
|
|
|
|
clearMessages("embeddings-reindex");
|
|
|
|
|
}
|
|
|
|
|
}
|
2025-03-16 18:36:20 +03:00
|
|
|
}, [reindexState, addMessage, clearMessages, t]);
|
2024-10-14 04:36:49 +03:00
|
|
|
|
2024-03-30 21:45:13 +03:00
|
|
|
return (
|
2024-05-14 18:06:44 +03:00
|
|
|
<div className="absolute bottom-0 left-0 right-0 z-10 flex h-8 w-full items-center justify-between border-t border-secondary-highlight bg-background_alt px-4 dark:text-secondary-foreground">
|
|
|
|
|
<div className="flex h-full items-center gap-2">
|
2024-03-30 21:45:13 +03:00
|
|
|
{cpuPercent && (
|
2024-05-09 16:19:41 +03:00
|
|
|
<Link to="/system#general">
|
2024-05-14 18:06:44 +03:00
|
|
|
<div className="flex cursor-pointer items-center gap-2 text-sm hover:underline">
|
2024-05-09 16:19:41 +03:00
|
|
|
<MdCircle
|
|
|
|
|
className={`size-2 ${
|
|
|
|
|
cpuPercent < 50
|
|
|
|
|
? "text-success"
|
|
|
|
|
: cpuPercent < 80
|
|
|
|
|
? "text-orange-400"
|
|
|
|
|
: "text-danger"
|
|
|
|
|
}`}
|
|
|
|
|
/>
|
|
|
|
|
CPU {cpuPercent}%
|
|
|
|
|
</div>
|
|
|
|
|
</Link>
|
2024-03-30 21:45:13 +03:00
|
|
|
)}
|
|
|
|
|
{Object.entries(stats?.gpu_usages || {}).map(([name, stats]) => {
|
|
|
|
|
if (name == "error-gpu") {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
let gpuTitle;
|
|
|
|
|
switch (name) {
|
|
|
|
|
case "amd-vaapi":
|
|
|
|
|
gpuTitle = "AMD GPU";
|
|
|
|
|
break;
|
2026-03-29 20:09:02 +03:00
|
|
|
case "intel-gpu":
|
2024-03-30 21:45:13 +03:00
|
|
|
gpuTitle = "Intel GPU";
|
|
|
|
|
break;
|
2025-04-20 00:34:05 +03:00
|
|
|
case "rockchip":
|
|
|
|
|
gpuTitle = "Rockchip GPU";
|
|
|
|
|
break;
|
2024-03-30 21:45:13 +03:00
|
|
|
default:
|
|
|
|
|
gpuTitle = name;
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
const gpu = parseInt(stats.gpu);
|
|
|
|
|
|
2024-05-30 22:10:24 +03:00
|
|
|
if (isNaN(gpu)) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
|
|
|
|
|
2024-03-30 21:45:13 +03:00
|
|
|
return (
|
2025-12-15 02:41:38 +03:00
|
|
|
<Link key={name} to="/system#general">
|
2024-05-09 16:19:41 +03:00
|
|
|
{" "}
|
|
|
|
|
<div
|
2025-12-15 02:41:38 +03:00
|
|
|
key={name}
|
2024-05-14 18:06:44 +03:00
|
|
|
className="flex cursor-pointer items-center gap-2 text-sm hover:underline"
|
2024-05-09 16:19:41 +03:00
|
|
|
>
|
|
|
|
|
<MdCircle
|
|
|
|
|
className={`size-2 ${
|
|
|
|
|
gpu < 50
|
|
|
|
|
? "text-success"
|
|
|
|
|
: gpu < 80
|
|
|
|
|
? "text-orange-400"
|
|
|
|
|
: "text-danger"
|
|
|
|
|
}`}
|
|
|
|
|
/>
|
|
|
|
|
{gpuTitle} {gpu}%
|
|
|
|
|
</div>
|
|
|
|
|
</Link>
|
2024-03-30 21:45:13 +03:00
|
|
|
);
|
|
|
|
|
})}
|
Camera profile support (#22482)
* add CameraProfileConfig model for named config overrides
* add profiles field to CameraConfig
* add active_profile field to FrigateConfig
Runtime-only field excluded from YAML serialization, tracks which
profile is currently active.
* add ProfileManager for profile activation and persistence
Handles snapshotting base configs, applying profile overrides via
deep_merge + apply_section_update, publishing ZMQ updates, and
persisting active profile to /config/.active_profile.
* add profile API endpoints (GET /profiles, GET/PUT /profile)
* add MQTT and dispatcher integration for profiles
- Subscribe to frigate/profile/set MQTT topic
- Publish profile/state and profiles/available on connect
- Add _on_profile_command handler to dispatcher
- Broadcast active profile state on WebSocket connect
* wire ProfileManager into app startup and FastAPI
- Create ProfileManager after dispatcher init
- Restore persisted profile on startup
- Pass dispatcher and profile_manager to FastAPI app
* add tests for invalid profile values and keys
Tests that Pydantic rejects: invalid field values (fps: "not_a_number"),
unknown section keys (ffmpeg in profile), invalid nested values, and
invalid profiles in full config parsing.
* formatting
* fix CameraLiveConfig JSON serialization error on profile activation
refactor _publish_updates to only publish ZMQ updates for
sections that actually changed, not all sections on affected cameras.
* consolidate
* add enabled field to camera profiles for enabling/disabling cameras
* add zones support to camera profiles
* add frontend profile types, color utility, and config save support
* add profile state management and save preview support
* add profileName prop to BaseSection for profile-aware config editing
* add profile section dropdown and wire into camera settings pages
* add per-profile camera enable/disable to Camera Management view
* add profiles summary page with card-based layout and fix backend zone comparison bug
* add active profile badge to settings toolbar
* i18n
* add red dot for any pending changes including profiles
* profile support for mask and zone editor
* fix hidden field validation errors caused by lodash wildcard and schema gaps
lodash unset does not support wildcard (*) segments, so hidden fields like
filters.*.mask were never stripped from form data, leaving null raw_coordinates
that fail RJSF anyOf validation. Add unsetWithWildcard helper and also strip
hidden fields from the JSON schema itself as defense-in-depth.
* add face_recognition and lpr to profile-eligible sections
* move profile dropdown from section panes to settings header
* add profiles enable toggle and improve empty state
* formatting
* tweaks
* tweak colors and switch
* fix profile save diff, masksAndZones delete, and config sync
* ui tweaks
* ensure profile manager gets updated config
* rename profile settings to ui settings
* refactor profilesview and add dots/border colors when overridden
* implement an update_config method for profile manager
* fix mask deletion
* more unique colors
* add top-level profiles config section with friendly names
* implement profile friendly names and improve profile UI
- Add ProfileDefinitionConfig type and profiles field to FrigateConfig
- Use ProfilesApiResponse type with friendly_name support throughout
- Replace Record<string, unknown> with proper JsonObject/JsonValue types
- Add profile creation form matching zone pattern (Zod + NameAndIdFields)
- Add pencil icon for renaming profile friendly names in ProfilesView
- Move Profiles menu item to first under Camera Configuration
- Add activity indicators on save/rename/delete buttons
- Display friendly names in CameraManagementView profile selector
- Fix duplicate colored dots in management profile dropdown
- Fix i18n namespace for overridden base config tooltips
- Move profile override deletion from dropdown trash icon to footer
button with confirmation dialog, matching Reset to Global pattern
- Remove Add Profile from section header dropdown to prevent saving
camera overrides before top-level profile definition exists
- Clean up newProfiles state after API profile deletion
- Refresh profiles SWR cache after saving profile definitions
* remove profile badge in settings and add profiles to main menu
* use icon only on mobile
* change color order
* docs
* show activity indicator on trash icon while deleting a profile
* tweak language
* immediately create profiles on backend instead of deferring to Save All
* hide restart-required fields when editing a profile section
fields that require a restart cannot take effect via profile switching,
so they are merged into hiddenFields when profileName is set
* show active profile indicator in desktop status bar
* fix profile config inheritance bug where Pydantic defaults override base values
The /config API was dumping profile overrides with model_dump() which included
all Pydantic defaults. When the frontend merged these over
the camera's base config, explicitly-set base values were
lost. Now profile overrides are re-dumped with exclude_unset=True so only
user-specified fields are returned.
Also fixes the Save All path generating spurious deletion markers for
restart-required fields that are hidden during profile
editing but not excluded from the raw data sanitization in
prepareSectionSavePayload.
* docs tweaks
* docs tweak
* formatting
* formatting
* fix typing
* fix test pollution
test_maintainer was injecting MagicMock() into sys.modules["frigate.config.camera.updater"] at module load time and never restoring it. When the profile tests later imported CameraConfigUpdateEnum and CameraConfigUpdateTopic from that module, they got mock objects instead of the real dataclass/enum, so equality comparisons always failed
* remove
* fix settings showing profile-merged values when editing base config
When a profile is active, the in-memory config contains effective
(profile-merged) values. The settings UI was displaying these merged
values even when the "Base Config" view was selected.
Backend: snapshot pre-profile base configs in ProfileManager and expose
them via a `base_config` key in the /api/config camera response when a
profile is active. The top-level sections continue to reflect the
effective running config.
Frontend: read from `base_config` when available in BaseSection,
useConfigOverride, useAllCameraOverrides, and prepareSectionSavePayload.
Include formData labels in Object/Audio switches widgets so that labels
added only by a profile override remain visible when editing that profile.
* use rasterized_mask as field
makes it easier to exclude from the schema with exclude=True
prevents leaking of the field when using model_dump for profiles
* fix zones
- Fix zone colors not matching across profiles by falling back to base zone color when profile zone data lacks a color field
- Use base_config for base-layer values in masks/zones view so profile-merged values don't pollute the base config editing view
- Handle zones separately in profile manager snapshot/restore since ZoneConfig requires special serialization (color as private attr, contour generation)
- Inherit base zone color and generate contours for profile zone overrides in profile manager
* formatting
* don't require restart for camera enabled change for profiles
* publish camera state when changing profiles
* formatting
* remove available profiles from mqtt
* improve typing
2026-03-19 17:47:57 +03:00
|
|
|
{activeProfile && (
|
|
|
|
|
<Link to="/settings?page=profiles">
|
|
|
|
|
<div className="flex cursor-pointer items-center gap-2 text-sm hover:underline">
|
|
|
|
|
<span
|
|
|
|
|
className={cn(
|
|
|
|
|
"size-2 shrink-0 rounded-full",
|
|
|
|
|
activeProfile.color.dot,
|
|
|
|
|
)}
|
|
|
|
|
/>
|
|
|
|
|
<span className="max-w-[150px] truncate">
|
|
|
|
|
{activeProfile.friendlyName}
|
|
|
|
|
</span>
|
|
|
|
|
</div>
|
|
|
|
|
</Link>
|
|
|
|
|
)}
|
2024-03-30 21:45:13 +03:00
|
|
|
</div>
|
2024-05-18 23:19:32 +03:00
|
|
|
<div className="no-scrollbar flex h-full max-w-[50%] items-center gap-2 overflow-x-auto">
|
2024-04-22 17:20:23 +03:00
|
|
|
{Object.entries(messages).length === 0 ? (
|
2024-05-14 18:06:44 +03:00
|
|
|
<div className="flex items-center gap-2 text-sm">
|
2024-04-22 17:20:23 +03:00
|
|
|
<FaCheck className="size-3 text-green-500" />
|
2025-03-16 18:36:20 +03:00
|
|
|
{t("stats.healthy")}
|
2024-02-22 05:27:02 +03:00
|
|
|
</div>
|
2024-04-22 17:20:23 +03:00
|
|
|
) : (
|
|
|
|
|
Object.entries(messages).map(([key, messageArray]) => (
|
2024-05-14 18:06:44 +03:00
|
|
|
<div key={key} className="flex h-full items-center gap-2">
|
2024-05-18 19:54:46 +03:00
|
|
|
{messageArray.map(({ text, color, link }: StatusMessage) => {
|
2024-04-29 01:59:03 +03:00
|
|
|
const message = (
|
|
|
|
|
<div
|
2024-05-18 19:54:46 +03:00
|
|
|
key={text}
|
2024-05-18 23:19:32 +03:00
|
|
|
className={`flex items-center gap-2 whitespace-nowrap text-sm ${link ? "cursor-pointer hover:underline" : ""}`}
|
2024-04-29 01:59:03 +03:00
|
|
|
>
|
|
|
|
|
<IoIosWarning
|
|
|
|
|
className={`size-5 ${color || "text-danger"}`}
|
|
|
|
|
/>
|
|
|
|
|
{text}
|
|
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
if (link) {
|
2024-04-30 16:09:50 +03:00
|
|
|
return (
|
2024-05-18 19:54:46 +03:00
|
|
|
<Link key={text} to={link}>
|
2024-04-30 16:09:50 +03:00
|
|
|
{message}
|
|
|
|
|
</Link>
|
|
|
|
|
);
|
2024-04-29 01:59:03 +03:00
|
|
|
} else {
|
|
|
|
|
return message;
|
|
|
|
|
}
|
|
|
|
|
})}
|
2024-04-22 17:20:23 +03:00
|
|
|
</div>
|
|
|
|
|
))
|
|
|
|
|
)}
|
2024-03-30 21:45:13 +03:00
|
|
|
</div>
|
2024-02-22 05:27:02 +03:00
|
|
|
</div>
|
|
|
|
|
);
|
|
|
|
|
}
|