neu
This commit is contained in:
63
app.py
63
app.py
@@ -1,35 +1,46 @@
|
|||||||
"""
|
"""
|
||||||
moOde Radio Controller
|
moOde Radio Controller
|
||||||
Flask-Webapp zur Steuerung des moOde Audio Players
|
Flask-Webapp zur Steuerung des moOde Audio Players
|
||||||
|
|
||||||
|
Offizielles API-Format (aus setup_guide.md Abschnitt 6.1):
|
||||||
|
Alle Befehle gehen an: GET http://<moode>/command/?cmd=BEFEHL
|
||||||
|
Beispiele:
|
||||||
|
get_currentsong -> aktuellen Song/Sender + Status + Lautstaerke
|
||||||
|
toggle_play_pause -> Play/Stop (Radio) / Play/Pause (Dateien)
|
||||||
|
set_volume N -> Lautstaerke absolut setzen (0-100)
|
||||||
|
set_volume -up N -> Lautstaerke um N erhoehen
|
||||||
|
set_volume -dn N -> Lautstaerke um N verringern
|
||||||
|
set_volume -mute -> Mute umschalten
|
||||||
"""
|
"""
|
||||||
|
|
||||||
import os
|
import os
|
||||||
import requests
|
import requests
|
||||||
from flask import Flask, jsonify, render_template, request
|
from flask import Flask, jsonify, render_template, request
|
||||||
|
|
||||||
# templates/ und static/ immer relativ zur app.py finden,
|
|
||||||
# egal von welchem Verzeichnis aus gestartet wird
|
|
||||||
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
BASE_DIR = os.path.dirname(os.path.abspath(__file__))
|
||||||
app = Flask(__name__, template_folder=os.path.join(BASE_DIR, "templates"))
|
app = Flask(__name__, template_folder=os.path.join(BASE_DIR, "templates"))
|
||||||
|
|
||||||
# moOde Player IP-Adresse – anpassen!
|
MOODE_URL = "http://10.2.196.29"
|
||||||
MOODE_URL = "http://moode.local"
|
MOODE_CMD = f"{MOODE_URL}/command/"
|
||||||
|
|
||||||
|
|
||||||
def moode_cmd(cmd: str, **kwargs) -> dict:
|
def moode_cmd(cmd: str) -> dict:
|
||||||
"""Sendet einen Befehl an die moOde-API."""
|
"""
|
||||||
|
Sendet einen Befehl an die moOde REST API.
|
||||||
|
Offizielles Format: GET /command/?cmd=BEFEHL
|
||||||
|
(entspricht: curl -G -S -s --data-urlencode "cmd=BEFEHL" http://moode/command/)
|
||||||
|
"""
|
||||||
try:
|
try:
|
||||||
params = {"cmd": cmd, **kwargs}
|
r = requests.get(MOODE_CMD, params={"cmd": cmd}, timeout=5)
|
||||||
r = requests.get(f"{MOODE_URL}/engine/index.php", params=params, timeout=5)
|
|
||||||
r.raise_for_status()
|
r.raise_for_status()
|
||||||
try:
|
try:
|
||||||
return {"ok": True, "data": r.json()}
|
return {"ok": True, "data": r.json()}
|
||||||
except Exception:
|
except Exception:
|
||||||
return {"ok": True, "data": r.text}
|
return {"ok": True, "data": r.text.strip()}
|
||||||
except requests.exceptions.ConnectionError:
|
except requests.exceptions.ConnectionError:
|
||||||
return {"ok": False, "error": "moOde nicht erreichbar. IP-Adresse prüfen."}
|
return {"ok": False, "error": f"moOde nicht erreichbar ({MOODE_URL})"}
|
||||||
except requests.exceptions.Timeout:
|
except requests.exceptions.Timeout:
|
||||||
return {"ok": False, "error": "Verbindungs-Timeout."}
|
return {"ok": False, "error": "Verbindungs-Timeout"}
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
return {"ok": False, "error": str(e)}
|
return {"ok": False, "error": str(e)}
|
||||||
|
|
||||||
@@ -41,31 +52,37 @@ def index():
|
|||||||
|
|
||||||
@app.route("/api/play", methods=["POST"])
|
@app.route("/api/play", methods=["POST"])
|
||||||
def play():
|
def play():
|
||||||
result = moode_cmd("play")
|
"""Play/Stop umschalten - bei Radio: play/stop, bei Dateien: play/pause"""
|
||||||
return jsonify(result)
|
return jsonify(moode_cmd("toggle_play_pause"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/stop", methods=["POST"])
|
@app.route("/api/stop", methods=["POST"])
|
||||||
def stop():
|
def stop():
|
||||||
result = moode_cmd("stop")
|
"""Dasselbe Toggle - moOde kennt keinen separaten Stop-Befehl ueber die REST API"""
|
||||||
return jsonify(result)
|
return jsonify(moode_cmd("toggle_play_pause"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/volume", methods=["POST"])
|
@app.route("/api/volume", methods=["POST"])
|
||||||
def volume():
|
def volume():
|
||||||
level = request.json.get("level")
|
level = request.json.get("level")
|
||||||
if level is None or not (0 <= int(level) <= 100):
|
if level is None:
|
||||||
return jsonify({"ok": False, "error": "Ungültige Lautstärke (0–100)."})
|
return jsonify({"ok": False, "error": "Kein Lautstaerke-Wert angegeben."})
|
||||||
result = moode_cmd("vol.set", level=int(level))
|
level = int(level)
|
||||||
return jsonify(result)
|
if not (0 <= level <= 100):
|
||||||
|
return jsonify({"ok": False, "error": "Lautstaerke muss zwischen 0 und 100 liegen."})
|
||||||
|
# Laut Doku: cmd=set_volume N (N = absoluter Wert 0-100)
|
||||||
|
return jsonify(moode_cmd(f"set_volume {level}"))
|
||||||
|
|
||||||
|
|
||||||
@app.route("/api/status")
|
@app.route("/api/status")
|
||||||
def status():
|
def status():
|
||||||
result = moode_cmd("get_currentsong")
|
"""
|
||||||
return jsonify(result)
|
get_currentsong liefert laut Doku volume, mute und state bereits mit -
|
||||||
|
ein einziger API-Aufruf reicht fuer den kompletten Status.
|
||||||
|
"""
|
||||||
|
return jsonify(moode_cmd("get_currentsong"))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
print("moOde Controller gestartet → http://localhost:5555")
|
print(f"moOde Controller gestartet -> http://localhost:5555 (Player: {MOODE_URL})")
|
||||||
app.run(debug=True, host="0.0.0.0", port=5555)
|
app.run(debug=True, host="0.0.0.0", port=5555)
|
||||||
Reference in New Issue
Block a user