Add a plugin hook for opening the serial port
This hook allows the plugin to create the serial port object (or pass to the next hook or the builtin serial port handler) which allows for serial communication filtering or a different communication transport. Use @foosel's code to use the same loop for hooks as well as the builtin.
This commit is contained in:
parent
c5484fe139
commit
e4d8d67f65
1 changed files with 67 additions and 38 deletions
|
|
@ -1179,50 +1179,79 @@ class MachineCom(object):
|
|||
else:
|
||||
return False
|
||||
|
||||
def _openSerial(self):
|
||||
if self._port == 'AUTO':
|
||||
self._changeState(self.STATE_DETECT_SERIAL)
|
||||
programmer = stk500v2.Stk500v2()
|
||||
self._log("Serial port list: %s" % (str(serialList())))
|
||||
for p in serialList():
|
||||
try:
|
||||
self._log("Connecting to: %s" % (p))
|
||||
programmer.connect(p)
|
||||
self._serial = programmer.leaveISP()
|
||||
break
|
||||
except ispBase.IspError as (e):
|
||||
self._log("Error while connecting to %s: %s" % (p, str(e)))
|
||||
pass
|
||||
except:
|
||||
self._log("Unexpected error while connecting to serial port: %s %s" % (p, get_exception_string()))
|
||||
programmer.close()
|
||||
if self._serial is None:
|
||||
self._log("Failed to autodetect serial port")
|
||||
self._errorValue = 'Failed to autodetect serial port.'
|
||||
self._changeState(self.STATE_ERROR)
|
||||
eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
|
||||
return False
|
||||
elif self._port == 'VIRTUAL':
|
||||
self._changeState(self.STATE_OPEN_SERIAL)
|
||||
self._serial = VirtualPrinter()
|
||||
else:
|
||||
self._changeState(self.STATE_OPEN_SERIAL)
|
||||
def _detectPort(self, close):
|
||||
programmer = stk500v2.Stk500v2()
|
||||
self._log("Serial port list: %s" % (str(serialList())))
|
||||
for p in serialList():
|
||||
serial_obj = None
|
||||
|
||||
try:
|
||||
self._log("Connecting to: %s" % self._port)
|
||||
if self._baudrate == 0:
|
||||
self._serial = serial.Serial(str(self._port), 115200, timeout=settings().getFloat(["serial", "timeout", "connection"]), writeTimeout=10000, parity=serial.PARITY_ODD)
|
||||
else:
|
||||
self._serial = serial.Serial(str(self._port), self._baudrate, timeout=settings().getFloat(["serial", "timeout", "connection"]), writeTimeout=10000, parity=serial.PARITY_ODD)
|
||||
self._serial.close()
|
||||
self._serial.parity = serial.PARITY_NONE
|
||||
self._serial.open()
|
||||
self._log("Connecting to: %s" % (p))
|
||||
programmer.connect(p)
|
||||
serial_obj = programmer.leaveISP()
|
||||
break
|
||||
except ispBase.IspError as (e):
|
||||
self._log("Error while connecting to %s: %s" % (p, str(e)))
|
||||
except:
|
||||
self._log("Unexpected error while connecting to serial port: %s %s" % (self._port, get_exception_string()))
|
||||
self._log("Unexpected error while connecting to serial port: %s %s" % (p, get_exception_string()))
|
||||
|
||||
if serial_obj is not None:
|
||||
if (close):
|
||||
serial_obj.close()
|
||||
return serial_obj
|
||||
|
||||
programmer.close()
|
||||
return None
|
||||
|
||||
def _openSerial(self):
|
||||
def default(_, port, baudrate, connection_timeout):
|
||||
if self._port is None or self._port == 'AUTO':
|
||||
# no known port, try auto detection
|
||||
self._changeState(self.STATE_DETECT_SERIAL)
|
||||
serial_obj = self._detectPort(False)
|
||||
if serial_obj is None:
|
||||
self._log("Failed to autodetect serial port")
|
||||
self._errorValue = 'Failed to autodetect serial port.'
|
||||
self._changeState(self.STATE_ERROR)
|
||||
eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
|
||||
return None
|
||||
|
||||
elif port == "VIRTUAL":
|
||||
# virtual printer, use that
|
||||
serial_obj = VirtualPrinter()
|
||||
|
||||
else:
|
||||
# connect to regular serial port
|
||||
self._log("Connecting to: %s" % self._port)
|
||||
if baudrate == 0:
|
||||
serial_obj = serial.Serial(str(port), 115200, timeout=connection_timeout, writeTimeout=10000, parity=serial.PARITY_ODD)
|
||||
else:
|
||||
serial_obj = serial.Serial(str(port), baudrate, timeout=connection_timeout, writeTimeout=10000, parity=serial.PARITY_ODD)
|
||||
serial_obj.close()
|
||||
serial_obj.parity = serial.PARITY_NONE
|
||||
serial_obj.open()
|
||||
|
||||
return serial_obj
|
||||
|
||||
serial_factories = self._serial_hooks.items() + [("default", default)]
|
||||
for name, factory in serial_factories:
|
||||
try:
|
||||
serial_obj = factory(self, self._port, self._baudrate, settings().getFloat(["serial", "timeout", "connection"]))
|
||||
except Exception:
|
||||
self._log("Unexpected error while connecting to serial port: %s %s (hook %s)" % (self._port, get_exception_string(), name))
|
||||
self._errorValue = "Failed to open serial port, permissions correct?"
|
||||
self._changeState(self.STATE_ERROR)
|
||||
eventManager().fire(Events.ERROR, {"error": self.getErrorString()})
|
||||
return False
|
||||
return True
|
||||
|
||||
if serial_obj is not None:
|
||||
# first hook to succeed wins, but any can pass on to the next
|
||||
self._changeState(self.STATE_OPEN_SERIAL)
|
||||
self._serial = serial_obj
|
||||
self._clear_to_send.clear()
|
||||
return True
|
||||
|
||||
return False
|
||||
|
||||
def _handleErrors(self, line):
|
||||
# No matter the state, if we see an error, goto the error state and store the error for reference.
|
||||
|
|
|
|||
Loading…
Reference in a new issue