diff --git a/app.py b/app.py index 66932f8..4dcf2cc 100644 --- a/app.py +++ b/app.py @@ -35,6 +35,19 @@ def cleanup_old_log_dirs(max_age_days=90): except Exception as e: logger.error(f"Fehler beim Löschen von {subdir_path}: {e}") +# ── Hilfsfunktion - globale Sounds laden ──────────────────────────────────────────────────────────────── +def load_global_sounds(): + global_sounds_path = os.path.join(app.root_path, 'sounds.json') # oder configs/sounds.json + if os.path.exists(global_sounds_path): + try: + with open(global_sounds_path, 'r', encoding='utf-8') as f: + data = json.load(f) + return data.get('global_sounds', []) + except Exception as e: + logger.error(f"Fehler beim Laden globaler Sounds: {e}") + return [] + return [] + # ── Bluetooth ──────────────────────────────────────────────────────────────── from mkconnect.mouldking.MouldKing import MouldKing from mkconnect.tracer.TracerConsole import TracerConsole @@ -215,11 +228,17 @@ def control_page(): if current_config is None: logger.warning("current_config ist None → Redirect zu index") return redirect(url_for('index')) + + global_sounds = load_global_sounds() logger.info(f"Übergebe config an Template: {current_config}") print("DEBUG: config hat channels?", 'channels' in current_config, len(current_config.get('channels', []))) - return render_template('control.html', config=current_config) + return render_template( + 'control.html', + config=current_config, + global_sounds=global_sounds + ) @app.route('/soundboard') diff --git a/configs/sounds.json b/configs/sounds.json new file mode 100644 index 0000000..782bb5d --- /dev/null +++ b/configs/sounds.json @@ -0,0 +1,22 @@ +{ + "global_sounds": [ + { + "id": "pfeife_lang", + "file": "pfeife_lang.wav", + "name": "Pfeife lang", + "description": "Langgezogene Dampflok-Pfeife" + }, + { + "id": "dampf_ausstoß", + "file": "dampf_ausstoß.mp3", + "name": "Dampfausstoß", + "description": "Kurzes Zischen" + }, + { + "id": "bahnhof_ankunft", + "file": "bahnhof_ankunft.mp3", + "name": "Bahnhofsankunft", + "description": "Stationsansage + Bremsquietschen" + } + ] +} \ No newline at end of file diff --git a/static/js/app.js b/static/js/app.js index 231d1ac..262620e 100644 --- a/static/js/app.js +++ b/static/js/app.js @@ -307,6 +307,47 @@ document.addEventListener('DOMContentLoaded', () => { } } +// ── Soundboard Buttons ───────────────────────────────────────────────────── +document.querySelectorAll('.play-sound-btn').forEach(btn => { + btn.addEventListener('click', async () => { + const soundId = btn.dataset.soundId; + btn.disabled = true; + const originalText = btn.innerHTML; + btn.innerHTML = ' Spielt...'; + + try { + const res = await fetch('/api/play_sound', { + method: 'POST', + headers: { 'Content-Type': 'application/json' }, + body: JSON.stringify({ sound_id: soundId }) + }); + + const data = await res.json(); + + if (data.success) { + btn.classList.remove('btn-outline-primary', 'btn-outline-secondary'); + btn.classList.add('btn-success'); + btn.innerHTML = ' Gespielt'; + setTimeout(() => { + btn.classList.remove('btn-success'); + btn.classList.add('btn-outline-primary'); // oder secondary + btn.innerHTML = originalText; + btn.disabled = false; + }, 2000); + } else { + alert('Fehler: ' + (data.message || 'Unbekannt')); + btn.disabled = false; + btn.innerHTML = originalText; + } + } catch (err) { + console.error('Sound-Play-Fehler:', err); + alert('Netzwerkfehler beim Abspielen'); + btn.disabled = false; + btn.innerHTML = originalText; + } + }); +}); + // Initialer Status updateStatus(false); diff --git a/templates/control.html b/templates/control.html index 4a00532..a9b6382 100644 --- a/templates/control.html +++ b/templates/control.html @@ -6,83 +6,133 @@
-
-
-

{{ config.name }}

-

- Hub-ID: {{ config.hub_id | default('unbekannt') }} • - Typ: {{ config.hub_type | default('unbekannt') }} • - Datei: {{ config.filename }} -

-
-
- {% if config.image %} - {{ config.name }} - {% else %} -
- -
- {% endif %} + +
+
+ Nicht verbunden
- -
-
- Nicht verbunden +
+ +
+
+
+

{{ config.name }}

+

+ Hub-ID: {{ config.hub_id | default('unbekannt') }} • + Typ: {{ config.hub_type | default('unbekannt') }} • + Datei: {{ config.filename }} +

-
+
+ {% if config.image %} + {{ config.name }} + {% else %} +
+ +
+ {% endif %} +
+
- -
- -

Stelle sicher, dass der Hub eingeschaltet ist und im Bluetooth-Modus ausgewählt wurde.

-
+ +
+ +

Stelle sicher, dass der Hub eingeschaltet ist und im Bluetooth-Modus ausgewählt wurde.

+
- - + +
+
+
+
Soundboard
+
+
+ + + {% if config.sounds and config.sounds|length > 0 %} +
Lok-spezifisch
+
+ {% for sound in config.sounds %} + + {% endfor %} +
+ {% endif %} + + + {% if global_sounds and global_sounds|length > 0 %} +
Standard-Sounds
+
+ {% for sound in global_sounds %} + + {% endfor %} +
+ {% endif %} + + {% if (not config.sounds or config.sounds|length == 0) and (not global_sounds or global_sounds|length == 0) %} +

Keine Sounds konfiguriert

+ {% endif %} +
+
+
+
{% endblock %} - {% block scripts %} {% endblock %} \ No newline at end of file