From 3e65412fbaadc600f4facc991512c92d708a9f71 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 6 Aug 2021 13:17:16 +0200 Subject: [PATCH 1/5] 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 95e18c6..09a64c3 100644 --- a/calibration.html +++ b/calibration.html @@ -294,10 +294,8 @@
First layer gcode generator
-

-

Interpreting Results:

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

@@ -324,10 +322,8 @@
Baseline test print generator
-

-

Interpreting Results:

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

@@ -752,8 +748,6 @@
Retraction tuning tower generator
-

-

Interpreting Results:

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

@@ -810,8 +804,6 @@
Temperature tuning tower generator
-

-

Interpreting Results:

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

@@ -922,8 +914,6 @@
Acceleration & jerk/junction deviation tuning tower generator
-

-

This gcode will raise the acceleration limits (M201), set acceleration (M204) and set junction deviation/jerk (M205) for the purposes of the test. If you print another job afterwards these higher values will still be in place. If you are unsure how to restore your previous values, the easiest thing to do is to power cycle the printer.

Interpreting Results:

diff --git a/js/commongcode.js b/js/commongcode.js index e110a18..344c6d5 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 1aea81b..bdbb9db 100644 --- a/js/createform.js +++ b/js/createform.js @@ -459,6 +459,13 @@ var endGcode = /*html*/ `

Additional end gcode

var preview = /*html*/ `

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

Download

+

+

+

+

+`; + function createForm(n){ document.write('') document.write(nozzleLayer); @@ -495,4 +502,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 1e5f6d1..74194a7 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -118,7 +118,6 @@ function updateFeedsTower(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; @@ -600,37 +599,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"; @@ -728,6 +704,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 bf063aeb7fcc1c8943affbdea035630c1dc7f425 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Wed, 11 Aug 2021 16:00:02 +0200 Subject: [PATCH 2/5] Fix filename generation for Output Settings --- js/createform.js | 2 +- js/gcodeprocessing.js | 6 ++++-- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/js/createform.js b/js/createform.js index bdbb9db..8d2c748 100644 --- a/js/createform.js +++ b/js/createform.js @@ -460,7 +460,7 @@ var endGcode = /*html*/ `

Additional end gcode

var preview = /*html*/ `

It is advised to preview the generated gcode through your slicer or Zupfe GCode Viewer before printing.`; var downloadGcodeHtml = /*html*/ `

Download

-

+

diff --git a/js/gcodeprocessing.js b/js/gcodeprocessing.js index 74194a7..9f717d3 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -715,8 +715,9 @@ function downloadGcode(form, fileName) { // process finished gcode file if (!fileName) { - fileName = form.description.value + ".gcode"; + fileName = form.description.value; } + fileName += ".gcode"; var output = ""; // prefix each line with ; to indicate comment @@ -729,7 +730,8 @@ function downloadSettings(form, fileName) { var settings = outputSettings(form); if (!fileName) { - fileName = form.description.value + "settings.txt"; + fileName = form.description.value; } + fileName += "settings.txt"; downloadFile(fileName, settings); } From 3f2fe1b4889ad02fed9ec8051fd7e1489f909029 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 6 Aug 2021 13:17:16 +0200 Subject: [PATCH 3/5] Improve download function - Allow to specify used filename - Output all settings as a comment on top of gcode - Unify download buttons --- calibration.html | 2 -- js/createform.js | 2 +- js/gcodeprocessing.js | 10 +++------- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/calibration.html b/calibration.html index 09a64c3..9d397b0 100644 --- a/calibration.html +++ b/calibration.html @@ -1174,8 +1174,6 @@
Speed/feedrate tuning tower generator
-

-

Interpreting Results:

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

diff --git a/js/createform.js b/js/createform.js index 8d2c748..bdbb9db 100644 --- a/js/createform.js +++ b/js/createform.js @@ -460,7 +460,7 @@ var endGcode = /*html*/ `

Additional end gcode

var preview = /*html*/ `

It is advised to preview the generated gcode through your slicer or Zupfe GCode Viewer before printing.`; var downloadGcodeHtml = /*html*/ `

Download

-

+

diff --git a/js/gcodeprocessing.js b/js/gcodeprocessing.js index 9f717d3..08db144 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -714,9 +714,7 @@ function downloadGcode(form, fileName) { var settings = outputSettings(form); // process finished gcode file - if (!fileName) { - fileName = form.description.value; - } + fileName = fileName.trimRight(".gcode"); fileName += ".gcode"; var output = ""; @@ -729,9 +727,7 @@ function downloadGcode(form, fileName) { function downloadSettings(form, fileName) { var settings = outputSettings(form); - if (!fileName) { - fileName = form.description.value; - } - fileName += "settings.txt"; + fileName = fileName.trimRight(".gcode"); + fileName += "_settings.txt"; downloadFile(fileName, settings); } From 9c437eb2bd1d00da5c9b68bfa1d28e8de4b8475f Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 6 Aug 2021 15:04:03 +0200 Subject: [PATCH 4/5] Add `Upload&Print Gcode` option - Allow to specify URL/API key - Upload&Print directly - Document what needs to be configured --- js/createform.js | 26 ++++++++++++- js/gcodeprocessing.js | 91 ++++++++++++++++++++++++++++++++++++++----- js/persist.js | 1 + 3 files changed, 106 insertions(+), 12 deletions(-) diff --git a/js/createform.js b/js/createform.js index bdbb9db..429532e 100644 --- a/js/createform.js +++ b/js/createform.js @@ -460,10 +460,32 @@ var endGcode = /*html*/ `

Additional end gcode

var preview = /*html*/ `

It is advised to preview the generated gcode through your slicer or Zupfe GCode Viewer before printing.`; 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 08db144..ccbb763 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -708,26 +708,97 @@ function outputSettings(formName) { return string; } - -function downloadGcode(form, fileName) { +function getGcodeAndSettings(form) { var gcode = processGcode(form); var settings = outputSettings(form); - // process finished gcode file - fileName = fileName.trimRight(".gcode"); - fileName += ".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; + } + fileName = fileName.trimRight(".gcode"); + fileName += ".gcode"; + downloadFile(fileName, getGcodeAndSettings(form)); +} + +function downloadSettings(form, fileName) { + if (!fileName) { + fileName = form.description.value; + } fileName = fileName.trimRight(".gcode"); fileName += "_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]; + fileName = fileName.trimRight(".gcode"); + fileName += ".gcode"; + + // 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 a0f2006194b9d501106c3294a30be9d95f420e57 Mon Sep 17 00:00:00 2001 From: Kamil Trzcinski Date: Fri, 6 Aug 2021 19:35:43 +0200 Subject: [PATCH 5/5] Use `POST` form instead of `XHR` This allows to send files without having to configure CORS. --- calibration.html | 8 +++++++ js/createform.js | 12 ++-------- js/gcodeprocessing.js | 52 ++++++++----------------------------------- 3 files changed, 19 insertions(+), 53 deletions(-) diff --git a/calibration.html b/calibration.html index 9d397b0..ad8f3e0 100644 --- a/calibration.html +++ b/calibration.html @@ -1180,6 +1180,14 @@

Interpreting Results:

You may wish to stop the print early if it is clear extrusion has ceased or become unreliable. This may prevent the need for disassembly of the extruder to clear the blockage.

+ +
diff --git a/js/createform.js b/js/createform.js index 429532e..bb2b527 100644 --- a/js/createform.js +++ b/js/createform.js @@ -473,16 +473,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 .
  • -
  • Restart afterwards
  • +
  • Login to your Octoprint from this browser
  • +
  • Or get API Key from User Settings > Application Keys
diff --git a/js/gcodeprocessing.js b/js/gcodeprocessing.js index ccbb763..87b42d7 100644 --- a/js/gcodeprocessing.js +++ b/js/gcodeprocessing.js @@ -749,56 +749,22 @@ function uploadGcode(form, fileName) { // get only basename if (!fileName) { - fileName = form.description.value + ".gcode"; + fileName = form.description.value; } + fileName += ".gcode"; fileName = fileName.split('/').reverse()[0]; fileName = fileName.trimRight(".gcode"); fileName += ".gcode"; // remove `/` from the end of URL - var url = form.octoprint_url.value.replace(/\/$/, ''); + 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"); + const dataTransfer = new DataTransfer(); + dataTransfer.items.add(new File([output], fileName, {type : 'text/plain'})); - 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(); }