完善云端RUN执行反馈
This commit is contained in:
@@ -59,6 +59,7 @@ function render(regions, state, dispatch) {
|
||||
}
|
||||
|
||||
function renderTitlebar(element, state) {
|
||||
const currentLine = currentGcodeExecutionLine(state);
|
||||
element.innerHTML = `
|
||||
<div class="brand-dot" aria-hidden="true">NS</div>
|
||||
<div class="title-stack">
|
||||
@@ -73,6 +74,10 @@ function renderTitlebar(element, state) {
|
||||
`).join("")}
|
||||
</select>
|
||||
</label>
|
||||
<div class="current-line-indicator" data-current-gcode-line="${currentLine}" data-current-gcode-source="${escapeHtml(currentGcodeLineSource(state))}">
|
||||
<span>G-code line</span>
|
||||
<strong>${currentLine}</strong>
|
||||
</div>
|
||||
<div class="run-state" data-run-state="${state.runState}">${state.runState}</div>
|
||||
`;
|
||||
element.querySelector('[data-action="select-profile"]').addEventListener("change", (event) => {
|
||||
@@ -192,11 +197,20 @@ function droRow(axis, value, dtg) {
|
||||
}
|
||||
|
||||
function renderGcode(element, state, dispatch) {
|
||||
const currentLine = currentGcodeExecutionLine(state);
|
||||
const rows = state.programLines
|
||||
.map((line, index) => {
|
||||
const lineNumber = state.programStartLine + index;
|
||||
const execution = state.programLineExecution?.[lineNumber] || null;
|
||||
const active = lineNumber === state.activeLine ? " active" : "";
|
||||
return `<li class="gcode-row${active}" data-program-line="${lineNumber}"><span>${lineNumber}</span><code>${escapeHtml(line)}</code></li>`;
|
||||
const status = execution?.status || (lineNumber < state.activeLine ? "done" : "pending");
|
||||
return `
|
||||
<li class="gcode-row${active}" data-program-line="${lineNumber}" data-line-status="${escapeHtml(status)}">
|
||||
<span>${lineNumber}</span>
|
||||
<code>${escapeHtml(line)}</code>
|
||||
<small data-line-execution="${lineNumber}">${formatLineExecution(execution, active)}</small>
|
||||
</li>
|
||||
`;
|
||||
})
|
||||
.join("");
|
||||
const programEndLine = state.programStartLine + Math.max(state.programLines.length - 1, 0);
|
||||
@@ -210,7 +224,7 @@ function renderGcode(element, state, dispatch) {
|
||||
<div class="gcode-header">
|
||||
<strong>${escapeHtml(state.activeProgram)}</strong>
|
||||
<span data-program-source="${state.programSource}">${state.programSource}</span>
|
||||
<span data-active-program-line="${state.activeLine}">Current line ${state.activeLine}</span>
|
||||
<span data-active-program-line="${currentLine}" data-current-gcode-line="${currentLine}">Executing line ${currentLine}</span>
|
||||
</div>
|
||||
<div class="linuxcnc-source-row" data-linuxcnc-gcode-source="row">
|
||||
<label>
|
||||
@@ -272,6 +286,19 @@ function renderGcode(element, state, dispatch) {
|
||||
});
|
||||
}
|
||||
|
||||
function currentGcodeExecutionLine(state) {
|
||||
const feedbackLine = Number(state.programRuntimeFeedback?.line);
|
||||
if (Number.isFinite(feedbackLine) && feedbackLine > 0) {
|
||||
return feedbackLine;
|
||||
}
|
||||
const activeLine = Number(state.activeLine);
|
||||
return Number.isFinite(activeLine) && activeLine > 0 ? activeLine : state.programStartLine;
|
||||
}
|
||||
|
||||
function currentGcodeLineSource(state) {
|
||||
return state.programRuntimeFeedback?.sourceMode || state.programExecutionSourceMode || "ui-state";
|
||||
}
|
||||
|
||||
function renderLinuxCncGcodeSourceOptions(state) {
|
||||
const sources = state.machineFileStaging.gcodeSources || [];
|
||||
if (sources.length === 0) {
|
||||
@@ -444,6 +471,21 @@ function formatProgramRuntimeDtg(state) {
|
||||
return `DTG ${formatNumber(dtg.x, 3)} / ${formatNumber(dtg.y, 3)} / ${formatNumber(dtg.z, 3)} distance ${formatNumber(feedback.distanceToGo, 3)}`;
|
||||
}
|
||||
|
||||
function formatLineExecution(execution, active) {
|
||||
if (!execution) return active ? "running" : "pending";
|
||||
const axes = execution.axisPose || {};
|
||||
return [
|
||||
execution.status || (active ? "running" : "done"),
|
||||
`F ${formatNumber(execution.feed, 1)}`,
|
||||
`X ${formatNumber(axes.x, 3)}`,
|
||||
`Y ${formatNumber(axes.y, 3)}`,
|
||||
`Z ${formatNumber(axes.z, 3)}`,
|
||||
`A ${formatNumber(axes.a, 3)}`,
|
||||
`C ${formatNumber(axes.c, 3)}`,
|
||||
`cycle ${execution.taskCycle || 0}/${execution.servoCycle || 0}`,
|
||||
].join(" | ");
|
||||
}
|
||||
|
||||
function formatDuration(seconds) {
|
||||
const safeSeconds = Math.max(Number(seconds) || 0, 0);
|
||||
const minutes = Math.floor(safeSeconds / 60);
|
||||
@@ -604,6 +646,7 @@ function renderBottomControls(element, state, dispatch) {
|
||||
const controls = [
|
||||
["Open", "OPEN", null],
|
||||
["Reload", "RELOAD", () => dispatch({ type: "RELOAD_PROGRAM" })],
|
||||
["Run Ready", "RUN_READY", () => dispatch({ type: "RUN_READY" })],
|
||||
["Run", "RUN", () => dispatch({ type: "RUN" })],
|
||||
["Stop", "STOP", () => dispatch({ type: "STOP" })],
|
||||
["Pause", "PAUSE", () => dispatch({ type: "PAUSE" })],
|
||||
@@ -659,6 +702,7 @@ function renderBottomControls(element, state, dispatch) {
|
||||
function bottomControlGate(state, action) {
|
||||
const actionMap = {
|
||||
RUN: { type: "RUN" },
|
||||
RUN_READY: { type: "UI_CONTROL" },
|
||||
STEP: { type: "STEP" },
|
||||
PAUSE: { type: "PAUSE" },
|
||||
RESUME: { type: "RESUME" },
|
||||
|
||||
Reference in New Issue
Block a user