Skip to content

Commit

Permalink
added .hex file support fixes #3
Browse files Browse the repository at this point in the history
  • Loading branch information
Renaud11232 committed Apr 3, 2019
1 parent 2ba898b commit 190968f
Show file tree
Hide file tree
Showing 4 changed files with 61 additions and 34 deletions.
81 changes: 53 additions & 28 deletions octoprint_marlin_flasher/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
import serial
import flask
import pyduinocli
import intelhex
from flask_babel import gettext
import shlex
import zipfile
Expand All @@ -22,6 +23,7 @@ class MarlinFlasherPlugin(octoprint.plugin.SettingsPlugin,

def on_after_startup(self):
self.__sketch = None
self.__sketch_ino = False

def get_settings_defaults(self):
return dict(
Expand All @@ -40,38 +42,56 @@ def get_assets(self):
]
)

def __handle_zip(self, zip_file):
self.__sketch_ino = True
sketch_dir = os.path.join(self.get_plugin_data_folder(), "extracted_sketch")
if os.path.exists(sketch_dir):
shutil.rmtree(sketch_dir)
os.makedirs(sketch_dir)
zip_file.extractall(sketch_dir)
for root, dirs, files in os.walk(sketch_dir):
for f in files:
if f == self._settings.get(["sketch_ino"]):
self.__sketch = root
result = dict(
path=root,
file=f
)
return flask.make_response(flask.jsonify(result), 200)
result = dict(message=gettext("No valid sketch found in the given file."))
return flask.make_response(flask.jsonify(result), 400)

def __handle_hex(self, path):
self.__sketch_ino = False
try:
ih = intelhex.IntelHex()
ih.loadhex(path)
except intelhex.IntelHexError:
result = dict(message=gettext("The given file is not a zip file nor a hex file"))
return flask.make_response(flask.jsonify(result), 400)
self.__sketch = os.path.join(self.get_plugin_data_folder(), "sketch.hex")
shutil.copyfile(path, self.__sketch)
result = dict(
path=self.get_plugin_data_folder(),
file="sketch.hex"
)
return flask.make_response(flask.jsonify(result), 200)

@octoprint.plugin.BlueprintPlugin.route("/upload_sketch", methods=["POST"])
@restricted_access
@admin_permission.require(403)
def upload_sketch(self):
self.__sketch = None
upload_path = "sketch_file." + self._settings.global_get(["server", "uploads", "pathSuffix"])
if upload_path not in flask.request.values:
result = dict(message=gettext("Missing sketch_file."))
return flask.make_response(flask.jsonify(result), 400)
path = flask.request.values[upload_path]
try:
with zipfile.ZipFile(path, "r") as zip_file:
self.__sketch = None
sketch_dir = os.path.join(self.get_plugin_data_folder(), "extracted_sketch")
if os.path.exists(sketch_dir):
shutil.rmtree(sketch_dir)
os.makedirs(sketch_dir)
zip_file.extractall(sketch_dir)
for root, dirs, files in os.walk(sketch_dir):
for f in files:
if f == self._settings.get(["sketch_ino"]):
self.__sketch = root
result = dict(
path=root,
ino=f
)
return flask.make_response(flask.jsonify(result), 200)
shutil.rmtree(sketch_dir)
result = dict(message=gettext("No valid sketch found in the given file."))
return flask.make_response(flask.jsonify(result), 400)
return self.__handle_zip(zip_file)
except zipfile.BadZipfile:
result = dict(message=gettext("The given file was not a valid zip file."))
return flask.make_response(flask.jsonify(result), 400)
return self.__handle_hex(path)

@octoprint.plugin.BlueprintPlugin.route("/cores/search", methods=["GET"])
@restricted_access
Expand All @@ -83,7 +103,7 @@ def search_cores(self):
arduino = self.__get_arduino()
try:
arduino.core_update_index()
result = arduino.core_search(*self.__split(flask.request.values["query"]))
result = arduino.core_search(self.__split(flask.request.values["query"]))
except pyduinocli.ArduinoError as e:
return flask.make_response(self.__get_error_json(e), 400)
return flask.make_response(flask.jsonify(result), 200)
Expand All @@ -98,7 +118,7 @@ def search_libs(self):
arduino = self.__get_arduino()
try:
arduino.lib_update_index()
result = arduino.lib_search(*self.__split(flask.request.values["query"]))
result = arduino.lib_search(self.__split(flask.request.values["query"]))
except pyduinocli.ArduinoError as e:
return flask.make_response(self.__get_error_json(e), 400)
return flask.make_response(flask.jsonify(result), 200)
Expand All @@ -112,7 +132,7 @@ def install_core(self):
return flask.make_response(flask.jsonify(result), 400)
arduino = self.__get_arduino()
try:
arduino.core_install(flask.request.values["core"])
arduino.core_install([flask.request.values["core"]])
except pyduinocli.ArduinoError as e:
return flask.make_response(self.__get_error_json(e), 400)
result = dict(core=flask.request.values["core"])
Expand All @@ -127,7 +147,7 @@ def install_lib(self):
return flask.make_response(flask.jsonify(result), 400)
arduino = self.__get_arduino()
try:
arduino.lib_install(flask.request.values["lib"])
arduino.lib_install([flask.request.values["lib"]])
except pyduinocli.ArduinoError as e:
return flask.make_response(self.__get_error_json(e), 400)
result = dict(lib=flask.request.values["lib"])
Expand All @@ -142,7 +162,7 @@ def uninstall_core(self):
return flask.make_response(flask.jsonify(result), 400)
arduino = self.__get_arduino()
try:
arduino.core_uninstall(flask.request.values["core"])
arduino.core_uninstall([flask.request.values["core"]])
except pyduinocli.ArduinoError as e:
return flask.make_response(self.__get_error_json(e), 400)
result = dict(core=flask.request.values["core"])
Expand All @@ -157,7 +177,7 @@ def uninstall_lib(self):
return flask.make_response(flask.jsonify(result), 400)
arduino = self.__get_arduino()
try:
arduino.lib_uninstall(flask.request.values["lib"])
arduino.lib_uninstall([flask.request.values["lib"]])
except pyduinocli.ArduinoError as e:
return flask.make_response(self.__get_error_json(e), 400)
result = dict(lib=flask.request.values["lib"])
Expand Down Expand Up @@ -211,16 +231,21 @@ def flash(self):
fqbn = "%s:%s" % (fqbn, options)
arduino = self.__get_arduino()
try:
arduino.compile(self.__sketch, fqbn=fqbn)
if self.__sketch_ino:
arduino.compile(self.__sketch, fqbn=fqbn)
transport = self._printer.get_transport()
if not isinstance(transport, serial.Serial):
result = dict(message=gettext("The printer is not connected through Serial."))
return flask.make_response(result, 400)
flash_port = transport.port
_, port, baudrate, profile = self._printer.get_current_connection()
self._printer.disconnect()
arduino.upload(self.__sketch, fqbn=fqbn, port=flash_port)
if self.__sketch_ino:
arduino.upload(sketch=self.__sketch, fqbn=fqbn, port=flash_port)
else:
arduino.upload(fqbn=fqbn, port=flash_port, input=self.__sketch)
self._printer.connect(port, baudrate, profile)
self.__sketch = None
result = dict(message=gettext("Board successfully flashed."))
return flask.make_response(flask.jsonify(result), 200)
except pyduinocli.ArduinoError as e:
Expand Down
5 changes: 3 additions & 2 deletions octoprint_marlin_flasher/static/js/marlin_flasher.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ $(function() {
done: function(e, data) {
new PNotify({
title: gettext("Sketch upload successful"),
text: data.result.ino,
text: data.result.file,
type: "success"
});
self.uploadProgress(0);
Expand All @@ -41,7 +41,8 @@ $(function() {
text: jqXHR.responseJSON.message,
type: "error"
});
}
};
self.uploadProgress(0);
},
progress: function(e, data) {
self.uploadProgress((data.loaded / data.total) * 100);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,15 +7,15 @@
<div id="sketch" class="accordion-body collapse">
<div class="accordion-inner">
<p>
{{ _("Here you can upload whatever firmware you want to be running on your printer. Make sure it's a zip file containing a valid Arduino sketch.") }}
{{ _("Here you can upload whatever firmware you want to be running on your printer. Make sure it's a zip, or hex file containing a valid Arduino sketch for your board.") }}
</p>
<form class="form-horizontal">
<div class="control-group">
<label class="control-label" for="sketch_file">{{ _('Arduino sketch') }} :</label>
<div class="controls">
<span class="btn fileinput-button">
<span>{{ _('Browse') }}</span>
<input id="sketch_file" type="file" name="sketch_file" data-url="{{ url_for("plugin.marlin_flasher.upload_sketch") }}" accept=".zip">
<input id="sketch_file" type="file" name="sketch_file" data-url="{{ url_for("plugin.marlin_flasher.upload_sketch") }}" accept=".zip, .hex">
</span>
</div>
</div>
Expand Down
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
@@ -1,14 +1,15 @@
plugin_identifier = "marlin_flasher"
plugin_package = "octoprint_marlin_flasher"
plugin_name = "OctoPrint-Marlin-Flasher"
plugin_version = "0.1.2"
plugin_version = "0.1.3"
plugin_description = """Plugin that allows you to flash your printer with the latest Marlin version, or Arduino code"""
plugin_author = "Renaud Gaspard"
plugin_author_email = "[email protected]"
plugin_url = "https://github.com/Renaud11232/Octoprint-Marlin-Flasher"
plugin_license = "MIT"
plugin_requires = [
"pyduinocli"
"pyduinocli>=0.1.1",
"intelhex"
]
plugin_additional_data = []
plugin_additional_packages = []
Expand Down

0 comments on commit 190968f

Please sign in to comment.