Hibernate communication with printer during active G4 on Repetier

Should hopefully solve #1506
This commit is contained in:
Gina Häußge 2017-01-24 18:15:49 +01:00
parent 7beabf953c
commit 216f05d553
6 changed files with 52 additions and 7 deletions

View file

@ -92,6 +92,7 @@ class VirtualPrinter(object):
self._supportF = settings().getBoolean(["devel", "virtualPrinter", "supportF"])
self._sendWait = settings().getBoolean(["devel", "virtualPrinter", "sendWait"])
self._sendBusy = settings().getBoolean(["devel", "virtualPrinter", "sendBusy"])
self._waitInterval = settings().getFloat(["devel", "virtualPrinter", "waitInterval"])
self._echoOnM117 = settings().getBoolean(["devel", "virtualPrinter", "echoOnM117"])
@ -451,6 +452,24 @@ class VirtualPrinter(object):
_gcode_G2 = _gcode_G0
_gcode_G3 = _gcode_G0
def _gcode_G4(self, data):
matchS = re.search('S([0-9]+)', data)
matchP = re.search('P([0-9]+)', data)
_timeout = 0
if matchP:
_timeout = float(matchP.group(1)) / 1000.0
elif matchS:
_timeout = float(matchS.group(1))
if self._sendBusy:
until = time.time() + _timeout
while time.time() < until:
time.sleep(1.0)
self._send("busy:processing")
else:
time.sleep(_timeout)
##~~ further helpers
def _calculate_checksum(self, line):

View file

@ -126,7 +126,8 @@ def getSettings():
"ignoreIdenticalResends": s.getBoolean(["feature", "ignoreIdenticalResends"]),
"modelSizeDetection": s.getBoolean(["feature", "modelSizeDetection"]),
"firmwareDetection": s.getBoolean(["feature", "firmwareDetection"]),
"printCancelConfirmation": s.getBoolean(["feature", "printCancelConfirmation"])
"printCancelConfirmation": s.getBoolean(["feature", "printCancelConfirmation"]),
"blockWhileDwelling": s.getBoolean(["feature", "blockWhileDwelling"])
},
"serial": {
"port": connectionOptions["portPreference"],
@ -311,6 +312,7 @@ def _saveSettings(data):
if "modelSizeDetection" in data["feature"]: s.setBoolean(["feature", "modelSizeDetection"], data["feature"]["modelSizeDetection"])
if "firmwareDetection" in data["feature"]: s.setBoolean(["feature", "firmwareDetection"], data["feature"]["firmwareDetection"])
if "printCancelConfirmation" in data["feature"]: s.setBoolean(["feature", "printCancelConfirmation"], data["feature"]["printCancelConfirmation"])
if "blockWhileDwelling" in data["feature"]: s.setBoolean(["feature", "blockWhileDwelling"], data["feature"]["blockWhileDwelling"])
if "serial" in data.keys():
if "autoconnect" in data["serial"].keys(): s.setBoolean(["serial", "autoconnect"], data["serial"]["autoconnect"])

View file

@ -168,7 +168,6 @@ default_settings = {
"options": {},
"postRoll": 0,
"fps": 25,
"capturePostRoll": True
},
"cleanTmpAfterDays": 7
},
@ -203,7 +202,8 @@ default_settings = {
"supportFAsCommand": False,
"modelSizeDetection": True,
"firmwareDetection": True,
"printCancelConfirmation": True
"printCancelConfirmation": True,
"blockWhileDwelling": False
},
"folder": {
"uploads": None,
@ -357,7 +357,8 @@ default_settings = {
"brokenM29": True,
"supportF": False,
"firmwareName": "Virtual Marlin 1.0",
"sharedNozzle": False
"sharedNozzle": False,
"sendBusy": False,
}
}
}

View file

@ -139,6 +139,7 @@ $(function() {
self.feature_modelSizeDetection = ko.observable(undefined);
self.feature_firmwareDetection = ko.observable(undefined);
self.feature_printCancelConfirmation = ko.observable(undefined);
self.feature_blockWhileDwelling = ko.observable(undefined);
self.serial_port = ko.observable();
self.serial_baudrate = ko.observable();

View file

@ -88,6 +88,13 @@
</label>
</div>
</div>
<div class="control-group">
<div class="controls">
<label class="checkbox">
<input type="checkbox" data-bind="checked: feature_blockWhileDwelling" id="settings-featureBlockWhileDwelling"> {{ _('Actively pause communication during <code>G4</code> dwell command') }} <span class="label">{{ _('Repetier') }}</span>
</label>
</div>
</div>
<div class="control-group">
<label class="control-label">{{ _('Send a checksum with the command')}}</label>
<div class="controls">

View file

@ -284,6 +284,7 @@ class MachineCom(object):
self._long_running_command = False
self._heating = False
self._dwelling_until = False
self._connection_closing = False
self._timeout = None
@ -315,6 +316,7 @@ class MachineCom(object):
self._unknownCommandsNeedAck = settings().getBoolean(["feature", "unknownCommandsNeedAck"])
self._sdAlwaysAvailable = settings().getBoolean(["feature", "sdAlwaysAvailable"])
self._sdRelativePath = settings().getBoolean(["feature", "sdRelativePath"])
self._blockWhileDwelling = settings().getBoolean(["feature", "blockWhileDwelling"])
self._currentLine = 1
self._line_mutex = threading.RLock()
self._resendDelta = None
@ -1058,6 +1060,7 @@ class MachineCom(object):
self.sayHello()
while self._monitoring_active:
now = time.time()
try:
line = self._readline()
if line is None:
@ -1066,6 +1069,9 @@ class MachineCom(object):
self._consecutive_timeouts = 0
self._timeout = get_new_timeout("communication", self._timeout_intervals)
if self._dwelling_until and now > self._dwelling_until:
self._dwelling_until = False
##~~ debugging output handling
if line.startswith("//"):
debugging_output = line[2:].strip()
@ -1147,7 +1153,7 @@ class MachineCom(object):
handled = True
# process timeouts
elif line == "" and time.time() > self._timeout:
elif line == "" and (not self._blockWhileDwelling or not self._dwelling_until or now > self._dwelling_until) and now > self._timeout:
# timeout only considered handled if the printer is printing
self._handle_timeout()
handled = self.isPrinting()
@ -1237,6 +1243,7 @@ class MachineCom(object):
self._alwaysSendChecksum = True
self._resendSwallowRepetitions = True
self._blockWhileDwelling = True
supportRepetierTargetTemp = True
disable_external_heatup_detection = True
@ -1550,7 +1557,7 @@ class MachineCom(object):
command or heating, no poll will be done.
"""
if self.isOperational() and not self._connection_closing and not self.isStreaming() and not self._long_running_command and not self._heating and not self._manualStreaming:
if self.isOperational() and not self._connection_closing and not self.isStreaming() and not self._long_running_command and not self._heating and not self._dwelling_until and not self._manualStreaming:
self.sendCommand("M105", cmd_type="temperature_poll")
def _poll_sd_status(self):
@ -1561,7 +1568,7 @@ class MachineCom(object):
command or heating, no poll will be done.
"""
if self.isOperational() and not self._connection_closing and self.isSdPrinting() and not self._long_running_command and not self._heating:
if self.isOperational() and not self._connection_closing and self.isSdPrinting() and not self._long_running_command and not self._dwelling_until and not self._heating:
self.sendCommand("M27", cmd_type="sd_status_poll")
def _onConnected(self):
@ -2018,6 +2025,12 @@ class MachineCom(object):
if not self._send_queue_active:
break
# sleep if we are dwelling
now = time.time()
if self._blockWhileDwelling and self._dwelling_until and now < self._dwelling_until:
time.sleep(self._dwelling_until - now)
self._dwelling_until = False
# fetch command, command type and optional linenumber and sent callback from queue
command, linenumber, command_type, on_sent = entry
@ -2422,7 +2435,9 @@ class MachineCom(object):
_timeout = float(p_match.group("value")) / 1000.0
elif s_match:
_timeout = float(s_match.group("value"))
self._timeout = get_new_timeout("communication", self._timeout_intervals) + _timeout
self._dwelling_until = time.time() + _timeout
##~~ command phase handlers