SebiTimeWaster / G213Colors

A Python script to change the key colors on a Logitech G213 Prodigy Gaming Keyboard
MIT License
155 stars 44 forks source link

Adaptation for Windows #16

Open SirNio opened 2 years ago

SirNio commented 2 years ago

Not a real issue, but I wanted to let you know that your code can perfectly used under Windows. The user just also needs to install libusb via Zadig, but then magic. I made small adaptations since I just wanted to set my color at the start without starting GHub. I made it realy simply. I know not the best coding style. But definitely the fastest.

import sys import usb.core

device = usb.core.find(idVendor=0x046d, idProduct=0xc336) if device is None: sys.exit(1)

device.ctrl_transfer(0x21, 0x09, 0x0211, 0x0001, b'\x11\xff\x0c:\x00\x01\xff\xa1\xf6\x02\x00\x00\x00\x00\x00\x00\x00\x00\x00\x00') device.read(0x82, 20)

xcme commented 2 years ago

Hi @SirNio,

How did you manage to run it under Windows? I installed:

pip install pyusb
pip install libusb

Then copied the libusb-1.0.dll to some folder within $Env:Path (%PATH%) variable. But after running the code I receive:

NotImplementedError: Operation not supported or unimplemented on this platform

This happens for connectG(). How can I solve this?

SirNio commented 2 years ago

Yeah I had the same error at first. It is fixed by installing Libusb with a software called Zadig. (Windows somehow needs a special interface for accessing it) If you open Zadig one can find the option to install libusb in the menu for the matching device.

xcme commented 2 years ago

Seems it's needed to change driver for that device? Current HID driver should be replaced to WinUSB? Will it work in the same manner after this trick?

P.S. Not sure if I want to run some program (Zadig) that is going to change my device settings when I don't understand what and why it's exactly doing :) But thanks for the answer.

P.P.S. Googled a bit if it's possible to work with HID devices directly from python and it seems there are some limitations for keyboards/mices due to security reasons. Ah, stupid keyboard that cannot just remember static color! If it could, I wouldn't require any special software for that.

rnayabed commented 1 year ago

@xcme , hey, did you ever figure out a method for getting this to run on windows? I am writing a similar software for Royal Kludge Keyboards. I managed to get it working on Linux but no clue on how to get it working on windows :(

xcme commented 1 year ago

Hi @rnayabed, I figured out that Windows uses different HIDs for keyboard/mouse and RGB stuff. When I found correct 'usage' and 'usage page' it started to work. I stopped at the PoC with cmd file when it sends data via hidapitester and it works like a charm. :) No additional drivers were installed, it works with the default stuff the Windows has.

xcme commented 1 year ago

@rnayabed, You can download that hidapitester and issue: hidapitester --list

It will show all devices it sees. Find your device in the output and remember its VID and PID. Then issue: hidapitester --vidpid %vid%:%pid% --list-detail (Use your VID and PID and colon, not slash)

It will show your chosen device with all pages it has. Then you can try to send your data, using different pages: hidapitester.exe --vidpid %vid%:%pid% --usagePage %usagepage% --usage %usage% --open --send-output %data% One of that 'usagePage'/'usage' pair may work.

P.S. I'm not sure if it's safe, because it's possible to damage the device by sending wrong data there. For my G213 I was able so send something that hung the keyboard up, but in my case sending correct data after that returns the device in good state again.

rnayabed commented 1 year ago

Thank you so much @xcme !!

I was finally able to get it working on windows, but now i run into a weird behavior:

PS D:\Downloads\hidapitester-windows-x86_64 (1)> .\hidapitester.exe --list-detail 258a:00ea

...

258A/00EA: SINO WEALTH - Gaming  vendorId:      0x258A
  productId:     0x00EA
  usagePage:     0x0001
  usage:         0x0080
  serial_number: (null)
  interface:     1
  path: \\?\hid#vid_258a&pid_00ea&mi_01&col01#8&3ad4f8ff&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}

258A/00EA: SINO WEALTH - Gaming  vendorId:      0x258A
  productId:     0x00EA
  usagePage:     0x0001
  usage:         0x0006
  serial_number: (null)
  interface:     1
  path: \\?\hid#vid_258a&pid_00ea&mi_01&col04#8&3ad4f8ff&0&0003#{4d1e55b2-f16f-11cf-88cb-001111000030}\kbd

258A/00EA: SINO WEALTH - Gaming  vendorId:      0x258A
  productId:     0x00EA
  usagePage:     0x000C
  usage:         0x0001
  serial_number: (null)
  interface:     1
  path: \\?\hid#vid_258a&pid_00ea&mi_01&col02#8&3ad4f8ff&0&0001#{4d1e55b2-f16f-11cf-88cb-001111000030}

258A/00EA: SINO WEALTH - Gaming  vendorId:      0x258A
  productId:     0x00EA
  usagePage:     0xFF00
  usage:         0x0001
  serial_number: (null)
  interface:     1
  path: \\?\hid#vid_258a&pid_00ea&mi_01&col03#8&3ad4f8ff&0&0002#{4d1e55b2-f16f-11cf-88cb-001111000030}

258A/00EA: SINO WEALTH - Gaming  vendorId:      0x258A
  productId:     0x00EA
  usagePage:     0xFF00
  usage:         0x0001
  serial_number: (null)
  interface:     1
  path: \\?\hid#vid_258a&pid_00ea&mi_01&col05#8&3ad4f8ff&0&0004#{4d1e55b2-f16f-11cf-88cb-001111000030}

258A/00EA: SINO WEALTH - Gaming  vendorId:      0x258A
  productId:     0x00EA
  usagePage:     0x0001
  usage:         0x0006
  serial_number: (null)
  interface:     0
  path: \\?\hid#vid_258a&pid_00ea&mi_00#8&2a1e3531&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}\kbd

There are two entries with exactly the same Usage and Usage Pair, but different paths! One of them is actually the one I can use to configure RGB (the \\?\hid#vid_258a&pid_00ea&mi_01&col05#8&3ad4f8ff&0&0004#{4d1e55b2-f16f-11cf-88cb-001111000030} one)

I guess one way I could do is to manually test every entry and keep trying until one succeeds, but there is a risk of bricking involved if one of them accepts but is not the one meant for accepting rgb values..

xcme commented 1 year ago

@rnayabed , Tbh, I'm not expert in this field and haven't seen duplicates before. In my case all pairs are different. And I can't remember how I found the right one. I may have tested them one by one, not sure now. :)

You pointed out to one entry, have you tried it or you're just guessing that this is the right pair? Personally, I think you are probably right. That entry has usagePage 0xFF00. The range FF00-FFFF should mean vendor-defined and in my case the right pair has usagePage that starts from 0xFF as well.