Skip to content
EN

Getting Started

A Python SDK to drive Hapbeat over Wi-Fi UDP. For research (PsychoPy / Jupyter / ROS), media art, and prototyping. It separates the fire side (when / where to play) from the tuning side (what / how to play), linking them only by event id.

pip install hapbeat-python-sdk # library + CLI
pipx install hapbeat-python-sdk # CLI / launchpad only, in an isolated environment

pipx is for installing the CLI (hapbeat scan / launchpad, etc.) in an isolated environment. To import hapbeat from your own scripts, use pip install inside a venv.

import hapbeat
hb = hapbeat.connect(app_name="MyApp")
hb.play("sample-kit.sine_100hz", gain=0.5)
hb.close()
  • connect() opens a UDP broadcast socket and sends a keep-alive so the app name appears on the device OLED.
  • play(event_id, gain) sends a play instruction. gain is 0..1; if omitted, the EventMap described below supplies the default (the kit’s intensity).

"sample-kit.sine_100hz" must be an event id present in the kit deployed to the device (flashed via Hapbeat Studio). The SDK sends only the instruction; the waveform lives in the kit on the device (command mode; for the separate clip mode, see Choosing between command and clip).

with hapbeat.connect() as hb:
for d in hb.discover(timeout=1.5):
print(d.ip, d.address, d.firmware_version)

Separating the fire side from the tuning side (EventMap)

Section titled “Separating the fire side from the tuning side (EventMap)”

Instead of writing “haptic tuning values” such as intensity into your firing code, collect them in a haptic file (kit manifest = EventMap). play("id") resolves the defaults from there.

em = hapbeat.EventMap.from_manifest("kits/my-kit/my-kit-manifest.json")
with hapbeat.connect(event_map=em) as hb:
hb.play("sample-kit.sine_100hz") # fires at the kit manifest's intensity

This lets you swap “when to play (code)” and “how strong (kit)” independently. For details, see EventMap Reference.

hb.play("sample-kit.sine_100hz", target="player_1/chest") # one device
hb.play("sample-kit.sine_100hz", target="*/chest") # all chest devices
hb.play("sample-kit.sine_100hz") # broadcast to all

To have Claude / Cursor / Copilot, etc. use this SDK, hand it the AGENTS.md bundled with the SDK. It packs the specification, usage, and pitfalls into a single file — enough on its own to grasp the whole picture.

  • Location: AGENTS.md at the root of the SDK repository
  • Example of what to hand over (paste as-is to the agent):
Use the Hapbeat Python SDK. Read AGENTS.md and follow its specification and best practices.