Files
Gamemax-linux-apps/README.md
T

200 lines
9.1 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# GAMEMAX LCD — Linux bridge & tray app
Drive the LCD panel of a GAMEMAX **IceBurg Digital** AIO cooler from Linux: a small
sender plus a tray application (GUI) with live monitoring, settings and autostart.
Reverse engineered independently from the Windows vendor software
(`PcInfoMonitorPro.exe` / "IceBurg Digital Software"); the protocol notes are in
[`docs/reverse-engineering.md`](docs/reverse-engineering.md) (Indonesian).
[![Release](https://img.shields.io/github/v/release/oxpoe/Gamemax-linux-apps?color=def750&label=release)](https://github.com/oxpoe/Gamemax-linux-apps/releases)
[![License: MIT](https://img.shields.io/badge/license-MIT-def750)](LICENSE)
Author: **oxpoe** · License: **MIT** · Independent project, **not affiliated with the
vendor** — please read [DISCLAIMER.md](DISCLAIMER.md) before using it.
> **Compatibility**
> - **OS:** Linux only (Windows is handled by the vendor software). No kernel module,
> no patched driver — it talks to the standard `hidraw` interface.
> - **Tested on:** CachyOS (Arch) · kernel 7.2.9 · KDE Plasma Wayland · Python 3.14,
> with the panel of a **GAMEMAX IceBurg 240 Digital BK** (HID `5131:2007`,
> vendor-defined usage page `0xFF00`, 64-byte reports).
> - Other IceBurg Digital models/sizes very likely share the same protocol; if a panel
> revision differs, `gamemax_report.py --dry-run` lets you inspect the report without
> writing to the device.
> - The panel keeps animating on its own; the firmware offers **no command to power the
> display off** and **no way to change the logo** — blank mode simply sends zeros.
![Tray app preview](assets/preview.png)
### On real hardware
![GAMEMAX IceBurg 240 Digital LCD driven from Linux](assets/preview-panel.jpg)
*The cooler's LCD while driven by this project on Linux, during protocol testing
(GAMEMAX IceBurg 240 Digital BK).*
### Screen modes
| Normal — sensor values | Blank — zeros (indicator is clear) |
|---|---|
| ![normal](assets/preview.png) | ![blank mode](assets/preview-blank-mode.png) |
## Tested hardware
The target is the **LCD block of an AIO cooler**. Two things confuse people, so they are
stated up front:
1. `lsusb` shows this device as *"MSR MSR-101U Mini HID magnetic card reader"*. That is a
**VID/PID collision in the `usb.ids` database** (the `0x5131` range is shared by cheap
OEM modules), not what the device is. The HID report descriptor is vendor-defined
(`0xFF00`, 64-byte input + 64-byte output, no report IDs) — a card reader or keyboard
looks completely different. Check it yourself:
```bash
cat /sys/class/hidraw/hidraw*/device/report_descriptor | xxd | head
```
2. The panel is not a general monitor. It belongs to one specific cooler family, and its
firmware decides what it renders (two digits, fixed `°C` label, its own animations).
| Component | What it is / what it provides |
|---|---|
| Cooler + LCD panel | **GAMEMAX IceBurg 240 Digital BK** — 240 mm AIO, round 66×45 mm LCD block |
| Panel USB identity | `VID 0x5131` / `PID 0x2007` · USB 1.10 full-speed · 2 × 64-byte interrupt endpoints · `bInterval` 160 ms · no report IDs |
| Vendor software analysed | `PcInfoMonitorPro.exe` **V_1.0.0.04** ("IceBurg 240 Digital Software", [product page](https://gamemaxpc.com/cpu-liquid-cooler/1550.html)) |
| CPU (temperature source) | AMD Ryzen 5 5600 → `k10temp` (`Tctl`, `Tccd1`; the script sends the highest) |
| Motherboard (fan source) | ASUS PRIME B550M-A WIFI II → Nuvoton **`nct6798`** (`fan1..fan7`; only the connected headers read non-zero) |
| GPU | AMD Radeon RX 6600 (Navi 23) → `amdgpu` hwmon (temp, fan, power, busy %) |
| Memory / storage | 32 GB RAM · NVMe root filesystem |
| OS / session | CachyOS (Arch) · kernel 7.2.9 · KDE Plasma on Wayland |
| Tooling | Python 3.14.7 · PySide6 6.12.0 · hidraw (no kernel module, no driver patch) |
Because fan headers differ per board, the fan channel is a **setting**, not a constant:
the GUI lists every `fan*_input` channel with its current RPM and (if the chosen one reads
0 RPM while another spins) tells you which channel to pick. Same idea for the CPU
temperature source (Tctl vs Tccd).
## Features
- Sends CPU temp/load/clock/fan/power, GPU temp/load/clock/fan/power, RAM and disk
usage to the panel as a 65-byte HID report (the layout the firmware understands)
- Reads sensors from standard Linux interfaces: `hwmon`, `/proc/stat`, `cpufreq`,
`/proc/meminfo`, `statvfs` — no extra dependencies (pure Python, stdlib only)
- **Tray app** (`--tray-only`) plus a window with an animated gauge, bars and details
- **Settings**: fan channel (pick the header your fans are on), CPU temperature source,
send/sample interval — saved to `~/.config/gamemax-report/config.json`
- **Clear mode indicators**: green "showing sensor data" / orange "blank (zeros)" /
grey "sending stopped", dimmed tray icon and a desktop notification per change
- **Autostart** via a systemd user unit (equivalent of the vendor's Task Scheduler trick)
- **Plug and play**: the service waits for the device, streams while present and keeps
waiting through unplug/replug; a udev rule grants access to the logged-in user
- **Single instance**: launching the app again just raises the running window
- **AppImage build** script (`packaging/build_appimage.sh`, PySide6 bundled)
The GUI labels are in Indonesian.
## Requirements
- A GAMEMAX IceBurg Digital panel connected over USB (VID `0x5131`, PID `0x2007`)
- `hidraw` access for your user (see the udev rule in *Install*)
- Linux with a working `hidraw` stack (tested on CachyOS / Arch, KDE Wayland)
- Python 3.10+ for the sender (stdlib only)
- For the tray app: PySide6 (`uv run --with pyside6 python src/gamemax_gui.py`)
or use the prebuilt AppImage
## Install
```bash
# 1. device access for the logged-in user (once, needs root)
sudo cp packaging/70-gamemax.rules /etc/udev/rules.d/
sudo udevadm control --reload && sudo udevadm trigger --subsystem-match=hidraw
# 2. try it without installing anything
cd src
python3 gamemax_report.py --dry-run # build and print a report, no device writes
python3 gamemax_report.py --listen 5 # read panel -> host reports (none on this panel)
# 3. send for real
python3 gamemax_report.py --count 3 # a few reports
python3 gamemax_report.py # keep streaming (Ctrl-C to stop)
```
## Run as a background service (autostart + plug and play)
```bash
mkdir -p ~/.local/share/gamemax-report ~/.config/systemd/user
cp src/gamemax_report.py ~/.local/share/gamemax-report/
cp packaging/gamemax-report.service ~/.config/systemd/user/
systemctl --user daemon-reload
systemctl --user enable --now gamemax-report.service
journalctl --user -u gamemax-report -f # shows "waiting for 0x5131:0x2007" / "opened ..."
```
The tray app can do all of this for you (buttons *Pasang / perbarui layanan*,
*Mulai otomatis saat login*).
## Tray app / AppImage
**Download (recommended):** grab `GAMEMAX-LCD-x86_64.AppImage` from
[Releases](../../releases) — it bundles PySide6, the sender script and the icon, and is
built automatically from source by `.github/workflows/release.yml`.
```bash
chmod +x GAMEMAX-LCD-x86_64.AppImage
./GAMEMAX-LCD-x86_64.AppImage --selftest # verify it starts (no display needed)
./GAMEMAX-LCD-x86_64.AppImage # window + tray
# or run from source
uv run --with pyside6 python src/gamemax_gui.py # window + tray
uv run --with pyside6 python src/gamemax_gui.py --tray-only
bash packaging/build_appimage.sh # -> dist/GAMEMAX-LCD-x86_64.AppImage
```
## Protocol (verified on hardware)
VID `0x5131` / PID `0x2007`, vendor-defined HID page `0xFF00`, 64-byte IN + 64-byte OUT,
no report IDs. The host sends 64 data bytes:
| Offset | Field | Notes |
|---|---|---|
| 0 | report ID | always 0 |
| 1 | 64 | payload length |
| 2 | CPU temp | 0..99 °C, two digits only; values ≥ 128 are ignored by firmware |
| 3 | CPU load % | |
| 4..5 | RPM slot | big-endian u16 — the panel shows *this* field next to the fan icon |
| 6..7 | CPU clock MHz | big-endian u16 |
| 8..9 | CPU power W | big-endian u16 |
| 10 | GPU temp | 0..99 °C |
| 11 | GPU load % | |
| 12..13 | GPU clock MHz | big-endian u16 |
| 14..15 | GPU fan RPM | big-endian u16 |
| 16..17 | GPU power W | big-endian u16 |
| 18 | RAM usage % | |
| 19..20 | total RAM MiB | big-endian u16 |
| 21 | disk free % | |
| 22..23 | total disk GB | big-endian u16 |
| 24..64 | unused | zero |
Firmware behaviours worth knowing: the panel latches values it accepts, blinks the
value area when the data stops changing, cannot display three digits, has a fixed `°C`
label, and offers no command to power the display off.
## Repository layout
```
src/ gamemax_report.py (sender) gamemax_gui.py (tray app) icon.png
packaging/ build_appimage.sh 70-gamemax.rules gamemax-report.service
tools/ ildump.py, string_refs.py — helpers used to read the vendor MSIL
docs/ reverse-engineering.md — full analysis (Indonesian)
assets/ previews and icon
```
## Credits
Reverse engineered and written by **oxpoe**, with the help of
[REA](https://github.com/morluto/rea) (managed-code analysis) and Ghidra.
Not affiliated with GAMEMAX/GameMax — see [DISCLAIMER.md](DISCLAIMER.md).