Files
appRobotDriver/public/app.js
2026-06-12 05:40:40 +02:00

204 lines
7.9 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
document.addEventListener('DOMContentLoaded', function() {
function fmt(v) {
if (v === undefined || v === null || isNaN(v)) return '';
return Number(v).toFixed(0);
}
function updatePosition() {
fetch('/api/position')
.then(res => res.json())
.then(data => {
const p = data.position || {};
const m = data.motorCounts || {};
document.getElementById('state-x').textContent = fmt(p.x);
document.getElementById('state-y').textContent = fmt(p.y);
document.getElementById('state-z').textContent = fmt(p.z);
document.getElementById('state-phi').textContent = fmt(p.a*180/Math.PI);
document.getElementById('state-theta').textContent = fmt(p.b*180/Math.PI);
document.getElementById('state-psi').textContent = fmt(p.c*180/Math.PI);
document.getElementById('state-e').textContent = fmt(m.e*180/Math.PI);
/* Motor-Zustand */
document.getElementById('motor-x').textContent = fmt(m.x);
document.getElementById('motor-y').textContent = fmt(m.y*180/Math.PI);
document.getElementById('motor-z').textContent = fmt(m.z*180/Math.PI);
document.getElementById('motor-a').textContent = fmt(m.a*180/Math.PI);
document.getElementById('motor-b').textContent = fmt(m.b*180/Math.PI);
document.getElementById('motor-c').textContent = fmt(m.c*180/Math.PI);
document.getElementById('motor-e').textContent = fmt(m.e);
})
.catch(err => console.error('Error fetching position:', err));
}
function updateStatus() {
fetch('/api/status')
.then(response => response.json())
.then(data => {
// WebClients
const clientsUl = document.getElementById('clients');
clientsUl.innerHTML = '';
data.clients.forEach(client => {
const li = document.createElement('li');
li.textContent = client;
clientsUl.appendChild(li);
});
// Sender
const sendersUl = document.getElementById('senderList');
sendersUl.innerHTML = '';
data.senders.forEach(sender => {
const li = document.createElement('li');
const state = sender.state || 'disconnected';
const label = sender.url ? `${sender.name} (${sender.url}): ${state}` : `${sender.name}: ${state}`;
li.textContent = label;
li.classList.add(state.toLowerCase());
sendersUl.appendChild(li);
});
// Letzte Commands
const commandsUl = document.getElementById('commandList');
commandsUl.innerHTML = '';
data.lastCommands.forEach(cmd => {
const li = document.createElement('li');
li.textContent = cmd;
commandsUl.appendChild(li);
});
// Letzte Pings
const pingsUl = document.getElementById('pingList');
pingsUl.innerHTML = '';
data.lastPings.forEach(ping => {
const li = document.createElement('li');
li.textContent = ping;
pingsUl.appendChild(li);
});
})
.catch(error => console.error('Error fetching status:', error));
}
// ── Robot.json + History ─────────────────────────────────────────────────
let robotJsonActive = 'current';
function renderJsonTree(data, container) {
container.innerHTML = '';
const tree = document.createElement('div');
tree.className = 'json-tree';
for (const [key, value] of Object.entries(data)) {
if (value !== null && typeof value === 'object' && !Array.isArray(value)) {
const details = document.createElement('details');
const summary = document.createElement('summary');
summary.textContent = key;
details.appendChild(summary);
const pre = document.createElement('pre');
pre.textContent = JSON.stringify(value, null, 2);
details.appendChild(pre);
tree.appendChild(details);
} else {
const row = document.createElement('div');
row.className = 'json-scalar';
row.innerHTML =
`<span class="json-key">${key}</span>` +
`<span class="json-val">${JSON.stringify(value)}</span>`;
tree.appendChild(row);
}
}
container.appendChild(tree);
}
function updateRobotJson() {
const url = robotJsonActive === 'current'
? '/api/robot'
: `/api/robot/history/${robotJsonActive}`;
fetch(url)
.then(res => res.ok ? res.json() : Promise.reject(res.status))
.then(data => {
document.getElementById('robotJsonLabel').textContent =
robotJsonActive === 'current' ? '(aktuell)' : `(${robotJsonActive})`;
renderJsonTree(data, document.getElementById('robotJsonTree'));
})
.catch(err => {
document.getElementById('robotJsonTree').textContent = `Fehler: ${err}`;
});
}
function setHistoryActive(ts) {
robotJsonActive = ts;
updateRobotJson();
document.querySelectorAll('#robotHistoryList li').forEach(l => {
l.classList.toggle('rh-active', l.dataset.ts === ts);
});
}
function updateRobotHistory() {
fetch('/api/robot/history')
.then(res => res.json())
.then(({ history }) => {
const ul = document.getElementById('robotHistoryList');
ul.innerHTML = '';
const liCurrent = document.createElement('li');
liCurrent.textContent = 'robot.json (aktuell)';
liCurrent.dataset.ts = 'current';
if (robotJsonActive === 'current') liCurrent.classList.add('rh-active');
liCurrent.addEventListener('click', () => setHistoryActive('current'));
ul.appendChild(liCurrent);
history.forEach(entry => {
const ts = entry.filename.slice(6, -5); // robot_YYYYMMDD_HHmmss.json → YYYYMMDD_HHmmss
const li = document.createElement('li');
li.textContent = entry.filename;
li.dataset.ts = ts;
if (robotJsonActive === ts) li.classList.add('rh-active');
li.addEventListener('click', () => setHistoryActive(ts));
ul.appendChild(li);
});
})
.catch(err => console.error('Error fetching robot history:', err));
}
updateStatus();
updatePosition();
updateRobotJson();
updateRobotHistory();
setInterval(() => {
updateStatus();
updatePosition();
if (robotJsonActive === 'current') updateRobotJson();
}, 1000);
setInterval(updateRobotHistory, 30000);
});
document.querySelectorAll('.section').forEach(sec => {
const id = sec.dataset.id;
const saved = localStorage.getItem('section_' + id);
if (saved === 'collapsed') sec.classList.add('collapsed');
sec.querySelector('h2').addEventListener('click', () => {
sec.classList.toggle('collapsed');
localStorage.setItem(
'section_' + id,
sec.classList.contains('collapsed') ? 'collapsed' : 'open'
);
});
});
/* Initial-Zustand
['clients','pings'].forEach(id => {
if (!localStorage.getItem('section_' + id))
localStorage.setItem('section_' + id, 'collapsed');
});
*/