Agent Brief
Use public imports:
from swbt import (
Button,
DirectJoyConL, DirectJoyConR, DirectProController,
IMUFrame,
InputState,
JoyConL, JoyConR, ProController,
PeriodicSwitchGamepad, DirectSwitchGamepad,
Stick,
SwitchGamepad,
)
Prefer this minimal pattern:
async with ProController(adapter="usb:0", profile_path="profiles/switch-pro.json") as pad:
await pad.connect(timeout=30.0, allow_pairing=True)
await pad.tap(Button.A)
await pad.neutral()
Create a new persistent Pro Controller profile once with
await ProController.create_profile(adapter=..., profile_path=...,
pair_timeout=...). This keeps the adapter's current default address and does not
write volatile identity state. Pass local_address=... only when the caller owns
address generation and collision avoidance. The path must not already exist. Reuse
the returned connected controller or close it and pass the same profile_path to
ProController(...). The adapter-default path has been verified for a Pro
Controller profile on Windows 11 with CSR8510 A10 and WinUSB; other controller
profiles, operating systems, and adapters remain unverified. The explicit-address
CSR8510 A10 path writes only volatile state. On
AdapterIdentityRecoveryRequired, unplug and reconnect the dedicated USB Bluetooth
dongle before retrying.
For a single Joy-Con L/R, use JoyConL(...) or JoyConR(...):
async with JoyConL(adapter="usb:0", profile_path="switch-left-joycon-bond.json") as left:
await left.connect(timeout=30.0, allow_pairing=True)
await left.tap(Button.L)
await left.neutral()
Use DirectProController(...), DirectJoyConL(...), or DirectJoyConR(...)
when caller code owns every input-report trigger:
async with DirectProController(adapter="usb:0", profile_path="switch-direct.json") as pad:
await pad.connect(timeout=30.0, allow_pairing=True)
await pad.send(InputState.neutral().with_buttons([Button.A]))
Rules:
- Use
connect(..., allow_pairing=True)for first-run examples. - Use
pair()only when the target device is in controller pairing/search mode. - Use
reconnect()only when the profile contains one current bonded peer. - Use
try_connect()/try_reconnect()when code needsConnectionResultinstead of exceptions. - Use
tap()for immediate short button input. - Use
press()/release()for held button state. - Use
lstick()/rstick()for one-stick state updates. - Use
sticks()when both sticks should be updated in one state update. - Use
Stick.up(),Stick.down(),Stick.left(),Stick.right(), orStick.tilt()to construct stick values. - Use
imu()for IMU state updates. - Use
IMUFrame.gyro(),IMUFrame.accel(),IMUFrame.raw(),IMUFrame.with_gyro(), orIMUFrame.with_accel()for raw IMU values. - Use
IMUFrame.gyro_rate()orIMUFrame.with_gyro_rate()for angular velocity in rad/s, andIMUFrame.to_gyro_rate()for conversion back to rad/s. The scale is fixed at0.070 dps/raw. - Do not pre-pack quaternion motion. The runtime selects standard or quaternion wire packing from the host IMU mode.
- Treat an unspecified host IMU mode or mode
0x00as disabled; the runtime sends a zero IMU block and does not carry host mode or quaternion state across reopen. - Use
IMUFrame.accel_g()orIMUFrame.with_accel_g()for acceleration in G, andIMUFrame.to_accel_g()for conversion back to G. The scale is fixed at1/4096 G/raw. - Use
InputState+apply()when buttons, sticks, and IMU must be one complete state. - Use
InputState+send()for one complete Direct input report. Awaiting it means Bumble accepted the report for enqueue; it does not guarantee HCI completion or target-device reflection. State commits after enqueue acceptance. - Use a separate
profile_pathfor every controller shape and target device. When an explicit local address is used, manage it separately as well. - Treat unsupported one-sided Joy-Con inputs as
UnsupportedInputError: left does not support right stick or A/B/X/Y, right does not support left stick or D-pad. - Use
SwitchGamepadonly when code accepts either reporting contract. UsePeriodicSwitchGamepadorDirectSwitchGamepadwhen the sending contract matters. - Instantiate
ProController,JoyConL, orJoyConRfor Periodic reporting. Instantiate the correspondingDirect*class for Direct reporting. - Do not call
apply()on Direct types orsend()on Periodic types. - Do not assume Periodic
press()/release()/lstick()/rstick()/sticks()/imu()/neutral()send immediately. - Direct semantic input operations send one report and commit only after successful enqueue acceptance.
- Do not pass tuples or raw tuples to stick APIs.
- Do not invent
pad.gyro()orpad.accel(). - Do not invent
hold(),sequence(),send_current_input(), fluent builder APIs, or macro helpers. - Do not invent
JoyConPair; paired left/right Joy-Con support is not implemented. - Do not show low-level Joy-Con profile classes or the removed side-string Joy-Con wrapper in user-facing examples.
- Do not import internal modules unless writing swbt's own tests.
- Do not present Joy-Con hardware compatibility beyond the recorded Windows 11 / CSR8510 A10 / WinUSB / Switch 2 firmware 22.5.0 profile scenarios. Exact SDP parity, Linux, Joy-Con on macOS, other dongles, other firmware, and pairing-free incoming bond reuse are not confirmed.