{"id":50965079,"url":"https://github.com/stableflux/steelseries-apex-roller","last_synced_at":"2026-06-18T19:01:50.360Z","repository":{"id":359102973,"uuid":"1244535252","full_name":"StableFlux/steelseries-apex-roller","owner":"StableFlux","description":"Remap the SteelSeries Apex Pro Gen 3 volume roller and media button to per-channel Sonar control (Game/Chat/Media/Aux), with live UI sync and OLED feedback. Windows tray app.","archived":false,"fork":false,"pushed_at":"2026-05-20T13:27:52.000Z","size":60,"stargazers_count":0,"open_issues_count":0,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-05-20T15:40:52.841Z","etag":null,"topics":["apex-pro","apex-pro-gen-3","audio","audio-mixer","gamesense","keyboard","media-keys","oled","pyinstaller","python","sonar","steelseries","system-tray","tray-app","volume-control","websocket","windows"],"latest_commit_sha":null,"homepage":"https://github.com/StableFlux/steelseries-apex-roller/releases/latest","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/StableFlux.png","metadata":{"files":{"readme":"README.md","changelog":"CHANGELOG.md","contributing":null,"funding":".github/FUNDING.yml","license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":"SECURITY.md","support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null},"funding":{"buy_me_a_coffee":"stableflux"}},"created_at":"2026-05-20T11:03:35.000Z","updated_at":"2026-05-20T13:28:20.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/StableFlux/steelseries-apex-roller","commit_stats":null,"previous_names":["stableflux/steelseries-apex-roller"],"tags_count":4,"template":false,"template_full_name":null,"purl":"pkg:github/StableFlux/steelseries-apex-roller","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StableFlux%2Fsteelseries-apex-roller","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StableFlux%2Fsteelseries-apex-roller/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StableFlux%2Fsteelseries-apex-roller/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StableFlux%2Fsteelseries-apex-roller/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/StableFlux","download_url":"https://codeload.github.com/StableFlux/steelseries-apex-roller/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/StableFlux%2Fsteelseries-apex-roller/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":34503511,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-05-26T15:22:16.424Z","status":"online","status_checked_at":"2026-06-18T02:00:06.871Z","response_time":128,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["apex-pro","apex-pro-gen-3","audio","audio-mixer","gamesense","keyboard","media-keys","oled","pyinstaller","python","sonar","steelseries","system-tray","tray-app","volume-control","websocket","windows"],"created_at":"2026-06-18T19:01:48.001Z","updated_at":"2026-06-18T19:01:50.354Z","avatar_url":"https://github.com/StableFlux.png","language":"Python","funding_links":["https://buymeacoffee.com/stableflux"],"categories":[],"sub_categories":[],"readme":"# Apex Roller\n\n[![Latest release](https://img.shields.io/github/v/release/StableFlux/steelseries-apex-roller?label=release\u0026color=blue)](https://github.com/StableFlux/steelseries-apex-roller/releases/latest)\n[![Downloads](https://img.shields.io/github/downloads/StableFlux/steelseries-apex-roller/total?color=brightgreen)](https://github.com/StableFlux/steelseries-apex-roller/releases)\n[![License: MIT](https://img.shields.io/badge/license-MIT-yellow.svg)](LICENSE)\n[![Platform: Windows](https://img.shields.io/badge/platform-Windows%2010%2F11-0078D4)](#requirements)\n[![Build](https://github.com/StableFlux/steelseries-apex-roller/actions/workflows/release.yml/badge.svg)](https://github.com/StableFlux/steelseries-apex-roller/actions/workflows/release.yml)\n\nRemap the SteelSeries Apex Pro Gen 3 volume roller and media button to control\nSteelSeries Sonar channels instead of Windows master volume — with live UI\nsync, OLED feedback, and no driver hacks.\n\n\u003cp align=\"center\"\u003e\n  If this app is useful to you, a coffee is always appreciated ❤\u003cbr\u003e\u003cbr\u003e\n  \u003ca href=\"https://buymeacoffee.com/stableflux\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" width=\"200\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n\u003c!--\nScreenshot placeholder: add an image at docs/screenshot.png showing the\nkeyboard OLED + the Sonar GG window with the matching slider, and replace\nthis comment with:\n\n![Apex Roller in action](docs/screenshot.png)\n--\u003e\n\n\n## What it does\n\nWhen SteelSeries GG with Sonar is running, the Apex Pro's roller and media\nbutton normally just move the Windows master volume slider. That collides\nwith Sonar's virtual-audio setup: you wanted per-channel control, you got\nmaster.\n\nThis app sits between the keyboard and Windows:\n\n- **Media button** cycles through Sonar's channels. By default\n  (Streamer mode): **Game → Chat → Media → Aux**, monitoring sliders only.\n  Two tray toggles extend this:\n  - *Include Master channel* — adds Master to the cycle.\n  - *Include Streaming sliders* — gives every channel two positions\n    (monitoring first, then streaming), so you can dial in the broadcast\n    feed independently of what you hear locally.\n  Both off by default; choices persist across launches.\n- **Roller up/down** adjusts the active channel's volume.\n- **OLED** on the keyboard shows the active channel and current level.\n- **Sonar GG UI sliders move live**, in real time, exactly as if you were\n  dragging them with the mouse.\n- The original Windows-master behaviour is preserved on any *other*\n  keyboard you plug in — we only intercept events the SteelSeries software\n  synthesizes from the Apex Pro itself (LLKHF_INJECTED).\n\nAudio engine, OLED, and the Sonar GG visual sliders all stay in sync.\n\n## Requirements\n\n- Windows 10/11\n- SteelSeries Apex Pro Gen 3 (or any Apex Pro variant with the OLED + roller)\n- [SteelSeries GG](https://steelseries.com/gg) installed, with **Sonar enabled**\n- Sonar in **Streamer mode** for full feature coverage (Classic mode currently\n  drives audio + OLED but not live-UI redraw — see Known limitations)\n\n## Install\n\n1. Grab `apex-roller-setup-vX.Y.Z.exe` from the\n   [Releases](https://github.com/StableFlux/steelseries-apex-roller/releases) page.\n2. Run it (UAC prompt — the installer needs admin to write to Program Files).\n   Tick **Launch Apex Roller automatically at Windows startup** in the wizard\n   if you want it on at login (recommended).\n3. The Apex Roller tray icon appears in the system tray. You're done.\n\nUninstall any time via **Settings \u003e Apps \u003e Installed apps \u003e Apex Roller \u003e Uninstall**.\n\nPer-user config and logs live in `%LocalAppData%\\ApexRoller\\`.\n\n## Tray menu\n\n- **Pause** — temporarily passes roller/media events through to Windows\n  (master volume + media play/pause behave normally).\n- **Include Master channel** — adds Sonar's Master entry to the cycle.\n  Off by default.\n- **Include Streaming sliders** — each channel becomes two cycle positions\n  (monitoring, then streaming). Off by default.\n- **Run at Startup** — toggles a shortcut in your per-user Startup folder.\n- **Check for Updates** — opens the Releases page so you can grab a newer\n  build if there is one.\n- **Open Logs Folder** — Explorer to `%LocalAppData%\\ApexRoller\\logs\\`.\n- **Quit** — exit; OLED returns to its default content.\n\nSettings are saved to `%LocalAppData%\\ApexRoller\\config.json`.\n\n## How it works (briefly)\n\nThree local APIs do the heavy lifting:\n\n1. **A `WH_KEYBOARD_LL` hook** intercepts the volume/media VK events that\n   SteelSeries GG synthesizes from the Apex Pro roller, before they reach\n   Windows. We swallow them so master volume stays put.\n2. **The Sonar REST API** at `http://127.0.0.1:50166/volumeSettings/...`\n   (discovered via `coreProps.json` → GG `/subApps`) applies the new value\n   to the audio engine.\n3. **GG core's `/eventing` WebSocket** at `wss://127.0.0.1:6327/eventing`\n   gets an `EVENT_SUB_APP_ACTIONS_DATA_CHANGED` event for the matching\n   action name (`MONITOR_GAME_VOLUME`, etc.). Sonar's internal action\n   handler picks it up and broadcasts `SONAR_EVENT_VOLUME_DATA` over its\n   own `/sock` channel, which is what the GG UI listens to — so the\n   slider repaints live.\n\nThe OLED display uses the SteelSeries\n[GameSense SDK](https://github.com/SteelSeries/gamesense-sdk) at\n`http://127.0.0.1:50063` with a `screened` device handler.\n\n## Known limitations\n\n- **Classic-mode live UI sync is not wired.** In Classic mode, Sonar's\n  internal `VolumeActionProvider` only exposes the mic-mute action as a\n  typed action; the other classic-mode volumes don't have an\n  `EVENT_SUB_APP_ACTIONS_DATA_CHANGED` action name we can target. Audio\n  and OLED still work in Classic mode — only the GG UI sliders won't\n  update live. Run Sonar in Streamer mode for the full experience.\n- **No auto-update yet.** Check Releases for new versions manually.\n- **Sonar API is community-documented, not officially supported by\n  SteelSeries.** It could change in a future GG release. The app re-reads\n  `coreProps.json` and re-discovers endpoints on each connection error,\n  but a major schema change would still break us.\n\n## Build from source\n\n```powershell\ngit clone https://github.com/StableFlux/steelseries-apex-roller.git\ncd steelseries-apex-roller\npython -m venv .venv\n.venv\\Scripts\\Activate.ps1\npip install -r requirements.txt\n\n# Dev run (console mode, shows logs)\npython -m apex_roller --no-tray\n\n# Tray run\npython -m apex_roller --tray\n\n# Build the redistributable .exe\npython build.py\n# -\u003e dist\\apex-roller.exe\n```\n\nThe `probes/` directory contains the small validation scripts used while\nbuilding each layer — useful for debugging.\n\n## Community\n\n- **Questions / usage help** → [Discussions](https://github.com/StableFlux/steelseries-apex-roller/discussions)\n- **Bugs** → [open an issue](https://github.com/StableFlux/steelseries-apex-roller/issues/new/choose)\n- **Security reports** → see [SECURITY.md](SECURITY.md)\n- **Changes per release** → [CHANGELOG.md](CHANGELOG.md)\n\n## Support the project\n\nApex Roller is free and open source. If it saved you from having your game,\nchat, and Spotify volumes all glued to Windows master, a coffee is always\nappreciated — it keeps the updates coming.\n\n\u003cp align=\"center\"\u003e\n  \u003ca href=\"https://buymeacoffee.com/stableflux\"\u003e\u003cimg src=\"https://cdn.buymeacoffee.com/buttons/v2/default-yellow.png\" alt=\"Buy Me A Coffee\" width=\"200\"/\u003e\u003c/a\u003e\n\u003c/p\u003e\n\n## License\n\n[MIT](LICENSE) © StableFlux\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstableflux%2Fsteelseries-apex-roller","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fstableflux%2Fsteelseries-apex-roller","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fstableflux%2Fsteelseries-apex-roller/lists"}