# Sensor Bench EXE Build This folder contains Windows PyInstaller build setups for: - **Public** exhibition app → `dist/SensorBench/` - **Private** operator app → `dist/SensorBenchOperator/` (internal use only) ## Requirements - Windows x64 - Anaconda or Miniconda available as `conda` - Python 3.10 build environment - Internet access to install `orisys` from PyPI The build installs `orisys` from PyPI. Do not use `PYTHONPATH` or an editable `orisys-sdk` checkout for release builds. ## Build From the repository root (cmd or PowerShell): ```bat .\build\create_env.bat .\build\build_exe.bat ``` The `.bat` wrappers bypass the local PowerShell execution policy. If you prefer calling PowerShell directly: ```bat powershell -NoProfile -ExecutionPolicy Bypass -File .\build\create_env.ps1 powershell -NoProfile -ExecutionPolicy Bypass -File .\build\build_exe.ps1 ``` Output: ```text dist/SensorBench/SensorBench.exe ``` After installing/upgrading `orisys`, the build syncs wheel sensor `*.json` into repo `config/` via `build/sync_wheel_configs.py` (for example `ddjx01.json`) before PyInstaller, never touching `locales/`. The helper reads from the installed wheel's bundled `orisys/configs/` directory instead of `orisys.configs.CONFIG_DIR`, which can point at the repo's local `config/` during builds. PyInstaller bundles that `config/`, then the script copies repo `config/` beside the EXE so operators can edit sensor JSON and locales. The public build intentionally excludes: - `internal/` (private operator UI) - `steps/` workflow JSON - `config/options.json` lab component metadata - `sensor_bench_operator` / former `sensor_bench.app` modules The build is `onedir` rather than `onefile` so startup is faster and bundled DLL/resource issues are easier to diagnose. ## Validation The build script runs: ```powershell python tests/test_smoke.py python build/verify_dist.py ``` `verify_dist.py` checks the expected public layout **and** fails if internal paths, operator modules, workflow locale keys, or private workflow text appear in the dist tree. Manual hardware check: 1. Run `dist\SensorBench\SensorBench.exe`. 2. Confirm the exhibition UI opens without setting `PYTHONPATH`. 3. Confirm the UI defaults to Simplified Chinese and can switch to English. 4. Confirm Orisys status is available, the config dropdown lists local editable sensor configs (for example `ddjx01`), and Start uses DDJX01. 5. Confirm Search finds cameras (or logs none) and Camera still opens a video-file picker. There is no Cal (.npy) field; Reset resets the Orisys tracker while preview is running. 6. Start preview with camera index `0` (or a searched index / video file). 7. Confirm the image panel and FN/FX/FY plots update. 8. Toggle processed/raw view and start/stop recording under `dist\SensorBench\recordings`. Locale files are bundled under `_internal/config/locales/` (and can also be placed beside the EXE under `config/locales/` for overrides). Edit those JSON files to change exhibition-facing text without rebuilding. ## Private operator EXE (internal only) Do **not** ship `SensorBenchOperator` to customers. It includes workflow steps, lab `options.json`, and operator locale copy. ```bat .\build\create_env.bat .\build\build_operator_exe.bat ``` Or: ```bat powershell -NoProfile -ExecutionPolicy Bypass -File .\build\build_operator_exe.ps1 ``` Output: ```text dist/SensorBenchOperator/SensorBenchOperator.exe ``` Validation: ```powershell python tests/test_smoke.py python internal/tests/test_operator_smoke.py python build/verify_operator_dist.py ``` Manual check: 1. Run `dist\SensorBenchOperator\SensorBenchOperator.exe`. 2. Confirm the workflow/steps panel and component options appear. 3. Confirm Start Preview / record / force curves still work with a camera. 4. Confirm `config/options.json` and `steps/default.json` beside the EXE are editable. Source-level operator docs: [`../internal/README.md`](../internal/README.md).