- 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
183 lines
7 KiB
Python
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()
|