With this, we will have to address it pragmatically as we do not have pre-canned options for doing this. We do it this way to prevent operators from accidentally hitting the a zero when they do not mean to. Use the following code in your UserGUIModule. It should function like you want. This code will address your Edit Offsets..
----------------------------------------------------------------------
-- Always-On Edit Offsets
--
-- INTENDED FOR SINGLE-INSTANCE MACH CONFIGURATIONS.
--
-- Policy:
-- Edit Offsets ON whenever Mach is Idle.
-- Edit Offsets OFF whenever Mach is not Idle.
-- Do not fight the Cycle Start sequence while it intentionally
-- turns Edit Mode off.
-- If Mach or the operator turns Edit Offsets off while Idle,
-- restore it automatically.
--
----------------------------------------------------------------------
----------------------------------------------------------------------
-- Preserve existing OEM / inherited callbacks.
----------------------------------------------------------------------
local PreviousScreenIsLoadedScript =
UserGUIModule.ScreenIsLoadedScript
local PreviousMachStateChanged =
UserGUIModule.MachStateChanged
local PreviousPostScreenTabEnter =
UserGUIModule.PostScreenTabEnter
local PreviousUserPLCScript =
UserGUIModule.UserPLCScript
----------------------------------------------------------------------
-- State
----------------------------------------------------------------------
local PendingEditModeEnable = false
local EditModeWatchdogTimer = wx.wxStopWatch()
local EDIT_MODE_WATCHDOG_MS = 250
local MultiInstanceWarningLogged = false
----------------------------------------------------------------------
-- CallPreservedCallback
--
-- Runs an OEM / inherited callback that existed before this module
-- replaced the exact callback name.
----------------------------------------------------------------------
function UserGUIModule.CallPreservedCallback(callback, ...)
if callback == nil then
return true, true, nil
end
local is_ok, a, b, c =
w.pcall(callback, ...)
if not is_ok then
return nil, false,
w.FunctionError(w.ErrorMessage(a))
end
if b == false then
return a, false,
w.FunctionError(c)
end
if a == false then
return false, b, c
end
return true, true, c
end
----------------------------------------------------------------------
-- IsAlwaysOnEditModeSupported
--
-- CommonScreenV02.EditModeOn() checks the global MACH_STATE, which
-- represents instance 0.
--
-- Because of that Common implementation, this policy is deliberately
-- disabled when more than one Mach instance is configured.
----------------------------------------------------------------------
function UserGUIModule.IsAlwaysOnEditModeSupported()
if w.GetInstanceCount() ~= 1 then
if not MultiInstanceWarningLogged then
w.Log(
"Always-On Edit Offsets disabled: "
.. "CommonScreenV02.EditModeOn uses the instance-0 "
.. "MACH_STATE global and is not selected-instance safe."
)
MultiInstanceWarningLogged = true
end
return false
end
return true
end
----------------------------------------------------------------------
-- ApplyAlwaysOnEditMode
--
-- Central policy function.
----------------------------------------------------------------------
function UserGUIModule.ApplyAlwaysOnEditMode()
--------------------------------------------------------------
-- Do not claim multi-instance support that CommonScreenV02
-- cannot provide.
--------------------------------------------------------------
if not UserGUIModule.IsAlwaysOnEditModeSupported() then
return true, true,
"Always-On Edit Offsets skipped for multi-instance configuration"
end
local inst = 0
--------------------------------------------------------------
-- Determine the real current idle state from Mach's output
-- signal rather than depending on the cached MACH_STATE global.
--------------------------------------------------------------
local idle, b, c =
w.GetSignalState(
mc.OSIG_MACHINE_IDLE,
inst
)
if b ~= true then
return nil, false,
w.FunctionError(c)
end
--------------------------------------------------------------
-- IDLE
--------------------------------------------------------------
if idle then
----------------------------------------------------------
-- Cycle Start deliberately turns Edit Mode off while its
-- startup sequence is running.
--
-- Do not fight that sequence.
----------------------------------------------------------
if w.FuncTracing["m.CycleStart"] == true then
PendingEditModeEnable = true
return true, true,
"Edit Offsets enable deferred during Cycle Start"
end
----------------------------------------------------------
-- Already active -- nothing to do.
----------------------------------------------------------
if m.screen.IsEditModeActive() then
PendingEditModeEnable = false
return true, true,
"Edit Offsets already active"
end
----------------------------------------------------------
-- Ask the normal Mach screen to enable Edit Mode.
----------------------------------------------------------
local is_ok, a, b, c =
w.pcall(m.screen.EditModeOn)
if not is_ok then
local msg = string.format(
"Unable to automatically enable Edit Offsets: %s",
w.ErrorMessage(a)
)
w.Log(msg)
PendingEditModeEnable = true
return nil, false,
w.FunctionError(msg)
end
if b == false then
PendingEditModeEnable = true
return a, false,
w.FunctionError(c)
end
----------------------------------------------------------
-- EditModeOn can return success even when its MACH_STATE
-- check prevented activation.
--
-- Verify the actual GUI state before logging success.
----------------------------------------------------------
if not m.screen.IsEditModeActive() then
PendingEditModeEnable = true
return true, true,
"Edit Offsets enable deferred"
end
PendingEditModeEnable = false
w.Log(
"Edit Offsets automatically enabled: machine is Idle"
)
--------------------------------------------------------------
-- NOT IDLE
--------------------------------------------------------------
else
PendingEditModeEnable = false
----------------------------------------------------------
-- If already off, nothing is required.
----------------------------------------------------------
if not m.screen.IsEditModeActive() then
return true, true,
"Edit Offsets already inactive"
end
----------------------------------------------------------
-- Turn Edit Mode off immediately whenever motion/state
-- leaves Idle.
----------------------------------------------------------
local is_ok, a, b, c =
w.pcall(m.screen.EditModeOff)
if not is_ok then
local msg = string.format(
"Unable to automatically disable Edit Offsets: %s",
w.ErrorMessage(a)
)
w.Log(msg)
return nil, false,
w.FunctionError(msg)
end
if b == false then
return a, false,
w.FunctionError(c)
end
----------------------------------------------------------
-- Verify that the screen actually changed state before
-- reporting success.
----------------------------------------------------------
if m.screen.IsEditModeActive() then
return nil, false,
w.FunctionError(
"Edit Offsets remained active after EditModeOff"
)
end
w.Log(
"Edit Offsets automatically disabled: machine is not Idle"
)
end
return true, true,
"Always-On Edit Offsets policy satisfied"
end
----------------------------------------------------------------------
-- ScreenIsLoadedScript Hook
--
-- Apply the policy once the normal screen startup has completed.
----------------------------------------------------------------------
function UserGUIModule.ScreenIsLoadedScript()
--------------------------------------------------------------
-- Preserve inherited / OEM behavior.
--------------------------------------------------------------
local a, b, c =
UserGUIModule.CallPreservedCallback(
PreviousScreenIsLoadedScript
)
if b ~= true then
return a, false, w.FunctionError(c)
end
if a == false then
return false, b, c
end
--------------------------------------------------------------
-- Start the watchdog timing from a known point.
--------------------------------------------------------------
EditModeWatchdogTimer:Start()
--------------------------------------------------------------
-- If this is multi-instance, log the limitation and leave the
-- normal Mach behavior untouched.
--------------------------------------------------------------
if not UserGUIModule.IsAlwaysOnEditModeSupported() then
return true, true, w.FunctionCompleted()
end
--------------------------------------------------------------
-- Startup normally occurs after the Mach state globals are
-- valid, so try immediately.
--
-- If EditModeOn declines because state initialization is still
-- settling, ApplyAlwaysOnEditMode sets PendingEditModeEnable
-- and the PLC callback will retry.
--------------------------------------------------------------
PendingEditModeEnable = true
local pa, pb, pc =
UserGUIModule.ApplyAlwaysOnEditMode()
if pb ~= true then
return pa, false, w.FunctionError(pc)
end
return true, true, w.FunctionCompleted()
end
----------------------------------------------------------------------
-- MachStateChanged Hook
--
-- IMPORTANT:
--
-- CommonGUIModule invokes this hook BEFORE it updates the global
-- instance-0 MACH_STATE.
--
-- Therefore:
--
-- Going NON-IDLE:
-- Disable Edit Mode immediately. This path does not depend on
-- EditModeOn's MACH_STATE check.
--
-- Going IDLE:
-- Set PendingEditModeEnable and let UserPLCScript enable Edit
-- Mode later in the SAME PLC pass, after MACH_STATE is current.
----------------------------------------------------------------------
function UserGUIModule.MachStateChanged(inst, state)
--------------------------------------------------------------
-- Preserve inherited / OEM behavior.
--------------------------------------------------------------
local a, b, c =
UserGUIModule.CallPreservedCallback(
PreviousMachStateChanged,
inst,
state
)
if b ~= true then
return a, false, w.FunctionError(c)
end
if a == false then
return false, b, c
end
--------------------------------------------------------------
-- This implementation intentionally supports instance 0 only.
--------------------------------------------------------------
if not UserGUIModule.IsAlwaysOnEditModeSupported() then
return true, true, w.FunctionCompleted()
end
if inst ~= 0 then
return true, true, w.FunctionCompleted()
end
--------------------------------------------------------------
-- Idle transition:
--
-- Do NOT call EditModeOn here. MACH_STATE still contains the
-- previous state at this point.
--------------------------------------------------------------
if state == mc.MC_STATE_IDLE then
PendingEditModeEnable = true
return true, true,
w.FunctionCompleted(
"Edit Offsets enable scheduled after state update"
)
end
--------------------------------------------------------------
-- Leaving Idle:
--
-- Turn Edit Mode off immediately.
--------------------------------------------------------------
PendingEditModeEnable = false
local pa, pb, pc =
UserGUIModule.ApplyAlwaysOnEditMode()
if pb ~= true then
return pa, false, w.FunctionError(pc)
end
return true, true, w.FunctionCompleted()
end
----------------------------------------------------------------------
-- PostScreenTabEnter Hook
--
-- CommonScreenV02 can automatically turn Edit Mode off when entering
-- tabs other than Tools / Fixtures.
--
-- This hook executes after normal tab processing, so restore the
-- Always-On policy here.
----------------------------------------------------------------------
function UserGUIModule.PostScreenTabEnter(tab)
--------------------------------------------------------------
-- Preserve inherited / OEM behavior.
--------------------------------------------------------------
local a, b, c =
UserGUIModule.CallPreservedCallback(
PreviousPostScreenTabEnter,
tab
)
if b ~= true then
return a, false, w.FunctionError(c)
end
if a == false then
return false, b, c
end
if not UserGUIModule.IsAlwaysOnEditModeSupported() then
return true, true, w.FunctionCompleted()
end
--------------------------------------------------------------
-- MACH_STATE is already current here, so an immediate restore
-- is appropriate.
--------------------------------------------------------------
local pa, pb, pc =
UserGUIModule.ApplyAlwaysOnEditMode()
if pb ~= true then
return pa, false, w.FunctionError(pc)
end
return true, true, w.FunctionCompleted()
end
----------------------------------------------------------------------
-- UserPLCScript
--
-- Performs two jobs:
--
-- 1. Services an Idle transition after CommonGUIModule has updated
-- MACH_STATE.
--
-- 2. Acts as a throttled watchdog so Edit Offsets cannot remain
-- manually turned off while Mach is Idle.
----------------------------------------------------------------------
function UserGUIModule.UserPLCScript()
--------------------------------------------------------------
-- Preserve inherited / OEM PLC behavior first.
--------------------------------------------------------------
local a, b, c =
UserGUIModule.CallPreservedCallback(
PreviousUserPLCScript
)
if b ~= true then
return a, false, w.FunctionError(c)
end
--------------------------------------------------------------
-- Do nothing in unsupported multi-instance configurations.
--------------------------------------------------------------
if not UserGUIModule.IsAlwaysOnEditModeSupported() then
return true, true,
"Always-On Edit Offsets disabled"
end
--------------------------------------------------------------
-- HIGH PRIORITY:
-- Service a pending Idle transition immediately.
--
-- UserPLCScript executes after the Common PLC has refreshed
-- MACH_STATE, so EditModeOn can now pass its normal state check.
--------------------------------------------------------------
if PendingEditModeEnable then
local pa, pb, pc =
UserGUIModule.ApplyAlwaysOnEditMode()
if pb ~= true then
return pa, false, w.FunctionError(pc)
end
----------------------------------------------------------
-- ApplyAlwaysOnEditMode deliberately leaves the pending
-- flag high if Cycle Start or state timing still requires
-- another attempt.
----------------------------------------------------------
return true, true,
"Pending Edit Offsets enable processed"
end
--------------------------------------------------------------
-- Normal watchdog.
--------------------------------------------------------------
if EditModeWatchdogTimer:Time()
< EDIT_MODE_WATCHDOG_MS then
return true, true,
"Edit Offsets watchdog waiting"
end
EditModeWatchdogTimer:Start()
--------------------------------------------------------------
-- Apply normal Always-On policy.
--------------------------------------------------------------
local pa, pb, pc =
UserGUIModule.ApplyAlwaysOnEditMode()
if pb ~= true then
return pa, false, w.FunctionError(pc)
end
return true, true,
"Edit Offsets watchdog complete"
end
Make sure that this code exsists below "local UserGUIModule = ModuleLoader.RequireOEMUserGUIModule(UserGUIModule)" but above "return UserGUIModule.