visionA/local-tool/docs/LOCAL-TOOL-SPEC.md
jim800121chen 61f9b8bf6b docs(local-tool): 功能規格文件 LOCAL-TOOL-SPEC.md
涵蓋:
- 概述(三平台 + 完全離線安裝)
- Wails 控制台(5 階段啟動進度、timeout 機制、控制台功能、single-instance)
- Web UI(頁面路由、推論來源、結果顯示、模型管理、裝置管理、離線覆蓋層)
- 預設模型清單(KL520 × 4 + KL720 × 3)
- 內嵌依賴(Python/numpy/opencv/KneronPLUS/ffmpeg LGPL)
- Server API 摘要(系統/模型/裝置/媒體/WebSocket)
- M8 重構變更紀錄(15 個 commit 的完整 changelog)
- 資料目錄結構(三平台路徑 + 檔案說明)
- Build 指引(macOS/Windows/Linux)
- 除錯指引(Windows 啟動問題 + 常見問題)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
2026-04-16 14:46:09 +08:00

17 KiB
Raw Blame History

visionA Local Tool — 功能規格文件

版本v0.1.0-dev | 最後更新2026-04-16 | 對應 commit9793a2e

概述

visionA Local Tool 是 Kneron KL520 / KL720 邊緣 AI 推論硬體的本機桌面應用,讓使用者在完全離線的環境下,透過 USB 連接 Kneron 裝置,進行影像 / 影片 / 攝影機即時推論。

架構為 Wails 桌面 AppGo + Vanilla JS 控制台)+ Go HTTP Server + Next.js Web UI瀏覽器。Wails 控制台負責 server lifecycle 管理,瀏覽器 Web UI 負責裝置操作、模型管理、推論工作區。

三平台支援

平台 安裝格式 Build target
macOS (x86_64) .dmg make dmg
Windows (x64) .exe (Inno Setup) make exe
Linux (x86_64) .AppImage make appimage

完全離線安裝

所有依賴Python runtime、wheels、ffmpeg、ffprobe、.nef 模型)全部 vendor 進 installer安裝和執行過程不需要網路連線


1. Wails 控制台(桌面應用程式視窗)

1.1 啟動流程 — 5 階段進度面板

階段 名稱 做什麼
1 初始化控制台 建立 dataDir、舊資料遷移、single-instance lock、IPC server、首次啟動 seed複製內建模型到 user dataDir
2 檢查 Python 執行環境 偵測系統 Python → 或解壓內建 Python runtime首次啟動 ~1-3 分鐘)→ 建 venv → pip install wheelsnumpy/opencv/KneronPLUS 等 9 個套件)
3 啟動本機伺服器 spawn visiona-local-server subprocess → 等 health check 通過(首次啟動 Windows Defender 掃描可能需 1-2 分鐘)
4 偵測 Kneron 裝置 /api/devices 發一次 GET 確認 server 可 serve 業務 endpoint
5 開啟瀏覽器 自動開啟系統預設瀏覽器到 http://127.0.0.1:3721(可在設定中關閉)
  • 全屏 splashapp 啟動最一開始顯示 logo + spinner 全屏 overlay收到第一個 stage event 後切換到 5 階段面板
  • 每階段細步文案Go 端在每個 sub-step emit startup:stage-detail event前端即時顯示當前正在做什麼例如「正在解壓 Python runtime」「等待伺服器健康檢查通過」
  • 啟動完成自動收合5 階段全部完成後面板收合成一行 summary「✓ 啟動完成 · 點此展開檢視」,使用者點擊可展開歷史紀錄
  • 重啟 / 重試時重新展開:按「重新啟動伺服器」或「重試」會重置面板並完整重跑 5 階段
  • 前端 snapshot 補漏:前端 init 完成後呼叫 GetStartupSnapshot() 補上 race window 中漏掉的 stage events避免順序亂跳
  • Web UI 連線指示燈Stage 6「等待 Web UI 連線」從面板隱藏,改為 header 的 Web UI 連線指示燈(綠燈 = 已連線、黃燈 pulse = 等待中)

1.2 Timeout 機制

類型 時長 行為
每階段 soft timeout 20 秒 emit「正在重試...」提示,不中斷流程
整體 hard timeout 5 分鐘300 秒) 超過則 fail 進 Error state
首次 bootstrap pause 無上限 Stage 1 seed / Stage 2 Python bootstrap / Stage 3 waitHealthy 期間暫停 hard timeout 計時,不算進 5 分鐘 budget

1.3 控制台功能

  • 狀態列:顯示 server 狀態(閒置 / 啟動中 / 執行中 / 停止中 / 已停止 / 錯誤、port、PID、uptime、Web UI 連線狀態
  • 主要控制:在瀏覽器開啟 / 啟動 / 管理(停止 / 重新啟動 / 開啟 log 資料夾)
  • Log 面板server 即時 log 顯示、自動跟隨最新、關鍵字過濾、層級過濾All / INFO / WARN / ERROR、清空 / 複製 / 匯出 / 開啟 log 資料夾
  • Settings啟動時自動開啟瀏覽器macOS/Windows 預設 ON、Linux 預設 OFF、語言切換繁體中文 / English / Auto、關於資訊
  • Shutdown modalserver 停止時顯示「正在停止伺服器…」overlay15 秒 watchdog 自動 hide可用 Esc / 點 backdrop 手動關閉
  • Error 處理server 啟動失敗 → 紅 banner「伺服器無法啟動」+ 重試按鈕runtime crash → OS 原生通知 + Error state
  • i18n 雙語:繁體中文 + English全 UI 元素(含 stage 細步文案、設定、錯誤訊息)

1.4 Single-instance 保護

  • visiona-local.lock 檔案鎖 + PID 存活檢查
  • 第二次啟動偵測到已有 instance → 嘗試 IPC raise 把現有視窗提到前景 → 自己 quietly exit
  • Stale lockPID 已死)自動清理並取得新 lock

2. Web UI瀏覽器介面

2.1 頁面路由

路由 功能
/ 儀表板 — 已連接裝置列表、活動時間軸、統計卡片
/devices 裝置列表 — 掃描 / 連接 / 斷開 Kneron USB 裝置
/devices/[id] 裝置詳細 — 狀態、健康度、韌體版本、連線日誌、設定
/models 模型庫 — 7 個預設 .nef 模型KL520 × 4 + KL720 × 3+ 上傳自訂模型
/models/[id] 模型詳細 — metadata、支援硬體、效能數據
/workspace 工作區 — 選裝置 → 選模型 → 選來源 → 推論
/workspace/[deviceId] 單一裝置工作區 — 推論操作主介面
/settings 設定 — 語言、主題、其他偏好

2.2 推論來源

來源 說明
攝影機 (Camera) USB / IP Camera 即時串流推論
圖片 (Image) 上傳單張 JPG/PNG 做單次推論
影片 (Video) 上傳 MP4/AVI/MOV/MPEG/MPG 做逐幀推論ffmpeg 解碼)
批次圖片 (Batch Images) 上傳多張圖片逐張推論

2.3 推論結果顯示

  • MJPEG 即時串流/api/camera/stream 提供多客戶端 multipart MJPEG 串流
  • Canvas overlaybounding box + label + confidence 即時疊加
  • 推論面板FPS、平均延遲、信心度門檻調整、分類結果展示
  • 影片進度:目前幀 / 總幀、seek 跳轉
  • 批次進度:已處理 / 總張數、縮圖預覽

2.4 模型管理

  • 7 個預設模型NEF 格式、INT8 量化)
  • 上傳自訂 .nef 模型POST /api/models/upload
  • 刪除已上傳模型DELETE /api/models/:id
  • 模型篩選按任務類型object_detection / classification、硬體KL520 / KL720、關鍵字
  • 模型對比工具:並排比較兩個模型的規格

2.5 裝置管理

  • 掃描 USB 裝置:偵測已連接的 Kneron KL520 / KL720
  • 連接 / 斷開:連接時自動載入 firmwareKL520 USB Boot 流程)
  • 韌體更新flash .nef 到裝置 + 進度 WebSocket 即時回報
  • WinUSB 驅動安裝Windows only首次啟動自動透過 KneronPLUS SDK libwdi 安裝,需 UAC 提權

2.6 離線覆蓋層

  • Server 關閉 / 崩潰時,瀏覽器 tab 顯示 Offline Overlay
  • role=alertdialog + focus trap + WebSocket 重連機制
  • boot-id 偵測 server restart → 自動 reload含 reload loop guard

3. 預設模型

KL5204 個)

模型 ID 名稱 任務 輸入 FPS
kl520-yolov5-detection YOLOv5 Detection 物件偵測 640×640 ~20
kl520-fcos-detection FCOS Detection 物件偵測 512×512 ~22
kl520-ssd-face-detection SSD Face Detection 人臉偵測 320×240 ~100
kl520-tiny-yolov3 Tiny YOLOv3 物件偵測 416×416 ~28

KL7203 個)

模型 ID 名稱 任務 輸入 FPS
kl720-yolov5-detection YOLOv5 Detection 物件偵測 640×640 ~33
kl720-resnet18-classification ResNet18 Classification 分類1000 類) 224×224 ~100
kl720-fcos-detection FCOS Detection 物件偵測 512×512 ~33

4. 內嵌依賴

依賴 版本 用途 授權
Python 3.12.9 (python-build-standalone) Kneron Python bridge PSF
numpy 2.4.4 影像處理 BSD
opencv-python-headless 4.10.0 影像處理 Apache-2.0
KneronPLUS 2.0.0 Kneron SDK Python binding Kneron
pyusb 1.3.1 USB 裝置存取 BSD
requests 2.33.1 HTTP 工具 Apache-2.0
ffmpeg 自建 LGPL v3 decoder-only 影片解碼mp4/avi/mov/mpeg/mpg LGPL v3
ffprobe 同上 影片 metadata 提取 LGPL v3

ffmpeg LGPL 合規

macOS 版為自行編譯的最小 decoder-only build~5.7MB),只啟用必要的 demuxer/decoder/parser/filter無 --enable-gpl / libx264 / libx265,符合 LGPL v3。Windows/Linux 使用 BtbN 官方 LGPL 預編譯 binary。


5. Server API 摘要

系統

Method Path 說明
GET /api/system/health 健康檢查(高頻輪詢用,無 log
GET /api/system/info 版本、平台、uptime
GET /api/system/metrics Go runtime 記憶體統計
GET /api/system/deps 外部依賴檢查python/ffmpeg/ffprobe
GET /api/system/boot-id server 啟動 ID偵測 restart 用)
POST /api/system/restart 重啟 server
POST /api/system/install-driver 安裝 Kneron USB 驅動Windows only
POST /api/system/shutdown-notify 廣播關機通知到 WebSocket clients

模型

Method Path 說明
GET /api/models 列出所有模型(支援 filter
GET /api/models/:id 取得單一模型詳細
POST /api/models/upload 上傳自訂 .nef 模型
DELETE /api/models/:id 刪除已上傳模型

裝置

Method Path 說明
GET /api/devices 列出已偵測裝置
POST /api/devices/scan 掃描 USB 裝置
GET /api/devices/:id 取得裝置詳細
POST /api/devices/:id/connect 連接裝置
POST /api/devices/:id/disconnect 斷開裝置
POST /api/devices/:id/flash 燒錄韌體
POST /api/devices/:id/inference/start 啟動推論
POST /api/devices/:id/inference/stop 停止推論

媒體

Method Path 說明
GET /api/camera/list 列出可用攝影機
POST /api/camera/start 啟動攝影機推論 pipeline
POST /api/camera/stop 停止 pipeline
GET /api/camera/stream MJPEG 即時串流
POST /api/media/upload/image 上傳單張圖片推論
POST /api/media/upload/video 上傳影片逐幀推論
POST /api/media/upload/batch-images 批次上傳圖片推論
GET /api/media/batch-images/:index 取得批次中特定幀
POST /api/media/seek 影片 seek 跳轉

WebSocket

Path 說明
/ws/devices/events 裝置連接 / 斷開事件
/ws/devices/:id/flash-progress 韌體更新進度
/ws/devices/:id/inference 推論結果即時串流
/ws/server-logs server log 即時廣播
/ws/system 系統事件(含 shutdown-imminent

6. M8 重構變更紀錄2026-04-14 ~ 2026-04-16

以下是 M8 重構後的所有修復和改動,按時間排序:

架構變更R5 決策實作)

Commit 變更
8cd5751 M8 重構 — Wails 控制台 + 瀏覽器 Web UI:原 Wails 內嵌 Next.js 改為「Wails 控制台管理 server lifecycle + 瀏覽器開 Web UI」。砍 yt-dlpM8-1、砍 Mock 模式M8-2、ffmpeg LGPL vendorM8-3、ServerController v2 state machineM8-4、啟動階段管線 6 stage pipelineM8-4b、Wails 控制台 vanilla JS UIM8-5、Offline OverlayM8-7、CORS middlewareM8-8、shutdown broadcastMAJ-4、Boot-ID + tab 重連M8-9

Bug 修復

Commit 問題 修法
d7cddf3 預設模型永遠載入 0 個 — server 預設 dataDir 算錯models.json 找不到 builtInDataDirread-only bundlevs dataDirwritable user home新增 resolveBuiltInDataDir + findFirstExisting helper跨 macOS/Windows/Linux AppImage 五路徑自動偵測
a6cd1c1 Wails 控制台一打開就看到 Settings + shutdown-modal — CSS .modal-backdrop { display: flex } 覆蓋 user agent [hidden] { display: none } 全域 [hidden] { display: none !important; }
a209470 Windows 乾淨環境啟動失敗Stage 2 Python bootstrap > 60s StartupPipeline 加 PauseHardTimeout / ResumeHardTimeout API首次 bootstrap 不算入 hard timeout budget
c649a81 Stage 3 waitHealthy 也被 hard timeout 幹掉 waitHealthy 冷啟動時也 pausehealthCheckTimeout 30s → 180s
35db6c8 shutdown-modal「正在停止伺服器」popup 卡死 + Wails app stderr 在 Windows 上看不到 前端 15s watchdog + Esc/backdrop 可關 + stopGraceful hardBailout timer + appLog 覆蓋啟動流程關鍵訊息到 wails.log
d946561 Stage 順序亂跳Stage 1 等待中但 Stage 2 完成) 新增 GetStartupSnapshot() binding前端 init 後拉 snapshot 補漏 events + monotonic status rank 避免倒退
ad9beab Restart / Stop+Start 後 5 階段面板不更新 startInternal 進場偵測 pipeline 已完成/已失敗 → 自動 rebuildStartupPipeline 重建,didRebuild flag 分流 Stage 5 openBrowser
fbd585a Linux build 找不到 webkit2gtk-4.0 Makefile wails-linux 自動偵測 4.1 → -tags webkit2_41bootstrap-linux.sh 也做版本偵測
485a2e0 Linux build 找不到 appimagetool bootstrap-linux.sh 新增自動下載安裝 appimagetool

功能改善

Commit 變更
dd35b56 regen Wails bindingsM8 漏提的 binding 產物)
9c9e005 Stage 3 sub-step 細步進度 + 啟動完成後面板可收合
ff5cab6 hard timeout 放寬 + 全 stage 細步 detail emit13 個 i18n keys+ Stage 1 seed pause
f5655e3 hard timeout → 5 分鐘300s+ Stage 6 隱藏到 header 連線指示燈 + 全屏 splash overlay
9793a2e models.json 從 15 筆精簡為 7 筆(只保留有實體 .nef 的模型)

開發工具 / Bug A

Commit 變更
a209470 killStaleServerOnPort 改用 ps -o args= 識別 go run 產生的 server開發/Reviewer 測試用)

7. 資料目錄

平台 位置
macOS ~/Library/Application Support/visiona-local/
Windows %APPDATA%\visiona-local\
Linux ~/.config/visiona-local/$XDG_DATA_HOME/visiona-local/

目錄結構

visiona-local/
├── visiona-local.lock              # single-instance 鎖
├── visiona-local.ipc-port          # server port供 raise 用)
├── visiona-local.wails-ipc-port    # Wails IPC port
├── preferences.json                # 使用者偏好autoOpenBrowser / locale
├── models.json                     # 預設模型 catalog首次啟動從 bundle seed
├── nef/                            # 預設 .nef 模型檔(首次啟動從 bundle seed
│   ├── kl520/
│   └── kl720/
├── custom-models/                  # 使用者上傳的自訂模型
├── runtime/                        # Python runtime首次啟動解壓
│   ├── python/
│   └── venv/
├── logs/
│   ├── server.stdout.log           # server subprocess stdout
│   ├── server.stderr.log           # server subprocess stderr
│   └── wails.log                   # Wails app (appLog) 啟動流程日誌
└── .first-ws-connected             # WebSocket sentinel file啟動階段用

8. Build 指引

macOS

cd local-tool
make vendor-sync          # 下載 Python + wheels + 驗證 ffmpeg LGPL
make payload-macos        # 準備 payload/darwin/
make dmg                  # → dist/visiona-local.dmg (~163MB)

Windows需在 Windows 機器上)

cd local-tool
.\scripts\bootstrap-windows.ps1    # 安裝 Go / Node / pnpm / Wails / Python / MSYS2
make exe                            # → dist/visiona-local-*-windows-x64.exe

LinuxUbuntu 22.04+

cd local-tool
bash scripts/bootstrap-linux.sh    # 安裝所有依賴 + 自動 build
# 或手動:
make vendor-python-linux vendor-wheels-linux vendor-ffmpeg-linux
make payload-linux
make appimage                      # → dist/visiona-local-*-linux-x64.AppImage

9. 除錯指引

Windows 啟動問題

  1. 檢查 %APPDATA%\visiona-local\logs\wails.log
    • 第一行應有 fix marker: d946561+(確認 build 版本)
    • Stage 1-5 的細步文案會記錄每個 sub-step
  2. 檢查 server.stdout.log / server.stderr.log
  3. 如需更詳細的 Wails 端 log從命令列啟動
    "C:\Program Files\visiona-local\visiona-local.exe" > %TEMP%\wails-debug.txt 2>&1
    

常見問題

症狀 可能原因 解法
啟動 Stage 3 timeout Windows Defender 首次掃 .exe 等待,有 pause 機制不會 fail或加白名單
第二次啟動閃黑窗消失 前一次 crash 的 lock 殘留 visiona-local.lock
瀏覽器看不到裝置 USB 權限Linux/ WinUSB driver 沒裝 Linux: sudo bash install-udev.shWindows: 從 UI 點「安裝 Kneron USB 驅動程式」
模型庫是空的 首次啟動 seed 失敗 檢查 wails.log 的 seed 訊息;或手動複製 models.json + nef/ 從 installer 到 user dataDir