mirror of
https://github.com/blakeblackshear/frigate.git
synced 2026-04-27 17:17:40 +03:00
add enabled switch
This commit is contained in:
parent
38a5797681
commit
aca9e15790
@ -107,6 +107,8 @@ class CameraConfigUpdateSubscriber:
|
||||
config.record = updated_config
|
||||
elif update_type == CameraConfigUpdateEnum.review:
|
||||
config.review = updated_config
|
||||
elif update_type == CameraConfigUpdateEnum.semantic_search:
|
||||
config.semantic_search = updated_config
|
||||
elif update_type == CameraConfigUpdateEnum.snapshots:
|
||||
config.snapshots = updated_config
|
||||
elif update_type == CameraConfigUpdateEnum.zones:
|
||||
|
||||
@ -125,10 +125,11 @@ class SemanticSearchConfig(FrigateBaseModel):
|
||||
|
||||
|
||||
class TriggerConfig(FrigateBaseModel):
|
||||
enabled: bool = Field(default=True, title="Enable this trigger")
|
||||
type: TriggerType = Field(default=TriggerType.DESCRIPTION, title="Type of trigger")
|
||||
data: str = Field(title="Trigger content (text phrase or image ID)")
|
||||
threshold: float = Field(
|
||||
title="Confidence score required to run the trigger.",
|
||||
title="Confidence score required to run the trigger",
|
||||
default=0.8,
|
||||
gt=0.0,
|
||||
le=1.0,
|
||||
|
||||
@ -80,6 +80,16 @@ class SemanticTriggerProcessor(PostProcessorApi):
|
||||
)
|
||||
|
||||
for trigger in triggers:
|
||||
if (
|
||||
not self.config.cameras[camera]
|
||||
.semantic_search.triggers[trigger["name"]]
|
||||
.enabled
|
||||
):
|
||||
logger.debug(
|
||||
f"Trigger {trigger['name']} is disabled for camera {camera}"
|
||||
)
|
||||
continue
|
||||
|
||||
logger.debug(
|
||||
f"Processing {trigger['type']} trigger for {event_id} on {trigger['camera']}: {trigger['name']}"
|
||||
)
|
||||
@ -171,6 +181,7 @@ class SemanticTriggerProcessor(PostProcessorApi):
|
||||
.actions
|
||||
):
|
||||
# TODO: handle actions for the trigger
|
||||
# notifications already handled by webpush
|
||||
pass
|
||||
|
||||
if WRITE_DEBUG_IMAGES:
|
||||
|
||||
@ -97,7 +97,11 @@ class EmbeddingMaintainer(threading.Thread):
|
||||
self.config_updater = CameraConfigUpdateSubscriber(
|
||||
self.config,
|
||||
self.config.cameras,
|
||||
[CameraConfigUpdateEnum.add, CameraConfigUpdateEnum.remove],
|
||||
[
|
||||
CameraConfigUpdateEnum.add,
|
||||
CameraConfigUpdateEnum.remove,
|
||||
CameraConfigUpdateEnum.semantic_search,
|
||||
],
|
||||
)
|
||||
|
||||
# Configure Frigate DB
|
||||
|
||||
@ -693,6 +693,9 @@
|
||||
"alreadyExists": "A trigger with this name already exists for this camera."
|
||||
}
|
||||
},
|
||||
"enabled": {
|
||||
"description": "Enable or disable this trigger"
|
||||
},
|
||||
"type": {
|
||||
"title": "Trigger Type",
|
||||
"placeholder": "Select trigger type"
|
||||
|
||||
@ -34,12 +34,14 @@ import ActivityIndicator from "@/components/indicators/activity-indicator";
|
||||
import { FrigateConfig } from "@/types/frigateConfig";
|
||||
import ImagePicker from "@/components/overlay/ImagePicker";
|
||||
import { Trigger, TriggerAction, TriggerType } from "@/types/trigger";
|
||||
import { Switch } from "@/components/ui/switch";
|
||||
|
||||
type CreateTriggerDialogProps = {
|
||||
show: boolean;
|
||||
trigger: Trigger | null;
|
||||
selectedCamera: string;
|
||||
onCreate: (
|
||||
enabled: boolean,
|
||||
name: string,
|
||||
type: TriggerType,
|
||||
data: string,
|
||||
@ -74,6 +76,7 @@ export default function CreateTriggerDialog({
|
||||
}, [config, selectedCamera]);
|
||||
|
||||
const formSchema = z.object({
|
||||
enabled: z.boolean(),
|
||||
name: z
|
||||
.string()
|
||||
.min(2, t("triggers.dialog.form.name.error.minLength"))
|
||||
@ -101,6 +104,7 @@ export default function CreateTriggerDialog({
|
||||
resolver: zodResolver(formSchema),
|
||||
mode: "onChange",
|
||||
defaultValues: {
|
||||
enabled: trigger?.enabled ?? true,
|
||||
name: trigger?.name ?? "",
|
||||
type: trigger?.type ?? "description",
|
||||
data: trigger?.data ?? "",
|
||||
@ -115,6 +119,7 @@ export default function CreateTriggerDialog({
|
||||
onEdit({ ...values });
|
||||
} else {
|
||||
onCreate(
|
||||
values.enabled,
|
||||
values.name,
|
||||
values.type,
|
||||
values.data,
|
||||
@ -128,6 +133,7 @@ export default function CreateTriggerDialog({
|
||||
useEffect(() => {
|
||||
if (!show) {
|
||||
form.reset({
|
||||
enabled: true,
|
||||
name: "",
|
||||
type: "description",
|
||||
data: "",
|
||||
@ -136,6 +142,7 @@ export default function CreateTriggerDialog({
|
||||
});
|
||||
} else if (trigger) {
|
||||
form.reset({
|
||||
enabled: trigger.enabled,
|
||||
name: trigger.name,
|
||||
type: trigger.type,
|
||||
data: trigger.data,
|
||||
@ -194,6 +201,29 @@ export default function CreateTriggerDialog({
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="enabled"
|
||||
render={({ field }) => (
|
||||
<FormItem className="flex flex-row items-center justify-between">
|
||||
<div className="space-y-0.5">
|
||||
<FormLabel className="text-base">
|
||||
{t("enabled", { ns: "common" })}
|
||||
</FormLabel>
|
||||
<div className="text-sm text-muted-foreground">
|
||||
{t("triggers.dialog.form.enabled.description")}
|
||||
</div>
|
||||
</div>
|
||||
<FormControl>
|
||||
<Switch
|
||||
checked={field.value}
|
||||
onCheckedChange={field.onChange}
|
||||
/>
|
||||
</FormControl>
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="type"
|
||||
|
||||
@ -224,6 +224,7 @@ export interface CameraConfig {
|
||||
semantic_search: {
|
||||
triggers: {
|
||||
[triggerName: string]: {
|
||||
enabled: boolean;
|
||||
type: TriggerType;
|
||||
data: string;
|
||||
threshold: number;
|
||||
|
||||
@ -2,6 +2,7 @@ export type TriggerType = "thumbnail" | "description";
|
||||
export type TriggerAction = "alert" | "notification";
|
||||
|
||||
export type Trigger = {
|
||||
enabled: boolean;
|
||||
name: string;
|
||||
type: TriggerType;
|
||||
data: string;
|
||||
|
||||
@ -36,6 +36,7 @@ type ConfigSetBody = {
|
||||
triggers?: {
|
||||
[key: string]:
|
||||
| {
|
||||
enabled: boolean;
|
||||
type: string;
|
||||
data: string;
|
||||
threshold: number;
|
||||
@ -84,6 +85,7 @@ export default function TriggerView({
|
||||
return Object.entries(
|
||||
config.cameras[selectedCamera].semantic_search.triggers,
|
||||
).map(([name, trigger]) => ({
|
||||
enabled: trigger.enabled,
|
||||
name,
|
||||
type: trigger.type,
|
||||
data: trigger.data,
|
||||
@ -99,7 +101,7 @@ export default function TriggerView({
|
||||
const saveToConfig = useCallback(
|
||||
(trigger: Trigger, isEdit: boolean) => {
|
||||
setIsLoading(true);
|
||||
const { name, type, data, threshold, actions } = trigger;
|
||||
const { enabled, name, type, data, threshold, actions } = trigger;
|
||||
const embeddingBody: TriggerEmbeddingBody = { type, data, threshold };
|
||||
const embeddingUrl = isEdit
|
||||
? `/trigger/embedding/${selectedCamera}/${name}`
|
||||
@ -117,6 +119,7 @@ export default function TriggerView({
|
||||
semantic_search: {
|
||||
triggers: {
|
||||
[name]: {
|
||||
enabled,
|
||||
type,
|
||||
data,
|
||||
threshold,
|
||||
@ -172,6 +175,7 @@ export default function TriggerView({
|
||||
|
||||
const onCreate = useCallback(
|
||||
(
|
||||
enabled: boolean,
|
||||
name: string,
|
||||
type: TriggerType,
|
||||
data: string,
|
||||
@ -179,7 +183,7 @@ export default function TriggerView({
|
||||
actions: TriggerAction[],
|
||||
) => {
|
||||
setUnsavedChanges(true);
|
||||
saveToConfig({ name, type, data, threshold, actions }, false);
|
||||
saveToConfig({ enabled, name, type, data, threshold, actions }, false);
|
||||
setShowCreate(false);
|
||||
},
|
||||
[saveToConfig, setUnsavedChanges],
|
||||
|
||||
Loading…
Reference in New Issue
Block a user