# KNEO Academy(Innovedus AI Playground)v2.0 — 產品需求文件(PRD) > **文件性質說明**:本 PRD 為從既有程式碼與文件反向整理而成,已對照 README.md、flowchart.md、主要 controller、view 和 service 原始碼推導。標注「⚠️ 待確認」的項目為推斷內容,請產品負責人核實。 --- ## 1. 產品概述 ### 1.1 產品定位 **KNEO Academy**(對外名稱:**Innovedus AI Playground**)是一款 Windows 桌面應用程式,讓擁有 Kneron NPU USB Dongle 硬體的客戶能夠在本機端執行 AI 推論,無需雲端服務、無需自行撰寫程式碼。 **核心價值主張**: - 即插即用的 Edge AI 體驗——插上 Kneron dongle 即可執行 AI 模型 - 支援多種推論模式(即時攝影機、圖片上傳、自定義模型) - 透過 Plugin 系統讓第三方或 Kneron 官方模型能被彈性載入 - 提供硬體管理工具(韌體更新、驅動安裝、裝置授權) ### 1.2 目標使用者 **主要使用者(Persona A):企業/研發客戶** - 角色:使用 Kneron NPU 硬體進行 AI PoC 或產品評估的工程師、研究人員 - 目標:快速驗證 Kneron NPU 在特定任務上的推論效果 - 技術素養:中等(懂 AI 概念,不一定熟悉 SDK 整合) - 痛點:Kneron SDK 入門門檻高,想要一個能快速展示能力的工具 **次要使用者(Persona B):內部 Demo / 業務展示** - 角色:Kneron / Innovedus 業務或技術支援人員 - 目標:向潛在客戶展示 Kneron NPU 的 AI 推論能力 - 技術素養:低至中等 - 痛點:需要一個無需開發、開箱即用的展示工具 **⚠️ 待確認**:上述 Persona 定義是從產品功能推斷。實際目標客群請與產品負責人確認。 ### 1.3 應用名稱對照 | 名稱 | 用途 | |------|------| | KNEO Academy | 專案內部/開發用名稱 | | Innovedus AI Playground | 對外正式名稱(`APP_NAME` 常數定義) | --- ## 2. 支援的硬體裝置 應用程式目前支援以下 Kneron NPU Dongle 型號(來自 `config.py` 的 `DeviceType` Enum): | 裝置型號 | Product ID(Hex) | 支援狀態 | |---------|-----------------|---------| | KL520 | 0x100 | ✅ 已支援(有 icon、model map) | | KL720 | 0x720 | ✅ 已支援(有 icon、model map) | | KL720_L | 0x200 | ⚠️ Enum 有定義,但無 DongleModelMap 對應,**可能不完整** | | KL530 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 | | KL832 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 | | KL730 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 | | KL630 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 | | KL540 | — | ⚠️ Enum 有定義,但無 DongleModelMap 對應 | **⚠️ 待確認**:KL520 和 KL720 以外的裝置是否已在計畫中支援?`DongleModelMap` 僅有這兩型。 --- ## 3. 應用程式頁面架構 ### 3.1 頁面流程圖 ``` 應用程式啟動 │ ▼ SelectionScreen(首頁 / 入口選擇畫面) ├── [Demo App 按鈕] ──────────────────→ MainWindow(AI Demo 推論主視窗) └── [Utilities 按鈕] → LoginScreen(登入畫面) │ ├── [登入成功] → UtilitiesScreen(裝置管理工具) └── [返回] → SelectionScreen ``` ### 3.2 各頁面功能摘要 | 頁面 | Class 名稱 | 主要用途 | 需要登入 | |------|-----------|---------|---------| | 首頁 | `SelectionScreen` | 選擇進入 Demo App 或 Utilities 工具 | 否 | | 登入畫面 | `LoginScreen` | Server 驗證,作為進入 Utilities 的門禁 | — | | 裝置管理工具 | `UtilitiesScreen` | 裝置掃描、韌體更新、驅動安裝、已購項目 | 是 | | AI Demo 主視窗 | `MainWindow` | AI 推論執行、攝影機顯示、工具選擇 | 否 | --- ## 4. 功能需求 ### 4.1 SelectionScreen(首頁選擇畫面) **功能描述**:應用程式的入口,提供兩個主要路徑。 **功能清單**: - 顯示應用程式 Logo 與名稱 - 「Demo App」按鈕:直接進入 AI 推論主視窗(不需登入) - 「Utilities」按鈕:跳轉到登入畫面,登入後才能進入裝置管理工具 **⚠️ 待確認**:首頁是否有其他 UI 元素(介紹文字、版本號等)? --- ### 4.2 LoginScreen(登入畫面) **功能描述**:透過 Server 驗證機制保護 Utilities 功能的存取。 **功能清單**: - 帳號密碼輸入欄位 - 登入按鈕 → 觸發 Server 驗證 - 返回按鈕 → 回到 SelectionScreen **登入結果處理**: | 情境 | 行為 | |------|------| | 驗證成功 | 發出 `login_success` signal → 進入 UtilitiesScreen | | 帳密錯誤 | 顯示「無效用戶名或密碼」提示 | | 多次錯誤 | Server 停止服務,顯示提示訊息 | | 返回 | 發出 `back_to_selection` signal → 回到 SelectionScreen | **⚠️ 待確認**: - 登入 Server 的端點 URL 在哪裡設定?(程式碼中未見明確設定) - 是否有記住密碼/Token 快取機制? --- ### 4.3 UtilitiesScreen(裝置管理工具頁面) **功能描述**:登入後才能存取的裝置管理介面,包含兩個子頁面。 #### 4.3.1 Utilities 子頁面(裝置管理) **功能清單**: **裝置掃描與列表** - 掃描當前連接的 Kneron dongle 裝置(呼叫 `check_available_device()`,含 5 秒 timeout) - 以表格(`QTableWidget`)顯示裝置清單,欄位包含:裝置型號、KN Number、狀態 - 「Refresh」按鈕:重新掃描裝置 - 未偵測到裝置時顯示提示 **裝置連接操作** - 選擇裝置後可執行連接(透過 `DeviceController.connect_device()`) - 連接過程: 1. 驗證 firmware 檔案是否存在(`%LOCALAPPDATA%/Kneron_Academy/firmware/{device}/`) 2. 呼叫 `kp.core.connect_devices()` 3. 上傳 firmware(`fw_scpu.bin` + `fw_ncpu.bin`) - 中斷連接按鈕(`DeviceController.disconnect_device()`) **Firmware 管理** - 顯示目前 Firmware 版本 - 偵測到版本需要更新時,提示使用者是否更新 - 支援從本機載入 firmware 檔案進行更新 **Driver 管理**(⚠️ 設計中,尚未完整實作) - 偵測 Kneron USB driver 是否已安裝 - 尚未安裝時:提示安裝,詢問使用者是否執行安裝程序 - 安裝失敗處理:顯示錯誤訊息 **Dongle 授權管理**(⚠️ 設計中,尚未完整實作) - 查詢 KN Number(Dongle 唯一識別號) - 授權卡(Authorization Card)驗證流程 - 已授權裝置:顯示已授權提示 - 未授權裝置:詢問是否啟動授權,執行授權流程 - **詳細流程見 `flowchart.md`** **狀態顯示** - `QProgressBar`:顯示操作進度(連接、韌體上傳等) - `QLabel`(status_label):顯示目前狀態訊息 #### 4.3.2 Purchased Items 子頁面(已購項目) **功能描述**:顯示用戶已購買的 AI 模型,可以下載到本機。 **功能清單**: - 表格顯示已購買項目,欄位:Select(勾選)、Product(產品名)、Model(模型名)、Current Version(版本)、Compatible Dongles(相容裝置) - 多選(Checkbox)功能 - 「Refresh Items」按鈕:重新從 Server 取得已購列表 - 「Download Selected」按鈕:下載所選項目到本機 **⚠️ 待確認**: - 目前程式碼中有 `populate_mock_purchased_items()` 方法,顯示此功能使用 Mock 資料,**尚未對接真實 API** - 下載後的模型存放路徑?(推斷為 `%LOCALAPPDATA%/Kneron_Academy/utils/`) - 購買平台/Store 是否已確定? --- ### 4.4 MainWindow(AI Demo 推論主視窗) **功能描述**:核心的 AI 推論展示視窗,整合攝影機顯示、工具選擇與推論結果呈現。 #### 4.4.1 畫面布局組件 | 組件 | Class 名稱 | 功能 | |------|-----------|------| | 攝影機顯示區 | `CanvasArea` | 顯示攝影機畫面和推論結果(Bounding Box 等) | | 裝置清單 | `DeviceList` | 顯示可連接的 dongle,讓使用者選擇 | | 裝置連接彈窗 | `DevicePopup` | 彈出式裝置連接確認介面 | | 媒體控制面板 | `MediaPanel` | 攝影機開啟/暫停、圖片上傳按鈕 | | AI 工具箱 | `Toolbox` | 顯示可選擇的 AI 模型(來自 config.json) | | 自定義模型上傳 | `CustomModelBlock` | 上傳自定義 .nef 模型的 UI | #### 4.4.2 AI 推論模式 ##### 模式一:Video 模式(即時攝影機推論) **流程**: 1. 使用者選擇 Video 類型的 AI 工具 2. 呼叫 `MediaController.start_camera()` 啟動相機 3. `VideoThread` 持續擷取影像幀(640×480, 30fps),轉為 QImage 發出 signal 4. 影像幀轉為 NumPy 陣列後,透過 `InferenceController.add_frame_to_queue()` 放入推論 queue(最大容量:5 幀) 5. `InferenceWorkerThread` 從 queue 取出影像幀,呼叫對應的 `script.py` 執行推論 6. 推論結果透過 `inference_result_signal` 傳回主視窗 7. 主視窗在 `CanvasArea` 上繪製 Bounding Box 等視覺化結果 **效能優化機制**: - MSE(Mean Squared Error)幀差異偵測:若連續幀的 MSE 低於 `mse_threshold=500`,沿用上一次推論結果(避免重複計算靜止畫面) - 最短推論間隔:`min_interval=2` 秒(標準模式) - 模型超時設定:`MODEL_TIMEOUT = 5000` ms(`config.py`) ##### 模式二:Image 模式(上傳圖片單次推論) **流程**: 1. 使用者選擇 Image 類型的 AI 工具 2. 使用者透過 `MediaPanel` 上傳圖片(存入 `%LOCALAPPDATA%/Kneron_Academy/uploads/`) 3. 使用 `cv2.imread()` 讀取圖片,放入推論 queue(`once_mode=True`,只推論一次) 4. `InferenceWorkerThread` 執行推論並回傳結果 5. 切換到 Image 模式時,相機信號會暫時斷開(非停止),以避免 Video 模式的幀繼續進入 queue **注意**:切回 Video 工具時,相機信號會重新連接,無需重新開啟相機。 ##### 模式三:Custom Model(使用者自定義模型) **流程**: 1. 使用者透過 `CustomModelBlock` 上傳以下三個檔案: - `.nef` 模型檔 - `fw_scpu.bin`(SCPU firmware) - `fw_ncpu.bin`(NCPU firmware) - (可選)自定義標籤清單(class labels) 2. `InferenceController.select_custom_tool()` 被呼叫 3. 啟動 `CustomInferenceWorkerThread`(與標準 worker 不同的實作) 4. Custom worker 會在首次推論時自行完成: - 連接裝置(`kp.core.connect_devices()`) - 上傳 firmware - 上傳模型(`kp.core.load_model_from_file()`) 5. 預處理:影像縮放至 640×640,轉為 BGR565 格式 6. 後處理:使用 YOLOv5 演算法(NMS threshold=0.5)解析輸出 7. 若有提供自定義標籤,使用自定義標籤;否則使用預設 COCO 80 類別 **Custom Model 預設行為**: - 輸入類型:Video(即時攝影機) - 後處理演算法:固定使用 YOLOv5(**⚠️ 待確認**:是否計畫支援其他後處理演算法?) - 預設偵測閾值:`thresh=0.2` - 推論間隔:`min_interval=0.5` 秒(比標準模式更頻繁) #### 4.4.3 裝置相容性檢查 當使用者選擇 AI 工具時: - 讀取 `config.json` 中的 `compatible_devices` 欄位 - 比對目前選中的 dongle 型號 - 若不相容,彈出警告對話框並阻止推論啟動 --- ### 4.5 Plugin 系統(Script & Model 配置) **功能描述**:透過設定檔驅動的 Plugin 架構,讓 AI 模型能被動態載入,無需修改應用程式原始碼。 #### 4.5.1 檔案結構 ``` %LOCALAPPDATA%/Kneron_Academy/ ├── uploads/ # 使用者上傳的圖片/影片 ├── utils/ │ ├── config.json # 全域 plugin 設定(必要) │ └── {mode}/ # 推論模式資料夾(e.g., face_recognition) │ └── {model}/ # 模型資料夾(e.g., face_detection) │ ├── config.json # 模型設定(必要) │ ├── script.py # 推論腳本(必要) │ └── *.nef # 模型檔(必要) └── firmware/ └── {device}/ # 裝置型號資料夾(e.g., KL520) ├── fw_scpu.bin └── fw_ncpu.bin ``` #### 4.5.2 全域 config.json 格式 ```json { "plugins": [ { "mode": "face_recognition", "display_name": "人臉辨識", "models": [ { "name": "face_detection", "display_name": "人臉偵測 (ResNet-18)", "description": "基於ResNet-18的高精度人臉偵測", "compatible_devices": ["KL520", "KL720"] } ] } ] } ``` #### 4.5.3 模型 config.json 格式 ```json { "display_name": "人臉偵測 (ResNet-18)", "description": "使用ResNet-18架構的高精度人臉偵測模型", "model_file": "face_detection.nef", "input_info": { "type": "video", "supported_formats": ["mp4", "avi", "webm"] }, "input_parameters": { "threshold": 0.75, "max_faces": 10, "tracking": true }, "compatible_devices": ["KL520", "KL720"] } ``` **`input_info.type` 的有效值**: - `"video"` — 啟動攝影機進行即時推論 - `"image"` — 使用者上傳圖片進行單次推論 - `"voice"` — 音訊輸入模式(⚠️ **程式碼中有對應處理路徑但未見完整實作**) #### 4.5.4 script.py 介面規範 `InferenceWorkerThread` 會動態 import 各模型的 `script.py`。 **⚠️ 待確認(重要)**:`script.py` 的標準介面(函數名稱、參數格式、回傳格式)目前無正式文件。 從 `InferenceWorkerThread` 的呼叫方式推斷: - `script.py` 應提供一個可被 worker 呼叫的推論函數 - 接收 `input_params` 字典(包含 `usb_port_id`、`device_group`、`model`、`scpu_path`、`ncpu_path`、`file_path` 等) - 回傳 Bounding Box 結果,格式為: ```json { "num_boxes": 2, "bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]], "results": ["label1", "label2"] } ``` --- ## 5. 非功能需求 ### 5.1 效能需求 | 項目 | 規格 | 來源 | |------|------|------| | 推論 Queue 大小 | 最大 5 幀 | `InferenceController.__init__` | | 標準模式最短推論間隔 | 2 秒 | `InferenceController.select_tool()` | | Custom Model 最短推論間隔 | 0.5 秒 | `InferenceController.select_custom_tool()` | | 模型推論超時 | 5,000 ms | `config.py MODEL_TIMEOUT` | | 裝置掃描超時 | 5 秒 | `device_service.check_available_device()` | | 攝影機開啟超時 | 5 秒 / 最多 3 次嘗試 | `VideoThread._camera_timeout` | | 攝影機解析度 | 640×480 | `VideoThread.run()` | | 攝影機目標幀率 | 30 fps | `VideoThread.run()` | | Custom Model 輸入大小 | 640×640 | `custom_inference_worker.preprocess_frame()` | | 模型推論設備超時(Custom) | 5,000 ms | `CustomInferenceWorkerThread.initialize_device()` | ### 5.2 平台相容性 | 項目 | 規格 | |------|------| | 作業系統 | Windows(使用 `%LOCALAPPDATA%`,PowerInstaller 打包) | | Python 版本 | Python 3.12 | | 視窗尺寸 | 1200×900 像素(固定,`WINDOW_SIZE` 常數) | **⚠️ 待確認**:是否計畫支援 macOS 或 Linux?目前路徑處理和打包設定為 Windows 專屬。 ### 5.3 應用程式打包 | 項目 | 工具 | 狀態 | |------|------|------| | 打包工具 | PyInstaller 6.12.0 | ✅ 已設定 | | 安裝包製作 | Inno Setup(`dist/test.iss`) | ✅ 有設定檔 | | 程式碼加密 | PyArmor | ⚠️ 計畫中 | **打包注意事項**: - 需要包含 KneronPLUS SDK 的 `kp/lib` 資料夾 - 需包含 `uxui/` 資源目錄和 `src/` 目錄 ### 5.4 資料儲存 所有執行期資料存放於 `%LOCALAPPDATA%/Kneron_Academy/`: - **uploads/**:使用者上傳的圖片/影片 - **utils/**:Plugin 設定與模型檔案 - **firmware/**:裝置韌體檔案 **⚠️ 待確認**:安裝包是否會預先建立這些目錄,或由應用程式首次執行時自動建立? --- ## 6. 裝置連接與授權流程(詳細) 根據 `flowchart.md` 的設計(⚠️ 此流程尚未完整實作於程式碼中,為設計規格): ``` 登入畫面 │ ▼ Server 驗證(帳密驗證) ├── 成功 → 進入 Dongle 模組畫面 └── 失敗 → 顯示錯誤(帳密錯誤 / 服務被暫停) Dongle 模組畫面 │ ▼ 連接 Dongle ├── 未偵測到 → 顯示「未偵測到裝置」提示 └── 偵測到 → 檢查 Driver 是否安裝 Driver 檢查 ├── 已安裝 → 檢查 FW 版本 └── 未安裝 → 詢問是否安裝 Driver ├── 使用者同意 → 執行安裝(可能失敗) └── 失敗 → 顯示錯誤 FW 版本檢查 ├── 版本符合 → 取得 Dongle KN Number └── 需要更新 → 詢問是否更新 FW ├── 使用者同意 → 下載並安裝 FW └── 失敗 → 顯示錯誤 取得 KN Number └── 成功 → 檢查授權狀態 授權狀態檢查 ├── 已授權 → 顯示已授權提示 → 回到 App 主頁 └── 未授權 → 詢問是否啟動授權 ├── 使用者同意 → 執行授權流程 │ ├── 成功 → 顯示成功提示 → 回到主頁 │ └── 失敗 → 顯示失敗提示 └── 使用者不重試 → 顯示提示 → 回到主頁 ``` --- ## 7. 已知限制與未完成功能 以下為從程式碼分析發現的限制與尚未完成的功能: ### 7.1 尚未完整實作 | 功能 | 狀態 | 說明 | |------|------|------| | 登入 Server 驗證 | 🔄 部分實作 | `LoginScreen` 存在,但 Server 端點設定不明確 | | Driver 自動安裝 | 🔄 設計中 | `flowchart.md` 有設計,程式碼中未見完整實作 | | Dongle 授權管理 | 🔄 設計中 | `flowchart.md` 有設計,程式碼中未見完整實作 | | 音訊(voice)推論模式 | 🔄 設計中 | `config.py` 有引入 `librosa`、`sounddevice`,但推論路徑不完整 | | Purchased Items API 對接 | 🔄 Mock 資料 | `utilities_screen.py` 有 `populate_mock_purchased_items()` 方法,使用假資料 | | 程式碼加密(PyArmor) | ⏳ 計畫中 | 僅列在 `env.txt`,尚未見到具體加密流程 | | KL520/KL720 以外裝置支援 | ⏳ 計畫中 | `DeviceType` enum 有定義,但 `DongleModelMap` 僅有這兩型 | ### 7.2 已知技術問題 | 問題 | 嚴重度 | 說明 | |------|--------|------| | Debug print 語句殘留 | 低 | 多個 controller 中有大量 `print()` debug 訊息 | | 錯誤處理不完整 | 中 | 部分 try/except 只 print 不處理(如 `device_controller.py`) | | 測試覆蓋率為零 | 高 | 完全沒有自動化測試 | | UI 更新 Thread 安全性 | 中 | 待確認推論結果回傳到主線程的路徑是否完全使用 Qt Signal | | `custom_inference_worker.py` 中引用未導入的 `kp` | 中 | `_boxes_scale()` 和 `post_process_yolo_v5()` 在模組頂層使用 `kp.HwPreProcInfo` 等型別,但 `import kp` 在函數內才執行 | ### 7.3 設計假設(未驗證) - Custom Model 後處理固定使用 YOLOv5,未提供自定義後處理的擴充機制 - 應用程式假設攝影機 index 為 0(第一個相機),無法選擇其他相機 - 應用程式固定使用 Windows 路徑格式,不支援跨平台 --- ## 8. 功能優先級(RICE 分析) > ⚠️ 以下 RICE 分數為從現有程式碼功能狀態推斷,Effort 值基於程式碼完成度估算。**請與產品負責人及開發團隊確認 Reach、Impact 和 Confidence 的實際數值。** | 功能 | Reach | Impact | Confidence | Effort(人天) | RICE 分數 | 階段 | |------|-------|--------|------------|--------------|----------|------| | Video 模式推論 | 100% | 3 | 90% | — | 高 | ✅ 已完成 | | Image 模式推論 | 90% | 2 | 90% | — | 高 | ✅ 已完成 | | Plugin 系統(config.json) | 100% | 3 | 85% | — | 高 | ✅ 已完成 | | Custom Model 推論 | 60% | 3 | 80% | — | 中高 | ✅ 已完成 | | 裝置掃描 / 連接 | 100% | 3 | 90% | — | 高 | ✅ 已完成 | | 登入驗證(完整實作) | 100% | 3 | 70% | 5 | 高 | 🔄 進行中 | | Dongle 授權管理 | 100% | 3 | 65% | 10 | 高 | 🔄 設計中 | | Purchased Items API 對接 | 80% | 2 | 70% | 7 | 中 | 🔄 設計中 | | Driver 自動安裝 | 70% | 2 | 60% | 5 | 中 | 🔄 設計中 | | 音訊推論模式 | 40% | 2 | 50% | 10 | 低中 | ⏳ 待實作 | | 多攝影機選擇 | 30% | 1 | 70% | 3 | 低 | ⏳ 未排期 | | 跨平台支援(macOS/Linux) | 50% | 2 | 50% | 20 | 中 | ⏳ 未排期 | --- ## 9. 輸入資料格式規範 ### 9.1 攝影機影像 - 擷取方式:OpenCV `cv2.VideoCapture`,DirectShow backend(Windows 優先) - 解析度:640×480 - 格式:`QImage.Format_RGB888`(透過 `VideoThread` 發出),後轉為 NumPy 陣列 `(height, width, 3)`,通道順序 RGB888 ### 9.2 上傳圖片 - 讀取方式:`cv2.imread()` - 格式:NumPy 陣列,BGR 格式(OpenCV 預設) - 儲存位置:`%LOCALAPPDATA%/Kneron_Academy/uploads/` ### 9.3 Custom Model 輸入(預處理後) - 目標大小:640×640 - 格式:BGR565(`cv2.COLOR_BGR2BGR565`) ### 9.4 input_params 字典格式 `InferenceWorkerThread` 接收的 `input_params` 標準結構: ```python { "usb_port_id": 32, # Dongle USB port ID "device_group": , # 已連接的裝置群組物件 "scpu_path": "...\\firmware\\KL520\\fw_scpu.bin", "ncpu_path": "...\\firmware\\KL520\\fw_ncpu.bin", "fw_folder": "...\\firmware", # 全域 firmware 目錄 "file_path": "...\\uploads\\image.jpg", # 圖片模式使用 "model": "...\\utils\\{mode}\\{model}\\{model_file}.nef", "model_descriptor": , # 已上傳的模型描述符 # 以下為 config.json 中的 input_parameters 欄位(由模型設定決定) "threshold": 0.75, "max_faces": 10, ... } ``` --- ## 10. 推論結果輸出格式 `script.py` 回傳或 `CustomInferenceWorkerThread` 發出的標準推論結果: ```json { "num_boxes": 2, "bounding boxes": [[x1, y1, x2, y2], [x3, y3, x4, y4]], "results": ["label1", "label2"] } ``` 其中座標為絕對像素值,對應原始影像尺寸(非縮放後的模型輸入尺寸)。 --- ## 11. 安裝需求 ### 11.1 開發環境安裝 ```shell # 1. 安裝 KneronPLUS SDK cd ./external/kneron_plus_{version}/package/{platform}/ pip install KneronPLUS-{version}-py3-none-any.whl # 2. 安裝其他依賴 pip install PyQt5 opencv-python pyinstaller pyarmor # 3. 執行應用程式 python main.py ``` ### 11.2 打包指令 ```shell pyinstaller --onefile --windowed main.py \ --additional-hooks-dir=hooks \ --add-data "uxui;uxui" \ --add-data "src;src" \ --add-data "{conda_env}\\Lib\\site-packages\\kp\\lib;kp\\lib" ``` --- ## 12. 風險與緩解措施 | 風險 | 可能性 | 影響 | 緩解措施 | |------|--------|------|----------| | `script.py` 介面無標準文件,第三方難以開發 Plugin | 高 | 高 | 盡速制定並文件化 `script.py` 介面規範 | | Purchased Items 功能仍是 Mock 資料,影響客戶體驗 | 中 | 高 | 確認後端 API 規格,完成對接 | | 缺乏自動化測試,難以安全重構 | 高 | 中 | 補齊關鍵路徑的 unit test(推論 queue、裝置連接) | | `custom_inference_worker.py` 的 `kp` 引入問題,可能在非 kp 環境崩潰 | 中 | 中 | 修復模組頂層的型別引用問題 | | 硬體相依性強,無 dongle 時無法測試核心功能 | 高 | 中 | 建立 Mock/Stub 的 kp 測試層 | | Windows 專屬設計,未來擴展平台成本高 | 低 | 中 | 現階段維持 Windows 優先,抽象化路徑處理為未來鋪路 | --- ## 附錄 A:程式碼結構快速參照 | 模組 | 路徑 | 功能 | |------|------|------| | `AppController` | `main.py` | 應用程式入口,管理 QStackedWidget 頁面切換 | | `SelectionScreen` | `src/views/selection_screen.py` | 首頁選擇畫面 | | `LoginScreen` | `src/views/login_screen.py` | 登入驗證畫面 | | `UtilitiesScreen` | `src/views/utilities_screen.py` | 裝置管理工具頁面 | | `MainWindow` | `src/views/mainWindows.py` | AI 推論主視窗 | | `DeviceController` | `src/controllers/device_controller.py` | 裝置掃描、連接、中斷 | | `InferenceController` | `src/controllers/inference_controller.py` | 推論工具選擇、queue 管理 | | `MediaController` | `src/controllers/media_controller.py` | 攝影機操作 | | `InferenceWorkerThread` | `src/models/inference_worker.py` | 標準推論 Worker(動態載入 script.py) | | `CustomInferenceWorkerThread` | `src/models/custom_inference_worker.py` | Custom Model 推論 Worker(YOLOv5 後處理) | | `VideoThread` | `src/models/video_thread.py` | 攝影機影像擷取 Thread | | `check_available_device()` | `src/services/device_service.py` | 含 timeout 的裝置掃描服務 | | `DeviceType`, `DongleModelMap` | `src/config.py` | 支援裝置型號列舉與對應表 | --- *本 PRD 版本:v1.0(從程式碼反推)* *建立日期:2026-04-04* *建立者:PM Agent(Autoflow)* *狀態:待產品負責人確認標注「⚠️ 待確認」的項目*