export const gmoccapyHalModel = { apiName: "web-rtcp-5axis-gmoccapy-hal-model", profileId: "gmoccapy-xyzab", nativeConfigPath: "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.ini", halFiles: [ { path: "linuxcnc/configs/sim/gmoccapy/core_sim_XYZAB.hal", stage: "HALFILE", role: "trivkins and motmod simulation loopback", semanticBoundary: "native_hal_reference", }, { path: "linuxcnc/configs/sim/gmoccapy/spindle_sim.hal", stage: "HALFILE", role: "spindle speed encoder and at-speed simulation", semanticBoundary: "native_hal_reference", }, { path: "linuxcnc/configs/sim/gmoccapy/simulated_home.hal", stage: "HALFILE", role: "simulated X/Y/Z home switches", semanticBoundary: "native_hal_reference", }, { path: "linuxcnc/configs/sim/gmoccapy/gmoccapy_postgui.hal", stage: "POSTGUI_HALFILE", role: "connections that require gmoccapy.* pins", requiresHalcompReady: true, semanticBoundary: "native_postgui_hal_reference", }, ], nativePins: [ { group: "hard-buttons", pins: [ "gmoccapy.h-button.button-0", "gmoccapy.h-button.button-1", "gmoccapy.h-button.button-2", "gmoccapy.h-button.button-3", "gmoccapy.h-button.button-4", "gmoccapy.h-button.button-5", "gmoccapy.h-button.button-6", "gmoccapy.h-button.button-7", "gmoccapy.h-button.button-8", "gmoccapy.h-button.button-9", "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", ], webSource: "current visible Web button set", semanticBoundary: "native_hardware_button_pin_reference", }, { group: "jog", pins: [ "gmoccapy.jog.axis.jog-x-plus", "gmoccapy.jog.axis.jog-x-minus", "gmoccapy.jog.axis.jog-y-plus", "gmoccapy.jog.axis.jog-y-minus", "gmoccapy.jog.axis.jog-z-plus", "gmoccapy.jog.axis.jog-z-minus", "gmoccapy.jog.axis.jog-a-plus", "gmoccapy.jog.axis.jog-a-minus", "gmoccapy.jog.axis.jog-b-plus", "gmoccapy.jog.axis.jog-b-minus", "gmoccapy.jog.jog-inc-0", "gmoccapy.jog.jog-inc-1", "gmoccapy.jog.jog-inc-2", "gmoccapy.jog.jog-inc-3", "gmoccapy.jog.jog-inc-4", "gmoccapy.jog.jog-inc-5", "gmoccapy.jog.jog-increment", "gmoccapy.jog.turtle-jog", ], webSource: "JOG dispatch and machine.jogIncrement", semanticBoundary: "native_jog_pin_reference_web_task_policy_gate", }, { group: "override", pins: [ "gmoccapy.feed.feed-override.counts", "gmoccapy.feed.feed-override.count-enable", "gmoccapy.feed.feed-override.analog-enable", "gmoccapy.feed.feed-override.direct-value", "gmoccapy.feed.reset-feed-override", "gmoccapy.spindle.spindle-override.counts", "gmoccapy.spindle.spindle-override.count-enable", "gmoccapy.spindle.spindle-override.analog-enable", "gmoccapy.spindle.spindle-override.direct-value", "gmoccapy.spindle.reset-spindle-override", "gmoccapy.jog.jog-velocity.counts", "gmoccapy.jog.jog-velocity.count-enable", "gmoccapy.jog.jog-velocity.analog-enable", "gmoccapy.jog.jog-velocity.direct-value", "gmoccapy.rapid.rapid-override.counts", "gmoccapy.rapid.rapid-override.count-enable", "gmoccapy.rapid.rapid-override.analog-enable", "gmoccapy.rapid.rapid-override.direct-value", "gmoccapy.rapid.reset-rapid-override", ], webSource: "feed/spindle override state", semanticBoundary: "native_override_pin_reference_web_state_mapping", }, { group: "operator-inputs", pins: [ "gmoccapy.ignore-limits", "gmoccapy.optional-stop", "gmoccapy.blockdelete", ], webSource: "gmoccapyGui ignoreLimits, optionalBlocks, optionalStop", semanticBoundary: "native_ignore_limits_optional_stop_blockdelete_pin_reference_web_state_mapping", }, { group: "settings", pins: [ "gmoccapy.unlock-settings", ], webSource: "gmoccapyGui settingsUnlockPin and setupSensitive", semanticBoundary: "native_settings_unlock_pin_reference_web_diagnostic_state", }, { group: "tool", pins: [ "gmoccapy.tooloffset-x", "gmoccapy.tooloffset-z", "gmoccapy.tool-diameter", "gmoccapy.probeheight", "gmoccapy.blockheight", "gmoccapy.toolmeasurement", "gmoccapy.searchvel", "gmoccapy.probevel", "gmoccapy.toolchange-change", "gmoccapy.toolchange-changed", "gmoccapy.toolchange-number", "gmoccapy.toolchange-confirm", ], webSource: "toolPreview, disconnected manual tool-change diagnostics, and disabled XYZAB tool measurement outputs", semanticBoundary: "native_tool_pin_reference_simulated_tool_loop", }, { group: "program", pins: [ "gmoccapy.program.length", "gmoccapy.program.current-line", "gmoccapy.program.progress", ], webSource: "programLines, activeLine, programRuntimeFeedback", semanticBoundary: "native_program_pin_reference_web_execution_status", }, { group: "message", pins: [ "gmoccapy.error", "gmoccapy.delete-message", "gmoccapy.warning-confirm", ], webSource: "operatorMessage and browser diagnostics", semanticBoundary: "native_message_pin_reference_web_operator_message", }, { group: "spindle-postgui", pins: [ "gmoccapy.spindle_feedback_bar", "gmoccapy.spindle_at_speed_led", ], webSource: "spindle rpm/status panel", semanticBoundary: "postgui_spindle_feedback_reference", }, ], coreNets: [ { signal: "Xpos", source: "joint.0.motor-pos-cmd", target: "joint.0.motor-pos-fb", role: "X command-to-feedback simulation loop", }, { signal: "Ypos", source: "joint.1.motor-pos-cmd", target: "joint.1.motor-pos-fb", role: "Y command-to-feedback simulation loop", }, { signal: "Zpos", source: "joint.2.motor-pos-cmd", target: "joint.2.motor-pos-fb", role: "Z command-to-feedback simulation loop", }, { signal: "Apos", source: "joint.3.motor-pos-cmd", target: "joint.3.motor-pos-fb", role: "A command-to-feedback simulation loop", }, { signal: "Bpos", source: "joint.4.motor-pos-cmd", target: "joint.4.motor-pos-fb", role: "B command-to-feedback simulation loop", }, { signal: "estop-loop", source: "iocontrol.0.user-enable-out", target: "iocontrol.0.emc-enable-in", role: "simulated estop enable loop", }, { signal: "tool-prep-loop", source: "iocontrol.0.tool-prepare", target: "iocontrol.0.tool-prepared", role: "simulated tool prepare completion", }, { signal: "tool-change-loop", source: "iocontrol.0.tool-change", target: "iocontrol.0.tool-changed", role: "simulated automatic tool-change completion", }, { signal: "flood", source: "iocontrol.0.coolant-flood", target: "gmoccapy coolant display via status", role: "coolant flood state", }, { signal: "mist", source: "iocontrol.0.coolant-mist", target: "gmoccapy coolant display via status", role: "coolant mist state", }, ], spindleNets: [ { signal: "spindle-speed-cmd", source: "spindle.0.speed-out", target: "limit_speed.in", role: "commanded spindle speed", }, { signal: "spindle-speed-limited", source: "limit_speed.out", target: "sim_encoder_0.speed", role: "simulated spindle inertia", }, { signal: "spindle-pos", source: "encoder_0.position", target: "spindle.0.revs", role: "encoder feedback position", }, { signal: "spindle-at-speed", source: "near_speed.out", target: "spindle.0.at-speed", role: "at-speed comparator result", }, ], postguiNets: [ { signal: "spindle-abs", source: "abs_spindle_feedback.out", target: "gmoccapy.spindle_feedback_bar", requiresHalcompReady: true, role: "spindle feedback bar", }, { signal: "spindle-at-speed", source: "spindle.0.at-speed", target: "gmoccapy.spindle_at_speed_led", requiresHalcompReady: true, role: "spindle at-speed LED", }, { signal: "tooloffset-x", source: "motion.tooloffset.x", target: "gmoccapy.tooloffset-x", requiresHalcompReady: true, role: "tool X offset display", }, { signal: "tooloffset-z", source: "motion.tooloffset.z", target: "gmoccapy.tooloffset-z", requiresHalcompReady: true, role: "tool Z offset display", }, { signal: "tool-change-loop", source: "iocontrol.0.tool-change", target: "iocontrol.0.tool-changed", requiresHalcompReady: true, simulationLoop: true, role: "automatic simulated tool-change completion", }, ], hardwareButtons: { source: { path: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py", methods: ["_button_pin_changed", "_get_child_button", "_make_hal_pins"], }, behavior: { edge: "rising-edge-only", hButtonContainer: "current ntb_button page visible children", vButtonContainer: "vbtb_main visible children", insensitiveTarget: "ignored", hiddenLabelsSkipped: true, semanticBoundary: "native_gmoccapy_hardware_button_pin_to_visible_sensitive_button", }, verticalMain: [ { index: 0, pin: "gmoccapy.v-button.button-0", nativeWidget: "tbtn_estop", webAction: "ESTOP", webDispatch: { type: "ESTOP" }, webSelector: '[data-action="estop"]', gate: "always clickable safety action", }, { index: 1, pin: "gmoccapy.v-button.button-1", nativeWidget: "tbtn_on", webAction: "TOGGLE_POWER", webDispatch: { type: "TOGGLE_POWER" }, webSelector: '[data-action="power"]', gate: "blocked while STATE_ESTOP", }, { index: 2, pin: "gmoccapy.v-button.button-2", nativeWidget: "rbt_manual", webAction: "SET_MODE manual", webDispatch: { type: "SET_MODE", mode: "manual" }, webSelector: '[data-action="mode-manual"]', gate: "machine on and AUTO interpreter idle", }, { index: 3, pin: "gmoccapy.v-button.button-3", nativeWidget: "rbt_mdi", webAction: "SET_MODE mdi", webDispatch: { type: "SET_MODE", mode: "mdi" }, webSelector: '[data-action="mode-mdi"]', gate: "machine on and homed when NO_FORCE_HOMING=0", }, { index: 4, pin: "gmoccapy.v-button.button-4", nativeWidget: "rbt_auto", webAction: "SET_MODE auto", webDispatch: { type: "SET_MODE", mode: "auto" }, webSelector: '[data-action="mode-auto"]', gate: "machine on and homed when NO_FORCE_HOMING=0", }, { index: 5, pin: "gmoccapy.v-button.button-5", nativeWidget: "tbtn_user_tabs", webAction: "GMOCAPY_NATIVE_PAGE user-tabs", webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "user-tabs", nativeWidget: "tbtn_user_tabs" }, webSelector: null, gate: "native user tabs page is diagnostic-only in the Web shell", }, { index: 6, pin: "gmoccapy.v-button.button-6", nativeWidget: "tbtn_setup", webAction: "GMOCAPY_NATIVE_PAGE setup", webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "setup", nativeWidget: "tbtn_setup" }, webSelector: null, gate: "native setup page is diagnostic-only in the Web shell", }, ], bottomMain: [ { index: 0, pin: "gmoccapy.h-button.button-0", nativeWidget: "btn_homing", webAction: "HOME", webDispatch: { type: "HOME" }, webSelector: '[data-action="HOME"]', gate: "machine on and manual mode", }, { index: 1, pin: "gmoccapy.h-button.button-1", nativeWidget: "btn_touch", webAction: "GMOCAPY_NATIVE_PAGE touch-off", webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "touch-off", nativeWidget: "btn_touch" }, webSelector: null, gate: "touch-off page not implemented in Web shell", }, { index: 3, pin: "gmoccapy.h-button.button-3", nativeWidget: "btn_tool", webAction: "GMOCAPY_NATIVE_PAGE tool-editor", webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "tool-editor", nativeWidget: "btn_tool" }, webSelector: null, gate: "tool editor page not implemented in Web shell", }, { index: 6, pin: "gmoccapy.h-button.button-6", nativeWidget: "tbtn_switch_mode", webAction: "GMOCAPY_NATIVE_PAGE switchkins-mode", webDispatch: { type: "GMOCAPY_NATIVE_PAGE", pageId: "switchkins-mode", nativeWidget: "tbtn_switch_mode" }, webSelector: null, gate: "native joint/world switch page position is diagnostic-only in the Web shell", }, ], }, halPinActions: { source: { path: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py", methods: [ "_ignore_limits", "_optional_blocks", "_blockdelete", "_on_pin_jog_changed", "_on_pin_incr_changed", "_on_counts_changed", "_on_analog_enable_changed", "_on_analog_value_changed", "_reset_override", "_del_message_changed", "_on_unlock_settings_changed", "_check_toolmeasurement", "on_chk_use_tool_measurement_toggled", "on_btn_block_height_clicked", "_on_blockheight_value_changed", "_init_user_messages", "_show_user_message", ], prefPath: "linuxcnc/configs/sim/gmoccapy/gmoccapy_XYZAB.pref", }, jogPins: { axes: [ { axis: "x", plus: "gmoccapy.jog.axis.jog-x-plus", minus: "gmoccapy.jog.axis.jog-x-minus" }, { axis: "y", plus: "gmoccapy.jog.axis.jog-y-plus", minus: "gmoccapy.jog.axis.jog-y-minus" }, { axis: "z", plus: "gmoccapy.jog.axis.jog-z-plus", minus: "gmoccapy.jog.axis.jog-z-minus" }, { axis: "a", plus: "gmoccapy.jog.axis.jog-a-plus", minus: "gmoccapy.jog.axis.jog-a-minus" }, { axis: "b", plus: "gmoccapy.jog.axis.jog-b-plus", minus: "gmoccapy.jog.axis.jog-b-minus" }, ], increments: [ { index: 0, pin: "gmoccapy.jog.jog-inc-0", label: "Continuous", distance: 0 }, { index: 1, pin: "gmoccapy.jog.jog-inc-1", label: "1.000 mm", distance: 1 }, { index: 2, pin: "gmoccapy.jog.jog-inc-2", label: "0.100 mm", distance: 0.1 }, { index: 3, pin: "gmoccapy.jog.jog-inc-3", label: "0.010 mm", distance: 0.01 }, { index: 4, pin: "gmoccapy.jog.jog-inc-4", label: "0.001 mm", distance: 0.001 }, { index: 5, pin: "gmoccapy.jog.jog-inc-5", label: "1.2345 in", distance: 31.3563 }, ], outputPin: "gmoccapy.jog.jog-increment", turtlePin: "gmoccapy.jog.turtle-jog", nativeCallbacks: { axis: "_on_pin_jog_changed -> _on_btn_jog_pressed/_on_btn_jog_released", increment: "_on_pin_incr_changed -> _jog_increment_changed", turtle: "_on_pin_turtle_jog -> tbtn_turtle_jog.set_active", }, }, operatorPins: [ { pin: "gmoccapy.ignore-limits", nativeCallback: "_ignore_limits -> chk_ignore_limits.set_active", nativeCommand: "on_chk_ignore_limits_toggled -> command.override_limits() when active", webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.ignore-limits" }, webState: "gmoccapyGui.ignoreLimits", }, { pin: "gmoccapy.optional-stop", nativeCallback: "_optional_blocks", nativeCommand: "tbtn_optional_blocks -> command.set_block_delete(state)", webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.optional-stop" }, webState: "gmoccapyGui.optionalBlocks", }, { pin: "gmoccapy.blockdelete", nativeCallback: "_blockdelete", nativeCommand: "command.set_optional_stop(state)", webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.blockdelete" }, webState: "gmoccapyGui.optionalStop", }, ], settingsPins: [ { pin: "gmoccapy.unlock-settings", nativeCallback: "_on_unlock_settings_changed", nativeCommand: "rbt_hal_unlock active gates tbtn_setup sensitivity from pin level", prefDefault: "unlock_way=use", webDispatch: { type: "GMOCAPY_HAL_PIN", pin: "gmoccapy.unlock-settings" }, webState: "gmoccapyGui.settingsUnlockPin", }, ], overridePins: [ { target: "feed", counts: "gmoccapy.feed.feed-override.counts", countEnable: "gmoccapy.feed.feed-override.count-enable", analogEnable: "gmoccapy.feed.feed-override.analog-enable", directValue: "gmoccapy.feed.feed-override.direct-value", reset: "gmoccapy.feed.reset-feed-override", nativeWidget: "spc_feed", scalePref: "scale_feed_override=1", webState: "feed.feedOverride", }, { target: "rapid", counts: "gmoccapy.rapid.rapid-override.counts", countEnable: "gmoccapy.rapid.rapid-override.count-enable", analogEnable: "gmoccapy.rapid.rapid-override.analog-enable", directValue: "gmoccapy.rapid.rapid-override.direct-value", reset: "gmoccapy.rapid.reset-rapid-override", nativeWidget: "spc_rapid", scalePref: "scale_rapid_override=1", webState: "feed.rapidOverride", }, { target: "spindle", counts: "gmoccapy.spindle.spindle-override.counts", countEnable: "gmoccapy.spindle.spindle-override.count-enable", analogEnable: "gmoccapy.spindle.spindle-override.analog-enable", directValue: "gmoccapy.spindle.spindle-override.direct-value", reset: "gmoccapy.spindle.reset-spindle-override", nativeWidget: "spc_spindle", scalePref: "scale_spindle_override=1", webState: "spindle.override", }, { target: "jogVelocity", counts: "gmoccapy.jog.jog-velocity.counts", countEnable: "gmoccapy.jog.jog-velocity.count-enable", analogEnable: "gmoccapy.jog.jog-velocity.analog-enable", directValue: "gmoccapy.jog.jog-velocity.direct-value", reset: null, nativeWidget: "spc_lin_jog_vel", scalePref: "scale_jog_vel=140.4", webState: "gmoccapyGui.jogVelocity", }, ], messagePins: [ { pin: "gmoccapy.delete-message", nativeCallback: "_del_message_changed", nativeCommand: "pin true deletes first alert message when gmoccapy.error is set, otherwise del_last()", webState: "operatorMessage", }, { pin: "gmoccapy.warning-confirm", nativeCallback: "dialogs.warning_dialog periodic confirm_pin poll", nativeCommand: "pin true responds OK to active warning dialog", webState: "gmoccapyGui.warningConfirm", }, { pin: "gmoccapy.error", nativeCallback: "_show_error/_on_message_deleted", nativeCommand: "HAL OUT bit tracks alert messages", webState: "gmoccapyGui.error", }, ], toolMeasurementPins: { toolsensorConfigured: false, useToolMeasurementPref: false, prefDefaults: { useToolMeasurement: "use_toolmeasurement=False", blockHeight: "blockheight=0.0", }, disabledReason: "gmoccapy_XYZAB.ini has no [TOOLSENSOR] data, so _check_toolmeasurement disables the controls", pins: [ { pin: "gmoccapy.probeheight", direction: "HAL_OUT", nativeCallback: "on_spbtn_probe_height_value_changed / on_chk_use_tool_measurement_toggled / on_btn_block_height_clicked", webState: "gmoccapyGui.probeHeight", }, { pin: "gmoccapy.blockheight", direction: "HAL_OUT", nativeCallback: "on_btn_block_height_clicked / _on_blockheight_value_changed", webState: "gmoccapyGui.blockHeight", }, { pin: "gmoccapy.toolmeasurement", direction: "HAL_OUT", nativeCallback: "on_chk_use_tool_measurement_toggled", webState: "gmoccapyGui.toolMeasurement", }, { pin: "gmoccapy.searchvel", direction: "HAL_OUT", nativeCallback: "on_spbtn_search_vel_value_changed / on_chk_use_tool_measurement_toggled", webState: "gmoccapyGui.searchVelocity", }, { pin: "gmoccapy.probevel", direction: "HAL_OUT", nativeCallback: "on_spbtn_probe_vel_value_changed / on_chk_use_tool_measurement_toggled", webState: "gmoccapyGui.probeVelocity", }, ], }, userMessages: { configured: false, configuredMessageCount: 0, pins: [], source: "get_ini_info.get_user_messages()", disabledReason: "gmoccapy_XYZAB.ini has no MESSAGE_* entries, so _init_user_messages() returns without creating messages.* pins", dynamicPinPatterns: [ "gmoccapy.messages.", "gmoccapy.messages.-waiting", "gmoccapy.messages.-response", ], supportedTypes: ["status", "okdialog", "yesnodialog"], }, behavior: { optionalStopPinCrossesToBlockDelete: true, blockdeletePinCrossesToOptionalStop: true, unlockSettingsLevelDriven: true, jogAxisPinsPressRelease: true, jogPinsUseTaskPolicyGate: true, jogIncrementPinsRisingEdgeOnly: true, jogIncrementZeroIsContinuous: true, turtleJogLevelDriven: true, countInputRequiresEnable: true, directValueRequiresAnalogEnable: true, resetPinsRisingEdgeOnly: true, deleteMessageRisingEdgeOnly: true, warningConfirmLevelPolled: true, toolMeasurementPinsAreHalOut: true, toolMeasurementDisabledWithoutToolsensor: true, userMessagesDynamicIniOnly: true, directValueRange: "0..1", semanticBoundary: "native_gmoccapy_hal_pin_callbacks_to_web_store_actions", }, }, nativePages: { source: { path: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.py", gladePath: "linuxcnc/src/emc/usr_intf/gmoccapy/gmoccapy.glade", methods: [ "_init_IconFileSelection", "_init_file_to_load", "on_btn_load_clicked", "on_IconFileSelection1_selected", "on_hal_status_file_loaded", "_make_macro_button", "_on_btn_macro_pressed", "_init_tooleditor", "_show_tooledit_tab", "on_btn_tool_clicked", "on_btn_selected_tool_clicked", "on_btn_select_tool_by_no_clicked", "on_tbtn_setup_toggled", "on_tbtn_user_tabs_toggled", "on_btn_touch_clicked", ], }, filePage: { pageId: "file-load", nativeNotebookPage: "_BB_LOAD_FILE / ntb_preview page 3", nativeWidget: "IconFileSelection1", programPrefix: "../../nc_files/", defaultOpenPreference: "open_file", fileExtensions: [ "*.ngc", "*.png", "*.gif", "*.jpg", "*.py", ], nativeCallbacks: [ "on_btn_load_clicked -> _show_iconview_tab(True)", "on_IconFileSelection1_selected -> hal_action_open.load_file(path)", "on_hal_status_file_loaded -> gmoccapy.program.length", "on_hal_status_line_changed -> gmoccapy.program.current-line/progress", ], webSurface: "OPEN_FILE input, staged LinuxCNC G-code source selector and program preview", webAction: "GMOCAPY_PAGE_ACTION file-load diagnostics", implementation: "partial", boundary: "native_GtkIconFileSelection_not_embedded_in_browser", }, macroPage: { pageId: "mdi-macros", nativeContainer: "hbtb_MDI", iniSection: "[MACROS]", macroLimit: 14, macros: [ { name: "i_am_lost", args: [], file: "macros/i_am_lost.ngc", commandTemplate: "O call" }, { name: "halo_world", args: [], file: "macros/halo_world.ngc", commandTemplate: "O call" }, { name: "jog_around", args: [], file: "macros/jog_around.ngc", commandTemplate: "O call" }, { name: "increment", args: ["xinc", "yinc"], file: "macros/increment.ngc", commandTemplate: "O call [xinc] [yinc]" }, { name: "go_to_position", args: ["X-pos", "Y-pos", "Z-pos"], file: "macros/go_to_position.ngc", commandTemplate: "O call [X-pos] [Y-pos] [Z-pos]" }, ], nativeCallbacks: [ "_make_macro_button -> get_ini_info.get_macros()", "_on_btn_macro_pressed -> command.mdi(O call [args])", "on_hal_status_interp_idle enables macro buttons", "on_hal_status_interp_run disables macro buttons", ], webAction: "GMOCAPY_RUN_MACRO", implementation: "partial", boundary: "macro_buttons_map_to_MDI_command_without_native_entry_dialogs", }, toolEditorPage: { pageId: "tool-editor", nativeNotebookPage: "ntb_preview page 2 / _BB_TOOL", nativeWidget: "tooledit1", toolTablePath: "linuxcnc/configs/sim/gmoccapy/tool.tbl", visibleAxes: ["X", "Y", "Z", "A", "B"], toolCount: 17, nativeCallbacks: [ "_init_tooleditor -> tooledit1.set_filename(tool.tbl)", "_show_tooledit_tab(True) -> tooledit1.reload()", "on_btn_selected_tool_clicked -> M61 Q? or T? M6", "on_btn_save_tool_changes_clicked -> tooledit1.save(None)", "on_btn_reload_tooltable_clicked -> tooledit1.reload(None)", ], webAction: "GMOCAPY_TOOL_EDITOR_ACTION diagnostics", editableInWeb: false, implementation: "diagnostic-only", boundary: "tool_table_writeback_not_promoted_browser_keeps_iocontrol_loopback", }, implementationMatrix: [ { pageId: "main", nativeWidget: "ntb_main page 0", implementation: "implemented", webSurface: "DRO/G-code/preview/main controls", hardButton: null }, { pageId: "manual-home", nativeWidget: "btn_homing / _BB_HOME", implementation: "partial", webSurface: "HOME action", hardButton: "gmoccapy.h-button.button-0" }, { pageId: "mdi-macros", nativeWidget: "hbtb_MDI macro buttons", implementation: "partial", webSurface: "MDI macro diagnostics and dispatch", hardButton: null }, { pageId: "auto-run", nativeWidget: "_BB_AUTO buttons", implementation: "partial", webSurface: "RUN/STOP/PAUSE/STEP controls", hardButton: null }, { pageId: "file-load", nativeWidget: "IconFileSelection1 / _BB_LOAD_FILE", implementation: "partial", webSurface: "OPEN_FILE input and staged source selector", hardButton: null }, { pageId: "tool-editor", nativeWidget: "btn_tool / tooledit1", implementation: "diagnostic-only", webSurface: "tool table summary and action diagnostics", hardButton: "gmoccapy.h-button.button-3" }, { pageId: "touch-off", nativeWidget: "btn_touch / offsetpage1", implementation: "diagnostic-only", webSurface: "touch-off boundary diagnostics", hardButton: "gmoccapy.h-button.button-1" }, { pageId: "setup", nativeWidget: "tbtn_setup / ntb_setup", implementation: "diagnostic-only", webSurface: "settings/unlock diagnostics", hardButton: "gmoccapy.v-button.button-6" }, { pageId: "user-tabs", nativeWidget: "tbtn_user_tabs / ntb_user_tabs", implementation: "diagnostic-only", webSurface: "user tab boundary diagnostics", hardButton: "gmoccapy.v-button.button-5" }, { pageId: "switchkins-mode", nativeWidget: "tbtn_switch_mode", implementation: "diagnostic-only", webSurface: "identity-only XYZAB switchkins diagnostic", hardButton: "gmoccapy.h-button.button-6" }, { pageId: "edit", nativeWidget: "_BB_EDIT / gcode_view editable", implementation: "native-only", webSurface: "not promoted", hardButton: null }, { pageId: "offset-editor", nativeWidget: "offsetpage1 edit offsets", implementation: "native-only", webSurface: "not promoted", hardButton: null }, ], behavior: { unimplementedPagesDiagnosticOnly: true, hardButtonsDoNotFakeNativePages: true, fileChooserNotNativeGtk: true, macroButtonsUseMdiGate: true, toolEditorWritebackDisabled: true, toolEditorKeepsIocontrolLoopback: true, semanticBoundary: "native_gmoccapy_page_matrix_web_diagnostic_boundary", }, }, toolChange: { strategy: "iocontrol-loopback", manualGmoccapyPinsConnected: false, remapCodes: ["M6", "M61"], postguiUnlinks: [ { pin: "iocontrol.0.tool-change", reason: "gmoccapy_postgui.hal removes the core_sim connection before applying the final loopback", }, { pin: "iocontrol.0.tool-changed", reason: "gmoccapy_postgui.hal removes the core_sim connection before applying the final loopback", }, { pin: "iocontrol.0.tool-prep-number", reason: "manual gmoccapy tool-change number net is not active in this simulation", }, ], commentedManualGuiNets: [ { signal: "tool-change", source: "iocontrol.0.tool-change", target: "gmoccapy.toolchange-change", }, { signal: "tool-changed", source: "gmoccapy.toolchange-changed", target: "iocontrol.0.tool-changed", }, { signal: "tool-prep-number", source: "iocontrol.0.tool-prep-number", target: "gmoccapy.toolchange-number", }, ], activeLoop: { signal: "tool-change-loop", source: "iocontrol.0.tool-change", target: "iocontrol.0.tool-changed", stage: "POSTGUI_HALFILE", }, semanticBoundary: "gmoccapy_xyzab_iocontrol_tool_change_loop_no_manual_gui_dialog", }, semanticBoundary: "gmoccapy_hal_pin_postgui_reference_web_diagnostic_only", }; export function createGmoccapyHalSummary(model = gmoccapyHalModel) { const pinCount = model.nativePins.reduce((total, group) => total + group.pins.length, 0); const postguiFile = model.halFiles.find((file) => file.stage === "POSTGUI_HALFILE"); const mappedHardwareButtonCount = [ ...(model.hardwareButtons?.verticalMain || []), ...(model.hardwareButtons?.bottomMain || []), ].filter((button) => button.webSelector).length; return { apiName: `${model.apiName}-summary`, profileId: model.profileId, halFileCount: model.halFiles.length, nativePinGroupCount: model.nativePins.length, nativePinCount: pinCount, coreNetCount: model.coreNets.length, spindleNetCount: model.spindleNets.length, postguiNetCount: model.postguiNets.length, postguiRequiresHalcompReady: Boolean(postguiFile?.requiresHalcompReady) && model.postguiNets.every((net) => net.requiresHalcompReady), hasToolChangeSimulationLoop: model.postguiNets.some((net) => net.simulationLoop), toolChangeStrategy: model.toolChange.strategy, manualToolChangeGuiConnected: model.toolChange.manualGmoccapyPinsConnected, postguiToolUnlinkCount: model.toolChange.postguiUnlinks.length, commentedManualToolChangeNetCount: model.toolChange.commentedManualGuiNets.length, hardwareButtonVerticalCount: model.hardwareButtons.verticalMain.length, hardwareButtonBottomMainCount: model.hardwareButtons.bottomMain.length, mappedHardwareButtonCount, hardwareButtonEdge: model.hardwareButtons.behavior.edge, hardwareButtonInsensitiveTarget: model.hardwareButtons.behavior.insensitiveTarget, operatorInputPinCount: model.halPinActions.operatorPins.length, settingsInputPinCount: model.halPinActions.settingsPins.length, overridePinTargetCount: model.halPinActions.overridePins.length, jogAxisPinCount: (model.halPinActions.jogPins?.axes || []).length * 2, jogIncrementPinCount: model.halPinActions.jogPins?.increments?.length || 0, messageInputPinCount: model.halPinActions.messagePins.length, toolMeasurementPinCount: model.halPinActions.toolMeasurementPins.pins.length, toolMeasurementEnabled: model.halPinActions.toolMeasurementPins.useToolMeasurementPref, toolsensorConfigured: model.halPinActions.toolMeasurementPins.toolsensorConfigured, userMessagePinCount: model.halPinActions.userMessages.pins.length, userMessagesConfigured: model.halPinActions.userMessages.configured, optionalStopPinCrossesToBlockDelete: model.halPinActions.behavior.optionalStopPinCrossesToBlockDelete, blockdeletePinCrossesToOptionalStop: model.halPinActions.behavior.blockdeletePinCrossesToOptionalStop, unlockSettingsLevelDriven: model.halPinActions.behavior.unlockSettingsLevelDriven, jogAxisPinsPressRelease: model.halPinActions.behavior.jogAxisPinsPressRelease, jogPinsUseTaskPolicyGate: model.halPinActions.behavior.jogPinsUseTaskPolicyGate, jogIncrementPinsRisingEdgeOnly: model.halPinActions.behavior.jogIncrementPinsRisingEdgeOnly, jogIncrementZeroIsContinuous: model.halPinActions.behavior.jogIncrementZeroIsContinuous, turtleJogLevelDriven: model.halPinActions.behavior.turtleJogLevelDriven, countInputRequiresEnable: model.halPinActions.behavior.countInputRequiresEnable, directValueRequiresAnalogEnable: model.halPinActions.behavior.directValueRequiresAnalogEnable, resetPinsRisingEdgeOnly: model.halPinActions.behavior.resetPinsRisingEdgeOnly, deleteMessageRisingEdgeOnly: model.halPinActions.behavior.deleteMessageRisingEdgeOnly, warningConfirmLevelPolled: model.halPinActions.behavior.warningConfirmLevelPolled, toolMeasurementPinsAreHalOut: model.halPinActions.behavior.toolMeasurementPinsAreHalOut, toolMeasurementDisabledWithoutToolsensor: model.halPinActions.behavior.toolMeasurementDisabledWithoutToolsensor, userMessagesDynamicIniOnly: model.halPinActions.behavior.userMessagesDynamicIniOnly, nativePageCount: model.nativePages.implementationMatrix.length, implementedNativePageCount: model.nativePages.implementationMatrix .filter((page) => page.implementation === "implemented").length, partialNativePageCount: model.nativePages.implementationMatrix .filter((page) => page.implementation === "partial").length, diagnosticOnlyNativePageCount: model.nativePages.implementationMatrix .filter((page) => page.implementation === "diagnostic-only").length, nativeOnlyPageCount: model.nativePages.implementationMatrix .filter((page) => page.implementation === "native-only").length, filePageImplementation: model.nativePages.filePage.implementation, filePageBoundary: model.nativePages.filePage.boundary, macroCount: model.nativePages.macroPage.macros.length, macroLimit: model.nativePages.macroPage.macroLimit, macroButtonsUseMdiGate: model.nativePages.behavior.macroButtonsUseMdiGate, toolEditorImplementation: model.nativePages.toolEditorPage.implementation, toolEditorWritebackDisabled: model.nativePages.behavior.toolEditorWritebackDisabled, hardButtonsDoNotFakeNativePages: model.nativePages.behavior.hardButtonsDoNotFakeNativePages, unimplementedPagesDiagnosticOnly: model.nativePages.behavior.unimplementedPagesDiagnosticOnly, semanticBoundary: model.semanticBoundary, }; } export function resolveGmoccapyHardwareButton(input, model = gmoccapyHalModel) { const pin = typeof input === "string" ? input : input?.pin; const location = typeof input === "object" ? input?.location || input?.panel : null; const index = typeof input === "object" && input?.index !== undefined ? Number(input.index) : null; const allButtons = [ ...(model.hardwareButtons?.verticalMain || []).map((button) => ({ ...button, panel: "right", location: "v" })), ...(model.hardwareButtons?.bottomMain || []).map((button) => ({ ...button, panel: "bottom", location: "h" })), ]; if (pin) return allButtons.find((button) => button.pin === pin) || null; if (!Number.isFinite(index)) return null; const normalizedLocation = location === "right" || location === "v" || location === "vertical" ? "v" : location === "bottom" || location === "h" || location === "horizontal" ? "h" : null; return allButtons.find((button) => button.location === normalizedLocation && button.index === index) || null; }