111 lines
3.7 KiB
JavaScript
111 lines
3.7 KiB
JavaScript
const broNameInput = document.getElementById('bro-name');
|
|
const picoKeyInput = document.getElementById('pico-key');
|
|
const brainUrlInput = document.getElementById('brain-url');
|
|
const wakeWordSelect = document.getElementById('wake-word');
|
|
const customWakeWordInput = document.getElementById('custom-wake-word');
|
|
const audioIndexInput = document.getElementById('audio-index');
|
|
const saveBtn = document.getElementById('save-btn');
|
|
const statusBadge = document.getElementById('status-badge');
|
|
const toast = document.getElementById('toast');
|
|
const uptimeEl = document.getElementById('uptime');
|
|
|
|
// Toggle custom wake-word input
|
|
wakeWordSelect.addEventListener('change', () => {
|
|
customWakeWordInput.style.display = wakeWordSelect.value === 'custom' ? 'block' : 'none';
|
|
});
|
|
|
|
async function fetchConfig() {
|
|
try {
|
|
const res = await fetch('/config');
|
|
const data = await res.json();
|
|
broNameInput.value = data.bro_name || '';
|
|
picoKeyInput.value = data.pico_key || '';
|
|
brainUrlInput.value = data.brain_url || '';
|
|
wakeWordSelect.value = data.wake_word || 'porcupine';
|
|
customWakeWordInput.value = data.custom_wake_word_path || '';
|
|
audioIndexInput.value = data.audio_index || '';
|
|
|
|
if (wakeWordSelect.value === 'custom') {
|
|
customWakeWordInput.style.display = 'block';
|
|
}
|
|
|
|
checkBrainStatus(data.brain_url);
|
|
} catch (err) {
|
|
console.error('Failed to fetch config', err);
|
|
}
|
|
}
|
|
|
|
async function checkBrainStatus(url) {
|
|
if (!url) {
|
|
statusBadge.textContent = 'Bereit';
|
|
statusBadge.className = 'badge checking';
|
|
return;
|
|
}
|
|
|
|
try {
|
|
const res = await fetch(`/check-brain?url=${encodeURIComponent(url)}`);
|
|
const data = await res.json();
|
|
if (data.online) {
|
|
statusBadge.textContent = 'Brain Online';
|
|
statusBadge.className = 'badge online';
|
|
} else {
|
|
statusBadge.textContent = 'Brain Offline';
|
|
statusBadge.className = 'badge offline';
|
|
showToast('Brain konnte nicht erreicht werden!', true);
|
|
}
|
|
} catch (err) {
|
|
statusBadge.textContent = 'Brain Offline';
|
|
statusBadge.className = 'badge offline';
|
|
showToast('Verbindung zum Brain fehlgeschlagen!', true);
|
|
}
|
|
}
|
|
|
|
saveBtn.addEventListener('click', async () => {
|
|
saveBtn.classList.add('loading');
|
|
|
|
const config = {
|
|
bro_name: broNameInput.value,
|
|
pico_key: picoKeyInput.value,
|
|
brain_url: brainUrlInput.value,
|
|
wake_word: wakeWordSelect.value,
|
|
custom_wake_word_path: customWakeWordInput.value,
|
|
audio_index: audioIndexInput.value
|
|
};
|
|
|
|
try {
|
|
const res = await fetch('/config', {
|
|
method: 'POST',
|
|
headers: { 'Content-Type': 'application/json' },
|
|
body: JSON.stringify(config)
|
|
});
|
|
|
|
if (res.ok) {
|
|
showToast('Einstellungen gespeichert!');
|
|
checkBrainStatus(config.brain_url);
|
|
}
|
|
} catch (err) {
|
|
showToast('Fehler beim Speichern!', true);
|
|
} finally {
|
|
saveBtn.classList.remove('loading');
|
|
}
|
|
});
|
|
|
|
function showToast(msg, isError = false) {
|
|
toast.textContent = msg;
|
|
toast.style.background = isError ? 'var(--error)' : 'var(--success)';
|
|
toast.classList.add('show');
|
|
setTimeout(() => toast.classList.remove('show'), 3000);
|
|
}
|
|
|
|
// Simple uptime ticker
|
|
let seconds = 0;
|
|
setInterval(() => {
|
|
seconds++;
|
|
const h = Math.floor(seconds / 3600).toString().padStart(2, '0');
|
|
const m = Math.floor((seconds % 3600) / 60).toString().padStart(2, '0');
|
|
const s = (seconds % 60).toString().padStart(2, '0');
|
|
uptimeEl.textContent = `${h}:${m}:${s}`;
|
|
}, 1000);
|
|
|
|
fetchConfig();
|