update for soundboard with global soundfiles
This commit is contained in:
parent
fc08da804f
commit
0eacdbf973
21
app.py
21
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
|
||||
@ -216,10 +229,16 @@ def control_page():
|
||||
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')
|
||||
|
||||
22
configs/sounds.json
Normal file
22
configs/sounds.json
Normal file
@ -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"
|
||||
}
|
||||
]
|
||||
}
|
||||
@ -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 = '<span class="spinner-border spinner-border-sm me-2"></span> 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 = '<i class="bi bi-check-lg me-2"></i> 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);
|
||||
|
||||
|
||||
@ -6,6 +6,16 @@
|
||||
|
||||
<div class="container my-4">
|
||||
|
||||
<!-- Status-Anzeige (oben rechts fixiert) -->
|
||||
<div class="position-fixed top-0 end-0 m-3" style="z-index: 1050;">
|
||||
<div id="connection-status" class="badge bg-secondary px-3 py-2 fs-6">
|
||||
<i class="bi bi-circle-fill me-2 text-muted"></i> Nicht verbunden
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="row">
|
||||
<!-- Linke Spalte: Kanal-Steuerung (8/12 auf lg) -->
|
||||
<div class="col-lg-8">
|
||||
<div class="row mb-4 align-items-center">
|
||||
<div class="col-md-8">
|
||||
<h1 class="mb-1">{{ config.name }}</h1>
|
||||
@ -30,15 +40,8 @@
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Status-Anzeige -->
|
||||
<div class="position-fixed top-0 end-0 m-3" style="z-index: 1050;">
|
||||
<div id="connection-status" class="badge bg-secondary px-3 py-2 fs-6">
|
||||
<i class="bi bi-circle-fill me-2 text-muted"></i> Nicht verbunden
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Connect-Button -->
|
||||
<div class="text-center mb-5" id="connect-section">
|
||||
<!-- Connect-Bereich -->
|
||||
<div id="connect-section" class="text-center mb-5">
|
||||
<button id="connect-btn" class="btn btn-lg btn-success px-5 py-3">
|
||||
<i class="bi bi-bluetooth me-2"></i> Mit Hub verbinden
|
||||
</button>
|
||||
@ -61,8 +64,9 @@
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<!-- Reconnect-Bereich – wird nur angezeigt, wenn Verbindung verloren -->
|
||||
<div class="text-center mt-5" id="reconnect-section" style="display: none;">
|
||||
|
||||
<!-- Reconnect-Bereich – wird nur bei Verbindungsverlust eingeblendet -->
|
||||
<div id="reconnect-section" class="text-center mt-5" style="display: none;">
|
||||
<div class="alert alert-warning">
|
||||
<strong>Verbindung unterbrochen</strong><br>
|
||||
Der Hub reagiert nicht mehr. Bitte erneut verbinden.
|
||||
@ -71,18 +75,64 @@
|
||||
<i class="bi bi-arrow-repeat me-2"></i> Erneut verbinden
|
||||
</button>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<!-- Rechte Spalte: Soundboard (4/12 auf lg) -->
|
||||
<div class="col-lg-4">
|
||||
<div class="card shadow sticky-top" style="top: 20px;">
|
||||
<div class="card-header bg-info text-white">
|
||||
<h5 class="mb-0">Soundboard</h5>
|
||||
</div>
|
||||
<div class="card-body" style="max-height: 70vh; overflow-y: auto;">
|
||||
|
||||
<!-- Lok-spezifische Sounds -->
|
||||
{% if config.sounds and config.sounds|length > 0 %}
|
||||
<h6 class="mt-0 mb-3">Lok-spezifisch</h6>
|
||||
<div class="d-grid gap-2 mb-4">
|
||||
{% for sound in config.sounds %}
|
||||
<button class="btn btn-outline-primary play-sound-btn"
|
||||
data-sound-id="{{ sound.id }}">
|
||||
{{ sound.name }}
|
||||
{% if sound.description %}
|
||||
<small class="d-block text-muted">{{ sound.description }}</small>
|
||||
{% endif %}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
<!-- Globale / Standard-Sounds -->
|
||||
{% if global_sounds and global_sounds|length > 0 %}
|
||||
<h6 class="mt-4 mb-3">Standard-Sounds</h6>
|
||||
<div class="d-grid gap-2">
|
||||
{% for sound in global_sounds %}
|
||||
<button class="btn btn-outline-secondary play-sound-btn"
|
||||
data-sound-id="{{ sound.id }}">
|
||||
{{ sound.name }}
|
||||
{% if sound.description %}
|
||||
<small class="d-block text-muted">{{ sound.description }}</small>
|
||||
{% endif %}
|
||||
</button>
|
||||
{% endfor %}
|
||||
</div>
|
||||
{% endif %}
|
||||
|
||||
{% if (not config.sounds or config.sounds|length == 0) and (not global_sounds or global_sounds|length == 0) %}
|
||||
<p class="text-muted text-center py-4">Keine Sounds konfiguriert</p>
|
||||
{% endif %}
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{% endblock %}
|
||||
|
||||
|
||||
{% block scripts %}
|
||||
<script>
|
||||
// config global verfügbar machen
|
||||
window.mkConfig = {{ config | tojson | safe }};
|
||||
|
||||
console.log("window.mkConfig gesetzt:", window.mkConfig);
|
||||
console.log("Channels:", window.mkConfig?.channels);
|
||||
// Config + globale Sounds direkt ins JS übergeben
|
||||
const config = {{ config | tojson | safe }};
|
||||
const globalSounds = {{ global_sounds | tojson | safe }};
|
||||
window.mkConfig = config; // falls du es global brauchst
|
||||
</script>
|
||||
{% endblock %}
|
||||
Loading…
x
Reference in New Issue
Block a user