Implement preheating hotends for USB printing

This commit is contained in:
fieldOfView 2018-01-11 15:27:38 +01:00
parent 70cd6aad53
commit bc5b5ac283
6 changed files with 89 additions and 17 deletions

View file

@ -17,14 +17,23 @@ class ExtruderOutputModel(QObject):
targetHotendTemperatureChanged = pyqtSignal() targetHotendTemperatureChanged = pyqtSignal()
hotendTemperatureChanged = pyqtSignal() hotendTemperatureChanged = pyqtSignal()
activeMaterialChanged = pyqtSignal() activeMaterialChanged = pyqtSignal()
isPreheatingChanged = pyqtSignal()
def __init__(self, printer: "PrinterOutputModel", parent=None): def __init__(self, printer: "PrinterOutputModel", position: int, parent=None):
super().__init__(parent) super().__init__(parent)
self._printer = printer self._printer = printer
self._position = position
self._target_hotend_temperature = 0 self._target_hotend_temperature = 0
self._hotend_temperature = 0 self._hotend_temperature = 0
self._hotend_id = "" self._hotend_id = ""
self._active_material = None # type: Optional[MaterialOutputModel] self._active_material = None # type: Optional[MaterialOutputModel]
self._is_preheating = False
def getPrinter(self):
return self._printer
def getPosition(self):
return self._position
@pyqtProperty(QObject, notify = activeMaterialChanged) @pyqtProperty(QObject, notify = activeMaterialChanged)
def activeMaterial(self) -> "MaterialOutputModel": def activeMaterial(self) -> "MaterialOutputModel":
@ -68,3 +77,25 @@ class ExtruderOutputModel(QObject):
if self._hotend_id != id: if self._hotend_id != id:
self._hotend_id = id self._hotend_id = id
self.hotendIDChanged.emit() self.hotendIDChanged.emit()
def updateIsPreheating(self, pre_heating):
if self._is_preheating != pre_heating:
self._is_preheating = pre_heating
self.isPreheatingChanged.emit()
@pyqtProperty(bool, notify=isPreheatingChanged)
def isPreheating(self):
return self._is_preheating
## Pre-heats the extruder before printer.
#
# \param temperature The temperature to heat the extruder to, in degrees
# Celsius.
# \param duration How long the bed should stay warm, in seconds.
@pyqtSlot(float, float)
def preheatHotend(self, temperature, duration):
self._printer._controller.preheatHotend(self, temperature, duration)
@pyqtSlot()
def cancelPreheatHotend(self):
self._printer._controller.cancelPreheatHotend(self)

View file

@ -15,7 +15,7 @@ class PrinterOutputController:
self.can_pause = True self.can_pause = True
self.can_abort = True self.can_abort = True
self.can_pre_heat_bed = True self.can_pre_heat_bed = True
self.can_pre_heat_extruders = True self.can_pre_heat_hotends = True
self.can_control_manually = True self.can_control_manually = True
self._output_device = output_device self._output_device = output_device

View file

@ -32,7 +32,7 @@ class PrinterOutputModel(QObject):
self._name = "" self._name = ""
self._key = "" # Unique identifier self._key = "" # Unique identifier
self._controller = output_controller self._controller = output_controller
self._extruders = [ExtruderOutputModel(printer=self) for i in range(number_of_extruders)] self._extruders = [ExtruderOutputModel(printer=self, position=i) for i in range(number_of_extruders)]
self._head_position = Vector(0, 0, 0) self._head_position = Vector(0, 0, 0)
self._active_print_job = None # type: Optional[PrintJobOutputModel] self._active_print_job = None # type: Optional[PrintJobOutputModel]
self._firmware_version = firmware_version self._firmware_version = firmware_version
@ -220,9 +220,9 @@ class PrinterOutputModel(QObject):
# Does the printer support pre-heating the bed at all # Does the printer support pre-heating the bed at all
@pyqtProperty(bool, constant=True) @pyqtProperty(bool, constant=True)
def canPreHeatExtruders(self): def canPreHeatHotends(self):
if self._controller: if self._controller:
return self._controller.can_pre_heat_extruders return self._controller.can_pre_heat_hotends
return False return False
# Does the printer support pause at all # Does the printer support pause at all

View file

@ -13,7 +13,7 @@ class ClusterUM3PrinterOutputController(PrinterOutputController):
def __init__(self, output_device): def __init__(self, output_device):
super().__init__(output_device) super().__init__(output_device)
self.can_pre_heat_bed = False self.can_pre_heat_bed = False
self.can_pre_heat_extruders = False self.can_pre_heat_hotends = False
self.can_control_manually = False self.can_control_manually = False
def setJobState(self, job: "PrintJobOutputModel", state: str): def setJobState(self, job: "PrintJobOutputModel", state: str):

View file

@ -19,6 +19,11 @@ class USBPrinterOuptutController(PrinterOutputController):
self._preheat_bed_timer.timeout.connect(self._onPreheatBedTimerFinished) self._preheat_bed_timer.timeout.connect(self._onPreheatBedTimerFinished)
self._preheat_printer = None self._preheat_printer = None
self._preheat_extruders_timer = QTimer()
self._preheat_extruders_timer.setSingleShot(True)
self._preheat_extruders_timer.timeout.connect(self._onPreheatHotendsTimerFinished)
self._preheat_extruders = set()
def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed): def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed):
self._output_device.sendCommand("G91") self._output_device.sendCommand("G91")
self._output_device.sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed)) self._output_device.sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed))
@ -42,6 +47,9 @@ class USBPrinterOuptutController(PrinterOutputController):
self._output_device.cancelPrint() self._output_device.cancelPrint()
pass pass
def setTargetBedTemperature(self, printer: "PrinterOutputModel", temperature: int):
self._output_device.sendCommand("M140 S%s" % temperature)
def preheatBed(self, printer: "PrinterOutputModel", temperature, duration): def preheatBed(self, printer: "PrinterOutputModel", temperature, duration):
try: try:
temperature = round(temperature) # The API doesn't allow floating point. temperature = round(temperature) # The API doesn't allow floating point.
@ -60,9 +68,42 @@ class USBPrinterOuptutController(PrinterOutputController):
self._preheat_bed_timer.stop() self._preheat_bed_timer.stop()
printer.updateIsPreheating(False) printer.updateIsPreheating(False)
def setTargetBedTemperature(self, printer: "PrinterOutputModel", temperature: int):
self._output_device.sendCommand("M140 S%s" % temperature)
def _onPreheatBedTimerFinished(self): def _onPreheatBedTimerFinished(self):
self.setTargetBedTemperature(self._preheat_printer, 0) self.setTargetBedTemperature(self._preheat_printer, 0)
self._preheat_printer.updateIsPreheating(False) self._preheat_printer.updateIsPreheating(False)
def setTargetHotendTemperature(self, printer: "PrinterOutputModel", position: int, temperature: int):
self._output_device.sendCommand("M104 S%s T%s" % (temperature, position))
def _onPreheatHotendsTimerFinished(self):
for extruder in self._preheat_extruders:
self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), 0)
self._preheat_extruders = set()
self._preheat_printer.updateIsPreheating(False)
def cancelPreheatHotend(self, extruder: "ExtruderOutputModel"):
self.preheatHotend(extruder, temperature=0, duration=0)
self._preheat_extruders_timer.stop()
try:
self._preheat_extruders.remove(extruder)
except KeyError:
pass
extruder.updateIsPreheating(False)
def preheatHotend(self, extruder: "ExtruderOutputModel", temperature, duration):
position = extruder.getPosition()
number_of_extruders = len(extruder.getPrinter().extruders)
if position >= number_of_extruders:
return # Got invalid extruder nr, can't pre-heat.
try:
temperature = round(temperature) # The API doesn't allow floating point.
duration = round(duration)
except ValueError:
return # Got invalid values, can't pre-heat.
self.setTargetHotendTemperature(extruder.getPrinter(), position, temperature=temperature)
self._preheat_extruders_timer.setInterval(duration * 1000)
self._preheat_extruders_timer.start()
self._preheat_extruders.add(extruder)
extruder.updateIsPreheating(True)

View file

@ -95,7 +95,7 @@ Item
base.showTooltip( base.showTooltip(
base, base,
{x: 0, y: parent.mapToItem(base, 0, Math.floor(-parent.height / 4)).y}, {x: 0, y: parent.mapToItem(base, 0, Math.floor(-parent.height / 4)).y},
catalog.i18nc("@tooltip", "The current temperature of this extruder.") catalog.i18nc("@tooltip", "The current temperature of this hotend.")
); );
} }
else else
@ -144,7 +144,7 @@ Item
anchors.bottomMargin: UM.Theme.getSize("default_margin").height anchors.bottomMargin: UM.Theme.getSize("default_margin").height
width: Math.floor(UM.Theme.getSize("setting_control").width * 0.75) width: Math.floor(UM.Theme.getSize("setting_control").width * 0.75)
height: UM.Theme.getSize("setting_control").height height: UM.Theme.getSize("setting_control").height
visible: extruderModel != null ? extruderModel.canPreHeatExtruders: true visible: extruderModel != null ? extruderModel.canPreHeatHotends: true
Rectangle //Highlight of input field. Rectangle //Highlight of input field.
{ {
anchors.fill: parent anchors.fill: parent
@ -166,7 +166,7 @@ Item
base.showTooltip( base.showTooltip(
base, base,
{x: 0, y: preheatTemperatureInputMouseArea.mapToItem(base, 0, 0).y}, {x: 0, y: preheatTemperatureInputMouseArea.mapToItem(base, 0, 0).y},
catalog.i18nc("@tooltip of temperature input", "The temperature to pre-heat the extruder to.") catalog.i18nc("@tooltip of temperature input", "The temperature to pre-heat the hotend to.")
); );
} }
else else
@ -208,7 +208,7 @@ Item
{ {
id: preheatButton id: preheatButton
height: UM.Theme.getSize("setting_control").height height: UM.Theme.getSize("setting_control").height
visible: extruderModel != null ? extruderModel.canPreHeatExtruders: true visible: extruderModel != null ? extruderModel.canPreHeatHotends: true
enabled: enabled:
{ {
if (!preheatTemperatureControl.enabled) if (!preheatTemperatureControl.enabled)
@ -333,11 +333,11 @@ Item
{ {
if (!extruderModel.isPreheating) if (!extruderModel.isPreheating)
{ {
extruderModel.preheatExtruder(preheatTemperatureInput.text, 900); extruderModel.preheatHotend(preheatTemperatureInput.text, 900);
} }
else else
{ {
extruderModel.cancelPreheatExtruder(); extruderModel.cancelPreheatHotend();
} }
} }
@ -348,7 +348,7 @@ Item
base.showTooltip( base.showTooltip(
base, base,
{x: 0, y: preheatButton.mapToItem(base, 0, 0).y}, {x: 0, y: preheatButton.mapToItem(base, 0, 0).y},
catalog.i18nc("@tooltip of pre-heat", "Heat the extruder in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the extruder to heat up when you're ready to print.") catalog.i18nc("@tooltip of pre-heat", "Heat the hotend in advance before printing. You can continue adjusting your print while it is heating, and you won't have to wait for the hotend to heat up when you're ready to print.")
); );
} }
else else