mirror of
https://github.com/Ultimaker/Cura.git
synced 2025-07-08 07:27:29 -06:00
Implement preheating hotends for USB printing
This commit is contained in:
parent
70cd6aad53
commit
bc5b5ac283
6 changed files with 89 additions and 17 deletions
|
@ -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)
|
|
@ -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
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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):
|
||||||
|
|
|
@ -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)
|
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue