4

I like to send a rumble effect to a device using python evdev. This should be achieved with the upload_effect() function, which requires a buffer object as input.

This is what capabilities() reveals:

('EV_FF', 21L): [
    (['FF_EFFECT_MIN', 'FF_RUMBLE'], 80L),
    ('FF_PERIODIC', 81L),
    (['FF_SQUARE', 'FF_WAVEFORM_MIN'], 88L),
    ('FF_TRIANGLE', 89L),
    ('FF_SINE', 90L),
    ('FF_GAIN', 96L),
    ],

How do I create that buffer?

Sven Rojek
  • 5,476
  • 2
  • 35
  • 57
  • 1
    Hello. Author of python-evdev here. Long ago I started working on a branch that was supposed to make all of this easy. You basically have to define an `ff_effect` [struct](https://github.com/torvalds/linux/blob/master/include/uapi/linux/input.h#L424) from Python and upload that. It's not very straightforward, but perhaps [this](https://github.com/gvalkov/python-evdev/blob/ff/evdev/ff.py) can help you get started. I really hope to get back to this feature someday ... – gvalkov Nov 18 '15 at 16:51

1 Answers1

6

Python-evdev 1.1.0 supports force-feedback effect uploads. Here's an example from the documentation:

from evdev import ecodes, InputDevice, ff

# Find first EV_FF capable event device (that we have permissions
# to use).
for name in evdev.list_devices():
    dev = InputDevice(name)
    if ecodes.EV_FF in dev.capabilities():
        break

rumble = ff.Rumble(strong_magnitude=0x0000, weak_magnitude=0xffff)
effect_type = ff.EffectType(ff_rumble_effect=rumble)
duration_ms = 1000

effect = ff.Effect(
    ecodes.FF_RUMBLE, -1, 0,
    ff.Trigger(0, 0),
    ff.Replay(duration_ms, 0),
    effect_type
)

repeat_count = 1
effect_id = dev.upload_effect(effect)
dev.write(ecodes.EV_FF, effect_id, repeat_count)
dev.erase_effect(effect_id)
SOFe
  • 7,867
  • 4
  • 33
  • 61
gvalkov
  • 3,977
  • 30
  • 31
  • 1
    Awesome! Thanks for your effort! – Sven Rojek Aug 27 '18 at 19:51
  • I'm unable to get this to work with my controller. I can read events/button presses fine using python evdev, and I can test the force feedback correctly using the common fftest binary. Your code example has a few typos but even after correcting them, the result is that 'nothing happens' (EC_FF is in dev.capabilities) – Prismatic Nov 23 '19 at 04:19
  • 1
    For those that come to this answer. You need to wait after writing the FF effect, before calling erase_effect(). If you erase_effect() right after write()-ing the FF effect, it won't trigger properly – Martin Dinov Jun 11 '21 at 15:01