From 4a06f0dc0b8fd55baa79e535c6607d61d693c629 Mon Sep 17 00:00:00 2001 From: Joey Date: Fri, 23 Feb 2018 16:07:09 -0500 Subject: [PATCH] Alpha v0.9.1 MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Turns out Web Sockets isn’t that great for sending GCode. Now GCode is sent via the REST API and the printer response is displayed via Web Sockets. Relative Position will be only resent when needed. ie after a home request or after page reload. Better print/cancel button status. --- README.md | 21 +++++++------- source/webui.js | 67 +++++++++++++++++++++++++++------------------ source/webui.min.js | 2 +- webui.html | 9 +++--- 4 files changed, 57 insertions(+), 42 deletions(-) diff --git a/README.md b/README.md index c4d2543..8d8099f 100644 --- a/README.md +++ b/README.md @@ -4,11 +4,11 @@ Upgrade the Malyan M200 or the Monoprice Select Mini's V1 Web UI and enable faster Wi-Fi file uploads automatically. For V2, download the [V2 branch](https://github.com/nokemono42/MP-Select-Mini-Web/tree/v2). -Note: Requires UI Controller firmware version 42 or greater to enable the custom Web UI. This has not been tested on anything lower then firmware version 42. +Note: Requires UI Controller firmware version 42 or greater to enable a custom Web UI. -![Image of printer LCD](https://mpselectmini.com/_detail/firmware_version_explanation.png) +![Image of printer LCD](https://mpselectmini.com/_media/firmware_version_explanation.png?cache= =333x250) -This Web UI is built using Bootstrap so its mobile-friendly and tablet-friendly. Multiple browser connections are supported. GCode commands are sent via Web Sockets so all browser windows will display the printer responses. +This Web UI is built using Bootstrap so its mobile-friendly and tablet-friendly. Multiple browser connections are supported. GCode responses are sent via Web Sockets so all browser windows will display the printer responses. GCode commands are sent via the REST API since sending via Web Sockets proved to be unreliable. ![Image of the WebUI](https://raw.githubusercontent.com/nokemono42/MP-Select-Mini-Web/master/screenshot.png) @@ -36,9 +36,9 @@ M563 parameters can be values between S2 - S6. Transfers happen over telnet whic | M563 S# | Avg Transfer Speed | Supported On | | ------- | -----------------: | ------------------------ | | S2 | 39 Kbps | Same as Firmware Default | -| S3 | 63 Kbps | All | -| S4 | 90 Kbps | All | -| S5 | 102 Kbps | V2 / Delta | +| S3 | 63 Kbps | V1 / V2 / Delta | +| S4 | 91 Kbps | V1 / V2 / Delta | +| S5 | 103 Kbps | V2 | | S6 | 112 Kbps | V1 | @@ -71,12 +71,13 @@ Mario Anthony Galliano (Facebook Group posting with upgrade/downgrade instructio ## Upcoming Improvements -* Test on MPSM V2 +* Test on MP Select Mini V2 +* Create V2 Branch +* Create Delta Mini repo * Change multiplier -* Show time lasped / time remaining -* Show filename that is printing -* Rename cache.gc file with M566 after upload +* Rename cache.gc file with M566 after upload (Pending more SD functions) * Query SD card for list of files M20 * Delete file from SD card M30 * Print file from SD card M24 * Pause print M25 +* Start printer state. If inquiry not able to load, reset page bool values. (Same as page refresh) \ No newline at end of file diff --git a/source/webui.js b/source/webui.js index 2188be1..f6aec99 100644 --- a/source/webui.js +++ b/source/webui.js @@ -5,7 +5,11 @@ URL: https://github.com/nokemono42/MP-Select-Mini-Web $(document).ready(function() { printerStatus(); - startup(); + initWebSocket(); + + setTimeout(function() { + startup(); + }, 2000); setInterval(function() { printerStatus(); @@ -23,6 +27,7 @@ $(document).ready(function() { } sendCmd(code, 'Home ' + comment); + setPositioning = false; }); $(".movement .direction button").click(function() { @@ -32,17 +37,22 @@ $(document).ready(function() { axis = $(this).attr("data-axis"); comment = 'Move ' + axis; + if (setPositioning == false) { + sendCmd('G91', 'Set to Relative Positioning'); + setPositioning = true; + } + if (movement == 'up' || movement == 'left') { rate = rate * -1; } if (axis == 'Z' && movement == 'down') { comment = 'Raise Z '; } if (axis == 'Z' && movement == 'up') { comment = 'Lower Z '; } if (axis == 'E' && movement == 'plus') { comment = 'Extrude '; } if (axis == 'E' && movement == 'minus') { sendCmd(command + axis + '-' + rate, 'Retract ' + rate + 'mm'); - return false; + return; } if (movement == 'disable') { sendCmd('M18', 'Disable motor lock'); - return false; + return; } sendCmd(command + axis + rate, comment + ' ' + rate + 'mm'); @@ -108,6 +118,7 @@ $(document).ready(function() { }); var timers = {}; +var setPositioning = false; function pad(num, size) { s = '000' + num; @@ -120,10 +131,20 @@ function scrollConsole() { } function feedback(output) { - msg = output.replace(/N0 P15 B15/g, ''); - msg = msg.replace(/N0 P14 B15/g, ''); - msg = msg.replace(/echo:/g, ''); - $("#gCodeLog").append('

' + msg + '

'); + if (output.substring(0, 2) == 'T:') { + //Hide temperature reporting + return; + } + + if (output.substring(0, 5) == 'ok N0') { + output = 'ok'; + } + + $("#gCodeLog").append('

' + output + '

'); + + //if (output.substring(0, 5) == 'Begin') { + //$(".sd-files").html('

' + output + '

'); + //} scrollConsole(); } @@ -132,13 +153,8 @@ function sendCmd(code, comment, type) { $("#gCodeLog").append('

' + code + ' ; ' + comment + '

'); - if (type == 'cmd') { - $.ajax({ url: 'set?' + type + '=' + code, cache: false }).done(function(data) { - feedback(data); - }); - } else { - ws.send(code); - } + $.ajax({ url: 'set?' + type + '=' + code, cache: false }).done(); + //ws.send(code); scrollConsole(); } @@ -149,7 +165,7 @@ function initWebSocket() { try { ws = new WebSocket('ws://' + url + ':81'); ws.onopen = function() { - feedback('Connected'); + feedback('Connection Established'); }; ws.onmessage = function(a) { feedback(a.data); @@ -183,7 +199,7 @@ Dropzone.options.mydz = { accept: function(file, done) { if (file.name.contains('.g')) { //window.startTimer = new Date(); - + done(); $(".print-actions button").addClass('btn-disable'); $(".movement button").addClass('btn-disable'); @@ -214,7 +230,10 @@ Dropzone.options.mydz = { $(".movement button").removeClass('btn-disable'); $("#gCodeSend").removeClass('btn-disable'); $(".temperature button").removeClass('btn-disable'); - sendCmd('M566 ' + file.name, ''); + + //setTimeout(function() { + //sendCmd('M566 ' + file.name, ''); + //}, 1000); }); } }; @@ -245,12 +264,14 @@ function printerStatus() { if (c == 'I') { $("#stat").text('Idle'); $("#pgs").css('width', '0%'); + $("#start_print").removeClass('btn-disable'); $(".movement button").removeClass('btn-disable'); $("#gCodeSend").removeClass('btn-disable'); } else if (c == 'P') { $("#stat").text('Printing'); $("#pgs").css('width', data.match(/\d+/g )[4] + '%'); $("#pgs").html(data.match(/\d+/g )[4] + '% Complete'); + $("#start_print").addClass('btn-disable'); $(".movement button").addClass('btn-disable'); $("#gCodeSend").addClass('btn-disable'); } else { @@ -260,15 +281,8 @@ function printerStatus() { } function startup() { - initWebSocket(); - if ($("#stat").text() != 'Printing') { - setTimeout(function() { - sendCmd('M563 S4', 'Enable faster Wi-Fi file uploads'); - sendCmd('G91', 'Set to Relative Positioning'); - }, 1750); - } else { - alert('Printing'); + sendCmd('M563 S6', 'Enable faster Wi-Fi file uploads'); } } @@ -304,5 +318,6 @@ function delaySyncTemperatures(extruder, platform) { } function refreshSD() { - sendCmd('M563 S3', 'Enable faster Wi-Fi file uploads'); + sendCmd('M21', 'Initialize SD card'); + sendCmd('M20', 'List SD card files'); } \ No newline at end of file diff --git a/source/webui.min.js b/source/webui.min.js index 7444f14..2028eac 100644 --- a/source/webui.min.js +++ b/source/webui.min.js @@ -1 +1 @@ -function pad(e,t){return s="000"+e,s.substr(s.length-t)}function scrollConsole(){$cont=$("#console"),$cont[0].scrollTop=$cont[0].scrollHeight}function feedback(e){msg=e.replace(/N0 P15 B15/g,""),msg=msg.replace(/N0 P14 B15/g,""),msg=msg.replace(/echo:/g,""),$("#gCodeLog").append('

'+msg+"

"),scrollConsole()}function sendCmd(e,t,n){void 0===n&&(n="code"),$("#gCodeLog").append('

'+e+' ; '+t+"

"),"cmd"==n?$.ajax({url:"set?"+n+"="+e,cache:!1}).done(function(e){feedback(e)}):ws.send(e),scrollConsole()}function initWebSocket(){url=window.location.hostname;try{ws=new WebSocket("ws://"+url+":81"),ws.onopen=function(){feedback("Connected")},ws.onmessage=function(e){feedback(e.data)},ws.onclose=function(){feedback("Disconnected")}}catch(e){feedback("Web Socket Error")}}function msToTime(e){var t=parseInt(e%1e3/100),n=parseInt(e/1e3%60),a=parseInt(e/6e4%60),o=parseInt(e/36e5%24);return o=o<10?"0"+o:o,a=a<10?"0"+a:a,n=n<10?"0"+n:n,o+":"+a+":"+n+"."+t}function start_p(){$("#stat").text("Printing"),sendCmd("M565","Start printing cache.gc")}function cancel_p(){$("#stat").text("Canceling"),sendCmd("{P:X}","Cancel print","cmd")}function printerStatus(){$.get("inquiry",function(e,t){$("#rde").text(e.match(/\d+/g)[0]),$("#rdp").text(e.match(/\d+/g)[2]),delaySyncTemperatures(e.match(/\d+/g)[1],e.match(/\d+/g)[3]);var n=e.charAt(e.length-1);"I"==n?($("#stat").text("Idle"),$("#pgs").css("width","0%"),$(".movement button").removeClass("btn-disable"),$("#gCodeSend").removeClass("btn-disable")):"P"==n?($("#stat").text("Printing"),$("#pgs").css("width",e.match(/\d+/g)[4]+"%"),$("#pgs").html(e.match(/\d+/g)[4]+"% Complete"),$(".movement button").addClass("btn-disable"),$("#gCodeSend").addClass("btn-disable")):$("#stat").text("N/A")})}function startup(){initWebSocket(),"Printing"!=$("#stat").text()?setTimeout(function(){sendCmd("M563 S4","Enable faster Wi-Fi file uploads"),sendCmd("G91","Set to Relative Positioning")},1750):alert("Printing")}function delaySendTemp(e,t){clearTimeout(timers),timers=setTimeout(function(){compValue=pad(e,3),"extruder"==t&&sendCmd("{C:T0"+compValue+"}","Set extruder preheat to "+e+"°C","cmd"),"platform"==t&&sendCmd("{C:P"+compValue+"}","Set platform preheat to "+e+"°C","cmd")},250)}function delaySendSpeed(e){clearTimeout(timers),timers=setTimeout(function(){actualSpeed=Math.floor(255*(e/100)),sendCmd("M106 S"+actualSpeed,"Set fan speed to "+e+"%")},250)}function delaySyncTemperatures(e,t){clearTimeout(timers),timers=setTimeout(function(){$("#wre").is(":focus")||$("#wre").val(e),$("#wrp").is(":focus")||$("#wrp").val(t)},3e3)}function refreshSD(){sendCmd("M563 S3","Enable faster Wi-Fi file uploads")}$(document).ready(function(){printerStatus(),startup(),setInterval(function(){printerStatus()},2e3),$(".movement .home").click(function(){axis=$(this).attr("data-axis"),"all"==axis?(code="G28 X0 Y0 Z0",comment="all axes"):(code="G28 "+axis,comment=axis+" axis"),sendCmd(code,"Home "+comment)}),$(".movement .direction button").click(function(){return command="G1 ",movement=$(this).attr("data-movement"),rate=$(".movement .rate button.active").attr("data-rate"),axis=$(this).attr("data-axis"),comment="Move "+axis,"up"!=movement&&"left"!=movement||(rate*=-1),"Z"==axis&&"down"==movement&&(comment="Raise Z "),"Z"==axis&&"up"==movement&&(comment="Lower Z "),"E"==axis&&"plus"==movement&&(comment="Extrude "),"E"==axis&&"minus"==movement?(sendCmd(command+axis+"-"+rate,"Retract "+rate+"mm"),!1):"disable"==movement?(sendCmd("M18","Disable motor lock"),!1):void sendCmd(command+axis+rate,comment+" "+rate+"mm")}),$(".movement .rate button").click(function(){rate=$(this).attr("data-rate"),$(".movement .rate button").removeClass("active"),$(this).addClass("active")}),$("#gCodeSend").click(function(){gCode2Send=$("#gcode").val(),""!=gCode2Send&&(sendCmd(gCode2Send,""),$("#gcode").val(""))}),$("#wre").change(function(){delaySendTemp($("#wre").val(),"extruder")}),$("#sete").click(function(){delaySendTemp($("#wre").val(),"extruder")}),$("#clre").click(function(){sendCmd("{C:T0000}","Turn off extruder preheat","cmd")}),$("#wrp").change(function(){delaySendTemp($("#wrp").val(),"platform")}),$("#setp").click(function(){delaySendTemp($("#wrp").val(),"platform")}),$("#clrp").click(function(){sendCmd("{C:P000}","Turn off platform preheat","cmd")}),$("#fanspeed").slider({min:30,max:100,value:50,reversed:!0,orientation:"vertical",formatter:function(e){return e+"%"}}),$("#fanspeed").on("slide",function(e){delaySendSpeed(e.value)}),$("#clrfan").click(function(){sendCmd("M106 S0","Turn off fan")}),$("form").submit(function(){return!1})});var timers={};String.prototype.contains=function(e){return this.indexOf(e)!=-1},Dropzone.options.mydz={accept:function(e,t){e.name.contains(".g")?(t(),$(".print-actions button").addClass("btn-disable"),$(".movement button").addClass("btn-disable"),$("#gCodeSend").addClass("btn-disable"),$(".temperature button").addClass("btn-disable")):t("Not a valid G-code file.")},init:function(){this.on("error",function(e,t){var n=t.errorMessage;$(e.previewElement).find(".dz-error-message").text(n)}),this.on("addedfile",function(){null!=this.files[1]&&this.removeFile(this.files[0])}),this.on("complete",function(e){$(".print-actions button").removeClass("btn-disable"),$(".movement button").removeClass("btn-disable"),$("#gCodeSend").removeClass("btn-disable"),$(".temperature button").removeClass("btn-disable"),sendCmd("M566 "+e.name,"")})}}; \ No newline at end of file +function pad(e,t){return s="000"+e,s.substr(s.length-t)}function scrollConsole(){$cont=$("#console"),$cont[0].scrollTop=$cont[0].scrollHeight}function feedback(e){"T:"!=e.substring(0,2)&&("ok N0"==e.substring(0,5)&&(e="ok"),$("#gCodeLog").append('

'+e+"

"),scrollConsole())}function sendCmd(e,t,n){void 0===n&&(n="code"),$("#gCodeLog").append('

'+e+' ; '+t+"

"),$.ajax({url:"set?"+n+"="+e,cache:!1}).done(),scrollConsole()}function initWebSocket(){url=window.location.hostname;try{ws=new WebSocket("ws://"+url+":81"),ws.onopen=function(){feedback("Connection Established")},ws.onmessage=function(e){feedback(e.data)},ws.onclose=function(){feedback("Disconnected")}}catch(e){feedback("Web Socket Error")}}function msToTime(e){var t=parseInt(e%1e3/100),n=parseInt(e/1e3%60),a=parseInt(e/6e4%60),o=parseInt(e/36e5%24);return o=o<10?"0"+o:o,a=a<10?"0"+a:a,n=n<10?"0"+n:n,o+":"+a+":"+n+"."+t}function start_p(){$("#stat").text("Printing"),sendCmd("M565","Start printing cache.gc")}function cancel_p(){$("#stat").text("Canceling"),sendCmd("{P:X}","Cancel print","cmd")}function printerStatus(){$.get("inquiry",function(e,t){$("#rde").text(e.match(/\d+/g)[0]),$("#rdp").text(e.match(/\d+/g)[2]),delaySyncTemperatures(e.match(/\d+/g)[1],e.match(/\d+/g)[3]);var n=e.charAt(e.length-1);"I"==n?($("#stat").text("Idle"),$("#pgs").css("width","0%"),$("#start_print").removeClass("btn-disable"),$(".movement button").removeClass("btn-disable"),$("#gCodeSend").removeClass("btn-disable")):"P"==n?($("#stat").text("Printing"),$("#pgs").css("width",e.match(/\d+/g)[4]+"%"),$("#pgs").html(e.match(/\d+/g)[4]+"% Complete"),$("#start_print").addClass("btn-disable"),$(".movement button").addClass("btn-disable"),$("#gCodeSend").addClass("btn-disable")):$("#stat").text("N/A")})}function startup(){"Printing"!=$("#stat").text()&&sendCmd("M563 S6","Enable faster Wi-Fi file uploads")}function delaySendTemp(e,t){clearTimeout(timers),timers=setTimeout(function(){compValue=pad(e,3),"extruder"==t&&sendCmd("{C:T0"+compValue+"}","Set extruder preheat to "+e+"°C","cmd"),"platform"==t&&sendCmd("{C:P"+compValue+"}","Set platform preheat to "+e+"°C","cmd")},250)}function delaySendSpeed(e){clearTimeout(timers),timers=setTimeout(function(){actualSpeed=Math.floor(255*(e/100)),sendCmd("M106 S"+actualSpeed,"Set fan speed to "+e+"%")},250)}function delaySyncTemperatures(e,t){clearTimeout(timers),timers=setTimeout(function(){$("#wre").is(":focus")||$("#wre").val(e),$("#wrp").is(":focus")||$("#wrp").val(t)},3e3)}function refreshSD(){sendCmd("M21","Initialize SD card"),sendCmd("M20","List SD card files")}$(document).ready(function(){printerStatus(),initWebSocket(),setTimeout(function(){startup()},2e3),setInterval(function(){printerStatus()},2e3),$(".movement .home").click(function(){axis=$(this).attr("data-axis"),"all"==axis?(code="G28 X0 Y0 Z0",comment="all axes"):(code="G28 "+axis,comment=axis+" axis"),sendCmd(code,"Home "+comment),setPositioning=!1}),$(".movement .direction button").click(function(){return command="G1 ",movement=$(this).attr("data-movement"),rate=$(".movement .rate button.active").attr("data-rate"),axis=$(this).attr("data-axis"),comment="Move "+axis,0==setPositioning&&(sendCmd("G91","Set to Relative Positioning"),setPositioning=!0),"up"!=movement&&"left"!=movement||(rate*=-1),"Z"==axis&&"down"==movement&&(comment="Raise Z "),"Z"==axis&&"up"==movement&&(comment="Lower Z "),"E"==axis&&"plus"==movement&&(comment="Extrude "),"E"==axis&&"minus"==movement?void sendCmd(command+axis+"-"+rate,"Retract "+rate+"mm"):"disable"==movement?void sendCmd("M18","Disable motor lock"):void sendCmd(command+axis+rate,comment+" "+rate+"mm")}),$(".movement .rate button").click(function(){rate=$(this).attr("data-rate"),$(".movement .rate button").removeClass("active"),$(this).addClass("active")}),$("#gCodeSend").click(function(){gCode2Send=$("#gcode").val(),""!=gCode2Send&&(sendCmd(gCode2Send,""),$("#gcode").val(""))}),$("#wre").change(function(){delaySendTemp($("#wre").val(),"extruder")}),$("#sete").click(function(){delaySendTemp($("#wre").val(),"extruder")}),$("#clre").click(function(){sendCmd("{C:T0000}","Turn off extruder preheat","cmd")}),$("#wrp").change(function(){delaySendTemp($("#wrp").val(),"platform")}),$("#setp").click(function(){delaySendTemp($("#wrp").val(),"platform")}),$("#clrp").click(function(){sendCmd("{C:P000}","Turn off platform preheat","cmd")}),$("#fanspeed").slider({min:30,max:100,value:50,reversed:!0,orientation:"vertical",formatter:function(e){return e+"%"}}),$("#fanspeed").on("slide",function(e){delaySendSpeed(e.value)}),$("#clrfan").click(function(){sendCmd("M106 S0","Turn off fan")}),$("form").submit(function(){return!1})});var timers={},setPositioning=!1;String.prototype.contains=function(e){return this.indexOf(e)!=-1},Dropzone.options.mydz={accept:function(e,t){e.name.contains(".g")?(t(),$(".print-actions button").addClass("btn-disable"),$(".movement button").addClass("btn-disable"),$("#gCodeSend").addClass("btn-disable"),$(".temperature button").addClass("btn-disable")):t("Not a valid G-code file.")},init:function(){this.on("error",function(e,t){var n=t.errorMessage;$(e.previewElement).find(".dz-error-message").text(n)}),this.on("addedfile",function(){null!=this.files[1]&&this.removeFile(this.files[0])}),this.on("complete",function(e){$(".print-actions button").removeClass("btn-disable"),$(".movement button").removeClass("btn-disable"),$("#gCodeSend").removeClass("btn-disable"),$(".temperature button").removeClass("btn-disable")})}}; \ No newline at end of file diff --git a/webui.html b/webui.html index 5540576..4439a47 100755 --- a/webui.html +++ b/webui.html @@ -39,10 +39,10 @@

Printer Status:
- +
- +
@@ -212,7 +212,7 @@

N/A

- Alpha v0.9 + Alpha v0.9.1
@@ -221,10 +221,9 @@

N/A

+