updated api.py
This commit is contained in:
parent
e3ef7806c8
commit
0d6e416464
@ -1,30 +1,39 @@
|
|||||||
# app/routes/api.py
|
# app/routes/api.py
|
||||||
|
import os
|
||||||
|
import time
|
||||||
|
import threading
|
||||||
|
import logging
|
||||||
|
|
||||||
import pygame
|
import pygame
|
||||||
from flask import Blueprint, jsonify, request
|
from flask import Blueprint, jsonify, request, current_app
|
||||||
from app.state import current_device, current_config
|
|
||||||
|
import app.state as state
|
||||||
|
from app.bluetooth.manager import MouldKing, advertiser, tracer
|
||||||
|
from app.utils.helpers import load_default_sounds
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
api_bp = Blueprint('api', __name__)
|
api_bp = Blueprint('api', __name__)
|
||||||
|
|
||||||
@api_bp.route('/connect', methods=['POST'])
|
@api_bp.route('/connect', methods=['POST'])
|
||||||
def api_connect():
|
def api_connect():
|
||||||
global current_hub, current_module, current_device
|
if state.current_config is None:
|
||||||
if current_config is None:
|
|
||||||
return jsonify({"success": False, "message": "Keine Konfiguration geladen"}), 400
|
return jsonify({"success": False, "message": "Keine Konfiguration geladen"}), 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
hub_id = int(current_config.get('hub_id', 0))
|
hub_id = int(state.current_config.get('hub_id', 0))
|
||||||
hub_type = current_config.get('hub_type', '6channel') # '4channel' oder '6channel'
|
hub_type = state.current_config.get('hub_type', '6channel') # '4channel' oder '6channel'
|
||||||
|
|
||||||
# Alte Verbindung sauber trennen
|
# Alte Verbindung sauber trennen
|
||||||
if current_device is not None:
|
if state.current_device is not None:
|
||||||
try:
|
try:
|
||||||
current_device.Disconnect()
|
state.current_device.Disconnect()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if current_module is not None:
|
if state.current_module is not None:
|
||||||
# ggf. Stop vor Disconnect
|
# ggf. Stop vor Disconnect
|
||||||
try:
|
try:
|
||||||
current_device.Stop()
|
state.current_device.Stop()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@ -38,21 +47,21 @@ def api_connect():
|
|||||||
|
|
||||||
# Modul holen
|
# Modul holen
|
||||||
if hub_type.lower() in ['6channel', '6']:
|
if hub_type.lower() in ['6channel', '6']:
|
||||||
current_module = mk.Module6_0()
|
state.current_module = mk.Module6_0()
|
||||||
else:
|
else:
|
||||||
current_module = mk.Module4_0()
|
state.current_module = mk.Module4_0()
|
||||||
|
|
||||||
# Device auswählen (hub_id = 0,1,2 → Device0,1,2)
|
# Device auswählen (hub_id = 0,1,2 → Device0,1,2)
|
||||||
device_attr = f'Device{hub_id}'
|
device_attr = f'Device{hub_id}'
|
||||||
if not hasattr(current_module, device_attr):
|
if not hasattr(state.current_module, device_attr):
|
||||||
raise ValueError(f"Hub-ID {hub_id} nicht unterstützt (max 0-2)")
|
raise ValueError(f"Hub-ID {hub_id} nicht unterstützt (max 0-2)")
|
||||||
|
|
||||||
current_device = getattr(current_module, device_attr)
|
state.current_device = getattr(state.current_module, device_attr)
|
||||||
|
|
||||||
# Verbinden
|
# Verbinden
|
||||||
current_device.Connect()
|
state.current_device.Connect()
|
||||||
|
|
||||||
current_hub = mk # falls später noch gebraucht
|
state.current_hub = mk # falls später noch gebraucht
|
||||||
|
|
||||||
logger.info(f"Verbunden: {hub_type} Hub-ID {hub_id} → {device_attr}")
|
logger.info(f"Verbunden: {hub_type} Hub-ID {hub_id} → {device_attr}")
|
||||||
return jsonify({"success": True, "message": f"Hub {hub_id} ({hub_type}) verbunden"})
|
return jsonify({"success": True, "message": f"Hub {hub_id} ({hub_type}) verbunden"})
|
||||||
@ -65,21 +74,20 @@ def api_connect():
|
|||||||
|
|
||||||
@api_bp.route('/reconnect', methods=['POST'])
|
@api_bp.route('/reconnect', methods=['POST'])
|
||||||
def api_reconnect():
|
def api_reconnect():
|
||||||
global current_device, current_module, current_hub
|
if state.current_config is None:
|
||||||
if current_config is None:
|
|
||||||
return jsonify({"success": False, "message": "Keine Konfiguration geladen"}), 400
|
return jsonify({"success": False, "message": "Keine Konfiguration geladen"}), 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Alte Verbindung sauber beenden, falls nötig
|
# Alte Verbindung sauber beenden, falls nötig
|
||||||
if current_device is not None:
|
if state.current_device is not None:
|
||||||
try:
|
try:
|
||||||
current_device.Disconnect()
|
state.current_device.Disconnect()
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
# Neu verbinden (kopierter Code aus api_connect)
|
# Neu verbinden (kopierter Code aus api_connect)
|
||||||
hub_id = int(current_config.get('hub_id', 0))
|
hub_id = int(state.current_config.get('hub_id', 0))
|
||||||
hub_type = current_config.get('hub_type', '6channel')
|
hub_type = state.current_config.get('hub_type', '6channel')
|
||||||
|
|
||||||
mk = MouldKing()
|
mk = MouldKing()
|
||||||
mk.SetAdvertiser(advertiser)
|
mk.SetAdvertiser(advertiser)
|
||||||
@ -89,18 +97,18 @@ def api_reconnect():
|
|||||||
pass
|
pass
|
||||||
|
|
||||||
if hub_type.lower() in ['6channel', '6']:
|
if hub_type.lower() in ['6channel', '6']:
|
||||||
current_module = mk.Module6_0()
|
state.current_module = mk.Module6_0()
|
||||||
else:
|
else:
|
||||||
current_module = mk.Module4_0()
|
state.current_module = mk.Module4_0()
|
||||||
|
|
||||||
device_attr = f'Device{hub_id}'
|
device_attr = f'Device{hub_id}'
|
||||||
if not hasattr(current_module, device_attr):
|
if not hasattr(state.current_module, device_attr):
|
||||||
raise ValueError(f"Hub-ID {hub_id} nicht unterstützt")
|
raise ValueError(f"Hub-ID {hub_id} nicht unterstützt")
|
||||||
|
|
||||||
current_device = getattr(current_module, device_attr)
|
state.current_device = getattr(state.current_module, device_attr)
|
||||||
current_device.Connect()
|
state.current_device.Connect()
|
||||||
|
|
||||||
current_hub = mk
|
state.current_hub = mk
|
||||||
|
|
||||||
logger.info(f"Re-Connect erfolgreich: Hub {hub_id}")
|
logger.info(f"Re-Connect erfolgreich: Hub {hub_id}")
|
||||||
return jsonify({"success": True, "message": "Verbindung wiederhergestellt"})
|
return jsonify({"success": True, "message": "Verbindung wiederhergestellt"})
|
||||||
@ -113,8 +121,7 @@ def api_reconnect():
|
|||||||
|
|
||||||
@api_bp.route('/control', methods=['POST'])
|
@api_bp.route('/control', methods=['POST'])
|
||||||
def api_control():
|
def api_control():
|
||||||
global current_device
|
if state.current_device is None:
|
||||||
if current_device is None:
|
|
||||||
return jsonify({"success": False, "message": "Nicht verbunden"}), 400
|
return jsonify({"success": False, "message": "Nicht verbunden"}), 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
@ -134,7 +141,7 @@ def api_control():
|
|||||||
channel_id = int(port)
|
channel_id = int(port)
|
||||||
|
|
||||||
# Config-spezifische Anpassungen (invert, negative_only, on/off-Werte)
|
# Config-spezifische Anpassungen (invert, negative_only, on/off-Werte)
|
||||||
ch_cfg = next((c for c in current_config['channels'] if c['port'].upper() == port.upper()), None)
|
ch_cfg = next((c for c in state.current_config['channels'] if c['port'].upper() == port.upper()), None)
|
||||||
if ch_cfg:
|
if ch_cfg:
|
||||||
if ch_cfg.get('invert', False):
|
if ch_cfg.get('invert', False):
|
||||||
value = -value
|
value = -value
|
||||||
@ -144,7 +151,7 @@ def api_control():
|
|||||||
value = ch_cfg.get('on_value', 1.0) if value != 0 else ch_cfg.get('off_value', 0.0)
|
value = ch_cfg.get('on_value', 1.0) if value != 0 else ch_cfg.get('off_value', 0.0)
|
||||||
|
|
||||||
# Echter Aufruf!
|
# Echter Aufruf!
|
||||||
current_device.SetChannel(channel_id, value)
|
state.current_device.SetChannel(channel_id, value)
|
||||||
|
|
||||||
logger.info(f"SetChannel({channel_id}, {value:.2f}) → Port {port}")
|
logger.info(f"SetChannel({channel_id}, {value:.2f}) → Port {port}")
|
||||||
return jsonify({"success": True})
|
return jsonify({"success": True})
|
||||||
@ -157,13 +164,12 @@ def api_control():
|
|||||||
|
|
||||||
@api_bp.route('/stop_all', methods=['POST'])
|
@api_bp.route('/stop_all', methods=['POST'])
|
||||||
def api_stop_all():
|
def api_stop_all():
|
||||||
global current_device
|
if state.current_device is None:
|
||||||
if current_device is None:
|
|
||||||
return jsonify({"success": False, "message": "Nicht verbunden"}), 400
|
return jsonify({"success": False, "message": "Nicht verbunden"}), 400
|
||||||
|
|
||||||
try:
|
try:
|
||||||
# Nur stoppen – KEIN Disconnect!
|
# Nur stoppen – KEIN Disconnect!
|
||||||
current_device.Stop()
|
state.current_device.Stop()
|
||||||
logger.info("Alle Kanäle gestoppt (Verbindung bleibt bestehen)")
|
logger.info("Alle Kanäle gestoppt (Verbindung bleibt bestehen)")
|
||||||
return jsonify({"success": True, "message": "Alle Kanäle gestoppt"})
|
return jsonify({"success": True, "message": "Alle Kanäle gestoppt"})
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -174,9 +180,7 @@ def api_stop_all():
|
|||||||
|
|
||||||
@api_bp.route('/status', methods=['GET'])
|
@api_bp.route('/status', methods=['GET'])
|
||||||
def api_status():
|
def api_status():
|
||||||
global current_device
|
if state.current_device is not None:
|
||||||
|
|
||||||
if current_device is not None:
|
|
||||||
return jsonify({
|
return jsonify({
|
||||||
"connected": True,
|
"connected": True,
|
||||||
"message": "Verbunden"
|
"message": "Verbunden"
|
||||||
@ -198,15 +202,20 @@ def api_play_sound():
|
|||||||
if not sound_id:
|
if not sound_id:
|
||||||
return jsonify({"success": False, "message": "Kein sound_id angegeben"}), 400
|
return jsonify({"success": False, "message": "Kein sound_id angegeben"}), 400
|
||||||
|
|
||||||
# Sound aus aktueller Config suchen
|
# Sounds zusammenstellen: lokalspezifisch + globale Default-Sounds
|
||||||
if current_config is None or 'sounds' not in current_config:
|
config_sounds = state.current_config.get('sounds', []) if state.current_config else []
|
||||||
return jsonify({"success": False, "message": "Keine Sounds in der aktuellen Konfiguration"}), 400
|
global_sounds = load_default_sounds(current_app.config['CONFIG_DIR'])
|
||||||
|
all_sounds = list(config_sounds) + list(global_sounds)
|
||||||
|
|
||||||
sound_entry = next((s for s in current_config['sounds'] if s['id'] == sound_id), None)
|
if not all_sounds:
|
||||||
|
return jsonify({"success": False, "message": "Keine Sounds konfiguriert"}), 400
|
||||||
|
|
||||||
|
sound_entry = next((s for s in all_sounds if s.get('id') == sound_id), None)
|
||||||
if not sound_entry:
|
if not sound_entry:
|
||||||
return jsonify({"success": False, "message": f"Sound mit ID '{sound_id}' nicht gefunden"}), 404
|
return jsonify({"success": False, "message": f"Sound mit ID '{sound_id}' nicht gefunden"}), 404
|
||||||
|
|
||||||
file_path = os.path.join('sounds', sound_entry['file'])
|
sounds_dir = current_app.config['SOUNDS_DIR']
|
||||||
|
file_path = os.path.join(sounds_dir, sound_entry['file'])
|
||||||
if not os.path.exists(file_path):
|
if not os.path.exists(file_path):
|
||||||
logger.error(f"Sound-Datei nicht gefunden: {file_path}")
|
logger.error(f"Sound-Datei nicht gefunden: {file_path}")
|
||||||
return jsonify({"success": False, "message": "Sound-Datei nicht gefunden"}), 404
|
return jsonify({"success": False, "message": "Sound-Datei nicht gefunden"}), 404
|
||||||
@ -256,4 +265,4 @@ def api_set_volume():
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
logger.error(f"Volume-Fehler: {e}")
|
logger.error(f"Volume-Fehler: {e}")
|
||||||
return jsonify({"success": False, "message": str(e)}), 500
|
return jsonify({"success": False, "message": str(e)}), 500
|
||||||
pass
|
pass
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user