superx-goes-arch/tools/superx-ctrl-menu.py
Kay Türtscher 1738820df5 feat: add ONEXPLAYER SUPER X support to oxp-sensors + Super X Control tools
- Patched oxpec.c with DMI match for 'ONEXPLAYER SUPER X' (oxp_x1)
- Added DKMS build files (dkms.conf, Makefile)
- Added superx-ctrl-menu.py (yad-based GUI menu)
- Added superx-tray.py (Qt6 system tray, optional)
- Fixed frostbay_ble.py path in superx-ctrl.py
2026-06-20 06:33:39 +02:00

183 lines
7 KiB
Python

#!/usr/bin/env python3
"""
Super X Control - CLI Menu (zenity)
Einfach, robust, funktioniert immer.
Starte mit: python3 superx-ctrl-menu.py
"""
import sys
import os
import subprocess
import json
CTRL = os.path.expanduser("~/Projekte/superx-goes-arch/tools/superx-ctrl.py")
def run_cmd(*args):
try:
r = subprocess.run([sys.executable, CTRL] + list(args),
capture_output=True, text=True, timeout=10)
if r.returncode == 0 and r.stdout.strip():
return json.loads(r.stdout)
return {"ok": False, "error": r.stderr}
except Exception as e:
return {"ok": False, "error": str(e)}
def zenity_list(title, text, columns, items):
"""Zeigt eine zenity-Liste und gibt die Auswahl zurück."""
cols = "--column=" + " --column=".join(columns)
args = ["zenity", "--list", "--title=" + title, "--text=" + text,
"--width=400", "--height=400", cols]
for item in items:
args.append(str(item))
try:
r = subprocess.run(args, capture_output=True, text=True, timeout=30)
if r.returncode == 0:
return r.stdout.strip()
return None
except:
return None
def zenity_scale(title, text, value=50):
"""Zeigt einen Schieberegler."""
try:
r = subprocess.run(
["zenity", "--scale", "--title=" + title, "--text=" + text,
"--value=" + str(value), "--min-value=0", "--max-value=100",
"--step=5", "--width=400"],
capture_output=True, text=True, timeout=30)
if r.returncode == 0 and r.stdout.strip():
return int(r.stdout.strip())
return None
except:
return None
def zenity_question(text):
"""Ja/Nein Frage."""
try:
r = subprocess.run(
["zenity", "--question", "--text=" + text, "--width=300"],
capture_output=True, timeout=30)
return r.returncode == 0
except:
return False
def main_menu():
while True:
choice = zenity_list(
"Super X Control",
"Wähle eine Aktion:",
["Option"],
[
"❄️ Cooling Mode",
"🎮 Custom Fan/Pump",
"🌈 Frostbay RGB",
"💡 Tablet RGB",
"📊 Status",
"❌ Beenden"
]
)
if not choice or "Beenden" in choice:
break
elif "Cooling" in choice:
mode = zenity_list(
"Cooling Mode",
"Wähle Kühlmodus:",
["Modus"],
["⏹️ Off", "🔇 Silent", "🌬️ Gentle", "💨 Strong", "🚀 Extreme", "🤖 Smart"]
)
if mode:
mid = mode.split()[-1].lower()
if mid == "off": mid = "off"
elif mid == "silent": mid = "silent"
elif mid == "gentle": mid = "gentle"
elif mid == "strong": mid = "strong"
elif mid == "extreme": mid = "extreme"
elif mid == "smart": mid = "smart"
result = run_cmd("mode", mid)
if result.get("ok"):
subprocess.run(["notify-send", "Super X", f"Mode: {mid}"])
else:
subprocess.run(["notify-send", "-u", "critical", "Super X", f"Fehler: {result.get('error', '?')}"])
elif "Custom" in choice:
# Beide Regler in einem Fenster
try:
r = subprocess.run(
["yad", "--form", "--title=Lüfter & Pumpe",
"--text=Stelle Lüfter und Pumpe ein:",
"--field=Lüfter:SCL", "0:100:30",
"--field=Pumpe:SCL", "0:100:30",
"--width=400", "--button=Abbrechen:1", "--button=Anwenden:0"],
capture_output=True, text=True, timeout=60
)
if r.returncode == 0 and r.stdout.strip():
parts = r.stdout.strip().split("|")
if len(parts) >= 2:
fan = int(float(parts[0].strip()))
pump = int(float(parts[1].strip()))
result = run_cmd("custom", str(fan), str(pump))
if result.get("ok"):
subprocess.run(["notify-send", "Super X", f"Fan: {fan}% | Pump: {pump}%"])
else:
subprocess.run(["notify-send", "-u", "critical", "Super X", f"Fehler: {result.get('error', '?')}"])
except Exception as e:
subprocess.run(["notify-send", "-u", "critical", "Super X", f"Fehler: {e}"])
elif "Frostbay" in choice:
preset = zenity_list(
"Frostbay RGB",
"Wähle RGB-Preset:",
["Preset"],
["1 Static", "2 Breath", "3 Wave", "4 Strobe",
"5 Rainbow", "6 Marquee", "7 Meteor", "8 Fire",
"9 Aurora", "10 Pulse", "---", "RGB ON", "RGB OFF"]
)
if preset:
if "ON" in preset:
run_cmd("rgb-on")
subprocess.run(["notify-send", "Super X", "RGB ON"])
elif "OFF" in preset:
run_cmd("rgb-off")
subprocess.run(["notify-send", "Super X", "RGB OFF"])
elif preset.strip():
pid = preset.split()[0]
result = run_cmd("rgb-preset", pid)
if result.get("ok"):
subprocess.run(["notify-send", "Super X", f"RGB Preset: {pid}"])
elif "Tablet" in choice:
action = zenity_list(
"Tablet RGB",
"Wähle Aktion:",
["Aktion"],
["An", "Aus", "Regenbogen", "Aurora", "Farbe wählen"]
)
if action:
if action == "Farbe wählen":
color = zenity_list(
"Farbe",
"Wähle Farbe:",
["Farbe"],
["Rot", "Grün", "Blau", "Gelb", "Lila", "Weiß"]
)
if color:
colors = {"Rot": "255 0 0", "Grün": "0 255 0", "Blau": "0 0 255",
"Gelb": "255 255 0", "Lila": "255 0 255", "Weiß": "255 255 255"}
run_cmd("tablet", colors.get(color, "255 255 255"))
subprocess.run(["notify-send", "Super X", f"Tablet: {color}"])
else:
cmd = action.lower()
run_cmd("tablet", cmd)
subprocess.run(["notify-send", "Super X", f"Tablet: {action}"])
elif "Status" in choice:
result = run_cmd("status")
if result.get("ok"):
subprocess.run(["notify-send", "Super X", "Status OK ✓"])
else:
subprocess.run(["notify-send", "-u", "critical", "Super X", f"Fehler: {result.get('error', '?')}"])
if __name__ == "__main__":
main_menu()