I got a new gaming mouse, a logitech G203 LightSync.
This mouse has RBG LEDs, and is supported by libratbag (also known as its frontend, Piper)
Sadly, for the time being, libratbag cannot control the RGB zones individually, nor enable the rainbow wave animation.
it's very cool and pretty, but not very useful
On Windows, the G Hub software enables some integrations with games. But when you play a game, your hand is on the mouse, so you cannot see the LEDs !
Libratbag provides an Python API as well as a command-line interface, so I can program whatever color, animation (pulse, solid) and brightness I want.
I decided to use the RGB LEDs as a battery indicator:
- fast-pulsing red for
- fast-pulsing orange for
- slow-pulsing green for discharging
- slow-pulsing blue for charging
I can get the battery status through the
psutil Python package.
I also added another feature: a fast-pulsing bright white whenever a notification comes up.
The D-Bus API allows you to not only listen for incoming notifications, but also to listen for the dismissal event. So the notification indicator won't be a dumb timer, but will correctly react to the desktop state.
I didn't implement a timeout for the notification indicator, because my GNOME desktop automatically dimisses notifications (they remain in the notification history).
#!/usr/bin/env python3 from psutil import sensors_battery from piper.ratbagd import Ratbagd, RatbagdLed from time import sleep import dbus from dbus.mainloop.glib import DBusGMainLoop from gi.repository import GLib from threading import Thread STATE_ALARM = 'alarme' STATE_OK = 'ok' STATE_CHARGING = 'charging' STATE_UNPLUG = 'unplug' STATE_NOTIF = 'notif' color_ok = (115, 210, 22) color_alarme = (255, 95, 0) color_unplug = (255, 0, 0) color_charge = (128, 255, 255) color_notif = (255, 255, 255) timing_alarme = 500 timing_ok = 3000 timing_charge = 2000 def set_rgb(color, duration, brightness=200): r = Ratbagd(api_version=1) souris = r.devices profil = souris.profiles led = profil.leds led.mode = RatbagdLed.Mode.BREATHING led.color = color led.brightness = brightness led.effect_duration = duration souris.commit() def apply_state(state): if state == STATE_OK: set_rgb(color_ok, timing_ok) elif state == STATE_ALARM: set_rgb(color_alarme, timing_alarme) elif state == STATE_CHARGING: set_rgb(color_charge, timing_charge) elif state == STATE_UNPLUG: set_rgb(color_unplug, timing_alarme) elif state == STATE_NOTIF: set_rgb(color_notif, timing_alarme) notif = False def handler(bus, msg): print(msg) member = msg.get_member() print(member) global notif if member == 'Notify': notif = True elif member == 'NotificationClosed': notif = False return session_bus = dbus.SessionBus(mainloop=DBusGMainLoop(set_as_default=True)) loop = GLib.MainLoop() session_bus.add_match_string("interface='org.freedesktop.Notifications',eavesdrop='true'") session_bus.add_message_filter(handler) Thread(target=loop.run, daemon=True).start() saved_state = 'err' state = 'err' if __name__ == '__main__': while True: bat = sensors_battery() if bat.percent < 30: new_state = STATE_ALARM if bat.percent >= 30: new_state = STATE_OK if bat.percent < 10: new_state = STATE_UNPLUG if bat.power_plugged: if bat.percent >= 99: new_state = STATE_UNPLUG else: new_state = STATE_CHARGING if notif: new_state = STATE_NOTIF notif = False if new_state != state: print(new_state) state = new_state apply_state(state) saved_state = state sleep(0.5)
Conclusion & disclaimers
This script has only been tested on Ubuntu 20.04 LTS, with the Ubuntu GNOME desktop, and with my Logitech G203 LightSync.
If you have RGB mouse that has multiple LEDs, this script will only use the first one. You can modify the function
set_rgb to use multiple LEDs.
You could even use each LED for a separate indicator, the possibilities are endless !