motion_report: Simplify shutdown_clock tracking

Determine which mcu raised the shutdown from the shutdown details
report.  Also, pass shutdown_clock via that details report.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor
2025-10-08 14:40:23 -04:00
parent 1bba59b7a0
commit 0d0d3917c9
2 changed files with 25 additions and 28 deletions

View File

@@ -146,7 +146,7 @@ class PrinterMotionReport:
def __init__(self, config):
self.printer = config.get_printer()
self.steppers = {}
self.trapqs = {}
self.dtrapqs = {}
# get_status information
self.next_status_time = 0.
gcode = self.printer.lookup_object('gcode')
@@ -166,7 +166,7 @@ class PrinterMotionReport:
# Lookup toolhead trapq
toolhead = self.printer.lookup_object("toolhead")
trapq = toolhead.get_trapq()
self.trapqs['toolhead'] = DumpTrapQ(self.printer, 'toolhead', trapq)
self.dtrapqs['toolhead'] = DumpTrapQ(self.printer, 'toolhead', trapq)
# Lookup extruder trapqs
for i in range(99):
ename = "extruder%d" % (i,)
@@ -176,34 +176,35 @@ class PrinterMotionReport:
if extruder is None:
break
etrapq = extruder.get_trapq()
self.trapqs[ename] = DumpTrapQ(self.printer, ename, etrapq)
self.dtrapqs[ename] = DumpTrapQ(self.printer, ename, etrapq)
# Populate 'trapq' and 'steppers' in get_status result
self.last_status['steppers'] = list(sorted(self.steppers.keys()))
self.last_status['trapq'] = list(sorted(self.trapqs.keys()))
self.last_status['trapq'] = list(sorted(self.dtrapqs.keys()))
# Shutdown handling
def _handle_analyze_shutdown(self, msg, details):
if msg != "MCU shutdown":
return
mcu = self.printer.lookup_object(details.get("mcu"), None)
if mcu is None or details.get("shutdown_clock") is None:
return
shutdown_clock = details["shutdown_clock"]
shutdown_time = mcu.clock_to_print_time(shutdown_clock)
clock_100ms = mcu.seconds_to_clock(0.100)
start_clock = max(0, shutdown_clock - clock_100ms)
end_clock = shutdown_clock + clock_100ms
# Log stepper queue_steps on mcu that started shutdown (if any)
shutdown_time = NEVER_TIME
for dstepper in self.steppers.values():
mcu = dstepper.mcu_stepper.get_mcu()
sc = mcu.get_shutdown_clock()
if not sc:
if dstepper.mcu_stepper.get_mcu() is not mcu:
continue
shutdown_time = min(shutdown_time, mcu.clock_to_print_time(sc))
clock_100ms = mcu.seconds_to_clock(0.100)
start_clock = max(0, sc - clock_100ms)
end_clock = sc + clock_100ms
data, cdata = dstepper.get_step_queue(start_clock, end_clock)
dstepper.log_steps(data)
if shutdown_time >= NEVER_TIME:
return
# Log trapqs around time of shutdown
for dtrapq in self.trapqs.values():
for dtrapq in self.dtrapqs.values():
data, cdata = dtrapq.extract_trapq(shutdown_time - .100,
shutdown_time + .100)
dtrapq.log_trapq(data)
# Log estimated toolhead position at time of shutdown
dtrapq = self.trapqs.get('toolhead')
dtrapq = self.dtrapqs.get('toolhead')
if dtrapq is None:
return
pos, velocity = dtrapq.get_trapq_position(shutdown_time)
@@ -212,7 +213,7 @@ class PrinterMotionReport:
, shutdown_time, pos)
# Status reporting
def get_status(self, eventtime):
if eventtime < self.next_status_time or not self.trapqs:
if eventtime < self.next_status_time or not self.dtrapqs:
return self.last_status
self.next_status_time = eventtime + STATUS_REFRESH_TIME
xyzpos = (0., 0., 0.)
@@ -221,13 +222,13 @@ class PrinterMotionReport:
# Calculate current requested toolhead position
mcu = self.printer.lookup_object('mcu')
print_time = mcu.estimated_print_time(eventtime)
pos, velocity = self.trapqs['toolhead'].get_trapq_position(print_time)
pos, velocity = self.dtrapqs['toolhead'].get_trapq_position(print_time)
if pos is not None:
xyzpos = pos[:3]
xyzvelocity = velocity
# Calculate requested position of currently active extruder
toolhead = self.printer.lookup_object('toolhead')
ehandler = self.trapqs.get(toolhead.get_extruder().get_name())
ehandler = self.dtrapqs.get(toolhead.get_extruder().get_name())
if ehandler is not None:
pos, velocity = ehandler.get_trapq_position(print_time)
if pos is not None:

View File

@@ -697,7 +697,6 @@ class MCUConnectHelper:
# Shutdown tracking
self._emergency_stop_cmd = None
self._is_shutdown = self._is_timeout = False
self._shutdown_clock = 0
self._shutdown_msg = ""
# Register handlers
printer.register_event_handler("klippy:mcu_identify",
@@ -720,14 +719,15 @@ class MCUConnectHelper:
if self._is_shutdown:
return
self._is_shutdown = True
clock = params.get("clock")
if clock is not None:
self._shutdown_clock = self._mcu.clock32_to_clock64(clock)
self._shutdown_msg = msg = params['static_string_id']
shutdown_clock = params.get("clock")
if shutdown_clock is not None:
shutdown_clock = self._mcu.clock32_to_clock64(shutdown_clock)
event_type = params['#name']
self._printer.invoke_async_shutdown(
"MCU shutdown", {"reason": msg, "mcu": self._name,
"event_type": event_type})
"event_type": event_type,
"shutdown_clock": shutdown_clock})
def _handle_starting(self, params):
if not self._is_shutdown:
self._printer.invoke_async_shutdown("MCU '%s' spontaneous restart"
@@ -810,8 +810,6 @@ class MCUConnectHelper:
self._name,))
def is_shutdown(self):
return self._is_shutdown
def get_shutdown_clock(self):
return self._shutdown_clock
def get_shutdown_msg(self):
return self._shutdown_msg
@@ -1112,8 +1110,6 @@ class MCU:
# Low-level connection wrappers
def is_shutdown(self):
return self._conn_helper.is_shutdown()
def get_shutdown_clock(self):
return self._conn_helper.get_shutdown_clock()
# Statistics wrappers
def get_status(self, eventtime=None):
return self._stats_helper.get_status(eventtime)