推进 INI 面板 machine session state snapshot helper
This commit is contained in:
72
text11.txt
72
text11.txt
@@ -451,3 +451,75 @@ host_wasm_opfs_browser_smokes=ok
|
|||||||
更完整的 machine session state snapshot helper,供上层 UI/API 直接消费当前 machine、
|
更完整的 machine session state snapshot helper,供上层 UI/API 直接消费当前 machine、
|
||||||
session、loaded WASM mapping、selected G-code、last run summary、panel badges 和 error
|
session、loaded WASM mapping、selected G-code、last run summary、panel badges 和 error
|
||||||
state;该 helper 只聚合已有 host/runtime boundary facts,不解析 G-code 或扩展 CNC 语义。
|
state;该 helper 只聚合已有 host/runtime boundary facts,不解析 G-code 或扩展 CNC 语义。
|
||||||
|
|
||||||
|
三、2026-06-14 继续执行记录:INI panel machine session state snapshot helper
|
||||||
|
|
||||||
|
本轮继续按 `text11.txt` 第一原则推进实质性 UI/API 能力,把 save/restore/load/run workflow
|
||||||
|
的结果汇总成一个 machine session state snapshot,供上层 UI/API 直接读取,而不是继续
|
||||||
|
依赖分散的 DOM 字段、日志文本和临时全局值。
|
||||||
|
|
||||||
|
完成内容:
|
||||||
|
|
||||||
|
- 扩展 `wasm-port/runtime/ui/ini-panel/panel-state-summary.js`;
|
||||||
|
- 新增导出 `createMachineSessionStateSnapshot(input)`;
|
||||||
|
- state snapshot 汇总:
|
||||||
|
- panel badges;
|
||||||
|
- machine;
|
||||||
|
- machineFiles;
|
||||||
|
- sessionSnapshot;
|
||||||
|
- sessionLoad;
|
||||||
|
- selectedProgram;
|
||||||
|
- run summary;
|
||||||
|
- fields;
|
||||||
|
- lastAction;
|
||||||
|
- error;
|
||||||
|
- fiveaxisRemap;
|
||||||
|
- `wasm-port/runtime/ui/ini-panel/app.js` 在 save/restore/load/run/failure/boot 路径后更新
|
||||||
|
`window.linuxCncIniPanelMachineSessionState`;
|
||||||
|
- browser INI panel smoke 现在直接校验该 state snapshot 的关键字段;
|
||||||
|
- `wasm-port/tests/ui/node/verify_ini_panel_state_summary.mjs` 覆盖新 state snapshot 形状;
|
||||||
|
- `wasm-port/docs/ui-panel-state-summary.md` 更新 state snapshot API、window 暴露和边界说明;
|
||||||
|
- 未改变 OPFS bridge、snapshot-store、machine-file-store、LinuxCNC interpreter、G-code 文本、
|
||||||
|
canonical-event 语义、tool、parameter、planner 或 LinuxCNC-owned runtime semantics。
|
||||||
|
|
||||||
|
验证已通过:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
git diff --check
|
||||||
|
wasm-port/tests/ui/node/verify_ini_panel_state_summary.sh
|
||||||
|
wasm-port/tests/ui/node/verify_ui_node_smokes.sh
|
||||||
|
SKIP_INI_BUILD=1 SKIP_INTERP_BUILD=1 wasm-port/tests/browser/verify_ini_panel_browser.sh
|
||||||
|
wasm-port/tools/verify_vendor_sync.sh
|
||||||
|
wasm-port/tools/verify_no_standalone_cnc_semantics.sh
|
||||||
|
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_interp_wasm.sh
|
||||||
|
SKIP_INTERP_BUILD=1 wasm-port/tests/wasm/node/verify_sim_configs_inventory_wasm.sh
|
||||||
|
wasm-port/tests/host/verify_host_smokes.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
关键输出:
|
||||||
|
|
||||||
|
```text
|
||||||
|
ini_panel_state_summary_node_smoke=ok
|
||||||
|
ini_panel_run_summary_node_smoke=ok
|
||||||
|
ini_panel_run_workflow_node_smoke=ok
|
||||||
|
ini_panel_session_summary_node_smoke=ok
|
||||||
|
ini_panel_session_workflow_node_smoke=ok
|
||||||
|
ini_panel_machine_file_summary_node_smoke=ok
|
||||||
|
ui_node_smokes=ok
|
||||||
|
browser_ini_opfs_smoke=ok
|
||||||
|
vendor sync up to date
|
||||||
|
standalone CNC semantics guard complete
|
||||||
|
interp_wasm_node_smoke=ok
|
||||||
|
sim_configs_wasm_node_inventory_executed=28
|
||||||
|
sim_configs_wasm_node_inventory_passed=28
|
||||||
|
sim_configs_wasm_node_inventory_skipped=131
|
||||||
|
sim_configs_wasm_node_inventory_unexpected_fail=0
|
||||||
|
host_wasm_opfs_browser_smokes=ok
|
||||||
|
```
|
||||||
|
|
||||||
|
下一步建议:
|
||||||
|
|
||||||
|
继续按“实质性能力优先”推进。下一批优先把 `window.linuxCncIniPanelMachineSessionState`
|
||||||
|
整理成更明确的 API/文档使用方式,或者在 `run-gcode`/restore/load/save 之外再补一层
|
||||||
|
更高阶的 UI consumer helper,用于读取状态并生成上层展示/导出结果;只围绕已有
|
||||||
|
host/runtime boundary facts 组合,不回到 path guard。
|
||||||
|
|||||||
@@ -30,11 +30,45 @@ reading ad hoc DOM text.
|
|||||||
The returned snapshot preserves those nested objects and normalizes missing
|
The returned snapshot preserves those nested objects and normalizes missing
|
||||||
badge entries to `null`.
|
badge entries to `null`.
|
||||||
|
|
||||||
|
## `createMachineSessionStateSnapshot(input)`
|
||||||
|
|
||||||
|
This helper builds the richer state snapshot used by the INI panel and exposed
|
||||||
|
as `window.linuxCncIniPanelMachineSessionState`.
|
||||||
|
|
||||||
|
It preserves the base panel state and adds:
|
||||||
|
|
||||||
|
```js
|
||||||
|
{
|
||||||
|
selectedProgram: { source: "snapshot", opfsPath: "...", wasmPath: "..." },
|
||||||
|
fields: {
|
||||||
|
sessionIni: "/work/session-machine.ini",
|
||||||
|
sessionParameters: "/work/session-linuxcnc.var",
|
||||||
|
sessionToolTable: "/work/session-tool.tbl",
|
||||||
|
sessionGcode: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
sessionSnapshot: "ui-machine-session/ui-machine-session.json",
|
||||||
|
runStatus: "ok",
|
||||||
|
runSource: "snapshot",
|
||||||
|
runSnapshot: "ui-machine-session/ui-machine-session.json",
|
||||||
|
runWorkflow: "save-session-snapshot",
|
||||||
|
runOpfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
runWasmPath: "/work/ui-session.ngc"
|
||||||
|
},
|
||||||
|
lastAction: "run-gcode",
|
||||||
|
error: null
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
The INI panel updates this state after save, restore, load, run, and error
|
||||||
|
paths so browser tests and future API consumers can read one machine-readable
|
||||||
|
state object instead of collecting DOM fields and log text.
|
||||||
|
|
||||||
## Boundary Rules
|
## Boundary Rules
|
||||||
|
|
||||||
- Do not parse G-code text in this helper.
|
- Do not parse G-code text in this helper.
|
||||||
- Do not infer CNC semantics from the nested summaries.
|
- Do not infer CNC semantics from the nested summaries.
|
||||||
- Keep the helper as a bundling layer over already-observed UI boundary state.
|
- Keep the helper as a bundling layer over already-observed UI boundary state.
|
||||||
|
- Keep workflow result objects as host/runtime boundary facts; this helper must
|
||||||
|
not promote, reinterpret, or synthesize CNC behavior.
|
||||||
|
|
||||||
## Validation
|
## Validation
|
||||||
|
|
||||||
|
|||||||
@@ -45,6 +45,9 @@ import {
|
|||||||
restoreMachineSessionSnapshotWorkflow,
|
restoreMachineSessionSnapshotWorkflow,
|
||||||
saveMachineSessionSnapshotWorkflow,
|
saveMachineSessionSnapshotWorkflow,
|
||||||
} from "./session-workflow.js";
|
} from "./session-workflow.js";
|
||||||
|
import {
|
||||||
|
createMachineSessionStateSnapshot,
|
||||||
|
} from "./panel-state-summary.js";
|
||||||
|
|
||||||
const SAMPLE_PATH =
|
const SAMPLE_PATH =
|
||||||
"../../../vendor/linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini";
|
"../../../vendor/linuxcnc/configs/sim/axis/vismach/5axis/table-dual-rotary/xyzab-tdr.ini";
|
||||||
@@ -146,6 +149,20 @@ let loadedSession = null;
|
|||||||
let restoredSessionSnapshot = null;
|
let restoredSessionSnapshot = null;
|
||||||
let canonicalEventText = "";
|
let canonicalEventText = "";
|
||||||
let runPlaybackTimer = null;
|
let runPlaybackTimer = null;
|
||||||
|
let panelMachineSessionState = createMachineSessionStateSnapshot();
|
||||||
|
|
||||||
|
function updatePanelMachineSessionState(patch = {}) {
|
||||||
|
panelMachineSessionState = createMachineSessionStateSnapshot({
|
||||||
|
...panelMachineSessionState,
|
||||||
|
...patch,
|
||||||
|
fields: {
|
||||||
|
...panelMachineSessionState.fields,
|
||||||
|
...(patch.fields ?? {}),
|
||||||
|
},
|
||||||
|
});
|
||||||
|
window.linuxCncIniPanelMachineSessionState = panelMachineSessionState;
|
||||||
|
return panelMachineSessionState;
|
||||||
|
}
|
||||||
|
|
||||||
function setBadge(node, text, className = "badge") {
|
function setBadge(node, text, className = "badge") {
|
||||||
node.className = className;
|
node.className = className;
|
||||||
@@ -377,6 +394,17 @@ function setLastRunSummary(summary) {
|
|||||||
setField("runWorkflow", summary.workflow ?? "-");
|
setField("runWorkflow", summary.workflow ?? "-");
|
||||||
setField("runOpfsPath", summary.programOpfsPath);
|
setField("runOpfsPath", summary.programOpfsPath);
|
||||||
setField("runWasmPath", summary.programWasmPath);
|
setField("runWasmPath", summary.programWasmPath);
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
run: summary,
|
||||||
|
fields: {
|
||||||
|
runStatus: summary.runStatus,
|
||||||
|
runSource: summary.programSource,
|
||||||
|
runSnapshot: summary.snapshotLabel ?? "-",
|
||||||
|
runWorkflow: summary.workflow ?? "-",
|
||||||
|
runOpfsPath: summary.programOpfsPath,
|
||||||
|
runWasmPath: summary.programWasmPath,
|
||||||
|
},
|
||||||
|
});
|
||||||
return summary;
|
return summary;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -463,27 +491,45 @@ async function boot() {
|
|||||||
try {
|
try {
|
||||||
iniSdk = await createLinuxCncIniSdk();
|
iniSdk = await createLinuxCncIniSdk();
|
||||||
setBadge(wasmBadge, "INI WASM: ready");
|
setBadge(wasmBadge, "INI WASM: ready");
|
||||||
|
updatePanelMachineSessionState({ badges: { ...panelMachineSessionState.badges, ini: "INI WASM: ready" } });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setBadge(wasmBadge, "INI WASM: failed", "badge danger");
|
setBadge(wasmBadge, "INI WASM: failed", "badge danger");
|
||||||
setLog(`INI WASM init failed: ${error.message}`, true);
|
setLog(`INI WASM init failed: ${error.message}`, true);
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
badges: { ...panelMachineSessionState.badges, ini: "INI WASM: failed" },
|
||||||
|
lastAction: "boot",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
interpSdk = await createLinuxCncInterpSdk();
|
interpSdk = await createLinuxCncInterpSdk();
|
||||||
setBadge(interpBadge, "Interpreter WASM: ready");
|
setBadge(interpBadge, "Interpreter WASM: ready");
|
||||||
|
updatePanelMachineSessionState({ badges: { ...panelMachineSessionState.badges, interp: "Interpreter WASM: ready" } });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setBadge(interpBadge, "Interpreter WASM: failed", "badge danger");
|
setBadge(interpBadge, "Interpreter WASM: failed", "badge danger");
|
||||||
setLog(`Interpreter WASM init failed: ${error.message}`, true);
|
setLog(`Interpreter WASM init failed: ${error.message}`, true);
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
badges: { ...panelMachineSessionState.badges, interp: "Interpreter WASM: failed" },
|
||||||
|
lastAction: "boot",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
throw error;
|
throw error;
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await getOpfsRoot();
|
await getOpfsRoot();
|
||||||
setBadge(opfsBadge, "OPFS: ready");
|
setBadge(opfsBadge, "OPFS: ready");
|
||||||
|
updatePanelMachineSessionState({ badges: { ...panelMachineSessionState.badges, opfs: "OPFS: ready" } });
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setBadge(opfsBadge, "OPFS: unavailable", "badge danger");
|
setBadge(opfsBadge, "OPFS: unavailable", "badge danger");
|
||||||
setLog(`OPFS check failed: ${error.message}`, true);
|
setLog(`OPFS check failed: ${error.message}`, true);
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
badges: { ...panelMachineSessionState.badges, opfs: "OPFS: unavailable" },
|
||||||
|
lastAction: "boot",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -513,6 +559,11 @@ document.getElementById("save-machine-files").addEventListener("click", async ()
|
|||||||
});
|
});
|
||||||
const gcodePath = await saveGcodeProgram(UI_SESSION.defaultGcodeFilename, DEFAULT_GCODE);
|
const gcodePath = await saveGcodeProgram(UI_SESSION.defaultGcodeFilename, DEFAULT_GCODE);
|
||||||
const summary = createMachineFileSaveSummary(paths, gcodePath);
|
const summary = createMachineFileSaveSummary(paths, gcodePath);
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
machineFiles: summary,
|
||||||
|
lastAction: "save-machine-files",
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
setLog(
|
setLog(
|
||||||
[
|
[
|
||||||
"Saved machine text files to OPFS.",
|
"Saved machine text files to OPFS.",
|
||||||
@@ -544,6 +595,15 @@ document.getElementById("save-session-snapshot").addEventListener("click", async
|
|||||||
for (const [name, value] of Object.entries(workflow.fields)) {
|
for (const [name, value] of Object.entries(workflow.fields)) {
|
||||||
setField(name, value);
|
setField(name, value);
|
||||||
}
|
}
|
||||||
|
restoredSessionSnapshot = workflow.snapshot;
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
sessionSnapshot: workflow.summary,
|
||||||
|
sessionLoad: null,
|
||||||
|
selectedProgram: null,
|
||||||
|
fields: workflow.fields,
|
||||||
|
lastAction: "save-session-snapshot",
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
setLog(
|
setLog(
|
||||||
[
|
[
|
||||||
"Saved machine session snapshot to OPFS.",
|
"Saved machine session snapshot to OPFS.",
|
||||||
@@ -551,6 +611,10 @@ document.getElementById("save-session-snapshot").addEventListener("click", async
|
|||||||
].join("\n"),
|
].join("\n"),
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
lastAction: "save-session-snapshot",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
setLog(`Machine session snapshot save failed: ${error.message}`, true);
|
setLog(`Machine session snapshot save failed: ${error.message}`, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -571,6 +635,15 @@ document.getElementById("restore-session-snapshot").addEventListener("click", as
|
|||||||
setField("sessionToolTable", workflow.fields.sessionToolTable);
|
setField("sessionToolTable", workflow.fields.sessionToolTable);
|
||||||
setField("sessionGcode", workflow.fields.sessionGcode);
|
setField("sessionGcode", workflow.fields.sessionGcode);
|
||||||
setField("sessionSnapshot", workflow.fields.sessionSnapshot);
|
setField("sessionSnapshot", workflow.fields.sessionSnapshot);
|
||||||
|
restoredSessionSnapshot = workflow.snapshot;
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
sessionSnapshot: workflow.summary,
|
||||||
|
sessionLoad: null,
|
||||||
|
selectedProgram: null,
|
||||||
|
fields: workflow.fields,
|
||||||
|
lastAction: "restore-session-snapshot",
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
setLog(
|
setLog(
|
||||||
[
|
[
|
||||||
"Restored machine session snapshot from OPFS.",
|
"Restored machine session snapshot from OPFS.",
|
||||||
@@ -578,6 +651,10 @@ document.getElementById("restore-session-snapshot").addEventListener("click", as
|
|||||||
].join("\n"),
|
].join("\n"),
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
lastAction: "restore-session-snapshot",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
setLog(`Machine session snapshot restore failed: ${error.message}`, true);
|
setLog(`Machine session snapshot restore failed: ${error.message}`, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -586,6 +663,16 @@ document.getElementById("load-session").addEventListener("click", async () => {
|
|||||||
try {
|
try {
|
||||||
await loadMachineSessionIntoWasm();
|
await loadMachineSessionIntoWasm();
|
||||||
const loadSummary = createMachineSessionLoadSummary(loadedSession);
|
const loadSummary = createMachineSessionLoadSummary(loadedSession);
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
sessionLoad: loadSummary,
|
||||||
|
fields: {
|
||||||
|
sessionIni: loadSummary.iniWasmPath,
|
||||||
|
sessionParameters: loadSummary.parameterWasmPath,
|
||||||
|
sessionToolTable: loadSummary.toolTableWasmPath,
|
||||||
|
},
|
||||||
|
lastAction: "load-session",
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
setLog(
|
setLog(
|
||||||
[
|
[
|
||||||
"Loaded machine session into the interpreter WASM filesystem.",
|
"Loaded machine session into the interpreter WASM filesystem.",
|
||||||
@@ -593,6 +680,10 @@ document.getElementById("load-session").addEventListener("click", async () => {
|
|||||||
].join("\n"),
|
].join("\n"),
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
lastAction: "load-session",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
setLog(`Machine session load failed: ${error.message}`, true);
|
setLog(`Machine session load failed: ${error.message}`, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -614,6 +705,18 @@ document.getElementById("restore-load-session").addEventListener("click", async
|
|||||||
setField("sessionToolTable", workflow.fields.sessionToolTable);
|
setField("sessionToolTable", workflow.fields.sessionToolTable);
|
||||||
setField("sessionGcode", workflow.fields.sessionGcode);
|
setField("sessionGcode", workflow.fields.sessionGcode);
|
||||||
setField("sessionSnapshot", workflow.fields.sessionSnapshot);
|
setField("sessionSnapshot", workflow.fields.sessionSnapshot);
|
||||||
|
restoredSessionSnapshot = workflow.snapshot;
|
||||||
|
if (workflow.loadedSession) {
|
||||||
|
loadedSession = workflow.loadedSession;
|
||||||
|
}
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
sessionSnapshot: workflow.summary,
|
||||||
|
sessionLoad: workflow.loadSummary,
|
||||||
|
selectedProgram: null,
|
||||||
|
fields: workflow.fields,
|
||||||
|
lastAction: "restore-load-session",
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
setLog(
|
setLog(
|
||||||
[
|
[
|
||||||
"Restored and loaded machine session snapshot.",
|
"Restored and loaded machine session snapshot.",
|
||||||
@@ -621,6 +724,10 @@ document.getElementById("restore-load-session").addEventListener("click", async
|
|||||||
].join("\n"),
|
].join("\n"),
|
||||||
);
|
);
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
lastAction: "restore-load-session",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
setLog(`Machine session snapshot restore/load failed: ${error.message}`, true);
|
setLog(`Machine session snapshot restore/load failed: ${error.message}`, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
@@ -631,8 +738,6 @@ document.getElementById("run-gcode").addEventListener("click", async () => {
|
|||||||
throw new Error("Load a machine session before running G-code.");
|
throw new Error("Load a machine session before running G-code.");
|
||||||
}
|
}
|
||||||
const interp = requireInterpSdk();
|
const interp = requireInterpSdk();
|
||||||
const program = await loadSelectedGcodeProgram();
|
|
||||||
interp.writeTextFile(program.wasmPath, program.text);
|
|
||||||
clearRunPlayback();
|
clearRunPlayback();
|
||||||
setField("runStatus", "running");
|
setField("runStatus", "running");
|
||||||
clearLastRunSummary();
|
clearLastRunSummary();
|
||||||
@@ -659,6 +764,17 @@ document.getElementById("run-gcode").addEventListener("click", async () => {
|
|||||||
setField("sessionGcode", workflow.fields.sessionGcode);
|
setField("sessionGcode", workflow.fields.sessionGcode);
|
||||||
setField("runStatus", workflow.fields.runStatus);
|
setField("runStatus", workflow.fields.runStatus);
|
||||||
setLastRunSummary(workflow.summary);
|
setLastRunSummary(workflow.summary);
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
selectedProgram: {
|
||||||
|
source: workflow.program.source,
|
||||||
|
opfsPath: workflow.program.opfsPath,
|
||||||
|
wasmPath: workflow.program.wasmPath,
|
||||||
|
},
|
||||||
|
run: workflow.summary,
|
||||||
|
fields: workflow.fields,
|
||||||
|
lastAction: "run-gcode",
|
||||||
|
error: null,
|
||||||
|
});
|
||||||
setCanonicalEvents(workflow.resultText);
|
setCanonicalEvents(workflow.resultText);
|
||||||
playRunMotion(workflow.resultText, workflow.program.text, workflow.motionSnapshots);
|
playRunMotion(workflow.resultText, workflow.program.text, workflow.motionSnapshots);
|
||||||
setLog(
|
setLog(
|
||||||
@@ -673,6 +789,13 @@ document.getElementById("run-gcode").addEventListener("click", async () => {
|
|||||||
clearRunPlayback();
|
clearRunPlayback();
|
||||||
clearLastRunSummary();
|
clearLastRunSummary();
|
||||||
setRunMonitor(0, "failed", {}, "failed");
|
setRunMonitor(0, "failed", {}, "failed");
|
||||||
|
updatePanelMachineSessionState({
|
||||||
|
fields: {
|
||||||
|
runStatus: "failed",
|
||||||
|
},
|
||||||
|
lastAction: "run-gcode",
|
||||||
|
error: error.message,
|
||||||
|
});
|
||||||
setLog(`G-code run failed: ${error.message}`, true);
|
setLog(`G-code run failed: ${error.message}`, true);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -21,3 +21,45 @@ export function createIniPanelStateSummary({
|
|||||||
fiveaxisRemap: fiveaxisRemap ?? null,
|
fiveaxisRemap: fiveaxisRemap ?? null,
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function createMachineSessionStateSnapshot({
|
||||||
|
badges = {},
|
||||||
|
machine = null,
|
||||||
|
machineFiles = null,
|
||||||
|
sessionSnapshot = null,
|
||||||
|
sessionLoad = null,
|
||||||
|
selectedProgram = null,
|
||||||
|
run = null,
|
||||||
|
fields = {},
|
||||||
|
lastAction = null,
|
||||||
|
error = null,
|
||||||
|
fiveaxisRemap = null,
|
||||||
|
} = {}) {
|
||||||
|
return {
|
||||||
|
...createIniPanelStateSummary({
|
||||||
|
badges,
|
||||||
|
machine,
|
||||||
|
machineFiles,
|
||||||
|
sessionSnapshot,
|
||||||
|
sessionLoad,
|
||||||
|
run,
|
||||||
|
fiveaxisRemap,
|
||||||
|
}),
|
||||||
|
selectedProgram,
|
||||||
|
fields: {
|
||||||
|
sessionIni: fields.sessionIni ?? null,
|
||||||
|
sessionParameters: fields.sessionParameters ?? null,
|
||||||
|
sessionToolTable: fields.sessionToolTable ?? null,
|
||||||
|
sessionGcode: fields.sessionGcode ?? null,
|
||||||
|
sessionSnapshot: fields.sessionSnapshot ?? null,
|
||||||
|
runStatus: fields.runStatus ?? null,
|
||||||
|
runSource: fields.runSource ?? null,
|
||||||
|
runSnapshot: fields.runSnapshot ?? null,
|
||||||
|
runWorkflow: fields.runWorkflow ?? null,
|
||||||
|
runOpfsPath: fields.runOpfsPath ?? null,
|
||||||
|
runWasmPath: fields.runWasmPath ?? null,
|
||||||
|
},
|
||||||
|
lastAction: lastAction ?? null,
|
||||||
|
error: error ?? null,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|||||||
@@ -660,6 +660,37 @@ TOOL_TABLE = browser-tool.tbl
|
|||||||
2,
|
2,
|
||||||
"UI snapshot run summary motion snapshot count",
|
"UI snapshot run summary motion snapshot count",
|
||||||
);
|
);
|
||||||
|
const machineSessionState = uiDocument.defaultView.linuxCncIniPanelMachineSessionState;
|
||||||
|
assertEqual(
|
||||||
|
machineSessionState.lastAction,
|
||||||
|
"run-gcode",
|
||||||
|
"UI machine session state last action",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
machineSessionState.selectedProgram.opfsPath,
|
||||||
|
"linuxcnc/gcode/ui-session.ngc",
|
||||||
|
"UI machine session state selected program OPFS path",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
machineSessionState.sessionLoad.iniWasmPath,
|
||||||
|
"/work/session-machine.ini",
|
||||||
|
"UI machine session state loaded INI WASM path",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
machineSessionState.run.programSource,
|
||||||
|
"snapshot",
|
||||||
|
"UI machine session state run source",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
machineSessionState.fields.runWorkflow,
|
||||||
|
"save-session-snapshot",
|
||||||
|
"UI machine session state run workflow field",
|
||||||
|
);
|
||||||
|
assertEqual(
|
||||||
|
machineSessionState.error,
|
||||||
|
null,
|
||||||
|
"UI machine session state error",
|
||||||
|
);
|
||||||
if (
|
if (
|
||||||
!runLog.includes("canon_event=STRAIGHT_TRAVERSE") ||
|
!runLog.includes("canon_event=STRAIGHT_TRAVERSE") ||
|
||||||
!runLog.includes("canon_event=STRAIGHT_FEED")
|
!runLog.includes("canon_event=STRAIGHT_FEED")
|
||||||
|
|||||||
@@ -1,6 +1,9 @@
|
|||||||
import assert from "node:assert/strict";
|
import assert from "node:assert/strict";
|
||||||
|
|
||||||
import { createIniPanelStateSummary } from "../../../runtime/ui/ini-panel/panel-state-summary.js";
|
import {
|
||||||
|
createIniPanelStateSummary,
|
||||||
|
createMachineSessionStateSnapshot,
|
||||||
|
} from "../../../runtime/ui/ini-panel/panel-state-summary.js";
|
||||||
|
|
||||||
const summary = createIniPanelStateSummary({
|
const summary = createIniPanelStateSummary({
|
||||||
badges: {
|
badges: {
|
||||||
@@ -81,4 +84,106 @@ assert.deepEqual(
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
createMachineSessionStateSnapshot({
|
||||||
|
badges: {
|
||||||
|
ini: "INI WASM: ready",
|
||||||
|
interp: "Interpreter WASM: ready",
|
||||||
|
opfs: "OPFS: ready",
|
||||||
|
},
|
||||||
|
machine: {
|
||||||
|
machine: "xyzab-tdr",
|
||||||
|
},
|
||||||
|
sessionSnapshot: {
|
||||||
|
snapshotLabel: "ui-machine-session/ui-machine-session.json",
|
||||||
|
},
|
||||||
|
sessionLoad: {
|
||||||
|
iniWasmPath: "/work/session-machine.ini",
|
||||||
|
},
|
||||||
|
selectedProgram: {
|
||||||
|
source: "snapshot",
|
||||||
|
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
wasmPath: "/work/ui-session.ngc",
|
||||||
|
},
|
||||||
|
run: {
|
||||||
|
runStatus: "ok",
|
||||||
|
programSource: "snapshot",
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
sessionIni: "/work/session-machine.ini",
|
||||||
|
sessionParameters: "/work/session-linuxcnc.var",
|
||||||
|
sessionToolTable: "/work/session-tool.tbl",
|
||||||
|
sessionGcode: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
sessionSnapshot: "ui-machine-session/ui-machine-session.json",
|
||||||
|
runStatus: "ok",
|
||||||
|
runSource: "snapshot",
|
||||||
|
runSnapshot: "ui-machine-session/ui-machine-session.json",
|
||||||
|
runWorkflow: "save-session-snapshot",
|
||||||
|
runOpfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
runWasmPath: "/work/ui-session.ngc",
|
||||||
|
},
|
||||||
|
lastAction: "run-gcode",
|
||||||
|
fiveaxisRemap: "ok",
|
||||||
|
}),
|
||||||
|
{
|
||||||
|
badges: {
|
||||||
|
ini: "INI WASM: ready",
|
||||||
|
interp: "Interpreter WASM: ready",
|
||||||
|
opfs: "OPFS: ready",
|
||||||
|
},
|
||||||
|
machine: {
|
||||||
|
machine: "xyzab-tdr",
|
||||||
|
},
|
||||||
|
machineFiles: null,
|
||||||
|
sessionSnapshot: {
|
||||||
|
snapshotLabel: "ui-machine-session/ui-machine-session.json",
|
||||||
|
},
|
||||||
|
sessionLoad: {
|
||||||
|
iniWasmPath: "/work/session-machine.ini",
|
||||||
|
},
|
||||||
|
run: {
|
||||||
|
runStatus: "ok",
|
||||||
|
programSource: "snapshot",
|
||||||
|
},
|
||||||
|
fiveaxisRemap: "ok",
|
||||||
|
selectedProgram: {
|
||||||
|
source: "snapshot",
|
||||||
|
opfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
wasmPath: "/work/ui-session.ngc",
|
||||||
|
},
|
||||||
|
fields: {
|
||||||
|
sessionIni: "/work/session-machine.ini",
|
||||||
|
sessionParameters: "/work/session-linuxcnc.var",
|
||||||
|
sessionToolTable: "/work/session-tool.tbl",
|
||||||
|
sessionGcode: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
sessionSnapshot: "ui-machine-session/ui-machine-session.json",
|
||||||
|
runStatus: "ok",
|
||||||
|
runSource: "snapshot",
|
||||||
|
runSnapshot: "ui-machine-session/ui-machine-session.json",
|
||||||
|
runWorkflow: "save-session-snapshot",
|
||||||
|
runOpfsPath: "linuxcnc/gcode/ui-session.ngc",
|
||||||
|
runWasmPath: "/work/ui-session.ngc",
|
||||||
|
},
|
||||||
|
lastAction: "run-gcode",
|
||||||
|
error: null,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
|
assert.deepEqual(
|
||||||
|
createMachineSessionStateSnapshot().fields,
|
||||||
|
{
|
||||||
|
sessionIni: null,
|
||||||
|
sessionParameters: null,
|
||||||
|
sessionToolTable: null,
|
||||||
|
sessionGcode: null,
|
||||||
|
sessionSnapshot: null,
|
||||||
|
runStatus: null,
|
||||||
|
runSource: null,
|
||||||
|
runSnapshot: null,
|
||||||
|
runWorkflow: null,
|
||||||
|
runOpfsPath: null,
|
||||||
|
runWasmPath: null,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
|
||||||
console.log("ini_panel_state_summary_node_smoke=ok");
|
console.log("ini_panel_state_summary_node_smoke=ok");
|
||||||
|
|||||||
Reference in New Issue
Block a user