/** * editRobot.js * Hilfsfunktionen zum Bearbeiten von robot_xxx.json. * Alle Schreibvorgänge machen ein Backup-Kommentar in der Datei (nein, aber * atomisches Write per Temp-Datei ist hier nicht nötig – die Datei wird direkt * überschrieben; bei Bedarf Backup-Strategie ergänzen). */ import fsPromises from 'fs/promises'; // ── I/O ─────────────────────────────────────────────────────────────────────── async function readRobot(robotPath) { return JSON.parse(await fsPromises.readFile(robotPath, 'utf8')); } async function writeRobot(robotPath, data) { await fsPromises.writeFile(robotPath, JSON.stringify(data, null, 2), 'utf8'); } // ── Aktion 1: Marker nach Z-Bereich zuordnen ───────────────────────────────── /** * Weist allen Markern, deren z-Position (mm) zwischen zMin und zMax liegt, * das angegebene Set und/oder den angegebenen Link zu. * * - set (optional): Setzt den set-Wert des Markers. * - link (optional): Verschiebt den Marker in diesen Link (wird ggf. angelegt). * * Gibt { numChanged, changes[] } zurück. * changes[]: { markerId, oldLink, newLink, oldSet, newSet } */ export async function assignByZRange(robotPath, { zMin, zMax, set, link }) { const robot = await readRobot(robotPath); const links = robot.links ?? {}; const changes = []; // Snapshot aller Marker (mit aktuellem Link-Name) – vor der Mutation const snapshot = []; for (const [linkName, linkData] of Object.entries(links)) { for (const marker of (linkData.markers ?? [])) { if (Array.isArray(marker.position)) { snapshot.push({ id: marker.id, currentLink: linkName }); } } } // Nur Marker im Z-Fenster bearbeiten const zLo = Number(zMin); const zHi = Number(zMax); for (const { id, currentLink } of snapshot) { const srcLinkData = links[currentLink]; const idx = (srcLinkData?.markers ?? []).findIndex(m => Number(m.id) === id); if (idx === -1) continue; const marker = srcLinkData.markers[idx]; const z = Number(marker.position[2]); if (z < zLo || z > zHi) continue; const change = { markerId: marker.id, oldLink: currentLink, oldSet: marker.set ?? '', newLink: currentLink, newSet: marker.set ?? '', }; // Set setzen if (set !== undefined && set !== '') { marker.set = set; change.newSet = set; } // Link wechseln if (link && link !== currentLink) { // Aus altem Link entfernen srcLinkData.markers.splice(idx, 1); // Ziel-Link anlegen falls noch nicht vorhanden if (!links[link]) links[link] = { markers: [] }; if (!links[link].markers) links[link].markers = []; links[link].markers.push(marker); change.newLink = link; } changes.push(change); } if (changes.length > 0) { robot.links = links; await writeRobot(robotPath, robot); } return { numChanged: changes.length, changes }; } // ── Aktion 2: Set oder Link-Zuordnung entfernen ─────────────────────────────── /** * Entfernt die Set- oder Link-Zuordnung eines Markers. * * removeFrom: 'set' → löscht nur den set-Wert (Marker bleibt im Link) * removeFrom: 'link' → entfernt Marker komplett aus dem Link * (nur wenn set bereits leer/nicht gesetzt) * * Gibt { changed, markerId, action, link, [oldSet], [error] } zurück. */ export async function removeMarkerAssignment(robotPath, { markerId, removeFrom }) { const id = Number(markerId); const robot = await readRobot(robotPath); const links = robot.links ?? {}; for (const [linkName, linkData] of Object.entries(links)) { const markers = linkData.markers ?? []; const idx = markers.findIndex(m => Number(m.id) === id); if (idx === -1) continue; const marker = markers[idx]; if (removeFrom === 'set') { const oldSet = marker.set ?? ''; delete marker.set; await writeRobot(robotPath, robot); return { changed: true, markerId: id, action: 'set-removed', link: linkName, oldSet }; } if (removeFrom === 'link') { if (marker.set) { return { changed: false, markerId: id, error: `Marker ${id} hat noch Set "${marker.set}". Bitte zuerst Set entfernen.`, }; } markers.splice(idx, 1); await writeRobot(robotPath, robot); return { changed: true, markerId: id, action: 'link-removed', link: linkName }; } return { changed: false, error: `Unbekannte Aktion: "${removeFrom}"` }; } return { changed: false, error: `Marker-ID ${id} nicht gefunden.` }; }