80 lines
2.9 KiB
Python
80 lines
2.9 KiB
Python
#!/usr/bin/python
|
|
import struct
|
|
import sys
|
|
|
|
def parseToolAction():
|
|
global s3gFile
|
|
packetStr = s3gFile.read(3)
|
|
if len(packetStr) != 3:
|
|
raise "Incomplete s3g file during tool command parse"
|
|
(index,command,payload) = struct.unpack("<BBB",packetStr)
|
|
contents = s3gFile.read(payload)
|
|
if len(contents) != payload:
|
|
raise "Incomplete s3g file: tool packet truncated"
|
|
return (index,command,contents)
|
|
|
|
def printToolAction(tuple):
|
|
return "Command %i for tool %i (len %i)" % (tuple[1],tuple[0],len(tuple[2]))
|
|
|
|
# Command table entries consist of:
|
|
# * The key: the integer command code
|
|
# * A tuple:
|
|
# * idx 0: the python struct description of the rest of the data,
|
|
# of a function that unpacks the remaining data from the
|
|
# stream
|
|
# * idx 1: either a format string that will take the tuple of unpacked
|
|
# data, or a function that takes the tuple as input and returns
|
|
# a string
|
|
|
|
# REMINDER: all values are little-endian. Struct strings with multibyte
|
|
# types should begin with "<".
|
|
# For a refresher on Python struct syntax, see here:
|
|
# http://docs.python.org/library/struct.html
|
|
commandTable = {
|
|
129: ("<iiiI","Absolute move to (%i,%i,%i) at DDA %i"),
|
|
130: ("<iii","Machine position set as (%i,%i,%i)"),
|
|
131: ("<BIH","Home minimum on %X, feedrate %i, timeout %i s"),
|
|
132: ("<BIH","Home maximum on %X, feedrate %i, timeout %i s"),
|
|
133: ("<I","Delay of %i us"),
|
|
134: ("<B","Switch to tool %i"),
|
|
135: ("<BHH","Wait for tool %i (%i ms between polls, %i s timeout"),
|
|
136: (parseToolAction, printToolAction),
|
|
137: ("<B", "Enable/disable axes %X"),
|
|
138: ("<H", "User block on ID %i"),
|
|
139: ("<iiiiiI","Absolute move to (%i,%i,%i,%i,%i) at DDA %i"),
|
|
140: ("<iiiii","Machine position set as (%i,%i,%i,%i,%i)"),
|
|
141: ("<BHH","Wait for platform %i (%i ms between polls, %i s timeout)"),
|
|
142: ("<iiiiiIB","Move to (%i,%i,%i,%i,%i) in %i us (relative: %X)"),
|
|
143: ("<b","Store home position for axes %d"),
|
|
144: ("<b","Recall home position for axes %d"),
|
|
}
|
|
|
|
def parseNextCommand():
|
|
"""Parse and handle the next command. Returns
|
|
True for success, False on EOF, and raises an
|
|
exception on corrupt data."""
|
|
global s3gFile
|
|
commandStr = s3gFile.read(1)
|
|
if len(commandStr) == 0:
|
|
print "EOF"
|
|
return False
|
|
(command) = struct.unpack("B",commandStr)
|
|
(parse, disp) = commandTable[command[0]]
|
|
if type(parse) == type(""):
|
|
packetLen = struct.calcsize(parse)
|
|
packetData = s3gFile.read(packetLen)
|
|
if len(packetData) != packetLen:
|
|
raise "Packet incomplete"
|
|
parsed = struct.unpack(parse,packetData)
|
|
else:
|
|
parsed = parse()
|
|
if type(disp) == type(""):
|
|
print disp % parsed
|
|
else:
|
|
disp(parsed)
|
|
return True
|
|
|
|
s3gFile = open(sys.argv[1],'rb')
|
|
while parseNextCommand():
|
|
pass
|