I bought myself a new keyboard last November, a Logitech G213. True keyboard fans will tell me it’s not a real mechanical keyboard, but it was a lot cheaper and met my requirements of having some backlighting and a few media keys (really all I use are the volume control keys). Oh, and being a proper UK layout.

While the G213 isn’t fully independent RGB per key it does have a set of zones that can be controlled. Also this has been reverse engineered, so there are tools to do this under Linux. All I really wanted was some basic backlighting to make things a bit nicer in the evenings, but with the ability to control colour I felt I should put it to good use.

As previously mentioned I have a personal desktop / work laptop setup combined with a UGREEN USB 3.0 Sharing Switch Box, so the keyboard is shared between both machines. So I configured up both machines to set the keyboard colour when the USB device is plugged in, and told them to use different colours. Instant visual indication of which machine I’m currently typing on!

Running the script on USB detection is easy, a file in /etc/udev/rules.d/. I called it 99-keyboard-colour.rules:

# Change the keyboard colour when we see it
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="046d", ATTR{idProduct}=="c336", \
        RUN+="/usr/local/sbin/g213-set"

g213-set is a simple bit of Python:

#!/usr/bin/python3

import sys

found = False
devnum = 0
while not found:
    try:
        with open("/sys/class/hidraw/hidraw" + str(devnum) + "/device/uevent") as f:
            for line in f:
                line = line.rstrip()
                if line == 'HID_NAME=Logitech Gaming Keyboard G213':
                    found = True
    except:
        break

    if not found:
        devnum += 1

if not found:
    print("Could not find keyboard device")
    sys.exit(1)

eventfile = "/dev/hidraw" + str(devnum)

#                                   z       r     g     b
command = [ 0x11, 0xff, 0x0c, 0x3a, 0, 1, 0xff, 0xff, 0x00, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ]

with open(eventfile, "wb") as f:
    f.write(bytes(command))

I did wonder about trying to make it turn red when I’m in a root terminal, but that gets a bit more complicated (I’m guessing I need to hook into GNOME Terminal some how?) and this simple hack gives me a significant win anyway.