1 __copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
11 from Cura.util import machineCom
12 from Cura.util.printerConnection import printerConnectionBase
14 class serialConnectionGroup(printerConnectionBase.printerConnectionGroup):
16 super(serialConnectionGroup, self).__init__("USB")
17 self._connectionMap = {}
19 def getAvailableConnections(self):
20 serialList = machineCom.serialList(True)
21 for port in machineCom.serialList(True):
22 if port not in self._connectionMap:
23 self._connectionMap[port] = serialConnection(port)
24 for key in self._connectionMap.keys():
25 if key not in serialList and not self._connectionMap[key].isActiveConnectionOpen():
26 self._connectionMap.pop(key)
27 return self._connectionMap.values()
32 def getPriority(self):
35 class serialConnection(printerConnectionBase.printerConnectionBase):
36 def __init__(self, port):
37 super(serialConnection, self).__init__(port)
43 self._temperature = []
46 self._commState = None
47 self._commStateString = None
50 #Load the data into memory for printing, returns True on success
51 def loadGCodeData(self, dataStream):
52 if self.isPrinting() is None:
55 for line in dataStream:
56 #Strip out comments, we do not need to send comments
58 line = line[:line.index(';')]
59 #Strip out whitespace at the beginning/end this saves data to send.
64 self._gcodeData.append(line)
67 #Start printing the previously loaded file
69 if self.isPrinting() or len(self._gcodeData) < 1 or self._process is None:
71 self._process.stdin.write('STOP\n')
72 for line in self._gcodeData:
73 self._process.stdin.write('G:%s\n' % (line))
74 self._process.stdin.write('START\n')
76 #Abort the previously loaded print file
77 def cancelPrint(self):
81 return self._commState == machineCom.MachineCom.STATE_PRINTING
83 #Amount of progression of the current print file. 0.0 to 1.0
84 def getPrintProgress(self):
85 if self._lineCount < 1:
87 return float(self._progressLine) / float(self._lineCount)
89 # Return if the printer with this connection type is available
90 def isAvailable(self):
93 # Get the connection status string. This is displayed to the user and can be used to communicate
94 # various information to the user.
95 def getStatusString(self):
96 return "%s" % (self._commStateString)
98 #Returns true if we need to establish an active connection. True for serial connections.
99 def hasActiveConnection(self):
102 #Open the active connection to the printer so we can send commands
103 def openActiveConnection(self):
104 self.closeActiveConnection()
105 self._thread = threading.Thread(target=self._serialCommunicationThread)
106 self._thread.daemon = True
109 #Close the active connection to the printer
110 def closeActiveConnection(self):
111 if self._process is not None:
112 self._process.terminate()
115 #Is the active connection open right now.
116 def isActiveConnectionOpen(self):
117 if self._process is None:
119 return self._commState == machineCom.MachineCom.STATE_OPERATIONAL or self._commState == machineCom.MachineCom.STATE_PRINTING or self._commState == machineCom.MachineCom.STATE_PAUSED
121 def getTemperature(self, extruder):
122 if extruder >= len(self._temperature):
124 return self._temperature[extruder]
126 def _serialCommunicationThread(self):
127 if platform.system() == "Darwin" and hasattr(sys, 'frozen'):
128 cmdList = [os.path.join(os.path.dirname(sys.executable), 'Cura')]
130 cmdList = [sys.executable, '-m', 'Cura.serialCommunication']
131 cmdList += [self._portName]
132 if platform.system() == "Darwin":
133 if platform.machine() == 'i386':
134 cmdList = ['arch', '-i386'] + cmdList
135 self._process = subprocess.Popen(cmdList, stdin=subprocess.PIPE, stdout=subprocess.PIPE)
136 line = self._process.stdout.readline()
139 line = line.split(':', 1)
142 elif line[0] == 'temp':
143 line = line[1].split(':', 1)
144 self._temperature = json.loads(line[0])
146 elif line[0] == 'message':
147 self._doCallback(line[1])
148 elif line[0] == 'state':
149 line = line[1].split(':', 1)
150 self._commState = int(line[0])
151 self._commStateString = line[1]
155 line = self._process.stdout.readline()