mirror of
https://git.mirrors.martin98.com/https://github.com/Ultimaker/Cura
synced 2025-05-14 04:38:05 +08:00
Merge branch 'master' of https://github.com/Ultimaker/Cura
This commit is contained in:
commit
a20193a13b
328
cura/PrinterOutputDevice.py
Normal file
328
cura/PrinterOutputDevice.py
Normal file
@ -0,0 +1,328 @@
|
|||||||
|
from UM.OutputDevice.OutputDevice import OutputDevice
|
||||||
|
from PyQt5.QtCore import pyqtProperty, pyqtSignal, pyqtSlot, QObject
|
||||||
|
from enum import IntEnum # For the connection state tracking.
|
||||||
|
from UM.Logger import Logger
|
||||||
|
|
||||||
|
|
||||||
|
## Printer output device adds extra interface options on top of output device.
|
||||||
|
#
|
||||||
|
# The assumption is made the printer is a FDM printer.
|
||||||
|
#
|
||||||
|
# Note that a number of settings are marked as "final". This is because decorators
|
||||||
|
# are not inherited by children. To fix this we use the private counter part of those
|
||||||
|
# functions to actually have the implementation.
|
||||||
|
#
|
||||||
|
# For all other uses it should be used in the same way as a "regular" OutputDevice.
|
||||||
|
class PrinterOutputDevice(OutputDevice, QObject):
|
||||||
|
def __init__(self, device_id, parent = None):
|
||||||
|
super().__init__(device_id = device_id, parent = parent)
|
||||||
|
|
||||||
|
self._target_bed_temperature = 0
|
||||||
|
self._bed_temperature = 0
|
||||||
|
self._num_extruders = 1
|
||||||
|
self._hotend_temperatures = [0] * self._num_extruders
|
||||||
|
self._target_hotend_temperatures = [0] * self._num_extruders
|
||||||
|
self._progress = 0
|
||||||
|
self._head_x = 0
|
||||||
|
self._head_y = 0
|
||||||
|
self._head_z = 0
|
||||||
|
self._connection_state = ConnectionState.closed
|
||||||
|
|
||||||
|
def requestWrite(self, node, file_name = None, filter_by_machine = False):
|
||||||
|
raise NotImplementedError("requestWrite needs to be implemented")
|
||||||
|
|
||||||
|
## Signals
|
||||||
|
|
||||||
|
# Signal to be emitted when bed temp is changed
|
||||||
|
bedTemperatureChanged = pyqtSignal()
|
||||||
|
|
||||||
|
# Signal to be emitted when target bed temp is changed
|
||||||
|
targetBedTemperatureChanged = pyqtSignal()
|
||||||
|
|
||||||
|
# Signal when the progress is changed (usually when this output device is printing / sending lots of data)
|
||||||
|
progressChanged = pyqtSignal()
|
||||||
|
|
||||||
|
# Signal to be emitted when hotend temp is changed
|
||||||
|
hotendTemperaturesChanged = pyqtSignal()
|
||||||
|
|
||||||
|
# Signal to be emitted when target hotend temp is changed
|
||||||
|
targetHotendTemperaturesChanged = pyqtSignal()
|
||||||
|
|
||||||
|
# Signal to be emitted when head position is changed (x,y,z)
|
||||||
|
headPositionChanged = pyqtSignal()
|
||||||
|
|
||||||
|
# Signal that is emitted every time connection state is changed.
|
||||||
|
# it also sends it's own device_id (for convenience sake)
|
||||||
|
connectionStateChanged = pyqtSignal(str)
|
||||||
|
|
||||||
|
## Get the bed temperature of the bed (if any)
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /sa _getBedTemperature implementation function
|
||||||
|
@pyqtProperty(float, notify = bedTemperatureChanged)
|
||||||
|
def bedTemperature(self):
|
||||||
|
return self._bed_temperature
|
||||||
|
|
||||||
|
## Set the (target) bed temperature
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /param temperature new target temperature of the bed (in deg C)
|
||||||
|
# /sa _setTargetBedTemperature implementation function
|
||||||
|
@pyqtSlot(int)
|
||||||
|
def setTargetBedTemperature(self, temperature):
|
||||||
|
self._setTargetBedTemperature(temperature)
|
||||||
|
self._target_bed_temperature = temperature
|
||||||
|
self.targetBedTemperatureChanged.emit()
|
||||||
|
|
||||||
|
## Home the head of the connected printer
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /sa _homeHead implementation function
|
||||||
|
@pyqtSlot()
|
||||||
|
def homeHead(self):
|
||||||
|
self._homeHead()
|
||||||
|
|
||||||
|
## Home the head of the connected printer
|
||||||
|
# This is an implementation function and should be overriden by children.
|
||||||
|
def _homeHead(self):
|
||||||
|
Logger.log("w", "_homeHead is not implemented by this output device")
|
||||||
|
|
||||||
|
## Home the bed of the connected printer
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /sa _homeBed implementation function
|
||||||
|
@pyqtSlot()
|
||||||
|
def homeBed(self):
|
||||||
|
self._homeBed()
|
||||||
|
|
||||||
|
## Home the bed of the connected printer
|
||||||
|
# This is an implementation function and should be overriden by children.
|
||||||
|
# /sa homeBed
|
||||||
|
def _homeBed(self):
|
||||||
|
Logger.log("w", "_homeBed is not implemented by this output device")
|
||||||
|
|
||||||
|
## Protected setter for the bed temperature of the connected printer (if any).
|
||||||
|
# /parameter temperature Temperature bed needs to go to (in deg celsius)
|
||||||
|
# /sa setTargetBedTemperature
|
||||||
|
def _setTargetBedTemperature(self, temperature):
|
||||||
|
Logger.log("w", "_setTargetBedTemperature is not implemented by this output device")
|
||||||
|
|
||||||
|
## Protected setter for the current bed temperature.
|
||||||
|
# This simply sets the bed temperature, but ensures that a signal is emitted.
|
||||||
|
# /param temperature temperature of the bed.
|
||||||
|
def _setBedTemperature(self, temperature):
|
||||||
|
self._bed_temperature = temperature
|
||||||
|
self.bedTemperatureChanged.emit()
|
||||||
|
|
||||||
|
## Get the target bed temperature if connected printer (if any)
|
||||||
|
@pyqtProperty(int, notify = targetBedTemperatureChanged)
|
||||||
|
def targetBedTemperature(self):
|
||||||
|
return self._target_bed_temperature
|
||||||
|
|
||||||
|
## Set the (target) hotend temperature
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /param index the index of the hotend that needs to change temperature
|
||||||
|
# /param temperature The temperature it needs to change to (in deg celsius).
|
||||||
|
# /sa _setTargetHotendTemperature implementation function
|
||||||
|
@pyqtSlot(int, int)
|
||||||
|
def setTargetHotendTemperature(self, index, temperature):
|
||||||
|
self._setTargetHotendTemperature(index, temperature)
|
||||||
|
self._target_hotend_temperatures[index] = temperature
|
||||||
|
self.targetHotendTemperaturesChanged.emit()
|
||||||
|
|
||||||
|
## Implementation function of setTargetHotendTemperature.
|
||||||
|
# /param index Index of the hotend to set the temperature of
|
||||||
|
# /param temperature Temperature to set the hotend to (in deg C)
|
||||||
|
# /sa setTargetHotendTemperature
|
||||||
|
def _setTargetHotendTemperature(self, index, temperature):
|
||||||
|
Logger.log("w", "_setTargetHotendTemperature is not implemented by this output device")
|
||||||
|
|
||||||
|
@pyqtProperty("QVariantList", notify = targetHotendTemperaturesChanged)
|
||||||
|
def targetHotendTemperatures(self):
|
||||||
|
return self._target_hotend_temperatures
|
||||||
|
|
||||||
|
@pyqtProperty("QVariantList", notify = hotendTemperaturesChanged)
|
||||||
|
def hotendTemperatures(self):
|
||||||
|
return self._hotend_temperatures
|
||||||
|
|
||||||
|
## Protected setter for the current hotend temperature.
|
||||||
|
# This simply sets the hotend temperature, but ensures that a signal is emitted.
|
||||||
|
# /param index Index of the hotend
|
||||||
|
# /param temperature temperature of the hotend (in deg C)
|
||||||
|
def _setHotendTemperature(self, index, temperature):
|
||||||
|
self._hotend_temperatures[index] = temperature
|
||||||
|
self.hotendTemperaturesChanged.emit()
|
||||||
|
|
||||||
|
## Attempt to establish connection
|
||||||
|
def connect(self):
|
||||||
|
raise NotImplementedError("connect needs to be implemented")
|
||||||
|
|
||||||
|
## Attempt to close the connection
|
||||||
|
def close(self):
|
||||||
|
raise NotImplementedError("close needs to be implemented")
|
||||||
|
|
||||||
|
@pyqtProperty(bool, notify = connectionStateChanged)
|
||||||
|
def connectionState(self):
|
||||||
|
return self._connection_state
|
||||||
|
|
||||||
|
## Set the connection state of this output device.
|
||||||
|
# /param connection_state ConnectionState enum.
|
||||||
|
def setConnectionState(self, connection_state):
|
||||||
|
self._connection_state = connection_state
|
||||||
|
self.connectionStateChanged.emit(self._id)
|
||||||
|
|
||||||
|
## Ensure that close gets called when object is destroyed
|
||||||
|
def __del__(self):
|
||||||
|
self.close()
|
||||||
|
|
||||||
|
## Get the x position of the head.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
@pyqtProperty(float, notify = headPositionChanged)
|
||||||
|
def headX(self):
|
||||||
|
return self._head_x
|
||||||
|
|
||||||
|
## Get the y position of the head.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
@pyqtProperty(float, notify = headPositionChanged)
|
||||||
|
def headY(self):
|
||||||
|
return self._head_y
|
||||||
|
|
||||||
|
## Get the z position of the head.
|
||||||
|
# In some machines it's actually the bed that moves. For convenience sake we simply see it all as head movements.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
@pyqtProperty(float, notify = headPositionChanged)
|
||||||
|
def headZ(self):
|
||||||
|
return self._head_z
|
||||||
|
|
||||||
|
## Update the saved position of the head
|
||||||
|
# This function should be called when a new position for the head is recieved.
|
||||||
|
def _updateHeadPosition(self, x, y ,z):
|
||||||
|
position_changed = False
|
||||||
|
if self._head_x != x:
|
||||||
|
self._head_x = x
|
||||||
|
position_changed = True
|
||||||
|
if self._head_y != y:
|
||||||
|
self._head_y = y
|
||||||
|
position_changed = True
|
||||||
|
if self._head_z != z:
|
||||||
|
self._head_z = z
|
||||||
|
position_changed = True
|
||||||
|
if position_changed:
|
||||||
|
self.headPositionChanged.emit()
|
||||||
|
|
||||||
|
## Set the position of the head.
|
||||||
|
# In some machines it's actually the bed that moves. For convenience sake we simply see it all as head movements.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /param x new x location of the head.
|
||||||
|
# /param y new y location of the head.
|
||||||
|
# /param z new z location of the head.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa _setHeadPosition implementation function
|
||||||
|
@pyqtSlot("long", "long", "long")
|
||||||
|
@pyqtSlot("long", "long", "long", "long")
|
||||||
|
def setHeadPosition(self, x, y, z, speed = 3000):
|
||||||
|
self._setHeadPosition(x, y , z, speed)
|
||||||
|
|
||||||
|
## Set the X position of the head.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /param x x position head needs to move to.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa _setHeadx implementation function
|
||||||
|
@pyqtSlot("long")
|
||||||
|
@pyqtSlot("long", "long")
|
||||||
|
def setHeadX(self, x, speed = 3000):
|
||||||
|
self._setHeadX(x, speed)
|
||||||
|
|
||||||
|
## Set the Y position of the head.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /param y y position head needs to move to.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa _setHeadY implementation function
|
||||||
|
@pyqtSlot("long")
|
||||||
|
@pyqtSlot("long", "long")
|
||||||
|
def setHeadY(self, y, speed = 3000):
|
||||||
|
self._setHeadY(y, speed)
|
||||||
|
|
||||||
|
## Set the Z position of the head.
|
||||||
|
# In some machines it's actually the bed that moves. For convenience sake we simply see it all as head movements.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /param z z position head needs to move to.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa _setHeadZ implementation function
|
||||||
|
@pyqtSlot("long")
|
||||||
|
@pyqtSlot("long", "long")
|
||||||
|
def setHeadZ(self, z, speed = 3000):
|
||||||
|
self._setHeadY(z, speed)
|
||||||
|
|
||||||
|
## Move the head of the printer.
|
||||||
|
# Note that this is a relative move. If you want to move the head to a specific position you can use
|
||||||
|
# setHeadPosition
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /param x distance in x to move
|
||||||
|
# /param y distance in y to move
|
||||||
|
# /param z distance in z to move
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa _moveHead implementation function
|
||||||
|
@pyqtSlot("long", "long", "long")
|
||||||
|
@pyqtSlot("long", "long", "long", "long")
|
||||||
|
def moveHead(self, x = 0, y = 0, z = 0, speed = 3000):
|
||||||
|
self._moveHead(x, y, z, speed)
|
||||||
|
|
||||||
|
## Implementation function of moveHead.
|
||||||
|
# /param x distance in x to move
|
||||||
|
# /param y distance in y to move
|
||||||
|
# /param z distance in z to move
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa moveHead
|
||||||
|
def _moveHead(self, x, y, z, speed):
|
||||||
|
Logger.log("w", "_moveHead is not implemented by this output device")
|
||||||
|
|
||||||
|
## Implementation function of setHeadPosition.
|
||||||
|
# /param x new x location of the head.
|
||||||
|
# /param y new y location of the head.
|
||||||
|
# /param z new z location of the head.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa setHeadPosition
|
||||||
|
def _setHeadPosition(self, x, y, z, speed):
|
||||||
|
Logger.log("w", "_setHeadPosition is not implemented by this output device")
|
||||||
|
|
||||||
|
## Implementation function of setHeadX.
|
||||||
|
# /param x new x location of the head.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa setHeadX
|
||||||
|
def _setHeadX(self, x, speed):
|
||||||
|
Logger.log("w", "_setHeadX is not implemented by this output device")
|
||||||
|
|
||||||
|
## Implementation function of setHeadY.
|
||||||
|
# /param y new y location of the head.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa _setHeadY
|
||||||
|
def _setHeadY(self, y, speed):
|
||||||
|
Logger.log("w", "_setHeadY is not implemented by this output device")
|
||||||
|
|
||||||
|
## Implementation function of setHeadZ.
|
||||||
|
# /param z new z location of the head.
|
||||||
|
# /param speed Speed by which it needs to move (in mm/minute)
|
||||||
|
# /sa _setHeadZ
|
||||||
|
def _setHeadZ(self, z, speed):
|
||||||
|
Logger.log("w", "_setHeadZ is not implemented by this output device")
|
||||||
|
|
||||||
|
## Get the progress of any currently active process.
|
||||||
|
# This function is "final" (do not re-implement)
|
||||||
|
# /sa _getProgress
|
||||||
|
# /returns float progress of the process. -1 indicates that there is no process.
|
||||||
|
@pyqtProperty(float, notify = progressChanged)
|
||||||
|
def progress(self):
|
||||||
|
return self._progress
|
||||||
|
|
||||||
|
## Set the progress of any currently active process
|
||||||
|
# /param progress Progress of the process.
|
||||||
|
def setProgress(self, progress):
|
||||||
|
if self._progress != progress:
|
||||||
|
self._progress = progress
|
||||||
|
self.progressChanged.emit()
|
||||||
|
|
||||||
|
|
||||||
|
## The current processing state of the backend.
|
||||||
|
class ConnectionState(IntEnum):
|
||||||
|
closed = 0
|
||||||
|
connecting = 1
|
||||||
|
connected = 2
|
||||||
|
busy = 3
|
||||||
|
error = 4
|
@ -25,7 +25,7 @@ UM.Dialog
|
|||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
//: USB Printing dialog label, %1 is head temperature
|
//: USB Printing dialog label, %1 is head temperature
|
||||||
text: catalog.i18nc("@label","Extruder Temperature %1").arg(manager.extruderTemperature)
|
text: catalog.i18nc("@label","Extruder Temperature %1").arg(manager.hotendTemperatures[0])
|
||||||
}
|
}
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
|
@ -11,25 +11,20 @@ import functools
|
|||||||
import os.path
|
import os.path
|
||||||
|
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Signal import Signal, SignalEmitter
|
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.OutputDevice.OutputDevice import OutputDevice
|
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
|
from cura.PrinterOutputDevice import PrinterOutputDevice, ConnectionState
|
||||||
|
|
||||||
from PyQt5.QtQuick import QQuickView
|
|
||||||
from PyQt5.QtQml import QQmlComponent, QQmlContext
|
from PyQt5.QtQml import QQmlComponent, QQmlContext
|
||||||
from PyQt5.QtCore import QUrl, QObject, pyqtSlot, pyqtProperty, pyqtSignal, Qt
|
from PyQt5.QtCore import QUrl, pyqtSlot, pyqtSignal
|
||||||
|
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
catalog = i18nCatalog("cura")
|
catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
|
|
||||||
class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
class USBPrinterOutputDevice(PrinterOutputDevice):
|
||||||
def __init__(self, serial_port, parent = None):
|
def __init__(self, serial_port):
|
||||||
QObject.__init__(self, parent)
|
super().__init__(serial_port)
|
||||||
OutputDevice.__init__(self, serial_port)
|
|
||||||
SignalEmitter.__init__(self)
|
|
||||||
#super().__init__(serial_port)
|
|
||||||
self.setName(catalog.i18nc("@item:inmenu", "USB printing"))
|
self.setName(catalog.i18nc("@item:inmenu", "USB printing"))
|
||||||
self.setShortDescription(catalog.i18nc("@action:button", "Print with USB"))
|
self.setShortDescription(catalog.i18nc("@action:button", "Print with USB"))
|
||||||
self.setDescription(catalog.i18nc("@info:tooltip", "Print with USB"))
|
self.setDescription(catalog.i18nc("@info:tooltip", "Print with USB"))
|
||||||
@ -46,18 +41,10 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
self._end_stop_thread.daemon = True
|
self._end_stop_thread.daemon = True
|
||||||
self._poll_endstop = -1
|
self._poll_endstop = -1
|
||||||
|
|
||||||
# Printer is connected
|
|
||||||
self._is_connected = False
|
|
||||||
|
|
||||||
# Printer is in the process of connecting
|
|
||||||
self._is_connecting = False
|
|
||||||
|
|
||||||
# The baud checking is done by sending a number of m105 commands to the printer and waiting for a readable
|
# The baud checking is done by sending a number of m105 commands to the printer and waiting for a readable
|
||||||
# response. If the baudrate is correct, this should make sense, else we get giberish.
|
# response. If the baudrate is correct, this should make sense, else we get giberish.
|
||||||
self._required_responses_auto_baud = 3
|
self._required_responses_auto_baud = 3
|
||||||
|
|
||||||
self._progress = 0
|
|
||||||
|
|
||||||
self._listen_thread = threading.Thread(target=self._listen)
|
self._listen_thread = threading.Thread(target=self._listen)
|
||||||
self._listen_thread.daemon = True
|
self._listen_thread.daemon = True
|
||||||
|
|
||||||
@ -82,24 +69,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
# List of gcode lines to be printed
|
# List of gcode lines to be printed
|
||||||
self._gcode = []
|
self._gcode = []
|
||||||
|
|
||||||
# Number of extruders
|
# Check if endstops are ever pressed (used for first run)
|
||||||
self._extruder_count = 1
|
|
||||||
|
|
||||||
# Temperatures of all extruders
|
|
||||||
self._extruder_temperatures = [0] * self._extruder_count
|
|
||||||
|
|
||||||
# Target temperatures of all extruders
|
|
||||||
self._target_extruder_temperatures = [0] * self._extruder_count
|
|
||||||
|
|
||||||
#Target temperature of the bed
|
|
||||||
self._target_bed_temperature = 0
|
|
||||||
|
|
||||||
# Temperature of the bed
|
|
||||||
self._bed_temperature = 0
|
|
||||||
|
|
||||||
# Current Z stage location
|
|
||||||
self._current_z = 0
|
|
||||||
|
|
||||||
self._x_min_endstop_pressed = False
|
self._x_min_endstop_pressed = False
|
||||||
self._y_min_endstop_pressed = False
|
self._y_min_endstop_pressed = False
|
||||||
self._z_min_endstop_pressed = False
|
self._z_min_endstop_pressed = False
|
||||||
@ -119,40 +89,36 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
self._control_view = None
|
self._control_view = None
|
||||||
|
|
||||||
onError = pyqtSignal()
|
onError = pyqtSignal()
|
||||||
progressChanged = pyqtSignal()
|
|
||||||
extruderTemperatureChanged = pyqtSignal()
|
|
||||||
bedTemperatureChanged = pyqtSignal()
|
|
||||||
firmwareUpdateComplete = pyqtSignal()
|
firmwareUpdateComplete = pyqtSignal()
|
||||||
|
|
||||||
endstopStateChanged = pyqtSignal(str ,bool, arguments = ["key","state"])
|
endstopStateChanged = pyqtSignal(str ,bool, arguments = ["key","state"])
|
||||||
|
|
||||||
@pyqtProperty(float, notify = progressChanged)
|
def _setTargetBedTemperature(self, temperature):
|
||||||
def progress(self):
|
Logger.log("d", "Setting bed temperature to %s", temperature)
|
||||||
return self._progress
|
self._sendCommand("M140 S%s" % temperature)
|
||||||
|
|
||||||
@pyqtProperty(float, notify = extruderTemperatureChanged)
|
def _setTargetHotendTemperature(self, index, temperature):
|
||||||
def extruderTemperature(self):
|
Logger.log("d", "Setting hotend %s temperature to %s", index, temperature)
|
||||||
return self._extruder_temperatures[0]
|
self._sendCommand("M104 T%s S%s" % (index, temperature))
|
||||||
|
|
||||||
@pyqtProperty(float, notify = bedTemperatureChanged)
|
def _setHeadPosition(self, x, y , z, speed):
|
||||||
def bedTemperature(self):
|
self._sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed))
|
||||||
return self._bed_temperature
|
|
||||||
|
|
||||||
@pyqtProperty(str, notify = onError)
|
def _setHeadX(self, x, speed):
|
||||||
def error(self):
|
self._sendCommand("G0 X%s F%s" % (x, speed))
|
||||||
return self._error_state
|
|
||||||
|
|
||||||
# TODO: Might need to add check that extruders can not be changed when it started printing or loading these settings from settings object
|
def _setHeadY(self, y, speed):
|
||||||
def setNumExtuders(self, num):
|
self._sendCommand("G0 Y%s F%s" % (y, speed))
|
||||||
self._extruder_count = num
|
|
||||||
self._extruder_temperatures = [0] * self._extruder_count
|
|
||||||
self._target_extruder_temperatures = [0] * self._extruder_count
|
|
||||||
|
|
||||||
## Is the printer actively printing
|
def _setHeadZ(self, z, speed):
|
||||||
def isPrinting(self):
|
self._sendCommand("G0 Y%s F%s" % (z, speed))
|
||||||
if not self._is_connected or self._serial is None:
|
|
||||||
return False
|
def _homeHead(self):
|
||||||
return self._is_printing
|
self._sendCommand("G28")
|
||||||
|
|
||||||
|
def _homeBed(self):
|
||||||
|
self._sendCommand("G28 Z")
|
||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def startPrint(self):
|
def startPrint(self):
|
||||||
@ -160,10 +126,15 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
gcode_list = getattr( Application.getInstance().getController().getScene(), "gcode_list")
|
gcode_list = getattr( Application.getInstance().getController().getScene(), "gcode_list")
|
||||||
self.printGCode(gcode_list)
|
self.printGCode(gcode_list)
|
||||||
|
|
||||||
|
def _moveHead(self, x, y, z, speed):
|
||||||
|
self._sendCommand("G91")
|
||||||
|
self._sendCommand("G0 X%s Y%s Z%s F%s" % (x, y, z, speed))
|
||||||
|
self._sendCommand("G90")
|
||||||
|
|
||||||
## Start a print based on a g-code.
|
## Start a print based on a g-code.
|
||||||
# \param gcode_list List with gcode (strings).
|
# \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._progress or self._connection_state != ConnectionState.connected:
|
||||||
Logger.log("d", "Printer is busy or not connected, aborting print")
|
Logger.log("d", "Printer is busy or not connected, aborting print")
|
||||||
self.writeError.emit(self)
|
self.writeError.emit(self)
|
||||||
return
|
return
|
||||||
@ -172,14 +143,14 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
for layer in gcode_list:
|
for layer in gcode_list:
|
||||||
self._gcode.extend(layer.split("\n"))
|
self._gcode.extend(layer.split("\n"))
|
||||||
|
|
||||||
#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()
|
||||||
|
|
||||||
self.writeFinished.emit(self)
|
self.writeFinished.emit(self)
|
||||||
@ -194,11 +165,11 @@ class PrinterConnection(OutputDevice, QObject, 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.
|
## Private function (threaded) that actually uploads the firmware.
|
||||||
def _updateFirmware(self):
|
def _updateFirmware(self):
|
||||||
self.setProgress(0, 100)
|
self.setProgress(0, 100)
|
||||||
|
|
||||||
if self._is_connecting or self._is_connected:
|
if self._connection_state != ConnectionState.closed:
|
||||||
self.close()
|
self.close()
|
||||||
hex_file = intelHex.readHex(self._firmware_file_name)
|
hex_file = intelHex.readHex(self._firmware_file_name)
|
||||||
|
|
||||||
@ -214,7 +185,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
except Exception:
|
except Exception:
|
||||||
pass
|
pass
|
||||||
|
|
||||||
time.sleep(1) # Give programmer some time to connect. Might need more in some cases, but this worked in all tested cases.
|
# Give programmer some time to connect. Might need more in some cases, but this worked in all tested cases.
|
||||||
|
time.sleep(1)
|
||||||
|
|
||||||
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")
|
||||||
@ -253,14 +225,14 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
self._poll_endstop = False
|
self._poll_endstop = False
|
||||||
|
|
||||||
def _pollEndStop(self):
|
def _pollEndStop(self):
|
||||||
while self._is_connected and self._poll_endstop:
|
while self._connection_state == ConnectionState.connected and self._poll_endstop:
|
||||||
self.sendCommand("M119")
|
self.sendCommand("M119")
|
||||||
time.sleep(0.5)
|
time.sleep(0.5)
|
||||||
|
|
||||||
## Private connect function run by thread. Can be started by calling connect.
|
## Private connect function run by thread. Can be started by calling connect.
|
||||||
def _connect(self):
|
def _connect(self):
|
||||||
Logger.log("d", "Attempting to connect to %s", self._serial_port)
|
Logger.log("d", "Attempting to connect to %s", self._serial_port)
|
||||||
self._is_connecting = True
|
self.setConnectionState(ConnectionState.connecting)
|
||||||
programmer = stk500v2.Stk500v2()
|
programmer = stk500v2.Stk500v2()
|
||||||
try:
|
try:
|
||||||
programmer.connect(self._serial_port) # Connect with the serial, if this succeeds, it's an arduino based usb device.
|
programmer.connect(self._serial_port) # Connect with the serial, if this succeeds, it's an arduino based usb device.
|
||||||
@ -270,14 +242,15 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
except Exception as e:
|
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 useful, but it does give some debugging information.
|
# If the programmer connected, we know its an atmega based version.
|
||||||
|
# Not all that useful, but it does give some debugging information.
|
||||||
for baud_rate in self._getBaudrateList(): # Cycle all baud rates (auto detect)
|
for baud_rate in self._getBaudrateList(): # Cycle all baud rates (auto detect)
|
||||||
Logger.log("d","Attempting to connect to printer with serial %s on baud rate %s", self._serial_port, baud_rate)
|
Logger.log("d","Attempting to connect to printer with serial %s on baud rate %s", self._serial_port, baud_rate)
|
||||||
if self._serial is None:
|
if self._serial is None:
|
||||||
try:
|
try:
|
||||||
self._serial = serial.Serial(str(self._serial_port), baud_rate, timeout = 3, writeTimeout = 10000)
|
self._serial = serial.Serial(str(self._serial_port), baud_rate, timeout = 3, writeTimeout = 10000)
|
||||||
except serial.SerialException:
|
except serial.SerialException:
|
||||||
#Logger.log("i", "Could not open port %s" % self._serial_port)
|
Logger.log("d", "Could not open port %s" % self._serial_port)
|
||||||
continue
|
continue
|
||||||
else:
|
else:
|
||||||
if not self.setBaudRate(baud_rate):
|
if not self.setBaudRate(baud_rate):
|
||||||
@ -291,23 +264,25 @@ class PrinterConnection(OutputDevice, QObject, 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.
|
# Something went wrong with reading, could be that close was called.
|
||||||
|
self.setConnectionState(ConnectionState.closed)
|
||||||
return
|
return
|
||||||
|
|
||||||
if b"T:" in line:
|
if b"T:" in line:
|
||||||
self._serial.timeout = 0.5
|
self._serial.timeout = 0.5
|
||||||
sucesfull_responses += 1
|
sucesfull_responses += 1
|
||||||
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.setConnectionState(ConnectionState.connected)
|
||||||
|
self._listen_thread.start() # Start listening
|
||||||
Logger.log("i", "Established printer connection on port %s" % self._serial_port)
|
Logger.log("i", "Established printer connection on port %s" % self._serial_port)
|
||||||
return
|
return
|
||||||
|
|
||||||
self._sendCommand("M105") # Send M105 as long as we are listening, otherwise we end up in an undefined state
|
self._sendCommand("M105") # Send M105 as long as we are listening, otherwise we end up in an undefined state
|
||||||
|
|
||||||
Logger.log("e", "Baud rate detection for %s failed", self._serial_port)
|
Logger.log("e", "Baud rate detection for %s failed", self._serial_port)
|
||||||
self.close() # Unable to connect, wrap up.
|
self.close() # Unable to connect, wrap up.
|
||||||
self.setIsConnected(False)
|
self.setConnectionState(ConnectionState.closed)
|
||||||
|
|
||||||
## 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.
|
||||||
def setBaudRate(self, baud_rate):
|
def setBaudRate(self, baud_rate):
|
||||||
@ -317,21 +292,9 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
except Exception as e:
|
except Exception as e:
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def setIsConnected(self, state):
|
|
||||||
self._is_connecting = False
|
|
||||||
if self._is_connected != state:
|
|
||||||
self._is_connected = state
|
|
||||||
self.connectionStateChanged.emit(self._serial_port)
|
|
||||||
if self._is_connected:
|
|
||||||
self._listen_thread.start() #Start listening
|
|
||||||
else:
|
|
||||||
Logger.log("w", "Printer connection state was not changed")
|
|
||||||
|
|
||||||
connectionStateChanged = Signal()
|
|
||||||
|
|
||||||
## Close the printer connection
|
## Close the printer connection
|
||||||
def close(self):
|
def close(self):
|
||||||
Logger.log("d", "Closing the printer connection.")
|
Logger.log("d", "Closing the USB printer connection.")
|
||||||
if self._connect_thread.isAlive():
|
if self._connect_thread.isAlive():
|
||||||
try:
|
try:
|
||||||
self._connect_thread.join()
|
self._connect_thread.join()
|
||||||
@ -339,10 +302,10 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
Logger.log("d", "PrinterConnection.close: %s (expected)", e)
|
Logger.log("d", "PrinterConnection.close: %s (expected)", e)
|
||||||
pass # This should work, but it does fail sometimes for some reason
|
pass # This should work, but it does fail sometimes for some reason
|
||||||
|
|
||||||
self._connect_thread = threading.Thread(target=self._connect)
|
self._connect_thread = threading.Thread(target = self._connect)
|
||||||
self._connect_thread.daemon = True
|
self._connect_thread.daemon = True
|
||||||
|
|
||||||
self.setIsConnected(False)
|
self.setConnectionState(ConnectionState.closed)
|
||||||
if self._serial is not None:
|
if self._serial is not None:
|
||||||
try:
|
try:
|
||||||
self._listen_thread.join()
|
self._listen_thread.join()
|
||||||
@ -350,50 +313,10 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
pass
|
pass
|
||||||
self._serial.close()
|
self._serial.close()
|
||||||
|
|
||||||
self._listen_thread = threading.Thread(target=self._listen)
|
self._listen_thread = threading.Thread(target = self._listen)
|
||||||
self._listen_thread.daemon = True
|
self._listen_thread.daemon = True
|
||||||
self._serial = None
|
self._serial = None
|
||||||
|
|
||||||
def isConnected(self):
|
|
||||||
return self._is_connected
|
|
||||||
|
|
||||||
@pyqtSlot(int)
|
|
||||||
def heatupNozzle(self, temperature):
|
|
||||||
Logger.log("d", "Setting nozzle temperature to %s", temperature)
|
|
||||||
self._sendCommand("M104 S%s" % temperature)
|
|
||||||
|
|
||||||
@pyqtSlot(int)
|
|
||||||
def heatupBed(self, temperature):
|
|
||||||
Logger.log("d", "Setting bed temperature to %s", temperature)
|
|
||||||
self._sendCommand("M140 S%s" % temperature)
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def setMoveToRelative(self):
|
|
||||||
self._sendCommand("G91")
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def setMoveToAbsolute(self):
|
|
||||||
self._sendCommand("G90")
|
|
||||||
|
|
||||||
@pyqtSlot("long", "long","long")
|
|
||||||
def moveHead(self, x, y, z):
|
|
||||||
Logger.log("d","Moving head to %s, %s , %s", x, y, z)
|
|
||||||
self._sendCommand("G0 X%s Y%s Z%s F3000" % (x, y, z))
|
|
||||||
|
|
||||||
@pyqtSlot("long", "long","long")
|
|
||||||
def moveHeadRelative(self, x, y, z):
|
|
||||||
self.setMoveToRelative()
|
|
||||||
self.moveHead(x,y,z)
|
|
||||||
self.setMoveToAbsolute()
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def homeHead(self):
|
|
||||||
self._sendCommand("G28")
|
|
||||||
|
|
||||||
@pyqtSlot()
|
|
||||||
def homeBed(self):
|
|
||||||
self._sendCommand("G28 Z")
|
|
||||||
|
|
||||||
## Directly send the command, withouth checking connection state (eg; printing).
|
## Directly send the command, withouth checking connection state (eg; printing).
|
||||||
# \param cmd string with g-code
|
# \param cmd string with g-code
|
||||||
def _sendCommand(self, cmd):
|
def _sendCommand(self, cmd):
|
||||||
@ -402,19 +325,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
if "M109" in cmd or "M190" in cmd:
|
if "M109" in cmd or "M190" in cmd:
|
||||||
self._heatup_wait_start_time = time.time()
|
self._heatup_wait_start_time = time.time()
|
||||||
if "M104" in cmd or "M109" in cmd:
|
|
||||||
try:
|
|
||||||
t = 0
|
|
||||||
if "T" in cmd:
|
|
||||||
t = int(re.search("T([0-9]+)", cmd).group(1))
|
|
||||||
self._target_extruder_temperatures[t] = float(re.search("S([0-9]+)", cmd).group(1))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
if "M140" in cmd or "M190" in cmd:
|
|
||||||
try:
|
|
||||||
self._target_bed_temperature = float(re.search("S([0-9]+)", cmd).group(1))
|
|
||||||
except:
|
|
||||||
pass
|
|
||||||
try:
|
try:
|
||||||
command = (cmd + "\n").encode()
|
command = (cmd + "\n").encode()
|
||||||
self._serial.write(b"\n")
|
self._serial.write(b"\n")
|
||||||
@ -433,10 +344,6 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
self._setErrorState("Unexpected error while writing serial port %s " % e)
|
self._setErrorState("Unexpected error while writing serial port %s " % e)
|
||||||
self.close()
|
self.close()
|
||||||
|
|
||||||
## Ensure that close gets called when object is destroyed
|
|
||||||
def __del__(self):
|
|
||||||
self.close()
|
|
||||||
|
|
||||||
def createControlInterface(self):
|
def createControlInterface(self):
|
||||||
if self._control_view is None:
|
if self._control_view is None:
|
||||||
Logger.log("d", "Creating control interface for printer connection")
|
Logger.log("d", "Creating control interface for printer connection")
|
||||||
@ -456,9 +363,9 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
## Send a command to printer.
|
## Send a command to printer.
|
||||||
# \param cmd string with g-code
|
# \param cmd string with g-code
|
||||||
def sendCommand(self, cmd):
|
def sendCommand(self, cmd):
|
||||||
if self.isPrinting():
|
if self._progress:
|
||||||
self._command_queue.put(cmd)
|
self._command_queue.put(cmd)
|
||||||
elif self.isConnected():
|
elif self._connection_state == ConnectionState.connected:
|
||||||
self._sendCommand(cmd)
|
self._sendCommand(cmd)
|
||||||
|
|
||||||
## Set the error state with a message.
|
## Set the error state with a message.
|
||||||
@ -467,24 +374,6 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
self._error_state = error
|
self._error_state = error
|
||||||
self.onError.emit()
|
self.onError.emit()
|
||||||
|
|
||||||
## Private function to set the temperature of an extruder
|
|
||||||
# \param index index of the extruder
|
|
||||||
# \param temperature received temperature
|
|
||||||
def _setExtruderTemperature(self, index, temperature):
|
|
||||||
try:
|
|
||||||
self._extruder_temperatures[index] = temperature
|
|
||||||
self.extruderTemperatureChanged.emit()
|
|
||||||
except Exception as e:
|
|
||||||
Logger.log("d", "PrinterConnection._setExtruderTemperature: ", e)
|
|
||||||
pass
|
|
||||||
|
|
||||||
## 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):
|
|
||||||
self._bed_temperature = temperature
|
|
||||||
self.bedTemperatureChanged.emit()
|
|
||||||
|
|
||||||
def requestWrite(self, node, file_name = None, filter_by_machine = False):
|
def requestWrite(self, node, file_name = None, filter_by_machine = False):
|
||||||
self.showControlInterface()
|
self.showControlInterface()
|
||||||
|
|
||||||
@ -507,15 +396,14 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
Logger.log("i", "Printer connection listen thread started for %s" % self._serial_port)
|
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._connection_state == ConnectionState.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 time.time() > temperature_request_timeout:
|
if time.time() > temperature_request_timeout:
|
||||||
if self._extruder_count > 0:
|
if self._num_extruders > 0:
|
||||||
self._temperature_requested_extruder_index = (self._temperature_requested_extruder_index + 1) % self._extruder_count
|
self._temperature_requested_extruder_index = (self._temperature_requested_extruder_index + 1) % self._num_extruders
|
||||||
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")
|
||||||
@ -524,8 +412,8 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
if line.startswith(b"Error:"):
|
if line.startswith(b"Error:"):
|
||||||
# Oh YEAH, consistency.
|
# Oh YEAH, consistency.
|
||||||
# Marlin reports a MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
|
# Marlin reports a MIN/MAX temp error as "Error:x\n: Extruder switched off. MAXTEMP triggered !\n"
|
||||||
# But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!"
|
# But a bed temp error is reported as "Error: Temperature heated bed switched off. MAXTEMP triggered !!"
|
||||||
# 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()
|
||||||
|
|
||||||
@ -534,12 +422,12 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
if not self.hasError():
|
if not self.hasError():
|
||||||
self._setErrorState(line[6:])
|
self._setErrorState(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._setHotendTemperature(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)))
|
||||||
except Exception as e:
|
except Exception as e:
|
||||||
@ -551,7 +439,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
if self._is_printing:
|
if self._is_printing:
|
||||||
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 (basically, send next command)
|
||||||
|
|
||||||
if b"ok" in line:
|
if b"ok" in line:
|
||||||
ok_timeout = time.time() + 5
|
ok_timeout = time.time() + 5
|
||||||
@ -559,17 +447,17 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
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: # Because a resend can be asked with "resend" and "rs"
|
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:
|
||||||
if b"rs" in line:
|
if b"rs" in line:
|
||||||
self._gcode_position = int(line.split()[1])
|
self._gcode_position = int(line.split()[1])
|
||||||
|
|
||||||
else: # Request the temperature on comm timeout (every 2 seconds) when we are not printing.)
|
else: # Request the temperature on comm timeout (every 2 seconds) when we are not printing.)
|
||||||
if line == b"":
|
if line == b"":
|
||||||
if self._extruder_count > 0:
|
if self._num_extruders > 0:
|
||||||
self._temperature_requested_extruder_index = (self._temperature_requested_extruder_index + 1) % self._extruder_count
|
self._temperature_requested_extruder_index = (self._temperature_requested_extruder_index + 1) % self._num_extruders
|
||||||
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")
|
||||||
@ -588,7 +476,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
line = line.strip()
|
line = line.strip()
|
||||||
try:
|
try:
|
||||||
if line == "M0" or line == "M1":
|
if line == "M0" or line == "M1":
|
||||||
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:
|
||||||
@ -600,13 +488,13 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum))
|
self._sendCommand("N%d%s*%d" % (self._gcode_position, line, checksum))
|
||||||
self._gcode_position += 1
|
self._gcode_position += 1
|
||||||
self.setProgress(( self._gcode_position / len(self._gcode)) * 100)
|
self.setProgress((self._gcode_position / len(self._gcode)) * 100)
|
||||||
self.progressChanged.emit()
|
self.progressChanged.emit()
|
||||||
|
|
||||||
## Set the progress of the print.
|
## Set the progress of the print.
|
||||||
# It will be normalized (based on max_progress) to range 0 - 100
|
# 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.progressChanged.emit()
|
self.progressChanged.emit()
|
||||||
|
|
||||||
## Cancel the current print. Printer connection wil continue to listen.
|
## Cancel the current print. Printer connection wil continue to listen.
|
||||||
@ -623,7 +511,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
## Check if the process did not encounter an error yet.
|
## Check if the process did not encounter an error yet.
|
||||||
def hasError(self):
|
def hasError(self):
|
||||||
return self._error_state != None
|
return self._error_state is not None
|
||||||
|
|
||||||
## private read line used by printer connection to listen for data on serial port.
|
## private read line used by printer connection to listen for data on serial port.
|
||||||
def _readline(self):
|
def _readline(self):
|
||||||
@ -632,7 +520,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
try:
|
try:
|
||||||
ret = self._serial.readline()
|
ret = self._serial.readline()
|
||||||
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.close()
|
self.close()
|
||||||
return None
|
return None
|
||||||
@ -646,7 +534,7 @@ class PrinterConnection(OutputDevice, QObject, SignalEmitter):
|
|||||||
|
|
||||||
def _onFirmwareUpdateComplete(self):
|
def _onFirmwareUpdateComplete(self):
|
||||||
self._update_firmware_thread.join()
|
self._update_firmware_thread.join()
|
||||||
self._update_firmware_thread = threading.Thread(target= self._updateFirmware)
|
self._update_firmware_thread = threading.Thread(target = self._updateFirmware)
|
||||||
self._update_firmware_thread.daemon = True
|
self._update_firmware_thread.daemon = True
|
||||||
|
|
||||||
self.connect()
|
self.connect()
|
@ -2,12 +2,13 @@
|
|||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from UM.Signal import Signal, SignalEmitter
|
from UM.Signal import Signal, SignalEmitter
|
||||||
from . import PrinterConnection
|
from . import USBPrinterOutputDevice
|
||||||
from UM.Application import Application
|
from UM.Application import Application
|
||||||
from UM.Resources import Resources
|
from UM.Resources import Resources
|
||||||
from UM.Logger import Logger
|
from UM.Logger import Logger
|
||||||
from UM.PluginRegistry import PluginRegistry
|
from UM.PluginRegistry import PluginRegistry
|
||||||
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
from UM.OutputDevice.OutputDevicePlugin import OutputDevicePlugin
|
||||||
|
from cura.PrinterOutputDevice import ConnectionState
|
||||||
from UM.Qt.ListModel import ListModel
|
from UM.Qt.ListModel import ListModel
|
||||||
from UM.Message import Message
|
from UM.Message import Message
|
||||||
|
|
||||||
@ -20,21 +21,19 @@ import time
|
|||||||
import os.path
|
import os.path
|
||||||
from UM.Extension import Extension
|
from UM.Extension import Extension
|
||||||
|
|
||||||
from PyQt5.QtQuick import QQuickView
|
|
||||||
from PyQt5.QtQml import QQmlComponent, QQmlContext
|
from PyQt5.QtQml import QQmlComponent, QQmlContext
|
||||||
from PyQt5.QtCore import QUrl, QObject, pyqtSlot, pyqtProperty, pyqtSignal, Qt
|
from PyQt5.QtCore import QUrl, QObject, pyqtSlot, pyqtProperty, pyqtSignal, Qt
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
i18n_catalog = i18nCatalog("cura")
|
i18n_catalog = i18nCatalog("cura")
|
||||||
|
|
||||||
class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|
||||||
|
## Manager class that ensures that a usbPrinteroutput device is created for every connected USB printer.
|
||||||
|
class USBPrinterOutputDeviceManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
||||||
def __init__(self, parent = None):
|
def __init__(self, parent = None):
|
||||||
QObject.__init__(self, parent)
|
super().__init__(parent = parent)
|
||||||
SignalEmitter.__init__(self)
|
|
||||||
OutputDevicePlugin.__init__(self)
|
|
||||||
Extension.__init__(self)
|
|
||||||
self._serial_port_list = []
|
self._serial_port_list = []
|
||||||
self._printer_connections = {}
|
self._usb_output_devices = {}
|
||||||
self._printer_connections_model = None
|
self._usb_output_devices_model = None
|
||||||
self._update_thread = threading.Thread(target = self._updateThread)
|
self._update_thread = threading.Thread(target = self._updateThread)
|
||||||
self._update_thread.setDaemon(True)
|
self._update_thread.setDaemon(True)
|
||||||
|
|
||||||
@ -46,20 +45,20 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|||||||
self.addMenuItem(i18n_catalog.i18nc("@item:inmenu", "Update Firmware"), self.updateAllFirmware)
|
self.addMenuItem(i18n_catalog.i18nc("@item:inmenu", "Update Firmware"), self.updateAllFirmware)
|
||||||
|
|
||||||
Application.getInstance().applicationShuttingDown.connect(self.stop)
|
Application.getInstance().applicationShuttingDown.connect(self.stop)
|
||||||
self.addConnectionSignal.connect(self.addConnection) #Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
|
self.addUSBOutputDeviceSignal.connect(self.addOutputDevice) #Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
|
||||||
|
|
||||||
addConnectionSignal = Signal()
|
addUSBOutputDeviceSignal = Signal()
|
||||||
printerConnectionStateChanged = pyqtSignal()
|
connectionStateChanged = pyqtSignal()
|
||||||
|
|
||||||
progressChanged = pyqtSignal()
|
progressChanged = pyqtSignal()
|
||||||
|
|
||||||
@pyqtProperty(float, notify = progressChanged)
|
@pyqtProperty(float, notify = progressChanged)
|
||||||
def progress(self):
|
def progress(self):
|
||||||
progress = 0
|
progress = 0
|
||||||
for printer_name, connection in self._printer_connections.items(): # TODO: @UnusedVariable "printer_name"
|
for printer_name, device in self._usb_output_devices.items(): # TODO: @UnusedVariable "printer_name"
|
||||||
progress += connection.progress
|
progress += device.progress
|
||||||
|
|
||||||
return progress / len(self._printer_connections)
|
return progress / len(self._usb_output_devices)
|
||||||
|
|
||||||
def start(self):
|
def start(self):
|
||||||
self._check_updates = True
|
self._check_updates = True
|
||||||
@ -93,25 +92,25 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|||||||
|
|
||||||
@pyqtSlot()
|
@pyqtSlot()
|
||||||
def updateAllFirmware(self):
|
def updateAllFirmware(self):
|
||||||
if not self._printer_connections:
|
if not self._usb_output_devices:
|
||||||
Message(i18n_catalog.i18nc("@info","Cannot update firmware, there were no connected printers found.")).show()
|
Message(i18n_catalog.i18nc("@info","Cannot update firmware, there were no connected printers found.")).show()
|
||||||
return
|
return
|
||||||
|
|
||||||
self.spawnFirmwareInterface("")
|
self.spawnFirmwareInterface("")
|
||||||
for printer_connection in self._printer_connections:
|
for printer_connection in self._usb_output_devices:
|
||||||
try:
|
try:
|
||||||
self._printer_connections[printer_connection].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName()))
|
self._usb_output_devices[printer_connection].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName()))
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self._printer_connections[printer_connection].setProgress(100, 100)
|
self._usb_output_devices[printer_connection].setProgress(100, 100)
|
||||||
Logger.log("w", "No firmware found for printer %s", printer_connection)
|
Logger.log("w", "No firmware found for printer %s", printer_connection)
|
||||||
continue
|
continue
|
||||||
|
|
||||||
@pyqtSlot(str, result = bool)
|
@pyqtSlot(str, result = bool)
|
||||||
def updateFirmwareBySerial(self, serial_port):
|
def updateFirmwareBySerial(self, serial_port):
|
||||||
if serial_port in self._printer_connections:
|
if serial_port in self._usb_output_devices:
|
||||||
self.spawnFirmwareInterface(self._printer_connections[serial_port].getSerialPort())
|
self.spawnFirmwareInterface(self._usb_output_devices[serial_port].getSerialPort())
|
||||||
try:
|
try:
|
||||||
self._printer_connections[serial_port].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName()))
|
self._usb_output_devices[serial_port].updateFirmware(Resources.getPath(CuraApplication.ResourceTypes.Firmware, self._getDefaultFirmwareName()))
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
self._firmware_view.close()
|
self._firmware_view.close()
|
||||||
Logger.log("e", "Could not find firmware required for this machine")
|
Logger.log("e", "Could not find firmware required for this machine")
|
||||||
@ -123,10 +122,10 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|||||||
@classmethod
|
@classmethod
|
||||||
def getInstance(cls, engine = None, script_engine = None):
|
def getInstance(cls, engine = None, script_engine = None):
|
||||||
# Note: Explicit use of class name to prevent issues with inheritance.
|
# Note: Explicit use of class name to prevent issues with inheritance.
|
||||||
if USBPrinterManager._instance is None:
|
if USBPrinterOutputDeviceManager._instance is None:
|
||||||
USBPrinterManager._instance = cls()
|
USBPrinterOutputDeviceManager._instance = cls()
|
||||||
|
|
||||||
return USBPrinterManager._instance
|
return USBPrinterOutputDeviceManager._instance
|
||||||
|
|
||||||
def _getDefaultFirmwareName(self):
|
def _getDefaultFirmwareName(self):
|
||||||
machine_instance = Application.getInstance().getMachineManager().getActiveMachineInstance()
|
machine_instance = Application.getInstance().getMachineManager().getActiveMachineInstance()
|
||||||
@ -155,13 +154,13 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|||||||
|
|
||||||
##TODO: Add check for multiple extruders
|
##TODO: Add check for multiple extruders
|
||||||
hex_file = None
|
hex_file = None
|
||||||
if machine_type in machine_without_extras.keys(): # The machine needs to be defined here!
|
if machine_type in machine_without_extras.keys(): # The machine needs to be defined here!
|
||||||
if machine_type in machine_with_heated_bed.keys() and machine_instance.getMachineSettingValue("machine_heated_bed"):
|
if machine_type in machine_with_heated_bed.keys() and machine_instance.getMachineSettingValue("machine_heated_bed"):
|
||||||
Logger.log("d", "Choosing firmware with heated bed enabled for machine %s.", machine_type)
|
Logger.log("d", "Choosing firmware with heated bed enabled for machine %s.", machine_type)
|
||||||
hex_file = machine_with_heated_bed[machine_type] # Return firmware with heated bed enabled
|
hex_file = machine_with_heated_bed[machine_type] # Return firmware with heated bed enabled
|
||||||
else:
|
else:
|
||||||
Logger.log("d", "Choosing basic firmware for machine %s.", machine_type)
|
Logger.log("d", "Choosing basic firmware for machine %s.", machine_type)
|
||||||
hex_file = machine_without_extras[machine_type] # Return "basic" firmware
|
hex_file = machine_without_extras[machine_type] # Return "basic" firmware
|
||||||
else:
|
else:
|
||||||
Logger.log("e", "There is no firmware for machine %s.", machine_type)
|
Logger.log("e", "There is no firmware for machine %s.", machine_type)
|
||||||
|
|
||||||
@ -171,48 +170,53 @@ class USBPrinterManager(QObject, SignalEmitter, OutputDevicePlugin, Extension):
|
|||||||
Logger.log("e", "Could not find any firmware for machine %s.", machine_type)
|
Logger.log("e", "Could not find any firmware for machine %s.", machine_type)
|
||||||
raise FileNotFoundError()
|
raise FileNotFoundError()
|
||||||
|
|
||||||
|
## Helper to identify serial ports (and scan for them)
|
||||||
def _addRemovePorts(self, serial_ports):
|
def _addRemovePorts(self, serial_ports):
|
||||||
# First, find and add all new or changed keys
|
# First, find and add all new or changed keys
|
||||||
for serial_port in list(serial_ports):
|
for serial_port in list(serial_ports):
|
||||||
if serial_port not in self._serial_port_list:
|
if serial_port not in self._serial_port_list:
|
||||||
self.addConnectionSignal.emit(serial_port) #Hack to ensure its created in main thread
|
self.addUSBOutputDeviceSignal.emit(serial_port) # Hack to ensure its created in main thread
|
||||||
continue
|
continue
|
||||||
self._serial_port_list = list(serial_ports)
|
self._serial_port_list = list(serial_ports)
|
||||||
|
|
||||||
connections_to_remove = []
|
devices_to_remove = []
|
||||||
for port, connection in self._printer_connections.items():
|
for port, device in self._usb_output_devices.items():
|
||||||
if port not in self._serial_port_list:
|
if port not in self._serial_port_list:
|
||||||
connection.close()
|
device.close()
|
||||||
connections_to_remove.append(port)
|
devices_to_remove.append(port)
|
||||||
|
|
||||||
for port in connections_to_remove:
|
|
||||||
del self._printer_connections[port]
|
|
||||||
|
|
||||||
|
for port in devices_to_remove:
|
||||||
|
del self._usb_output_devices[port]
|
||||||
|
|
||||||
## Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
|
## Because the model needs to be created in the same thread as the QMLEngine, we use a signal.
|
||||||
def addConnection(self, serial_port):
|
def addOutputDevice(self, serial_port):
|
||||||
connection = PrinterConnection.PrinterConnection(serial_port)
|
device = USBPrinterOutputDevice.USBPrinterOutputDevice(serial_port)
|
||||||
connection.connect()
|
device.connectionStateChanged.connect(self._onConnectionStateChanged)
|
||||||
connection.connectionStateChanged.connect(self._onPrinterConnectionStateChanged)
|
device.connect()
|
||||||
connection.progressChanged.connect(self.progressChanged)
|
device.progressChanged.connect(self.progressChanged)
|
||||||
self._printer_connections[serial_port] = connection
|
self._usb_output_devices[serial_port] = device
|
||||||
|
|
||||||
def _onPrinterConnectionStateChanged(self, serial_port):
|
## If one of the states of the connected devices change, we might need to add / remove them from the global list.
|
||||||
if self._printer_connections[serial_port].isConnected():
|
def _onConnectionStateChanged(self, serial_port):
|
||||||
self.getOutputDeviceManager().addOutputDevice(self._printer_connections[serial_port])
|
try:
|
||||||
else:
|
if self._usb_output_devices[serial_port].connectionState == ConnectionState.connected:
|
||||||
self.getOutputDeviceManager().removeOutputDevice(serial_port)
|
self.getOutputDeviceManager().addOutputDevice(self._usb_output_devices[serial_port])
|
||||||
self.printerConnectionStateChanged.emit()
|
else:
|
||||||
|
self.getOutputDeviceManager().removeOutputDevice(serial_port)
|
||||||
|
self.connectionStateChanged.emit()
|
||||||
|
except KeyError:
|
||||||
|
pass # no output device by this device_id found in connection list.
|
||||||
|
|
||||||
@pyqtProperty(QObject , notify = printerConnectionStateChanged)
|
|
||||||
|
@pyqtProperty(QObject , notify = connectionStateChanged)
|
||||||
def connectedPrinterList(self):
|
def connectedPrinterList(self):
|
||||||
self._printer_connections_model = ListModel()
|
self._usb_output_devices_model = ListModel()
|
||||||
self._printer_connections_model.addRoleName(Qt.UserRole + 1,"name")
|
self._usb_output_devices_model.addRoleName(Qt.UserRole + 1, "name")
|
||||||
self._printer_connections_model.addRoleName(Qt.UserRole + 2, "printer")
|
self._usb_output_devices_model.addRoleName(Qt.UserRole + 2, "printer")
|
||||||
for connection in self._printer_connections:
|
for connection in self._usb_output_devices:
|
||||||
if self._printer_connections[connection].isConnected():
|
if self._usb_output_devices[connection].connectionState == ConnectionState.connected:
|
||||||
self._printer_connections_model.appendItem({"name":connection, "printer": self._printer_connections[connection]})
|
self._usb_output_devices_model.appendItem({"name": connection, "printer": self._usb_output_devices[connection]})
|
||||||
return self._printer_connections_model
|
return self._usb_output_devices_model
|
||||||
|
|
||||||
## Create a list of serial ports on the system.
|
## Create a list of serial ports on the system.
|
||||||
# \param only_list_usb If true, only usb ports are listed
|
# \param only_list_usb If true, only usb ports are listed
|
@ -1,7 +1,7 @@
|
|||||||
# Copyright (c) 2015 Ultimaker B.V.
|
# Copyright (c) 2015 Ultimaker B.V.
|
||||||
# Cura is released under the terms of the AGPLv3 or higher.
|
# Cura is released under the terms of the AGPLv3 or higher.
|
||||||
|
|
||||||
from . import USBPrinterManager
|
from . import USBPrinterOutputDeviceManager
|
||||||
from PyQt5.QtQml import qmlRegisterType, qmlRegisterSingletonType
|
from PyQt5.QtQml import qmlRegisterType, qmlRegisterSingletonType
|
||||||
from UM.i18n import i18nCatalog
|
from UM.i18n import i18nCatalog
|
||||||
i18n_catalog = i18nCatalog("cura")
|
i18n_catalog = i18nCatalog("cura")
|
||||||
@ -19,5 +19,7 @@ def getMetaData():
|
|||||||
}
|
}
|
||||||
|
|
||||||
def register(app):
|
def register(app):
|
||||||
qmlRegisterSingletonType(USBPrinterManager.USBPrinterManager, "UM", 1, 0, "USBPrinterManager", USBPrinterManager.USBPrinterManager.getInstance)
|
# We are violating the QT API here (as we use a factory, which is technically not allowed).
|
||||||
return {"extension":USBPrinterManager.USBPrinterManager.getInstance(),"output_device": USBPrinterManager.USBPrinterManager.getInstance() }
|
# but we don't really have another means for doing this (and it seems to you know -work-)
|
||||||
|
qmlRegisterSingletonType(USBPrinterOutputDeviceManager.USBPrinterOutputDeviceManager, "Cura", 1, 0, "USBPrinterManager", USBPrinterOutputDeviceManager.USBPrinterOutputDeviceManager.getInstance)
|
||||||
|
return {"extension":USBPrinterOutputDeviceManager.USBPrinterOutputDeviceManager.getInstance(), "output_device": USBPrinterOutputDeviceManager.USBPrinterOutputDeviceManager.getInstance()}
|
||||||
|
@ -18,11 +18,11 @@ Item
|
|||||||
property int platform_width: UM.MachineManager.getSettingValue("machine_width")
|
property int platform_width: UM.MachineManager.getSettingValue("machine_width")
|
||||||
property int platform_height: UM.MachineManager.getSettingValue("machine_depth")
|
property int platform_height: UM.MachineManager.getSettingValue("machine_depth")
|
||||||
anchors.fill: parent;
|
anchors.fill: parent;
|
||||||
property variant printer_connection: UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
property variant printer_connection: Cura.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
||||||
Component.onCompleted:
|
Component.onCompleted:
|
||||||
{
|
{
|
||||||
printer_connection.homeBed()
|
printer_connection.homeBed()
|
||||||
printer_connection.moveHeadRelative(0, 0, 3)
|
printer_connection.moveHead(0, 0, 3)
|
||||||
printer_connection.homeHead()
|
printer_connection.homeHead()
|
||||||
}
|
}
|
||||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||||
@ -73,23 +73,23 @@ Item
|
|||||||
{
|
{
|
||||||
if(wizardPage.leveling_state == 0)
|
if(wizardPage.leveling_state == 0)
|
||||||
{
|
{
|
||||||
printer_connection.moveHeadRelative(0, 0, 3)
|
printer_connection.moveHead(0, 0, 3)
|
||||||
printer_connection.homeHead()
|
printer_connection.homeHead()
|
||||||
printer_connection.moveHeadRelative(0, 0, 3)
|
printer_connection.moveHead(0, 0, 3)
|
||||||
printer_connection.moveHeadRelative(platform_width - 10, 0, 0)
|
printer_connection.moveHead(platform_width - 10, 0, 0)
|
||||||
printer_connection.moveHeadRelative(0, 0, -3)
|
printer_connection.moveHead(0, 0, -3)
|
||||||
}
|
}
|
||||||
if(wizardPage.leveling_state == 1)
|
if(wizardPage.leveling_state == 1)
|
||||||
{
|
{
|
||||||
printer_connection.moveHeadRelative(0, 0, 3)
|
printer_connection.moveHead(0, 0, 3)
|
||||||
printer_connection.moveHeadRelative(-platform_width/2, platform_height - 10, 0)
|
printer_connection.moveHead(-platform_width/2, platform_height - 10, 0)
|
||||||
printer_connection.moveHeadRelative(0, 0, -3)
|
printer_connection.moveHead(0, 0, -3)
|
||||||
}
|
}
|
||||||
if(wizardPage.leveling_state == 2)
|
if(wizardPage.leveling_state == 2)
|
||||||
{
|
{
|
||||||
printer_connection.moveHeadRelative(0, 0, 3)
|
printer_connection.moveHead(0, 0, 3)
|
||||||
printer_connection.moveHeadRelative(-platform_width/2 + 10, -(platform_height + 10), 0)
|
printer_connection.moveHead(-platform_width/2 + 10, -(platform_height + 10), 0)
|
||||||
printer_connection.moveHeadRelative(0, 0, -3)
|
printer_connection.moveHead(0, 0, -3)
|
||||||
}
|
}
|
||||||
wizardPage.leveling_state++
|
wizardPage.leveling_state++
|
||||||
if (wizardPage.leveling_state >= 3){
|
if (wizardPage.leveling_state >= 3){
|
||||||
|
@ -31,9 +31,9 @@ Item
|
|||||||
}
|
}
|
||||||
|
|
||||||
property variant printer_connection: {
|
property variant printer_connection: {
|
||||||
if (UM.USBPrinterManager.connectedPrinterList.rowCount() != 0){
|
if (Cura.USBPrinterManager.connectedPrinterList.rowCount() != 0){
|
||||||
wizardPage.checkupProgress.connection = true
|
wizardPage.checkupProgress.connection = true
|
||||||
return UM.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
return Cura.USBPrinterManager.connectedPrinterList.getItem(0).printer
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
return null
|
return null
|
||||||
@ -140,7 +140,7 @@ Item
|
|||||||
anchors.left: connectionLabel.right
|
anchors.left: connectionLabel.right
|
||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: UM.USBPrinterManager.connectedPrinterList.rowCount() > 0 || base.addOriginalProgress.checkUp[0] ? catalog.i18nc("@info:status","Done"):catalog.i18nc("@info:status","Incomplete")
|
text: Cura.USBPrinterManager.connectedPrinterList.rowCount() > 0 || base.addOriginalProgress.checkUp[0] ? catalog.i18nc("@info:status","Done"):catalog.i18nc("@info:status","Incomplete")
|
||||||
}
|
}
|
||||||
//////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////
|
||||||
Label
|
Label
|
||||||
@ -237,7 +237,7 @@ Item
|
|||||||
if(printer_connection != null)
|
if(printer_connection != null)
|
||||||
{
|
{
|
||||||
nozzleTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
nozzleTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
||||||
printer_connection.heatupNozzle(190)
|
printer_connection.setTargetHotendTemperature(0, 190)
|
||||||
wizardPage.extruder_target_temp = 190
|
wizardPage.extruder_target_temp = 190
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -251,7 +251,7 @@ Item
|
|||||||
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
anchors.leftMargin: UM.Theme.getSize("default_margin").width
|
||||||
width: wizardPage.rightRow * 0.2
|
width: wizardPage.rightRow * 0.2
|
||||||
wrapMode: Text.WordWrap
|
wrapMode: Text.WordWrap
|
||||||
text: printer_connection != null ? printer_connection.extruderTemperature + "°C" : "0°C"
|
text: printer_connection != null ? printer_connection.hotendTemperatures[0] + "°C" : "0°C"
|
||||||
font.bold: true
|
font.bold: true
|
||||||
}
|
}
|
||||||
/////////////////////////////////////////////////////////////////////////////
|
/////////////////////////////////////////////////////////////////////////////
|
||||||
@ -293,7 +293,7 @@ Item
|
|||||||
if(printer_connection != null)
|
if(printer_connection != null)
|
||||||
{
|
{
|
||||||
bedTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
bedTempStatus.text = catalog.i18nc("@info:progress","Checking")
|
||||||
printer_connection.heatupBed(60)
|
printer_connection.setTargetBedTemperature(60)
|
||||||
wizardPage.bed_target_temp = 60
|
wizardPage.bed_target_temp = 60
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -346,16 +346,16 @@ Item
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
onExtruderTemperatureChanged:
|
onHotendTemperaturesChanged:
|
||||||
{
|
{
|
||||||
if(printer_connection.extruderTemperature > wizardPage.extruder_target_temp - 10 && printer_connection.extruderTemperature < wizardPage.extruder_target_temp + 10)
|
if(printer_connection.hotendTemperatures[0] > wizardPage.extruder_target_temp - 10 && printer_connection.hotendTemperatures[0] < wizardPage.extruder_target_temp + 10)
|
||||||
{
|
{
|
||||||
if(printer_connection != null)
|
if(printer_connection != null)
|
||||||
{
|
{
|
||||||
nozzleTempStatus.text = catalog.i18nc("@info:status","Works")
|
nozzleTempStatus.text = catalog.i18nc("@info:status","Works")
|
||||||
wizardPage.checkupProgress.nozzleTemp = true
|
wizardPage.checkupProgress.nozzleTemp = true
|
||||||
checkTotalCheckUp()
|
checkTotalCheckUp()
|
||||||
printer_connection.heatupNozzle(0)
|
printer_connection.setTargetHotendTemperature(0, 0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -366,7 +366,7 @@ Item
|
|||||||
bedTempStatus.text = catalog.i18nc("@info:status","Works")
|
bedTempStatus.text = catalog.i18nc("@info:status","Works")
|
||||||
wizardPage.checkupProgress.bedTemp = true
|
wizardPage.checkupProgress.bedTemp = true
|
||||||
checkTotalCheckUp()
|
checkTotalCheckUp()
|
||||||
printer_connection.heatupBed(0)
|
printer_connection.setTargetBedTemperature(0)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,7 +14,7 @@ Item
|
|||||||
|
|
||||||
SystemPalette{id: palette}
|
SystemPalette{id: palette}
|
||||||
UM.I18nCatalog { id: catalog; name:"cura"}
|
UM.I18nCatalog { id: catalog; name:"cura"}
|
||||||
property variant printer_connection: UM.USBPrinterManager.connectedPrinterList.rowCount() != 0 ? UM.USBPrinterManager.connectedPrinterList.getItem(0).printer : null
|
property variant printer_connection: Cura.USBPrinterManager.connectedPrinterList.rowCount() != 0 ? Cura.USBPrinterManager.connectedPrinterList.getItem(0).printer : null
|
||||||
Label
|
Label
|
||||||
{
|
{
|
||||||
id: pageTitle
|
id: pageTitle
|
||||||
@ -62,7 +62,7 @@ Item
|
|||||||
anchors.top: parent.top
|
anchors.top: parent.top
|
||||||
anchors.left: parent.left
|
anchors.left: parent.left
|
||||||
text: catalog.i18nc("@action:button","Upgrade to Marlin Firmware");
|
text: catalog.i18nc("@action:button","Upgrade to Marlin Firmware");
|
||||||
onClicked: UM.USBPrinterManager.updateAllFirmware()
|
onClicked: Cura.USBPrinterManager.updateAllFirmware()
|
||||||
}
|
}
|
||||||
Button {
|
Button {
|
||||||
id: skipUpgradeButton
|
id: skipUpgradeButton
|
||||||
|
Loading…
x
Reference in New Issue
Block a user