# Kneron Dongle PoC (Windows) - Strategy

## Scope (PoC)
- OS: Windows only.
- Devices: KL520, KL720.
- Control path: Browser -> localhost HTTP service -> KneronPLUS (kp wrapper + DLL).
- Non-goals: macOS/Linux support, production hardening, installer automation for all platforms.

## Required Installation (Windows)
Before running the local service, install Python dependencies and the KneronPLUS wheel.

### 1. Install dependencies from requirements
```powershell
cd local_service_win
python -m pip install -r requirements.txt
```

### 2. Install KneronPLUS wheel
```powershell
cd local_service_win
python -m pip install .\KneronPLUS-3.1.2-py3-none-any.whl
```

### 3. (Optional) Force reinstall KneronPLUS wheel
Use this when switching versions or seeing package mismatch issues.
```powershell
cd local_service_win
python -m pip install --force-reinstall .\KneronPLUS-3.1.2-py3-none-any.whl
```

## Cross-Project Workflow
This repo is the main PoC implementation. If additional references are required, we can switch to
other repos during the same conversation and return here as needed. This is workable.

## High-Level Architecture
- Browser UI
  - Talks to localhost HTTP service for control APIs.
  - Uses WebSocket for streaming inference.
  - No direct USB access from browser.
- Local Service (Windows)
  - Owns Kneron device lifecycle and IO.
  - Uses Python `kp` high-level API (backed by `libkplus.dll`).
  - Exposes HTTP endpoints for scan/connect/model/firmware/inference.
- KneronPLUS Runtime
  - `kp` Python wrapper + DLLs + required USB driver.
  - Version pinned inside installer to avoid mismatches.

## API Spec (PoC)
### Conventions
- Base URL: `http://127.0.0.1:4398`
- WebSocket URL: `ws://127.0.0.1:4398/ws`
- Response envelope:
  ```json
  {
    "ok": true,
    "data": {},
    "error": null
  }
  ```
  ```json
  {
    "ok": false,
    "data": null,
    "error": { "code": "KP_ERROR_CONNECT_FAILED", "message": "..." }
  }
  ```

### `GET /health`
Response
```json
{ "ok": true, "data": { "status": "up" }, "error": null }
```

### `GET /version`
Response
```json
{
  "ok": true,
  "data": {
    "service_version": "0.1.0",
    "kneronplus_version": "3.0.0"
  },
  "error": null
}
```

### `GET /devices`
Response
```json
{
  "ok": true,
  "data": {
    "devices": [
      {
        "scan_index": 0,
        "usb_port_id": 32,
        "product_id": 0x520,
        "link_speed": "High-Speed",
        "usb_port_path": "1-3",
        "kn_number": 12345,
        "is_connectable": true,
        "firmware": "KDP2"
      }
    ]
  },
  "error": null
}
```

### `POST /devices/connect`
Request
```json
{ "port_id": 32 }
```
Response
```json
{
  "ok": true,
  "data": {
    "connected": true,
    "port_id": 32
  },
  "error": null
}
```

### `POST /devices/disconnect`
Response
```json
{ "ok": true, "data": { "connected": false }, "error": null }
```

### `POST /firmware/load`
Request
```json
{
  "scpu_path": "C:\\path\\fw_scpu.bin",
  "ncpu_path": "C:\\path\\fw_ncpu.bin"
}
```
Response
```json
{ "ok": true, "data": { "loaded": true }, "error": null }
```

### `POST /models/load`
Request
```json
{ "nef_path": "C:\\path\\model.nef" }
```
Response
```json
{
  "ok": true,
  "data": {
    "model_id": 1,
    "input_tensor_count": 1,
    "output_tensor_count": 1
  },
  "error": null
}
```

### `POST /models/clear`
Notes
- PoC uses device reset to clear RAM model.
Response
```json
{ "ok": true, "data": { "cleared": true }, "error": null }
```

### `POST /models/reset`
Notes
- Alias of `/models/clear`, uses device reset to clear RAM model.
Response
```json
{ "ok": true, "data": { "reset": true }, "error": null }
```

### `POST /inference/run`
Request (image inference, single image)
```json
{
  "model_id": 1,
  "image_format": "RGB888",
  "width": 224,
  "height": 224,
  "image_base64": "..."
}
```
Response
```json
{
  "ok": true,
  "data": {
    "outputs": [
      { "node_idx": 0, "dtype": "float", "shape": [1, 1000], "data_base64": "..." }
    ]
  },
  "error": null
}
```

### `WS /ws` (streaming inference)
Notes
- For camera/video stream, use WebSocket for low-latency send/receive.
- HTTP endpoints remain for control operations during PoC.
Message (client -> server)
```json
{
  "type": "inference_frame",
  "model_id": 1,
  "image_format": "RGB888",
  "width": 224,
  "height": 224,
  "image_base64": "..."
}
```
Message (server -> client)
```json
{
  "type": "inference_result",
  "outputs": [
    { "node_idx": 0, "dtype": "float", "shape": [1, 1000], "data_base64": "..." }
  ]
}
```

### `POST /firmware/update`
- Reserved for flash update (later; may need C wrapper).

## Packaging (PoC)
- Single Windows installer:
  - Includes driver, `kp` wrapper, DLLs, and service.
  - Ensures fixed versions (no external Kneron tools required).
  - Reference from `C:\Users\user\Documents\KNEOX\README.md`:
    - Install KneronPLUS wheel from `external/kneron_plus_{version}/package/{platform}/`
    - `pip install KneronPLUS-{version}-py3-none-any.whl` (use `--force-reinstall` if needed)
    - PyInstaller must bundle `kp\lib` with the app.
    - Example:
      ```shell
      pyinstaller --onefile --windowed main.py --additional-hooks-dir=hooks --add-data "uxui;uxui" --add-data "src;src" --add-data "C:\path\to\venv\Lib\site-packages\kp\lib;kp\lib"
      ```

## Risks / Constraints
- Flash model update / flash firmware update may not be exposed in Python.
  - Use C library or request Kneron to expose in wrapper if required.
- Browser security model prevents direct USB access; local service is required.

## API Test Progress (Windows PoC)
### Completed
- `GET /health`
- `GET /version`
- `GET /devices`
- `POST /devices/connect`
- `POST /devices/disconnect`

### Pending
- `POST /firmware/load`
- `POST /models/load`
- `POST /models/clear`
- `POST /models/reset`
- `POST /inference/run`
- `WS /ws`
- `POST /firmware/update`

### Paired Test Requirement
- `POST /models/load` and `POST /inference/run` must be tested as a pair in the same flow.
- Test pairs are defined in `local_service_win/TestRes/TEST_PAIRS.md`.

### Model/Inference Test Pairs
#### KL520
1. YOLOv5 (model zoo)
   - Model: `kl520_20005_yolov5-noupsample_w640h640.nef`
   - Image: `one_bike_many_cars_800x800` (Base64)
2. FCOS (model zoo)
   - Model: `kl520_20004_fcos-drk53s_w512h512.nef`
   - Image: `one_bike_many_cars_800x800` (Base64)
3. Tiny YOLO v3 (generic demo)
   - Model: `models_520.nef`
   - Image: `bike_cars_street_224x224` (Base64)
4. Tiny YOLO v3 (multithread demo)
   - Model: `models_520.nef`
   - Image: `bike_cars_street_224x224` (Base64)

#### KL720
1. YOLOv5 (model zoo)
   - Model: `kl720_20005_yolov5-noupsample_w640h640.nef`
   - Image: `one_bike_many_cars_800x800` (Base64)
2. FCOS (model zoo)
   - Model: `kl720_20004_fcos-drk53s_w512h512.nef`
   - Image: `one_bike_many_cars_800x800` (Base64)

## Next Steps (After Strategy)
- Confirm endpoint payloads (JSON schema).
- Decide service framework (FastAPI/Flask).
- Define error model and device state machine.
- Plan installer workflow (driver + service).
