Testing / rollout plan
swbt backend は、設定 model、adapter discovery、session、port、runtime integration、GUI 接続操作、実機接続の順に導入する。
導入順序
swbt-python==0.5.3を通常依存として固定する。nyxpy.framework.core.hardware.swbtpackage を追加する。SwbtControllerType/SwbtControllerModel/ capabilities /SwbtControllerConfigをconfig.pyに定義する。ControllerOutputPort.imu(...)とCommand.imu(...)を既定 unsupported として追加する。SwbtAdapterDiscoveryServiceを追加し、CLInyxpy swbt adaptersを実装する。SwbtControllerSessionと fake session を追加する。NyxSwbtInputMapperに button / D-pad / stick / IMU mapping を追加する。SwbtControllerOutputPortを追加する。SwbtControllerOutputPortFactoryを追加し、macro 用 port と GUI lifetime port の両方を生成できるようにする。- runtime builder の構成起点で serial / swbt の factory 選択を行う。
- CLI
nyxpy swbt pair/nyxpy swbt reconnectを追加する。別 process の cached session を閉じられない CLIdisconnectは追加しない。 - GUI に adapter refresh、controller type、pair、reconnect、disconnect を追加する。
- 既存
VirtualControllerModelへ swbt port が差し込まれることを確認する。 - 実機 test で Pro Controller / Joy-Con L / Joy-Con R の接続と入力を確認する。
完了条件
[ ] swbt 固有実装が nyxpy.framework.core.hardware.swbt に収まっている
[ ] swbt_*.py という module が増えていない
[ ] hardware/swbt/manual.py が存在しない
[ ] SwbtManualInputSession が存在しない
[ ] SwbtGamepadService と SwbtControllerSession が二重化していない
[ ] runtime config に controller_type 文字列 field が残っていない
[ ] Literal による controller 種別分岐がない
[ ] CLI / GUI choices が supported_controller_models() から導出される
[ ] list_adapters() が GUI / CLI から使える
[ ] adapter refresh が pairing / reconnect / report loop を開始しない
[ ] macro run で pairing が暗黙実行されない
[ ] Command.imu(...) が追加されている
[ ] 非対応 backend の imu(...) が NotImplementedError になる
[ ] swbt backend が IMUFrame を InputState.with_imu(...) に入れられる
[ ] GUI manual input が既存 VirtualControllerModel -> ControllerOutputPort 経路を使う
[ ] GUI model が swbt を import しない
[ ] GUI manual input と macro runtime が同じ adapter を同時に開かない
[ ] GUI に clipboard / CLI command 生成がない
[ ] GUI に diagnostics editor / controller color editor がない
[ ] GUI manual input に IMU gesture / pose / raw frame editor がない
[ ] Joy-Con type ごとの unsupported input が明確に失敗する
[ ] close 時に neutral を試みる
[ ] swbt が通常依存であり、`[project.optional-dependencies].swbt` がない
[ ] adapter 未指定時に自動採用せず `NYX_SWBT_ADAPTER_NOT_SELECTED` になる
[ ] pairing profile 未指定時に `.nyxpy/swbt/<controller>-profile.json` を使う
[ ] 相対 pairing profile path が workspace root 基準で解決される
[ ] pair / reconnect 後の接続判定が `GamepadStatus.connection_state` に基づく
[ ] GUI の swbt lifecycle と macro start が worker thread で実行される
[ ] GUI manual input が port なし、macro 実行中、lifecycle 操作中に無効になる
[ ] swbt diagnostics が production の technical log へ流れる
[ ] 実機 test が `@pytest.mark.realdevice` と環境変数 gate で制御される
[ ] 実機 evidence が `tmp/hardware/swbt/<timestamp>/` に残る
リスクと対策
| リスク | 対策 |
|---|---|
| adapter 名が接続状態で変わる | list_adapters() の結果で aliases と VID/PID も表示する |
| pairing profile に複数候補が入る | controller type と対象機器ごとに file を分け、InvalidKeyStoreError を明示表示する |
| GUI manual input と macro runtime が競合する | macro start 前に GUI lifetime port を release/close する |
| IMU command が非対応 backend で silent no-op になる | 共通 default を NotImplementedError にする |
| Joy-Con type で存在しない入力を送る | SwbtControllerModel.capabilities で mapper が拒否する |
| 短い押下が report loop に載らない | 実機 test で最小 dur を確認し、ドキュメントへ反映する |
| diagnostics が GUI の通常機能として肥大化する | production composition root から writer を注入して LoggerPort.technical(...) に流し、GUI / CLI / settings には path を出さない |
実機確認 checklist
Adapter discovery
[ ] adapter が 1 件以上表示される
[ ] aliases / VID/PID が表示される
[ ] refresh だけでは pairing 待ち受けが開始されない
Pair / reconnect
[x] Pro Controller で pair 成功
[x] 同じ pairing profile で reconnect 成功
[x] Joy-Con L で pair/reconnect 成功
[x] Joy-Con R で pair/reconnect 成功
[ ] invalid pairing profile が明確に表示される
[ ] GUI Disconnect が factory-managed cached session を閉じる
Macro input
[x] Button.A press/release
[x] 16ms / 33ms / 50ms の短い押下を確認
[x] D-pad input を確認(観察画面は斜め方向を上として表示するため、右上の方向区別は未確認)
[x] left stick / right stick
[x] Command.imu(...) による IMU neutral / gyro frame を送信し、切断・想定外入力がないことを確認(gyro 値自体の画面上の反映は未確認)
[x] release all / close neutral
GUI manual input
[ ] reconnect 後に virtual controller が有効になる
[ ] button down/up が反映される
[ ] D-pad が反映される
[ ] stick が反映される
[ ] macro start 前に GUI lifetime port が閉じられる
[ ] GUI に IMU 操作 UI がない
local_026 時点の実機未確定項目
unit、CLI、GUI の非実機 gate では mapping と lifecycle 境界を確認できる。次の項目は Switch、専用 USB Bluetooth adapter、operator がそろった環境で確定するまで未検証として扱う。
[x] Pro Controller / Joy-Con L / Joy-Con R の pair / reconnect
[ ] NyX `0..255`、Y-down から `Stick.normalized`、Y-up への変換が実機で期待方向に反映されること
[x] 16ms / 33ms / 50ms short press の反映
[ ] public flush / send_current 相当 API が必要かどうか
座標変換規則自体は単体テストで固定する。Switch 画面では左右 stick の上方向を確認した。D-pad の UPRIGHT は上として反映されたが、観察画面が斜め方向を区別しないため、右成分を含むことは未確認である。
実機で short press が取りこぼされる場合、この文書と利用者向け docs に最小推奨 duration を反映する。実機確認前の段階では、NyX は swbt backend 固有の最小押下時間を保証しない。