# coding: utf-8
# python 2 only

# Copyright (c) 2026 TormachTips.com. All rights reserved.
# Licensed under the TormachTips Personal Use License.
# Permission is granted only for private personal use and private personal modification.
# No sharing, publication, distribution, resale, sublicensing, screenshots, code excerpts,
# benchmarks, or videos are permitted without prior written permission.
# Requests:         tormach.1100m@gmail.com
# Information page: https://tormachtips.com/plugins.htm

#-----------------------------------------------------------------------#
# Copyright © 2022 XoomSpeed All rights reserved.                       #
# License: GPL Version 2                                                #   
# Written by David Loomes 7/10/22                                       #
#-----------------------------------------------------------------------#

############################################
##                                        ##
##        Modified ProbeGuard 1.00        ##
##          www.tormachtips.com           ##
##                                        ##
############################################

# 1.00 - fixed utf encoding bug - 4/19/2026
# 0.99 - adds disabled / enabled - 4/16/26

# this is dave and nick's good code

import os
from threading import Thread
import time
import linuxcnc
import hal
import constants
from ui_hooks import plugin

CURRENT_VER         = "1.00"
SCRIPT_NAME         = "ProbeGuard in Cradle Plugin"
DESCRIPTION         = "A modified version of David Loomes ProbeGuard that has an extra check for a closed limit switch, ensuring probe is resting in its holder."
PROBE_TOOL_NUMBERS  = (99,)
PROBE_SLEEP_TIME    = 0.1
NONPROBE_SLEEP_TIME = 1.0
ENABLED             = 1
DEV_MACHINE         = 0
DEV_MACHINE_FLAG    = "/home/operator/gcode/python/dev_machine.txt"

class UserPlugin(plugin):
    def __init__(self):
        plugin.__init__(self, 'Probe guard')
        dev_machine_found = os.path.exists(DEV_MACHINE_FLAG)
        if dev_machine_found:
            plugin_enabled = DEV_MACHINE
        else:
            plugin_enabled = ENABLED
        if plugin_enabled:
            self.error_handler.write("Modified ProbeGuard loaded", constants.ALARM_LEVEL_QUIET)
        else:
            if dev_machine_found:
                self.error_handler.write("Dev machine found. Plugin loaded, but disabled by DEV_MACHINE.", constants.ALARM_LEVEL_QUIET)
            else:
                self.error_handler.write("Plugin loaded, but disabled.", constants.ALARM_LEVEL_QUIET)
                self.error_handler.write("To enable, open script, find ENABLED = 0 and change to ENABLED = 1", constants.ALARM_LEVEL_QUIET)
            return
        self.ProbeGuard_hal = hal.component("ProbeGuard")
        self.ProbeGuard_hal.newpin("new-probe-enable", hal.HAL_BIT, hal.HAL_OUT)
        self.ProbeGuard_hal.newpin("old-probe-enable", hal.HAL_BIT, hal.HAL_IN)
        self.ProbeGuard_hal.ready()
        self.probeMonitorthread = Thread(target=self.monitorProbe)
        self.probeMonitorthread.daemon = True
        self.probeMonitorthread.start()
    
    def monitorProbe(self):
        while True:
            self.halStatus.poll()
            toolIsAProbe = self.halStatus.tool_in_spindle in PROBE_TOOL_NUMBERS
            toolIsAProbe = toolIsAProbe or not self.halStatus.din[3]
            self.ProbeGuard_hal["new-probe-enable"] = self.ProbeGuard_hal["old-probe-enable"] and (toolIsAProbe or self.halStatus.task_mode != linuxcnc.MODE_AUTO)
            if toolIsAProbe:
                if self.halStatus.spindle_enabled:
                    self.halCommand.abort()
                    self.error_handler.write('Spindle halted - T99 selected or probe out of holder.')
                time.sleep(PROBE_SLEEP_TIME)
            else:
                time.sleep(NONPROBE_SLEEP_TIME)

DESCRIPTION_LONG = """Xoomspeedâ€™s ProbeGuard prevents the spindle 
    from turning on when T99 is selected in PathPilot, which helps protect a 
    wired probe and cable from damage. </font></p>
    <p><font face="Verdana" size="2">However, it doesn't protect against edge 
    cases where the probe is still in the spindle, but the tool has been changed 
    on the screen (in other words, you have an end mill loaded in PathPilot, but 
    the spindle hasn't been physically changed yet).</font></p>
    <p><font face="Verdana" size="2">I wanted to take that protection one step 
    further, so I added a limit switch to the probe cradle, connected to the USB 
    I/O module. </font></p>
    <p><font face="Verdana" size="2">When the probe is safely stored, the switch 
    is closed. This modified version of ProbeGuard checks for that closed 
    circuit, and if it is open, it refuses to start the spindle. </font></p>"""                