Line Sender

This commit is contained in:
chk
2026-06-15 09:22:41 +02:00
parent b7d742b9a4
commit 635b8bd1f3
14 changed files with 1050 additions and 217 deletions

View File

@@ -53,13 +53,23 @@
<div class="kv"><span class="k">Version</span><span class="v" id="ai-version"></span></div>
</div>
<div class="controls">
<button id="btn-first" disabled title="Erste Zeile">|◀ First</button>
<button id="btn-prev" disabled title="Schritt zurück">Prev</button>
<button id="btn-next" disabled title="Schritt vor">Next ▶</button>
<button id="btn-last" disabled title="Letzte Zeile">Last ▶|</button>
<button id="btn-clear" disabled title="Programm leeren">✕ Clear</button>
<a id="btn-download" class="dl-link" style="display:none" download>⬇ .gcode</a>
<div class="controls-row">
<div class="ctrl-group">
<button id="btn-first" disabled title="Erste Zeile">|First</button>
<button id="btn-prev" disabled title="Schritt zurück">◀ Prev</button>
<button id="btn-next" disabled title="Schritt vor">Next ▶</button>
<button id="btn-last" disabled title="Letzte Zeile">Last ▶|</button>
</div>
<div class="ctrl-group">
<button id="btn-clear" disabled title="Programm leeren">✕ Clear</button>
<a id="btn-download" class="dl-link" style="display:none" download>⬇ .gcode</a>
</div>
<div class="ctrl-group">
<div class="toggle-group">
<button id="btn-mode-nav" class="toggle active" title="Nur Cursor bewegen">↕ Navigieren</button>
<button id="btn-mode-send" class="toggle" title="Zeile an Roboter senden" disabled>▶ Senden</button>
</div>
</div>
</div>
<div class="status-line" id="active-status"></div>
@@ -102,6 +112,7 @@
let cachedState = null; // letzter bekannter Serverzustand (für Abbrechen)
let currentDir = ''; // aktuelles Verzeichnis (relativer Pfad, z. B. 'training/run1')
let currentPath = []; // Segmente des currentDir als Array (für Breadcrumb)
let sendMode = false; // false = Navigieren, true = Senden an Driver
// ─── DOM-Referenzen ───────────────────────────────────────────────────────────
const elProgCount = document.getElementById('prog-count');
@@ -373,14 +384,27 @@
}
// ─── Stepping ────────────────────────────────────────────────────────────────
const STEP_BTN_IDS = ['btn-first', 'btn-prev', 'btn-next', 'btn-last'];
async function step(endpoint) {
setStatus(elActStatus, '…');
if (sendMode) {
STEP_BTN_IDS.forEach(id => { document.getElementById(id).disabled = true; });
setStatus(elActStatus, '⏳ Sende an Roboter…');
} else {
setStatus(elActStatus, '…');
}
try {
const r = await apiFetch('POST', `/api/active/${endpoint}`);
setStatus(elActStatus, `Cursor → ${r.cursor}`);
await refresh();
const url = sendMode
? `/api/active/${endpoint}?execute=true`
: `/api/active/${endpoint}`;
const r = await apiFetch('POST', url);
setStatus(elActStatus, sendMode
? `✓ Ausgeführt → Cursor ${r.cursor}`
: `Cursor → ${r.cursor}`);
} catch (err) {
setStatus(elActStatus, `Fehler: ${err.message}`, true);
} finally {
await refresh(); // renderLines() setzt Buttons korrekt nach Cursor-Position
}
}
@@ -409,11 +433,14 @@
setStatus(elActStatus, `Lösche ${indices.length} Zeile(n)…`);
document.getElementById('btn-save-delete').disabled = true;
try {
let lastState;
for (const i of indices) {
await apiFetch('DELETE', `/api/active/lines/${i}`);
lastState = await apiFetch('DELETE', `/api/active/lines/${i}`);
}
pendingDeletes.clear();
setStatus(elActStatus, `${indices.length} Zeile(n) gelöscht`);
// Sofortiges Neuzeichnen aus der DELETE-Antwort (enthält getState() mit aktualisierten Zeilen)
if (lastState) renderLines(lastState);
await refresh();
} catch (err) {
setStatus(elActStatus, `Fehler: ${err.message}`, true);
@@ -495,6 +522,22 @@
elBtnLast .addEventListener('click', () => step('last'));
elBtnClear.addEventListener('click', clearProgram);
// ─── Navigieren / Senden Toggle ──────────────────────────────────────────────
const elBtnModeNav = document.getElementById('btn-mode-nav');
const elBtnModeSend = document.getElementById('btn-mode-send');
elBtnModeNav.addEventListener('click', () => {
sendMode = false;
elBtnModeNav.classList.add('active');
elBtnModeSend.classList.remove('active');
setStatus(elActStatus, '');
});
elBtnModeSend.addEventListener('click', () => {
sendMode = true;
elBtnModeSend.classList.add('active');
elBtnModeNav.classList.remove('active');
setStatus(elActStatus, '');
});
// Collapse-Verhalten (wie im appRobotHoming)
document.querySelectorAll('.section h2').forEach(h2 => {
h2.addEventListener('click', () => h2.closest('.section').classList.toggle('collapsed'));
@@ -506,6 +549,16 @@
}
// ─── Start ───────────────────────────────────────────────────────────────────
// Prüfen ob Driver konfiguriert ist, dann Senden-Button freigeben
apiFetch('GET', '/api/config').then(cfg => {
if (cfg.driverConfigured) {
elBtnModeSend.disabled = false;
elBtnModeSend.title = 'Zeile an Roboter senden';
} else {
elBtnModeSend.title = 'Driver WS nicht konfiguriert (DRIVER_WS_URL fehlt)';
}
}).catch(() => { /* config nicht verfügbar → Senden bleibt deaktiviert */ });
refresh();
setInterval(refresh, REFRESH_MS);
</script>