Files
joycontrol/scripts/joycon_rumble.py
T
2021-03-06 16:15:53 +01:00

109 lines
3.0 KiB
Python

import asyncio
import logging
import os
from joycontrol import logging_default as log
from joycontrol.hid import get_blt_hid_device, AsyncHID
from joycontrol.report import InputReport, OutputReport, OutputReportID, SubCommand
logger = logging.getLogger(__name__)
VENDOR_ID = 1406
PRODUCT_ID_JL = 8198
PRODUCT_ID_JR = 8199
PRODUCT_ID_PC = 8201
"""
Sends some vibration reports to a joycon. Only works with the right joycon atm.
"""
async def print_outputs(hid_device):
while True:
data = await hid_device.read(255)
# add byte for input report
data = b'\xa1' + data
input_report = InputReport(list(data))
vibrator_input = input_report.data[13]
# print(hex(vibrator_input))
async def send_vibration_report(hid_device):
reader = asyncio.ensure_future(print_outputs(hid_device))
CHANGE_INPUT_REPORT_MODE = [1, 8, 0, 0, 0, 0, 0, 1, 64, 64, 3, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0]
data = CHANGE_INPUT_REPORT_MODE
print('writing', data)
await hid_device.write(bytes(data))
await asyncio.sleep(0.1)
report = OutputReport()
report.set_timer(1)
report.set_output_report_id(OutputReportID.SUB_COMMAND)
report.set_sub_command(SubCommand.ENABLE_VIBRATION)
report.set_sub_command_data([0x01])
data = bytes(report)[1:]
print('writing', data)
await hid_device.write(bytes(data))
await asyncio.sleep(0.1)
time = 2
while True:
for i in range(10):
rumble_report = OutputReport()
report.set_timer(time)
time += 1
rumble_report.set_output_report_id(OutputReportID.RUMBLE_ONLY)
# increase frequency
rumble_report.set_right_rumble_data(100 + i * 100, 1)
data = bytes(rumble_report)[1:]
print('writing', data)
await hid_device.write(bytes(data))
await asyncio.sleep(.5)
break
try:
await reader
except KeyboardInterrupt:
pass
async def _main(loop):
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 = await get_blt_hid_device()
logger.info(f'Found controller "{controller}".')
with AsyncHID(path=controller['path'], loop=loop) as hid_controller:
await send_vibration_report(hid_controller)
if __name__ == '__main__':
# check if root
if not os.geteuid() == 0:
raise PermissionError('Script must be run as root!')
# setup logging
log.configure()
loop = asyncio.get_event_loop()
task = asyncio.ensure_future(_main(loop))
try:
loop.run_until_complete(task)
except KeyboardInterrupt:
task.cancel()
try:
loop.run_until_complete(task)
except asyncio.CancelledError:
pass
finally:
loop.stop()
loop.close()