mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-03-20 15:18:21 +03:00
* 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
315 lines
8.5 KiB
JSON
315 lines
8.5 KiB
JSON
{
|
|
"time": {
|
|
"untilForTime": "Until {{time}}",
|
|
"untilForRestart": "Until Frigate restarts.",
|
|
"untilRestart": "Until restart",
|
|
"never": "Never",
|
|
"ago": "{{timeAgo}} ago",
|
|
"justNow": "Just now",
|
|
"today": "Today",
|
|
"yesterday": "Yesterday",
|
|
"last7": "Last 7 days",
|
|
"last14": "Last 14 days",
|
|
"last30": "Last 30 days",
|
|
"thisWeek": "This Week",
|
|
"lastWeek": "Last Week",
|
|
"thisMonth": "This Month",
|
|
"lastMonth": "Last Month",
|
|
"5minutes": "5 minutes",
|
|
"10minutes": "10 minutes",
|
|
"30minutes": "30 minutes",
|
|
"1hour": "1 hour",
|
|
"12hours": "12 hours",
|
|
"24hours": "24 hours",
|
|
"pm": "pm",
|
|
"am": "am",
|
|
"yr": "{{time}}yr",
|
|
"year_one": "{{time}} year",
|
|
"year_other": "{{time}} years",
|
|
"mo": "{{time}}mo",
|
|
"month_one": "{{time}} month",
|
|
"month_other": "{{time}} months",
|
|
"d": "{{time}}d",
|
|
"day_one": "{{time}} day",
|
|
"day_other": "{{time}} days",
|
|
"h": "{{time}}h",
|
|
"hour_one": "{{time}} hour",
|
|
"hour_other": "{{time}} hours",
|
|
"m": "{{time}}m",
|
|
"minute_one": "{{time}} minute",
|
|
"minute_other": "{{time}} minutes",
|
|
"s": "{{time}}s",
|
|
"second_one": "{{time}} second",
|
|
"second_other": "{{time}} seconds",
|
|
"formattedTimestamp": {
|
|
"12hour": "MMM d, h:mm:ss aaa",
|
|
"24hour": "MMM d, HH:mm:ss"
|
|
},
|
|
"formattedTimestamp2": {
|
|
"12hour": "MM/dd h:mm:ssa",
|
|
"24hour": "d MMM HH:mm:ss"
|
|
},
|
|
"formattedTimestampHourMinute": {
|
|
"12hour": "h:mm aaa",
|
|
"24hour": "HH:mm"
|
|
},
|
|
"formattedTimestampHourMinuteSecond": {
|
|
"12hour": "h:mm:ss aaa",
|
|
"24hour": "HH:mm:ss"
|
|
},
|
|
"formattedTimestampMonthDayHourMinute": {
|
|
"12hour": "MMM d, h:mm aaa",
|
|
"24hour": "MMM d, HH:mm"
|
|
},
|
|
"formattedTimestampMonthDayYear": {
|
|
"12hour": "MMM d, yyyy",
|
|
"24hour": "MMM d, yyyy"
|
|
},
|
|
"formattedTimestampMonthDayYearHourMinute": {
|
|
"12hour": "MMM d yyyy, h:mm aaa",
|
|
"24hour": "MMM d yyyy, HH:mm"
|
|
},
|
|
"formattedTimestampMonthDay": "MMM d",
|
|
"formattedTimestampFilename": {
|
|
"12hour": "MM-dd-yy-h-mm-ss-a",
|
|
"24hour": "MM-dd-yy-HH-mm-ss"
|
|
},
|
|
"inProgress": "In progress",
|
|
"invalidStartTime": "Invalid start time",
|
|
"invalidEndTime": "Invalid end time"
|
|
},
|
|
"unit": {
|
|
"speed": {
|
|
"mph": "mph",
|
|
"kph": "kph"
|
|
},
|
|
"length": {
|
|
"feet": "feet",
|
|
"meters": "meters"
|
|
},
|
|
"data": {
|
|
"kbps": "kB/s",
|
|
"mbps": "MB/s",
|
|
"gbps": "GB/s",
|
|
"kbph": "kB/hour",
|
|
"mbph": "MB/hour",
|
|
"gbph": "GB/hour"
|
|
}
|
|
},
|
|
"label": {
|
|
"back": "Go back",
|
|
"hide": "Hide {{item}}",
|
|
"show": "Show {{item}}",
|
|
"ID": "ID",
|
|
"none": "None",
|
|
"all": "All",
|
|
"other": "Other"
|
|
},
|
|
"list": {
|
|
"two": "{{0}} and {{1}}",
|
|
"many": "{{items}}, and {{last}}",
|
|
"separatorWithSpace": ", "
|
|
},
|
|
"field": {
|
|
"optional": "Optional",
|
|
"internalID": "The Internal ID Frigate uses in the configuration and database"
|
|
},
|
|
"button": {
|
|
"add": "Add",
|
|
"apply": "Apply",
|
|
"applying": "Applying…",
|
|
"reset": "Reset",
|
|
"undo": "Undo",
|
|
"done": "Done",
|
|
"enabled": "Enabled",
|
|
"enable": "Enable",
|
|
"disabled": "Disabled",
|
|
"disable": "Disable",
|
|
"save": "Save",
|
|
"saving": "Saving…",
|
|
"cancel": "Cancel",
|
|
"close": "Close",
|
|
"copy": "Copy",
|
|
"copiedToClipboard": "Copied to clipboard",
|
|
"back": "Back",
|
|
"history": "History",
|
|
"fullscreen": "Fullscreen",
|
|
"exitFullscreen": "Exit Fullscreen",
|
|
"pictureInPicture": "Picture in Picture",
|
|
"twoWayTalk": "Two Way Talk",
|
|
"cameraAudio": "Camera Audio",
|
|
"on": "ON",
|
|
"off": "OFF",
|
|
"edit": "Edit",
|
|
"copyCoordinates": "Copy coordinates",
|
|
"delete": "Delete",
|
|
"yes": "Yes",
|
|
"no": "No",
|
|
"download": "Download",
|
|
"info": "Info",
|
|
"suspended": "Suspended",
|
|
"unsuspended": "Unsuspend",
|
|
"play": "Play",
|
|
"unselect": "Unselect",
|
|
"export": "Export",
|
|
"deleteNow": "Delete Now",
|
|
"next": "Next",
|
|
"continue": "Continue",
|
|
"modified": "Modified",
|
|
"overridden": "Overridden",
|
|
"resetToGlobal": "Reset to Global",
|
|
"resetToDefault": "Reset to Default",
|
|
"saveAll": "Save All",
|
|
"savingAll": "Saving All…",
|
|
"undoAll": "Undo All"
|
|
},
|
|
"menu": {
|
|
"system": "System",
|
|
"systemMetrics": "System metrics",
|
|
"configuration": "Configuration",
|
|
"systemLogs": "System logs",
|
|
"profiles": "Profiles",
|
|
"settings": "Settings",
|
|
"configurationEditor": "Configuration Editor",
|
|
"languages": "Languages",
|
|
"language": {
|
|
"en": "English (English)",
|
|
"es": "Español (Spanish)",
|
|
"zhCN": "简体中文 (Simplified Chinese)",
|
|
"hi": "हिन्दी (Hindi)",
|
|
"fr": "Français (French)",
|
|
"ar": "العربية (Arabic)",
|
|
"pt": "Português (Portuguese)",
|
|
"ptBR": "Português brasileiro (Brazilian Portuguese)",
|
|
"ru": "Русский (Russian)",
|
|
"de": "Deutsch (German)",
|
|
"ja": "日本語 (Japanese)",
|
|
"tr": "Türkçe (Turkish)",
|
|
"it": "Italiano (Italian)",
|
|
"nl": "Nederlands (Dutch)",
|
|
"sv": "Svenska (Swedish)",
|
|
"cs": "Čeština (Czech)",
|
|
"nb": "Norsk Bokmål (Norwegian Bokmål)",
|
|
"ko": "한국어 (Korean)",
|
|
"vi": "Tiếng Việt (Vietnamese)",
|
|
"fa": "فارسی (Persian)",
|
|
"pl": "Polski (Polish)",
|
|
"uk": "Українська (Ukrainian)",
|
|
"he": "עברית (Hebrew)",
|
|
"el": "Ελληνικά (Greek)",
|
|
"ro": "Română (Romanian)",
|
|
"hu": "Magyar (Hungarian)",
|
|
"fi": "Suomi (Finnish)",
|
|
"da": "Dansk (Danish)",
|
|
"sk": "Slovenčina (Slovak)",
|
|
"yue": "粵語 (Cantonese)",
|
|
"th": "ไทย (Thai)",
|
|
"ca": "Català (Catalan)",
|
|
"hr": "Hrvatski (Croatian)",
|
|
"sr": "Српски (Serbian)",
|
|
"sl": "Slovenščina (Slovenian)",
|
|
"lt": "Lietuvių (Lithuanian)",
|
|
"bg": "Български (Bulgarian)",
|
|
"gl": "Galego (Galician)",
|
|
"id": "Bahasa Indonesia (Indonesian)",
|
|
"ur": "اردو (Urdu)",
|
|
"withSystem": {
|
|
"label": "Use the system settings for language"
|
|
}
|
|
},
|
|
"appearance": "Appearance",
|
|
"darkMode": {
|
|
"label": "Dark Mode",
|
|
"light": "Light",
|
|
"dark": "Dark",
|
|
"withSystem": {
|
|
"label": "Use the system settings for light or dark mode"
|
|
}
|
|
},
|
|
"withSystem": "System",
|
|
"theme": {
|
|
"label": "Theme",
|
|
"blue": "Blue",
|
|
"green": "Green",
|
|
"nord": "Nord",
|
|
"red": "Red",
|
|
"highcontrast": "High Contrast",
|
|
"default": "Default"
|
|
},
|
|
"help": "Help",
|
|
"documentation": {
|
|
"title": "Documentation",
|
|
"label": "Frigate documentation"
|
|
},
|
|
"restart": "Restart Frigate",
|
|
"live": {
|
|
"title": "Live",
|
|
"allCameras": "All Cameras",
|
|
"cameras": {
|
|
"title": "Cameras",
|
|
"count_one": "{{count}} Camera",
|
|
"count_other": "{{count}} Cameras"
|
|
}
|
|
},
|
|
"review": "Review",
|
|
"explore": "Explore",
|
|
"export": "Export",
|
|
"actions": "Actions",
|
|
"uiPlayground": "UI Playground",
|
|
"faceLibrary": "Face Library",
|
|
"classification": "Classification",
|
|
"chat": "Chat",
|
|
"user": {
|
|
"title": "User",
|
|
"account": "Account",
|
|
"current": "Current User: {{user}}",
|
|
"anonymous": "anonymous",
|
|
"logout": "Logout",
|
|
"setPassword": "Set Password"
|
|
}
|
|
},
|
|
"toast": {
|
|
"copyUrlToClipboard": "Copied URL to clipboard.",
|
|
"save": {
|
|
"title": "Save",
|
|
"error": {
|
|
"title": "Failed to save config changes: {{errorMessage}}",
|
|
"noMessage": "Failed to save config changes"
|
|
}
|
|
}
|
|
},
|
|
"role": {
|
|
"title": "Role",
|
|
"admin": "Admin",
|
|
"viewer": "Viewer",
|
|
"desc": "Admins have full access to all features in the Frigate UI. Viewers are limited to viewing cameras, review items, and historical footage in the UI."
|
|
},
|
|
"pagination": {
|
|
"label": "pagination",
|
|
"previous": {
|
|
"title": "Previous",
|
|
"label": "Go to previous page"
|
|
},
|
|
"next": {
|
|
"title": "Next",
|
|
"label": "Go to next page"
|
|
},
|
|
"more": "More pages"
|
|
},
|
|
"accessDenied": {
|
|
"documentTitle": "Access Denied - Frigate",
|
|
"title": "Access Denied",
|
|
"desc": "You don't have permission to view this page."
|
|
},
|
|
"notFound": {
|
|
"documentTitle": "Not Found - Frigate",
|
|
"title": "404",
|
|
"desc": "Page not found"
|
|
},
|
|
"selectItem": "Select {{item}}",
|
|
"readTheDocumentation": "Read the documentation",
|
|
"information": {
|
|
"pixels": "{{area}}px"
|
|
}
|
|
}
|