From 01b7774e6af93be0029c4eebdaeea1f856467786 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 6 Aug 2021 13:17:16 +0200 Subject: [PATCH 1/3] Improve download function - Allow to specify used filename - Output all settings as a comment on top of gcode - Unify download buttons --- calibration.html | 14 ++-------- js/commongcode.js | 4 +-- js/createform.js | 10 ++++++- js/gcodeprocessing.js | 64 ++++++++++++++++++++++--------------------- 4 files changed, 45 insertions(+), 47 deletions(-) diff --git a/calibration.html b/calibration.html index dd25130..1ecd2e2 100644 --- a/calibration.html +++ b/calibration.html @@ -255,10 +255,8 @@
First layer gcode generator
-

-

Interpreting Results:

Please use the following video as a guide to this test:

@@ -285,10 +283,8 @@
Baseline test print generator
-

-

Interpreting Results:

Please use the following video as a guide to this test:

@@ -690,8 +686,6 @@
Retraction tuning tower generator
-

-

Interpreting Results:

Please use the following video as a guide to this test:

@@ -748,8 +742,6 @@
Temperature tuning tower generator
-

-

Interpreting Results:

Please use the following video as a guide to this test:

@@ -855,8 +847,6 @@
Acceleration & jerk/junction deviation tuning tower generator
-

-

Interpreting Results:

Please use the following video as a guide to this test:

diff --git a/js/commongcode.js b/js/commongcode.js index 7d2ba1a..09091ed 100644 --- a/js/commongcode.js +++ b/js/commongcode.js @@ -1,6 +1,4 @@ -var commonStart = `; G-Code originally generated by Simplify3D(R) Version 4.1.2 -; This calibration test gcode modified by the Teaching Tech Calibration website: https://teachingtechyt.github.io/calibration.html -;M80 ; power supply on +var commonStart = `;M80 ; power supply on G90 M82 M106 S0 diff --git a/js/createform.js b/js/createform.js index d370596..b19cf54 100644 --- a/js/createform.js +++ b/js/createform.js @@ -326,6 +326,13 @@ var endGcode = /*html*/ `

Additional end gcode

var preview = /*html*/ `

It is advised to preview the generated gcode through your slicer or Gcode.ws before printing.`; +var downloadGcodeHtml = /*html*/ `

Download

+

+

+

+

+`; + function createForm(n){ document.write('') document.write(nozzleLayer); @@ -357,4 +364,5 @@ function createForm(n){ } document.write(endGcode); document.write(preview); -} \ No newline at end of file + document.write(downloadGcodeHtml.replaceAll('{formName}', n)); +} diff --git a/js/gcodeprocessing.js b/js/gcodeprocessing.js index 927ce74..0142790 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -112,7 +112,6 @@ function updateFeeds(feedrate) { function processGcode(formName) { var name = formName.name; - var description = formName.description.value; var nozzleLayer = formName.nozzleLayer.value; var bedTemp = formName.bedtemp.value; var centre = formName.centre.checked; @@ -544,37 +543,14 @@ function processGcode(formName) { if(formName.deltaHome.checked == true) { gcode = gcode.replace(/G28 X0 ; home X axis/, "G28 ; home all on delta"); } - - // process finished gcode file - downloadFile(description+'.gcode', gcode); + + return gcode; } function outputSettings(formName) { - var fileName; - var string = "Settings for "; - switch(formName.name) { - case "firstlayerForm": - string += "first layer" - fileName = "firstlayersettings.txt"; - break; - case "baselineForm": - string += "baseline print" - fileName = "baselinesettings.txt"; - break; - case "retractionForm": - string += "retraction tuning" - fileName = "retractionsettings.txt"; - break; - case "temperatureForm": - string += "temperature tuning" - fileName = "temperaturesettings.txt"; - break; - case "accelerationForm": - string += "acceleration and jerk/junction deviation tuning" - fileName = "accelerationsettings.txt"; - break; - } - string += " form\n_________________________________________________________________________\n\n"; + var string = ""; + string += "Settings for " + formName.description.value + " form\n"; + string += "_________________________________________________________________________\n\n"; string += "G-Code originally generated by Simplify3D(R) Version 4.1.2\nThis calibration test gcode modified by the Teaching Tech Calibration website: https://teachingtechyt.github.io/calibration.html\n"; string += "All changes are marked in the gcode with 'custom' at the end of each line. Open the gcode in a text editor and search for this to your check inputs if needed.\n\n"; if(formName.psuon.checked == true) { @@ -653,6 +629,32 @@ function outputSettings(formName) { string += " B | "+formName.accel_b1.value+" mm/sec/sec | "+formName.accel_b4.value+"\n"; string += " A | "+formName.accel_a1.value+" mm/sec/sec | "+formName.accel_a4.value+"\n"; } - } - downloadFile(fileName, string); + } + return string; +} + + +function downloadGcode(form, fileName) { + var gcode = processGcode(form); + var settings = outputSettings(form); + + // process finished gcode file + if (!fileName) { + fileName = form.description.value + ".gcode"; + } + + var output = ""; + // prefix each line with ; to indicate comment + output += "; " + settings.replaceAll("\n", "\n; "); + output += gcode; + downloadFile(fileName, output); +} + +function downloadSettings(form, fileName) { + var settings = outputSettings(form); + + if (!fileName) { + fileName = form.description.value + "settings.txt"; + } + downloadFile(fileName, settings); } From 1a1cf386a181e9733c11bbb7132759b41c7cab8d Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 6 Aug 2021 15:04:03 +0200 Subject: [PATCH 2/3] Add `Upload&Print Gcode` option - Allow to specify URL/API key - Upload&Print directly - Document what needs to be configured --- js/createform.js | 24 +++++++++++- js/gcodeprocessing.js | 85 +++++++++++++++++++++++++++++++++++++------ js/persist.js | 1 + 3 files changed, 98 insertions(+), 12 deletions(-) diff --git a/js/createform.js b/js/createform.js index b19cf54..82366ab 100644 --- a/js/createform.js +++ b/js/createform.js @@ -328,9 +328,31 @@ var preview = /*html*/ `

It is advised to preview the generated gcode through var downloadGcodeHtml = /*html*/ `

Download

-

+

+

+ +

Octoprint / Moonraker

+

You can directly print from this website if you specify Octoprint or Moonraker server.

+

+

+
+ +
    +
  • Get API Key go to User Settings > Application Keys and manually generate new application key.
  • +
  • Enable CORS support by going to OctoPrint Settings > API and checking Allow Cross Origin Resource Sharing (CORS). Restart afterwards
  • +
  • Restart afterwards
  • +
+ + +
    +
  • As part of the [authorization] config + add to cors_domains: the .
  • +
  • Restart afterwards
  • +
+
+ `; function createForm(n){ diff --git a/js/gcodeprocessing.js b/js/gcodeprocessing.js index 0142790..1bda590 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -633,28 +633,91 @@ function outputSettings(formName) { return string; } - -function downloadGcode(form, fileName) { +function getGcodeAndSettings(form) { var gcode = processGcode(form); var settings = outputSettings(form); - // process finished gcode file - if (!fileName) { - fileName = form.description.value + ".gcode"; - } - var output = ""; // prefix each line with ; to indicate comment output += "; " + settings.replaceAll("\n", "\n; "); output += gcode; - downloadFile(fileName, output); + return output; } -function downloadSettings(form, fileName) { - var settings = outputSettings(form); +function downloadGcode(form, fileName) { + if (!fileName) { + fileName = form.description.value + ".gcode"; + } + + downloadFile(fileName, getGcodeAndSettings(form)); +} +function downloadSettings(form, fileName) { if (!fileName) { fileName = form.description.value + "settings.txt"; } - downloadFile(fileName, settings); + + downloadFile(fileName, outputSettings(form)); +} + +function uploadGcode(form, fileName) { + var output = getGcodeAndSettings(form); + + if (!form.octoprint_url.value) { + alert("No URL specified for Octoprint or Moonraker."); + return; + } + + // get only basename + if (!fileName) { + fileName = form.description.value + ".gcode"; + } + fileName = fileName.split('/').reverse()[0]; + + // remove `/` from the end of URL + var url = form.octoprint_url.value.replace(/\/$/, ''); + url += "/api/files/local"; + + // this detects a `mixed-context` scenario: + // sending request to `http:` when connected via `https:` is not possible + if (window.location.protocol == "https:" && url.toLowerCase().startsWith("http:")) { + httpUrl = window.location.href.replace('https:', 'http:'); + + alert("Your local Octoprint/Moonraker uses `http://`. " + + "You need to open the `" + httpUrl + "` instead"); + return; + } + + const formData = new FormData(); + formData.append("file", new Blob([output], {type : 'text/plain'}), fileName); + formData.append("path", "TeachingTechYT"); + formData.append("select", "true"); + formData.append("print", "true"); + + fetch(url, { + method: "POST", + body: formData, + headers: { + 'X-Api-Key': form.octoprint_key.value + } + }) + .then(response => { + if (response.ok) { + response.json().then(data => { + if (data.print_started) { + alert("Successfully uploaded and started print from " + fileName); + } else { + alert("Successfully uploaded, but print was not started from " + fileName); + } + }); + } else { + alert("Failed to upload due to " + response.statusText); + } + }) + .catch((error) => { + alert("Failed to upload due to an error. Possible causes:\n" + + "- CORS not configured properly\n" + + "- url does not start with `http://` or `https://`\n" + + "\n" + error); + }); } diff --git a/js/persist.js b/js/persist.js index 548d312..38a03da 100644 --- a/js/persist.js +++ b/js/persist.js @@ -17,6 +17,7 @@ function loadFormData(form) { element.tagName == "INPUT" && element.type == "checkbox" || element.tagName == "INPUT" && element.type == "radio" || element.tagName == "INPUT" && element.type == "text" || + element.tagName == "INPUT" && element.type == "password" || element.tagName == "TEXTAREA" || element.tagName == "SELECT" ) { From 2ca0c46467c8b13cb53a1fbb021eae40fe51d6f6 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 6 Aug 2021 19:35:43 +0200 Subject: [PATCH 3/3] Use `POST` form instead of `XHR` This allows to send files without having to configure CORS. --- calibration.html | 8 ++++++++ js/createform.js | 11 ++-------- js/gcodeprocessing.js | 47 ++++++------------------------------------- 3 files changed, 16 insertions(+), 50 deletions(-) diff --git a/calibration.html b/calibration.html index 1ecd2e2..a231867 100644 --- a/calibration.html +++ b/calibration.html @@ -1034,6 +1034,14 @@

Fixing persistent dimensional accuracy after X/Y/Z steps per unit have been

One final measure, that is the least desirable, is to design parts to be printed bigger or smaller to compensate. This is a band aid approach and falls apart very quickly once we print geometry designed by other people.

+ +
diff --git a/js/createform.js b/js/createform.js index 82366ab..4b6d7e7 100644 --- a/js/createform.js +++ b/js/createform.js @@ -340,15 +340,8 @@ var downloadGcodeHtml = /*html*/ `

Download

    -
  • Get API Key go to User Settings > Application Keys and manually generate new application key.
  • -
  • Enable CORS support by going to OctoPrint Settings > API and checking Allow Cross Origin Resource Sharing (CORS). Restart afterwards
  • -
  • Restart afterwards
  • -
- - -
    -
  • As part of the [authorization] config - add to cors_domains: the .
  • +
  • Login to your Octoprint
  • +
  • or get API Key go to User Settings > Application Keys and manually generate new application key.
  • Restart afterwards
diff --git a/js/gcodeprocessing.js b/js/gcodeprocessing.js index 1bda590..c57df76 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -678,46 +678,11 @@ function uploadGcode(form, fileName) { var url = form.octoprint_url.value.replace(/\/$/, ''); url += "/api/files/local"; - // this detects a `mixed-context` scenario: - // sending request to `http:` when connected via `https:` is not possible - if (window.location.protocol == "https:" && url.toLowerCase().startsWith("http:")) { - httpUrl = window.location.href.replace('https:', 'http:'); + const dataTransfer = new DataTransfer(); + dataTransfer.items.add(new File([output], fileName, {type : 'text/plain'})); - alert("Your local Octoprint/Moonraker uses `http://`. " + - "You need to open the `" + httpUrl + "` instead"); - return; - } - - const formData = new FormData(); - formData.append("file", new Blob([output], {type : 'text/plain'}), fileName); - formData.append("path", "TeachingTechYT"); - formData.append("select", "true"); - formData.append("print", "true"); - - fetch(url, { - method: "POST", - body: formData, - headers: { - 'X-Api-Key': form.octoprint_key.value - } - }) - .then(response => { - if (response.ok) { - response.json().then(data => { - if (data.print_started) { - alert("Successfully uploaded and started print from " + fileName); - } else { - alert("Successfully uploaded, but print was not started from " + fileName); - } - }); - } else { - alert("Failed to upload due to " + response.statusText); - } - }) - .catch((error) => { - alert("Failed to upload due to an error. Possible causes:\n" + - "- CORS not configured properly\n" + - "- url does not start with `http://` or `https://`\n" + - "\n" + error); - }); + document.octoprintForm.action = url; + document.octoprintForm.file.files = dataTransfer.files; + document.octoprintForm.apikey.value = form.octoprint_key.value; + document.octoprintForm.submit(); }