对齐 gmoccapy XYZAB 模式互锁
This commit is contained in:
@@ -218,6 +218,12 @@ function gateMode(status, requestedMode) {
|
||||
if (status.taskMode === "auto" && status.interpState !== "idle" && targetMode !== "auto") {
|
||||
return block(status, "mode blocked: AUTO interpreter is not idle");
|
||||
}
|
||||
if (status.taskState !== "on") {
|
||||
return block(status, `mode blocked: machine must be on before ${targetMode.toUpperCase()}`);
|
||||
}
|
||||
if ((targetMode === "mdi" || targetMode === "auto") && !status.allHomed && !status.noForceHoming) {
|
||||
return block(status, `mode blocked: home machine before ${targetMode.toUpperCase()}`);
|
||||
}
|
||||
return allow(status);
|
||||
}
|
||||
|
||||
|
||||
@@ -349,14 +349,17 @@ function mdiQuickCommands(state) {
|
||||
function renderSidebar(element, state, dispatch) {
|
||||
const tcpKinsType = tcpKinsTypeForProfile(state.profile);
|
||||
const tcpDisabled = tcpKinsType ? "" : ` disabled title="${escapeHtml(`${state.profile.id} is ${state.profile.kinematics} reference only`)}"`;
|
||||
const autoGate = gateLinuxCncTaskAction(state, { type: "SET_MODE", mode: "auto" });
|
||||
const manualGate = gateLinuxCncTaskAction(state, { type: "SET_MODE", mode: "manual" });
|
||||
const mdiGate = gateLinuxCncTaskAction(state, { type: "SET_MODE", mode: "mdi" });
|
||||
element.innerHTML = `
|
||||
${iconButtonHtml({ buttonId: "tbtn_estop", action: "estop", label: "E-STOP", title: "Estop the machine / F1", className: "sidebar-button estop", active: state.machine.estopActive })}
|
||||
${iconButtonHtml({ buttonId: "tbtn_on", action: "power", label: "POWER", title: "Turn the machine on/off / F2", className: "sidebar-button power", active: state.machine.powerOn })}
|
||||
${iconButtonHtml({ buttonId: "tbtn_setup", action: "reset", label: "RESET", title: "Reset estop and return machine off", className: "sidebar-button", active: false })}
|
||||
${iconButtonHtml({ buttonId: "rbt_auto", action: "mode-auto", label: "AUTO", title: "Enter auto mode", className: "sidebar-button", active: state.machine.mode === "auto" })}
|
||||
${iconButtonHtml({ buttonId: "rbt_manual", action: "mode-manual", label: "MANUAL", title: "Enter manual mode", className: "sidebar-button", active: state.machine.mode === "manual" })}
|
||||
${iconButtonHtml({ buttonId: "tbtn_user_tabs", action: "mode-jog", label: "JOG", title: "Manual jog page", className: "sidebar-button", active: state.machine.mode === "manual" })}
|
||||
${iconButtonHtml({ buttonId: "rbt_mdi", action: "mode-mdi", label: "MDI", title: "Enter MDI mode", className: "sidebar-button", active: state.machine.mode === "mdi" })}
|
||||
${iconButtonHtml({ buttonId: "rbt_auto", action: "mode-auto", label: "AUTO", title: autoGate.operatorMessage || "Enter auto mode", className: "sidebar-button", active: state.machine.mode === "auto", gate: autoGate })}
|
||||
${iconButtonHtml({ buttonId: "rbt_manual", action: "mode-manual", label: "MANUAL", title: manualGate.operatorMessage || "Enter manual mode", className: "sidebar-button", active: state.machine.mode === "manual", gate: manualGate })}
|
||||
${iconButtonHtml({ buttonId: "tbtn_user_tabs", action: "mode-jog", label: "JOG", title: manualGate.operatorMessage || "Manual jog page", className: "sidebar-button", active: state.machine.mode === "manual", gate: manualGate })}
|
||||
${iconButtonHtml({ buttonId: "rbt_mdi", action: "mode-mdi", label: "MDI", title: mdiGate.operatorMessage || "Enter MDI mode", className: "sidebar-button", active: state.machine.mode === "mdi", gate: mdiGate })}
|
||||
<button type="button" class="sidebar-button" data-action="kins-identity" data-active="${state.kinsType === "identity"}">IDENTITY</button>
|
||||
<button type="button" class="sidebar-button" data-action="kins-tcp" data-active="${state.kinsType.startsWith("tcp-")}"${tcpDisabled}>TCP</button>
|
||||
<time>13:30:31<br />20.06.2026</time>
|
||||
|
||||
@@ -4779,3 +4779,167 @@ Outcome:
|
||||
- The gmoccapy XYZAB `working4` completion commit was uploaded to the cloud repository.
|
||||
- Remote `master` now points to `a81b40447de313117e2a389a394c3b8d80931001`.
|
||||
- A follow-up process-log commit is required because this log entry was created after the main upload commit.
|
||||
|
||||
---
|
||||
|
||||
## 2026-06-26 18:15 EDT - working5 LinuxCNC gmoccapy_XYZAB execution-flow alignment
|
||||
|
||||
User request:
|
||||
- Compare `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan` against the five-axis machine execution flow documented in `/home/meswork/cnc_wams/work/working3/gmoccapy_XYZAB_execution_analysis.md`.
|
||||
- Execute, test, and improve the LinuxCNC-ported CNC simulation so its simulation behavior matches the LinuxCNC source implementation.
|
||||
- First create working files in `/home/meswork/cnc_wams/work/working5`:
|
||||
- `01-项目功能内容`
|
||||
- `02-项目程序开发详细步骤`
|
||||
- `03-推进台账`
|
||||
- `04-任务矩阵`
|
||||
- `05-验收证据`
|
||||
- `06-决策记录`
|
||||
- plus README index.
|
||||
|
||||
Process:
|
||||
- Confirmed workspace and root instructions:
|
||||
- `/home/meswork/cnc_wams`
|
||||
- `AGENTS.md` requires appending process logs to `web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`.
|
||||
- Read the LinuxCNC execution-flow reference:
|
||||
- `/home/meswork/cnc_wams/work/working3/gmoccapy_XYZAB_execution_analysis.md`
|
||||
- Key baseline: `gmoccapy_XYZAB.ini`, `trivkins coordinates=xyzab`, five joints, `NO_FORCE_HOMING = 0`, NML command/status/error, HAL loopbacks, POSTGUI after `halcomp.ready()`, and gmoccapy button sensitivity rules.
|
||||
- Inspected project structure and test inventory:
|
||||
- `app/src/runtime`
|
||||
- `app/src/state`
|
||||
- `app/src/ui`
|
||||
- `app/src/profiles`
|
||||
- `tests/node`
|
||||
- `tests/browser`
|
||||
- Created working5 control documents:
|
||||
- `/home/meswork/cnc_wams/work/working5/README.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/01-项目功能内容.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/02-项目程序开发详细步骤.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/03-推进台账.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/04-任务矩阵.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/05-验收证据.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/06-决策记录.md`
|
||||
- Ran initial baseline tests:
|
||||
- `cd /home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app && npm run smoke:node`
|
||||
- Result: passed.
|
||||
- Key output included:
|
||||
- `linuxcnc_kinematics_runtime_smoke=ok`
|
||||
- `linuxcnc_interpreter_runtime_smoke=ok`
|
||||
- `linuxcnc_ini_runtime_smoke=ok`
|
||||
- `linuxcnc_task_hal_runtime_smoke=ok`
|
||||
- `full_linuxcnc_5axis_source_node_smoke=ok`
|
||||
- `real_linuxcnc_5axis_program_cases_smoke=ok`
|
||||
- `gmoccapy_xyzab_profile_smoke=ok`
|
||||
- `gmoccapy_communication_model_smoke=ok`
|
||||
- `gmoccapy_hal_model_smoke=ok`
|
||||
- `gmoccapy_xyzab_gates_smoke=ok`
|
||||
- `linear_unit_conversion_smoke=ok`
|
||||
- `cd /home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app && npm run build`
|
||||
- Result: passed, output `gmoccapy_static_build=ok`.
|
||||
- `cd /home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app && npm run smoke`
|
||||
- Result: passed, output `gmoccapy_shell_smoke=ok` and `gmoccapy_dist_smoke=ok`.
|
||||
- Reviewed relevant implementation files:
|
||||
- `app/src/profiles/gmoccapy-xyzab.js`
|
||||
- `app/src/state/linuxcnc-task-policy.js`
|
||||
- `app/src/state/store.js`
|
||||
- `app/src/ui/gmoccapy-shell.js`
|
||||
- `app/src/runtime/gmoccapy-hal-model.js`
|
||||
- `app/src/runtime/gmoccapy-communication-model.js`
|
||||
- `tests/node/verify_gmoccapy_xyzab_gates.mjs`
|
||||
- `tests/node/verify_run_preconditions.mjs`
|
||||
- `tests/browser/gmoccapy_shell_smoke.html`
|
||||
- Compared against LinuxCNC/gmoccapy source:
|
||||
- `/home/meswork/cnc_wams/linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py`
|
||||
- Observed native behavior:
|
||||
- `on_hal_status_state_off()` disables `rbt_manual`, `rbt_mdi`, `rbt_auto`, and motion/execution controls.
|
||||
- `on_hal_status_state_on()` enables Manual and base machine controls.
|
||||
- With `NO_FORCE_HOMING = 0`, MDI/Auto remain unavailable until all axes are homed.
|
||||
- Setup-page exit logic restores:
|
||||
- estop/off: no mode buttons available
|
||||
- on but not homed: only Manual available
|
||||
- on and homed or no-force-homing: Manual/MDI/Auto available
|
||||
- Found a Web behavior gap:
|
||||
- Existing store/policy blocked `RUN` and `RUN_MDI` in invalid states.
|
||||
- But mode buttons could still be clicked earlier than gmoccapy allows.
|
||||
- Initial Web policy allowed mode changes that native gmoccapy would represent as insensitive buttons.
|
||||
- Implemented fixes:
|
||||
- In `app/src/state/linuxcnc-task-policy.js`:
|
||||
- Added `SET_MODE` gate requiring `taskState === "on"` for Manual/Jog/MDI/Auto.
|
||||
- Added homing gate for Auto/MDI when `NO_FORCE_HOMING = 0`.
|
||||
- Preserved Auto-running protection that blocks leaving Auto while interpreter is not idle.
|
||||
- In `app/src/ui/gmoccapy-shell.js`:
|
||||
- Bound Manual/Jog/Auto/MDI sidebar mode buttons to `gateLinuxCncTaskAction`.
|
||||
- Buttons now expose disabled state, `data-command-ready`, `aria-disabled`, and tooltip reason from the same task policy used by store dispatch.
|
||||
- In `tests/node/verify_gmoccapy_xyzab_gates.mjs`:
|
||||
- Added assertions that down/off state blocks Manual/MDI/Auto mode changes.
|
||||
- Added assertions that power-on but unhomed state allows Manual but blocks Auto/MDI.
|
||||
- Added assertions that after homing Auto mode is allowed.
|
||||
- In `tests/node/verify_run_preconditions.mjs`:
|
||||
- Updated expected behavior: trying Auto before homing leaves mode in Manual and run gate continues to say switch to Auto first.
|
||||
- In `tests/browser/gmoccapy_shell_smoke.html`:
|
||||
- Added DOM assertions for gmoccapy mode button sensitivity:
|
||||
- initially powered off: Manual/Jog/Auto/MDI disabled
|
||||
- powered on but unhomed: Manual/Jog enabled, Auto/MDI disabled with homing reason
|
||||
- homed: Auto/MDI enabled.
|
||||
- Ran targeted validation:
|
||||
- `cd /home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app && node ../tests/node/verify_gmoccapy_xyzab_gates.mjs && node ../tests/node/verify_run_preconditions.mjs && bash ../tests/browser/verify_gmoccapy_shell_browser.sh`
|
||||
- Result: passed.
|
||||
- Output:
|
||||
- `gmoccapy_xyzab_gates_smoke=ok`
|
||||
- `run_preconditions_ini_profile_smoke=ok`
|
||||
- `run_preconditions_kinematics_smoke=ok`
|
||||
- `run_preconditions_machine_file_smoke=ok`
|
||||
- `gmoccapy_shell_smoke=ok`
|
||||
- Ran final full regression:
|
||||
- `cd /home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app && npm run smoke:node`
|
||||
- Result: passed.
|
||||
- `cd /home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app && npm run build && npm run smoke`
|
||||
- Result: passed.
|
||||
- Output:
|
||||
- `gmoccapy_static_build=ok`
|
||||
- `gmoccapy_shell_smoke=ok`
|
||||
- `gmoccapy_dist_smoke=ok`
|
||||
- Ran quality checks:
|
||||
- `git diff --check` in `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan`
|
||||
- Result: passed.
|
||||
- `git diff --check` in `/home/meswork/cnc_wams`
|
||||
- Result: passed.
|
||||
- Updated working5 documentation:
|
||||
- `03-推进台账.md` now records R1 setup and R2 mode-interlock fix.
|
||||
- `04-任务矩阵.md` marks current pass complete for baseline profile/task/HAL/interpreter/UI verification.
|
||||
- `05-验收证据.md` records command evidence and outputs.
|
||||
- `06-决策记录.md` records why mode gating moved into `SET_MODE` and UI disabled state.
|
||||
- Started a local static server:
|
||||
- Command: `python3 -m http.server 4173`
|
||||
- Directory: `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app`
|
||||
- Confirmed with:
|
||||
- `curl -I --max-time 2 http://127.0.0.1:4173/`
|
||||
- HTTP 200 OK.
|
||||
- `ss -ltnp 'sport = :4173'`
|
||||
- Listener: `python3`, PID `24983`.
|
||||
|
||||
Files changed:
|
||||
- `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app/src/state/linuxcnc-task-policy.js`
|
||||
- `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/app/src/ui/gmoccapy-shell.js`
|
||||
- `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/tests/browser/gmoccapy_shell_smoke.html`
|
||||
- `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/tests/node/verify_gmoccapy_xyzab_gates.mjs`
|
||||
- `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/tests/node/verify_run_preconditions.mjs`
|
||||
- `/home/meswork/cnc_wams/work/working5/README.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/01-项目功能内容.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/02-项目程序开发详细步骤.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/03-推进台账.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/04-任务矩阵.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/05-验收证据.md`
|
||||
- `/home/meswork/cnc_wams/work/working5/06-决策记录.md`
|
||||
- `/home/meswork/cnc_wams/web-rtcp-5axis-sim-plan/gptlog-process/gpdlog.md`
|
||||
|
||||
Git/worktree notes:
|
||||
- `git status --short --branch` from `/home/meswork/cnc_wams` shows modified Web simulation files and new `work/working5/`.
|
||||
- There is an unrelated untracked file already visible outside this task:
|
||||
- `备忘/备忘3.txt`
|
||||
- It was not modified.
|
||||
|
||||
Outcome:
|
||||
- Created the requested working5 documentation set and README index.
|
||||
- Executed and passed Node, build, browser, and targeted gmoccapy gate regressions.
|
||||
- Fixed a real LinuxCNC/gmoccapy behavior mismatch: mode buttons now follow native `STATE_OFF`, `STATE_ON`, homing, and interpreter-idle sensitivity semantics.
|
||||
- Local app server is available at `http://127.0.0.1:4173/`.
|
||||
|
||||
@@ -303,6 +303,38 @@
|
||||
if (!doc.querySelector('[data-machine-state="summary"]')?.textContent.includes("power off")) {
|
||||
throw new Error("initial machine state should show power off");
|
||||
}
|
||||
const initialModeManualButton = doc.querySelector('[data-action="mode-manual"]');
|
||||
const initialModeJogButton = doc.querySelector('[data-action="mode-jog"]');
|
||||
const initialModeAutoButton = doc.querySelector('[data-action="mode-auto"]');
|
||||
const initialModeMdiButton = doc.querySelector('[data-action="mode-mdi"]');
|
||||
if (
|
||||
!initialModeManualButton?.disabled ||
|
||||
initialModeManualButton.dataset.commandReady !== "false" ||
|
||||
initialModeManualButton.getAttribute("aria-disabled") !== "true"
|
||||
) {
|
||||
throw new Error("MANUAL mode button should be disabled before machine power on");
|
||||
}
|
||||
if (
|
||||
!initialModeJogButton?.disabled ||
|
||||
initialModeJogButton.dataset.commandReady !== "false" ||
|
||||
initialModeJogButton.getAttribute("aria-disabled") !== "true"
|
||||
) {
|
||||
throw new Error("JOG mode button should be disabled before machine power on");
|
||||
}
|
||||
if (
|
||||
!initialModeAutoButton?.disabled ||
|
||||
initialModeAutoButton.dataset.commandReady !== "false" ||
|
||||
initialModeAutoButton.getAttribute("aria-disabled") !== "true"
|
||||
) {
|
||||
throw new Error("AUTO mode button should be disabled before machine power on");
|
||||
}
|
||||
if (
|
||||
!initialModeMdiButton?.disabled ||
|
||||
initialModeMdiButton.dataset.commandReady !== "false" ||
|
||||
initialModeMdiButton.getAttribute("aria-disabled") !== "true"
|
||||
) {
|
||||
throw new Error("MDI mode button should be disabled before machine power on");
|
||||
}
|
||||
|
||||
const initiallyBlockedRunButton = doc.querySelector('[data-action="RUN"]');
|
||||
if (
|
||||
@@ -325,8 +357,44 @@
|
||||
if (!doc.querySelector('[data-machine-state="summary"]')?.textContent.includes("power on")) {
|
||||
throw new Error("machine state did not render power on");
|
||||
}
|
||||
const unhomedModeManualButton = doc.querySelector('[data-action="mode-manual"]');
|
||||
const unhomedModeJogButton = doc.querySelector('[data-action="mode-jog"]');
|
||||
const unhomedModeAutoButton = doc.querySelector('[data-action="mode-auto"]');
|
||||
const unhomedModeMdiButton = doc.querySelector('[data-action="mode-mdi"]');
|
||||
if (
|
||||
unhomedModeManualButton?.disabled ||
|
||||
unhomedModeManualButton.dataset.commandReady !== "true" ||
|
||||
unhomedModeJogButton?.disabled ||
|
||||
unhomedModeJogButton.dataset.commandReady !== "true"
|
||||
) {
|
||||
throw new Error("MANUAL and JOG mode buttons should be enabled after power on");
|
||||
}
|
||||
if (
|
||||
!unhomedModeAutoButton?.disabled ||
|
||||
unhomedModeAutoButton.dataset.commandReady !== "false" ||
|
||||
!unhomedModeAutoButton.title.includes("home machine before AUTO")
|
||||
) {
|
||||
throw new Error("AUTO mode button should remain disabled until homed");
|
||||
}
|
||||
if (
|
||||
!unhomedModeMdiButton?.disabled ||
|
||||
unhomedModeMdiButton.dataset.commandReady !== "false" ||
|
||||
!unhomedModeMdiButton.title.includes("home machine before MDI")
|
||||
) {
|
||||
throw new Error("MDI mode button should remain disabled until homed");
|
||||
}
|
||||
doc.querySelector('[data-action="HOME"]').click();
|
||||
await wait(50);
|
||||
const homedModeAutoButton = doc.querySelector('[data-action="mode-auto"]');
|
||||
const homedModeMdiButton = doc.querySelector('[data-action="mode-mdi"]');
|
||||
if (
|
||||
homedModeAutoButton?.disabled ||
|
||||
homedModeAutoButton.dataset.commandReady !== "true" ||
|
||||
homedModeMdiButton?.disabled ||
|
||||
homedModeMdiButton.dataset.commandReady !== "true"
|
||||
) {
|
||||
throw new Error("AUTO and MDI mode buttons should be enabled after homing");
|
||||
}
|
||||
doc.querySelector('[data-action="mode-auto"]').click();
|
||||
await wait(50);
|
||||
if (!doc.querySelector('[data-linuxcnc-task-policy="gates"]')?.textContent.includes("auto")) {
|
||||
|
||||
@@ -15,18 +15,41 @@ let gate = gateLinuxCncTaskAction(store.getState(), { type: "RUN" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "run blocked: machine must be on");
|
||||
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "manual" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "mode blocked: machine must be on before MANUAL");
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "mdi" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "mode blocked: machine must be on before MDI");
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "auto" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "mode blocked: machine must be on before AUTO");
|
||||
|
||||
store.dispatch({ type: "TOGGLE_POWER" });
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "manual" });
|
||||
assert.equal(gate.allowed, true);
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "RUN" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "run blocked: switch to auto mode first");
|
||||
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "auto" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "mode blocked: home machine before AUTO");
|
||||
store.dispatch({ type: "SET_MODE", mode: "auto" });
|
||||
assert.equal(store.getState().machine.mode, "manual");
|
||||
assert.equal(store.getState().operatorMessage, "mode blocked: home machine before AUTO");
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "RUN" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "run blocked: home machine first");
|
||||
assert.equal(gate.operatorMessage, "run blocked: switch to auto mode first");
|
||||
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "mdi" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "mode blocked: home machine before MDI");
|
||||
|
||||
store.dispatch({ type: "SET_MODE", mode: "manual" });
|
||||
store.dispatch({ type: "HOME" });
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "auto" });
|
||||
assert.equal(gate.allowed, true);
|
||||
store.dispatch({ type: "SET_MODE", mode: "auto" });
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "RUN" });
|
||||
assert.equal(gate.allowed, false);
|
||||
|
||||
@@ -134,10 +134,14 @@ gate = gateLinuxCncTaskAction(store.getState(), { type: "RUN" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "run blocked: switch to auto mode first");
|
||||
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "SET_MODE", mode: "auto" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "mode blocked: home machine before AUTO");
|
||||
store.dispatch({ type: "SET_MODE", mode: "auto" });
|
||||
assert.equal(store.getState().machine.mode, "manual");
|
||||
gate = gateLinuxCncTaskAction(store.getState(), { type: "RUN" });
|
||||
assert.equal(gate.allowed, false);
|
||||
assert.equal(gate.operatorMessage, "run blocked: home machine first");
|
||||
assert.equal(gate.operatorMessage, "run blocked: switch to auto mode first");
|
||||
|
||||
store.dispatch({ type: "HOME" });
|
||||
store.dispatch({ type: "SET_MODE", mode: "manual" });
|
||||
|
||||
Reference in New Issue
Block a user