Added timeout settings for serial communiction, initial connection and baudrate detection
Closes #126master
parent
3ffaaa19be
commit
6d3e3221b8
|
@ -518,6 +518,9 @@ def getSettings():
|
||||||
"portOptions": connectionOptions["ports"],
|
"portOptions": connectionOptions["ports"],
|
||||||
"baudrateOptions": connectionOptions["baudrates"],
|
"baudrateOptions": connectionOptions["baudrates"],
|
||||||
"autoconnect": s.getBoolean(["serial", "autoconnect"]),
|
"autoconnect": s.getBoolean(["serial", "autoconnect"]),
|
||||||
|
"timeoutConnection": s.getFloat(["serial", "timeout", "connection"]),
|
||||||
|
"timeoutDetection": s.getFloat(["serial", "timeout", "detection"]),
|
||||||
|
"timeoutCommunication": s.getFloat(["serial", "timeout", "communication"]),
|
||||||
"log": s.getBoolean(["serial", "log"])
|
"log": s.getBoolean(["serial", "log"])
|
||||||
},
|
},
|
||||||
"folder": {
|
"folder": {
|
||||||
|
@ -576,6 +579,9 @@ def setSettings():
|
||||||
if "autoconnect" in data["serial"].keys(): s.setBoolean(["serial", "autoconnect"], data["serial"]["autoconnect"])
|
if "autoconnect" in data["serial"].keys(): s.setBoolean(["serial", "autoconnect"], data["serial"]["autoconnect"])
|
||||||
if "port" in data["serial"].keys(): s.set(["serial", "port"], data["serial"]["port"])
|
if "port" in data["serial"].keys(): s.set(["serial", "port"], data["serial"]["port"])
|
||||||
if "baudrate" in data["serial"].keys(): s.setInt(["serial", "baudrate"], data["serial"]["baudrate"])
|
if "baudrate" in data["serial"].keys(): s.setInt(["serial", "baudrate"], data["serial"]["baudrate"])
|
||||||
|
if "timeoutConnection" in data["serial"].keys(): s.setFloat(["serial", "timeout", "connection"], data["serial"]["timeoutConnection"])
|
||||||
|
if "timeoutDetection" in data["serial"].keys(): s.setFloat(["serial", "timeout", "detection"], data["serial"]["timeoutDetection"])
|
||||||
|
if "timeoutCommunication" in data["serial"].keys(): s.setFloat(["serial", "timeout", "communication"], data["serial"]["timeoutCommunication"])
|
||||||
|
|
||||||
oldLog = s.getBoolean(["serial", "log"])
|
oldLog = s.getBoolean(["serial", "log"])
|
||||||
if "log" in data["serial"].keys(): s.setBoolean(["serial", "log"], data["serial"]["log"])
|
if "log" in data["serial"].keys(): s.setBoolean(["serial", "log"], data["serial"]["log"])
|
||||||
|
|
|
@ -27,7 +27,12 @@ default_settings = {
|
||||||
"port": None,
|
"port": None,
|
||||||
"baudrate": None,
|
"baudrate": None,
|
||||||
"autoconnect": False,
|
"autoconnect": False,
|
||||||
"log": False
|
"log": False,
|
||||||
|
"timeout": {
|
||||||
|
"detection": 0.5,
|
||||||
|
"connection": 2,
|
||||||
|
"communication": 5
|
||||||
|
}
|
||||||
},
|
},
|
||||||
"server": {
|
"server": {
|
||||||
"host": "0.0.0.0",
|
"host": "0.0.0.0",
|
||||||
|
@ -199,6 +204,17 @@ class Settings(object):
|
||||||
self._logger.warn("Could not convert %r to a valid integer when getting option %r" % (value, path))
|
self._logger.warn("Could not convert %r to a valid integer when getting option %r" % (value, path))
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
def getFloat(self, path):
|
||||||
|
value = self.get(path)
|
||||||
|
if value is None:
|
||||||
|
return None
|
||||||
|
|
||||||
|
try:
|
||||||
|
return float(value)
|
||||||
|
except ValueError:
|
||||||
|
self._logger.warn("Could not convert %r to a valid integer when getting option %r" % (value, path))
|
||||||
|
return None
|
||||||
|
|
||||||
def getBoolean(self, path):
|
def getBoolean(self, path):
|
||||||
value = self.get(path)
|
value = self.get(path)
|
||||||
if value is None:
|
if value is None:
|
||||||
|
@ -288,6 +304,19 @@ class Settings(object):
|
||||||
|
|
||||||
self.set(path, intValue, force)
|
self.set(path, intValue, force)
|
||||||
|
|
||||||
|
def setFloat(self, path, value, force=False):
|
||||||
|
if value is None:
|
||||||
|
self.set(path, None, force)
|
||||||
|
return
|
||||||
|
|
||||||
|
try:
|
||||||
|
floatValue = float(value)
|
||||||
|
except ValueError:
|
||||||
|
self._logger.warn("Could not convert %r to a valid integer when setting option %r" % (value, path))
|
||||||
|
return
|
||||||
|
|
||||||
|
self.set(path, floatValue, force)
|
||||||
|
|
||||||
def setBoolean(self, path, value, force=False):
|
def setBoolean(self, path, value, force=False):
|
||||||
if value is None or isinstance(value, bool):
|
if value is None or isinstance(value, bool):
|
||||||
self.set(path, value, force)
|
self.set(path, value, force)
|
||||||
|
|
|
@ -1363,6 +1363,9 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
|
||||||
self.serial_portOptions = ko.observableArray([]);
|
self.serial_portOptions = ko.observableArray([]);
|
||||||
self.serial_baudrateOptions = ko.observableArray([]);
|
self.serial_baudrateOptions = ko.observableArray([]);
|
||||||
self.serial_autoconnect = ko.observable(undefined);
|
self.serial_autoconnect = ko.observable(undefined);
|
||||||
|
self.serial_timeoutConnection = ko.observable(undefined);
|
||||||
|
self.serial_timeoutDetection = ko.observable(undefined);
|
||||||
|
self.serial_timeoutCommunication = ko.observable(undefined);
|
||||||
self.serial_log = ko.observable(undefined);
|
self.serial_log = ko.observable(undefined);
|
||||||
|
|
||||||
self.folder_uploads = ko.observable(undefined);
|
self.folder_uploads = ko.observable(undefined);
|
||||||
|
@ -1421,6 +1424,9 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
|
||||||
self.serial_portOptions(response.serial.portOptions);
|
self.serial_portOptions(response.serial.portOptions);
|
||||||
self.serial_baudrateOptions(response.serial.baudrateOptions);
|
self.serial_baudrateOptions(response.serial.baudrateOptions);
|
||||||
self.serial_autoconnect(response.serial.autoconnect);
|
self.serial_autoconnect(response.serial.autoconnect);
|
||||||
|
self.serial_timeoutConnection(response.serial.timeoutConnection);
|
||||||
|
self.serial_timeoutDetection(response.serial.timeoutDetection);
|
||||||
|
self.serial_timeoutCommunication(response.serial.timeoutCommunication);
|
||||||
self.serial_log(response.serial.log);
|
self.serial_log(response.serial.log);
|
||||||
|
|
||||||
self.folder_uploads(response.folder.uploads);
|
self.folder_uploads(response.folder.uploads);
|
||||||
|
@ -1468,6 +1474,9 @@ function SettingsViewModel(loginStateViewModel, usersViewModel) {
|
||||||
"port": self.serial_port(),
|
"port": self.serial_port(),
|
||||||
"baudrate": self.serial_baudrate(),
|
"baudrate": self.serial_baudrate(),
|
||||||
"autoconnect": self.serial_autoconnect(),
|
"autoconnect": self.serial_autoconnect(),
|
||||||
|
"timeoutConnection": self.serial_timeoutConnection(),
|
||||||
|
"timeoutDetection": self.serial_timeoutDetection(),
|
||||||
|
"timeoutCommunication": self.serial_timeoutCommunication(),
|
||||||
"log": self.serial_log()
|
"log": self.serial_log()
|
||||||
},
|
},
|
||||||
"folder": {
|
"folder": {
|
||||||
|
|
|
@ -21,14 +21,14 @@
|
||||||
<div class="tab-pane active" id="settings_serialConnection">
|
<div class="tab-pane active" id="settings_serialConnection">
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="settings-serialPort">Serial Port</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label for="settings-serialPort">Serial Port</label>
|
|
||||||
<select id="settings-serialPort" data-bind="options: serial_portOptions, optionsCaption: 'AUTO', value: serial_port"></select>
|
<select id="settings-serialPort" data-bind="options: serial_portOptions, optionsCaption: 'AUTO', value: serial_port"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="settings-baudrate">Baudrate</label>
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label for="settings-baudrate">Baudrate</label>
|
|
||||||
<select id="settings-baudrate" data-bind="options: serial_baudrateOptions, optionsCaption: 'AUTO', value: serial_baudrate"></select>
|
<select id="settings-baudrate" data-bind="options: serial_baudrateOptions, optionsCaption: 'AUTO', value: serial_baudrate"></select>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
@ -39,6 +39,33 @@
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="settings-movementSpeedE">Communication timeout</label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="input-append">
|
||||||
|
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutCommunication" id="settings-serialTimeoutCommunication">
|
||||||
|
<span class="add-on">s</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="settings-movementSpeedE">Connection timeout</label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="input-append">
|
||||||
|
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutConnection" id="settings-serialTimeoutConnection">
|
||||||
|
<span class="add-on">s</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
<div class="control-group">
|
||||||
|
<label class="control-label" for="settings-movementSpeedE">Autodetection timeout</label>
|
||||||
|
<div class="controls">
|
||||||
|
<div class="input-append">
|
||||||
|
<input type="number" step="any" min="0" class="input-mini text-right" data-bind="value: serial_timeoutDetection" id="settings-serialTimeoutDetection">
|
||||||
|
<span class="add-on">s</span>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
<div class="control-group">
|
<div class="control-group">
|
||||||
<div class="controls">
|
<div class="controls">
|
||||||
<label class="checkbox">
|
<label class="checkbox">
|
||||||
|
|
|
@ -2,11 +2,12 @@
|
||||||
__author__ = "Gina Häußge <osd@foosel.net>"
|
__author__ = "Gina Häußge <osd@foosel.net>"
|
||||||
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
__license__ = 'GNU Affero General Public License http://www.gnu.org/licenses/agpl.html'
|
||||||
|
|
||||||
import re
|
|
||||||
import os
|
import os
|
||||||
import traceback
|
import traceback
|
||||||
import sys
|
import sys
|
||||||
|
import time
|
||||||
|
|
||||||
|
from octoprint.settings import settings
|
||||||
|
|
||||||
def getFormattedSize(num):
|
def getFormattedSize(num):
|
||||||
"""
|
"""
|
||||||
|
@ -79,3 +80,12 @@ def getGitInfo():
|
||||||
head = f.readline().strip()
|
head = f.readline().strip()
|
||||||
|
|
||||||
return (branch, head)
|
return (branch, head)
|
||||||
|
|
||||||
|
|
||||||
|
def getNewTimeout(type):
|
||||||
|
now = time.time()
|
||||||
|
|
||||||
|
if type not in ["connection", "detection", "communication"]:
|
||||||
|
return now # timeout immediately for unknown timeout type
|
||||||
|
|
||||||
|
return now + settings().getFloat(["serial", "timeout", type])
|
||||||
|
|
|
@ -19,7 +19,7 @@ from octoprint.util.avr_isp import ispBase
|
||||||
|
|
||||||
from octoprint.settings import settings
|
from octoprint.settings import settings
|
||||||
from octoprint.events import eventManager
|
from octoprint.events import eventManager
|
||||||
from octoprint.util import isDevVersion, getExceptionString
|
from octoprint.util import isDevVersion, getExceptionString, getNewTimeout
|
||||||
from octoprint.util.virtual import VirtualPrinter
|
from octoprint.util.virtual import VirtualPrinter
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
@ -467,7 +467,7 @@ class MachineCom(object):
|
||||||
if self._baudrate == 0:
|
if self._baudrate == 0:
|
||||||
self._serial = serial.Serial(str(self._port), 115200, timeout=0.1, writeTimeout=10000)
|
self._serial = serial.Serial(str(self._port), 115200, timeout=0.1, writeTimeout=10000)
|
||||||
else:
|
else:
|
||||||
self._serial = serial.Serial(str(self._port), self._baudrate, timeout=2, writeTimeout=10000)
|
self._serial = serial.Serial(str(self._port), self._baudrate, timeout=settings().getFloat(["serial", "timeout", "connection"]), writeTimeout=10000)
|
||||||
except:
|
except:
|
||||||
self._log("Unexpected error while connecting to serial port: %s %s" % (self._port, getExceptionString()))
|
self._log("Unexpected error while connecting to serial port: %s %s" % (self._port, getExceptionString()))
|
||||||
if self._serial == None:
|
if self._serial == None:
|
||||||
|
@ -483,7 +483,7 @@ class MachineCom(object):
|
||||||
self._changeState(self.STATE_CONNECTING)
|
self._changeState(self.STATE_CONNECTING)
|
||||||
|
|
||||||
#Start monitoring the serial port.
|
#Start monitoring the serial port.
|
||||||
timeout = time.time() + 5
|
timeout = getNewTimeout("communication")
|
||||||
tempRequestTimeout = timeout
|
tempRequestTimeout = timeout
|
||||||
sdStatusRequestTimeout = timeout
|
sdStatusRequestTimeout = timeout
|
||||||
startSeen = not settings().getBoolean(["feature", "waitForStartOnConnect"])
|
startSeen = not settings().getBoolean(["feature", "waitForStartOnConnect"])
|
||||||
|
@ -623,11 +623,11 @@ class MachineCom(object):
|
||||||
baudrate = self._baudrateDetectList.pop(0)
|
baudrate = self._baudrateDetectList.pop(0)
|
||||||
try:
|
try:
|
||||||
self._serial.baudrate = baudrate
|
self._serial.baudrate = baudrate
|
||||||
self._serial.timeout = 0.5
|
self._serial.timeout = getNewTimeout("detection")
|
||||||
self._log("Trying baudrate: %d" % (baudrate))
|
self._log("Trying baudrate: %d" % (baudrate))
|
||||||
self._baudrateDetectRetry = 5
|
self._baudrateDetectRetry = 5
|
||||||
self._baudrateDetectTestOk = 0
|
self._baudrateDetectTestOk = 0
|
||||||
timeout = time.time() + 5
|
timeout = getNewTimeout("communication")
|
||||||
self._serial.write('\n')
|
self._serial.write('\n')
|
||||||
self._sendCommand("M105")
|
self._sendCommand("M105")
|
||||||
self._testingBaudrate = True
|
self._testingBaudrate = True
|
||||||
|
@ -640,7 +640,7 @@ class MachineCom(object):
|
||||||
self._sendCommand("M105")
|
self._sendCommand("M105")
|
||||||
else:
|
else:
|
||||||
self._sendCommand("M999")
|
self._sendCommand("M999")
|
||||||
self._serial.timeout = 2
|
self._serial.timeout = getNewTimeout("connection")
|
||||||
self._changeState(self.STATE_OPERATIONAL)
|
self._changeState(self.STATE_OPERATIONAL)
|
||||||
if self._sdAvailable:
|
if self._sdAvailable:
|
||||||
self.refreshSdFiles()
|
self.refreshSdFiles()
|
||||||
|
@ -672,7 +672,7 @@ class MachineCom(object):
|
||||||
self._sendCommand(self._commandQueue.get())
|
self._sendCommand(self._commandQueue.get())
|
||||||
else:
|
else:
|
||||||
self._sendCommand("M105")
|
self._sendCommand("M105")
|
||||||
tempRequestTimeout = time.time() + 5
|
tempRequestTimeout = getNewTimeout("communication")
|
||||||
# resend -> start resend procedure from requested line
|
# resend -> start resend procedure from requested line
|
||||||
elif "resend" in line.lower() or "rs" in line:
|
elif "resend" in line.lower() or "rs" in line:
|
||||||
self._handleResendRequest(line)
|
self._handleResendRequest(line)
|
||||||
|
@ -686,22 +686,22 @@ class MachineCom(object):
|
||||||
if self.isSdPrinting():
|
if self.isSdPrinting():
|
||||||
if time.time() > tempRequestTimeout and not heatingUp:
|
if time.time() > tempRequestTimeout and not heatingUp:
|
||||||
self._sendCommand("M105")
|
self._sendCommand("M105")
|
||||||
tempRequestTimeout = time.time() + 5
|
tempRequestTimeout = getNewTimeout("communication")
|
||||||
|
|
||||||
if time.time() > sdStatusRequestTimeout and not heatingUp:
|
if time.time() > sdStatusRequestTimeout and not heatingUp:
|
||||||
self._sendCommand("M27")
|
self._sendCommand("M27")
|
||||||
sdStatusRequestTimeout = time.time() + 1
|
sdStatusRequestTimeout = time.time() + 1
|
||||||
|
|
||||||
if 'ok' or 'SD printing byte' in line:
|
if 'ok' or 'SD printing byte' in line:
|
||||||
timeout = time.time() + 5
|
timeout = getNewTimeout("communication")
|
||||||
else:
|
else:
|
||||||
# Even when printing request the temperature every 5 seconds.
|
# Even when printing request the temperature every 5 seconds.
|
||||||
if time.time() > tempRequestTimeout and not self.isStreaming():
|
if time.time() > tempRequestTimeout and not self.isStreaming():
|
||||||
self._commandQueue.put("M105")
|
self._commandQueue.put("M105")
|
||||||
tempRequestTimeout = time.time() + 5
|
tempRequestTimeout = getNewTimeout("communication")
|
||||||
|
|
||||||
if 'ok' in line:
|
if 'ok' in line:
|
||||||
timeout = time.time() + 5
|
timeout = getNewTimeout("communication")
|
||||||
if self._resendDelta is not None:
|
if self._resendDelta is not None:
|
||||||
self._resendNextCommand()
|
self._resendNextCommand()
|
||||||
elif not self._commandQueue.empty() and not self.isStreaming():
|
elif not self._commandQueue.empty() and not self.isStreaming():
|
||||||
|
|
Loading…
Reference in New Issue