Made settings module more flexible regarding variable path lengths to needed values, made speed for printer movement configurable

master
Gina Häußge 2013-02-16 20:28:09 +01:00
parent b64662c460
commit f03056c1b2
5 changed files with 120 additions and 64 deletions

View File

@ -20,8 +20,8 @@ def getConnectionOptions():
return {
"ports": comm.serialList(),
"baudrates": comm.baudrateList(),
"portPreference": settings().get("serial", "port"),
"baudratePreference": settings().getInt("serial", "baudrate")
"portPreference": settings().get(["serial", "port"]),
"baudratePreference": settings().getInt(["serial", "baudrate"])
}
class Printer():

View File

@ -29,9 +29,9 @@ printer = Printer(gcodeManager)
def index():
return render_template(
"index.html",
webcamStream=settings().get("webcam", "stream"),
enableTimelapse=(settings().get("webcam", "snapshot") is not None and settings().get("webcam", "ffmpeg") is not None),
enableGCodeVisualizer=settings().get("feature", "gCodeVisualizer")
webcamStream=settings().get(["webcam", "stream"]),
enableTimelapse=(settings().get(["webcam", "snapshot"]) is not None and settings().get(["webcam", "ffmpeg"]) is not None),
enableGCodeVisualizer=settings().get(["feature", "gCodeVisualizer"])
)
#~~ Printer state
@ -111,13 +111,13 @@ def connectionOptions():
def connect():
port = None
baudrate = None
if request.values.has_key("port"):
if "port" in request.values.keys():
port = request.values["port"]
if request.values.has_key("baudrate"):
if "baudrate" in request.values.keys():
baudrate = request.values["baudrate"]
if request.values.has_key("save"):
settings().set("serial", "port", port)
settings().set("serial", "baudrate", baudrate)
if "save" in request.values.keys():
settings().set(["serial", "port"], port)
settings().setInt(["serial", "baudrate"], baudrate)
settings().save()
printer.connect(port=port, baudrate=baudrate)
return jsonify(state="Connecting")
@ -181,21 +181,22 @@ def setTargetTemperature():
@app.route(BASEURL + "control/jog", methods=["POST"])
def jog():
if not printer.isOperational() or printer.isPrinting():
# do not jog when a print job is running or we don"t have a connection
# do not jog when a print job is running or we don't have a connection
return jsonify(SUCCESS)
(movementSpeedX, movementSpeedY, movementSpeedZ, movementSpeedE) = settings().get(["printerParameters", "movementSpeed", ["x", "y", "z", "e"]])
if "x" in request.values.keys():
# jog x
x = request.values["x"]
printer.commands(["G91", "G1 X" + x + " F3000", "G90"])
printer.commands(["G91", "G1 X%s F%d" % (x, movementSpeedX), "G90"])
if "y" in request.values.keys():
# jog y
y = request.values["y"]
printer.commands(["G91", "G1 Y" + y + " F3000", "G90"])
printer.commands(["G91", "G1 Y%s F%d" % (y, movementSpeedY), "G90"])
if "z" in request.values.keys():
# jog z
z = request.values["z"]
printer.commands(["G91", "G1 Z" + z + " F200", "G90"])
printer.commands(["G91", "G1 Z%s F%d" % (z, movementSpeedZ), "G90"])
if "homeXY" in request.values.keys():
# home x/y
printer.command("G28 X0 Y0")
@ -205,7 +206,7 @@ def jog():
if "extrude" in request.values.keys():
# extrude/retract
length = request.values["extrude"]
printer.commands(["G91", "G1 E" + length + " F300", "G90"])
printer.commands(["G91", "G1 E%s F%d" % (length, movementSpeedE), "G90"])
return jsonify(SUCCESS)
@ -227,7 +228,7 @@ def speed():
@app.route(BASEURL + "control/custom", methods=["GET"])
def getCustomControls():
customControls = settings().getObject("controls")
customControls = settings().get(["controls"])
return jsonify(controls=customControls)
#~~ GCODE file handling
@ -393,8 +394,8 @@ def initLogging():
def main():
from optparse import OptionParser
defaultHost = settings().get("server", "host")
defaultPort = settings().get("server", "port")
defaultHost = settings().get(["server", "host"])
defaultPort = settings().get(["server", "port"])
parser = OptionParser(usage="usage: %prog [options]")
parser.add_option("-d", "--debug", action="store_true", dest="debug",

View File

@ -45,9 +45,19 @@ old_default_settings = {
default_settings = old_default_settings.copy()
default_settings.update({
"controls": []
"controls": [],
"printerParameters": {
"movementSpeed": {
"x": 6000,
"y": 6000,
"z": 200,
"e": 300
}
}
})
valid_boolean_trues = ["true", "yes", "y", "1"]
class Settings(object):
def __init__(self):
@ -56,10 +66,10 @@ class Settings(object):
self._config = None
self._dirty = False
self.init_settings_dir()
self._init_settings_dir()
self.load()
def init_settings_dir(self):
def _init_settings_dir(self):
self.settings_dir = _resolveSettingsDir(APPNAME)
# migration due to rename
@ -67,6 +77,8 @@ class Settings(object):
if os.path.exists(old_settings_dir) and os.path.isdir(old_settings_dir) and not os.path.exists(self.settings_dir):
os.rename(old_settings_dir, self.settings_dir)
#~~ load and save
def load(self):
filename = os.path.join(self.settings_dir, "config.yaml")
oldFilename = os.path.join(self.settings_dir, "config.ini")
@ -102,29 +114,48 @@ class Settings(object):
self._dirty = False
self.load()
def getObject(self, key):
if key not in default_settings.keys():
#~~ getter
def get(self, path):
if len(path) == 0:
return None
if key in self._config.keys():
return self._config[key]
config = self._config
defaults = default_settings
return default_settings[key]
while len(path) > 1:
key = path.pop(0)
if key in config.keys() and key in defaults.keys():
config = config[key]
defaults = defaults[key]
elif key in defaults.keys():
config = {}
defaults = defaults[key]
else:
return None
def get(self, section, key):
if section not in default_settings.keys():
return None
k = path.pop(0)
if not isinstance(k, (list, tuple)):
keys = [k]
else:
keys = k
if self._config.has_key(section) and self._config[section].has_key(key):
return self._config[section][key]
results = []
for key in keys:
if key in config.keys():
results.append(config[key])
elif key in defaults:
results.append(defaults[key])
else:
results.append(None)
if default_settings.has_key(section) and default_settings[section].has_key(key):
return default_settings[section][key]
if not isinstance(k, (list, tuple)):
return results.pop()
else:
return results
return None
def getInt(self, section, key):
value = self.get(section, key)
def getInt(self, path):
value = self.get(path)
if value is None:
return None
@ -133,19 +164,19 @@ class Settings(object):
except ValueError:
return None
def getBoolean(self, section, key):
value = self.get(section, key)
def getBoolean(self, path):
value = self.get(path)
if value is None:
return None
if isinstance(value, bool):
return value
return value.lower() in ["true", "yes", "y", "1"]
return value.lower() in valid_boolean_trues
def getBaseFolder(self, type):
if type not in old_default_settings["folder"].keys():
return None
folder = self.get("folder", type)
folder = self.get(["folder", type])
if folder is None:
folder = os.path.join(self.settings_dir, type.replace("_", os.path.sep))
@ -154,25 +185,49 @@ class Settings(object):
return folder
def set(self, section, key, value):
if section not in default_settings.keys():
#~~ setter
def set(self, path, value):
if len(path) == 0:
return
if self._config.has_key(section):
sectionConfig = self._config[section]
config = self._config
defaults = default_settings
while len(path) > 1:
key = path.pop(0)
if key in config.keys():
config = config[key]
elif key in defaults.keys():
config[key] = {}
config = config[key]
else:
return
key = path.pop(0)
config[key] = value
self._dirty = True
def setInt(self, path, value):
if value is None:
return
try:
intValue = int(value)
except ValueError:
return
self.set(path, intValue)
def setBoolean(self, path, value):
if value is None:
return
elif isinstance(value, bool):
self.set(path, value)
elif value.lower() in valid_boolean_trues:
self.set(path, True)
else:
sectionConfig = {}
sectionConfig[key] = value
self._config[section] = sectionConfig
self._dirty = True
def setObject(self, key, value):
if key not in default_settings.keys():
return
self._config[key] = value
self._dirty = True
self.set(path, False)
def _resolveSettingsDir(applicationName):
# taken from http://stackoverflow.com/questions/1084697/how-do-i-store-desktop-application-data-in-a-cross-platform-way-for-python

View File

@ -31,7 +31,7 @@ class Timelapse(object):
self._captureDir = settings().getBaseFolder("timelapse_tmp")
self._movieDir = settings().getBaseFolder("timelapse")
self._snapshotUrl = settings().get("webcam", "snapshot")
self._snapshotUrl = settings().get(["webcam", "snapshot"])
self._renderThread = None
self._captureMutex = threading.Lock()
@ -79,8 +79,8 @@ class Timelapse(object):
urllib.urlretrieve(self._snapshotUrl, filename)
def _createMovie(self):
ffmpeg = settings().get("webcam", "ffmpeg")
bitrate = settings().get("webcam", "bitrate")
ffmpeg = settings().get(["webcam", "ffmpeg"])
bitrate = settings().get(["webcam", "bitrate"])
if ffmpeg is None or bitrate is None:
return

View File

@ -38,7 +38,7 @@ def serialList():
except:
pass
baselist = baselist + glob.glob("/dev/ttyUSB*") + glob.glob("/dev/ttyACM*") + glob.glob("/dev/tty.usb*") + glob.glob("/dev/cu.*") + glob.glob("/dev/rfcomm*")
prev = settings().get("serial", "port")
prev = settings().get(["serial", "port"])
if prev in baselist:
baselist.remove(prev)
baselist.insert(0, prev)
@ -48,7 +48,7 @@ def serialList():
def baudrateList():
ret = [250000, 230400, 115200, 57600, 38400, 19200, 9600]
prev = settings().getInt("serial", "baudrate")
prev = settings().getInt(["serial", "baudrate"])
if prev in ret:
ret.remove(prev)
ret.insert(0, prev)
@ -144,9 +144,9 @@ class MachineCom(object):
def __init__(self, port = None, baudrate = None, callbackObject = None):
if port == None:
port = settings().get("serial", "port")
port = settings().get(["serial", "port"])
if baudrate == None:
settingsBaudrate = settings().getInt("serial", "baudrate")
settingsBaudrate = settings().getInt(["serial", "baudrate"])
if settingsBaudrate is None:
baudrate = 0
else: