import assert from "node:assert/strict"; import { readFile } from "node:fs/promises"; import { createMemorySessionStorage } from "../../app/src/runtime/five-axis-session.js"; import { applyToolCommandSequence, createMemoryToolDbStorage, createToolDbReadiness, createToolDbSimulation, editToolEntry, extractToolCommandSequenceFromProgram, listToolEntries, parseLinuxCncToolTable, queryToolEntry, saveToolDbSimulation, } from "../../app/src/runtime/tool-db-simulation.js"; import { getFiveAxisProfile } from "../../app/src/profiles/index.js"; import { createSimulationStore } from "../../app/src/state/store.js"; const profile = getFiveAxisProfile("xyzac-trt"); const toolTableText = await readFile( new URL("../../../linuxcnc/configs/sim/axis/vismach/5axis/table-rotary-tilting/xyzac-trt.tbl", import.meta.url), "utf8", ); const parsed = parseLinuxCncToolTable(toolTableText, { sourceRel: profile.toolTablePath, }); assert.equal(parsed.randomToolChanger, false); assert.equal(parsed.toolCount, 10); assert.equal(parsed.pockets[0].toolNumber, 0); assert.equal(parsed.entries[0].idx, 1); assert.equal(parsed.entries[0].toolNumber, 1); assert.equal(parsed.entries[0].pocket, 1); assert.equal(parsed.entries[1].idx, 2); assert.equal(parsed.entries[1].toolNumber, 2); assert.equal(parsed.entries[1].pocket, 2); assert.equal(parsed.entries[1].offset.z, 15); assert.equal(parsed.entries[1].diameter, 8); let toolDb = createToolDbSimulation({ toolTable: parsed, profile, }); assert.equal(createToolDbReadiness(toolDb).toolDbProcessReady, true); assert.equal(createToolDbReadiness(toolDb).dbProgramReady, false); assert.equal(toolDb.hostProcessExecution, false); assert.equal(toolDb.toolTable.pockets[0].toolNumber, 0); assert.equal(listToolEntries(toolDb).length, 10); assert.equal(queryToolEntry(toolDb, { idx: 2 }).toolNumber, 2); assert.equal(queryToolEntry(toolDb, { toolNumber: 2 }).idx, 2); assert.equal(queryToolEntry(toolDb, { pocket: 2 }).diameter, 8); toolDb = applyToolCommandSequence(toolDb, [ { code: "T", toolNumber: 2 }, { code: "M6" }, { code: "G43", h: 2 }, ]); assert.equal(toolDb.toolInSpindle, 2); assert.equal(toolDb.toolFromPocket, 2); assert.equal(toolDb.currentPocket, 2); assert.equal(toolDb.toolTable.pockets[0].toolNumber, 2); assert.equal(toolDb.toolTable.pockets[0].offset.z, 15); assert.equal(queryToolEntry(toolDb, { pocket: 2 }).idx, 2); assert.equal(toolDb.emcioStatus.tool.pocketPrepped, -1); assert.equal(toolDb.iocontrol.toolNumber, 2); assert.equal(toolDb.iocontrol.toolFromPocket, 2); assert.equal(toolDb.activeToolOffset.toolNumber, 2); assert.equal(toolDb.activeToolOffset.offset.z, 15); assert.equal(toolDb.interpreterParameters[5400], 2); assert.equal(toolDb.interpreterParameters[5403], 15); assert.equal(toolDb.interpreterParameters[5410], 8); assert.equal(toolDb.events.some((event) => event.code === "READ_TOOL_INPUTS_PREPARED"), true); assert.equal(toolDb.events.some((event) => event.code === "READ_TOOL_INPUTS_CHANGED"), true); const compactToolCommands = extractToolCommandSequenceFromProgram("T2M6G43H2"); assert.deepEqual(compactToolCommands.map((command) => command.code), ["T", "M6", "G43"]); assert.equal(compactToolCommands[2].toolNumber, 2); toolDb = editToolEntry(toolDb, { toolNumber: 4, pocket: 44, diameter: 12.5, length: 42.25, comment: "edited by web simulation", }); const edited = queryToolEntry(toolDb, { toolNumber: 4 }); assert.equal(edited.idx, 4); assert.equal(edited.pocket, 44); assert.equal(edited.offset.z, 42.25); assert.equal(edited.diameter, 12.5); toolDb = editToolEntry(toolDb, { idx: 6, toolNumber: 66, pocket: 66, diameter: 6.6, toolLength: 16.6, }); const renumbered = queryToolEntry(toolDb, { toolNumber: 66 }); assert.equal(renumbered.idx, 6); assert.equal(renumbered.pocket, 66); assert.equal(renumbered.offset.z, 16.6); assert.equal(renumbered.diameter, 6.6); const storage = createMemoryToolDbStorage(); const save = await saveToolDbSimulation(toolDb, { storage, storageMode: "memory", }); assert.equal(save.storageMode, "memory"); assert.equal(storage.files.get(save.path), save.text); assert.equal(save.text.includes("T4 P44 D+12.500000 Z+42.250000 ;edited by web simulation"), true); assert.equal(save.text.includes("T66 P66 D+6.600000 Z+16.600000"), true); const fallbackSave = await saveToolDbSimulation(toolDb); assert.equal(fallbackSave.storageMode, "memory-fallback"); assert.equal(fallbackSave.storageCapability.opfsUnavailable, true); const store = createSimulationStore(); const machineStorage = createMemorySessionStorage(); await store.stageMachineFiles({ storage: machineStorage }); assert.equal(store.getState().toolDbReadiness.toolDbProcessReady, true); assert.equal(store.queryToolDb({ toolNumber: 2 }).offset.z, 15); assert.equal(store.queryToolDb({ all: true }).length, 10); store.editToolDb({ toolNumber: 3, pocket: 33, diameter: 9.75, toolLength: 21.5, }); assert.equal(store.queryToolDb({ toolNumber: 3 }).pocket, 33); assert.equal(store.queryToolDb({ toolNumber: 3 }).offset.z, 21.5); const storeSaveStorage = createMemoryToolDbStorage(); const storeSave = await store.saveToolDb({ storage: storeSaveStorage, storageMode: "memory", }); assert.equal(storeSave.text.includes("T3 P33 D+9.750000 Z+21.500000"), true); assert.equal(storeSaveStorage.files.get(storeSave.path), storeSave.text); console.log("tool_db_web_simulation_smoke=ok"); console.log("staged_tool_tbl_loaded=1"); console.log("tool_db_query_edit_save=1"); console.log("tool_db_t_m6_g43_state=1"); console.log("tool_db_memory_fallback_save=1"); console.log("host_tool_db_process=0");