···
+
diff --git a/frigate/api/media.py b/frigate/api/media.py
+
index b5f3ba70..09a09c13 100644
+
--- a/frigate/api/media.py
+
+++ b/frigate/api/media.py
+
@@ -31,6 +31,7 @@ from frigate.config import FrigateConfig
+
from frigate.const import (
+
@@ -154,7 +155,9 @@ def latest_frame(
+
frame_processor.get_current_frame_time(camera_name) + retry_interval
+
if request.app.camera_error_image is None:
+
- error_image = glob.glob("/opt/frigate/frigate/images/camera-error.jpg")
+
+ error_image = glob.glob(
+
+ os.path.join(INSTALL_DIR, "frigate/images/camera-error.jpg")
+
if len(error_image) > 0:
+
request.app.camera_error_image = cv2.imread(
+
@@ -497,7 +500,7 @@ def recording_clip(
+
file_name = sanitize_filename(f"playlist_{camera_name}_{start_ts}-{end_ts}.txt")
+
- file_path = f"/tmp/cache/{file_name}"
+
+ file_path = os.path.join(CACHE_DIR, file_name)
+
with open(file_path, "w") as file:
+
for clip in recordings:
+
diff --git a/frigate/api/preview.py b/frigate/api/preview.py
+
index d14a15ff..2db2326a 100644
+
--- a/frigate/api/preview.py
+
+++ b/frigate/api/preview.py
+
@@ -9,7 +9,7 @@ from fastapi import APIRouter
+
from fastapi.responses import JSONResponse
+
from frigate.api.defs.tags import Tags
+
-from frigate.const import CACHE_DIR, PREVIEW_FRAME_TYPE
+
+from frigate.const import BASE_DIR, CACHE_DIR, PREVIEW_FRAME_TYPE
+
from frigate.models import Previews
+
logger = logging.getLogger(__name__)
+
@@ -52,7 +52,7 @@ def preview_ts(camera_name: str, start_ts: float, end_ts: float):
+
"camera": preview["camera"],
+
- "src": preview["path"].replace("/media/frigate", ""),
+
+ "src": preview["path"].replace(BASE_DIR, ""),
+
"start": preview["start_time"],
+
"end": preview["end_time"],
+
diff --git a/frigate/comms/webpush.py b/frigate/comms/webpush.py
+
index abfd52d1..ab4cf3c5 100644
+
--- a/frigate/comms/webpush.py
+
+++ b/frigate/comms/webpush.py
+
@@ -12,7 +12,7 @@ from pywebpush import WebPusher
+
from frigate.comms.config_updater import ConfigSubscriber
+
from frigate.comms.dispatcher import Communicator
+
from frigate.config import FrigateConfig
+
-from frigate.const import CONFIG_DIR
+
+from frigate.const import BASE_DIR, CONFIG_DIR
+
from frigate.models import User
+
logger = logging.getLogger(__name__)
+
@@ -151,7 +151,7 @@ class WebPushClient(Communicator): # type: ignore[misc]
+
camera: str = payload["after"]["camera"]
+
title = f"{', '.join(sorted_objects).replace('_', ' ').title()}{' was' if state == 'end' else ''} detected in {', '.join(payload['after']['data']['zones']).replace('_', ' ').title()}"
+
message = f"Detected on {camera.replace('_', ' ').title()}"
+
- image = f"{payload['after']['thumb_path'].replace('/media/frigate', '')}"
+
+ image = f"{payload['after']['thumb_path'].replace(BASE_DIR, '')}"
+
# if event is ongoing open to live view otherwise open to recordings view
+
direct_url = f"/review?id={reviewId}" if state == "end" else f"/#{camera}"
+
diff --git a/frigate/const.py b/frigate/const.py
+
index 5976f47b..dc710467 100644
+
+INSTALL_DIR = "/opt/frigate"
+
DEFAULT_DB_PATH = f"{CONFIG_DIR}/frigate.db"
+
MODEL_CACHE_DIR = f"{CONFIG_DIR}/model_cache"
+
diff --git a/frigate/detectors/detector_config.py b/frigate/detectors/detector_config.py
+
index 452f1fee..13535a62 100644
+
--- a/frigate/detectors/detector_config.py
+
+++ b/frigate/detectors/detector_config.py
+
@@ -9,7 +9,7 @@ import requests
+
from pydantic import BaseModel, ConfigDict, Field
+
from pydantic.fields import PrivateAttr
+
-from frigate.const import DEFAULT_ATTRIBUTE_LABEL_MAP
+
+from frigate.const import DEFAULT_ATTRIBUTE_LABEL_MAP, MODEL_CACHE_DIR
+
from frigate.plus import PlusApi
+
from frigate.util.builtin import generate_color_palette, load_labels
+
@@ -117,7 +117,7 @@ class ModelConfig(BaseModel):
+
model_id = self.path[7:]
+
- self.path = f"/config/model_cache/{model_id}"
+
+ self.path = os.path.join(MODEL_CACHE_DIR, model_id)
+
model_info_path = f"{self.path}.json"
+
# download the model if it doesn't exist
+
diff --git a/frigate/detectors/plugins/hailo8l.py b/frigate/detectors/plugins/hailo8l.py
+
index b66d78bd..69e86bc5 100644
+
--- a/frigate/detectors/plugins/hailo8l.py
+
+++ b/frigate/detectors/plugins/hailo8l.py
+
@@ -22,6 +22,7 @@ except ModuleNotFoundError:
+
from pydantic import BaseModel, Field
+
from typing_extensions import Literal
+
+from frigate.const import MODEL_CACHE_DIR
+
from frigate.detectors.detection_api import DetectionApi
+
from frigate.detectors.detector_config import BaseDetectorConfig
+
@@ -57,7 +58,7 @@ class HailoDetector(DetectionApi):
+
self.h8l_tensor_format = detector_config.model.input_tensor
+
self.h8l_pixel_format = detector_config.model.input_pixel_format
+
self.model_url = "https://hailo-model-zoo.s3.eu-west-2.amazonaws.com/ModelZoo/Compiled/v2.11.0/hailo8l/ssd_mobilenet_v1.hef"
+
- self.cache_dir = "/config/model_cache/h8l_cache"
+
+ self.cache_dir = os.path.join(MODEL_CACHE_DIR, "h8l_cache")
+
self.expected_model_filename = "ssd_mobilenet_v1.hef"
+
output_type = "FLOAT32"
+
diff --git a/frigate/detectors/plugins/openvino.py b/frigate/detectors/plugins/openvino.py
+
index 51e48530..d199317b 100644
+
--- a/frigate/detectors/plugins/openvino.py
+
+++ b/frigate/detectors/plugins/openvino.py
+
@@ -7,6 +7,7 @@ import openvino.properties as props
+
from pydantic import Field
+
from typing_extensions import Literal
+
+from frigate.const import MODEL_CACHE_DIR
+
from frigate.detectors.detection_api import DetectionApi
+
from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum
+
@@ -35,8 +36,10 @@ class OvDetector(DetectionApi):
+
logger.error(f"OpenVino model file {detector_config.model.path} not found.")
+
raise FileNotFoundError
+
- os.makedirs("/config/model_cache/openvino", exist_ok=True)
+
- self.ov_core.set_property({props.cache_dir: "/config/model_cache/openvino"})
+
+ os.makedirs(os.path.join(MODEL_CACHE_DIR, "openvino"), exist_ok=True)
+
+ self.ov_core.set_property(
+
+ {props.cache_dir: os.path.join(MODEL_CACHE_DIR, "openvino")}
+
self.interpreter = self.ov_core.compile_model(
+
model=detector_config.model.path, device_name=detector_config.device
+
diff --git a/frigate/detectors/plugins/rknn.py b/frigate/detectors/plugins/rknn.py
+
index df94d7b6..bc3d9ae0 100644
+
--- a/frigate/detectors/plugins/rknn.py
+
+++ b/frigate/detectors/plugins/rknn.py
+
@@ -6,6 +6,7 @@ from typing import Literal
+
from pydantic import Field
+
+from frigate.const import MODEL_CACHE_DIR
+
from frigate.detectors.detection_api import DetectionApi
+
from frigate.detectors.detector_config import BaseDetectorConfig, ModelTypeEnum
+
@@ -17,7 +18,7 @@ supported_socs = ["rk3562", "rk3566", "rk3568", "rk3576", "rk3588"]
+
supported_models = {ModelTypeEnum.yolonas: "^deci-fp16-yolonas_[sml]$"}
+
-model_cache_dir = "/config/model_cache/rknn_cache/"
+
+model_cache_dir = os.path.join(MODEL_CACHE_DIR, "rknn_cache/")
+
class RknnDetectorConfig(BaseDetectorConfig):
+
diff --git a/frigate/detectors/plugins/rocm.py b/frigate/detectors/plugins/rocm.py
+
index 60118d12..7c87edb5 100644
+
--- a/frigate/detectors/plugins/rocm.py
+
+++ b/frigate/detectors/plugins/rocm.py
+
@@ -9,6 +9,7 @@ import numpy as np
+
from pydantic import Field
+
from typing_extensions import Literal
+
+from frigate.const import MODEL_CACHE_DIR
+
from frigate.detectors.detection_api import DetectionApi
+
from frigate.detectors.detector_config import (
+
@@ -116,7 +117,7 @@ class ROCmDetector(DetectionApi):
+
logger.info(f"AMD/ROCm: saving parsed model into {mxr_path}")
+
- os.makedirs("/config/model_cache/rocm", exist_ok=True)
+
+ os.makedirs(os.path.join(MODEL_CACHE_DIR, "rocm"), exist_ok=True)
+
migraphx.save(self.model, mxr_path)
+
logger.info("AMD/ROCm: model loaded")
+
diff --git a/frigate/output/birdseye.py b/frigate/output/birdseye.py
+
index 00f17c8f..8331eb64 100644
+
--- a/frigate/output/birdseye.py
+
+++ b/frigate/output/birdseye.py
+
@@ -16,7 +16,7 @@ import numpy as np
+
from frigate.comms.config_updater import ConfigSubscriber
+
from frigate.config import BirdseyeModeEnum, FfmpegConfig, FrigateConfig
+
-from frigate.const import BASE_DIR, BIRDSEYE_PIPE
+
+from frigate.const import BASE_DIR, BIRDSEYE_PIPE, INSTALL_DIR
+
from frigate.util.image import (
+
SharedMemoryFrameManager,
+
@@ -297,7 +297,9 @@ class BirdsEyeFrameManager:
+
birdseye_logo = cv2.imread(custom_logo_files[0], cv2.IMREAD_UNCHANGED)
+
if birdseye_logo is None:
+
- logo_files = glob.glob("/opt/frigate/frigate/images/birdseye.png")
+
+ logo_files = glob.glob(
+
+ os.path.join(INSTALL_DIR, "frigate/images/birdseye.png")
+
if len(logo_files) > 0:
+
birdseye_logo = cv2.imread(logo_files[0], cv2.IMREAD_UNCHANGED)
+
diff --git a/frigate/test/http_api/base_http_test.py b/frigate/test/http_api/base_http_test.py
+
index e7a1d03e..4fa4a5b5 100644
+
--- a/frigate/test/http_api/base_http_test.py
+
+++ b/frigate/test/http_api/base_http_test.py
+
@@ -9,6 +9,7 @@ from playhouse.sqliteq import SqliteQueueDatabase
+
from frigate.api.fastapi_app import create_fastapi_app
+
from frigate.config import FrigateConfig
+
+from frigate.const import BASE_DIR, CACHE_DIR
+
from frigate.models import Event, Recordings, ReviewSegment
+
from frigate.review.types import SeverityEnum
+
from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS
+
@@ -72,19 +73,19 @@ class BaseTestHttp(unittest.TestCase):
+
- "/media/frigate/clips": {
+
+ os.path.join(BASE_DIR, "clips"): {
+
- "/media/frigate/recordings": {
+
+ os.path.join(BASE_DIR, "recordings"): {
+
diff --git a/frigate/test/test_config.py b/frigate/test/test_config.py
+
index e6cb1274..5a3deefd 100644
+
--- a/frigate/test/test_config.py
+
+++ b/frigate/test/test_config.py
+
@@ -854,9 +854,9 @@ class TestConfig(unittest.TestCase):
+
assert frigate_config.model.merged_labelmap[0] == "person"
+
def test_plus_labelmap(self):
+
- with open("/config/model_cache/test", "w") as f:
+
+ with open(os.path.join(MODEL_CACHE_DIR, "test"), "w") as f:
+
json.dump(self.plus_model_info, f)
+
- with open("/config/model_cache/test.json", "w") as f:
+
+ with open(os.path.join(MODEL_CACHE_DIR, "test.json"), "w") as f:
+
json.dump(self.plus_model_info, f)
+
diff --git a/frigate/test/test_http.py b/frigate/test/test_http.py
+
index 21379425..66f9d22a 100644
+
--- a/frigate/test/test_http.py
+
+++ b/frigate/test/test_http.py
+
@@ -12,6 +12,7 @@ from playhouse.sqliteq import SqliteQueueDatabase
+
from frigate.api.fastapi_app import create_fastapi_app
+
from frigate.config import FrigateConfig
+
+from frigate.const import BASE_DIR, CACHE_DIR
+
from frigate.models import Event, Recordings, Timeline
+
from frigate.stats.emitter import StatsEmitter
+
from frigate.test.const import TEST_DB, TEST_DB_CLEANUPS
+
@@ -76,19 +77,19 @@ class TestHttp(unittest.TestCase):
+
- "/media/frigate/clips": {
+
+ os.path.join(BASE_DIR, "clips"): {
+
- "/media/frigate/recordings": {
+
+ os.path.join(BASE_DIR, "recordings"): {
+
diff --git a/frigate/util/config.py b/frigate/util/config.py
+
index d456c755..b6b270c9 100644
+
--- a/frigate/util/config.py
+
+++ b/frigate/util/config.py
+
@@ -14,7 +14,7 @@ from frigate.util.services import get_video_properties
+
logger = logging.getLogger(__name__)
+
CURRENT_CONFIG_VERSION = "0.15-1"
+
-DEFAULT_CONFIG_FILE = "/config/config.yml"
+
+DEFAULT_CONFIG_FILE = os.path.join(CONFIG_DIR, "config.yml")
+
def find_config_file() -> str:
+
diff --git a/frigate/util/model.py b/frigate/util/model.py
+
index ce2c9538..6e93cb38 100644
+
--- a/frigate/util/model.py
+
+++ b/frigate/util/model.py
+
@@ -12,6 +12,8 @@ except ImportError:
+
# openvino is not included
+
+from frigate.const import MODEL_CACHE_DIR
+
logger = logging.getLogger(__name__)
+
@@ -46,7 +48,8 @@ def get_ort_providers(
+
# so it is not enabled by default
+
if device == "Tensorrt":
+
- "/config/model_cache/tensorrt/ort/trt-engines", exist_ok=True
+
+ os.path.join(MODEL_CACHE_DIR, "tensorrt/ort/trt-engines"),
+
device_id = 0 if not device.isdigit() else int(device)
+
providers.append(provider)
+
@@ -57,19 +60,23 @@ def get_ort_providers(
+
and os.environ.get("USE_FP_16", "True") != "False",
+
"trt_timing_cache_enable": True,
+
"trt_engine_cache_enable": True,
+
- "trt_timing_cache_path": "/config/model_cache/tensorrt/ort",
+
- "trt_engine_cache_path": "/config/model_cache/tensorrt/ort/trt-engines",
+
+ "trt_timing_cache_path": os.path.join(
+
+ MODEL_CACHE_DIR, "tensorrt/ort"
+
+ "trt_engine_cache_path": os.path.join(
+
+ MODEL_CACHE_DIR, "tensorrt/ort/trt-engines"
+
elif provider == "OpenVINOExecutionProvider":
+
- os.makedirs("/config/model_cache/openvino/ort", exist_ok=True)
+
+ os.makedirs(os.path.join(MODEL_CACHE_DIR, "openvino/ort"), exist_ok=True)
+
providers.append(provider)
+
"arena_extend_strategy": "kSameAsRequested",
+
- "cache_dir": "/config/model_cache/openvino/ort",
+
+ "cache_dir": os.path.join(MODEL_CACHE_DIR, "openvino/ort"),
+
@@ -103,7 +110,7 @@ class ONNXModelRunner:
+
- {ov.properties.cache_dir: "/config/model_cache/openvino"}
+
+ {ov.properties.cache_dir: os.path.join(MODEL_CACHE_DIR, "openvino")}
+
self.interpreter = self.ov.compile_model(
+
model=model_path, device_name=device