開發者中心 · Universal v1.9.59 Fix30

Securex Nvr 外掛開發文件

以官方 Frigate 為基礎,透過 Universal 外掛 API 擴充功能。建議一個功能一個外掛,獨立安裝、獨立升級、獨立移除,盡量不修改 Frigate 核心原始碼。

外掛基線Universal v1.9.59 Fix30Empty Base
Frigatev0.18.0建議基線
一般外掛包≤ 16 MBZIP
介面語言3简 / 繁 / EN
01
QUICK START

5 分鐘建立第一個外掛

先從最小可運作骨架開始,再依需求加入設定頁、背景工作與商城能力。

1定義範圍一個功能一個外掛。
2建立骨架manifest.json + plugin.py
3本機驗證首次安裝/更新載入、熱儲存、啟停、移除。
4發布商城打包 ZIP 後提交審核。
核心原則能透過外掛完成的功能,不要直接修改 Frigate 核心,這樣升級 Frigate 時更容易保持相容。
02
PACKAGE

目錄與打包規範

建議目錄

tynvr_module_example/
├── manifest.json
├── plugin.py
├── config.example.yml
├── README.md
└── assets/
    └── plugin.css

打包要求

  • ZIP 最上層只放一個外掛根目錄。
  • manifest.jsonplugin.py 必須存在。
  • 一般外掛 ZIP 建議不超過 16 MB。
  • 大型模型、PyTorch、CUDA 等執行環境不要塞進一般外掛包。
避免不要把 __pycache__、暫存日誌、訓練結果、Token、資料庫備份一起打進發布 ZIP。
03
MANIFEST

manifest.json

描述外掛身分、版本、設定 UI、選單掛載與可執行操作。

manifest.json最小實用範例
{
  "id": "tynvr_module_example",
  "name": "Example Plugin",
  "version": "1.0.0",
  "description": "Example Securex Nvr plugin",
  "enabled": true,
  "kind": "tynvr_core_module",
  "module_id": "example",
  "order": 50,
  "config_apply": "hot",
  "first_install_restart": true,
  "navigation_user_toggle": true,
  "navigation_default_visible": true,
  "actions": [
    {"id": "reload", "label": "Reload"}
  ],
  "navigation": {
    "key": "example",
    "mount": "settings.sidebar.plugins",
    "label": "Example Plugin",
    "url": "/api/example/?embed=1",
    "view": "iframe",
    "order": 50,
    "icon": "puzzle"
  }
}
id穩定唯一 ID;建議 tynvr_module_xxx。
version每次商城升級必須遞增。
navigation選單由 manifest 動態宣告;建議明確提供穩定 key。
navigation_user_toggle允許使用者控制側欄顯示;升級必須保留使用者選擇。
config_apply建議 hot:一般設定儲存後立即套用,不要求重啟 Frigate。
first_install_restart首次安裝/程式碼升級可要求一次重載;一般設定儲存不應要求重啟。
actions提供給外掛管理頁的明確操作。
04
PYTHON

plugin.py / class Plugin

目前 Universal 外掛以 FrigatePlugin 為基底類別。建議把路由、設定、背景執行緒與停止邏輯都封裝在外掛實例內。

plugin.py建議骨架
from pathlib import Path
from typing import Any
from fastapi import APIRouter, Depends
from frigate.api.auth import require_role
from frigate.plugins.base import FrigatePlugin

class Plugin(FrigatePlugin):
    def __init__(self, frigate_config: Any, plugin_dir: Path, stop_event=None):
        super().__init__(frigate_config, plugin_dir, stop_event)
        self._router = APIRouter(tags=["example"])
        self._build_routes()

    @property
    def router(self):
        return self._router

    def _build_routes(self):
        @self._router.get(
            "/api/example/status",
            dependencies=[Depends(require_role(["admin"]))],
        )
        def status():
            return {"ok": True}

    def get_public_config(self):
        return {"enabled": True}

    def update_config(self, payload):
        return {"success": True}

    def run_action(self, action, payload):
        return {"success": action == "reload"}

    def stop(self):
        pass
建議瀏覽器可見設定只回傳安全欄位。完整 Token、密碼、私鑰不要透過 get_public_config() 回傳。
06
CONFIG & DATA

設定、狀態與使用者資料

config.yml外掛自己的持久設定。升級時保留。
*.db佇列、歷史與本機索引等資料。不要因升級而刪除。
*_status.json執行狀態與可恢復資訊。
.runtime/大型執行環境應與外掛程式碼分離,升級程式碼時盡量重用。
升級規則新增設定欄位必須提供安全預設值並相容舊設定。一般儲存應熱套用;升級不得覆蓋側欄顯示、Token、執行環境或持久資料。
07
SECURITY

權限、Secret 與敏感操作

01

最小權限:讀取使用已登入權限;修改設定、Token、模型部署、硬體控制等使用管理員權限。

02

Secret:完整 Token、密碼、金鑰只保留在伺服器端。UI 只顯示「已設定」或遮罩值。

03

CSRF / POST:變更狀態不可使用 GET。Frigate 同源 POST/PUT/PATCH/DELETE 應明確送出 X-CSRF-TOKEN: 1(建議同時 X-CACHE-BYPASS: 1);Universal 雖有通用橋接,外掛本身仍應正確實作。

04

輸入驗證:路徑、URL、命令參數、上傳檔名都要白名單/正規化,避免把使用者輸入直接拼進 shell。

08
RUNTIME

背景工作、網路與恢復

不要阻塞請求

訓練、下載、同步、掃描等長工作放入背景執行緒/Worker,並提供狀態、進度、停止與錯誤資訊。

非同步路由不要做同步回環 HTTP

async FastAPI 路由內不要直接用 urllib/requests 同步呼叫 Frigate 自己的 127.0.0.1 API,否則可能造成事件迴圈自鎖到 timeout。請使用執行緒池/非同步客戶端或重用既有資料。

網路操作必須可恢復

設定合理 timeout;斷網後退避重試;上傳大型檔案使用分塊與校驗;重複請求盡量做到冪等。

日誌與執行環境需可維護

日誌清理應使用原地 truncate,不停止 Worker/訓練;大型 runtime 與 artifacts 應與外掛程式碼分離,升級只替換外掛本體。

09
OFFICIAL AI REFERENCE

官方 AI 外掛參考

以下為目前正式基線,可用來驗證第三方外掛是否符合平台約定。

Securex AI Cloud v1.1.7

  • Shadow A/B 在同一畫面比較生產與候選模型,不切換生產 detector。
  • Explore 人工確認按「是/否」即提交;只有 Store 雲端確認 correct/incorrect 後才顯示「已提交」。
  • 人工確認樣本使用 sample_reason=manual,並在圖片頁顯示「正確/錯誤 · 人工確認」。
  • 人工提交讀取 Frigate event/snapshot 時必須在線程池執行,避免 async 路由自鎖。

Securex AI Training Worker v1.0.11

  • 訓練 runtime 與外掛程式碼分離,升級/重啟不刪除訓練環境與 artifacts。
  • 支援重新附著正在執行的 Job,不重複訓練。
  • 安裝日誌與 Worker 日誌可原地清空,不停止安裝器/Worker。
  • 獨立頁面跟隨 Frigate 主題,狀態操作遵循 Frigate CSRF 規則。
10
I18N & RESPONSIVE

簡體 / 繁體 / English 與響應式

EN

商城中的外掛名稱、描述、按鈕、錯誤、設定欄位都應完整提供三種語言;不要只翻譯標題。

  • 英文通常更長,按鈕與卡片不能依賴固定中文寬度。
  • 在 1366px、平板寬度與窄側欄嵌入場景下測試。
  • 日誌、長 ID、URL 使用換行/省略規則,避免撐破版面。
11
VERSIONING

版本、升級與移除

1.0.0首次發布
1.0.1相容修正
1.1.0新增能力

升級覆蓋外掛程式碼時,應保留使用者設定、側欄顯示偏好與持久資料;一般設定儲存採熱套用。移除時要區分「刪除外掛程式碼」與「刪除使用者資料」;破壞性清理必須明確提示。

12
RELEASE CHECKLIST

發布前檢查

ZIP 結構正確manifest.json / plugin.py

安裝與啟用正常全新安裝測試

重啟自動恢復Frigate 重啟後狀態正確

升級保留資料config / db / status

移除後無殘留選單動態選單正常

三語言完整简 / 繁 / EN

窄螢幕不溢出1366 / tablet / embed

網路失敗可恢復timeout / retry / resume

Secret 不洩漏瀏覽器與日誌檢查

寫入請求 CSRF 正確X-CSRF-TOKEN / POST / PUT / DELETE

熱儲存不需重啟config_apply=hot

升級保留側欄偏好navigation_visible

非同步路由無阻塞回環threadpool / async client

版本與商城資料一致manifest / catalog / ZIP

READY TO SHIP

外掛準備好了?

完成檢查後上傳 ZIP。商城審核重點包括安全、相容性、升級保留、多語言與介面完整性。

登入後提交