Emergency Stop
This commit is contained in:
@@ -173,6 +173,91 @@ document.addEventListener('DOMContentLoaded', function() {
|
||||
.catch(err => console.error('Error fetching robot history:', err));
|
||||
}
|
||||
|
||||
// ── Emergency Stop Panel ─────────────────────────────────────────────
|
||||
|
||||
// SVG-Button: Farbe + Text + Click-Handler je nach armed-Zustand wechseln.
|
||||
// armed=true → rot "EMERGENCY STOP" → POST /api/emergency-stop
|
||||
// armed=false → grün "START ROBOT" → POST /api/power-on
|
||||
let _lastArmed = null;
|
||||
|
||||
function updateEmergencyStopButton(armed) {
|
||||
if (armed === _lastArmed) return;
|
||||
_lastArmed = armed;
|
||||
|
||||
const stops = document.querySelectorAll('#estopGrad stop');
|
||||
const textPath = document.querySelector('#emergency-stop textPath');
|
||||
const btnInner = document.querySelector('#emergency-stop circle:last-of-type');
|
||||
const label = document.getElementById('armed-status');
|
||||
|
||||
if (armed) {
|
||||
// Rot: Roboter bestromt → Klick = Emergency Stop
|
||||
if (stops[0]) stops[0].setAttribute('stop-color', '#ff5555');
|
||||
if (stops[1]) stops[1].setAttribute('stop-color', '#cc0000');
|
||||
if (stops[2]) stops[2].setAttribute('stop-color', '#880000');
|
||||
if (btnInner) btnInner.setAttribute('stroke', '#660000');
|
||||
if (textPath) textPath.textContent = 'EMERGENCY STOP';
|
||||
if (label) { label.textContent = '● Bestromt'; label.className = 'estop-armed-label armed'; }
|
||||
} else {
|
||||
// Grün: Strom AUS → Klick = Strom einschalten (Start Robot)
|
||||
if (stops[0]) stops[0].setAttribute('stop-color', '#88ff99');
|
||||
if (stops[1]) stops[1].setAttribute('stop-color', '#00aa44');
|
||||
if (stops[2]) stops[2].setAttribute('stop-color', '#005522');
|
||||
if (btnInner) btnInner.setAttribute('stroke', '#003311');
|
||||
if (textPath) textPath.textContent = 'START ROBOT';
|
||||
if (label) { label.textContent = '○ Kein Strom'; label.className = 'estop-armed-label disarmed'; }
|
||||
}
|
||||
|
||||
const div = document.getElementById('emergency-stop');
|
||||
if (div) {
|
||||
div.onclick = armed
|
||||
? () => fetch('/api/emergency-stop', { method: 'POST' })
|
||||
: () => fetch('/api/power-on', { method: 'POST' });
|
||||
}
|
||||
}
|
||||
|
||||
async function pollPowerStatus() {
|
||||
try {
|
||||
const res = await fetch('/api/power-status');
|
||||
if (!res.ok) return;
|
||||
const data = await res.json();
|
||||
if (data.ok) updateEmergencyStopButton(data.armed);
|
||||
} catch { /* Netzwerkfehler → Button bleibt im letzten Zustand */ }
|
||||
}
|
||||
|
||||
pollPowerStatus();
|
||||
setInterval(pollPowerStatus, 2000);
|
||||
|
||||
const btnAlarmUnlock = document.getElementById('btn-alarm-unlock');
|
||||
const alarmUnlockStatus = document.getElementById('alarm-unlock-status');
|
||||
|
||||
if (btnAlarmUnlock) {
|
||||
btnAlarmUnlock.addEventListener('click', async () => {
|
||||
btnAlarmUnlock.disabled = true;
|
||||
alarmUnlockStatus.textContent = 'Wird ausgeführt…';
|
||||
alarmUnlockStatus.className = 'estop-status';
|
||||
try {
|
||||
const res = await fetch('/api/alarm-unlock', { method: 'POST' });
|
||||
const data = await res.json();
|
||||
if (data.ok) {
|
||||
alarmUnlockStatus.textContent = '✅ Alarm entsperrt';
|
||||
alarmUnlockStatus.className = 'estop-status ok';
|
||||
} else {
|
||||
const failed = (data.results || [])
|
||||
.filter(r => !r.ok && !r.skipped)
|
||||
.map(r => r.name)
|
||||
.join(', ');
|
||||
alarmUnlockStatus.textContent = `⚠️ Fehlgeschlagen: ${failed || 'unbekannt'}`;
|
||||
alarmUnlockStatus.className = 'estop-status err';
|
||||
}
|
||||
} catch (err) {
|
||||
alarmUnlockStatus.textContent = `❌ Fehler: ${err.message}`;
|
||||
alarmUnlockStatus.className = 'estop-status err';
|
||||
} finally {
|
||||
btnAlarmUnlock.disabled = false;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
updateStatus();
|
||||
updatePosition();
|
||||
updateRobotJson();
|
||||
|
||||
Reference in New Issue
Block a user