Last active
January 27, 2023 10:00
-
-
Save Ultrawipf/53bc237ce11a1f5f1d86107989f62675 to your computer and use it in GitHub Desktop.
Simucube and cube controls compatible bluetooth LE steering wheel to keyboard or vjoy using pyvjoy mapper
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import asyncio | |
import platform | |
from time import time,sleep | |
from bleak import BleakClient,BleakScanner | |
VJOYMODE = True # Set true to use vjoy gamepad instead of keyboard | |
if VJOYMODE: | |
import pyvjoy | |
joy = pyvjoy.VJoyDevice(2) | |
print(joy) | |
buttonsToKeys = [1,2,3,4,5,6,7,8,9,10] | |
encoderKeys = [(11,12),(13,14),(15,16),(17,18)] | |
else: | |
import keyboard | |
buttonsToKeys = ["page down","page up","F13","F14","F15","F16","F17","F18","F19","F20"] | |
#buttonsToKeys = [",",".","F13","F14","F15","F16","F17","F18","F19","F20"] | |
encoderKeys = [("-","+"),("4","7"),("5","8"),("6","9")] | |
name = "SC2-CUBE_WHEEL" # Device name | |
BUTTON_UUID = "5a0c806c-eb42-48bd-8429-0e62bf93a4a6" | |
STATUS_UUID = "E35FCF33-0EF2-49C8-A3DF-352B666D4BEC" | |
encoderbits = [(2,3),(4,5),(6,7),(8,9)] | |
buttonbits = [0,1,12,13,14,15,19,20,21,22] | |
lastButtons = [False]*10 | |
lastEncoder = [(False,False)]*4 | |
address = None | |
async def getAddress(name): | |
devices = await BleakScanner.discover() | |
for d in devices: | |
if d.name == name: | |
print("Found",d) | |
return d.address | |
return None | |
def press(id,down): | |
#print("press ",id,down) | |
if VJOYMODE: | |
joy.set_button(buttonsToKeys[id],1 if down else 0) | |
else: | |
if down: | |
keyboard.press(buttonsToKeys[id]) | |
else: | |
keyboard.release(buttonsToKeys[id]) | |
def clickEncoder(id,dir): | |
#print("enc ",id,dir) | |
if VJOYMODE: | |
joy.set_button(encoderKeys[id][1 if dir else 0],1) | |
sleep(0.1) | |
joy.set_button(encoderKeys[id][1 if dir else 0],0) | |
else: | |
keyboard.press_and_release(encoderKeys[id][1 if dir else 0]) | |
def decodeButton(sender,data): | |
bitstring = ''.join(format(byte, '08b')[::-1] for byte in data) | |
#high = [ i for i in range(len(bitstring)) if bitstring[i] == "1"] | |
buttons = [bitstring[i] == "1" for i in buttonbits] | |
#print(buttons) | |
# Decode buttons | |
for i,b in enumerate(buttons): | |
if b == lastButtons[i]: | |
continue | |
press(i,b) | |
lastButtons[i] = b | |
# Decode encoders (up/down) | |
for i,encoder in enumerate(encoderbits): | |
encoderValue = (bitstring[encoder[0]] == "1" , bitstring[encoder[1]] == "1") | |
lastVal = lastEncoder[i] | |
if(encoderValue == lastVal): | |
continue # No change | |
# calculate direction | |
direction = 0 # -1 down, 1 up | |
if(encoderValue[0] != lastVal[0]): # A changed | |
direction = -1 if encoderValue[1] == encoderValue[0] else 1 | |
elif(encoderValue[1] != lastVal[1]): # B changed | |
direction = 1 if encoderValue[0] == encoderValue[1] else -1 | |
lastEncoder[i] = encoderValue | |
# only update output if both pins are the same as there are 2 transistions per notch | |
if(encoderValue[0] == encoderValue[1]): | |
clickEncoder(i,direction == 1) | |
def statusHandler(sender, data): | |
voltage = (data[1]<<8) | data[0] | |
voltage = voltage /1000 | |
print("Voltage: {}V".format(voltage)) | |
async def runNotification(address): | |
async with BleakClient(address) as client: | |
await client.start_notify(STATUS_UUID, statusHandler) | |
await client.start_notify(BUTTON_UUID, decodeButton) | |
while client.is_connected: | |
await asyncio.sleep(5) | |
await client.stop_notify(BUTTON_UUID) | |
if __name__ == "__main__": | |
while(address == None): | |
loop = asyncio.new_event_loop() | |
asyncio.set_event_loop(loop) | |
address = loop.run_until_complete(getAddress(name)) | |
if(address == None): | |
print("Can not find device",name) | |
#exit() | |
# loop.set_debug(True) | |
loop.run_until_complete(runNotification(address)) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment