dualsense_api 1.0.1
dualsense_api: ^1.0.1 copied to clipboard
Control a Sony DualSense (PS5) controller over USB on macOS via HIDAPI + Dart FFI: read sticks, triggers, buttons, battery and audio jack in real time, and command the lightbar color.
dualsense_api #
Control a Sony DualSense (PS5) controller connected over USB from Dart/Flutter on macOS. Reads sticks, analog triggers, buttons, D-Pad, battery and the 3.5mm audio jack in real time, and commands the lightbar color.
Built on HIDAPI via Dart FFI — no native Flutter plugins, no platform channels.
Requirement: HIDAPI installed on the system #
This package does not bundle the native hidapi library — it loads it
from the system at runtime. Before using it, install it with
Homebrew:
brew install hidapi
This installs libhidapi.dylib at /opt/homebrew/lib/libhidapi.dylib,
which is the path DualSenseBindings.macOS() expects (Homebrew on
Apple Silicon). If you're on an Intel Mac, Homebrew installs to
/usr/local/lib instead — in that case you'll need to adjust the path or
create a symlink:
mkdir -p /opt/homebrew/lib
ln -s /usr/local/lib/libhidapi.dylib /opt/homebrew/lib/libhidapi.dylib
Without this step, connect() will throw an ArgumentError explaining
that the library couldn't be found.
Platform support: this package currently only works on macOS. Windows and Linux are on the roadmap (see below).
Installation #
dependencies:
dualsense_api: ^1.0.0
Usage #
import 'dart:io';
import 'package:dualsense_api/controllers/dualsense_controller.dart';
import 'package:dualsense_api/dualsense_bindings.dart';
Future<void> main() async {
final bindings = switch (Platform.operatingSystem) {
'macos' => DualSenseBindings.macOS(),
_ => throw UnsupportedError('Platform not supported yet'),
};
final controller = DualSenseController(bindings);
if (await controller.connect()) {
print('DualSense connected');
// Bright cyan
controller.setLedColor(0, 200, 255);
controller.onInputChanged.listen((state) {
print(state);
if (state.isPsPressed) {
controller.setLedColor(255, 0, 0);
}
});
} else {
print('No DualSense found. Is it connected via USB?');
}
// When you're done with it:
// controller.dispose();
}
See example/ for a complete, runnable example.
API #
| Class | Responsibility |
|---|---|
DualSenseBindings |
Loads libhidapi.dylib and exposes the C functions (hid_open, hid_read, hid_write, etc.) mapped to Dart. |
DualSenseController |
Connects to the controller, runs the polling loop, and exposes onInputChanged (Stream<DualSenseState>) + setLedColor(r, g, b). |
DualSenseState |
Immutable snapshot (Equatable) of the full physical state: sticks, triggers, buttons, D-Pad, battery, charging state, and audio jack. |
DualSenseState is only emitted when something actually changes compared
to the previous state — no manual deduplication needed in the UI.
Roadmap #
- Windows support (loading
.dllinstead of.dylib). - Adaptive triggers (physical resistance / weapon-trigger simulation).
- Stick drift visualization by normalizing axes to
-1.0..1.0.
License #
MIT — see LICENSE.