linuxcnc/lib/python/tooldb.py
Dewey Garrett fb59d73627 tooldata_db.cc: support db_program args v2.1
Optional args (10 max) can be used to specify startup parameters
for the [EMCIO]DB_PROGRAM

DB_VERSION=v2.1
Interface is backwards compatible, but DB_VERSION is bumped
in case applications used undocumented argv[1]==DB_VERSION
that was originally passed to DB_PROGRAM
2022-10-16 18:03:11 -07:00

161 lines
4.7 KiB
Python

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)