Compare commits

..

1 Commits

Author SHA1 Message Date
GuoQing Liu
84b80f1ac0
Merge d007bd0a6f into 4171efcd79 2026-04-27 13:20:07 +08:00
8 changed files with 26 additions and 35 deletions

View File

@ -42,7 +42,7 @@ function HardwareCheckbox({
export default function HardwareOptions({ deviceId, hardwareEnabled, onToggle, isDisabled }: Props) { export default function HardwareOptions({ deviceId, hardwareEnabled, onToggle, isDisabled }: Props) {
return ( return (
<div className={styles.formSection}> <div className={styles.formSection}>
<h4>Generic Hardware Devices</h4> <h4>Generic Hardware Acceleration</h4>
{deviceId !== "stable" && ( {deviceId !== "stable" && (
<p className={styles.helpText}> <p className={styles.helpText}>
Some options have been auto-configured based on your device type. Some options have been auto-configured based on your device type.

View File

@ -104,7 +104,7 @@ devices:
imageTagSuffix: "-standard-arm64" imageTagSuffix: "-standard-arm64"
autoHardware: autoHardware:
- "video11" - "video11"
helpText: "Raspberry Pi automatically configures the video11 device (RPi 4) and uses the arm64 image." helpText: "Raspberry Pi automatically configures the Video11 device and uses the arm64 image."
helpType: "info" helpType: "info"
- id: "stable-rk" - id: "stable-rk"
@ -180,7 +180,7 @@ hardware:
devices: devices:
- host: "/dev/dri" - host: "/dev/dri"
container: "/dev/dri" container: "/dev/dri"
comment: "Intel/AMD GPU hardware acceleration" comment: "GPU hardware acceleration"
- id: "intelNpu" - id: "intelNpu"
label: "Intel NPU (/dev/accel)" label: "Intel NPU (/dev/accel)"
@ -242,7 +242,7 @@ hardware:
comment: "AXERA libraries" comment: "AXERA libraries"
- id: "video11" - id: "video11"
label: "Raspberry Pi video11" label: "Raspberry Pi Video11"
description: "Pass through /dev/video11 for Raspberry Pi 4B hardware acceleration." description: "Pass through /dev/video11 for Raspberry Pi 4B hardware acceleration."
disabledWhen: disabledWhen:
- "stable-tensorrt" - "stable-tensorrt"
@ -267,6 +267,18 @@ ports:
defaultEnabled: true defaultEnabled: true
locked: true locked: true
- id: "5000"
host: 5000
container: 5000
protocol: "tcp"
description: "Unauthenticated Web UI port (not recommended)"
defaultEnabled: false
requiresConfirmation: true
warningType: "danger"
warningContent: "Exposing port 5000 allows **unauthenticated access** to your Frigate instance. Anyone on your network (or the internet if you have a public IP) could access it without any credentials. This may lead to **unauthorized access**, **privacy leaks**, or further attacks. Ensure you have proper firewall rules or VPN in place before enabling this."
confirmationLabel: "I understand the risk and confirm enabling port 5000"
cooldownSeconds: 10
- id: "8554" - id: "8554"
host: 8554 host: 8554
container: 8554 container: 8554

View File

@ -20,7 +20,6 @@ class CameraConfigUpdateEnum(str, Enum):
ffmpeg = "ffmpeg" ffmpeg = "ffmpeg"
live = "live" live = "live"
motion = "motion" # includes motion and motion masks motion = "motion" # includes motion and motion masks
mqtt = "mqtt"
notifications = "notifications" notifications = "notifications"
objects = "objects" objects = "objects"
object_genai = "object_genai" object_genai = "object_genai"
@ -34,7 +33,6 @@ class CameraConfigUpdateEnum(str, Enum):
lpr = "lpr" lpr = "lpr"
snapshots = "snapshots" snapshots = "snapshots"
timestamp_style = "timestamp_style" timestamp_style = "timestamp_style"
ui = "ui"
zones = "zones" zones = "zones"

View File

@ -27,7 +27,7 @@ class ReviewMetadata(BaseModel):
) )
title: str = Field( title: str = Field(
max_length=80, max_length=80,
description="Under 10 words. Name the apparent purpose or outcome of the activity together with the location involved. Do not narrate or list the sequence of actions step by step.", description="A short title characterizing what took place and where, under 10 words.",
) )
scene: str = Field( scene: str = Field(
min_length=150, min_length=150,
@ -36,7 +36,7 @@ class ReviewMetadata(BaseModel):
) )
shortSummary: str = Field( shortSummary: str = Field(
min_length=70, min_length=70,
max_length=120, max_length=100,
description="A brief 2-sentence summary of the scene, suitable for notifications.", description="A brief 2-sentence summary of the scene, suitable for notifications.",
) )
confidence: float = Field( confidence: float = Field(

View File

@ -517,16 +517,10 @@ class EmbeddingMaintainer(threading.Thread):
try: try:
event: Event = Event.get(Event.id == event_id) event: Event = Event.get(Event.id == event_id)
except DoesNotExist: except DoesNotExist:
for processor in self.post_processors:
if isinstance(processor, ObjectDescriptionProcessor):
processor.cleanup_event(event_id)
continue continue
# Skip the event if not an object # Skip the event if not an object
if event.data.get("type") != "object": if event.data.get("type") != "object":
for processor in self.post_processors:
if isinstance(processor, ObjectDescriptionProcessor):
processor.cleanup_event(event_id)
continue continue
# Extract valid thumbnail # Extract valid thumbnail

View File

@ -205,7 +205,6 @@ class AudioEventMaintainer(threading.Thread):
self.transcription_thread.start() self.transcription_thread.start()
self.was_enabled = camera.enabled self.was_enabled = camera.enabled
self.was_audio_enabled = camera.audio.enabled
def detect_audio(self, audio: np.ndarray) -> None: def detect_audio(self, audio: np.ndarray) -> None:
if not self.camera_config.audio.enabled or self.stop_event.is_set(): if not self.camera_config.audio.enabled or self.stop_event.is_set():
@ -364,17 +363,6 @@ class AudioEventMaintainer(threading.Thread):
time.sleep(0.1) time.sleep(0.1)
continue continue
audio_enabled = self.camera_config.audio.enabled
if audio_enabled != self.was_audio_enabled:
if not audio_enabled:
self.logger.debug(
f"Disabling audio detections for {self.camera_config.name}, ending events"
)
self.requestor.send_data(
EXPIRE_AUDIO_ACTIVITY, self.camera_config.name
)
self.was_audio_enabled = audio_enabled
self.read_audio() self.read_audio()
if self.audio_listener: if self.audio_listener:

View File

@ -201,10 +201,9 @@ Each line represents a detection state, not necessarily unique individuals. The
except json.JSONDecodeError as je: except json.JSONDecodeError as je:
logger.error("Failed to parse review description JSON: %s", je) logger.error("Failed to parse review description JSON: %s", je)
return None return None
# observations and confidence are required on the model; fill an empty default # observations is required on the model; fill an empty default
# if the response omitted it so attribute access stays safe. # if the response omitted it so attribute access stays safe.
raw.setdefault("observations", []) raw.setdefault("observations", [])
raw.setdefault("confidence", 0.0)
metadata = ReviewMetadata.model_construct(**raw) metadata = ReviewMetadata.model_construct(**raw)
except Exception as e: except Exception as e:
logger.error( logger.error(

View File

@ -317,16 +317,16 @@ class CameraWatchdog(threading.Thread):
if camera != self.config.name: if camera != self.config.name:
continue continue
if topic.endswith(RecordingsDataTypeEnum.invalid.value): if topic.endswith(RecordingsDataTypeEnum.valid.value):
self.logger.warning(
f"Invalid recording segment detected for {camera} at {segment_time}"
)
self.latest_invalid_segment_time = segment_time
elif topic.endswith(RecordingsDataTypeEnum.valid.value):
self.logger.debug( self.logger.debug(
f"Latest valid recording segment time on {camera}: {segment_time}" f"Latest valid recording segment time on {camera}: {segment_time}"
) )
self.latest_valid_segment_time = segment_time self.latest_valid_segment_time = segment_time
elif topic.endswith(RecordingsDataTypeEnum.invalid.value):
self.logger.warning(
f"Invalid recording segment detected for {camera} at {segment_time}"
)
self.latest_invalid_segment_time = segment_time
elif topic.endswith(RecordingsDataTypeEnum.latest.value): elif topic.endswith(RecordingsDataTypeEnum.latest.value):
if segment_time is not None: if segment_time is not None:
self.latest_cache_segment_time = segment_time self.latest_cache_segment_time = segment_time