Design exceeds the working area.
@@ -241,11 +242,12 @@
0,0
-
- 100%
- 0°
-
+ 0°
+
+ 0mm
+
+ 0mm
Design exceeds the working area.
diff --git a/src/octoprint/util/comm_acc.py b/src/octoprint/util/comm_acc.py
index 2646e13d..025a6f16 100644
--- a/src/octoprint/util/comm_acc.py
+++ b/src/octoprint/util/comm_acc.py
@@ -4,7 +4,6 @@ __author__ = "Gina Häußge based on work by David Braam"
__license__ = "GNU Affero General Public License http://www.gnu.org/licenses/agpl.html"
__copyright__ = "Copyright (C) 2013 David Braam - Released under terms of the AGPLv3 License"
-
import os
import glob
import time
@@ -415,13 +414,14 @@ class MachineCom(object):
if self._temperature_timer is not None:
try:
self._temperature_timer.cancel()
- except:
+ self._temperature_timer = None
+ except AttributeError:
pass
if self._sd_status_timer is not None:
try:
self._sd_status_timer.cancel()
- except:
+ except AttributeError:
pass
self._monitoring_active = False
@@ -462,6 +462,38 @@ class MachineCom(object):
cmd = process_gcode_line(cmd)
if not cmd:
return
+
+ if cmd[0] == "/":
+ specialcmd = cmd[1:].lower()
+ if "togglestatusreport" in specialcmd:
+ if self._temperature_timer is None:
+ self._temperature_timer = RepeatedTimer(1, self._poll_temperature, run_first=True)
+ self._temperature_timer.start()
+ else:
+ self._temperature_timer.cancel()
+ self._temperature_timer = None
+ elif "setstatusfrequency" in specialcmd:
+ data = specialcmd.split(' ')
+ try:
+ frequency = float(data[1])
+ except ValueError:
+ self._log("No frequency setting found! Using 1 sec.")
+ frequency = 1
+ if self._temperature_timer is not None:
+ self._temperature_timer.cancel()
+
+ self._temperature_timer = RepeatedTimer(frequency, self._poll_temperature, run_first=True)
+ self._temperature_timer.start()
+ elif "disconnect" in specialcmd:
+ self.close()
+ else:
+ self._log("Command not Found! %s" % cmd)
+ self._log("available commands are:")
+ self._log(" /togglestatusreport")
+ self._log(" /setstatusfrequency ")
+ self._log(" /disconnect")
+ return
+
eepromCmd = re.search("^\$[0-9]+=.+$", cmd)
if(eepromCmd and self.isPrinting()):
self._log("Warning: Configuration changes during print are not allowed!")
@@ -873,6 +905,8 @@ class MachineCom(object):
pathToGrblHex = cwd + "/../grbl/grbl.hex"
import subprocess
+ # TODO check if avrdude is installed.
+ # TODO log in logfile as well, not only to the serial monitor (use self._logger.info()... )
params = ["avrdude", "-patmega328p", "-carduino", "-b" + str(self._baudrate), "-P" + str(self._port), "-D", "-Uflash:w:" + pathToGrblHex]
returnCode = subprocess.call(params)
@@ -955,7 +989,7 @@ class MachineCom(object):
continue
##~~ Error handling
- line = self._handleErrors(line)
+ #line = self._handleErrors(line)
# GRBL Position update
if self._grbl :
@@ -1026,154 +1060,154 @@ class MachineCom(object):
if("error:" in line):
self.handle_grbl_error(line)
- ##~~ SD file list
- # if we are currently receiving an sd file list, each line is just a filename, so just read it and abort processing
- if self._sdFileList and not "End file list" in line:
- preprocessed_line = line.strip().lower()
- fileinfo = preprocessed_line.rsplit(None, 1)
- if len(fileinfo) > 1:
- # we might have extended file information here, so let's split filename and size and try to make them a bit nicer
- filename, size = fileinfo
- try:
- size = int(size)
- except ValueError:
- # whatever that was, it was not an integer, so we'll just use the whole line as filename and set size to None
- filename = preprocessed_line
- size = None
- else:
- # no extended file information, so only the filename is there and we set size to None
- filename = preprocessed_line
- size = None
-
- if valid_file_type(filename, "machinecode"):
- if filter_non_ascii(filename):
- self._logger.warn("Got a file from printer's SD that has a non-ascii filename (%s), that shouldn't happen according to the protocol" % filename)
- else:
- if not filename.startswith("/"):
- # file from the root of the sd -- we'll prepend a /
- filename = "/" + filename
- self._sdFiles.append((filename, size))
- continue
+# ##~~ SD file list
+# # if we are currently receiving an sd file list, each line is just a filename, so just read it and abort processing
+# if self._sdFileList and not "End file list" in line:
+# preprocessed_line = line.strip().lower()
+# fileinfo = preprocessed_line.rsplit(None, 1)
+# if len(fileinfo) > 1:
+# # we might have extended file information here, so let's split filename and size and try to make them a bit nicer
+# filename, size = fileinfo
+# try:
+# size = int(size)
+# except ValueError:
+# # whatever that was, it was not an integer, so we'll just use the whole line as filename and set size to None
+# filename = preprocessed_line
+# size = None
+# else:
+# # no extended file information, so only the filename is there and we set size to None
+# filename = preprocessed_line
+# size = None
+#
+# if valid_file_type(filename, "machinecode"):
+# if filter_non_ascii(filename):
+# self._logger.warn("Got a file from printer's SD that has a non-ascii filename (%s), that shouldn't happen according to the protocol" % filename)
+# else:
+# if not filename.startswith("/"):
+# # file from the root of the sd -- we'll prepend a /
+# filename = "/" + filename
+# self._sdFiles.append((filename, size))
+# continue
##~~ process oks
if line.strip().startswith("ok") or (self.isPrinting() and supportWait and line.strip().startswith("wait")):
self._clear_to_send.set()
self._long_running_command = False
- ##~~ Temperature processing
- if ' T:' in line or line.startswith('T:') or ' T0:' in line or line.startswith('T0:') or ' B:' in line or line.startswith('B:'):
- if not disable_external_heatup_detection and not line.strip().startswith("ok") and not self._heating:
- self._logger.debug("Externally triggered heatup detected")
- self._heating = True
- self._heatupWaitStartTime = time.time()
- self._processTemperatures(line)
- self._callback.on_comm_temperature_update(self._temp, self._bedTemp)
+# ##~~ Temperature processing
+# if ' T:' in line or line.startswith('T:') or ' T0:' in line or line.startswith('T0:') or ' B:' in line or line.startswith('B:'):
+# if not disable_external_heatup_detection and not line.strip().startswith("ok") and not self._heating:
+# self._logger.debug("Externally triggered heatup detected")
+# self._heating = True
+# self._heatupWaitStartTime = time.time()
+# self._processTemperatures(line)
+# self._callback.on_comm_temperature_update(self._temp, self._bedTemp)
+#
+# elif supportRepetierTargetTemp and ('TargetExtr' in line or 'TargetBed' in line):
+# matchExtr = self._regex_repetierTempExtr.match(line)
+# matchBed = self._regex_repetierTempBed.match(line)
+#
+# if matchExtr is not None:
+# toolNum = int(matchExtr.group(1))
+# try:
+# target = float(matchExtr.group(2))
+# if toolNum in self._temp.keys() and self._temp[toolNum] is not None and isinstance(self._temp[toolNum], tuple):
+# (actual, oldTarget) = self._temp[toolNum]
+# self._temp[toolNum] = (actual, target)
+# else:
+# self._temp[toolNum] = (None, target)
+# self._callback.on_comm_temperature_update(self._temp, self._bedTemp)
+# except ValueError:
+# pass
+# elif matchBed is not None:
+# try:
+# target = float(matchBed.group(1))
+# if self._bedTemp is not None and isinstance(self._bedTemp, tuple):
+# (actual, oldTarget) = self._bedTemp
+# self._bedTemp = (actual, target)
+# else:
+# self._bedTemp = (None, target)
+# self._callback.on_comm_temperature_update(self._temp, self._bedTemp)
+# except ValueError:
+# pass
- elif supportRepetierTargetTemp and ('TargetExtr' in line or 'TargetBed' in line):
- matchExtr = self._regex_repetierTempExtr.match(line)
- matchBed = self._regex_repetierTempBed.match(line)
+# #If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
+# if 'ok' in line and self._heatupWaitStartTime:
+# self._heatupWaitTimeLost = self._heatupWaitTimeLost + (time.time() - self._heatupWaitStartTime)
+# self._heatupWaitStartTime = None
+# self._heating = False
- if matchExtr is not None:
- toolNum = int(matchExtr.group(1))
- try:
- target = float(matchExtr.group(2))
- if toolNum in self._temp.keys() and self._temp[toolNum] is not None and isinstance(self._temp[toolNum], tuple):
- (actual, oldTarget) = self._temp[toolNum]
- self._temp[toolNum] = (actual, target)
- else:
- self._temp[toolNum] = (None, target)
- self._callback.on_comm_temperature_update(self._temp, self._bedTemp)
- except ValueError:
- pass
- elif matchBed is not None:
- try:
- target = float(matchBed.group(1))
- if self._bedTemp is not None and isinstance(self._bedTemp, tuple):
- (actual, oldTarget) = self._bedTemp
- self._bedTemp = (actual, target)
- else:
- self._bedTemp = (None, target)
- self._callback.on_comm_temperature_update(self._temp, self._bedTemp)
- except ValueError:
- pass
-
- #If we are waiting for an M109 or M190 then measure the time we lost during heatup, so we can remove that time from our printing time estimate.
- if 'ok' in line and self._heatupWaitStartTime:
- self._heatupWaitTimeLost = self._heatupWaitTimeLost + (time.time() - self._heatupWaitStartTime)
- self._heatupWaitStartTime = None
- self._heating = False
-
- ##~~ SD Card handling
- elif 'SD init fail' in line or 'volume.init failed' in line or 'openRoot failed' in line:
- self._sdAvailable = False
- self._sdFiles = []
- self._callback.on_comm_sd_state_change(self._sdAvailable)
- elif 'Not SD printing' in line:
- if self.isSdFileSelected() and self.isPrinting():
- # something went wrong, printer is reporting that we actually are not printing right now...
- self._sdFilePos = 0
- self._changeState(self.STATE_OPERATIONAL)
- elif 'SD card ok' in line and not self._sdAvailable:
- self._sdAvailable = True
- self.refreshSdFiles()
- self._callback.on_comm_sd_state_change(self._sdAvailable)
- elif 'Begin file list' in line:
- self._sdFiles = []
- self._sdFileList = True
- elif 'End file list' in line:
- self._sdFileList = False
- self._callback.on_comm_sd_files(self._sdFiles)
- elif 'SD printing byte' in line and self.isSdPrinting():
- # answer to M27, at least on Marlin, Repetier and Sprinter: "SD printing byte %d/%d"
- match = self._regex_sdPrintingByte.search(line)
- self._currentFile.setFilepos(int(match.group(1)))
- self._callback.on_comm_progress()
- elif 'File opened' in line and not self._ignore_select:
- # answer to M23, at least on Marlin, Repetier and Sprinter: "File opened:%s Size:%d"
- match = self._regex_sdFileOpened.search(line)
- if self._sdFileToSelect:
- name = self._sdFileToSelect
- self._sdFileToSelect = None
- else:
- name = match.group(1)
- self._currentFile = PrintingSdFileInformation(name, int(match.group(2)))
- elif 'File selected' in line:
- if self._ignore_select:
- self._ignore_select = False
- elif self._currentFile is not None:
- # final answer to M23, at least on Marlin, Repetier and Sprinter: "File selected"
- self._callback.on_comm_file_selected(self._currentFile.getFilename(), self._currentFile.getFilesize(), True)
- eventManager().fire(Events.FILE_SELECTED, {
- "file": self._currentFile.getFilename(),
- "origin": self._currentFile.getFileLocation()
- })
- elif 'Writing to file' in line:
- # anwer to M28, at least on Marlin, Repetier and Sprinter: "Writing to file: %s"
- self._changeState(self.STATE_PRINTING)
- self._clear_to_send.set()
- line = "ok"
- elif 'Done printing file' in line and self.isSdPrinting():
- # printer is reporting file finished printing
- self._sdFilePos = 0
- self._callback.on_comm_print_job_done()
- self._changeState(self.STATE_OPERATIONAL)
- eventManager().fire(Events.PRINT_DONE, {
- "file": self._currentFile.getFilename(),
- "filename": os.path.basename(self._currentFile.getFilename()),
- "origin": self._currentFile.getFileLocation(),
- "time": self.getPrintTime()
- })
- if self._sd_status_timer is not None:
- try:
- self._sd_status_timer.cancel()
- except:
- pass
- elif 'Done saving file' in line:
- self.refreshSdFiles()
- elif 'File deleted' in line and line.strip().endswith("ok"):
- # buggy Marlin version that doesn't send a proper \r after the "File deleted" statement, fixed in
- # current versions
- self._clear_to_send.set()
+# ##~~ SD Card handling
+# elif 'SD init fail' in line or 'volume.init failed' in line or 'openRoot failed' in line:
+# self._sdAvailable = False
+# self._sdFiles = []
+# self._callback.on_comm_sd_state_change(self._sdAvailable)
+# elif 'Not SD printing' in line:
+# if self.isSdFileSelected() and self.isPrinting():
+# # something went wrong, printer is reporting that we actually are not printing right now...
+# self._sdFilePos = 0
+# self._changeState(self.STATE_OPERATIONAL)
+# elif 'SD card ok' in line and not self._sdAvailable:
+# self._sdAvailable = True
+# self.refreshSdFiles()
+# self._callback.on_comm_sd_state_change(self._sdAvailable)
+# elif 'Begin file list' in line:
+# self._sdFiles = []
+# self._sdFileList = True
+# elif 'End file list' in line:
+# self._sdFileList = False
+# self._callback.on_comm_sd_files(self._sdFiles)
+# elif 'SD printing byte' in line and self.isSdPrinting():
+# # answer to M27, at least on Marlin, Repetier and Sprinter: "SD printing byte %d/%d"
+# match = self._regex_sdPrintingByte.search(line)
+# self._currentFile.setFilepos(int(match.group(1)))
+# self._callback.on_comm_progress()
+# elif 'File opened' in line and not self._ignore_select:
+# # answer to M23, at least on Marlin, Repetier and Sprinter: "File opened:%s Size:%d"
+# match = self._regex_sdFileOpened.search(line)
+# if self._sdFileToSelect:
+# name = self._sdFileToSelect
+# self._sdFileToSelect = None
+# else:
+# name = match.group(1)
+# self._currentFile = PrintingSdFileInformation(name, int(match.group(2)))
+# elif 'File selected' in line:
+# if self._ignore_select:
+# self._ignore_select = False
+# elif self._currentFile is not None:
+# # final answer to M23, at least on Marlin, Repetier and Sprinter: "File selected"
+# self._callback.on_comm_file_selected(self._currentFile.getFilename(), self._currentFile.getFilesize(), True)
+# eventManager().fire(Events.FILE_SELECTED, {
+# "file": self._currentFile.getFilename(),
+# "origin": self._currentFile.getFileLocation()
+# })
+# elif 'Writing to file' in line:
+# # anwer to M28, at least on Marlin, Repetier and Sprinter: "Writing to file: %s"
+# self._changeState(self.STATE_PRINTING)
+# self._clear_to_send.set()
+# line = "ok"
+# elif 'Done printing file' in line and self.isSdPrinting():
+# # printer is reporting file finished printing
+# self._sdFilePos = 0
+# self._callback.on_comm_print_job_done()
+# self._changeState(self.STATE_OPERATIONAL)
+# eventManager().fire(Events.PRINT_DONE, {
+# "file": self._currentFile.getFilename(),
+# "filename": os.path.basename(self._currentFile.getFilename()),
+# "origin": self._currentFile.getFileLocation(),
+# "time": self.getPrintTime()
+# })
+# if self._sd_status_timer is not None:
+# try:
+# self._sd_status_timer.cancel()
+# except:
+# pass
+# elif 'Done saving file' in line:
+# self.refreshSdFiles()
+# elif 'File deleted' in line and line.strip().endswith("ok"):
+# # buggy Marlin version that doesn't send a proper \r after the "File deleted" statement, fixed in
+# # current versions
+# self._clear_to_send.set()
##~~ Message handling
elif line.strip() != '' \
@@ -1194,6 +1228,7 @@ class MachineCom(object):
feedback_errors.append("_all")
##~~ Parsing for pause triggers
+
if pause_triggers and not self.isStreaming():
if "enable" in pause_triggers.keys() and pause_triggers["enable"].search(line) is not None:
self.setPause(True)
@@ -1251,9 +1286,9 @@ class MachineCom(object):
# self._clear_to_send.set()
elif " self._timeout:
- print("TIMEOUT_CLOSE")
- self.close()
+ # elif time.time() > self._timeout:
+ # print("TIMEOUT_CLOSE")
+ # self.close()
### Operational
elif self._state == self.STATE_OPERATIONAL or self._state == self.STATE_PAUSED:
@@ -1367,7 +1402,9 @@ class MachineCom(object):
def _onConnected(self, nextState):
self._serial.timeout = settings().getFloat(["serial", "timeout", "communication"])
#self._temperature_timer = RepeatedTimer(lambda: get_interval("temperature"), self._poll_temperature, run_first=True)
- self._temperature_timer = RepeatedTimer(0.2, self._poll_temperature, run_first=True)
+ if self._temperature_timer is not None:
+ self._temperature_timer.cancel()
+ self._temperature_timer = RepeatedTimer(1, self._poll_temperature, run_first=True)
self._temperature_timer.start()
if(nextState == None):
@@ -1707,8 +1744,11 @@ class MachineCom(object):
while self._send_queue_active:
try:
- if(self.RX_BUFFER_SIZE - sum(self.acc_line_lengths) < 20):
- time.sleep(0.1)
+ peeked_entry = self._send_queue.peek()
+ p_command, p_linenbr, p_cmd_type = peeked_entry
+
+ if(self.RX_BUFFER_SIZE - sum(self.acc_line_lengths) - len(p_command) < 5):
+ time.sleep(0.001)
continue
# wait until we have something in the queue
@@ -1982,33 +2022,38 @@ class MachineCom(object):
idx_mx_end = line.index('.', idx_mx_begin) + 2
idx_my_begin = line.index(',', idx_mx_end) + 1
idx_my_end = line.index('.', idx_my_begin) + 2
- idx_mz_begin = line.index(',', idx_my_end) + 1
- idx_mz_end = line.index('.', idx_mz_begin) + 2
+ #idx_mz_begin = line.index(',', idx_my_end) + 1
+ #idx_mz_end = line.index('.', idx_mz_begin) + 2
idx_wx_begin = line.index('WPos:') + 5
idx_wx_end = line.index('.', idx_wx_begin) + 2
idx_wy_begin = line.index(',', idx_wx_end) + 1
idx_wy_end = line.index('.', idx_wy_begin) + 2
- idx_wz_begin = line.index(',', idx_wy_end) + 1
- idx_wz_end = line.index('.', idx_wz_begin) + 2
+ #idx_wz_begin = line.index(',', idx_wy_end) + 1
+ #idx_wz_end = line.index('.', idx_wz_begin) + 2
- idx_intensity_begin = line.index('S:', idx_wz_end) + 2
- idx_intensity_end = line.index(',', idx_intensity_begin)
+ #idx_intensity_begin = line.index('S:', idx_wz_end) + 2
+ #idx_intensity_end = line.index(',', idx_intensity_begin)
- idx_laserstate_begin = line.index('laser ', idx_intensity_end) + 6
- idx_laserstate_end = line.index(':', idx_laserstate_begin)
+ #idx_laserstate_begin = line.index('laser ', idx_intensity_end) + 6
+ #idx_laserstate_end = line.index(':', idx_laserstate_begin)
- payload = {
- "mx": line[idx_mx_begin:idx_mx_end],
- "my": line[idx_my_begin:idx_my_end],
- "mz": line[idx_mz_begin:idx_mz_end],
- "wx": line[idx_wx_begin:idx_wx_end],
- "wy": line[idx_wy_begin:idx_wy_end],
- "wz": line[idx_wz_begin:idx_wz_end],
- "laser": line[idx_laserstate_begin:idx_laserstate_end],
- "intensity": line[idx_intensity_begin:idx_intensity_end]
- }
- eventManager().fire(Events.RT_STATE, payload)
+ #payload = {
+ #"mx": line[idx_mx_begin:idx_mx_end],
+ #"my": line[idx_my_begin:idx_my_end],
+ #"mz": line[idx_mz_begin:idx_mz_end],
+ #"wx": line[idx_wx_begin:idx_wx_end],
+ #"wy": line[idx_wy_begin:idx_wy_end],
+ #"wz": line[idx_wz_begin:idx_wz_end],
+ #"laser": line[idx_laserstate_begin:idx_laserstate_end],
+ #"intensity": line[idx_intensity_begin:idx_intensity_end]
+ #}
+ mx = float(line[idx_mx_begin:idx_mx_end])
+ my = float(line[idx_my_begin:idx_my_end])
+ wx = float(line[idx_wx_begin:idx_wx_end])
+ wy = float(line[idx_wy_begin:idx_wy_end])
+ self._callback.on_comm_pos_update([mx, my, 0], [wx, wy, 0])
+ #eventManager().fire(Events.RT_STATE, payload)
except ValueError:
pass
@@ -2117,6 +2162,9 @@ class MachineComPrintCallback(object):
def on_comm_force_disconnect(self):
pass
+ def on_comm_pos_update(self, MPos, WPos):
+ pass
+
### Printing file information classes ##################################################################################
class PrintingFileInformation(object):
@@ -2284,6 +2332,7 @@ class TypedQueue(queue.Queue):
def __init__(self, maxsize=0):
queue.Queue.__init__(self, maxsize=maxsize)
self._lookup = []
+ self._peekedItem = None;
def _put(self, item):
if isinstance(item, tuple) and len(item) == 3:
@@ -2297,7 +2346,11 @@ class TypedQueue(queue.Queue):
queue.Queue._put(self, item)
def _get(self):
- item = queue.Queue._get(self)
+ if self._peekedItem is None:
+ item = queue.Queue._get(self)
+ else:
+ item = self._peekedItem
+ self._peekedItem = None
if isinstance(item, tuple) and len(item) == 3:
cmd, line, cmd_type = item
@@ -2306,6 +2359,10 @@ class TypedQueue(queue.Queue):
return item
+ def peek(self):
+ if self._peekedItem is None:
+ self._peekedItem = self._get()
+ return self._peekedItem
class TypeAlreadyInQueue(Exception):
def __init__(self, t, *args, **kwargs):