完善 working5 gmoccapy HAL 输入对标

This commit is contained in:
2026-06-26 22:07:41 -04:00
parent 0d79b3545b
commit 917cec15ad
20 changed files with 2853 additions and 27 deletions

View File

@@ -17,6 +17,8 @@ assert.deepEqual(model.nativePaths.command.path, ["gmoccapy", "linuxcnc.command(
assert.equal(model.nativePaths.status.path.includes("linuxcnc.stat()"), true);
assert.equal(model.nativePaths.status.path.includes("linuxcnc.error_channel()"), true);
assert.equal(model.nativePaths.hal.path.includes("HAL shared memory"), true);
assert.equal(model.nativePaths.hardwareButtons.path.includes("_button_pin_changed"), true);
assert.equal(model.nativePaths.halPins.path.includes("hal_glib.GPin value_changed"), true);
assert.equal(model.nativePaths.remap.path.includes("Python remap prolog/ngc/epilog"), true);
assert.deepEqual(model.webPath.path, ["button", "store.dispatch", "linuxcnc-task-policy", "runtime/status snapshot", "UI/Three.js"]);
@@ -42,6 +44,10 @@ for (const actionId of [
"abort",
"spindle",
"coolant",
"hardware-button",
"hal-pin-input",
"hal-jog-pin",
"hal-warning-confirm",
]) {
assert.equal(actionIds.includes(actionId), true, `${actionId} missing`);
}
@@ -60,15 +66,42 @@ const spindleMapping = model.actionMappings.find((mapping) => mapping.actionId =
assert.equal(spindleMapping.nativeStatus.includes("spindle.0.forward"), true);
assert.equal(spindleMapping.gate.includes("restricted during interpreter"), true);
const hardwareButtonMapping = model.actionMappings.find((mapping) => mapping.actionId === "hardware-button");
assert.equal(hardwareButtonMapping.nativeCommand.includes("_button_pin_changed"), true);
assert.equal(hardwareButtonMapping.gate.includes("rising-edge"), true);
assert.equal(hardwareButtonMapping.gate.includes("insensitive"), true);
const halPinMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-pin-input");
assert.equal(halPinMapping.webAction, "GMOCAPY_HAL_PIN");
assert.equal(halPinMapping.nativeCommand.includes("_optional_blocks"), true);
assert.equal(halPinMapping.nativeCommand.includes("_on_counts_changed"), true);
assert.equal(halPinMapping.nativeCommand.includes("_del_message_changed"), true);
assert.equal(halPinMapping.gate.includes("counts require count-enable"), true);
assert.equal(halPinMapping.gate.includes("direct-value requires analog-enable"), true);
assert.equal(halPinMapping.gate.includes("delete-message pins are rising-edge only"), true);
const halJogMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-jog-pin");
assert.equal(halJogMapping.webAction, "GMOCAPY_HAL_PIN jog.axis/jog-inc");
assert.equal(halJogMapping.nativeCommand.includes("_on_pin_jog_changed"), true);
assert.equal(halJogMapping.nativeCommand.includes("_on_pin_incr_changed"), true);
assert.equal(halJogMapping.gate.includes("press/release level"), true);
assert.equal(halJogMapping.gate.includes("increment pins are rising-edge only"), true);
const warningConfirmMapping = model.actionMappings.find((mapping) => mapping.actionId === "hal-warning-confirm");
assert.equal(warningConfirmMapping.nativeCommand.includes("confirm_pin"), true);
assert.equal(warningConfirmMapping.gate, "level-polled while warning dialog is active");
const summary = createGmoccapyCommunicationSummary(model);
assert.equal(summary.apiName, "web-rtcp-5axis-gmoccapy-communication-model-summary");
assert.equal(summary.profileId, "gmoccapy-xyzab");
assert.equal(summary.nativePathCount, 4);
assert.equal(summary.nativePathCount, 6);
assert.equal(summary.startupStageCount, 9);
assert.equal(summary.actionCount, 15);
assert.equal(summary.actionCount, 19);
assert.equal(summary.postguiAfterHalcompReady, true);
assert.equal(summary.hasNativeNmlCommandPath, true);
assert.equal(summary.hasNativeHalPath, true);
assert.equal(summary.hasNativeHardwareButtonPath, true);
assert.equal(summary.hasNativeHalPinInputPath, true);
assert.equal(summary.hasWebStorePath, true);
assert.equal(summary.semanticBoundary, model.semanticBoundary);

View File

@@ -3,6 +3,7 @@ import assert from "node:assert/strict";
import {
createGmoccapyHalSummary,
gmoccapyHalModel,
resolveGmoccapyHardwareButton,
} from "../../app/src/runtime/gmoccapy-hal-model.js";
const model = gmoccapyHalModel;
@@ -23,6 +24,7 @@ for (const groupName of [
"hard-buttons",
"jog",
"override",
"operator-inputs",
"tool",
"program",
"message",
@@ -34,7 +36,14 @@ for (const groupName of [
assert.equal(groups.get("hard-buttons").pins.includes("gmoccapy.h-button.button-0"), true);
assert.equal(groups.get("hard-buttons").pins.includes("gmoccapy.v-button.button-6"), true);
assert.equal(groups.get("jog").pins.includes("gmoccapy.jog.axis.jog-b-minus"), true);
assert.equal(groups.get("jog").pins.includes("gmoccapy.jog.jog-inc-5"), true);
assert.equal(groups.get("jog").pins.includes("gmoccapy.jog.turtle-jog"), true);
assert.equal(groups.get("override").pins.includes("gmoccapy.rapid.rapid-override.direct-value"), true);
assert.equal(groups.get("override").pins.includes("gmoccapy.feed.feed-override.count-enable"), true);
assert.equal(groups.get("override").pins.includes("gmoccapy.spindle.reset-spindle-override"), true);
assert.equal(groups.get("operator-inputs").pins.includes("gmoccapy.ignore-limits"), true);
assert.equal(groups.get("operator-inputs").pins.includes("gmoccapy.optional-stop"), true);
assert.equal(groups.get("operator-inputs").pins.includes("gmoccapy.blockdelete"), true);
assert.equal(groups.get("tool").pins.includes("gmoccapy.toolchange-changed"), true);
assert.equal(groups.get("program").pins.includes("gmoccapy.program.current-line"), true);
assert.equal(groups.get("message").pins.includes("gmoccapy.error"), true);
@@ -56,17 +65,113 @@ assert.equal(model.postguiNets.some((net) => net.target === "gmoccapy.spindle_fe
assert.equal(model.postguiNets.some((net) => net.target === "gmoccapy.tooloffset-x"), true);
assert.equal(model.postguiNets.some((net) => net.simulationLoop && net.signal === "tool-change-loop"), true);
assert.equal(model.hardwareButtons.source.methods.includes("_button_pin_changed"), true);
assert.equal(model.hardwareButtons.behavior.edge, "rising-edge-only");
assert.equal(model.hardwareButtons.behavior.insensitiveTarget, "ignored");
assert.deepEqual(model.hardwareButtons.verticalMain.map((button) => button.nativeWidget), [
"tbtn_estop",
"tbtn_on",
"rbt_manual",
"rbt_mdi",
"rbt_auto",
"tbtn_user_tabs",
"tbtn_setup",
]);
assert.deepEqual(model.hardwareButtons.verticalMain.map((button) => button.pin), [
"gmoccapy.v-button.button-0",
"gmoccapy.v-button.button-1",
"gmoccapy.v-button.button-2",
"gmoccapy.v-button.button-3",
"gmoccapy.v-button.button-4",
"gmoccapy.v-button.button-5",
"gmoccapy.v-button.button-6",
]);
assert.equal(model.hardwareButtons.bottomMain.find((button) => button.index === 0).nativeWidget, "btn_homing");
assert.equal(model.hardwareButtons.bottomMain.find((button) => button.index === 0).webDispatch.type, "HOME");
assert.equal(resolveGmoccapyHardwareButton("gmoccapy.v-button.button-4", model).webDispatch.mode, "auto");
assert.equal(resolveGmoccapyHardwareButton({ location: "bottom", index: 0 }, model).webDispatch.type, "HOME");
assert.equal(resolveGmoccapyHardwareButton({ location: "right", index: 6 }, model).webDispatch, undefined);
assert.equal(resolveGmoccapyHardwareButton("gmoccapy.h-button.button-9", model), null);
assert.equal(model.halPinActions.source.methods.includes("_optional_blocks"), true);
assert.equal(model.halPinActions.source.methods.includes("_blockdelete"), true);
assert.equal(model.halPinActions.source.methods.includes("_on_pin_jog_changed"), true);
assert.equal(model.halPinActions.source.methods.includes("_on_pin_incr_changed"), true);
assert.equal(model.halPinActions.source.methods.includes("_del_message_changed"), true);
assert.equal(model.halPinActions.jogPins.axes.length, 5);
assert.equal(model.halPinActions.jogPins.axes.find((entry) => entry.axis === "b").minus, "gmoccapy.jog.axis.jog-b-minus");
assert.equal(model.halPinActions.jogPins.increments.length, 6);
assert.equal(model.halPinActions.jogPins.increments[0].distance, 0);
assert.equal(model.halPinActions.jogPins.increments[5].pin, "gmoccapy.jog.jog-inc-5");
assert.equal(model.halPinActions.jogPins.increments[5].distance, 31.3563);
assert.equal(model.halPinActions.jogPins.turtlePin, "gmoccapy.jog.turtle-jog");
assert.equal(model.halPinActions.operatorPins.find((pin) => pin.pin === "gmoccapy.optional-stop").webState, "gmoccapyGui.optionalBlocks");
assert.equal(model.halPinActions.operatorPins.find((pin) => pin.pin === "gmoccapy.blockdelete").webState, "gmoccapyGui.optionalStop");
assert.equal(model.halPinActions.overridePins.find((pin) => pin.target === "feed").countEnable, "gmoccapy.feed.feed-override.count-enable");
assert.equal(model.halPinActions.overridePins.find((pin) => pin.target === "spindle").reset, "gmoccapy.spindle.reset-spindle-override");
assert.equal(model.halPinActions.overridePins.find((pin) => pin.target === "jogVelocity").scalePref, "scale_jog_vel=140.4");
assert.equal(model.halPinActions.behavior.optionalStopPinCrossesToBlockDelete, true);
assert.equal(model.halPinActions.behavior.blockdeletePinCrossesToOptionalStop, true);
assert.equal(model.halPinActions.behavior.jogAxisPinsPressRelease, true);
assert.equal(model.halPinActions.behavior.jogPinsUseTaskPolicyGate, true);
assert.equal(model.halPinActions.behavior.jogIncrementPinsRisingEdgeOnly, true);
assert.equal(model.halPinActions.behavior.jogIncrementZeroIsContinuous, true);
assert.equal(model.halPinActions.behavior.turtleJogLevelDriven, true);
assert.equal(model.halPinActions.behavior.countInputRequiresEnable, true);
assert.equal(model.halPinActions.behavior.directValueRequiresAnalogEnable, true);
assert.equal(model.halPinActions.behavior.resetPinsRisingEdgeOnly, true);
assert.equal(model.halPinActions.messagePins.find((pin) => pin.pin === "gmoccapy.delete-message").nativeCallback, "_del_message_changed");
assert.equal(model.halPinActions.messagePins.find((pin) => pin.pin === "gmoccapy.warning-confirm").nativeCallback, "dialogs.warning_dialog periodic confirm_pin poll");
assert.equal(model.halPinActions.behavior.deleteMessageRisingEdgeOnly, true);
assert.equal(model.halPinActions.behavior.warningConfirmLevelPolled, true);
assert.equal(model.toolChange.strategy, "iocontrol-loopback");
assert.equal(model.toolChange.manualGmoccapyPinsConnected, false);
assert.deepEqual(model.toolChange.remapCodes, ["M6", "M61"]);
assert.equal(model.toolChange.postguiUnlinks.map((entry) => entry.pin).join(","), "iocontrol.0.tool-change,iocontrol.0.tool-changed,iocontrol.0.tool-prep-number");
assert.equal(model.toolChange.commentedManualGuiNets.some((net) => net.target === "gmoccapy.toolchange-change"), true);
assert.equal(model.toolChange.commentedManualGuiNets.some((net) => net.source === "gmoccapy.toolchange-changed"), true);
assert.equal(model.toolChange.activeLoop.signal, "tool-change-loop");
assert.equal(model.toolChange.activeLoop.stage, "POSTGUI_HALFILE");
assert.equal(model.toolChange.semanticBoundary, "gmoccapy_xyzab_iocontrol_tool_change_loop_no_manual_gui_dialog");
const summary = createGmoccapyHalSummary(model);
assert.equal(summary.apiName, "web-rtcp-5axis-gmoccapy-hal-model-summary");
assert.equal(summary.profileId, "gmoccapy-xyzab");
assert.equal(summary.halFileCount, 4);
assert.equal(summary.nativePinGroupCount, 7);
assert.equal(summary.nativePinGroupCount, 8);
assert.equal(summary.nativePinCount >= 50, true);
assert.equal(summary.coreNetCount, 10);
assert.equal(summary.spindleNetCount, 4);
assert.equal(summary.postguiNetCount, 5);
assert.equal(summary.postguiRequiresHalcompReady, true);
assert.equal(summary.hasToolChangeSimulationLoop, true);
assert.equal(summary.toolChangeStrategy, "iocontrol-loopback");
assert.equal(summary.manualToolChangeGuiConnected, false);
assert.equal(summary.postguiToolUnlinkCount, 3);
assert.equal(summary.commentedManualToolChangeNetCount, 3);
assert.equal(summary.hardwareButtonVerticalCount, 7);
assert.equal(summary.hardwareButtonBottomMainCount, 4);
assert.equal(summary.mappedHardwareButtonCount, 7);
assert.equal(summary.hardwareButtonEdge, "rising-edge-only");
assert.equal(summary.hardwareButtonInsensitiveTarget, "ignored");
assert.equal(summary.operatorInputPinCount, 3);
assert.equal(summary.overridePinTargetCount, 4);
assert.equal(summary.jogAxisPinCount, 10);
assert.equal(summary.jogIncrementPinCount, 6);
assert.equal(summary.messageInputPinCount, 3);
assert.equal(summary.optionalStopPinCrossesToBlockDelete, true);
assert.equal(summary.blockdeletePinCrossesToOptionalStop, true);
assert.equal(summary.jogAxisPinsPressRelease, true);
assert.equal(summary.jogPinsUseTaskPolicyGate, true);
assert.equal(summary.jogIncrementPinsRisingEdgeOnly, true);
assert.equal(summary.jogIncrementZeroIsContinuous, true);
assert.equal(summary.turtleJogLevelDriven, true);
assert.equal(summary.countInputRequiresEnable, true);
assert.equal(summary.directValueRequiresAnalogEnable, true);
assert.equal(summary.resetPinsRisingEdgeOnly, true);
assert.equal(summary.deleteMessageRisingEdgeOnly, true);
assert.equal(summary.warningConfirmLevelPolled, true);
assert.equal(summary.semanticBoundary, model.semanticBoundary);
console.log("gmoccapy_hal_model_smoke=ok");

View File

@@ -200,4 +200,116 @@ assert.equal(controlStore.getState().spindle.direction, "stop");
controlStore.dispatch({ type: "TOGGLE_COOLANT", kind: "flood" });
assert.equal(controlStore.getState().coolant.flood, true);
const hardButtonStore = createSimulationStore();
hardButtonStore.dispatch({ type: "SET_PROFILE", profileId: "gmoccapy-xyzab" });
hardButtonStore.dispatch({ type: "GMOCAPY_HARDWARE_BUTTON", pin: "gmoccapy.v-button.button-1", value: false });
assert.equal(hardButtonStore.getState().machine.powerOn, false);
assert.equal(hardButtonStore.getState().operatorMessage, "gmoccapy hardware button falling edge ignored");
hardButtonStore.dispatch({ type: "GMOCAPY_HARDWARE_BUTTON", pin: "gmoccapy.v-button.button-1", value: true });
assert.equal(hardButtonStore.getState().machine.powerOn, true);
hardButtonStore.dispatch({ type: "GMOCAPY_HARDWARE_BUTTON", pin: "gmoccapy.v-button.button-4", value: true });
assert.equal(hardButtonStore.getState().machine.mode, "manual");
assert.equal(hardButtonStore.getState().operatorMessage, "mode blocked: home machine before AUTO");
hardButtonStore.dispatch({ type: "GMOCAPY_HARDWARE_BUTTON", location: "bottom", index: 0, value: true });
assert.equal(hardButtonStore.getState().machine.allHomed, true);
hardButtonStore.dispatch({ type: "GMOCAPY_HARDWARE_BUTTON", pin: "gmoccapy.v-button.button-4", value: true });
assert.equal(hardButtonStore.getState().machine.mode, "auto");
hardButtonStore.dispatch({ type: "GMOCAPY_HARDWARE_BUTTON", pin: "gmoccapy.v-button.button-6", value: true });
assert.equal(hardButtonStore.getState().operatorMessage, "gmoccapy hardware button diagnostic-only: gmoccapy.v-button.button-6");
hardButtonStore.dispatch({ type: "GMOCAPY_HARDWARE_BUTTON", pin: "gmoccapy.h-button.button-9", value: true });
assert.equal(hardButtonStore.getState().operatorMessage, "gmoccapy hardware button unmapped: gmoccapy.h-button.button-9");
const halPinStore = createSimulationStore();
halPinStore.dispatch({ type: "SET_PROFILE", profileId: "gmoccapy-xyzab" });
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.ignore-limits", value: true });
assert.equal(halPinStore.getState().gmoccapyGui.ignoreLimits, true);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL ignore-limits requested");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.optional-stop", value: true });
assert.equal(halPinStore.getState().gmoccapyGui.optionalBlocks, true);
assert.equal(halPinStore.getState().gmoccapyGui.optionalStop, false);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL optional-stop -> block delete on");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.blockdelete", value: true });
assert.equal(halPinStore.getState().gmoccapyGui.optionalStop, true);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL blockdelete -> optional stop on");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.feed.feed-override.counts", value: 12 });
assert.equal(halPinStore.getState().feed.feedOverride, 100);
assert.equal(halPinStore.getState().gmoccapyGui.feedOverrideCounts, 12);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL feed counts synchronized");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.feed.feed-override.count-enable", value: true });
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.feed.feed-override.counts", value: 17 });
assert.equal(halPinStore.getState().feed.feedOverride, 105);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL feed counts adjusted");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.rapid.rapid-override.analog-enable", value: true });
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.rapid.rapid-override.direct-value", value: 0.25 });
assert.equal(halPinStore.getState().feed.rapidOverride, 50);
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.spindle.spindle-override.direct-value", value: 0.5 });
assert.equal(halPinStore.getState().spindle.override, 100);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL spindle direct-value ignored: analog disabled");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.spindle.spindle-override.analog-enable", value: true });
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.spindle.spindle-override.direct-value", value: 0.5 });
assert.equal(halPinStore.getState().spindle.override, 75);
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.spindle.reset-spindle-override", value: false });
assert.equal(halPinStore.getState().spindle.override, 75);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL spindle reset falling edge ignored");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.spindle.reset-spindle-override", value: true });
assert.equal(halPinStore.getState().spindle.override, 100);
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL spindle reset to 100");
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.jog-velocity.count-enable", value: true });
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.jog-velocity.counts", value: 2 });
assert.equal(halPinStore.getState().gmoccapyGui.jogVelocity, 380.8);
halPinStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.unknown", value: true });
assert.equal(halPinStore.getState().operatorMessage, "gmoccapy HAL pin unmapped: gmoccapy.unknown");
const halJogStore = createSimulationStore();
halJogStore.dispatch({ type: "SET_PROFILE", profileId: "gmoccapy-xyzab" });
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.axis.jog-x-plus", value: true });
assert.equal(halJogStore.getState().runState, "idle");
assert.equal(halJogStore.getState().operatorMessage, "gmoccapy HAL jog blocked: jog blocked: machine must be on");
halJogStore.dispatch({ type: "TOGGLE_POWER" });
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.axis.jog-x-plus", value: true });
assert.equal(halJogStore.getState().runState, "jogging");
assert.equal(halJogStore.getState().axisPose.x, 43);
assert.equal(halJogStore.getState().machine.jogIncrement, 0);
assert.equal(halJogStore.getState().gmoccapyGui.activeJogPin, "gmoccapy.jog.axis.jog-x-plus");
assert.equal(halJogStore.getState().operatorMessage, "gmoccapy HAL jog X+ continuous");
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.axis.jog-x-plus", value: false });
assert.equal(halJogStore.getState().runState, "idle");
assert.equal(halJogStore.getState().gmoccapyGui.activeJogPin, null);
assert.equal(halJogStore.getState().operatorMessage, "gmoccapy HAL jog X+ released");
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.jog-inc-2", value: false });
assert.equal(halJogStore.getState().machine.jogIncrement, 0);
assert.equal(halJogStore.getState().operatorMessage, "gmoccapy HAL jog increment falling edge ignored");
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.jog-inc-2", value: true });
assert.equal(halJogStore.getState().machine.jogIncrement, 0.1);
assert.equal(halJogStore.getState().gmoccapyGui.jogIncrementIndex, 2);
assert.equal(halJogStore.getState().gmoccapyGui.jogIncrementOutput, 0.1);
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.axis.jog-x-plus", value: true });
assert.equal(halJogStore.getState().axisPose.x, 43.1);
assert.equal(halJogStore.getState().operatorMessage, "gmoccapy HAL jog X+ 0.1");
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.jog-inc-5", value: true });
assert.equal(halJogStore.getState().machine.jogIncrement, 31.3563);
assert.equal(halJogStore.getState().gmoccapyGui.jogIncrementLabel, "1.2345 in");
halJogStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.turtle-jog", value: true });
assert.equal(halJogStore.getState().gmoccapyGui.turtleJog, true);
assert.equal(halJogStore.getState().operatorMessage, "gmoccapy HAL turtle jog on");
const halMessageStore = createSimulationStore();
halMessageStore.dispatch({ type: "SET_PROFILE", profileId: "gmoccapy-xyzab" });
halMessageStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.delete-message", value: false });
assert.equal(halMessageStore.getState().gmoccapyGui.deletedMessageCount, 0);
assert.equal(halMessageStore.getState().operatorMessage, "gmoccapy HAL delete-message falling edge ignored");
halMessageStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.jog.axis.jog-y-minus", value: true });
assert.equal(halMessageStore.getState().operatorMessage, "gmoccapy HAL jog blocked: jog blocked: machine must be on");
halMessageStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.delete-message", value: true });
assert.equal(halMessageStore.getState().gmoccapyGui.error, false);
assert.equal(halMessageStore.getState().gmoccapyGui.deletedMessageCount, 1);
assert.equal(halMessageStore.getState().operatorMessage, "gmoccapy HAL delete-message cleared alert");
halMessageStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.warning-confirm", value: true });
assert.equal(halMessageStore.getState().gmoccapyGui.warningConfirm, true);
assert.equal(halMessageStore.getState().operatorMessage, "gmoccapy HAL warning-confirm asserted");
halMessageStore.dispatch({ type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.warning-confirm", value: false });
assert.equal(halMessageStore.getState().gmoccapyGui.warningConfirm, false);
assert.equal(halMessageStore.getState().operatorMessage, "gmoccapy HAL warning-confirm cleared");
console.log("gmoccapy_xyzab_gates_smoke=ok");

View File

@@ -41,13 +41,46 @@ assert.equal(profile.jointConfig[4].homeOffset, 45);
assert.equal(profile.hal.halcmd.feedbackNets.length, 5);
assert.equal(profile.hal.halcmd.offsetNets.some((net) => net.target === "gmoccapy.tooloffset-z"), true);
assert.equal(profile.hal.halcmd.simulationLoops.some((net) => net.signal === "tool-change-loop"), true);
assert.equal(profile.hal.halcmd.toolChange.strategy, "iocontrol-loopback");
assert.equal(profile.hal.halcmd.toolChange.manualGmoccapyPinsConnected, false);
assert.deepEqual(profile.hal.halcmd.toolChange.postguiUnlinks, [
"iocontrol.0.tool-change",
"iocontrol.0.tool-changed",
"iocontrol.0.tool-prep-number",
]);
assert.equal(profile.hal.halcmd.toolChange.commentedManualGuiNets.length, 3);
assert.equal(profile.hal.halcmd.toolChange.activeLoop.signal, "tool-change-loop");
assert.equal(profile.halPins.includes("gmoccapy.program.current-line"), true);
assert.equal(profile.halPins.includes("gmoccapy.spindle_at_speed_led"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.axis.jog-x-plus"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.axis.jog-y-minus"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.axis.jog-b-minus"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.jog-inc-0"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.jog-inc-5"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.jog-increment"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.turtle-jog"), true);
assert.equal(profile.halPins.includes("gmoccapy.ignore-limits"), true);
assert.equal(profile.halPins.includes("gmoccapy.optional-stop"), true);
assert.equal(profile.halPins.includes("gmoccapy.blockdelete"), true);
assert.equal(profile.halPins.includes("gmoccapy.feed.feed-override.count-enable"), true);
assert.equal(profile.halPins.includes("gmoccapy.feed.reset-feed-override"), true);
assert.equal(profile.halPins.includes("gmoccapy.spindle.reset-spindle-override"), true);
assert.equal(profile.halPins.includes("gmoccapy.jog.jog-velocity.direct-value"), true);
assert.equal(profile.halPins.includes("gmoccapy.delete-message"), true);
assert.equal(profile.halPins.includes("gmoccapy.warning-confirm"), true);
assert.equal(profile.toolTable.toolCount, 17);
assert.equal(profile.macros.includes("go_to_position X-pos Y-pos Z-pos"), true);
assert.equal(profile.panelSchema.id, "gmoccapy-xyzab-hal-component");
assert.equal(profile.panelSchema.boundary, "gmoccapy_hal_component_reference_only");
assert.equal(profile.panelSchema.groups.length, 2);
const taskModeControls = profile.panelSchema.groups.find((group) => group.id === "task-mode-actions").controls;
assert.deepEqual(taskModeControls.map((control) => [control.id, control.halpin]), [
["tbtn-estop", "gmoccapy.v-button.button-0"],
["tbtn-on", "gmoccapy.v-button.button-1"],
["rbt-manual", "gmoccapy.v-button.button-2"],
["rbt-mdi", "gmoccapy.v-button.button-3"],
["rbt-auto", "gmoccapy.v-button.button-4"],
]);
assert.deepEqual(fiveAxisProfiles.map(({ id }) => id), ["xyzac-trt", "xyzbc-trt", "gmoccapy-xyzab"]);

View File

@@ -67,6 +67,8 @@ assert.equal(gmoccapyXyzabProfile.tcpCapable, false);
assert.equal(gmoccapyXyzabProfile.rtcpProof, false);
assert.equal(gmoccapyXyzabProfile.promotionAllowed, false);
assert.equal(gmoccapyXyzabProfile.hal.postguiRequiresHalcompReady, true);
assert.equal(gmoccapyXyzabProfile.hal.halcmd.toolChange.strategy, "iocontrol-loopback");
assert.equal(gmoccapyXyzabProfile.hal.halcmd.toolChange.manualGmoccapyPinsConnected, false);
const gmoccapySourceSummary = createProfileSourceReferenceSummary("gmoccapy-xyzab");
assert.equal(gmoccapySourceSummary.referenceCount >= 10, true);
assert.ok(gmoccapySourceSummary.references.some((reference) => reference.path.endsWith("gmoccapy_XYZAB.ini")));