mcu: Generate a dummy response to query commands when in debugging mode

Previously a querycmd.send() request would silently hang if the code
is run in "file output" mode (that is, it is not communicating with a
real micro-controller).  This behavior makes it hard to implement
regression tests and is generally confusing.

Change the code to respond with a dummy response (typically all zeros
and empty strings) instead.

Signed-off-by: Kevin O'Connor <kevin@koconnor.net>
This commit is contained in:
Kevin O'Connor 2026-01-19 21:25:19 -05:00
parent 1cde5e2018
commit 57b94520de
3 changed files with 42 additions and 1 deletions

View file

@ -175,6 +175,8 @@ class ADS1220:
# read startup register state and validate
val = self.read_reg(0x0, 4)
if val != RESET_STATE:
if self.mcu.is_fileoutput():
return
raise self.printer.command_error(
"Invalid ads1220 reset state (got %s vs %s).\n"
"This is generally indicative of connection problems\n"
@ -209,6 +211,8 @@ class ADS1220:
self.spi.spi_send(write_command)
stored_val = self.read_reg(reg, len(register_bytes))
if bytearray(register_bytes) != stored_val:
if self.mcu.is_fileoutput():
return
raise self.printer.command_error(
"Failed to set ADS1220 register [0x%x] to %s: got %s. "
"This may be a connection problem (e.g. faulty wiring)" % (

View file

@ -22,6 +22,20 @@ MAX_NOMINAL_DURATION = 3.0
# Command transmit helper classes
######################################################################
# Generate a dummy response to query commands when in debugging mode
class DummyResponse:
def __init__(self, serial, name, oid=None):
params = {}
if oid is not None:
params['oid'] = oid
msgparser = serial.get_msgparser()
resp = msgparser.create_dummy_response(name, params)
resp['#sent_time'] = 0.
resp['#receive_time'] = 0.
self._response = resp
def get_response(self, cmds, cmd_queue, minclock=0, reqclock=0, retry=True):
return dict(self._response)
# Class to retry sending of a query command until a given response is received
class RetryAsyncCommand:
TIMEOUT_TIME = 5.0
@ -69,7 +83,9 @@ class CommandQueryWrapper:
self._oid = oid
self._error = conn_helper.get_mcu().get_printer().command_error
self._xmit_helper = serialhdl.SerialRetryCommand
if is_async:
if conn_helper.get_mcu().is_fileoutput():
self._xmit_helper = DummyResponse
elif is_async:
self._xmit_helper = RetryAsyncCommand
if cmd_queue is None:
cmd_queue = serial.get_default_command_queue()

View file

@ -353,6 +353,27 @@ class MessageParser:
#logging.exception("Unable to encode")
self._error("Unable to encode: %s", msgname)
return cmd
def create_dummy_response(self, msgname, params={}):
mp = self.messages_by_name.get(msgname)
if mp is None:
self._error("Unknown response: %s", msgname)
argparts = dict(params)
for name, t in mp.name_to_type.items():
if name not in argparts:
tval = 0
if t.is_dynamic_string:
tval = ()
argparts[name] = tval
try:
msg = mp.encode_by_name(**argparts)
except error as e:
raise
except:
#logging.exception("Unable to encode")
self._error("Unable to encode: %s", msgname)
res, pos = mp.parse(msg, 0)
res['#name'] = msgname
return res
def fill_enumerations(self, enumerations):
for add_name, add_enums in enumerations.items():
enums = self.enumerations.setdefault(add_name, {})