def controlJob(): if not printer.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "start": [], "restart": [], "pause": [], "cancel": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response activePrintjob = printer.isPrinting() or printer.isPaused() if command == "start": if activePrintjob: return make_response("Printer already has an active print job, did you mean 'restart'?", 409) printer.startPrint() elif command == "restart": if not printer.isPaused(): return make_response("Printer does not have an active print job or is not paused", 409) printer.startPrint() elif command == "pause": if not activePrintjob: return make_response("Printer is neither printing nor paused, 'pause' command cannot be performed", 409) printer.togglePausePrint() elif command == "cancel": if not activePrintjob: return make_response("Printer is neither printing nor paused, 'cancel' command cannot be performed", 409) printer.cancelPrint() return NO_CONTENT
def gcodeFileCommand(filename, target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) if not _verifyFileExists(target, filename): return make_response("File not found on '%s': %s" % (target, filename), 404) # valid file commands, dict mapping command name to mandatory parameters valid_commands = { "select": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "select": # selects/loads a file printAfterLoading = False if "print" in data.keys() and data["print"]: if not printer.isOperational(): return make_response("Printer is not operational, cannot directly start printing", 409) printAfterLoading = True sd = False if target == FileDestinations.SDCARD: filenameToSelect = filename sd = True else: filenameToSelect = gcodeManager.getAbsolutePath(filename) printer.selectFile(filenameToSelect, sd, printAfterLoading) return NO_CONTENT
def connectionCommand(): valid_commands = { "connect": ["autoconnect"], "disconnect": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "connect": options = getConnectionOptions() port = None baudrate = None if "port" in data.keys(): port = data["port"] if port not in options["ports"]: return make_response("Invalid port: %s" % port, 400) if "baudrate" in data.keys(): baudrate = data["baudrate"] if baudrate not in options["baudrates"]: return make_response("Invalid baudrate: %d" % baudrate, 400) if "save" in data.keys() and data["save"]: settings().set(["serial", "port"], port) settings().setInt(["serial", "baudrate"], baudrate) settings().setBoolean(["serial", "autoconnect"], data["autoconnect"]) settings().save() printer.connect(port=port, baudrate=baudrate) elif command == "disconnect": printer.disconnect() return jsonify(SUCCESS)
def printerBedCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "target": ["target"], "offset": ["offset"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response ##~~ temperature if command == "target": target = data["target"] # make sure the target is a number if not isinstance(target, (int, long, float)): return make_response("Not a number: %r" % target, 400) # perform the actual temperature command pm.setTemperature("bed", target) return NO_CONTENT
def printerBedCommand(): if not printer.isOperational(): return make_response("Printer is not operational", 409) valid_commands = {"target": ["target"], "offset": ["offset"]} command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response ##~~ temperature if command == "target": target = data["target"] # make sure the target is a number if not isinstance(target, (int, long, float)): return make_response("Not a number: %r" % target, 400) # perform the actual temperature command printer.setTemperature("bed", target) ##~~ temperature offset elif command == "offset": offset = data["offsets"] # make sure the offset is valid if not isinstance(offset, (int, long, float)): return make_response("Not a number: %r" % offset, 400) if not -50 <= offset <= 50: return make_response("Offset not in range [-50, 50]: %f" % offset, 400) # set the offsets printer.setTemperatureOffset({"bed": offset}) return NO_CONTENT
def gcodeFileCommand(filename, target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Invalid target: %s" % target, 400) # valid file commands, dict mapping command name to mandatory parameters valid_commands = { "load": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "load": # selects/loads a file printAfterLoading = False if "print" in data.keys() and data["print"] in valid_boolean_trues: printAfterLoading = True sd = False if target == FileDestinations.SDCARD: filenameToSelect = filename sd = True else: filenameToSelect = gcodeManager.getAbsolutePath(filename) printer.selectFile(filenameToSelect, sd, printAfterLoading) return jsonify(SUCCESS) return make_response("Command %s is currently not implemented" % command, 400)
def gcodeFileCommand(filename, target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) if not _verifyFileExists(target, filename): return make_response("File not found on '%s': %s" % (target, filename), 404) # valid file commands, dict mapping command name to mandatory parameters valid_commands = {"select": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response if command == "select": # selects/loads a file printAfterLoading = False if "print" in data.keys() and data["print"]: if not printer.isOperational(): return make_response( "Printer is not operational, cannot directly start printing", 409) printAfterLoading = True sd = False if target == FileDestinations.SDCARD: filenameToSelect = filename sd = True else: filenameToSelect = gcodeManager.getAbsolutePath(filename) printer.selectFile(filenameToSelect, sd, printAfterLoading) return NO_CONTENT
def printerSdCommand(): if not settings().getBoolean(["feature", "sdSupport"]): return make_response("SD support is disabled", 404) pm = printerManager() if not pm.isOperational() or pm.isPrinting() or pm.isPaused(): return make_response("Printer is not operational or currently busy", 409) valid_commands = { "init": [], "refresh": [], "release": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "init": pm.initSdCard() elif command == "refresh": pm.refreshSdFiles() elif command == "release": pm.releaseSdCard() return NO_CONTENT
def connectionCommand(): valid_commands = {"connect": ["autoconnect"], "disconnect": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response if command == "connect": options = getConnectionOptions() port = None baudrate = None if "port" in data.keys(): port = data["port"] if port not in options["ports"]: return make_response("Invalid port: %s" % port, 400) if "baudrate" in data.keys(): baudrate = data["baudrate"] if baudrate not in options["baudrates"]: return make_response("Invalid baudrate: %d" % baudrate, 400) if "save" in data.keys() and data["save"]: settings().set(["serial", "port"], port) settings().setInt(["serial", "baudrate"], baudrate) if "autoconnect" in data.keys(): settings().setBoolean(["serial", "autoconnect"], data["autoconnect"]) settings().save() printer.connect(port=port, baudrate=baudrate) elif command == "disconnect": printer.disconnect() return NO_CONTENT
def printerPrintheadCommand(): pm = printerManager() valid_commands = {"jog": [], "home": ["axes"], "babystepping": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if not pm.isOperational() or command != "babystepping" and pm.isPrinting(): # do not jog when a print job is running or we don't have a connection return make_response( "Printer is not operational or currently printing", 409) if response is not None: return response valid_axes = ["x", "y", "z"] ##~~ jog command if command == "jog": # validate all jog instructions, make sure that the values are numbers validated_values = {} for axis in valid_axes: if axis in data: value = data[axis] if not isinstance(value, (int, long, float)): return make_response( "Not a number for axis %s: %r" % (axis, value), 400) validated_values[axis] = value # execute the jog commands for axis, value in validated_values.iteritems(): pm.jog(axis, value) ##~~ home command elif command == "home": validated_values = [] axes = data["axes"] for axis in axes: if not axis in valid_axes: return make_response("Invalid axis: %s" % axis, 400) validated_values.append(axis) # execute the home command pm.home(validated_values) ##~~ babystepping command elif command == "babystepping": if "amount" in data: value = data['amount'] if not isinstance(value, (int, long, float)): return make_response("Not a number for amount: %r" % (value), 400) validated_values = {} validated_values['amount'] = value # execute the babystepping command pm.babystepping(validated_values['amount']) return NO_CONTENT
def printerPrintheadCommand(): pm = printerManager() valid_commands = { "jog": [], "home": ["axes"], "babystepping": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if not pm.isOperational() or command != "babystepping" and pm.isPrinting(): # do not jog when a print job is running or we don't have a connection return make_response("Printer is not operational or currently printing", 409) if response is not None: return response valid_axes = ["x", "y", "z"] ##~~ jog command if command == "jog": # validate all jog instructions, make sure that the values are numbers validated_values = {} for axis in valid_axes: if axis in data: value = data[axis] if not isinstance(value, (int, long, float)): return make_response("Not a number for axis %s: %r" % (axis, value), 400) validated_values[axis] = value # execute the jog commands for axis, value in validated_values.iteritems(): pm.jog(axis, value) ##~~ home command elif command == "home": validated_values = [] axes = data["axes"] for axis in axes: if not axis in valid_axes: return make_response("Invalid axis: %s" % axis, 400) validated_values.append(axis) # execute the home command pm.home(validated_values) ##~~ babystepping command elif command == "babystepping": if "amount" in data: value = data['amount'] if not isinstance(value, (int, long, float)): return make_response("Not a number for amount: %r" % (value), 400) validated_values = {} validated_values['amount'] = value # execute the babystepping command pm.babystepping(validated_values['amount']) return NO_CONTENT
def controlPrinterHotend(): if not printer.isOperational(): return make_response("Printer is not operational", 403) valid_commands = { "temp": ["temps"], "offset": ["offsets"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response valid_targets = ["hotend", "bed"] ##~~ temperature if command == "temp": temps = data["temps"] # make sure the targets are valid and the values are numbers validated_values = {} for type, value in temps.iteritems(): if not type in valid_targets: return make_response("Invalid target for setting temperature: %s" % type, 400) if not isinstance(value, (int, long, float)): return make_response("Not a number for %s: %r" % (type, value), 400) validated_values[type] = value # perform the actual temperature commands # TODO make this a generic method call (printer.setTemperature(type, value)) to get rid of gcode here if "hotend" in validated_values: printer.command("M104 S%f" % validated_values["hotend"]) if "bed" in validated_values: printer.command("M140 S%f" % validated_values["bed"]) ##~~ temperature offset elif command == "offset": offsets = data["offsets"] # make sure the targets are valid, the values are numbers and in the range [-50, 50] validated_values = {} for type, value in offsets.iteritems(): if not type in valid_targets: return make_response("Invalid target for setting temperature: %s" % type, 400) if not isinstance(value, (int, long, float)): return make_response("Not a number for %s: %r" % (type, value), 400) if not -50 <= value <= 50: return make_response("Offset %s not in range [-50, 50]: %f" % (type, value), 400) validated_values[type] = value # set the offsets if "hotend" in validated_values and "bed" in validated_values: printer.setTemperatureOffset(validated_values["hotend"], validated_values["bed"]) elif "hotend" in validated_values: printer.setTemperatureOffset(validated_values["hotend"], None) elif "bed" in validated_values: printer.setTemperatureOffset(None, validated_values["bed"]) return jsonify(SUCCESS)
def printerPrintheadCommand(): valid_commands = { "jog": [], "fastbot":[], #lkj "home": ["axes"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if not printer.isOperational() or ( printer.isPrinting() and command != "fastbot"): # do not jog when a print job is running or we don't have a connection return make_response("Printer is not operational or currently printing", 409) valid_axes = ["x", "y", "z"] speedTarget = 0 ##~~ jog command if command == "jog": # validate all jog instructions, make sure that the values are numbers validated_values = {} for axis in valid_axes: if axis in data: value = data[axis] if not isinstance(value, (int, long, float)): return make_response("Not a number for axis %s: %r" % (axis, value), 400) validated_values[axis] = value #lkj add if "speed" in data: speedTarget = data["speed"] print("speed=%s" % str(speedTarget)) # execute the jog commands for axis, value in validated_values.iteritems(): #lkj printer.jog(axis, value) printer.jogSpeed(axis, value, speedTarget) ##~~ home command elif command == "home": validated_values = [] axes = data["axes"] for axis in axes: if not axis in valid_axes: return make_response("Invalid axis: %s" % axis, 400) validated_values.append(axis) # execute the home command printer.home(validated_values) elif command == "fastbot": #lkj if "FeedSpeed" in data: print("FeedSpeed=%s" % str(data["FeedSpeed"])) printer.feedSpeed(data["FeedSpeed"]) if "FanID" in data: print("FanID=%s" % str(data["FanID"])) print("on=%s" % str(data["on"])) printer.fanControl(data["FanID"], data["on"]) return NO_CONTENT
def printerToolCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "select": ["tool"], "target": ["targets"], "offset": ["offsets"], "extrude": ["amount"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response validation_regex = re.compile("tool\d+") ##~~ tool selection if command == "select": tool = data["tool"] if re.match(validation_regex, tool) is None: return make_response("Invalid tool: %s" % tool, 400) if not tool.startswith("tool"): return make_response("Invalid tool for selection: %s" % tool, 400) pm.changeTool(tool) ##~~ temperature elif command == "target": targets = data["targets"] # make sure the targets are valid and the values are numbers validated_values = {} for tool, value in targets.iteritems(): if re.match(validation_regex, tool) is None: return make_response("Invalid target for setting temperature: %s" % tool, 400) if not isinstance(value, (int, long, float)): return make_response("Not a number for %s: %r" % (tool, value), 400) validated_values[tool] = value # perform the actual temperature commands for tool in validated_values.keys(): pm.setTemperature(tool, validated_values[tool]) ##~~ extrusion elif command == "extrude": if pm.isPrinting(): # do not extrude when a print job is running return make_response("Printer is currently printing", 409) amount = data["amount"] if not isinstance(amount, (int, long, float)): return make_response("Not a number for extrusion amount: %r" % amount, 400) pm.extrude(None, amount) return NO_CONTENT
def connectionCommand(): valid_commands = { "connect": ["autoconnect"], "disconnect": [], "reconnect": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response pm = printerManager() if command in ["connect", "reconnect"]: s = settings() driver = None port = None baudrate = None options = pm.getConnectionOptions() if "port" in data: port = data["port"] if port not in options["ports"]: return make_response("Invalid port: %s" % port, 400) if "baudrate" in data and data['baudrate']: baudrate = int(data["baudrate"]) if baudrate: baudrates = options["baudrates"] if baudrates and baudrate not in baudrates: return make_response("Invalid baudrate: %d" % baudrate, 400) else: return make_response("Baudrate is null", 400) if "save" in data and data["save"]: s.set(["serial", "port"], port) s.setInt(["serial", "baudrate"], baudrate) if "autoconnect" in data: s.setBoolean(["serial", "autoconnect"], data["autoconnect"]) s.save() if command == "connect": pm.connect(port, baudrate) elif command == "reconnect": pm.reConnect(port, baudrate) elif command == "disconnect": pm.disconnect() return NO_CONTENT
def controlJob(): if not printer.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "start": [], "restart": [], "pause": [], "cancel": [], "stop": [] #add by kevin, for emergency stop } command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response activePrintjob = printer.isPrinting() or printer.isPaused() if command == "start": if activePrintjob: return make_response( "Printer already has an active print job, did you mean 'restart'?", 409) printer.startPrint() elif command == "restart": if not printer.isPaused(): return make_response( "Printer does not have an active print job or is not paused", 409) printer.startPrint() elif command == "pause": if not activePrintjob: return make_response( "Printer is neither printing nor paused, 'pause' command cannot be performed", 409) printer.togglePausePrint() elif command == "cancel": if not activePrintjob: return make_response( "Printer is neither printing nor paused, 'cancel' command cannot be performed", 409) printer.cancelPrint() #add by kevin, for emergency stop elif "stop" == command: printer.stopPrint() if not activePrintjob: return make_response( "Printer is neither printing nor paused, 'cancel' command cannot be performed", 409) printer.cancelPrint() #add end, stop return NO_CONTENT
def gcodeFileCommand(filename, target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) filepath = gcodeManager._uploadFolder verifyResult = _verifyFileExists(target, filename) if verifyResult and gcodeManager._uploadFolder == gcodeManager._usbpath: filename = gcodeManager.startThreadToCopyFile(filename, timeout=3 * 60) #wait for 3 mins fileTempPath = gcodeManager._usbpath gcodeManager._uploadFolder = gcodeManager._localpath elif not verifyResult and gcodeManager._uploadFolder == gcodeManager._usbpath: fileTempPath = gcodeManager._usbpath gcodeManager._uploadFolder = gcodeManager._localpath if not _verifyFileExists(target, filename): gcodeManager._uploadFolder = filepath return make_response( "File not found on '%s': %s" % (target, filename), 404) elif not verifyResult: return make_response("File not found on '%s': %s" % (target, filename), 404) # valid file commands, dict mapping command name to mandatory parameters valid_commands = {"select": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: gcodeManager._uploadFolder = filepath return response if command == "select": # selects/loads a file printAfterLoading = False if "print" in data.keys() and data["print"]: if not printer.isOperational(): gcodeManager._uploadFolder = filepath return make_response( "Printer is not operational, cannot directly start printing", 409) printAfterLoading = True sd = False if target == FileDestinations.SDCARD: filenameToSelect = filename sd = True else: filenameToSelect = gcodeManager.getAbsolutePath(filename) printer.selectFile(filenameToSelect, sd, printAfterLoading) gcodeManager._uploadFolder = filepath return NO_CONTENT
def printFileCommand(filename, target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) if not _verifyFileExists(target, filename): return make_response("File not found on '%s': %s" % (target, filename), 404) # valid file commands, dict mapping command name to mandatory parameters valid_commands = {"select": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response printer = printerManager() if command == "select": # selects/loads a file printAfterLoading = False if data.get('print'): if not printer.isOperational(): #We try at least once printer.connect() start = time.time() connect_timeout = 5 #5 secs while not printer.isOperational( ) and not printer.isClosedOrError( ) and time.time() - start < connect_timeout: time.sleep(1) if not printer.isOperational(): return make_response( "The printer is not responding, can't start printing", 409) printAfterLoading = True sd = False if target == FileDestinations.SDCARD: filenameToSelect = filename sd = True else: filenameToSelect = printer.fileManager.getAbsolutePath(filename) printer.selectFile(filenameToSelect, sd, printAfterLoading) return NO_CONTENT
def printerFanCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = {"set": ["tool", "speed"]} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response pm.fan(data["tool"], data["speed"]) return NO_CONTENT
def controlJob(): printer = printerManager() if not printer.isOperational(): return make_response("Printer is not operational", 409) valid_commands = {"start": [], "restart": [], "pause": [], "cancel": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response activePrintjob = printer.isPrinting() or printer.isPaused() if command == "start": if activePrintjob: return make_response( "Printer already has an active print job, did you mean 'restart'?", 409) printer.startPrint() elif command == "restart": if not printer.isPaused(): return make_response( "Printer does not have an active print job or is not paused", 409) printer.startPrint() elif command == "pause": if not activePrintjob: return make_response( "Printer is neither printing nor paused, 'pause' command cannot be performed", 409) printer.togglePausePrint() elif command == "cancel": if not activePrintjob: response = make_response( json.dumps({ 'id': 'no_active_print', 'msg': "Printer is neither printing nor paused, 'cancel' command cannot be performed" }), 409) response.headers['Content-Type'] = 'application/json' return response return jsonify(printer.cancelPrint()) return NO_CONTENT
def printerFanCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "set": ["tool", "speed"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response pm.fan(data["tool"], data["speed"]) return NO_CONTENT
def setPrinterFlowCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = {"set": ["amount"]} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response pm.setPrintingFlow(data["amount"]) return NO_CONTENT
def printFileCommand(filename, target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) if not _verifyFileExists(target, filename): return make_response("File not found on '%s': %s" % (target, filename), 404) # valid file commands, dict mapping command name to mandatory parameters valid_commands = { "select": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response printer = printerManager() if command == "select": # selects/loads a file printAfterLoading = False if data.get('print'): if not printer.isOperational(): #We try at least once printer.connect() start = time.time() connect_timeout = 5 #5 secs while not printer.isOperational() and not printer.isClosedOrError() and time.time() - start < connect_timeout: time.sleep(1) if not printer.isOperational(): return make_response("The printer is not responding, can't start printing", 409) printAfterLoading = True sd = False if target == FileDestinations.SDCARD: filenameToSelect = filename sd = True else: filenameToSelect = printer.fileManager.getAbsolutePath(filename) printer.selectFile(filenameToSelect, sd, printAfterLoading) return NO_CONTENT
def controlPrinterPrinthead(): if not printer.isOperational() or printer.isPrinting(): # do not jog when a print job is running or we don't have a connection return make_response("Printer is not operational or currently printing", 403) valid_commands = { "jog": [], "home": ["axes"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response movementSpeed = settings().get(["printerParameters", "movementSpeed", ["x", "y", "z"]], asdict=True) valid_axes = ["x", "y", "z"] ##~~ jog command if command == "jog": # validate all jog instructions, make sure that the values are numbers validated_values = {} for axis in valid_axes: if axis in data: value = data[axis] if not isinstance(value, (int, long, float)): return make_response("Not a number for axis %s: %r" % (axis, value), 400) validated_values[axis] = value # execute the jog commands for axis, value in validated_values.iteritems(): # TODO make this a generic method call (printer.jog(axis, value)) to get rid of gcode here printer.commands(["G91", "G1 %s%.4f F%d" % (axis.upper(), value, movementSpeed[axis]), "G90"]) ##~~ home command elif command == "home": validated_values = [] axes = data["axes"] for axis in axes: if not axis in valid_axes: return make_response("Invalid axis: %s" % axis, 400) validated_values.append(axis) # execute the home command # TODO make this a generic method call (printer.home(axis, ...)) to get rid of gcode here printer.commands(["G91", "G28 %s" % " ".join(map(lambda x: "%s0" % x.upper(), validated_values)), "G90"]) return jsonify(SUCCESS)
def setPrinterFlowCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "set": ["amount"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response pm.setPrintingFlow(data["amount"]) return NO_CONTENT
def pluginCommand(name): api_plugins = octoprint.plugin.plugin_manager().get_implementations(octoprint.plugin.SimpleApiPlugin) if not name in api_plugins: return make_response("Not found", 404) api_plugin = api_plugins[name] valid_commands = api_plugin.get_api_commands() if valid_commands is None: return make_response("Method not allowed", 405) command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response response = api_plugin.on_api_command(command, data) if response is not None: return response return NO_CONTENT
def connectionCommand(): valid_commands = {"connect": [], "disconnect": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response if command == "connect": connection_options = getConnectionOptions() port = None baudrate = None printerProfile = None if "port" in data.keys(): port = data["port"] if port not in connection_options["ports"]: return make_response("Invalid port: %s" % port, 400) if "baudrate" in data.keys(): baudrate = data["baudrate"] if baudrate not in connection_options["baudrates"]: return make_response("Invalid baudrate: %d" % baudrate, 400) if "printerProfile" in data.keys(): printerProfile = data["printerProfile"] if not printerProfileManager.exists(printerProfile): return make_response( "Invalid printer profile: %s" % printerProfile, 400) if "save" in data.keys() and data["save"]: settings().set(["serial", "port"], port) settings().setInt(["serial", "baudrate"], baudrate) printerProfileManager.set_default(printerProfile) if "autoconnect" in data.keys(): settings().setBoolean(["serial", "autoconnect"], data["autoconnect"]) settings().save() printer.connect(transport_option_overrides=dict(port=port, baudrate=baudrate), profile=printerProfile) elif command == "disconnect": printer.disconnect() return NO_CONTENT
def pluginCommand(name): api_plugins = octoprint.plugin.plugin_manager().get_implementations( octoprint.plugin.SimpleApiPlugin) if not name in api_plugins: return make_response("Not found", 404) api_plugin = api_plugins[name] valid_commands = api_plugin.get_api_commands() if valid_commands is None: return make_response("Method not allowed", 405) command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response response = api_plugin.on_api_command(command, data) if response is not None: return response return NO_CONTENT
def sdCommand(): if not settings().getBoolean(["feature", "sdSupport"]) or not printer.isOperational() or printer.isPrinting(): return make_response("SD support is disabled", 403) valid_commands = { "init": [], "refresh": [], "release": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "init": printer.initSdCard() elif command == "refresh": printer.refreshSdFiles() elif command == "release": printer.releaseSdCard() return jsonify(SUCCESS)
def controlJob(): if not printer.isOperational(): return make_response("Printer is not operational", 403) valid_commands = { "start": [], "pause": [], "cancel": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "start": printer.startPrint() elif command == "pause": printer.togglePausePrint() elif command == "cancel": printer.cancelPrint() return jsonify(SUCCESS)
def connectionCommand(): valid_commands = { "connect": [], "disconnect": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "connect": connection_options = getConnectionOptions() port = None baudrate = None printerProfile = None if "port" in data.keys(): port = data["port"] if port not in connection_options["ports"]: return make_response("Invalid port: %s" % port, 400) if "baudrate" in data.keys(): baudrate = data["baudrate"] if baudrate not in connection_options["baudrates"]: return make_response("Invalid baudrate: %d" % baudrate, 400) if "printerProfile" in data.keys(): printerProfile = data["printerProfile"] if not printerProfileManager.exists(printerProfile): return make_response("Invalid printer profile: %s" % printerProfile, 400) if "save" in data.keys() and data["save"]: settings().set(["serial", "port"], port) settings().setInt(["serial", "baudrate"], baudrate) printerProfileManager.set_default(printerProfile) if "autoconnect" in data.keys(): settings().setBoolean(["serial", "autoconnect"], data["autoconnect"]) settings().save() printer.connect(port=port, baudrate=baudrate, profile=printerProfile) elif command == "disconnect": printer.disconnect() return NO_CONTENT
def controlPrinterFeeder(): if not printer.isOperational() or printer.isPrinting(): # do not jog when a print job is running or we don't have a connection return make_response("Printer is not operational or currently printing", 403) valid_commands = { "extrude": ["amount"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response extrusionSpeed = settings().get(["printerParameters", "movementSpeed", "e"]) if command == "extrude": amount = data["amount"] if not isinstance(amount, (int, long, float)): return make_response("Not a number for extrusion amount: %r" % amount, 400) # TODO make this a generic method call (printer.extruder([hotend,] amount)) to get rid of gcode here printer.commands(["G91", "G1 E%s F%d" % (data["amount"], extrusionSpeed), "G90"]) return jsonify(SUCCESS)
def printerExtrudeCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = {"extrude": ["amount"]} validation_regex = re.compile("tool\d+") command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response ##~~ extrusion if command == "extrude": if pm.isPrinting(): # do not extrude when a print job is running return make_response("Printer is currently printing", 409) amount = data["amount"] speed = data.get("speed") tool = data.get("tool") if not isinstance(amount, (int, long, float)): return make_response( "Not a number for extrusion amount: %r" % amount, 400) if tool is not None and re.match(validation_regex, tool) is None: return make_response("Invalid extruder value: %r" % tool, 400) if speed and not isinstance(speed, (int, long, float)): speed = None pm.extrude( int(tool[len("tool"):]) if tool is not None else None, amount, speed) return NO_CONTENT
def printerBedCommand(): if not printer.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "target": ["target"], "offset": ["offset"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response ##~~ temperature if command == "target": target = data["target"] # make sure the target is a number if not isinstance(target, (int, long, float)): return make_response("Not a number: %r" % target, 400) # perform the actual temperature command printer.setTemperature("bed", target) ##~~ temperature offset elif command == "offset": offset = data["offset"] # make sure the offset is valid if not isinstance(offset, (int, long, float)): return make_response("Not a number: %r" % offset, 400) if not -50 <= offset <= 50: return make_response("Offset not in range [-50, 50]: %f" % offset, 400) # set the offsets printer.setTemperatureOffset({"bed": offset}) return NO_CONTENT
def gcodeFileCommand(filename, target): if not target in [FileDestinations.LOCAL, FileDestinations.SDCARD]: return make_response("Unknown target: %s" % target, 404) if not _verifyFileExists(target, filename): return make_response("File not found on '%s': %s" % (target, filename), 404) # valid file commands, dict mapping command name to mandatory parameters valid_commands = { "select": [], "slice": [] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response if command == "select": # selects/loads a file printAfterLoading = False if "print" in data.keys() and data["print"] in valid_boolean_trues: if not printer.isOperational(): return make_response("Printer is not operational, cannot directly start printing", 409) printAfterLoading = True sd = False if target == FileDestinations.SDCARD: filenameToSelect = filename sd = True else: filenameToSelect = fileManager.get_absolute_path(target, filename) printer.selectFile(filenameToSelect, sd, printAfterLoading) elif command == "slice": if "slicer" in data.keys(): slicer = data["slicer"] del data["slicer"] if not slicer in slicingManager.registered_slicers: return make_response("Slicer {slicer} is not available".format(**locals()), 400) slicer_instance = slicingManager.get_slicer(slicer) elif "cura" in slicingManager.registered_slicers: slicer = "cura" slicer_instance = slicingManager.get_slicer("cura") else: return make_response("Cannot slice {filename}, no slicer available".format(**locals()), 415) if not octoprint.filemanager.valid_file_type(filename, type="stl"): return make_response("Cannot slice {filename}, not an STL file".format(**locals()), 415) if slicer_instance.get_slicer_properties()["same_device"] and (printer.isPrinting() or printer.isPaused()): # slicer runs on same device as OctoPrint, slicing while printing is hence disabled return make_response("Cannot slice on {slicer} while printing due to performance reasons".format(**locals()), 409) if "gcode" in data.keys() and data["gcode"]: gcode_name = data["gcode"] del data["gcode"] else: import os name, _ = os.path.splitext(filename) gcode_name = name + ".gco" # prohibit overwriting the file that is currently being printed currentOrigin, currentFilename = _getCurrentFile() if currentFilename == gcode_name and currentOrigin == target and (printer.isPrinting() or printer.isPaused()): make_response("Trying to slice into file that is currently being printed: %s" % gcode_name, 409) if "profile" in data.keys() and data["profile"]: profile = data["profile"] del data["profile"] else: profile = None if "printerProfile" in data.keys() and data["printerProfile"]: printerProfile = data["printerProfile"] del data["printerProfile"] else: printerProfile = None if "position" in data.keys() and data["position"] and isinstance(data["position"], dict) and "x" in data["position"] and "y" in data["position"]: position = data["position"] del data["position"] else: position = None select_after_slicing = False if "select" in data.keys() and data["select"] in valid_boolean_trues: if not printer.isOperational(): return make_response("Printer is not operational, cannot directly select for printing", 409) select_after_slicing = True print_after_slicing = False if "print" in data.keys() and data["print"] in valid_boolean_trues: if not printer.isOperational(): return make_response("Printer is not operational, cannot directly start printing", 409) select_after_slicing = print_after_slicing = True override_keys = [k for k in data if k.startswith("profile.") and data[k] is not None] overrides = dict() for key in override_keys: overrides[key[len("profile."):]] = data[key] def slicing_done(target, gcode_name, select_after_slicing, print_after_slicing): if select_after_slicing or print_after_slicing: sd = False if target == FileDestinations.SDCARD: filenameToSelect = gcode_name sd = True else: filenameToSelect = fileManager.get_absolute_path(target, gcode_name) printer.selectFile(filenameToSelect, sd, print_after_slicing) ok, result = fileManager.slice(slicer, target, filename, target, gcode_name, profile=profile, printer_profile_id=printerProfile, position=position, overrides=overrides, callback=slicing_done, callback_args=(target, gcode_name, select_after_slicing, print_after_slicing)) if ok: files = {} location = url_for(".readGcodeFile", target=target, filename=gcode_name, _external=True) result = { "name": gcode_name, "origin": FileDestinations.LOCAL, "refs": { "resource": location, "download": url_for("index", _external=True) + "downloads/files/" + target + "/" + gcode_name } } r = make_response(jsonify(result), 202) r.headers["Location"] = location return r else: return make_response("Could not slice: {result}".format(result=result), 500) return NO_CONTENT
def printerToolCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "select": ["tool"], "target": ["targets"], "offset": ["offsets"], "extrude": ["amount"] } command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response validation_regex = re.compile("tool\d+") ##~~ tool selection if command == "select": tool = data["tool"] if re.match(validation_regex, tool) is None: return make_response("Invalid tool: %s" % tool, 400) if not tool.startswith("tool"): return make_response("Invalid tool for selection: %s" % tool, 400) pm.changeTool(int(tool[len("tool"):])) ##~~ temperature elif command == "target": targets = data["targets"] # make sure the targets are valid and the values are numbers validated_values = {} for tool, value in targets.iteritems(): if re.match(validation_regex, tool) is None: return make_response( "Invalid target for setting temperature: %s" % tool, 400) if not isinstance(value, (int, long, float)): return make_response("Not a number for %s: %r" % (tool, value), 400) validated_values[tool] = value # perform the actual temperature commands for tool in validated_values.keys(): pm.setTemperature(tool, validated_values[tool]) ##~~ extrusion elif command == "extrude": if pm.isPrinting(): # do not extrude when a print job is running return make_response("Printer is currently printing", 409) amount = data["amount"] speed = data.get("speed") tool = data.get("tool") if not isinstance(amount, (int, long, float)): return make_response( "Not a number for extrusion amount: %r" % amount, 400) if tool is not None and re.match(validation_regex, tool) is None: return make_response("Invalid extruder value: %r" % tool, 400) if speed and not isinstance(speed, (int, long, float)): speed = None pm.extrude( int(tool[len("tool"):]) if tool is not None else None, amount, speed) return NO_CONTENT
def gcodeFileCommand(filename, target): if not target in [ FileDestinations.LOCAL, FileDestinations.SDCARD, FileDestinations.FastbotSDCARD ]: return make_response("Unknown target: %s" % target, 404) if not _verifyFileExists(target, filename): return make_response("File not found on '%s': %s" % (target, filename), 404) # valid file commands, dict mapping command name to mandatory parameters valid_commands = {"select": [], "slice": []} command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response if command == "select": # selects/loads a file printAfterLoading = False if "print" in data.keys() and data["print"] in valid_boolean_trues: if not printer.isOperational(): return make_response( "Printer is not operational, cannot directly start printing", 409) printAfterLoading = True if target == FileDestinations.SDCARD: filenameToSelect = filename else: filenameToSelect = fileManager.get_absolute_path(target, filename) printer.selectFile(filenameToSelect, target, printAfterLoading) elif command == "slice": if "slicer" in data.keys(): slicer = data["slicer"] del data["slicer"] if not slicer in slicingManager.registered_slicers: return make_response( "Slicer {slicer} is not available".format(**locals()), 400) slicer_instance = slicingManager.get_slicer(slicer) elif "cura" in slicingManager.registered_slicers: slicer = "cura" slicer_instance = slicingManager.get_slicer("cura") else: return make_response( "Cannot slice {filename}, no slicer available".format( **locals()), 415) if not octoprint.filemanager.valid_file_type(filename, type="stl"): return make_response( "Cannot slice {filename}, not an STL file".format(**locals()), 415) if slicer_instance.get_slicer_properties()["same_device"] and ( printer.isPrinting() or printer.isPaused()): # slicer runs on same device as OctoPrint, slicing while printing is hence disabled return make_response( "Cannot slice on {slicer} while printing due to performance reasons" .format(**locals()), 409) if "gcode" in data.keys() and data["gcode"]: gcode_name = data["gcode"] del data["gcode"] else: import os name, _ = os.path.splitext(filename) gcode_name = name + ".gco" # prohibit overwriting the file that is currently being printed currentOrigin, currentFilename = _getCurrentFile() if currentFilename == gcode_name and currentOrigin == target and ( printer.isPrinting() or printer.isPaused()): make_response( "Trying to slice into file that is currently being printed: %s" % gcode_name, 409) if "profile" in data.keys() and data["profile"]: profile = data["profile"] del data["profile"] else: profile = None if "printerProfile" in data.keys() and data["printerProfile"]: printerProfile = data["printerProfile"] del data["printerProfile"] else: printerProfile = None if "position" in data.keys() and data["position"] and isinstance( data["position"], dict) and "x" in data["position"] and "y" in data["position"]: position = data["position"] del data["position"] else: position = None select_after_slicing = False if "select" in data.keys() and data["select"] in valid_boolean_trues: if not printer.isOperational(): return make_response( "Printer is not operational, cannot directly select for printing", 409) select_after_slicing = True print_after_slicing = False if "print" in data.keys() and data["print"] in valid_boolean_trues: if not printer.isOperational(): return make_response( "Printer is not operational, cannot directly start printing", 409) select_after_slicing = print_after_slicing = True override_keys = [ k for k in data if k.startswith("profile.") and data[k] is not None ] overrides = dict() for key in override_keys: overrides[key[len("profile."):]] = data[key] def slicing_done(target, gcode_name, select_after_slicing, print_after_slicing): if select_after_slicing or print_after_slicing: sd = False if target == FileDestinations.SDCARD: filenameToSelect = gcode_name sd = True else: filenameToSelect = fileManager.get_absolute_path( target, gcode_name) printer.selectFile(filenameToSelect, sd, print_after_slicing) ok, result = fileManager.slice(slicer, target, filename, target, gcode_name, profile=profile, printer_profile_id=printerProfile, position=position, overrides=overrides, callback=slicing_done, callback_args=(target, gcode_name, select_after_slicing, print_after_slicing)) if ok: files = {} location = url_for(".readGcodeFile", target=target, filename=gcode_name, _external=True) result = { "name": gcode_name, "origin": FileDestinations.LOCAL, "refs": { "resource": location, "download": url_for("index", _external=True) + "downloads/files/" + target + "/" + gcode_name } } r = make_response(jsonify(result), 202) r.headers["Location"] = location return r else: return make_response( "Could not slice: {result}".format(result=result), 500) return NO_CONTENT
def printerToolCommand(): pm = printerManager() if not pm.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "select": ["tool"], "target": ["targets"], "offset": ["offsets"], "extrude": ["amount"] } command, data, response = util.getJsonCommandFromRequest( request, valid_commands) if response is not None: return response validation_regex = re.compile("tool\d+") ##~~ tool selection if command == "select": tool = data["tool"] if re.match(validation_regex, tool) is None: return make_response("Invalid tool: %s" % tool, 400) if not tool.startswith("tool"): return make_response("Invalid tool for selection: %s" % tool, 400) pm.changeTool(int(tool[len("tool"):])) ##~~ temperature elif command == "target": targets = data["targets"] # make sure the targets are valid and the values are numbers validated_values = {} for tool, value in targets.iteritems(): if re.match(validation_regex, tool) is None: return make_response( "Invalid target for setting temperature: %s" % tool, 400) if not isinstance(value, (int, long, float)): return make_response("Not a number for %s: %r" % (tool, value), 400) validated_values[tool] = value # perform the actual temperature commands for tool in validated_values.keys(): pm.setTemperature(tool, validated_values[tool]) # update heatUp state # if sum(validated_values.values()) <= 0: # pm.mcHeatingUpUpdate(False) # else: # pm.mcHeatingUpUpdate(True) ## # Comment Added by: Toran Sahu <*****@*****.**> # above commented logic fails # TODO: use comm._gcode_M109 & _gcode_M190 to set temp in setTemperature; add logic to set value of {state: {heatingUp: <true/false>}} # refer _monitor from comm.py, pm.mcHeatingUpUpdate, mc._heatingUp, mc._oksAfterHeatingUp where mc is obj of comm.MachineCom ## ##~~ extrusion elif command == "extrude": if pm.isPrinting(): # do not extrude when a print job is running return make_response("Printer is currently printing", 409) amount = data["amount"] speed = data.get("speed") tool = data.get("tool") if not isinstance(amount, (int, long, float)): return make_response( "Not a number for extrusion amount: %r" % amount, 400) if tool is not None and re.match(validation_regex, tool) is None: return make_response("Invalid extruder value: %r" % tool, 400) if speed and not isinstance(speed, (int, long, float)): speed = None pm.extrude( int(tool[len("tool"):]) if tool is not None else None, amount, speed) return NO_CONTENT
def printerToolCommand(): if not printer.isOperational(): return make_response("Printer is not operational", 409) valid_commands = { "select": ["tool"], "target": ["targets"], "offset": ["offsets"], "extrude": ["amount"] } command, data, response = util.getJsonCommandFromRequest(request, valid_commands) if response is not None: return response validation_regex = re.compile("tool\d+") ##~~ tool selection if command == "select": tool = data["tool"] if re.match(validation_regex, tool) is None: return make_response("Invalid tool: %s" % tool, 400) if not tool.startswith("tool"): return make_response("Invalid tool for selection: %s" % tool, 400) printer.changeTool(tool) ##~~ temperature elif command == "target": targets = data["targets"] # make sure the targets are valid and the values are numbers validated_values = {} for tool, value in targets.iteritems(): if re.match(validation_regex, tool) is None: return make_response("Invalid target for setting temperature: %s" % tool, 400) if not isinstance(value, (int, long, float)): return make_response("Not a number for %s: %r" % (tool, value), 400) validated_values[tool] = value # perform the actual temperature commands for tool in validated_values.keys(): printer.setTemperature(tool, validated_values[tool]) ##~~ temperature offset elif command == "offset": offsets = data["offsets"] # make sure the targets are valid, the values are numbers and in the range [-50, 50] validated_values = {} for tool, value in offsets.iteritems(): if re.match(validation_regex, tool) is None: return make_response("Invalid target for setting temperature: %s" % tool, 400) if not isinstance(value, (int, long, float)): return make_response("Not a number for %s: %r" % (tool, value), 400) if not -50 <= value <= 50: return make_response("Offset %s not in range [-50, 50]: %f" % (tool, value), 400) validated_values[tool] = value # set the offsets printer.setTemperatureOffset(validated_values) ##~~ extrusion elif command == "extrude": if printer.isPrinting(): # do not extrude when a print job is running return make_response("Printer is currently printing", 409) amount = data["amount"] speedTarget = data["speed"] if not isinstance(amount, (int, long, float)): return make_response("Not a number for extrusion amount: %r" % amount, 400) #printer.extrude(amount) print("speed=%s" % str(speedTarget)) printer.extrudeSpeed(amount, speedTarget) return NO_CONTENT