Compare commits

...
Author SHA1 Message Date
Josh Hawkins d84aab09b1 add triggers to note 2025-12-22 18:33:17 -06:00
Josh Hawkins 2bf7ecb0b6 0.17 2025-12-22 17:56:00 -06:00
Josh Hawkins bcc2d37a4c remove footnote about 0.17 2025-12-22 17:53:11 -06:00
Nicolas Mowen bf4007d66a Reset the wizard state after closing with model 2025-12-22 16:01:20 -07:00
Josh Hawkins 6e1b2447ac only show allowed cameras and groups in camera filter button 2025-12-22 15:39:55 -06:00
Josh Hawkins bf74e74696 fix weekday starting point on explore when set to monday in UI settings 2025-12-22 13:41:28 -06:00
Nicolas Mowen 3fb9abc97d Add review thumbnail URL to integration docs 2025-12-22 10:53:25 -07:00
Josh Hawkins fb0838558f use fallback timeout for opening media source
covers the case where there is no active connection to the go2rtc stream and the camera takes a long time to start
2025-12-21 22:09:21 -06:00
8 changed files with 60 additions and 18 deletions
@@ -39,7 +39,7 @@ For object classification:
:::note
A tracked object can only have a single sub label. If you are using Face Recognition and you configure an object classification model for `person` using the sub label type, your sub label may not be assigned correctly as it depends on which enrichment completes its analysis first. Consider using the `attribute` type instead.
A tracked object can only have a single sub label. If you are using Triggers or Face Recognition and you configure an object classification model for `person` using the sub label type, your sub label may not be assigned correctly as it depends on which enrichment completes its analysis first. Consider using the `attribute` type instead.
:::
+6
View File
@@ -245,6 +245,12 @@ To load a preview gif of a review item:
https://HA_URL/api/frigate/notifications/<review-id>/review_preview.gif
```
To load the thumbnail of a review item:
```
https://HA_URL/api/frigate/notifications/<review-id>/<camera>/review_thumbnail.webp
```
<a name="streams"></a>
## RTSP stream
+7 -9
View File
@@ -15,13 +15,11 @@ There are three model types offered in Frigate+, `mobiledet`, `yolonas`, and `yo
Not all model types are supported by all detectors, so it's important to choose a model type to match your detector as shown in the table under [supported detector types](#supported-detector-types). You can test model types for compatibility and speed on your hardware by using the base models.
| Model Type | Description |
| ----------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `mobiledet` | Based on the same architecture as the default model included with Frigate. Runs on Google Coral devices and CPUs. |
| `yolonas` | A newer architecture that offers slightly higher accuracy and improved detection of small objects. Runs on Intel, NVidia GPUs, and AMD GPUs. |
| `yolov9` | A leading SOTA (state of the art) object detection model with similar performance to yolonas, but on a wider range of hardware options. Runs on Intel, NVidia GPUs, AMD GPUs, Hailo, MemryX\*, Apple Silicon\*, and Rockchip NPUs. |
_\* Support coming in 0.17_
| Model Type | Description |
| ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `mobiledet` | Based on the same architecture as the default model included with Frigate. Runs on Google Coral devices and CPUs. |
| `yolonas` | A newer architecture that offers slightly higher accuracy and improved detection of small objects. Runs on Intel, NVidia GPUs, and AMD GPUs. |
| `yolov9` | A leading SOTA (state of the art) object detection model with similar performance to yolonas, but on a wider range of hardware options. Runs on Intel, NVidia GPUs, AMD GPUs, Hailo, MemryX, Apple Silicon, and Rockchip NPUs. |
### YOLOv9 Details
@@ -39,7 +37,7 @@ If you have a Hailo device, you will need to specify the hardware you have when
#### Rockchip (RKNN) Support
For 0.16, YOLOv9 onnx models will need to be manually converted. First, you will need to configure Frigate to use the model id for your YOLOv9 onnx model so it downloads the model to your `model_cache` directory. From there, you can follow the [documentation](/configuration/object_detectors.md#converting-your-own-onnx-model-to-rknn-format) to convert it. Automatic conversion is coming in 0.17.
For 0.16, YOLOv9 onnx models will need to be manually converted. First, you will need to configure Frigate to use the model id for your YOLOv9 onnx model so it downloads the model to your `model_cache` directory. From there, you can follow the [documentation](/configuration/object_detectors.md#converting-your-own-onnx-model-to-rknn-format) to convert it. Automatic conversion is available in 0.17 and later.
## Supported detector types
@@ -55,7 +53,7 @@ Currently, Frigate+ models support CPU (`cpu`), Google Coral (`edgetpu`), OpenVi
| [Hailo8/Hailo8L/Hailo8R](/configuration/object_detectors#hailo-8) | `hailo8l` | `yolov9` |
| [Rockchip NPU](/configuration/object_detectors#rockchip-platform)\* | `rknn` | `yolov9` |
_\* Requires manual conversion in 0.16. Automatic conversion coming in 0.17._
_\* Requires manual conversion in 0.16. Automatic conversion available in 0.17 and later._
## Improving your model
@@ -137,6 +137,11 @@ export default function ClassificationModelWizardDialog({
onClose();
};
const handleSuccessClose = () => {
dispatch({ type: "RESET" });
onClose();
};
return (
<Dialog
open={open}
@@ -207,7 +212,7 @@ export default function ClassificationModelWizardDialog({
step1Data={wizardState.step1Data}
step2Data={wizardState.step2Data}
initialData={wizardState.step3Data}
onClose={onClose}
onClose={handleSuccessClose}
onBack={handleBack}
/>
)}
@@ -18,6 +18,7 @@ import PlatformAwareDialog from "../overlay/dialog/PlatformAwareDialog";
import { useTranslation } from "react-i18next";
import useSWR from "swr";
import { FrigateConfig } from "@/types/frigateConfig";
import { useUserPersistence } from "@/hooks/use-user-persistence";
type CalendarFilterButtonProps = {
reviewSummary?: ReviewSummary;
@@ -105,6 +106,7 @@ export function CalendarRangeFilterButton({
const { t } = useTranslation(["components/filter"]);
const { data: config } = useSWR<FrigateConfig>("config");
const timezone = useTimezone(config);
const [weekStartsOn] = useUserPersistence("weekStartsOn", 0);
const [open, setOpen] = useState(false);
const selectedDate = useFormattedRange(
@@ -138,6 +140,7 @@ export function CalendarRangeFilterButton({
initialDateTo={range?.to}
timezone={timezone}
showCompare={false}
weekStartsOn={weekStartsOn}
onUpdate={(range) => {
updateSelectedRange(range.range);
setOpen(false);
@@ -13,6 +13,7 @@ import { Drawer, DrawerContent, DrawerTrigger } from "../ui/drawer";
import FilterSwitch from "./FilterSwitch";
import { FaVideo } from "react-icons/fa";
import { useTranslation } from "react-i18next";
import { useAllowedCameras } from "@/hooks/use-allowed-cameras";
type CameraFilterButtonProps = {
allCameras: string[];
@@ -35,6 +36,30 @@ export function CamerasFilterButton({
const [currentCameras, setCurrentCameras] = useState<string[] | undefined>(
selectedCameras,
);
const allowedCameras = useAllowedCameras();
// Filter cameras to only include those the user has access to
const filteredCameras = useMemo(
() => allCameras.filter((camera) => allowedCameras.includes(camera)),
[allCameras, allowedCameras],
);
// Filter groups to only include those with at least one allowed camera
const filteredGroups = useMemo(
() =>
groups
.map(([name, config]) => {
const allowedGroupCameras = config.cameras.filter((camera) =>
allowedCameras.includes(camera),
);
return [name, { ...config, cameras: allowedGroupCameras }] as [
string,
CameraGroupConfig,
];
})
.filter(([, config]) => config.cameras.length > 0),
[groups, allowedCameras],
);
const buttonText = useMemo(() => {
if (isMobile) {
@@ -79,8 +104,8 @@ export function CamerasFilterButton({
);
const content = (
<CamerasFilterContent
allCameras={allCameras}
groups={groups}
allCameras={filteredCameras}
groups={filteredGroups}
currentCameras={currentCameras}
mainCamera={mainCamera}
setCurrentCameras={setCurrentCameras}
+2 -2
View File
@@ -260,7 +260,7 @@ function MSEPlayer({
// @ts-expect-error for typing
value: codecs(MediaSource.isTypeSupported),
},
3000,
(fallbackTimeout ?? 3) * 1000,
).catch(() => {
if (wsRef.current) {
onDisconnect();
@@ -290,7 +290,7 @@ function MSEPlayer({
type: "mse",
value: codecs(MediaSource.isTypeSupported),
},
3000,
(fallbackTimeout ?? 3) * 1000,
).catch(() => {
if (wsRef.current) {
onDisconnect();
+8 -3
View File
@@ -35,6 +35,8 @@ export interface DateRangePickerProps {
showCompare?: boolean;
/** timezone */
timezone?: string;
/** First day of the week: 0 = Sunday, 1 = Monday */
weekStartsOn?: number;
}
const getDateAdjustedForTimezone = (
@@ -91,6 +93,7 @@ export function DateRangePicker({
onUpdate,
onReset,
showCompare = true,
weekStartsOn = 0,
}: DateRangePickerProps) {
const [isOpen, setIsOpen] = useState(false);
@@ -150,7 +153,9 @@ export function DateRangePicker({
if (!preset) throw new Error(`Unknown date range preset: ${presetName}`);
const from = new TZDate(new Date(), timezone);
const to = new TZDate(new Date(), timezone);
const first = from.getDate() - from.getDay();
const dayOfWeek = from.getDay();
const daysFromWeekStart = (dayOfWeek - weekStartsOn + 7) % 7;
const first = from.getDate() - daysFromWeekStart;
switch (preset.name) {
case "today":
@@ -184,8 +189,8 @@ export function DateRangePicker({
to.setHours(23, 59, 59, 999);
break;
case "lastWeek":
from.setDate(from.getDate() - 7 - from.getDay());
to.setDate(to.getDate() - to.getDay() - 1);
from.setDate(first - 7);
to.setDate(first - 1);
from.setHours(0, 0, 0, 0);
to.setHours(23, 59, 59, 999);
break;