GenericOutputController.py 7.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167
  1. # Copyright (c) 2018 Ultimaker B.V.
  2. # Cura is released under the terms of the LGPLv3 or higher.
  3. from cura.PrinterOutput.PrinterOutputController import PrinterOutputController
  4. from PyQt5.QtCore import QTimer
  5. MYPY = False
  6. if MYPY:
  7. from cura.PrinterOutput.PrintJobOutputModel import PrintJobOutputModel
  8. from cura.PrinterOutput.PrinterOutputModel import PrinterOutputModel
  9. class GenericOutputController(PrinterOutputController):
  10. def __init__(self, output_device):
  11. super().__init__(output_device)
  12. self._preheat_bed_timer = QTimer()
  13. self._preheat_bed_timer.setSingleShot(True)
  14. self._preheat_bed_timer.timeout.connect(self._onPreheatBedTimerFinished)
  15. self._preheat_printer = None
  16. self._preheat_hotends_timer = QTimer()
  17. self._preheat_hotends_timer.setSingleShot(True)
  18. self._preheat_hotends_timer.timeout.connect(self._onPreheatHotendsTimerFinished)
  19. self._preheat_hotends = set()
  20. self._output_device.printersChanged.connect(self._onPrintersChanged)
  21. self._active_printer = None
  22. def _onPrintersChanged(self):
  23. if self._active_printer:
  24. self._active_printer.stateChanged.disconnect(self._onPrinterStateChanged)
  25. self._active_printer.targetBedTemperatureChanged.disconnect(self._onTargetBedTemperatureChanged)
  26. for extruder in self._active_printer.extruders:
  27. extruder.targetHotendTemperatureChanged.disconnect(self._onTargetHotendTemperatureChanged)
  28. self._active_printer = self._output_device.activePrinter
  29. if self._active_printer:
  30. self._active_printer.stateChanged.connect(self._onPrinterStateChanged)
  31. self._active_printer.targetBedTemperatureChanged.connect(self._onTargetBedTemperatureChanged)
  32. for extruder in self._active_printer.extruders:
  33. extruder.targetHotendTemperatureChanged.connect(self._onTargetHotendTemperatureChanged)
  34. def _onPrinterStateChanged(self):
  35. if self._active_printer.state != "idle":
  36. if self._preheat_bed_timer.isActive():
  37. self._preheat_bed_timer.stop()
  38. self._preheat_printer.updateIsPreheating(False)
  39. if self._preheat_hotends_timer.isActive():
  40. self._preheat_hotends_timer.stop()
  41. for extruder in self._preheat_hotends:
  42. extruder.updateIsPreheating(False)
  43. self._preheat_hotends = set()
  44. def moveHead(self, printer: "PrinterOutputModel", x, y, z, speed):
  45. self._output_device.sendCommand("G91")
  46. self._output_device.sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed))
  47. self._output_device.sendCommand("G90")
  48. def homeHead(self, printer):
  49. self._output_device.sendCommand("G28 X Y")
  50. def homeBed(self, printer):
  51. self._output_device.sendCommand("G28 Z")
  52. def sendRawCommand(self, printer: "PrinterOutputModel", command: str):
  53. self._output_device.sendCommand(command)
  54. def setJobState(self, job: "PrintJobOutputModel", state: str):
  55. if state == "pause":
  56. self._output_device.pausePrint()
  57. job.updateState("paused")
  58. elif state == "print":
  59. self._output_device.resumePrint()
  60. job.updateState("printing")
  61. elif state == "abort":
  62. self._output_device.cancelPrint()
  63. pass
  64. def setTargetBedTemperature(self, printer: "PrinterOutputModel", temperature: int):
  65. self._output_device.sendCommand("M140 S%s" % temperature)
  66. def _onTargetBedTemperatureChanged(self):
  67. if self._preheat_bed_timer.isActive() and self._preheat_printer.targetBedTemperature == 0:
  68. self._preheat_bed_timer.stop()
  69. self._preheat_printer.updateIsPreheating(False)
  70. def preheatBed(self, printer: "PrinterOutputModel", temperature, duration):
  71. try:
  72. temperature = round(temperature) # The API doesn't allow floating point.
  73. duration = round(duration)
  74. except ValueError:
  75. return # Got invalid values, can't pre-heat.
  76. self.setTargetBedTemperature(printer, temperature=temperature)
  77. self._preheat_bed_timer.setInterval(duration * 1000)
  78. self._preheat_bed_timer.start()
  79. self._preheat_printer = printer
  80. printer.updateIsPreheating(True)
  81. def cancelPreheatBed(self, printer: "PrinterOutputModel"):
  82. self.setTargetBedTemperature(printer, temperature=0)
  83. self._preheat_bed_timer.stop()
  84. printer.updateIsPreheating(False)
  85. def _onPreheatBedTimerFinished(self):
  86. self.setTargetBedTemperature(self._preheat_printer, 0)
  87. self._preheat_printer.updateIsPreheating(False)
  88. def setTargetHotendTemperature(self, printer: "PrinterOutputModel", position: int, temperature: int):
  89. self._output_device.sendCommand("M104 S%s T%s" % (temperature, position))
  90. def _onTargetHotendTemperatureChanged(self):
  91. if not self._preheat_hotends_timer.isActive():
  92. return
  93. for extruder in self._active_printer.extruders:
  94. if extruder in self._preheat_hotends and extruder.targetHotendTemperature == 0:
  95. extruder.updateIsPreheating(False)
  96. self._preheat_hotends.remove(extruder)
  97. if not self._preheat_hotends:
  98. self._preheat_hotends_timer.stop()
  99. def preheatHotend(self, extruder: "ExtruderOutputModel", temperature, duration):
  100. position = extruder.getPosition()
  101. number_of_extruders = len(extruder.getPrinter().extruders)
  102. if position >= number_of_extruders:
  103. return # Got invalid extruder nr, can't pre-heat.
  104. try:
  105. temperature = round(temperature) # The API doesn't allow floating point.
  106. duration = round(duration)
  107. except ValueError:
  108. return # Got invalid values, can't pre-heat.
  109. self.setTargetHotendTemperature(extruder.getPrinter(), position, temperature=temperature)
  110. self._preheat_hotends_timer.setInterval(duration * 1000)
  111. self._preheat_hotends_timer.start()
  112. self._preheat_hotends.add(extruder)
  113. extruder.updateIsPreheating(True)
  114. def cancelPreheatHotend(self, extruder: "ExtruderOutputModel"):
  115. self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), temperature=0)
  116. if extruder in self._preheat_hotends:
  117. extruder.updateIsPreheating(False)
  118. self._preheat_hotends.remove(extruder)
  119. if not self._preheat_hotends and self._preheat_hotends_timer.isActive():
  120. self._preheat_hotends_timer.stop()
  121. def _onPreheatHotendsTimerFinished(self):
  122. for extruder in self._preheat_hotends:
  123. self.setTargetHotendTemperature(extruder.getPrinter(), extruder.getPosition(), 0)
  124. self._preheat_hotends = set()
  125. # Cancel any ongoing preheating timers, without setting back the temperature to 0
  126. # This can be used eg at the start of a print
  127. def stopPreheatTimers(self):
  128. if self._preheat_hotends_timer.isActive():
  129. for extruder in self._preheat_hotends:
  130. extruder.updateIsPreheating(False)
  131. self._preheat_hotends = set()
  132. self._preheat_hotends_timer.stop()
  133. if self._preheat_bed_timer.isActive():
  134. self._preheat_printer.updateIsPreheating(False)
  135. self._preheat_bed_timer.stop()