diff --git a/.github/copilot-instructions.md b/.github/copilot-instructions.md index 6c14bb166..89acd8a9b 100644 --- a/.github/copilot-instructions.md +++ b/.github/copilot-instructions.md @@ -1,2 +1,3 @@ -Never write strings in the frontend directly, always write to and reference the relevant translations file. -Always conform new and refactored code to the existing coding style in the project. +- For Frigate NVR, never write strings in the frontend directly. Since the project uses `react-i18next`, use `t()` and write the English string in the relevant translations file in `web/public/locales/en`. +- Always conform new and refactored code to the existing coding style in the project. +- Always have a way to test your work and confirm your changes. When running backend tests, use `python3 -u -m unittest`. diff --git a/docs/docs/configuration/license_plate_recognition.md b/docs/docs/configuration/license_plate_recognition.md index a18c822f5..5f70dd9a0 100644 --- a/docs/docs/configuration/license_plate_recognition.md +++ b/docs/docs/configuration/license_plate_recognition.md @@ -68,8 +68,8 @@ Fine-tune the LPR feature using these optional parameters at the global level of - Default: `1000` pixels. Note: this is intentionally set very low as it is an _area_ measurement (length x width). For reference, 1000 pixels represents a ~32x32 pixel square in your camera image. - Depending on the resolution of your camera's `detect` stream, you can increase this value to ignore small or distant plates. - **`device`**: Device to use to run license plate detection _and_ recognition models. - - Default: `CPU` - - This can be `CPU`, `GPU`, or the GPU's device number. For users without a model that detects license plates natively, using a GPU may increase performance of the YOLOv9 license plate detector model. See the [Hardware Accelerated Enrichments](/configuration/hardware_acceleration_enrichments.md) documentation. However, for users who run a model that detects `license_plate` natively, there is little to no performance gain reported with running LPR on GPU compared to the CPU. + - Default: `None` + - This is auto-selected by Frigate and can be `CPU`, `GPU`, or the GPU's device number. For users without a model that detects license plates natively, using a GPU may increase performance of the YOLOv9 license plate detector model. See the [Hardware Accelerated Enrichments](/configuration/hardware_acceleration_enrichments.md) documentation. However, for users who run a model that detects `license_plate` natively, there is little to no performance gain reported with running LPR on GPU compared to the CPU. - **`model_size`**: The size of the model used to identify regions of text on plates. - Default: `small` - This can be `small` or `large`. @@ -432,6 +432,6 @@ If you are using a model that natively detects `license_plate`, add an _object m If you are not using a model that natively detects `license_plate` or you are using dedicated LPR camera mode, only a _motion mask_ over your text is required. -### I see "Error running ... model" in my logs. How can I fix this? +### I see "Error running ... model" in my logs, or my inference time is very high. How can I fix this? This usually happens when your GPU is unable to compile or use one of the LPR models. Set your `device` to `CPU` and try again. GPU acceleration only provides a slight performance increase, and the models are lightweight enough to run without issue on most CPUs. diff --git a/frigate/genai/gemini.py b/frigate/genai/gemini.py index 36e708594..83bd3340d 100644 --- a/frigate/genai/gemini.py +++ b/frigate/genai/gemini.py @@ -24,6 +24,14 @@ class GeminiClient(GenAIClient): http_options_dict = { "api_version": "v1", "timeout": int(self.timeout * 1000), # requires milliseconds + "retry_options": types.HttpRetryOptions( + attempts=3, + initial_delay=1.0, + max_delay=60.0, + exp_base=2.0, + jitter=1.0, + http_status_codes=[429, 500, 502, 503, 504], + ), } if isinstance(self.genai_config.provider_options, dict): diff --git a/web/public/locales/en/common.json b/web/public/locales/en/common.json index 2ae6297a1..8bf13ca61 100644 --- a/web/public/locales/en/common.json +++ b/web/public/locales/en/common.json @@ -3,6 +3,7 @@ "untilForTime": "Until {{time}}", "untilForRestart": "Until Frigate restarts.", "untilRestart": "Until restart", + "never": "Never", "ago": "{{timeAgo}} ago", "justNow": "Just now", "today": "Today", diff --git a/web/src/components/overlay/CreateTriggerDialog.tsx b/web/src/components/overlay/CreateTriggerDialog.tsx index 11734acaf..ef30c649d 100644 --- a/web/src/components/overlay/CreateTriggerDialog.tsx +++ b/web/src/components/overlay/CreateTriggerDialog.tsx @@ -268,7 +268,7 @@ export default function CreateTriggerDialog({
- {t("enabled", { ns: "common" })} + {t("button.enabled", { ns: "common" })}
{t("triggers.dialog.form.enabled.description")} @@ -394,7 +394,10 @@ export default function CreateTriggerDialog({
{availableActions.map((action) => ( -
+
+ + ))}
diff --git a/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx b/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx index 33568dca7..2b560ded3 100644 --- a/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx +++ b/web/src/components/trigger/wizard/Step3ThresholdAndActions.tsx @@ -142,7 +142,10 @@ export default function Step3ThresholdAndActions({ {t("triggers.dialog.form.actions.title")}
{availableActions.map((action) => ( -
+
+ + ))}
@@ -197,9 +200,7 @@ export default function Step3ThresholdAndActions({ {isLoading && } {isLoading ? t("button.saving", { ns: "common" }) - : t("triggers.dialog.form.save", { - defaultValue: "Save Trigger", - })} + : t("button.save", { ns: "common" })}
diff --git a/web/src/views/settings/TriggerView.tsx b/web/src/views/settings/TriggerView.tsx index 7448a210b..28aa148fe 100644 --- a/web/src/views/settings/TriggerView.tsx +++ b/web/src/views/settings/TriggerView.tsx @@ -1,6 +1,7 @@ import { useCallback, useEffect, useMemo, useState } from "react"; import { Trans, useTranslation } from "react-i18next"; -import { Toaster, toast } from "sonner"; +import { toast } from "sonner"; +import { Toaster } from "@/components/ui/sonner"; import useSWR from "swr"; import axios from "axios"; import { Button } from "@/components/ui/button"; @@ -598,7 +599,7 @@ export default function TriggerView({ date_style: "medium", }, ) - : "Never"} + : t("never", { ns: "common" })} {trigger_status?.triggers[trigger.name] ?.triggering_event_id && ( @@ -663,7 +664,9 @@ export default function TriggerView({ - {t("name", { ns: "common" })} + + {t("name", { ns: "triggers.table.name" })} + {t("triggers.table.type")} {t("triggers.table.lastTriggered")} @@ -759,7 +762,7 @@ export default function TriggerView({ date_style: "medium", }, ) - : "Never"} + : t("time.never", { ns: "common" })} {trigger_status?.triggers[trigger.name] ?.triggering_event_id && (