mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 23:46:22 -06:00
Merge branch 'master' of github.com:Ultimaker/PluggableCura
Conflicts: plugins/USBPrinting/PrinterConnection.py plugins/USBPrinting/USBPrinterManager.py plugins/Views/LayerView/LayerView.py
This commit is contained in:
commit
b28ca0881a
2 changed files with 116 additions and 115 deletions
|
@ -1,4 +1,3 @@
|
||||||
from UM.Logger import Logger
|
|
||||||
from .avr_isp import stk500v2, ispBase, intelHex
|
from .avr_isp import stk500v2, ispBase, intelHex
|
||||||
import serial
|
import serial
|
||||||
import threading
|
import threading
|
||||||
|
@ -10,7 +9,7 @@ import functools
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Signal import Signal, SignalEmitter
|
from UM.Signal import Signal, SignalEmitter
|
||||||
from UM.Resources import Resources
|
from UM.Resources import Resources
|
||||||
|
from UM.Logger import Logger
|
||||||
|
|
||||||
class PrinterConnection(SignalEmitter):
|
class PrinterConnection(SignalEmitter):
|
||||||
def __init__(self, serial_port):
|
def __init__(self, serial_port):
|
||||||
|
@ -90,24 +89,26 @@ class PrinterConnection(SignalEmitter):
|
||||||
self._extruder_temperatures = [0] * self._extruder_count
|
self._extruder_temperatures = [0] * self._extruder_count
|
||||||
self._target_extruder_temperatures = [0] * self._extruder_count
|
self._target_extruder_temperatures = [0] * self._extruder_count
|
||||||
|
|
||||||
|
## Is the printer actively printing
|
||||||
#TODO: Needs more logic
|
|
||||||
def isPrinting(self):
|
def isPrinting(self):
|
||||||
if not self._is_connected or self._serial is None:
|
if not self._is_connected or self._serial is None:
|
||||||
return False
|
return False
|
||||||
return self._is_printing
|
return self._is_printing
|
||||||
|
|
||||||
## Provide a list of G-Codes that need to be printed
|
## Start a print based on a g-code.
|
||||||
|
# \param gcode_list List with gcode (strings).
|
||||||
def printGCode(self, gcode_list):
|
def printGCode(self, gcode_list):
|
||||||
if self.isPrinting() or not self._is_connected:
|
if self.isPrinting() or not self._is_connected:
|
||||||
return
|
return
|
||||||
self._gcode = gcode_list
|
self._gcode = gcode_list
|
||||||
|
|
||||||
#Reset line number. If this is not done, first line is sometimes ignored
|
#Reset line number. If this is not done, first line is sometimes ignored
|
||||||
self._gcode.insert(0, "M110")
|
self._gcode.insert(0, "M110")
|
||||||
self._gcode_position = 0
|
self._gcode_position = 0
|
||||||
self._print_start_time_100 = None
|
self._print_start_time_100 = None
|
||||||
self._is_printing = True
|
self._is_printing = True
|
||||||
self._print_start_time = time.time()
|
self._print_start_time = time.time()
|
||||||
|
|
||||||
for i in range(0, 4): #Push first 4 entries before accepting other inputs
|
for i in range(0, 4): #Push first 4 entries before accepting other inputs
|
||||||
self._sendNextGcodeLine()
|
self._sendNextGcodeLine()
|
||||||
|
|
||||||
|
@ -121,21 +122,28 @@ class PrinterConnection(SignalEmitter):
|
||||||
if not self._updating_firmware and not self._connect_thread.isAlive():
|
if not self._updating_firmware and not self._connect_thread.isAlive():
|
||||||
self._connect_thread.start()
|
self._connect_thread.start()
|
||||||
|
|
||||||
|
## Private fuction (threaded) that actually uploads the firmware.
|
||||||
def _updateFirmware(self):
|
def _updateFirmware(self):
|
||||||
if self._is_connecting or self._is_connected:
|
if self._is_connecting or self._is_connected:
|
||||||
self.close()
|
self.close()
|
||||||
hex_file = intelHex.readHex(self._firmware_file_name)
|
hex_file = intelHex.readHex(self._firmware_file_name)
|
||||||
|
|
||||||
if len(hex_file) == 0:
|
if len(hex_file) == 0:
|
||||||
Logger.log('e', "Unable to read provided hex file. Could not update firmware")
|
Logger.log('e', "Unable to read provided hex file. Could not update firmware")
|
||||||
return
|
return
|
||||||
|
|
||||||
programmer = stk500v2.Stk500v2()
|
programmer = stk500v2.Stk500v2()
|
||||||
programmer.progressCallback = self.setProgress
|
programmer.progressCallback = self.setProgress
|
||||||
programmer.connect(self._serial_port)
|
programmer.connect(self._serial_port)
|
||||||
time.sleep(1) #Give programmer some time to connect
|
|
||||||
|
time.sleep(1) # Give programmer some time to connect. Might need more in some cases, but this worked in all tested cases.
|
||||||
|
|
||||||
if not programmer.isConnected():
|
if not programmer.isConnected():
|
||||||
Logger.log('e', "Unable to connect with serial. Could not update firmware")
|
Logger.log('e', "Unable to connect with serial. Could not update firmware")
|
||||||
return
|
return
|
||||||
|
|
||||||
self._updating_firmware = True
|
self._updating_firmware = True
|
||||||
|
|
||||||
try:
|
try:
|
||||||
programmer.programChip(hex_file)
|
programmer.programChip(hex_file)
|
||||||
self._updating_firmware = False
|
self._updating_firmware = False
|
||||||
|
@ -144,8 +152,9 @@ class PrinterConnection(SignalEmitter):
|
||||||
self._updating_firmware = False
|
self._updating_firmware = False
|
||||||
return
|
return
|
||||||
programmer.close()
|
programmer.close()
|
||||||
return
|
|
||||||
|
|
||||||
|
## Upload new firmware to machine
|
||||||
|
# \param filename full path of firmware file to be uploaded
|
||||||
def updateFirmware(self, file_name):
|
def updateFirmware(self, file_name):
|
||||||
self._firmware_file_name = file_name
|
self._firmware_file_name = file_name
|
||||||
self._update_firmware_thread.start()
|
self._update_firmware_thread.start()
|
||||||
|
@ -159,7 +168,7 @@ class PrinterConnection(SignalEmitter):
|
||||||
self._serial = programmer.leaveISP()
|
self._serial = programmer.leaveISP()
|
||||||
except ispBase.IspError as e:
|
except ispBase.IspError as e:
|
||||||
Logger.log('i', "Could not establish connection on %s: %s. Device is not arduino based." %(self._serial_port,str(e)))
|
Logger.log('i', "Could not establish connection on %s: %s. Device is not arduino based." %(self._serial_port,str(e)))
|
||||||
except:
|
except Exception as e:
|
||||||
Logger.log('i', "Could not establish connection on %s, unknown reasons. Device is not arduino based." % self._serial_port)
|
Logger.log('i', "Could not establish connection on %s, unknown reasons. Device is not arduino based." % self._serial_port)
|
||||||
|
|
||||||
# If the programmer connected, we know its an atmega based version. Not all that usefull, but it does give some debugging information.
|
# If the programmer connected, we know its an atmega based version. Not all that usefull, but it does give some debugging information.
|
||||||
|
@ -182,8 +191,9 @@ class PrinterConnection(SignalEmitter):
|
||||||
while timeout_time > time.time():
|
while timeout_time > time.time():
|
||||||
line = self._readline()
|
line = self._readline()
|
||||||
if line is None:
|
if line is None:
|
||||||
self.setIsConnected(False) # something went wrong with reading, could be that close was called.
|
self.setIsConnected(False) # Something went wrong with reading, could be that close was called.
|
||||||
return
|
return
|
||||||
|
|
||||||
if b"T:" in line:
|
if b"T:" in line:
|
||||||
self._serial.timeout = 0.5
|
self._serial.timeout = 0.5
|
||||||
self._serial.write(b"\n")
|
self._serial.write(b"\n")
|
||||||
|
@ -192,9 +202,9 @@ class PrinterConnection(SignalEmitter):
|
||||||
if sucesfull_responses >= self._required_responses_auto_baud:
|
if sucesfull_responses >= self._required_responses_auto_baud:
|
||||||
self._serial.timeout = 2 #Reset serial timeout
|
self._serial.timeout = 2 #Reset serial timeout
|
||||||
self.setIsConnected(True)
|
self.setIsConnected(True)
|
||||||
Logger.log('i', "Established connection on port %s" % self._serial_port)
|
Logger.log('i', "Established printer connection on port %s" % self._serial_port)
|
||||||
return
|
return
|
||||||
self.close()
|
self.close() # Unable to connect, wrap up.
|
||||||
self.setIsConnected(False)
|
self.setIsConnected(False)
|
||||||
|
|
||||||
## Set the baud rate of the serial. This can cause exceptions, but we simply want to ignore those.
|
## Set the baud rate of the serial. This can cause exceptions, but we simply want to ignore those.
|
||||||
|
@ -290,21 +300,29 @@ class PrinterConnection(SignalEmitter):
|
||||||
elif self.isConnected():
|
elif self.isConnected():
|
||||||
self._sendCommand(cmd)
|
self._sendCommand(cmd)
|
||||||
|
|
||||||
|
## Set the error state with a message.
|
||||||
|
# \param error String with the error message.
|
||||||
def _setErrorState(self, error):
|
def _setErrorState(self, error):
|
||||||
self._error_state = error
|
self._error_state = error
|
||||||
self.onError.emit(error)
|
self.onError.emit(error)
|
||||||
|
|
||||||
onError = Signal()
|
onError = Signal()
|
||||||
|
|
||||||
|
## Private function to set the temperature of an extruder
|
||||||
|
# \param index index of the extruder
|
||||||
|
# \param temperature recieved temperature
|
||||||
def _setExtruderTemperature(self, index, temperature):
|
def _setExtruderTemperature(self, index, temperature):
|
||||||
try:
|
try:
|
||||||
self._extruder_temperatures[index] = temperature
|
self._extruder_temperatures[index] = temperature
|
||||||
self.onExtruderTemperatureChange.emit(self._serial_port, index, temperature)
|
self.onExtruderTemperatureChange.emit(self._serial_port, index, temperature)
|
||||||
except:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
onExtruderTemperatureChange = Signal()
|
onExtruderTemperatureChange = Signal()
|
||||||
|
|
||||||
|
## Private function to set the temperature of the bed.
|
||||||
|
# As all printers (as of time of writing) only support a single heated bed,
|
||||||
|
# these are not indexed as with extruders.
|
||||||
def _setBedTemperature(self, temperature):
|
def _setBedTemperature(self, temperature):
|
||||||
self._bed_temperature = temperature
|
self._bed_temperature = temperature
|
||||||
self.onBedTemperatureChange.emit(self._serial_port,temperature)
|
self.onBedTemperatureChange.emit(self._serial_port,temperature)
|
||||||
|
@ -314,12 +332,15 @@ class PrinterConnection(SignalEmitter):
|
||||||
|
|
||||||
## Listen thread function.
|
## Listen thread function.
|
||||||
def _listen(self):
|
def _listen(self):
|
||||||
|
Logger.log('i', "Printer connection listen thread started for %s" % self._serial_port)
|
||||||
temperature_request_timeout = time.time()
|
temperature_request_timeout = time.time()
|
||||||
ok_timeout = time.time()
|
ok_timeout = time.time()
|
||||||
while self._is_connected:
|
while self._is_connected:
|
||||||
line = self._readline()
|
line = self._readline()
|
||||||
|
|
||||||
if line is None:
|
if line is None:
|
||||||
break # None is only returned when something went wrong. Stop listening
|
break # None is only returned when something went wrong. Stop listening
|
||||||
|
|
||||||
if line.startswith(b'Error:'):
|
if line.startswith(b'Error:'):
|
||||||
# Oh YEAH, consistency.
|
# Oh YEAH, consistency.
|
||||||
# Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
|
# Marlin reports an MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
|
||||||
|
@ -327,23 +348,20 @@ class PrinterConnection(SignalEmitter):
|
||||||
# So we can have an extra newline in the most common case. Awesome work people.
|
# So we can have an extra newline in the most common case. Awesome work people.
|
||||||
if re.match(b'Error:[0-9]\n', line):
|
if re.match(b'Error:[0-9]\n', line):
|
||||||
line = line.rstrip() + self._readline()
|
line = line.rstrip() + self._readline()
|
||||||
|
|
||||||
# Skip the communication errors, as those get corrected.
|
# Skip the communication errors, as those get corrected.
|
||||||
if b'Extruder switched off' in line or b'Temperature heated bed switched off' in line or b'Something is wrong, please turn off the printer.' in line:
|
if b'Extruder switched off' in line or b'Temperature heated bed switched off' in line or b'Something is wrong, please turn off the printer.' in line:
|
||||||
if not self.hasError():
|
if not self.hasError():
|
||||||
self._setErrorState(line[6:])
|
self._setErrorState(line[6:])
|
||||||
#self._error_state = line[6:]
|
|
||||||
elif b' T:' in line or line.startswith(b'T:'): #Temperature message
|
elif b' T:' in line or line.startswith(b'T:'): #Temperature message
|
||||||
try:
|
try:
|
||||||
self._setExtruderTemperature(self._temperature_requested_extruder_index,float(re.search(b"T: *([0-9\.]*)", line).group(1)))
|
self._setExtruderTemperature(self._temperature_requested_extruder_index,float(re.search(b"T: *([0-9\.]*)", line).group(1)))
|
||||||
#self._extruder_temperatures[self._temperature_requested_extruder_index] = float(re.search(b"T: *([0-9\.]*)", line).group(1))
|
|
||||||
except:
|
except:
|
||||||
pass
|
pass
|
||||||
if b'B:' in line: # Check if it's a bed temperature
|
if b'B:' in line: # Check if it's a bed temperature
|
||||||
try:
|
try:
|
||||||
self._setBedTemperature(float(re.search(b"B: *([0-9\.]*)", line).group(1)))
|
self._setBedTemperature(float(re.search(b"B: *([0-9\.]*)", line).group(1)))
|
||||||
#print("BED TEMPERATURE" ,float(re.search(b"B: *([0-9\.]*)", line).group(1)))
|
except Exception as e:
|
||||||
|
|
||||||
except:
|
|
||||||
pass
|
pass
|
||||||
#TODO: temperature changed callback
|
#TODO: temperature changed callback
|
||||||
|
|
||||||
|
@ -355,15 +373,17 @@ class PrinterConnection(SignalEmitter):
|
||||||
else:
|
else:
|
||||||
self.sendCommand("M105")
|
self.sendCommand("M105")
|
||||||
temperature_request_timeout = time.time() + 5
|
temperature_request_timeout = time.time() + 5
|
||||||
|
|
||||||
if line == b'' and time.time() > ok_timeout:
|
if line == b'' and time.time() > ok_timeout:
|
||||||
line = b'ok' # Force a timeout (basicly, send next command)
|
line = b'ok' # Force a timeout (basicly, send next command)
|
||||||
|
|
||||||
if b'ok' in line:
|
if b'ok' in line:
|
||||||
ok_timeout = time.time() + 5
|
ok_timeout = time.time() + 5
|
||||||
if not self._command_queue.empty():
|
if not self._command_queue.empty():
|
||||||
self._sendCommand(self._command_queue.get())
|
self._sendCommand(self._command_queue.get())
|
||||||
else:
|
else:
|
||||||
self._sendNextGcodeLine()
|
self._sendNextGcodeLine()
|
||||||
elif b"resend" in line.lower() or b"rs" in line:
|
elif b"resend" in line.lower() or b"rs" in line: # Because a resend can be asked with 'resend' and 'rs'
|
||||||
try:
|
try:
|
||||||
self._gcode_position = int(line.replace(b"N:",b" ").replace(b"N",b" ").replace(b":",b" ").split()[-1])
|
self._gcode_position = int(line.replace(b"N:",b" ").replace(b"N",b" ").replace(b":",b" ").split()[-1])
|
||||||
except:
|
except:
|
||||||
|
@ -377,28 +397,28 @@ class PrinterConnection(SignalEmitter):
|
||||||
self.sendCommand("M105 T%d" % self._temperature_requested_extruder_index)
|
self.sendCommand("M105 T%d" % self._temperature_requested_extruder_index)
|
||||||
else:
|
else:
|
||||||
self.sendCommand("M105")
|
self.sendCommand("M105")
|
||||||
|
Logger.log('i', "Printer connection listen thread stopped for %s" % self._serial_port)
|
||||||
|
|
||||||
## Send next Gcode in the gcode list
|
## Send next Gcode in the gcode list
|
||||||
def _sendNextGcodeLine(self):
|
def _sendNextGcodeLine(self):
|
||||||
if self._gcode_position >= len(self._gcode):
|
if self._gcode_position >= len(self._gcode):
|
||||||
#self._changeState(self.STATE_OPERATIONAL)
|
|
||||||
return
|
return
|
||||||
if self._gcode_position == 100:
|
if self._gcode_position == 100:
|
||||||
self._print_start_time_100 = time.time()
|
self._print_start_time_100 = time.time()
|
||||||
line = self._gcode[self._gcode_position]
|
line = self._gcode[self._gcode_position]
|
||||||
|
|
||||||
if ';' in line:
|
if ';' in line:
|
||||||
line = line[:line.find(';')]
|
line = line[:line.find(';')]
|
||||||
line = line.strip()
|
line = line.strip()
|
||||||
try:
|
try:
|
||||||
if line == 'M0' or line == 'M1':
|
if line == 'M0' or line == 'M1':
|
||||||
#self.setPause(True)
|
|
||||||
line = 'M105' #Don't send the M0 or M1 to the machine, as M0 and M1 are handled as an LCD menu pause.
|
line = 'M105' #Don't send the M0 or M1 to the machine, as M0 and M1 are handled as an LCD menu pause.
|
||||||
if ('G0' in line or 'G1' in line) and 'Z' in line:
|
if ('G0' in line or 'G1' in line) and 'Z' in line:
|
||||||
z = float(re.search('Z([0-9\.]*)', line).group(1))
|
z = float(re.search('Z([0-9\.]*)', line).group(1))
|
||||||
if self._current_z != z:
|
if self._current_z != z:
|
||||||
self._current_z = z
|
self._current_z = z
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Logger.log('e', "Unexpected error: %s" % e)
|
Logger.log('e', "Unexpected error with printer connection: %s" % e)
|
||||||
self._setErrorState("Unexpected error: %s" %e)
|
self._setErrorState("Unexpected error: %s" %e)
|
||||||
checksum = functools.reduce(lambda x,y: x^y, map(ord, 'N%d%s' % (self._gcode_position, line)))
|
checksum = functools.reduce(lambda x,y: x^y, map(ord, 'N%d%s' % (self._gcode_position, line)))
|
||||||
|
|
||||||
|
@ -409,23 +429,28 @@ class PrinterConnection(SignalEmitter):
|
||||||
|
|
||||||
progressChanged = Signal()
|
progressChanged = Signal()
|
||||||
|
|
||||||
|
## Set the progress of the print.
|
||||||
|
# It will be normalized (based on max_progress) to range 0 - 100
|
||||||
def setProgress(self, progress, max_progress = 100):
|
def setProgress(self, progress, max_progress = 100):
|
||||||
self._progress = progress / max_progress * 100 #Convert to scale of 0-100
|
self._progress = progress / max_progress * 100 #Convert to scale of 0-100
|
||||||
#self._progress = progress
|
|
||||||
self.progressChanged.emit(self._progress, self._serial_port)
|
self.progressChanged.emit(self._progress, self._serial_port)
|
||||||
|
|
||||||
|
## Cancel the current print. Printer connection wil continue to listen.
|
||||||
def cancelPrint(self):
|
def cancelPrint(self):
|
||||||
self._gcode_position = 0
|
self._gcode_position = 0
|
||||||
self.setProgress(0)
|
self.setProgress(0)
|
||||||
self._gcode = []
|
self._gcode = []
|
||||||
|
|
||||||
# Turn of temperatures
|
# Turn of temperatures
|
||||||
self._sendCommand("M140 S0")
|
self._sendCommand("M140 S0")
|
||||||
self._sendCommand("M109 S0")
|
self._sendCommand("M109 S0")
|
||||||
self._is_printing = False
|
self._is_printing = False
|
||||||
|
|
||||||
|
## Check if the process did not encounter an error yet.
|
||||||
def hasError(self):
|
def hasError(self):
|
||||||
return False
|
return self._error_state != None
|
||||||
|
|
||||||
|
## private read line used by printer connection to listen for data on serial port.
|
||||||
def _readline(self):
|
def _readline(self):
|
||||||
if self._serial is None:
|
if self._serial is None:
|
||||||
return None
|
return None
|
||||||
|
@ -434,22 +459,12 @@ class PrinterConnection(SignalEmitter):
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
Logger.log('e',"Unexpected error while reading serial port. %s" %e)
|
Logger.log('e',"Unexpected error while reading serial port. %s" %e)
|
||||||
self._setErrorState("Printer has been disconnected")
|
self._setErrorState("Printer has been disconnected")
|
||||||
#self._errorValue = getExceptionString()
|
|
||||||
self.close()
|
self.close()
|
||||||
return None
|
return None
|
||||||
#if ret == '':
|
|
||||||
#return ''
|
|
||||||
#self._log("Recv: %s" % (unicode(ret, 'ascii', 'replace').encode('ascii', 'replace').rstrip()))
|
|
||||||
return ret
|
return ret
|
||||||
|
|
||||||
|
|
||||||
## Create a list of baud rates at which we can communicate.
|
## Create a list of baud rates at which we can communicate.
|
||||||
# \return list of int
|
# \return list of int
|
||||||
def _getBaudrateList(self):
|
def _getBaudrateList(self):
|
||||||
ret = [250000, 230400, 115200, 57600, 38400, 19200, 9600]
|
ret = [250000, 230400, 115200, 57600, 38400, 19200, 9600]
|
||||||
#if profile.getMachineSetting('serial_baud_auto') != '':
|
|
||||||
#prev = int(profile.getMachineSetting('serial_baud_auto'))
|
|
||||||
#if prev in ret:
|
|
||||||
#ret.remove(prev)
|
|
||||||
#ret.insert(0, prev)
|
|
||||||
return ret
|
return ret
|
||||||
|
|
|
@ -31,16 +31,22 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
|
|
||||||
self._progress = 0
|
self._progress = 0
|
||||||
|
|
||||||
|
|
||||||
self._control_view = None
|
self._control_view = None
|
||||||
self._firmware_view = None
|
self._firmware_view = None
|
||||||
self._extruder_temp = 0
|
self._extruder_temp = 0
|
||||||
self._bed_temp = 0
|
self._bed_temp = 0
|
||||||
self._error_message = ""
|
self._error_message = ""
|
||||||
|
|
||||||
## Add menu item to top menu.
|
## Add menu item to top menu of the application.
|
||||||
self.addMenuItem(i18n_catalog.i18n("Update firmware"), self.updateAllFirmware)
|
self.addMenuItem(i18n_catalog.i18n("Update firmware"), self.updateAllFirmware)
|
||||||
|
|
||||||
|
pyqtError = pyqtSignal(str, arguments = ['amount'])
|
||||||
|
processingProgress = pyqtSignal(float, arguments = ['amount'])
|
||||||
|
pyqtExtruderTemperature = pyqtSignal(float, arguments = ['amount'])
|
||||||
|
pyqtBedTemperature = pyqtSignal(float, arguments = ['amount'])
|
||||||
|
|
||||||
|
## Show firmware interface.
|
||||||
|
# This will create the view if its not already created.
|
||||||
def spawnFirmwareInterface(self, serial_port):
|
def spawnFirmwareInterface(self, serial_port):
|
||||||
if self._firmware_view is None:
|
if self._firmware_view is None:
|
||||||
self._firmware_view = QQuickView()
|
self._firmware_view = QQuickView()
|
||||||
|
@ -48,7 +54,8 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
self._firmware_view.setSource(QUrl("plugins/USBPrinting/FirmwareUpdateWindow.qml"))
|
self._firmware_view.setSource(QUrl("plugins/USBPrinting/FirmwareUpdateWindow.qml"))
|
||||||
self._firmware_view.show()
|
self._firmware_view.show()
|
||||||
|
|
||||||
|
## Show control interface.
|
||||||
|
# This will create the view if its not already created.
|
||||||
def spawnControlInterface(self,serial_port):
|
def spawnControlInterface(self,serial_port):
|
||||||
if self._control_view is None:
|
if self._control_view is None:
|
||||||
self._control_view = QQuickView()
|
self._control_view = QQuickView()
|
||||||
|
@ -56,22 +63,18 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
self._control_view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml"))
|
self._control_view.setSource(QUrl("plugins/USBPrinting/ControlWindow.qml"))
|
||||||
self._control_view.show()
|
self._control_view.show()
|
||||||
|
|
||||||
processingProgress = pyqtSignal(float, arguments = ['amount'])
|
|
||||||
@pyqtProperty(float,notify = processingProgress)
|
@pyqtProperty(float,notify = processingProgress)
|
||||||
def progress(self):
|
def progress(self):
|
||||||
return self._progress
|
return self._progress
|
||||||
|
|
||||||
pyqtExtruderTemperature = pyqtSignal(float, arguments = ['amount'])
|
|
||||||
@pyqtProperty(float,notify = pyqtExtruderTemperature)
|
@pyqtProperty(float,notify = pyqtExtruderTemperature)
|
||||||
def extruderTemperature(self):
|
def extruderTemperature(self):
|
||||||
return self._extruder_temp
|
return self._extruder_temp
|
||||||
|
|
||||||
pyqtBedTemperature = pyqtSignal(float, arguments = ['amount'])
|
|
||||||
@pyqtProperty(float,notify = pyqtBedTemperature)
|
@pyqtProperty(float,notify = pyqtBedTemperature)
|
||||||
def bedTemperature(self):
|
def bedTemperature(self):
|
||||||
return self._bed_temp
|
return self._bed_temp
|
||||||
|
|
||||||
pyqtError = pyqtSignal(str, arguments = ['amount'])
|
|
||||||
@pyqtProperty(str,notify = pyqtError)
|
@pyqtProperty(str,notify = pyqtError)
|
||||||
def error(self):
|
def error(self):
|
||||||
return self._error_message
|
return self._error_message
|
||||||
|
@ -104,13 +107,6 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
connection.close()
|
connection.close()
|
||||||
time.sleep(5) # Throttle, as we don't need this information to be updated every single second.
|
time.sleep(5) # Throttle, as we don't need this information to be updated every single second.
|
||||||
|
|
||||||
def onExtruderTemperature(self, serial_port, index,temperature):
|
|
||||||
#print("ExtruderTemperature " , serial_port, " " , index, " " , temperature)
|
|
||||||
self._extruder_temp = temperature
|
|
||||||
self.pyqtExtruderTemperature.emit(temperature)
|
|
||||||
|
|
||||||
pass
|
|
||||||
|
|
||||||
def updateAllFirmware(self):
|
def updateAllFirmware(self):
|
||||||
self.spawnFirmwareInterface("")
|
self.spawnFirmwareInterface("")
|
||||||
for printer_connection in self._printer_connections:
|
for printer_connection in self._printer_connections:
|
||||||
|
@ -142,35 +138,38 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
elif machine_type == "ultimaker2":
|
elif machine_type == "ultimaker2":
|
||||||
return "MarlinUltimaker2.hex"
|
return "MarlinUltimaker2.hex"
|
||||||
|
|
||||||
|
|
||||||
##TODO: Add check for multiple extruders
|
##TODO: Add check for multiple extruders
|
||||||
|
|
||||||
if firmware_name != "":
|
if firmware_name != "":
|
||||||
firmware_name += ".hex"
|
firmware_name += ".hex"
|
||||||
return firmware_name
|
return firmware_name
|
||||||
|
|
||||||
|
## Callback for extruder temperature change
|
||||||
|
def onExtruderTemperature(self, serial_port, index, temperature):
|
||||||
|
self._extruder_temp = temperature
|
||||||
|
self.pyqtExtruderTemperature.emit(temperature)
|
||||||
|
|
||||||
|
## Callback for bed temperature change
|
||||||
def onBedTemperature(self, serial_port,temperature):
|
def onBedTemperature(self, serial_port,temperature):
|
||||||
self._bed_temperature = temperature
|
self._bed_temperature = temperature
|
||||||
self.pyqtBedTemperature.emit(temperature)
|
self.pyqtBedTemperature.emit(temperature)
|
||||||
#print("bedTemperature " , serial_port, " " , temperature)
|
|
||||||
pass
|
|
||||||
|
|
||||||
|
## Callback for error
|
||||||
def onError(self, error):
|
def onError(self, error):
|
||||||
self._error_message = error
|
self._error_message = error
|
||||||
self.pyqtError.emit(error)
|
self.pyqtError.emit(error)
|
||||||
pass
|
|
||||||
|
|
||||||
|
## Callback for progress change
|
||||||
def onProgress(self, progress, serial_port):
|
def onProgress(self, progress, serial_port):
|
||||||
self._progress = progress
|
self._progress = progress
|
||||||
self.processingProgress.emit(progress)
|
self.processingProgress.emit(progress)
|
||||||
pass
|
|
||||||
|
|
||||||
## Attempt to connect with all possible connections.
|
## Attempt to connect with all possible connections.
|
||||||
def connectAllConnections(self):
|
def connectAllConnections(self):
|
||||||
for connection in self._printer_connections:
|
for connection in self._printer_connections:
|
||||||
connection.connect()
|
connection.connect()
|
||||||
|
|
||||||
## send gcode to printer and start printing
|
## Send gcode to printer and start printing
|
||||||
def sendGCodeByPort(self, serial_port, gcode_list):
|
def sendGCodeByPort(self, serial_port, gcode_list):
|
||||||
printer_connection = self.getConnectionByPort(serial_port)
|
printer_connection = self.getConnectionByPort(serial_port)
|
||||||
if printer_connection is not None:
|
if printer_connection is not None:
|
||||||
|
@ -215,7 +214,8 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
else:
|
else:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
|
## Callback if the connection state of a connection is changed.
|
||||||
|
# This adds or removes the connection as a possible output device.
|
||||||
def serialConectionStateCallback(self, serial_port):
|
def serialConectionStateCallback(self, serial_port):
|
||||||
connection = self.getConnectionByPort(serial_port)
|
connection = self.getConnectionByPort(serial_port)
|
||||||
if connection.isConnected():
|
if connection.isConnected():
|
||||||
|
@ -229,13 +229,6 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
else:
|
else:
|
||||||
Application.getInstance().removeOutputDevice(serial_port)
|
Application.getInstance().removeOutputDevice(serial_port)
|
||||||
|
|
||||||
'''def _writeToSerial(self, serial_port):
|
|
||||||
gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None)
|
|
||||||
if gcode_list:
|
|
||||||
final_list = []
|
|
||||||
for gcode in gcode_list:
|
|
||||||
final_list += gcode.split('\n')
|
|
||||||
self.sendGCodeByPort(serial_port, gcode_list)'''
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def startPrint(self):
|
def startPrint(self):
|
||||||
gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None)
|
gcode_list = getattr(Application.getInstance().getController().getScene(), 'gcode_list', None)
|
||||||
|
@ -245,12 +238,11 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
final_list += gcode.split('\n')
|
final_list += gcode.split('\n')
|
||||||
self.sendGCodeToAllActive(gcode_list)
|
self.sendGCodeToAllActive(gcode_list)
|
||||||
|
|
||||||
|
|
||||||
## Get a list of printer connection objects that are connected.
|
## Get a list of printer connection objects that are connected.
|
||||||
def getActiveConnections(self):
|
def getActiveConnections(self):
|
||||||
return [connection for connection in self._printer_connections if connection.isConnected()]
|
return [connection for connection in self._printer_connections if connection.isConnected()]
|
||||||
|
|
||||||
## get a printer connection object by serial port
|
## Get a printer connection object by serial port
|
||||||
def getConnectionByPort(self, serial_port):
|
def getConnectionByPort(self, serial_port):
|
||||||
for printer_connection in self._printer_connections:
|
for printer_connection in self._printer_connections:
|
||||||
if serial_port == printer_connection.getSerialPort():
|
if serial_port == printer_connection.getSerialPort():
|
||||||
|
@ -268,21 +260,15 @@ class USBPrinterManager(QObject, SignalEmitter, Extension):
|
||||||
i = 0
|
i = 0
|
||||||
while True:
|
while True:
|
||||||
values = winreg.EnumValue(key, i)
|
values = winreg.EnumValue(key, i)
|
||||||
if 'USBSER' in values[0]:
|
if not base_list or 'USBSER' in values[0]:
|
||||||
base_list += [values[1]]
|
base_list += [values[1]]
|
||||||
i += 1
|
i += 1
|
||||||
except:
|
except Exception as e:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if base_list:
|
if base_list:
|
||||||
base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.usb*")
|
base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.usb*")
|
||||||
base_list = filter(lambda s: 'Bluetooth' not in s, base_list) # Filter because mac sometimes puts them in the list
|
base_list = filter(lambda s: 'Bluetooth' not in s, base_list) # Filter because mac sometimes puts them in the list
|
||||||
#prev = profile.getMachineSetting('serial_port_auto')
|
|
||||||
#if prev in base_list:
|
|
||||||
# base_list.remove(prev)
|
|
||||||
# base_list.insert(0, prev)
|
|
||||||
else:
|
else:
|
||||||
base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.*") + glob.glob("/dev/tty.usb*") + glob.glob("/dev/rfcomm*") + glob.glob('/dev/serial/by-id/*')
|
base_list = base_list + glob.glob('/dev/ttyUSB*') + glob.glob('/dev/ttyACM*') + glob.glob("/dev/cu.*") + glob.glob("/dev/tty.usb*") + glob.glob("/dev/rfcomm*") + glob.glob('/dev/serial/by-id/*')
|
||||||
#if version.isDevVersion() and not base_list:
|
|
||||||
#base_list.append('VIRTUAL')
|
|
||||||
return base_list
|
return base_list
|
Loading…
Add table
Add a link
Reference in a new issue