1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161
|
import sys
import traceback
# A python interface for LinuxCNC tool database usage
#Notes
# 1) host (LinuxCNC) pushes commands to this program
# 2) all writes to stdout go to host
# (caller: use stderr for debug prints)
#-----------------------------------------------------------
DB_VERSION = 'v2.1'
#-----------------------------------------------------------
# functions for import by user
# tooldb_callbacks
# tooldb_tools
# tooldb_loop
#-----------------------------------------------------------
def do_reply(msg):
sys.stdout.write("%s\n"%msg)
sys.stdout.flush()
def saveline(line):
global theline
theline = line
def currentline():
global theline
return theline
def nak_reply(msg):
theline = currentline()
if msg != "empty_line": sys.stderr.write(traceback.format_exc()+"\n")
sys.stdout.write("NAK %s <%s>\n"%(msg,theline))
sys.stdout.flush()
def tool_cmd(cmd,params):
# debug usage: return info for tool
# parms is toolno
if not len(params):
nak_reply("no toolno")
return
if len(params.split()) != 1:
nak_reply("too many parms")
return
try:
toolno = int(params)
except Exception as e:
nak_reply("non-integer toolno")
return
if toolno not in tools:
nak_reply("toolno out-of-range")
return
do_reply(get_tool(toolno))
def get_cmd(cmd,params):
for tno in tools:
try: msg = get_tool(tno)
except Exception as e:
nak_reply( "get_cmd():Exception:%s"%str(e))
return
try: do_reply(msg)
except:
if (tno==0):
if debug: sys.stderr.write("no tool in spindle\n")
pass
do_reply("FINI (get_cmd)")
def put_cmds(cmd,params):
# note: checks are mainly for commandline debugging,
# expect host to always provide a valid toolline
uparams = params.upper()
if len(uparams) == 0:
raise Exception("cmd=%s: requires tool entry line"%cmd)
try:
toolno = int(uparams[0:uparams.index(" ")].strip("T"))
toolline = uparams
except Exception as e:
sys.stderr.write("cmd=%s: %s:\n"%(cmd,e))
raise Exception("cmd=%s: failed to parse <%s>"%(cmd,params))
# require at least "Tvalue Pvalue"
try: toolline.index("T");toolline.index(" P")
except Exception as e:
sys.stderr.write("cmd=%s: %s:\n"%(cmd,e))
raise Exception("cmd=%s: failed to parse <%s>"%(cmd,params))
try:
if cmd == "p": put_tool( toolno,toolline)
elif cmd == "l": load_spindle( toolno,toolline)
elif cmd == "u": unload_spindle(toolno,toolline)
except Exception as e:
nak_reply( "cmd=%s: Exception:%s"%(cmd,str(e)))
return
do_reply("FINI (update recvd) %s"%params)
def unknown_cmd(cmd,params):
nak_reply("unknown cmd")
return
def do_cmd(line):
global debug
if debug: sys.stderr.write("!!line=<%s>\n"%line)
linelist = line.strip().split()
cmd = linelist[0]
params = ""
if len(linelist) > 1:
# params is everything after first " ":0
params = line.strip()[line.index(" "):].strip()
switcher = {
"g": get_cmd, # get (all tools)
"p": put_cmds, # put (update one tool offsets)
"u": put_cmds, # unload spindle
"l": put_cmds, # load spindle
"t": tool_cmd, # debug usage
}
thecmd = switcher.get(cmd) or unknown_cmd
thecmd(cmd,params)
def startup_ack():
global debug
debug = 0
do_reply("%s"%DB_VERSION);
if (len(sys.argv)>1 and sys.argv[1] == 'debug'): debug = 1
#-----------------------------------------------------------
# Begin functions that can be imported
def tooldb_callbacks(tool_getter,tool_putter,spindle_loader,spindle_unloader):
"""Specify callback functions"""
global get_tool, put_tool, load_spindle, unload_spindle
get_tool = tool_getter
put_tool = tool_putter
load_spindle = spindle_loader
unload_spindle = spindle_unloader
def tooldb_tools(tool_list):
"""Specify list = available toolnumers"""
global tools
tools = tool_list
def tooldb_loop():
"""Loop forever:
1) send startup acknowledgment
2) read line from stdino
3) parse line
execute command if valid
nak command if invalid
4) repeat
"""
startup_ack()
while True:
try:
line=sys.stdin.readline().strip()
saveline(line)
if (line == ""): nak_reply("empty_line")
else: do_cmd(line)
except BrokenPipeError: sys.stdout.close()
except Exception as e:
nak_reply("_exception=%s"%e)
|