From fd7b41d018cd6e8a7474d9bd463b29aa9f919341 Mon Sep 17 00:00:00 2001 From: Robert Martin Date: Sat, 6 Mar 2021 16:15:53 +0100 Subject: [PATCH] move hid stuff to extra module --- joycontrol/hid.py | 36 ++++++++++++++++++++++++++++++++++++ joycontrol/utils.py | 19 ------------------- scripts/__init__.py | 0 scripts/joycon_rumble.py | 18 ++++-------------- 4 files changed, 40 insertions(+), 33 deletions(-) create mode 100644 joycontrol/hid.py create mode 100644 scripts/__init__.py diff --git a/joycontrol/hid.py b/joycontrol/hid.py new file mode 100644 index 0000000..446f215 --- /dev/null +++ b/joycontrol/hid.py @@ -0,0 +1,36 @@ +import asyncio + +import hid + +VENDOR_ID = 1406 +PRODUCT_ID_JL = 8198 +PRODUCT_ID_JR = 8199 +PRODUCT_ID_PC = 8201 + + +async def get_blt_hid_device(): + while True: + for device in hid.enumerate(0, 0): + # looking for devices matching Nintendo's vendor id and JoyCon product id + if device['vendor_id'] == VENDOR_ID and device['product_id'] in ( + PRODUCT_ID_JL, PRODUCT_ID_JR, PRODUCT_ID_PC): + return device + + await asyncio.sleep(2) + + +class AsyncHID(hid.Device): + def __init__(self, *args, loop=asyncio.get_event_loop(), **kwargs): + super().__init__(*args, **kwargs) + self._loop = loop + + self._write_lock = asyncio.Lock() + self._read_lock = asyncio.Lock() + + async def read(self, size, timeout=None): + async with self._read_lock: + return await self._loop.run_in_executor(None, hid.Device.read, self, size, timeout) + + async def write(self, data): + async with self._write_lock: + return await self._loop.run_in_executor(None, hid.Device.write, self, data) \ No newline at end of file diff --git a/joycontrol/utils.py b/joycontrol/utils.py index 4eadc31..496cb02 100644 --- a/joycontrol/utils.py +++ b/joycontrol/utils.py @@ -2,28 +2,9 @@ import asyncio import logging from contextlib import contextmanager -import hid - logger = logging.getLogger(__name__) -class AsyncHID(hid.Device): - def __init__(self, *args, loop=asyncio.get_event_loop(), **kwargs): - super().__init__(*args, **kwargs) - self._loop = loop - - self._write_lock = asyncio.Lock() - self._read_lock = asyncio.Lock() - - async def read(self, size, timeout=None): - async with self._read_lock: - return await self._loop.run_in_executor(None, hid.Device.read, self, size, timeout) - - async def write(self, data): - async with self._write_lock: - return await self._loop.run_in_executor(None, hid.Device.write, self, data) - - @contextmanager def get_output(path=None, open_flags='wb', default=None): """ diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/joycon_rumble.py b/scripts/joycon_rumble.py index b4e589f..0abdae1 100644 --- a/scripts/joycon_rumble.py +++ b/scripts/joycon_rumble.py @@ -2,11 +2,9 @@ import asyncio import logging import os -import hid - from joycontrol import logging_default as log +from joycontrol.hid import get_blt_hid_device, AsyncHID from joycontrol.report import InputReport, OutputReport, OutputReportID, SubCommand -from joycontrol.utils import AsyncHID logger = logging.getLogger(__name__) @@ -75,19 +73,11 @@ async def send_vibration_report(hid_device): async def _main(loop): - logger.info('Waiting for HID devices... Please connect one JoyCon (left OR right), or a Pro Controller over Bluetooth. ' + logger.info('Waiting for HID devices... Please connect one JoyCon (left OR right), ' + 'or a Pro Controller over Bluetooth. ' 'Note: The bluez "input" plugin needs to be enabled (default)') - controller = None - while controller is None: - for device in hid.enumerate(0, 0): - # looking for devices matching Nintendo's vendor id and JoyCon product id - if device['vendor_id'] == VENDOR_ID and device['product_id'] in (PRODUCT_ID_JL, PRODUCT_ID_JR, PRODUCT_ID_PC): - controller = device - break - else: - await asyncio.sleep(2) - + controller = await get_blt_hid_device() logger.info(f'Found controller "{controller}".') with AsyncHID(path=controller['path'], loop=loop) as hid_controller: