question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

`PS` button raises RuntimeError('There is no current event loop in thread %r.'

See original GitHub issue

I’m trying to create a keyboard/mouse setup for anki with my controller.

I start ds4drv --hidraw:

[info][controller 1] Created devices /dev/input/js0 (joystick) /dev/input/event21 (evdev)
[info][controller 1] Connected to Bluetooth Controller (A4:53:85:86:E2:AB hidraw4)
[info][hidraw] Scanning for devices
[info][controller 1] Battery: 62%

So far nothing happens when I push buttons on the controller (except PS). Upon pressing the PS button however, the following Exceptions show up:

[info][controller 1] Switching to profile: kbmouse
Exception ignored in: <function InputDevice.__del__ at 0x7f80352723a0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 159, in __del__
    self.close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 304, in close
    super().close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/eventio_async.py", line 54, in close
    loop = asyncio.get_event_loop()
  File "/usr/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.
Exception ignored in: <function InputDevice.__del__ at 0x7f80352723a0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 159, in __del__
    self.close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 304, in close
    super().close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/eventio_async.py", line 54, in close
    loop = asyncio.get_event_loop()
  File "/usr/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 109, in run
    self.loop.run()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 101, in run
    callback()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 106, in read_report
    self.fire_event("device-report", report)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 38, in fire_event
    self.loop.fire_event(event, *args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 86, in fire_event
    self.process_events()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 92, in process_events
    callback(*args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/action.py", line 73, in _handle_report
    self.handle_report(report)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/actions/binding.py", line 105, in handle_report
    binding.callback(report, *binding.args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/actions/binding.py", line 62, in <lambda>
    lambda r: self.controller.next_profile())
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 61, in next_profile
    self.load_profile(self.profiles[next_index])
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 47, in load_profile
    self.load_options(profile_options)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 93, in load_options
    self.fire_event("load-options", options)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 38, in fire_event
    self.loop.fire_event(event, *args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 86, in fire_event
    self.process_events()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 92, in process_events
    callback(*args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/actions/input.py", line 75, in load_options
    self.joystick.device.close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/uinput.py", line 205, in close
    self.device.close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 304, in close
    super().close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/eventio_async.py", line 54, in close
    loop = asyncio.get_event_loop()
  File "/usr/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.

After that, no button presses on the controller do anything anymore (not even PS).


I also noticed, that when I start it with ds4drv --hidraw --mapping keyboard, I can move the mouse with the right stick, type wasd with the left stick and do some other things.

ds4drv --hidraw --mapping keyboard
[info][controller 1] Connected to Bluetooth Controller (A4:53:85:86:E2:AB hidraw4)
[info][hidraw] Scanning for devices
[info][controller 1] Battery: 62%

When I then press PS once, I can also use the trackpad to move the mouse, but the following error appears:

[info][controller 1] Switching to profile: kbmouse
Exception ignored in: <function InputDevice.__del__ at 0x7f9d612cc3a0>
Traceback (most recent call last):
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 159, in __del__
    self.close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 304, in close
    super().close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/eventio_async.py", line 54, in close
    loop = asyncio.get_event_loop()
  File "/usr/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.

If I hit PS again, the controller ceases that functionality with:

[info][controller 1] Switching to profile: xpad

And upon pressing PS yet again, the long Error we’ve already seen shows up:

[info][controller 1] Switching to profile: default
Exception in thread Thread-1:
Traceback (most recent call last):
  File "/usr/lib/python3.8/threading.py", line 932, in _bootstrap_inner
    self.run()
  File "/usr/lib/python3.8/threading.py", line 870, in run
    self._target(*self._args, **self._kwargs)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 109, in run
    self.loop.run()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 101, in run
    callback()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 106, in read_report
    self.fire_event("device-report", report)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 38, in fire_event
    self.loop.fire_event(event, *args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 86, in fire_event
    self.process_events()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 92, in process_events
    callback(*args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/action.py", line 73, in _handle_report
    self.handle_report(report)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/actions/binding.py", line 105, in handle_report
    binding.callback(report, *binding.args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/actions/binding.py", line 62, in <lambda>
    lambda r: self.controller.next_profile())
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 61, in next_profile
    self.load_profile(self.profiles[next_index])
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 47, in load_profile
    self.load_options(profile_options)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 93, in load_options
    self.fire_event("load-options", options)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/__main__.py", line 38, in fire_event
    self.loop.fire_event(event, *args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 86, in fire_event
    self.process_events()
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/eventloop.py", line 92, in process_events
    callback(*args)
  File "/usr/local/lib/python3.8/dist-packages/ds4drv/actions/input.py", line 75, in load_options
    self.joystick.device.close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/uinput.py", line 205, in close
    self.device.close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/device.py", line 304, in close
    super().close()
  File "/usr/local/lib/python3.8/dist-packages/evdev/eventio_async.py", line 54, in close
    loop = asyncio.get_event_loop()
  File "/usr/lib/python3.8/asyncio/events.py", line 639, in get_event_loop
    raise RuntimeError('There is no current event loop in thread %r.'
RuntimeError: There is no current event loop in thread 'Thread-1'.

No button pressing on the controller yields any reaction now.

My ~/.config/ds4drv.conf (copied from some sample configuration):

# Many of the settings used here are directly connected to their command line
# counterparts, see "ds4drv --help" for more information about available options.

##
# Global options
##
[ds4drv]
# Run ds4drv in background as a daemon
#daemon = true

# Location of the log file in daemon mode
#daemon-log = ~/.cache/ds4drv.log

# Location of the PID file in daemon mode
#daemon-pid = /tmp/ds4drv.pid

# Enable hidraw mode
#hidraw = true


##
# Controller settings
#
# This is the default profile for each controller.
# Multiple controllers slots are defined by increasing the number.
#
# Controller sections contain:
#  Key: A option, these are the same options that can used on the command line
#       but without the "--" prefix.
#  Value: The option's value, should be "true" if no value is needed.
#
# See "ds4drv --help" for a complete list of available options.
##sdwasawdwasdadawdsdadaw
[controller:1]
# Enables LED flash on low battery
#battery-flash = true

# Sets LED color
#led = 0000ff

# Enables profile switching
profile-toggle = PS

# Profiles to cycle through
profiles = kbmouse,xpad


##
# Profiles
#
# Profiles allows switching controller settings during runtime.
#
# Profile sections always require a name and are then enabled on a controller
# with "profiles = <profile1>[,<profile2>]".
#
# The same settings available for controllers are used here.
##
[profile:xpad]
led = ff0000
# Emulate the same button mapping as wired Xbox 360 controllers
emulate-xpad = true

[profile:kbmouse]
led = 00ff00
# Enable trackpad mouse
trackpad-mouse = true
# Custom button mapping
mapping = keyboard
# Custom action bindings
bindings = exec_stuff


##
# Mappings
#
# Mappings let you map buttons and sticks to mouse, key and joystick events.
#
# Mapping sections always require a name and are then enabled in a profile
# with "mapping = <name>".
#
# Mapping sections contain:
#  Key: A Linux input event, see /usr/include/linux/input-event-codes.h for a complete list
#  Value: Button on the DS4, use --dump-reports to see all the available buttons
##

[mapping:keyboard]
# General button to key mapping
KEY_UP = dpad_up
KEY_LEFT = dpad_left
KEY_DOWN = dpad_down
KEY_RIGHT = dpad_right
KEY_Z = button_cross
KEY_X = button_circle

# Turn analog stick directions into buttons
KEY_W = -left_analog_y
KEY_A = -left_analog_x
KEY_S = +left_analog_y
KEY_D = +left_analog_x

# Map relative mouse movement to a analog stick
REL_X = right_analog_x
REL_Y = right_analog_y

# Map mouse buttons
BTN_LEFT = button_r2
BTN_RIGHT = button_l2

# Emulate mouse wheel on r1 and l1
REL_WHEELUP = button_l1
REL_WHEELDOWN = button_r1

# Mouse settings
#mouse_sensitivity = 0.6
#mouse_deadzone = 5

# Scroll wheel emulation settings (values are in seconds)
#mouse_scroll_repeat_delay = 0.25 # How long to wait before continual scrolling
#mouse_scroll_delay = 0.05 # Lower this to scroll faster; raise to scroll slower


##
# Bindings
#
# Bindings let you bind button combos to special built-in actions.
#
# Binding sections can be defined with a name and are then enabled in a profile
# with "bindings = <name>".
#
# It's also possible to define a global bindings section that is enabled
# on all profiles.
#
# Sections contains:
#  Key: A button combo
#  Value: An action, see next section for valid actions.
#
#
# Valid actions:
#  next-profile                                  Loads the next profile
#  prev-profile                                  Loads the previous profile
#  load-profile <profile>                        Loads the specified profile
#  exec <command> [arg1] [arg2] ...              Executes the command with
#                                                specified arguments
#  exec-background <command> [arg1] [arg2] ...   Same as exec but launches in
#                                                the background
#
#
# Actions will be pre-processed and replace variables with real values.
#
# Valid variables:
#  $profile                The current profile
#  $name                   Pretty name of the current device
#  $device_addr            Bluetooth address of the device
#  $report.<attribute>     Replace <attribute> with a valid attribute,
#                          use --dump-reports to see which are available
##

[bindings]
# Cycle profiles
#PS+Right = next-profile
#PS+Left = prev-profile

# Go directly to specified profile
PS+Up = load-profile kbmouse
#PS+Down = load-profile default


[bindings:exec_stuff]
# Execute a command in the foreground, blocking until it has finished
PS+Cross = exec echo '$name'

# Execute a command in the background
PS+Triangle = exec-background sh -c 'echo "disconnect $device_addr" | bluetoothctl'

  1. Why do these errors show up and how do I fix them?
  2. The second example gets me to believe that the controller is a privileged paperweight in default profile - is that because my configuration is faulty? Is there some way to keep the controller from entering default profile, cycling only the others?
  3. Is there a way to start ds4drv with a specific profile (e.g. kbmouse) without having to switch profile using the controller?

Issue Analytics

  • State:open
  • Created 3 years ago
  • Comments:13 (1 by maintainers)

github_iconTop GitHub Comments

2reactions
cslevcommented, Sep 22, 2020

It seems no one is really interested in this anymore, however, I found a solution with python 2.7 that has the following error:

...
  File "/usr/local/lib/python2.7/dist-packages/ds4drv/actions/input.py", line 75, in load_options
    self.joystick.device.close()
  File "/usr/local/lib/python2.7/dist-packages/evdev/uinput.py", line 205, in close
    self.device.close()
  File "/usr/local/lib/python2.7/dist-packages/evdev/device.py", line 304, in close
    super().close()
TypeError: super() takes at least 1 argument (0 given)

Just telling you to comment out a line in the source code would not look like a clever idea, so let me explain why it is indeed a viable path.

First of all, due to Python2.7 and Python3+, the error you can see above is related to how the super() functions should be used. Just open that file /usr/local/lib/python2.7/dist-packages/evdev/device.py and look for the close() function. You will see it indeed looks like as in the error message, however, for this version of python we need to pass the class’ name as well as an argument, i.e., super(PARENT_CLASS). By looking at the main class definition of this device.py, we see it is an instance of the EventIO. Now, let’s check where does it come from! In the import section, we can see it can come from two sources:

try:
    from evdev.eventio_async import EventIO, EvdevError
except ImportError:
    from evdev.eventio import EventIO, EvdevError

If we take a closer look at these sources (by finding the relevant source codes of either /usr/local/lib/python2.7/dist-packages/evdev/eventio.py or /usr/local/lib/python2.7/dist-packages/evdev/eventio_async.py, we can deduce the following.

eventio_async.py does not have a close() function, while eventio.py has an empty close() function, i.e.,

def close(self):
        pass

Therefore, actually calling properly this function makes not too much sense, so we can surely go to line 304 in /usr/local/lib/python2.7/dist-packages/evdev/device.py and comment out the function call super().close() or the already tried to change super(EventIO).close().

After doing this, ds4drv works as expected, at least in the terminal (did not have time to check with games yet) without crashing:

[info][controller 1] Battery: Fully charged
[info][controller 1] Switching to profile: xpad
[info][controller 1] Switching to profile: kbmouse
[info][controller 1] Switching to profile: default
[info][controller 1] Switching to profile: xpad
[info][controller 1] Switching to profile: kbmouse
[info][controller 1] Switching to profile: default
[info][controller 1] Switching to profile: xpad
[info][controller 1] Switching to profile: kbmouse
[info][controller 1] Switching to profile: default

I hope it helps everyone being in a huge need of PS4 controllers and Linux gaming 😃 The solution might be a solution as well for other python versions complaining about the same problem by default.

1reaction
Ryochan7commented, Feb 22, 2021

Since the topic of mapping to SDL has been brought up, time to shill a project of mine. I made a GUI utility for mapping an evdev controller to the SDL GameController spec. The program was made as a replacement for the proprietary SDL2 Gamepad Tool and it offers feature parity. The app is written in Qt using Qt Quick/QML for the GUI. There is an AppImage available that has been tested on Fedora 32 and Ubuntu 20.04; I don’t think it has ever been tested on Fedora 33 so I should do that sometime.

Latest release page: https://gitlab.com/ryochan7/sdl2-gamepad-mapper/-/releases/v0.0.3

SDL2_Gamepad_Mapper-0.0.3-x86_64.AppImage: https://drive.google.com/file/d/12CtYjPbP8YLN7dCIJiKX5EcNdf4PIz4g/view?usp=sharing

Repo: https://gitlab.com/ryochan7/sdl2-gamepad-mapper

Read more comments on GitHub >

github_iconTop Results From Across the Web

There is no current event loop in thread 'Thread-1'. asyncio ...
It seems channel.send is a coroutine function, so you can just await it inside a regular async function. Typically a async main function ......
Read more >
runtimeerror: there is no current event loop in thread ... - You.com
RuntimeError('There is no current event loop in thread %r.' RuntimeError: There is ... ps: In nvim :JupyterConnect show up the same errors. Open...
Read more >
There is no current event loop in thread 'ScriptRunner ...
Then I updated my python from 3.9.7 to 3.9.12. And the browser showed “RuntimeError: There is no current event loop in thread 'ScriptRunner....
Read more >
ipython/ipython - Gitter
I know nothing about Jupyter on Windows. try this ... _loop is None: --> 650 raise RuntimeError('There is no current event loop in...
Read more >
Concurrent.futures + requests_html's render() = "There is no ...
File "C:\Users\Ze\Anaconda3\lib\asyncio\events.py", line 639, in get_event_loop raise RuntimeError('There is no current event loop in thread ...
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found