即時鏡頭預覽
目前沒有啟用中的鏡頭
畫面上的框是 M3 在伺服器端直接燒進畫格的,跟畫面本身同步(不是前端事後疊加)。優先用 WebRTC 播放(延遲通常在 1 秒內),網路環境不支援時自動退回 HLS(延遲較高,通常好幾秒)。分割畫面會同時對每支啟用中的鏡頭各開一條連線,鏡頭一多會吃比較多頻寬/瀏覽器解碼資源。在人臉框附近按右鍵可以替該 Global ID 標記姓名/代號。
即時偵測記錄(M2 人流 / M3 人臉比對)
武器/暴力/火煙這三種才算「事件」,會出現在下面的「最近事件」;單純有人經過鏡頭前不算事件、不會觸發通知,但 M2/M3 其實一直在背景偵測,這裡把原始結果攤開來看。
已知人員(近 10 分鐘,人臉縮圖 + 跨鏡頭紀錄)
每張卡片是一個 Global ID,縮圖是最新一次看到這個人的樣子。只顯示最近 10 分鐘內出現過的人——目前人臉比對還不夠穩定,同一個人有時會被誤判成新的 Global ID,只看「最近」可以避免清單一直累積一堆早就不在場的舊卡片。
目前沒有已知人員
匯出訓練資料
只導出已經人工審核過(標記「確認」或「誤報」)的事件,沒審核過的原始偵測結果可能是雜訊,不會混進去。內容是一個 ZIP:manifest.json(每筆事件的完整中繼資料)+ 對應的錄影片段(如果那筆事件當時有錄到,不是每筆都有)。只做「收集/導出標註資料」,不含任何模型微調邏輯。只有 admin 能導出。
稽核日誌(規格 M15)— 誰查了軌跡
「操作者」欄是登入中的帳號(見「👤 帳號管理」);2026-07-16 前的舊紀錄沒有登入系統,這欄會是空的。
目前沒有稽核紀錄
Email 通知
跟 LINE 是並行的兩個獨立管道,高優先級事件(武器/暴力/火煙/區域入侵/徘徊/跌倒/監控名單比對)都會兩邊各發一次。原本是 .env 設定,現在改到這裡管理,不用改設定重新部署。只有 admin 帳號能修改。
LINE 通知
最近收到的 LINE ID
加 bot 好友或把 bot 拉進群組後,這裡會出現對應的使用者/群組 ID(webhook 收到 follow/join 事件才會有紀錄,記得先設定好 Channel Secret+Webhook URL)。點「使用這個」直接帶入上面的 Target ID 欄位。
尚未收到任何 LINE 事件
通知內容範本
Email 內文跟 LINE 推播文字共用同一份範本內容。可用欄位:。「預設範本」套用到所有沒有專屬範本的事件類型,也可以針對特定事件類型另外建立專屬範本(優先套用)。
已標記人員
在即時預覽畫面的人臉框附近按右鍵可以新增標記。這裡管理已經標記過的人員:修改姓名,或取消標記(只是移除姓名標籤,不影響 Re-ID 比對本身——下次比對到同一張臉,Global ID 還是同一個,只是不會再顯示姓名)。
目前沒有標記過的人員
比對測試 / 合併 / 拆分
AI 自動判斷不保證每次都對——同一人可能被拆成好幾個 Global ID(比對不到),或反過來兩個不同人被誤併成一個。這裡先用「比對測試」看兩個 ID 實際的相似度數據,確認後再決定要不要合併/拆分。Global ID 直接輸入完整 UUID(可以從已知人員卡片、或最近人臉比對紀錄裡複製)。
身份判斷紀錄
AI 自動重新比對改綁(auto_rebind)、操作者手動合併/拆分/改名,都記在這裡,方便回頭查一個 Global ID 為什麼變成現在這樣。
目前沒有紀錄
Re-ID 比對設定
調整 M3 人臉/身體比對的門檻與模型。門檻/重新比對頻率存檔後 M3 會在幾秒內自動套用,不用重啟;更換比對模型例外,一定要重新啟動 m3-reid 服務才會生效,而且會自動清空目前累積的身體外觀樣本(不同模型的向量沒辦法互相比較,混著比只會產生雜訊)。
⚠️ 已選擇新模型,儲存後要手動重啟 m3-reid 服務(docker compose restart m3-reid)才會套用,並會自動清空身體外觀樣本重新累積。
個別鏡頭配對門檻
同一組門檻不見得適合所有鏡頭組合——視角差很大的兩支鏡頭,身體外觀相似度天花板可能明顯比視角接近的組合低。這裡可以針對特定鏡頭配對覆蓋上面的全域身體比對門檻,沒設定的組合維持用全域值。
目前沒有個別設定
M3 效能狀態
這台主機 GPU 是多租戶共用(曾發生過過載事件),這裡可以快速確認 M3 自己的資源用量是否正常,不用每次都進容器查。
人臉追蹤
挑選一個人(已標記姓名的優先,也可以直接貼 Global ID),依日期時間查詢他經過哪些鏡頭(區域)、幾點到達、待了多久——底層資料跟「Global ID 軌跡查詢」共用,但這裡是給人直接看的清單,不是座標點。
目前沒有符合條件的紀錄
車牌讀取紀錄
M16(規格外新增)車牌辨識模組的出入紀錄,一律記錄(不管有沒有命中監控名單)。信心門檻/取樣間隔/冷卻時間在「🚨 危險識別」頁一起管理(module 名稱 m16_anpr)。
目前沒有車牌讀取紀錄
📊 事件統計(D-013 P1)
查詢區間內 events 表的統計彙總。之後階段會再加通知發送報表 / 裝置稼動率報表 / 人流車流趨勢報表,見 docs/DECISIONS.md D-013。
每日趨勢
灰線是每日總事件數,紅線是其中高優先級的部分(提供情境對照,不是主角時本來就該用灰色淡出)。
總事件數
高優先級
🔔 通知發送統計(D-013 P2)
查詢區間內 alerts 表的發送結果。「延遲」是事件發生到 M9 處理到這筆的時間差(佇列輪詢延遲的代理指標),不是保證對方真的收到的端對端送達時間。
每日發送趨勢
灰線是每日成功發送數,紅線是失敗數。
成功
失敗
🖥️ 裝置稼動率(D-013 P3)
統計依據是 device_status_history 表——中控每 30 秒被動判斷一次「這台裝置的 last_heartbeat 是否超過 90 秒沒更新」,狀態真的改變(上線↔離線)才寫一筆,不主動對裝置發連線探測。這是被動統計,不是即時告警:只要裝置狀態監看是最近才啟用的,或查詢區間早於監看開始的時間,該裝置會顯示「資料不足」而不是假造一個數字。
稼動率
🟢 ≥99%
🟡 95–99%
🔴 <95%
鏡頭稼動率
統計依據是 camera_status_history 表——中控每 30 秒查詢一次中央 mediamtx 對這支鏡頭中繼路徑的即時 ready 狀態,狀態真的改變(連線↔斷線)才寫一筆,鏡頭沒有心跳概念所以是主動查詢 mediamtx,不是被動判斷。
🟢 ≥99%
🟡 95–99%
🔴 <95%
🚗 人流 / 車流趨勢(D-013 P4)
person_counts(M2 人流)/plate_reads(M16 ANPR 車流)已轉成 TimescaleDB hypertable,彙總在資料庫層做。
👣 人流趨勢
灰線是每日平均人數,藍線是每日尖峰人數(同一天內偵測到的最高瞬時人數)。
平均人數
尖峰人數
各鏡頭人流排行
🚗 車流趨勢(ANPR)
依小時分布(0–23 時,全區間累計)
⏰ 報表排程
到點自動重新彙總「事件統計/通知發送/裝置稼動率/人流車流趨勢」四種報表其中一種,用 Email 寄送 Excel/PDF 附件——不用每次都手動進來查詢。寄送時間是臺灣時間(UTC+8),daily 涵蓋昨天一整天、weekly 涵蓋過去 7 天、monthly 涵蓋上個完整月,範圍固定不能額外篩選鏡頭/裝置。
尚未建立任何排程
警戒線 / 區域
選鏡頭抓一張畫格當底圖,在上面點出警戒線(點 2 點)或區域(點多點,點完按「儲存」即封閉)。座標存成相對比例(0-1),鏡頭解析度改變也不用重畫。同一個區域可以同時當「虛擬警戒線/入侵偵測」跟「徘徊偵測」用(線只能做入侵偵測,徘徊偵測只對區域有意義)。「忽略煙火偵測」也只對區域有意義:框住畫面裡容易被誤判成火/煙的固定物件(例如螢幕、反光物),M6 就會跳過該區域,不受影響其他偵測模組。「違規停車偵測」(M23)一樣只對區域有意義:畫出禁停區,車輛停留超過門檻秒數才觸發,跟徘徊偵測是同一種邏輯換成偵測車輛。
此鏡頭現有的區域
| 名稱 | 類型 | 入侵偵測 | 徘徊偵測 | 徘徊門檻(秒) | 忽略煙火偵測 | 違規停車偵測 | 停車門檻(秒) | 冷卻(秒) | 啟用 | |
這支鏡頭還沒有設定任何區域,或尚未選擇鏡頭
一次性以圖搜圖
上傳照片,立即查詢過去是否有鏡頭拍到長得像的人(不會建立監控名單,查完就結束)。
| Global ID / 姓名 | 鏡頭 | 最後出現時間 | 相似度 |
尚未查詢,或查無符合結果
危險識別
M4(武器)/M5(暴力)/M6(火煙)目前能識別的類別,可以個別開關(例如某個類別誤報太多,先關掉它,不用整組模組停用),也可以調整每個模組的信心門檻/冷卻時間等參數。存檔後幾秒內自動生效,不用重啟服務。
訓練工作觸發
匯出資料集/訓練不用再上主機打指令——按下面按鈕會送一筆工作進佇列,host 上的 training_job_runner 服務每 15 秒輪詢一次,確認 GPU 沒有被正式偵測服務吃滿才會真的開始跑(這台主機曾因 GPU 負載疊加當機過,寧可讓工作排隊等待也不要搶跑)。同一時間全系統只能有一個工作,訓練通常要跑好一段時間,離開這頁不會中斷。
目前沒有任何訓練工作紀錄
模型版本管理
訓練平台第三層(`training/` 服務,`docker compose run --rm training python train.py ...`)產出的 fine-tune 權重會自動列在這裡(`is_active=false`,需要人工評估 metrics 後手動啟用)。
啟用後不會立刻生效,M4/M6 只在服務啟動時查一次要用哪個版本,切換後要重新啟動對應服務(docker compose restart m4-weapon 或 m6-fire)才會真的套用新模型。
M4 武器偵測(weapon)
| 建立時間 | 訓練/驗證樣本數 | Epochs | Metrics | 備註 | 狀態 | |
尚無自訓練版本,目前使用公開權重(Subh775/Threat-Detection-YOLOv8n)
M6 火煙偵測(fire_smoke)
| 建立時間 | 訓練/驗證樣本數 | Epochs | Metrics | 備註 | 狀態 | |
尚無自訓練版本,目前使用公開權重(leeyunjai/yolo11-firedetect)
語音求救關鍵詞(M21)
USB 陣列麥克風轉出的語音文字只要包含這裡任一個詞就會送 VLM 複核(判斷畫面是否真的有呼救者/嫌犯互動的跡象),複核通過才會觸發錄影跟通知。自己新增/刪除,不寫死在程式碼裡。
尚未設定任何關鍵詞——語音求救偵測目前不會比對任何內容
鏡頭定位
選一個樓層,從下面清單點選要定位的鏡頭(會反白),再直接點擊平面圖上對應的位置即可儲存座標。
VPN 伺服器資訊
M13 邊緣裝置(Jetson)透過 WireGuard 連進來的中心端。新增裝置要在主機上跑 ops/wireguard-add-jetson-peer.sh(這裡不能、也不該直接改 host 的 VPN 設定)。
連線設定
超過這麼久沒有 WireGuard 交握(handshake)就判定為離線。keepalive 預設每 25 秒一次,門檻不要設得太接近。
裝置連線狀態
尚未讀到連線快照——host 上的 wg-status-exporter.timer 可能還沒裝好或還沒跑過第一次。
目前沒有任何 peer 連線紀錄
感測器型號設定
一種 Modbus RTU 感測器型號的暫存器讀取設定(D-002)。新增一種新型號只是填一筆設定,不用改程式碼。
尚無感測器型號設定
實體感測器指派
把一種型號指派到某台邊緣裝置的某個序列埠/slave address。同一條 RS-485 匯流排(同一個序列埠)可以掛多顆不同 slave address 的感測器。
| 名稱 | 裝置 | 型號 | 序列埠 | Slave | 輪詢間隔 | 啟用 | 門檻告警(2026-07-21 新增,例如分貝計超過門檻寄通知) | |
尚無指派的感測器
感測器讀數
目前還沒有任何讀數
邊緣裝置清單
M13 遠端 Jetson Orin NX gateway(透過 WireGuard 連回本機)。目前尚無實體硬體連線時,狀態一律誠實回報「無法連線」,不會假裝連線成功——裝置實際插電、連上 VPN 後在這裡登記 VPN IP 即可開始管理。
| 名稱 | 目前運算 | 位置 | VPN IP:Port | 狀態 | 上次連線 | 啟用 | |
尚未登記任何邊緣裝置
操作紀錄
連線測試/重啟/更新/停用啟用/憑證變更的歷史紀錄,方便事後追查是誰在什麼時候對哪台裝置做了什麼操作。
尚無操作紀錄
🚀 佈署新的邊緣裝置(Jetson)
這裡是「現有 Jetson 掛了要換新機」或「要加第 2、3…台」時的完整
SOP。這個頁面只負責把指令組好方便複製,網頁本身不會替你連線
或執行任何東西——實際安裝仍在中控主機/新裝置的終端機進行,
理由是這一步要動到 root 權限、SSH 金鑰、WireGuard 設定,刻意不
讓網頁後端擁有這些權限(風險太集中,一旦網頁那層被攻破,後果會
從「資料被改」升級成「主機跟新裝置都被拿下」)。
前置需求(無法自動化,一定要先做一次)
- Jetson 已燒錄好 JetPack 6(L4T R36.4.4),可開機、先接乙太網路/區網(還不用先連 WireGuard)
- 佈署帳號(預設
korgsam)已建立、有 sudo 權限,且中控主機能用 SSH 金鑰登入這台新機器
- 知道這台 Jetson 目前的區網 IP(例如
192.168.1.50)
步驟 2:在新 Jetson 上執行 bootstrap
步驟 1 完成後會自動把設定跟原始碼 rsync 到目標機器,這裡執行的是收尾:依序裝好 WireGuard/mediamtx/edge-agent/whisper.cpp(M21 語音求救用)/edge-inference,並啟用對應的 systemd 服務讓它們開機自動啟動。整段約需 20-40 分鐘(edge-inference 那段要編譯 CUDA whisper.cpp + 下載模型,最久)。
步驟 3:驗證
- bootstrap 腳本結尾會自己做健康檢查,5 個服務都要顯示 ✓:
wg-quick@wg0 / mediamtx / ai-police-edge-agent / ai-police-whisper / ai-police-edge-inference
- 回到「🖥️ 邊緣運算」頁確認新裝置狀態變成 online(等下一次心跳,通常幾秒內)
- 在「邊緣運算」頁展開該裝置的「鏡頭」面板,登記實際接的鏡頭 RTSP URL、勾選要開的偵測模組(人流/武器/名單/槍聲/爆炸聲/車禍聲/語音求救)
疑難排解
SSH 進中控主機或新裝置後可以用這些指令查狀況:
ssh <目標SSH位址> journalctl -u ai-police-edge-inference.service -f --no-pager
ssh <目標SSH位址> systemctl status ai-police-edge-agent ai-police-edge-inference ai-police-whisper mediamtx wg-quick@wg0 --no-pager
完整原始碼在中控主機 /srv/projects/ai_police/ops/:provision-edge-device.sh(中控端協調)、jetson-bootstrap.sh(Jetson 端安裝,可重複執行)、templates/*.service(systemd unit 樣板)。這組腳本目前只在既有的 jetson-orin-01 上反推驗證過個別步驟,還沒有對一台全新機器跑過完整流程,第一次用時建議全程盯著、隨時能中斷排錯。
🎯 即時聲音雷達
D-003 擴充:USB 陣列麥克風的即時收音狀態。麥克風是線性陣列(一字排開),先天只能解析前方半圓(±90°),無法分辨正前方/正後方,相鄰間距是使用者現場量測的估計值(約 2 公分),方位角只能抓大致區間、不是精確角度。每 1 秒輪詢一次,不是即時串流。
🗺️ 地圖投影
裝置沒有 GPS,位置/朝向是人工在「邊緣運算」頁面設定的參考值(📍
按鈕)。紅色扇形是假設方向範圍,不是實測位置或距離
——這副陣列本來就沒有測距能力,扇形只是把方位角疊到地圖上方便
判斷大概往哪個街道方向找。
🎙️ 異常聲音錄音
槍聲/爆炸聲/車禍碰撞聲經 VLM 複核確認後,自動錄下觸發前後的音訊(預設前 3 秒+後 5 秒)。跟「最近事件」頁的對應事件用時間/類型/裝置對照即可,資料庫沒有強制關聯。
目前還沒有任何錄音
🕰️ 聲音事件時間軸
槍聲/爆炸聲/車禍碰撞聲三種音訊事件的歷史查詢,依時間/類型/鏡頭篩選。「視覺確認」欄是同一支鏡頭前後 10 秒內有沒有 M4/M5/M6 等視覺類危險事件也命中——兩者都命中可信度較高,但目前只做「音訊事件回頭找視覺事件」單方向比對,視覺事件比音訊晚到的情況不會補標記。「播放」是自動比對同裝置+同類型+前後 30 秒內最接近的錄音,資料庫沒有強制關聯,找不到是正常情況(不是每次事件都一定有錄到音)。
目前沒有符合條件的聲音事件
本地模型
跑在這台主機上的模型服務(例如 llm-gateway)。M5(暴力二次複核)/M7(VLM複核) 會呼叫「使用中」那一筆。
雲端模型
OpenAI 相容格式的雲端 API(OpenAI 本身、或其他相容服務)。M5(暴力二次複核)/M7(VLM複核) 會呼叫「使用中」那一筆——不管切成本地還是雲端,同一時間系統只有一筆是使用中的。
帳號清單
個別操作者帳號(2026-07-16 新增登入系統)。「管理員」可以管理帳號/建立其他人的帳號/重設別人的密碼;「操作員」可以使用所有監控功能,但這個清單跟下面「新增帳號」只有管理員看得到(會顯示「需要管理員權限」)。停用一個帳號不會刪除歷史稽核紀錄,只是讓那組帳密無法再登入(正在登入中的 session 要等最長 8 小時後才會真的失效)。「管理員」角色只要填了 Email,登入時會強制多一道 Email 驗證碼(2026-07-21 新增,見下方「Email OTP」欄),沒填就維持原本純帳密登入。
⚙️ 系統設定
登入頁面標題、登入後右上角標題、系統 logo——只有管理員能修改,變更後所有使用者(含登入頁面,未登入也看得到)立即生效,不用重新部署。留空欄位儲存=還原成預設文字。
系統 Logo
支援 PNG/JPEG/SVG/WebP,大小上限 2MB。沒有自訂 logo 時,標題前面顯示預設的 🚓 emoji。