gcode: Use the same underlying error object for homing and gcode errors

Introduce a homing.CommandError and use that as the basis for both
gcode and EndstopError exceptions.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2019-06-03 12:48:35 -04:00 committed by KevinOConnor
parent 97adca18c4
commit 945a84c0ea
2 changed files with 26 additions and 24 deletions

View File

@ -6,12 +6,9 @@
import os, re, logging, collections, shlex import os, re, logging, collections, shlex
import homing, kinematics.extruder import homing, kinematics.extruder
class error(Exception):
pass
# Parse and handle G-Code commands # Parse and handle G-Code commands
class GCodeParser: class GCodeParser:
error = error error = homing.CommandError
RETRY_TIME = 0.100 RETRY_TIME = 0.100
def __init__(self, printer, fd): def __init__(self, printer, fd):
self.printer = printer self.printer = printer
@ -220,7 +217,7 @@ class GCodeParser:
handler = self.gcode_handlers.get(cmd, self.cmd_default) handler = self.gcode_handlers.get(cmd, self.cmd_default)
try: try:
handler(params) handler(params)
except error as e: except self.error as e:
self.respond_error(str(e)) self.respond_error(str(e))
self.reset_last_position() self.reset_last_position()
if not need_ack: if not need_ack:
@ -290,7 +287,7 @@ class GCodeParser:
self.is_processing_data = True self.is_processing_data = True
try: try:
self._process_commands(commands, need_ack=False) self._process_commands(commands, need_ack=False)
except error as e: except self.error as e:
if self.pending_commands: if self.pending_commands:
self._process_pending() self._process_pending()
self.is_processing_data = False self.is_processing_data = False
@ -355,25 +352,25 @@ class GCodeParser:
minval=None, maxval=None, above=None, below=None): minval=None, maxval=None, above=None, below=None):
if name not in params: if name not in params:
if default is self.sentinel: if default is self.sentinel:
raise error("Error on '%s': missing %s" % ( raise self.error("Error on '%s': missing %s" % (
params['#original'], name)) params['#original'], name))
return default return default
try: try:
value = parser(params[name]) value = parser(params[name])
except: except:
raise error("Error on '%s': unable to parse %s" % ( raise self.error("Error on '%s': unable to parse %s" % (
params['#original'], params[name])) params['#original'], params[name]))
if minval is not None and value < minval: if minval is not None and value < minval:
raise error("Error on '%s': %s must have minimum of %s" % ( raise self.error("Error on '%s': %s must have minimum of %s" % (
params['#original'], name, minval)) params['#original'], name, minval))
if maxval is not None and value > maxval: if maxval is not None and value > maxval:
raise error("Error on '%s': %s must have maximum of %s" % ( raise self.error("Error on '%s': %s must have maximum of %s" % (
params['#original'], name, maxval)) params['#original'], name, maxval))
if above is not None and value <= above: if above is not None and value <= above:
raise error("Error on '%s': %s must be above %s" % ( raise self.error("Error on '%s': %s must be above %s" % (
params['#original'], name, above)) params['#original'], name, above))
if below is not None and value >= below: if below is not None and value >= below:
raise error("Error on '%s': %s must be below %s" % ( raise self.error("Error on '%s': %s must be below %s" % (
params['#original'], name, below)) params['#original'], name, below))
return value return value
def get_int(self, name, params, default=sentinel, minval=None, maxval=None): def get_int(self, name, params, default=sentinel, minval=None, maxval=None):
@ -400,7 +397,7 @@ class GCodeParser:
eparams.update({k: params[k] for k in params if k.startswith('#')}) eparams.update({k: params[k] for k in params if k.startswith('#')})
return eparams return eparams
except ValueError as e: except ValueError as e:
raise error("Malformed command '%s'" % (params['#original'],)) raise self.error("Malformed command '%s'" % (params['#original'],))
# Temperature wrappers # Temperature wrappers
def _get_temp(self, eventtime): def _get_temp(self, eventtime):
# Tn:XXX /YYY B:XXX /YYY # Tn:XXX /YYY B:XXX /YYY
@ -440,7 +437,7 @@ class GCodeParser:
try: try:
heater.set_temp(print_time, temp) heater.set_temp(print_time, temp)
except heater.error as e: except heater.error as e:
raise error(str(e)) raise self.error(str(e))
if wait and temp: if wait and temp:
self.bg_temp(heater) self.bg_temp(heater)
def _set_fan_speed(self, speed): def _set_fan_speed(self, speed):
@ -481,7 +478,7 @@ class GCodeParser:
try: try:
self.toolhead.set_extruder(e) self.toolhead.set_extruder(e)
except homing.EndstopError as e: except homing.EndstopError as e:
raise error(str(e)) raise self.error(str(e))
self.extruder = e self.extruder = e
self.reset_last_position() self.reset_last_position()
self.extrude_factor = 1. self.extrude_factor = 1.
@ -494,7 +491,8 @@ class GCodeParser:
else: else:
key_param = self.get_str(key, params) key_param = self.get_str(key, params)
if key_param not in values: if key_param not in values:
raise error("The value '%s' is not valid for %s" % (key_param, key)) raise self.error("The value '%s' is not valid for %s" % (
key_param, key))
values[key_param](params) values[key_param](params)
all_handlers = [ all_handlers = [
'G1', 'G4', 'G28', 'M18', 'M400', 'G1', 'G4', 'G28', 'M18', 'M400',
@ -529,15 +527,16 @@ class GCodeParser:
if 'F' in params: if 'F' in params:
gcode_speed = float(params['F']) gcode_speed = float(params['F'])
if gcode_speed <= 0.: if gcode_speed <= 0.:
raise error("Invalid speed in '%s'" % ( raise self.error("Invalid speed in '%s'" % (
params['#original'],)) params['#original'],))
self.speed = gcode_speed * self.speed_factor self.speed = gcode_speed * self.speed_factor
except ValueError as e: except ValueError as e:
raise error("Unable to parse move '%s'" % (params['#original'],)) raise self.error("Unable to parse move '%s'" % (
params['#original'],))
try: try:
self.move_with_transform(self.last_position, self.speed) self.move_with_transform(self.last_position, self.speed)
except homing.EndstopError as e: except homing.EndstopError as e:
raise error(str(e)) raise self.error(str(e))
def cmd_G4(self, params): def cmd_G4(self, params):
# Dwell # Dwell
if 'S' in params: if 'S' in params:
@ -559,7 +558,7 @@ class GCodeParser:
try: try:
homing_state.home_axes(axes) homing_state.home_axes(axes)
except homing.EndstopError as e: except homing.EndstopError as e:
raise error(str(e)) raise self.error(str(e))
for axis in homing_state.get_axes(): for axis in homing_state.get_axes():
self.base_position[axis] = self.homing_position[axis] self.base_position[axis] = self.homing_position[axis]
self.reset_last_position() self.reset_last_position()
@ -636,7 +635,7 @@ class GCodeParser:
try: try:
self.move_with_transform(self.last_position, speed) self.move_with_transform(self.last_position, speed)
except homing.EndstopError as e: except homing.EndstopError as e:
raise error(str(e)) raise self.error(str(e))
def cmd_M206(self, params): def cmd_M206(self, params):
# Offset axes # Offset axes
offsets = { self.axis2pos[a]: -self.get_float(a, params) offsets = { self.axis2pos[a]: -self.get_float(a, params)
@ -662,7 +661,7 @@ class GCodeParser:
state_name = self.get_str('NAME', params, 'default') state_name = self.get_str('NAME', params, 'default')
state = self.saved_states.get(state_name) state = self.saved_states.get(state_name)
if state is None: if state is None:
raise error("Unknown g-code state: %s" % (state_name,)) raise self.error("Unknown g-code state: %s" % (state_name,))
# Restore state # Restore state
self.absolute_coord = state['absolute_coord'] self.absolute_coord = state['absolute_coord']
self.absolute_extrude = state['absolute_extrude'] self.absolute_extrude = state['absolute_extrude']
@ -681,7 +680,7 @@ class GCodeParser:
try: try:
self.move_with_transform(self.last_position, speed) self.move_with_transform(self.last_position, speed)
except homing.EndstopError as e: except homing.EndstopError as e:
raise error(str(e)) raise self.error(str(e))
# G-Code temperature and fan commands # G-Code temperature and fan commands
cmd_M105_when_not_ready = True cmd_M105_when_not_ready = True
def cmd_M105(self, params): def cmd_M105(self, params):

View File

@ -146,7 +146,10 @@ class Homing:
self.toolhead.motor_off() self.toolhead.motor_off()
raise raise
class EndstopError(Exception): class CommandError(Exception):
pass
class EndstopError(CommandError):
pass pass
def EndstopMoveError(pos, msg="Move out of range"): def EndstopMoveError(pos, msg="Move out of range"):