File: tooldb.py

package info (click to toggle)
linuxcnc 2.9.0~pre1%2Bgit20230208.f1270d6ed7-1%2Bdeb12u1
  • links: PTS, VCS
  • area: main
  • in suites: bookworm
  • size: 274,984 kB
  • sloc: python: 142,166; ansic: 103,241; cpp: 99,140; tcl: 16,045; xml: 10,608; sh: 10,124; makefile: 1,229; javascript: 226; sql: 72; asm: 15
file content (161 lines) | stat: -rw-r--r-- 4,797 bytes parent folder | download | duplicates (2)
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)