From 98de58c1ee6ee4365787c7c17b2b6ed8f39810c6 Mon Sep 17 00:00:00 2001 From: donovan6000 Date: Wed, 3 Aug 2016 18:03:07 -0700 Subject: [PATCH] Version 1.5 release --- Changelog | 6 + README.md | 2 +- installers/Linux/90-micro-3d-local.rules | 2 +- .../Linux/91-micro-3d-heatbed-local.rules | 2 +- installers/Linux/install.zip | Bin 1483 -> 1531 bytes installers/Linux/uninstall.zip | Bin 910 -> 911 bytes .../OS X/command line tools installer.bash | 8 +- installers/OS X/install.sh | 128 +- installers/OS X/install.zip | Bin 52219 -> 51951 bytes installers/OS X/uninstall.sh | 20 +- installers/OS X/uninstall.zip | Bin 52300 -> 52026 bytes installers/Windows/install.zip | Bin 1992 -> 2438 bytes installers/Windows/uninstall.zip | Bin 1046 -> 1069 bytes octoprint_m33fio/__init__.py | 2021 ++++++++++------- octoprint_m33fio/static/css/m33fio.css | 4 + octoprint_m33fio/static/js/m33fio.js | 12 +- octoprint_m33fio/webcam_server.py | 6 +- setup.py | 2 +- 18 files changed, 1341 insertions(+), 872 deletions(-) mode change 100644 => 100755 installers/OS X/install.sh mode change 100644 => 100755 installers/OS X/uninstall.sh diff --git a/Changelog b/Changelog index c9532bc..7869b13 100644 --- a/Changelog +++ b/Changelog @@ -1,5 +1,11 @@ Changelog: +V1.5 August 3, 2016 + + * Made canceling a print and emergency stop more reliable + * Added more exeption handling when connecting to the printer + * Fixed issue in setting the extruder's current + V1.4 July 29, 2016 * Really fixed compatibility with OctoPrint V1.2.14 diff --git a/README.md b/README.md index a6eab21..a5638a1 100644 --- a/README.md +++ b/README.md @@ -6,7 +6,7 @@ OctoPrint plugin that provides the world's first platform independent software s ### Description M33 Fio is a plugin for [OctoPrint](http://octoprint.org/) that extends its capabilities to make it fully compatible with the Micro 3D printer. Both OctoPrint and M33 Fio can run on Windows, OS X, and Linux, so this solution is the first platform independent option available for this printer. -The latest version of M33 Fio is V1.4 released on July 29th, 2016, and an entire changelog for it can be found [here](https://raw.githubusercontent.com/donovan6000/M33-Fio/master/Changelog). +The latest version of M33 Fio is V1.5 released on August 3rd, 2016, and an entire changelog for it can be found [here](https://raw.githubusercontent.com/donovan6000/M33-Fio/master/Changelog). ### Features * Platform independent diff --git a/installers/Linux/90-micro-3d-local.rules b/installers/Linux/90-micro-3d-local.rules index 7d8649f..13e0981 100644 --- a/installers/Linux/90-micro-3d-local.rules +++ b/installers/Linux/90-micro-3d-local.rules @@ -1,5 +1,5 @@ # Run the following commands to install this rule -# cp ./90-micro-3d-local.rules /etc/udev/rules.d/ +# sudo cp ./90-micro-3d-local.rules /etc/udev/rules.d/ # sudo udevadm control --reload-rules # sudo udevadm trigger diff --git a/installers/Linux/91-micro-3d-heatbed-local.rules b/installers/Linux/91-micro-3d-heatbed-local.rules index 9e6bf0c..5ab903e 100644 --- a/installers/Linux/91-micro-3d-heatbed-local.rules +++ b/installers/Linux/91-micro-3d-heatbed-local.rules @@ -1,5 +1,5 @@ # Run the following commands to install this rule -# cp ./91-micro-3d-heatbed-local.rules /etc/udev/rules.d/ +# sudo cp ./91-micro-3d-heatbed-local.rules /etc/udev/rules.d/ # sudo udevadm control --reload-rules # sudo udevadm trigger diff --git a/installers/Linux/install.zip b/installers/Linux/install.zip index 780bf9288a23e6b3db5b0ed4262e7b7d174356e1..819e9cdb6660d36d2e2bd62aa7e9c6888053722e 100644 GIT binary patch delta 1506 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 DJF=x2 diff --git a/installers/OS X/command line tools installer.bash b/installers/OS X/command line tools installer.bash index 96f1681..4e6855a 100644 --- a/installers/OS X/command line tools installer.bash +++ b/installers/OS X/command line tools installer.bash @@ -22,6 +22,9 @@ if [[ "$osx_vers" -ge 9 ]]; then #Install the command line tools softwareupdate -i "$cmd_line_tools" -v + if [ 0 -ne $? ]; then + exit 1 + fi # Remove the temp file @@ -47,7 +50,10 @@ if [[ "$osx_vers" -eq 7 ]] || [[ "$osx_vers" -eq 8 ]]; then fi TOOLS=cltools.dmg - curl "$DMGURL" -o "$TOOLS" + curl "$DMGURL" -f -o "$TOOLS" + if [ 0 -ne $? ]; then + exit 1 + fi TMPMOUNT=`/usr/bin/mktemp -d /tmp/clitools.XXXX` hdiutil attach "$TOOLS" -mountpoint "$TMPMOUNT" -nobrowse # The "-allowUntrusted" flag has been added to the installer diff --git a/installers/OS X/install.sh b/installers/OS X/install.sh old mode 100644 new mode 100755 index c0e1768..19fba21 --- a/installers/OS X/install.sh +++ b/installers/OS X/install.sh @@ -20,25 +20,52 @@ else # Move to temporary location cd $TMPDIR + + # Stop OctoPrint + sudo -u $SUDO_USER launchctl unload /Library/LaunchAgents/com.octoprint.app.plist # Install Python - curl -o index.html https://www.python.org/downloads/mac-osx/ + while ! curl -f -o index.html https://www.python.org/downloads/mac-osx/ + do + : + done version="$(perl -nle'print $1 if m/Latest Python 2 Release - Python ([0-9\.]*)/' index.html)" rm index.html - curl -o python.pkg https://www.python.org/ftp/python/${version}/python-${version}-macosx10.6.pkg + while ! curl -f -o python.pkg https://www.python.org/ftp/python/${version}/python-${version}-macosx10.6.pkg + do + : + done installer -pkg python.pkg -target / rm python.pkg - + + # Update pip + while ! sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/pip install pip --user --upgrade + do + : + done + # Install command line tools - curl -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/command%20line%20tools%20installer.bash' - bash 'command%20line%20tools%20installer.bash' + while ! curl -f -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/command%20line%20tools%20installer.bash' + do + : + done + while ! bash 'command%20line%20tools%20installer.bash' + do + : + done rm 'command%20line%20tools%20installer.bash' # Install PyObjC core - curl -o index.html https://pypi.python.org/pypi/pyobjc-core + while ! curl -f -o index.html https://pypi.python.org/pypi/pyobjc-core + do + : + done version="$(perl -nle'print $1 if m/pyobjc-core-([0-9\.]*)\.tar\.gz/' index.html | head -1)" rm index.html - curl -o pyobjc-core.tar.gz https://pypi.python.org/packages/source/p/pyobjc-core/pyobjc-core-${version}.tar.gz + while ! curl -f -o pyobjc-core.tar.gz https://pypi.python.org/packages/source/p/pyobjc-core/pyobjc-core-${version}.tar.gz + do + : + done sudo -u $SUDO_USER tar zxvf pyobjc-core.tar.gz rm pyobjc-core.tar.gz cd pyobjc-core-${version} @@ -49,61 +76,96 @@ else sudo -u $SUDO_USER sed -i '' -e 's/\(universal_newlines=True.*\)/\1\ except subprocess.CalledProcessError as e:\ self.sdk_root = \'"'"'\/\'"'"'/g' setup.py - - sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + + while ! sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + do + : + done cd .. rm -rf pyobjc-core-${version} # Install PyObjC Cocoa framework - curl -o index.html https://pypi.python.org/pypi/pyobjc-framework-Cocoa + while ! curl -f -o index.html https://pypi.python.org/pypi/pyobjc-framework-Cocoa + do + : + done version="$(perl -nle'print $1 if m/pyobjc-framework-Cocoa-([0-9\.]*)\.tar\.gz/' index.html | head -1)" rm index.html - curl -o pyobjc-framework-Cocoa.tar.gz https://pypi.python.org/packages/source/p/pyobjc-framework-Cocoa/pyobjc-framework-Cocoa-${version}.tar.gz + while ! curl -f -o pyobjc-framework-Cocoa.tar.gz https://pypi.python.org/packages/source/p/pyobjc-framework-Cocoa/pyobjc-framework-Cocoa-${version}.tar.gz + do + : + done sudo -u $SUDO_USER tar zxvf pyobjc-framework-Cocoa.tar.gz rm pyobjc-framework-Cocoa.tar.gz cd pyobjc-framework-Cocoa-${version} - sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + + while ! sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + do + : + done cd .. rm -rf pyobjc-framework-Cocoa-${version} # Install PyObjC Quartz framework - curl -o index.html https://pypi.python.org/pypi/pyobjc-framework-Quartz + while ! curl -f -o index.html https://pypi.python.org/pypi/pyobjc-framework-Quartz + do + : + done version="$(perl -nle'print $1 if m/pyobjc-framework-Quartz-([0-9\.]*)\.tar\.gz/' index.html | head -1)" rm index.html - curl -o pyobjc-framework-Quartz.tar.gz https://pypi.python.org/packages/source/p/pyobjc-framework-Quartz/pyobjc-framework-Quartz-${version}.tar.gz + while ! curl -f -o pyobjc-framework-Quartz.tar.gz https://pypi.python.org/packages/source/p/pyobjc-framework-Quartz/pyobjc-framework-Quartz-${version}.tar.gz + do + : + done sudo -u $SUDO_USER tar zxvf pyobjc-framework-Quartz.tar.gz rm pyobjc-framework-Quartz.tar.gz cd pyobjc-framework-Quartz-${version} - sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + + while ! sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + do + : + done cd .. rm -rf pyobjc-framework-Quartz-${version} # Install PyObjC QTKit framework - curl -o index.html https://pypi.python.org/pypi/pyobjc-framework-QTKit + while ! curl -f -o index.html https://pypi.python.org/pypi/pyobjc-framework-QTKit + do + : + done version="$(perl -nle'print $1 if m/pyobjc-framework-QTKit-([0-9\.]*)\.tar\.gz/' index.html | head -1)" rm index.html - curl -o pyobjc-framework-QTKit.tar.gz https://pypi.python.org/packages/source/p/pyobjc-framework-QTKit/pyobjc-framework-QTKit-${version}.tar.gz + while ! curl -f -o pyobjc-framework-QTKit.tar.gz https://pypi.python.org/packages/source/p/pyobjc-framework-QTKit/pyobjc-framework-QTKit-${version}.tar.gz + do + : + done sudo -u $SUDO_USER tar zxvf pyobjc-framework-QTKit.tar.gz rm pyobjc-framework-QTKit.tar.gz cd pyobjc-framework-QTKit-${version} - sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + + while ! sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + do + : + done cd .. rm -rf pyobjc-framework-QTKit-${version} # Install OctoPrint - sudo -u $SUDO_USER launchctl unload /Library/LaunchAgents/com.octoprint.app.plist - while echo 'y' | sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/pip uninstall OctoPrint + while ! curl -f -LOk https://github.com/foosel/OctoPrint/archive/master.zip do : done - curl -LOk https://github.com/foosel/OctoPrint/archive/master.zip sudo -u $SUDO_USER unzip master.zip cd OctoPrint-master - sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + while ! sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/python setup.py install --user + do + : + done cd .. sudo -u $SUDO_USER mkdir -p '/Users/'"$SUDO_USER"'/Library/Application Support/OctoPrint' rm -rf '/Users/'"$SUDO_USER"'/Library/Application Support/OctoPrint/checkout' - sudo -u $SUDO_USER mv OctoPrint-master '/Users/'"$SUDO_USER"'/Library/Application Support/OctoPrint/checkout' + #sudo -u $SUDO_USER mv OctoPrint-master '/Users/'"$SUDO_USER"'/Library/Application Support/OctoPrint/checkout' + rm -rf OctoPrint-master rm master.zip # Install M33 Fio @@ -115,7 +177,10 @@ else do : done - curl -LOk https://github.com/donovan6000/M33-Fio/archive/master.zip + while ! curl -f -LOk https://github.com/donovan6000/M33-Fio/archive/master.zip + do + : + done while ! sudo -u $SUDO_USER /Library/Frameworks/Python.framework/Versions/2.7/bin/pip install master.zip --user do : @@ -123,17 +188,26 @@ else rm master.zip # Install heatbed drivers - curl -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/CH34x_Install.pkg' + while ! curl -f -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/CH34x_Install.pkg' + do + : + done installer -pkg CH34x_Install.pkg -target / rm CH34x_Install.pkg # Add OctoPrint to startup programs - curl -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/com.octoprint.app.plist' + while ! curl -f -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/com.octoprint.app.plist' + do + : + done sed -i '' -e 's/path to octoprint/\/Users\/'"$SUDO_USER"'\/Library\/Python\/2.7\/bin\/octoprint/g' com.octoprint.app.plist mv com.octoprint.app.plist '/Library/LaunchAgents' # Create URL link on desktop - curl -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/shortcut.zip' + while ! curl -f -O 'https://raw.githubusercontent.com/donovan6000/M33-Fio/master/installers/OS%20X/shortcut.zip' + do + : + done sudo -u $SUDO_USER ditto -x -k --sequesterRsrc --rsrc shortcut.zip '/Users/'"$SUDO_USER"'/Desktop' # Start OctoPrint diff --git a/installers/OS X/install.zip b/installers/OS X/install.zip index 6f7740c5ead6a7cf2b9e6b5b5d35497867390e16..dd0087bcb85c1c80eea760d7269304b28fe0859b 100644 GIT binary patch delta 2873 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 delta 2411 zcmaJ?3p|r+9NtAt)<#il39SoqzqaHuWNVY$B2F&3omwstT~N)XjtVhvNf$&)CDf6Q z%aBd8y-?!gy-~ahP@AE!;zvo|-32)AVqnzyFQu85# zj}a+g6CH)a(sc*jp`l#&VW=WxMwOy9tEvb=@GoI+nh7FjviElLGMJR$A?Sx0EETXx zGKzW<%KU%{9FGvJ_c`gQd)YoX1)(5l63UtUQUM>Tv7k>*PKXn*fN?nuAvZlu9XKIT zb4UUQkp#r4Nlj(`tlm@gJ%cWohrYvw^U^FuVrGsV4dOYH! z_zuV*Ov{6;34A@fp^zDl0CcSZsAVW&cl~gSLI>V491vm$fKAO_k%WpG3#|C5*y$-R z`MgBh&k~&FZuXIjNb=v^T>^t2_1Wo5!+k=&5#j>D*0nwMHf!yU*;2NKY*PrkP`=RA z$AVIA${W($c|`iGa)woU0E$;3ol=iy%cdP2x|6!$Vz8oJdsl!DaA}G_;!_U|5KCR_7${Jrld2T?>b_|v6#@r(hT9K~njNl(1 zZ*qO}=EQ47*Y=lHIVY5Hsvqy}eVakMwVmE@I5z@beqvFumm74SZaypyP$g!q8A@pQiUlRSFe3RHIm&o&oFwH^qLY3|O_CIxxg zdbK@?@a>3VR3a81pkc>p?AGirzDIJ2NN!Gl63Jo6CdGrwGwWb~{n}YtcPK(TuvJ~X zDfQ&`@)}s|{SDcn-nILOlL~dn8xNEn9nN(2Hw?E}7yhtTH@b^CJe+2gXIV5Bylq<( zw&JgdobF&^dIvNm`$mUF$8Gp;?!%3@dIFKpcNAvXkgw*IlvA=|X#2CGO#ACv5?n$~ zRejff>Vq2JW2O@}rX5x%`_xUrY_YAWar8VD*2u*cwI<|PcC^)waDP0hf>97iE$e@3 zTCJU*;MC7oW4Ic-NWFhhpUtb4nTVP&~z~=J9OK^)LLKM}49^g~2HCOp^z42V-5A~LFmB~!v ztg=KrU1vHY#PI|YS*ySr)@o6%IkL2;k~)#)EPBdi>0`um#mOEDQ-V*;9H7>)enwGZ zrHBSwjCiWd>TGVXS|ScnQE_Ut;O-NJtb)-ZSrcY*+CI2~O* z^aM+Z&*v=k5C;qQXF@WV809%})(^1oLIG~Y+_(#T+^_(r!#Cr9SDoOa99Vpm7T}xl z1I8&cKyVWlUi=>xR5ziGr|*3VyK5d}(13533;)JUGtRXEd~Z@wnL69^qy@Gr@-Hv` KYu?!)`1LQ)aell2 diff --git a/installers/Windows/install.zip b/installers/Windows/install.zip index d698baf899dc157cd8c7cefd6b94e494707f39b4..b2340d2d5340668a87acae6471efcb9ce0ba016b 100644 GIT binary patch literal 2438 zcmV;133>KVO9KQH0{{RB0N9KJNrKz(xDE*b0LLQ$01E&B0BLS>bYX04E@EMH&02Yr z(l8YNTW97dxQ6lLGwv_WHv|RfmzbPd^QHnS~$0E zXmI7i`Ew7vr3=Hd!rtV8_j;e z7QTqBQA;x>8qR`xk)VSV>A5fzLn0(U96~c7=-%GR2V#qNSG3`rxUSyteHX13lzG~_ ztMCBLMw|Pk$&3g~3f5OATti_POz^G1T5uFqx^|!)YFexVvdlj$hH@WNglf{SoLC&^)j>SR39hq92+=nYNH*K{jrfkDIum_$_H36M&KT zh%FObFc5PB)DtA|h>)gHZwBl2TAwjCbBS)V1(ZGXO?eH~N~MA%s7tAWYNRDp)1usW zty5SK&aD~2=`b#O`~VFvR+gAS8P0JCu=r>|96hnQho%K<%B7f8w#B-R*@}b!$iioV z6`X?0Hu-}T=+ihT(!&YUP%s~QwqX4L?U1v=;vYX!*9D_}4F0K@GjA<31`LecQJS~y zabdZxVh4x##B+#eQ^F6pyCvcdIR(Epf~QeU@nBu4-7*_WMiDpf?2}EjWzXfz>OpYaZEnzbFpwk;Q0j| zR%~KydkWp&2ryZPBT)QjsL(1frl1M-k$C*@js~UD6xv<5a(RkOpmi)EyJv*31_R;} zixVx+w98ka)q}8l1xEM{B z&rItJP7}B9kCCv%ECeq z`_9ZC9Grl1dC5s2Km1u>Ii!GB z>M2vA%>!P{HYl3C{wpv}LAJs*&SB(|WVx9_gzFbZr^2RZZSrqm@v`h~!uY>!tW1^S$zg983WYcfv| zPn0{vn~AxWFP(h0i7)aMpk){eDy~#>S?LsFow#B%hg`uu`0x;Fm5LOYk*9zMLr8NFt4us1ox;UG`k zxp)~NV&}AFy-H^)(!8zkxL$`N%JMhD8#_Bh^bt0P*pFfRJutAR&a4Gdoi`kotNLBN zs^ex?ua*7NntnU%b`dQ;7U&{3GQCx?Z&7XcRzAGHkV8He0DdzAT(K*vV#X)gaK?mY3$msfn~k@2 z+h}z<=*?J$nw-dd0_Ry>Od?~2=;IOXO^y>Bdb-k|bW5t~xzAh&w-u?ADk?&k#FpPn*-~h6*2oT#anm1D5E-0N5VsE%uy{u8e!Dh56~k(>o1Vf~C{}~0 zAP%K6>bTyD1m}ORS3#{R?X^Fry1 zL*5WYxROMgQ9q=Ie3+XG@-&<`w#H;M>>A-gw%5pw6!c+B_K_wz}EjQSbH8-TeC5O z^q>gb%=^@qgfwAho69r`+}yTWdu9$jq~`K@RUxW5m8@z`MO03mfvq;yhU28JcLW3U zULck}_yL>AOG8N*kQq3{C4zwVBG znld>6+os6Bp4XIv{_%@`l0NdZAGStC9F%$K-xiUkj2*O1@zXE=txZO0QE{t-d3EWF zMXZGW*3m_ObLD5wW;|3l#2dE}V2S*^kYpA8w1%#RQVZXwt7c_+PI4SSw^jsB2=Ra~ zZ5w%~OV>@#jEJMdV+Ml7C(!cV+?_Kn4sK#fAQ=ifg*7>WlYp(!Ba+q%1u2EnhO5%Y zXRhkiO+6CiVn`r_2*Te)s9)M_{SW}N0LVQg$JVqtVpO9ci1000010096w0000t2><{9 E0Ll)D=>Px# delta 1970 zcmV;j2Tk~f6UYyLP)h>@6axSN2ml&;{YWDsO4(2c002cA000XB003!jb97;BY%XG9 zbj?}mj?*v@{tXiEFhnYsXtD=40#Vv5RCJq?w44RxP2ARy#=&-5iV)Av*v-+Cg?%&%UItzF*!R3{r60`YbMN_$Ykd}yFqSs`M6F#aAx{Qu z*q3vu=-4`cclI*4t-w9aJ?b7F>~vqMY`VuX=qxL)?|XjBede|*&~~4~o(cKL>w3_u z)jNWZQ@w}dOe zkxyuUs0pq(s1XI0C@K=FG&GhBVK$rDL(YdWwL?CJYJ#F|l*LU0(AJEFv&#D?E|=Aw0u92saPftk~#WiBb}Suj3Z z%i#HNVOaM%FTt6Eo|!Y0VTuL!ndYf~0$gzK@9LX~IA$mJH~O;<8y|uy!RVA;l1f}c zUp5iL>FfPBZ!cek7105T-dsNd-m<>bsOsiXoD8|^@l#CWvse=jZaR%t z%hdbWd*)`A=p%yd@wB#;dA03-zWHxPv;mI9l5Gi2|~eACHpB$7df$vC4vs= zC#Y5@l8Rq2PgxxES!us}*U=q{$PXXT0-WY?w%E)TYid__--$U-_Y2z3;S2mAoJqpA z#lvm8?R8hTZgX-ofqt5AW)UCa+@751LxMBlT+-MnLOMi*BQ~YZm`Fu`h2dKE`qNxn zGpskt%&Lp7AM+=vnizk1fy$vWOfw99f;+@|se7m;`;}hc`t8~=3h=brAd2*TPH-z6 z_6t1LGEaZqO+VBJHa<~SK5I5o{!`9z))a-#+AH$qhV7I~cTzQBR*JCf94fuppIgN~U9mJF>gBb@VreKNaQ# z50OC7LjGDw1ew{3vS?V@mcFw>3qVem76x^mXNPB`jLnh(WY2#OCL{{7rv}qWIz7d3 zpV!uBN6qVx53lXxDq}x;(SYT~e*z1C0l;$OKY`V3AHj0t ze}HxSR#`1<{4dqIajk@fjsFBzr)%TE6qerqEvRsmk*Qwm!g6C{;o0CFE;lPPcSD9b z<+9zjNSIQu7_CyaQ7aU!0WFuhS`;na$|w$)uTYZ|Qo)D%zD_F&I)sSER8g=VKXG5a ztM`20ZFk@4Q%^sC-~%-yg7%MDD7eH{KdV*0J`n<|oLwID{fYkEe+E_&5t~PO1QJDm z!My^!19=y`!a(M_&-xy7W`;WW52~S7%|5d^`ZN3Q-Qvw26PDlyuvXskiQn^E5VPb1 z@B}L-KcLmWWo-$Zg&bB|`B8UOy5s)Z`nPEmBdhOZV5OCRr?DzM^|;etKW11-f49KS#m0u43SQy(Pb0;hi`Ms`AU+gxMLZSDTNbC6OfZIMBBk6j*D+D z8rkrOgW~z6g}$|oM_j5q*Rk}dhR)_NqbG18u+mg$U1A)S0W}8mcZRi#;^LkdySC?0 zq+l{IH}d5o-+5N9q0#?0P)h*hD2LJ#7 E075FcsQ>@~ diff --git a/installers/Windows/uninstall.zip b/installers/Windows/uninstall.zip index 5a3348930b5e7fc53b46812f15ec3add27b85e9c..eddf3b8d6b03ce6c561ead4757260520be587305 100644 GIT binary patch delta 1039 zcmV+q1n~Qo2(1WzP)h>@6axSN2mmI%{zxqTDQK|+006NG000dD004DvX>N0LVQg$J zVqtWxR_|}pP!#5sR**D(^~-|lU@ z4ipiS`2kAXd(S!d-t&0xJ+n?7aC*IF{Ry)sQg3A3Vi&4z}R8L$=|Yjj~FUxvt|5*cls`Fk+wKbxHZrnK&@*TH`E@ zrLNViU(Hh84P%kq1HIb_eNv9XLtW&i|%6#$8I5v!bnuG9LB^+5Qk+KUV_mM z!2F?JgIQ&p#k1m*-KddN*XwX!e$3A8_y4Outn$$09W+LUD3W)WrC z&@OI&gz~jfo6(wMumEulBoDX(UgeIcdXIU9ZQ;QM+jAp7R&yix0?pH@1SinxI1@=R z63x|rVj-dk+WjHOm7b@`vS<{vNpOz>?h~hpNR;LjIP7$wCsKO;E=p7RrtbL)zCT#Z zcKc_{^ea5y3o;?K@}-cK6Z0BuE#=j)V^^quE}`^R$yXB}{5RsxKM@~nG-Dg4R@M1G zs`kmLh+Hy^g7(etL{o*C^3AEo+);N(4`@+;*<5qqO*y$|=0ETlf0;0ZC@~2!2?VOT zzQae=m*EWW_Sbe;v%P&3n6Irh&%bL9F8!>yqD{kooO+Gl_SWjdEdA+wCfMLfBV zYK>4M7^k1u#iccMT{fCr77N7p(rdls8TvyJWT~P%|6C+tx>UZEXBj5?jA#Xo#?2E0 z+Gk)qP||I0OVHFEKqQg{qzTcgg-&IEHSt|La7u7xD_SB*jVgBUlC~@4^-^x-S+vn- zTPPXv6~w3%jqu*tt^4an*LV^>toS)6{a1(ys5}TL^E!{B)q2nv*4vV!$skLiaPtK4 zZ`9@Pw{fO|3~zFgVc06q3_k%-O928u0~7-Q00;mkz5Yln{wZj&0{{TA2><|-;R7!Q J+yejr006u@>p%bi delta 1039 zcmV+q1n~Q<2$l$cP)h>@6axSN2mnia{YU}haq*f1007|#000dD004DvX>N0LVQg$J zVqtWxR_~9}KoI>b3ID^SNsSr>J&Yeryol|dM+Ay(IlZLuve(YRN`LI_ZjU1|{_RfN z<3JHK(GO7Coq6xgyxA^qnRDuacXHBhy$x76^ql?>*tq|HZpd6V?4Q&3=ShDY47_o> z)o%H01U_Dus10C>H{4(XQi&Up;tX}WH8=swp7@@_g23}H`o42I2$>U3eP&z0K2E{n zS@P=v{ur*nD|p1#?W(PG8EDR2xy`)|ba{ zOtMMy#ExcYcm>?KxzrYck(nU5;+ZBW`^jtTjb*KWIS9W~!?9b8OM_s=SyFf5DOlYY z?C<(H*iE)wJ*z&d%(2X zZgu-TkHfo7^!~AF!YrTezQsUEgRP8{Y`NLJLeG!HZ2XQ6jG_ zFoMee!*#IX3;&1b--IlP-327 z9t+g}RFuLQ-u@GUq{%Fn&F0#Z?GA@Jx)DjtWk;@(sDV|mFzP+eRhSGDPKW`T9bu$W81mAZgq|4$^BND zbJBl_n1e3km@==*G+k|s#$^2(_Y4ilQfS;hG5?ObJ}tKXgMh;8QYcJ1^%?sEP)h*< zKLZp4000O8OMCrD0poG;ngaj;;RpZ#4FCWD00000001C>w1EHs004DvX>N0q4+Izn J#RC8U0053q?WzC( diff --git a/octoprint_m33fio/__init__.py b/octoprint_m33fio/__init__.py index af98991..da539f5 100755 --- a/octoprint_m33fio/__init__.py +++ b/octoprint_m33fio/__init__.py @@ -54,7 +54,7 @@ from PIL import Image import pygame.camera - except ImportError : + except : pass # Check if using Linux @@ -64,7 +64,7 @@ try : import dbus - except ImportError : + except : pass # Otherwise check if using OS X @@ -79,7 +79,7 @@ from Quartz import * import QTKit - except ImportError : + except : pass @@ -143,6 +143,7 @@ def __init__(self) : self.performCancelPrintMovement = False self.currentFirmwareType = None self.sharedLibraryIsUsable = False + self.cancelingPrint = False # Rom decryption and encryption tables self.romDecryptionTable = [0x26, 0xE2, 0x63, 0xAC, 0x27, 0xDE, 0x0D, 0x94, 0x79, 0xAB, 0x29, 0x87, 0x14, 0x95, 0x1F, 0xAE, 0x5F, 0xED, 0x47, 0xCE, 0x60, 0xBC, 0x11, 0xC3, 0x42, 0xE3, 0x03, 0x8E, 0x6D, 0x9D, 0x6E, 0xF2, 0x4D, 0x84, 0x25, 0xFF, 0x40, 0xC0, 0x44, 0xFD, 0x0F, 0x9B, 0x67, 0x90, 0x16, 0xB4, 0x07, 0x80, 0x39, 0xFB, 0x1D, 0xF9, 0x5A, 0xCA, 0x57, 0xA9, 0x5E, 0xEF, 0x6B, 0xB6, 0x2F, 0x83, 0x65, 0x8A, 0x13, 0xF5, 0x3C, 0xDC, 0x37, 0xD3, 0x0A, 0xF4, 0x77, 0xF3, 0x20, 0xE8, 0x73, 0xDB, 0x7B, 0xBB, 0x0B, 0xFA, 0x64, 0x8F, 0x08, 0xA3, 0x7D, 0xEB, 0x5C, 0x9C, 0x3E, 0x8C, 0x30, 0xB0, 0x7F, 0xBE, 0x2A, 0xD0, 0x68, 0xA2, 0x22, 0xF7, 0x1C, 0xC2, 0x17, 0xCD, 0x78, 0xC7, 0x21, 0x9E, 0x70, 0x99, 0x1A, 0xF8, 0x58, 0xEA, 0x36, 0xB1, 0x69, 0xC9, 0x04, 0xEE, 0x3B, 0xD6, 0x34, 0xFE, 0x55, 0xE7, 0x1B, 0xA6, 0x4A, 0x9A, 0x54, 0xE6, 0x51, 0xA0, 0x4E, 0xCF, 0x32, 0x88, 0x48, 0xA4, 0x33, 0xA5, 0x5B, 0xB9, 0x62, 0xD4, 0x6F, 0x98, 0x6C, 0xE1, 0x53, 0xCB, 0x46, 0xDD, 0x01, 0xE5, 0x7A, 0x86, 0x75, 0xDF, 0x31, 0xD2, 0x02, 0x97, 0x66, 0xE4, 0x38, 0xEC, 0x12, 0xB7, 0x00, 0x93, 0x15, 0x8B, 0x6A, 0xC5, 0x71, 0x92, 0x45, 0xA1, 0x59, 0xF0, 0x06, 0xA8, 0x5D, 0x82, 0x2C, 0xC4, 0x43, 0xCC, 0x2D, 0xD5, 0x35, 0xD7, 0x3D, 0xB2, 0x74, 0xB3, 0x09, 0xC6, 0x7C, 0xBF, 0x2E, 0xB8, 0x28, 0x9F, 0x41, 0xBA, 0x10, 0xAF, 0x0C, 0xFC, 0x23, 0xD9, 0x49, 0xF6, 0x7E, 0x8D, 0x18, 0x96, 0x56, 0xD1, 0x2B, 0xAD, 0x4B, 0xC1, 0x4F, 0xC8, 0x3A, 0xF1, 0x1E, 0xBD, 0x4C, 0xDA, 0x50, 0xA7, 0x52, 0xE9, 0x76, 0xD8, 0x19, 0x91, 0x72, 0x85, 0x3F, 0x81, 0x61, 0xAA, 0x05, 0x89, 0x0E, 0xB5, 0x24, 0xE0] @@ -560,7 +561,7 @@ def getPort(self) : firstInitializedPrinter = None # Loop forever - while(True) : + while True : # Go through all connected serial ports for port in serialPorts : @@ -696,11 +697,22 @@ def monitorHeatbed(self) : error = False try : self.heatbedConnection = serial.Serial(heatbedPort, 115200, timeout = 5) - if float(serial.VERSION) < 3 : - self.heatbedConnection.writeTimeout = 1 + + # check if using OS X or Linux and the user lacks read/write access to the heatbed + if (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(heatbedPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Otherwise else : - self.heatbedConnection.write_timeout = 1 - except Exception : + + # Set connection timeout + if float(serial.VERSION) < 3 : + self.heatbedConnection.writeTimeout = 1 + else : + self.heatbedConnection.write_timeout = 1 + except : error = True # Check if no errors occured @@ -714,7 +726,7 @@ def monitorHeatbed(self) : if self.heatbedConnection.read() == '\x1B' : self.heatbedConnection.timeout = 1 break - except Exception : + except : error = True break @@ -741,7 +753,7 @@ def monitorHeatbed(self) : self.heatbedConnection.reset_input_buffer() self.heatbedConnection.reset_output_buffer() - except Exception : + except : error = True # Check if no errors occured @@ -762,11 +774,21 @@ def monitorHeatbed(self) : # Create message self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Create message", type = "success", title = "Heatbed detected", text = "Heatbed has been connected")) - # Otherwise check if an error occured and it hasn't been show yet - if error and previousHeatbedPort != heatbedPort : + # Check if an error has occured + if error : - # Create message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Create message", type = "error", title = "Heatbed error", text = "Failed to connect to heatbed")) + # Check if connection to heatbed was established + if self.heatbedConnection is not None : + + # Close connection + self.heatbedConnection.close() + self.heatbedConnection = None + + # check if an error occured and it hasn't been show yet + if previousHeatbedPort != heatbedPort : + + # Create message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Create message", type = "error", title = "Heatbed error", text = "Failed to connect to heatbed")) # Set previous heatbed port previousHeatbedPort = heatbedPort @@ -1583,7 +1605,7 @@ def getIpAddress(self) : # Return IP address try : return [l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0] - except Exception : + except : return socket.gethostbyname(socket.gethostname()) # On settings save @@ -1700,7 +1722,7 @@ def on_settings_save(self, data) : try : self._printer._comm.close(False, False) - except TypeError : + except : pass self._printer.disconnect() @@ -1765,41 +1787,44 @@ def on_api_command(self, command, data) : # Check if parameter is a list of commands if isinstance(data["value"], list) : - # Check if not using a Micro 3D printer - if self._settings.get_boolean(["NotUsingAMicro3DPrinter"]) : + # Check if commands are provided + if len(data["value"]) : + + # Check if not using a Micro 3D printer + if self._settings.get_boolean(["NotUsingAMicro3DPrinter"]) : - # Send commands to printer - self._printer.commands(data["value"]) + # Send commands to printer + self._printer.commands(data["value"]) - # Otherwise - else : + # Otherwise + else : - # Set no line numbers if first command is to remove line numbers - if data["value"][0] == "M65538;no line numbers" : - noLineNumber = True - data["value"].pop(0) + # Set no line numbers if first command is to remove line numbers + if data["value"][0] == "M65538;no line numbers" : + noLineNumber = True + data["value"].pop(0) - # Otherwise clear no line numbers - else : - noLineNumber = False + # Otherwise clear no line numbers + else : + noLineNumber = False - # Check if waiting for commands to be sent - if data["value"][-1] == "M65536;wait" : + # Check if waiting for commands to be sent + if data["value"][-1] == "M65536;wait" : - # Append a command that receives a confirmation to the end of list - data["value"].insert(len(data["value"]) - 1, "G4") + # Append a command that receives a confirmation to the end of list + data["value"].insert(len(data["value"]) - 1, "G4") - # Check if not using line numbers or printing - if noLineNumber or self._printer.is_printing() : + # Check if not using line numbers or printing + if noLineNumber or self._printer.is_printing() : - # Send commands to printer - self.sendCommands(data["value"]) + # Send commands to printer + self.sendCommands(data["value"]) - # Otherwise - else : + # Otherwise + else : - # Send commands with line numbers - self.sendCommandsWithLineNumbers(data["value"]) + # Send commands with line numbers + self.sendCommandsWithLineNumbers(data["value"]) # Otherwise check if parameter is to set fan elif data["value"].startswith("Set Fan:") : @@ -1831,37 +1856,62 @@ def on_api_command(self, command, data) : # Return error if printer was found if currentPort is not None : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) - - # Check if getting EEPROM failed - if not self.getEeprom(connection) : + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break + + except : + connection = None + time.sleep(1) + # Check if failed to connect to the printer + if connection is None : + # Set error error = True - - # Otherwise - else : - - # Check if setting fan failed - if not self.setFan(connection, data["value"][9 :]) : + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Close connection + connection.close() + + # Check if an error hasn't occured + if not error : + + # Check if getting EEPROM failed + if not self.getEeprom(connection) : # Set error error = True - + # Otherwise else : - # Send new EEPROM - self.getEeprom(connection, True) + # Check if setting fan failed + if not self.setFan(connection, data["value"][9 :]) : - # Close connection - connection.close() + # Set error + error = True + + # Otherwise + else : - # Save connection - self.savedCurrentPort = currentPort - self.savedCurrentBaudrate = currentBaudrate - self.savedCurrentProfile = currentProfile + # Send new EEPROM + self.getEeprom(connection, True) + + # Close connection + connection.close() + + # Save connection + self.savedCurrentPort = currentPort + self.savedCurrentBaudrate = currentBaudrate + self.savedCurrentProfile = currentProfile # Otherwise else : @@ -1869,6 +1919,12 @@ def on_api_command(self, command, data) : # Set error error = True + # Check if an error occured + if error : + + # Clear EEPROM + self.eeprom = None + # Enable printer callbacks if self not in self._printer._callbacks : self._printer.register_callback(self) @@ -1909,41 +1965,66 @@ def on_api_command(self, command, data) : # Return error if printer was found if currentPort is not None : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) - - # Check if getting EEPROM failed - if not self.getEeprom(connection) : + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break + + except : + connection = None + time.sleep(1) + # Check if failed to connect to the printer + if connection is None : + # Set error error = True - - # Otherwise - else : - # Set fan offset and scale - fanOffset = int(data["value"][21 :]) - fanScale = float(255 - fanOffset) / 255 - - # Check if setting fan failed - if not self.setFan(connection, "Custom", fanOffset, fanScale) : + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Close connection + connection.close() + + # Check if an error hasn't occured + if not error : + + # Check if getting EEPROM failed + if not self.getEeprom(connection) : # Set error error = True - + # Otherwise else : + + # Set fan offset and scale + fanOffset = int(data["value"][21 :]) + fanScale = float(255 - fanOffset) / 255 - # Send new EEPROM - self.getEeprom(connection, True) + # Check if setting fan failed + if not self.setFan(connection, "Custom", fanOffset, fanScale) : - # Close connection - connection.close() + # Set error + error = True + + # Otherwise + else : + + # Send new EEPROM + self.getEeprom(connection, True) - # Save connection - self.savedCurrentPort = currentPort - self.savedCurrentBaudrate = currentBaudrate - self.savedCurrentProfile = currentProfile + # Close connection + connection.close() + + # Save connection + self.savedCurrentPort = currentPort + self.savedCurrentBaudrate = currentBaudrate + self.savedCurrentProfile = currentProfile # Otherwise else : @@ -1951,6 +2032,12 @@ def on_api_command(self, command, data) : # Set error error = True + # Check if an error occured + if error : + + # Clear EEPROM + self.eeprom = None + # Enable printer callbacks if self not in self._printer._callbacks : self._printer.register_callback(self) @@ -1991,37 +2078,62 @@ def on_api_command(self, command, data) : # Return error if printer was found if currentPort is not None : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) - - # Check if getting EEPROM failed - if not self.getEeprom(connection) : + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break + + except : + connection = None + time.sleep(1) + # Check if failed to connect to the printer + if connection is None : + # Set error error = True + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Close connection + connection.close() + + # Check if an error hasn't occured + if not error : - # Otherwise - else : - - # Check if setting extruder current failed - if not self.setExtruderCurrent(connection, int(data["value"][22 :])) : + # Check if getting EEPROM failed + if not self.getEeprom(connection) : # Set error error = True - + # Otherwise else : + + # Check if setting extruder current failed + if not self.setExtruderCurrent(connection, int(data["value"][22 :])) : + + # Set error + error = True + + # Otherwise + else : - # Send new EEPROM - self.getEeprom(connection, True) + # Send new EEPROM + self.getEeprom(connection, True) - # Close connection - connection.close() + # Close connection + connection.close() - # Save connection - self.savedCurrentPort = currentPort - self.savedCurrentBaudrate = currentBaudrate - self.savedCurrentProfile = currentProfile + # Save connection + self.savedCurrentPort = currentPort + self.savedCurrentBaudrate = currentBaudrate + self.savedCurrentProfile = currentProfile # Otherwise else : @@ -2029,6 +2141,12 @@ def on_api_command(self, command, data) : # Set error error = True + # Check if an error occured + if error : + + # Clear EEPROM + self.eeprom = None + # Enable printer callbacks if self not in self._printer._callbacks : self._printer.register_callback(self) @@ -2158,6 +2276,9 @@ def on_api_command(self, command, data) : # Otherwise check if parameter is to read EEPROM elif data["value"] == "Read EEPROM" : + # Initialize variables + error = False + # Disable printer callbacks while self in self._printer._callbacks : self._printer.unregister_callback(self) @@ -2182,19 +2303,44 @@ def on_api_command(self, command, data) : # Return error if printer was found if currentPort is not None : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break + + except : + connection = None + time.sleep(1) + + # Check if failed to connect to the printer + if connection is None : + + # Set error + error = True + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Close connection + connection.close() + + # Check if an error hasn't occured + if not error : - # Get EEPROM and send it - self.getEeprom(connection, True) + # Get EEPROM and send it + self.getEeprom(connection, True) - # Close connection - connection.close() + # Close connection + connection.close() - # Save connection - self.savedCurrentPort = currentPort - self.savedCurrentBaudrate = currentBaudrate - self.savedCurrentProfile = currentProfile + # Save connection + self.savedCurrentPort = currentPort + self.savedCurrentBaudrate = currentBaudrate + self.savedCurrentProfile = currentProfile # Otherwise else : @@ -2202,6 +2348,12 @@ def on_api_command(self, command, data) : # Set error error = True + # Check if an error occured + if error : + + # Clear EEPROM + self.eeprom = None + # Enable printer callbacks if self not in self._printer._callbacks : self._printer.register_callback(self) @@ -2254,47 +2406,72 @@ def on_api_command(self, command, data) : # Return error if printer was found if currentPort is not None : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) - - # Check if getting EEPROM failed - if not self.getEeprom(connection) : + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break + + except : + connection = None + time.sleep(1) + # Check if failed to connect to the printer + if connection is None : + + # Set error + error = True + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + # Set error error = True + + # Close connection + connection.close() + + # Check if an error hasn't occured + if not error : + + # Check if getting EEPROM failed + if not self.getEeprom(connection) : - # Otherwise - else : + # Set error + error = True - # Go through bytes of new EEPROM - index = 0 - while index < len(newEeprom) : + # Otherwise + else : + + # Go through bytes of new EEPROM + index = 0 + while index < len(newEeprom) : - # Check if bytes in EEPROM differ - if self.eeprom[index] != newEeprom[index] : + # Check if bytes in EEPROM differ + if self.eeprom[index] != newEeprom[index] : - # Check if updating byte in EEPROM failed - if not error and not self.writeToEeprom(connection, index, newEeprom[index]) : + # Check if updating byte in EEPROM failed + if not error and not self.writeToEeprom(connection, index, newEeprom[index]) : - # Set error - error = True + # Set error + error = True - # Increment index - index += 1 + # Increment index + index += 1 - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Clear EEPROM - self.eeprom = None + # Clear EEPROM + self.eeprom = None - # Close connection - connection.close() + # Close connection + connection.close() - # Save connection - self.savedCurrentPort = currentPort - self.savedCurrentBaudrate = currentBaudrate - self.savedCurrentProfile = currentProfile + # Save connection + self.savedCurrentPort = currentPort + self.savedCurrentBaudrate = currentBaudrate + self.savedCurrentProfile = currentProfile # Otherwise else : @@ -2302,6 +2479,12 @@ def on_api_command(self, command, data) : # Set error error = True + # Check if an error occured + if error : + + # Clear EEPROM + self.eeprom = None + # Enable printer callbacks if self not in self._printer._callbacks : self._printer.register_callback(self) @@ -2432,7 +2615,7 @@ def on_api_command(self, command, data) : # Get printer settings try : printerSettings = yaml.load(data["value"][21 :]) - except Exception : + except : return flask.jsonify(dict(value = "Error")) # Save printer settings @@ -2590,43 +2773,74 @@ def on_api_command(self, command, data) : # Return error if printer was found if currentPort is not None : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break + + except : + connection = None + time.sleep(1) - # Check if getting EEPROM failed - if not self.getEeprom(connection) : - + # Check if failed to connect to the printer + if connection is None : + # Set error error = True + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Close connection + connection.close() + + # Check if an error hasn't occured + if not error : + + # Check if getting EEPROM failed + if not self.getEeprom(connection) : - # Otherwise - else : - - # Check if updating firmware failed - if not self.updateToProvidedFirmware(connection, firmwareName) : - # Set error error = True - + # Otherwise else : + + # Check if updating firmware failed + if not self.updateToProvidedFirmware(connection, firmwareName) : + + # Set error + error = True - # Clear EEPROM - self.eeprom = None + # Otherwise + else : + + # Clear EEPROM + self.eeprom = None - # Close connection - connection.close() + # Close connection + connection.close() - # Save connection - self.savedCurrentPort = currentPort - self.savedCurrentBaudrate = currentBaudrate - self.savedCurrentProfile = currentProfile + # Save connection + self.savedCurrentPort = currentPort + self.savedCurrentBaudrate = currentBaudrate + self.savedCurrentProfile = currentProfile # Otherwise else : # Set error error = True + + # Check if an error occured + if error : + + # Clear EEPROM + self.eeprom = None # Enable printer callbacks if self not in self._printer._callbacks : @@ -2825,21 +3039,21 @@ def on_api_command(self, command, data) : error = False encryptedRom = '' - # Disable printer callbacks - while self in self._printer._callbacks : - self._printer.unregister_callback(self) - - # Get current printer connection state - currentState, currentPort, currentBaudrate, currentProfile = self._printer.get_current_connection() - - # Set baudrate if invalid - if not currentBaudrate or currentBaudrate == 0 : - currentBaudrate = 115200 - # Check if firmware version is valid firmwareVersion = re.search("(^| )\\d{10}(?=\\.|$)", data["name"]) if firmwareVersion is not None : + # Disable printer callbacks + while self in self._printer._callbacks : + self._printer.unregister_callback(self) + + # Get current printer connection state + currentState, currentPort, currentBaudrate, currentProfile = self._printer.get_current_connection() + + # Set baudrate if invalid + if not currentBaudrate or currentBaudrate == 0 : + currentBaudrate = 115200 + # Set firmware version firmwareVersion = firmwareVersion.group(0).strip() @@ -2856,47 +3070,82 @@ def on_api_command(self, command, data) : # Return error if printer was found if currentPort is not None : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) - - # Get encrypted rom from unicode content - for character in data["content"] : - encryptedRom += chr(ord(character)) - - # Check if getting EEPROM failed - if not self.getEeprom(connection) : + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break + except : + connection = None + time.sleep(1) + + # Check if failed to connect to the printer + if connection is None : + # Set error error = True - - # Otherwise - else : + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Close connection + connection.close() + + # Check if an error hasn't occured + if not error : - # Check if updating firmware failed - if not self.updateFirmware(connection, encryptedRom, int(firmwareVersion)) : + # Get encrypted rom from unicode content + for character in data["content"] : + encryptedRom += chr(ord(character)) + # Check if getting EEPROM failed + if not self.getEeprom(connection) : + # Set error error = True - + # Otherwise else : + + # Check if updating firmware failed + if not self.updateFirmware(connection, encryptedRom, int(firmwareVersion)) : + + # Set error + error = True - # Clear EEPROM - self.eeprom = None + # Otherwise + else : + + # Clear EEPROM + self.eeprom = None - # Close connection - connection.close() + # Close connection + connection.close() - # Save connection - self.savedCurrentPort = currentPort - self.savedCurrentBaudrate = currentBaudrate - self.savedCurrentProfile = currentProfile + # Save connection + self.savedCurrentPort = currentPort + self.savedCurrentBaudrate = currentBaudrate + self.savedCurrentProfile = currentProfile # Otherwise else : # Set error error = True + + # Check if an error occured + if error : + + # Clear EEPROM + self.eeprom = None + + # Enable printer callbacks + if self not in self._printer._callbacks : + self._printer.register_callback(self) # Otherwise else : @@ -2904,10 +3153,6 @@ def on_api_command(self, command, data) : # Set error error = True - # Enable printer callbacks - if self not in self._printer._callbacks : - self._printer.register_callback(self) - # Send response if error : return flask.jsonify(dict(value = "Error")) @@ -2942,7 +3187,7 @@ def getEeprom(self, connection, send = False) : self.eeprom = connection.read(0x301) # Check if an error occured - except serial.SerialException : + except : # Don't save response self.eeprom = None @@ -2951,7 +3196,7 @@ def getEeprom(self, connection, send = False) : return False # Check if EEPROM wasn't read successfully - if self.eeprom[-1] != '\r' : + if len(self.eeprom) != 0x301 or self.eeprom[-1] != '\r' : # Don't save response self.eeprom = None @@ -3255,12 +3500,8 @@ def updateFirmware(self, connection, encryptedRom, romVersion) : # Set error error = True - # Return false if an error occured - if error : - return False - - # Return true - return True + # Return if an error didn't occur + return not error # Set fan def setFan(self, connection, name, newFanOffset = None, newFanScale = None) : @@ -3326,24 +3567,23 @@ def setFan(self, connection, name, newFanOffset = None, newFanScale = None) : # Set error to if saving fan offset in EEPROM failed error = self.eepromSetInt(connection, "fanType", fanType) - # Return false if an error occured - if error : - return False - - # Return true - return True + # Return if an error didn't occur + return not error # Set extruder current def setExtruderCurrent(self, connection, value) : + # Clear error + error = False + # Check if extruder current values differ if self.eepromGetInt("eMotorCurrent") != value : - # Return if saving extruder current in EEPROM was successful - return self.eepromSetInt(connection, "eMotorCurrent", value) + # Set error to if saving extruder current in EEPROM was successful + error = self.eepromSetInt(connection, "eMotorCurrent", value) - # Return true - return True + # Return if an error didn't occur + return not error # Send command def sendCommands(self, commands) : @@ -3468,6 +3708,15 @@ def processWrite(self, data) : # Log sent data self._m33fio_logger.debug("Original Sent: " + data) + + # Check if canceling print + if self.cancelingPrint : + + # Fake confirmation + self._printer.fake_ack() + + # Return + return returnValue # Check if printing if self._printer.is_printing() : @@ -3486,6 +3735,19 @@ def processWrite(self, data) : # Set command to hard emergency stop data = "M0\n" + + # Empty command queue + self.emptyCommandQueue() + + # Set first line number to zero and clear history + if self._printer._comm is not None : + self._printer._comm._gcode_M110_sending("N0") + self._printer._comm._long_running_command = True + + # Clear sent commands + self.sentCommands = {} + self.resetLineNumberCommandSent = False + self.numberWrapCounter = 0 # Check if request is invalid if (not self._printer.is_printing() and (data.startswith("N0 M110 N0") or data.startswith("M110"))) or data == "M21\n" or data == "M84\n" : @@ -3498,69 +3760,112 @@ def processWrite(self, data) : # Check if request is hard emergency stop if "M0" in data : - + # Check if printing or paused if self._printer.is_printing() or self._printer.is_paused() : - - # Clear perform cancel print movement - self.performCancelPrintMovement = False - + + # Set canceling print + self.cancelingPrint = True + # Stop printing self._printer.cancel_print() - - # Empty command queue - self.emptyCommandQueue() - - # Set first line number to zero and clear history - if self._printer._comm is not None : - self._printer._comm._gcode_M110_sending("N0") - self._printer._comm._long_running_command = True - - # Clear sent commands - self.sentCommands = {} - self.resetLineNumberCommandSent = False - self.numberWrapCounter = 0 + + # Empty command queue + self.emptyCommandQueue() + + # Set first line number to zero and clear history + if self._printer._comm is not None : + self._printer._comm._gcode_M110_sending("N0") + self._printer._comm._long_running_command = True + + # Clear sent commands + self.sentCommands = {} + self.resetLineNumberCommandSent = False + self.numberWrapCounter = 0 + + # Clear canceling print + self.cancelingPrint = False + + # Set commands + commands = [ + "M104 S0" + ] + + if self.heatbedConnected : + commands += ["M140 S0"] + + if self._settings.get_boolean(["UseGpio"]) : + commands += ["M107 T1"] + + commands += ["M18"] + commands += ["M107"] + + if self._settings.get_boolean(["ChangeLedBrightness"]) : + if self.printerColor == "Clear" : + commands += ["M420 T20"] + else : + commands += ["M420 T100"] + + # Append print done to command list + commands += ["M65541;print done"] + + # Send commands with line numbers + self.sendCommandsWithLineNumbers(commands) # Otherwise check if request is soft emergency stop elif "M65537" in data : + + # Check if printing or paused + if self._printer.is_printing() or self._printer.is_paused() : + + # Set canceling print + self.cancelingPrint = True - # Empty command queue - self.emptyCommandQueue() + # Wait until all sent commands have been processed + while len(self.sentCommands) : + + # Set long running command + self._printer._comm._long_running_command = True + + # Update communication timeout to prevent other commands from being sent + if self._printer._comm is not None : + self._printer._comm._gcode_G4_sent("G4 P10") - # Wait until all sent commands have been processed - while len(self.sentCommands) : + time.sleep(0.01) + + # Stop printing + self._printer.cancel_print() - # Set long running command - self._printer._comm._long_running_command = True - - # Update communication timeout to prevent other commands from being sent + # Empty command queue + self.emptyCommandQueue() + + # Set first line number to zero and clear history if self._printer._comm is not None : - self._printer._comm._gcode_G4_sent("G4 P10") - - time.sleep(0.01) - - # Check if printing or paused - if self._printer.is_printing() or self._printer.is_paused() : - + self._printer._comm._gcode_M110_sending("N0") + self._printer._comm._long_running_command = True + + # Clear sent commands + self.sentCommands = {} + self.resetLineNumberCommandSent = False + self.numberWrapCounter = 0 + + # Clear canceling print + self.cancelingPrint = False + # Set perform cancel print movement self.performCancelPrintMovement = True - - # Stop printing - self._printer.cancel_print() - - # Empty command queue - self.emptyCommandQueue() - - # Set first line number to zero and clear history - if self._printer._comm is not None : - self._printer._comm._gcode_M110_sending("N0") + + # Set commands + commands = [ + "M114" + ] + + # Set long running command self._printer._comm._long_running_command = True - # Clear sent commands - self.sentCommands = {} - self.resetLineNumberCommandSent = False - self.numberWrapCounter = 0 - + # Send commands with line numbers + self.sendCommandsWithLineNumbers(commands) + # Return return returnValue @@ -3573,35 +3878,39 @@ def processWrite(self, data) : # Check if pre-processing on the fly and command is not a starting line number and wasn't added on the fly if self._printer.is_printing() and self._settings.get_boolean(["PreprocessOnTheFly"]) and not data.startswith("N0 M110") and "**" not in data : - # Get line number - lineNumber = int(re.findall("^N(\d+)", data)[0]) + # Check if command contains a line number + lineNumberLocation = re.findall("^N(\d+)", data) + if len(lineNumberLocation) : + + # Get line number + lineNumber = int(lineNumberLocation[0]) - # Check if shared library was loaded - if self.sharedLibrary : + # Check if shared library was loaded + if self.sharedLibrary : - # Pre-process command - commands = self.sharedLibrary.preprocess(ctypes.c_char_p(data), ctypes.c_char_p(None), ctypes.c_bool(False)).split(',') + # Pre-process command + commands = self.sharedLibrary.preprocess(ctypes.c_char_p(data), ctypes.c_char_p(None), ctypes.c_bool(False)).split(',') - # Otherwise - else : + # Otherwise + else : - # Pre-process command - commands = self.preprocess(data) + # Pre-process command + commands = self.preprocess(data) - # Check if pre-processed commands were returned - if len(commands) and commands != [''] : + # Check if pre-processed commands were returned + if len(commands) and commands != [''] : - # Set data to first pre-processed command - data = 'N' + str(lineNumber) + ' ' + commands[0] + '\n' + # Set data to first pre-processed command + data = 'N' + str(lineNumber) + ' ' + commands[0] + '\n' - # Send the remaining pre-processed commands to the printer - self.sendCommands(commands[1 :]) + # Send the remaining pre-processed commands to the printer + self.sendCommands(commands[1 :]) - # Otherwise - else : + # Otherwise + else : - # Set command to nothing - data = 'N' + str(lineNumber) + " G4\n" + # Set command to nothing + data = 'N' + str(lineNumber) + " G4\n" # Check if command contains valid G-code gcode = Gcode() @@ -3623,7 +3932,7 @@ def processWrite(self, data) : self.heatbedConnection.write("s " + temperature + '\r') self.showHeatbedTemperature = temperature != "0" - except Exception : + except : pass # Set command to nothing @@ -3645,7 +3954,7 @@ def processWrite(self, data) : self.heatbedConnection.write("w " + temperature + '\r') self.showHeatbedTemperature = temperature != "0" - except Exception : + except : error = True # Check if no errors occured and communication layer has been established @@ -3672,7 +3981,7 @@ def processWrite(self, data) : if heatbedTemperature == "ok" : readingTemperature = False - except Exception : + except : readingTemperature = False break @@ -3976,8 +4285,11 @@ def processWrite(self, data) : # Store command self.sentCommands[lineNumber % 0x10000] = data - # Set last command sent - self.lastCommandSent = data + # Check if command doesn't have a line number + if not gcode.hasValue('N') : + + # Set last command sent + self.lastCommandSent = data # Send command to printer self.originalWrite(data) @@ -4095,7 +4407,7 @@ def processRead(self) : self.heatbedConnection.write("t\r") heatbedTemperature = self.heatbedConnection.readline().strip() - except Exception : + except : heatbedTemperature = "0" # Append heatbed temperature to to response @@ -4477,7 +4789,7 @@ def on_event(self, event, payload) : try : self._printer._comm.close(False, False) - except TypeError : + except : pass self._printer.disconnect() @@ -4579,7 +4891,7 @@ def on_event(self, event, payload) : else : self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Camera Not Hostable")) - except Exception : + except : self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Camera Not Hostable")) # Set file locations @@ -4720,10 +5032,7 @@ def on_event(self, event, payload) : # Create message self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Create message", type = "error", title = "Print failed", text = "Could not print the file. The dimensions of the model go outside the bounds of the printer.")) - - # Clear perform cancel print movement - self.performCancelPrintMovement = False - + # Stop printing self._printer.cancel_print() @@ -4830,64 +5139,8 @@ def on_event(self, event, payload) : # Unload shared library self.unloadSharedLibrary() - # Check if using a Micro 3D printer - if not self._settings.get_boolean(["NotUsingAMicro3DPrinter"]) : - - # Empty command queue - self.emptyCommandQueue() - - # Set first line number to zero and clear history - if self._printer._comm is not None : - self._printer._comm._gcode_M110_sending("N0") - self._printer._comm._long_running_command = True - - # Clear sent commands - self.sentCommands = {} - self.resetLineNumberCommandSent = False - self.numberWrapCounter = 0 - - # Check if performing cancel print movement - if self.performCancelPrintMovement : - - # Set commands - commands = [ - "M114" - ] - - # Set long running command - self._printer._comm._long_running_command = True - - # Otherwise - else : - - # Set commands - commands = [ - "M104 S0" - ] - - if self.heatbedConnected : - commands += ["M140 S0"] - - if self._settings.get_boolean(["UseGpio"]) : - commands += ["M107 T1"] - - commands += ["M18"] - commands += ["M107"] - - if self._settings.get_boolean(["ChangeLedBrightness"]) : - if self.printerColor == "Clear" : - commands += ["M420 T20"] - else : - commands += ["M420 T100"] - - # Append print done to command list - commands += ["M65541;print done"] - - # Send commands with line numbers - self.sendCommandsWithLineNumbers(commands) - - # Otherwise - else : + # Check if not using a Micro 3D printer + if self._settings.get_boolean(["NotUsingAMicro3DPrinter"]) : # Enable sleep self.enableSleep() @@ -4903,7 +5156,7 @@ def isPortOpen(self, port) : socketConnection.bind(('', port)) # Return false if an error occured - except socket.error : + except : return False # Return true @@ -4917,7 +5170,7 @@ def getListenPort(self, process) : connections = process.connections() # Return none if process doesn't exist - except Exception : + except : return None # Go through all connections @@ -5085,7 +5338,7 @@ def on_printer_add_log(self, data) : try : self._printer._comm.close(False, False) - except TypeError : + except : pass self._printer.disconnect() @@ -5099,510 +5352,542 @@ def on_printer_add_log(self, data) : # Otherwise else : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) - - # Attempt to get current printer mode + # Attempt to connect to the printer try : - connection.write("M110") - bootloaderVersion = connection.read() + connection = serial.Serial(currentPort, currentBaudrate) - if float(serial.VERSION) < 3 : - bootloaderVersion += connection.read(connection.inWaiting()) - else : - bootloaderVersion += connection.read(connection.in_waiting) - # Check if an error occured - except serial.SerialException : + except : + + # Set connection to none + connection = None # Set error error = True # Send message self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) - + # Check if no errors occured if not error : - - # Check if not in bootloader mode - if not bootloaderVersion.startswith('B') : - - # Save ports - self.savePorts(currentPort) + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + if (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : - # Switch to bootloader mode - connection.write("M115 S628") + # Set error + error = True + + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "You don't have read/write access to " + str(port), header = "Connection Status", confirm = True)) + # Check if no errors occured + if not error : + + # Attempt to get current printer mode try : - gcode = Gcode("M115 S628") - connection.write(gcode.getBinary()) + connection.write("M110") + bootloaderVersion = connection.read() + + if float(serial.VERSION) < 3 : + bootloaderVersion += connection.read(connection.inWaiting()) + else : + bootloaderVersion += connection.read(connection.in_waiting) + # Check if an error occured - except serial.SerialException : - pass + except : + + # Set error + error = True - time.sleep(1) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + + # Check if no errors occured + if not error : + + # Check if not in bootloader mode + if not bootloaderVersion.startswith('B') : + + # Save ports + self.savePorts(currentPort) - # Close connection - connection.close() + # Switch to bootloader mode + connection.write("M115 S628") - # Set updated port - currentPort = self.getPort() + try : + gcode = Gcode("M115 S628") + connection.write(gcode.getBinary()) - # Check if printer wasn't found - if currentPort is None : + # Check if an error occured + except : + pass + + time.sleep(1) + + # Close connection + connection.close() + connection = None + + # Set updated port + currentPort = self.getPort() + + # Check if printer wasn't found + if currentPort is None : - # Set error - error = True + # Set error + error = True - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "No Micro 3D printer detected. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) - # Otherwise - else : + # Otherwise + else : - # Re-connect; wait for the device to be available - connection = None - for i in xrange(5) : - try : - connection = serial.Serial(currentPort, currentBaudrate) - break + # Re-connect; wait for the device to be available + for i in xrange(5) : + try : + connection = serial.Serial(currentPort, currentBaudrate) + break - except Exception : - connection = None - time.sleep(1) - - # Check if using OS X or Linux and the user lacks read/write access to the printer - if (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : - - # Set error - error = True + except : + connection = None + time.sleep(1) - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "You don't have read/write access to " + str(port), header = "Connection Status", confirm = True)) - - # Otherwise check if connecting to printer failed - elif connection is None : + # Check if connecting to printer failed + if connection is None : - # Set error - error = True + # Set error + error = True - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "You don't have read/write access to " + str(port), header = "Connection Status", confirm = True)) - # Check if an error hasn't occured - if not error : - - # Check if getting EEPROM was successful - if self.getEeprom(connection) : - - # Get firmware CRC from EEPROM - eepromCrc = self.eepromGetInt("firmwareCrc") - - # Request firmware CRC from chip - connection.write('C') - connection.write('A') - - # Get response - response = connection.read(4) - - # Get chip CRC - chipCrc = 0 - index = 3 - while index >= 0 : - chipCrc <<= 8 - chipCrc += int(ord(response[index])) - index -= 1 + # Check if an error hasn't occured + if not error : - # Get firmware details - firmwareType, firmwareVersion, firmwareRelease = self.getFirmwareDetails() - - # Get serial number from EEPROM - serialNumber = self.eepromGetString("serialNumber") - - # Set printer color - color = serialNumber[0 : 2] - if color == "BK" : - self.printerColor = "Black" - elif color == "WH" : - self.printerColor = "White" - elif color == "BL" : - self.printerColor = "Blue" - elif color == "GR" : - self.printerColor = "Green" - elif color == "OR" : - self.printerColor = "Orange" - elif color == "CL" : - self.printerColor = "Clear" - elif color == "SL" : - self.printerColor = "Silver" - elif color == "PL" : - self.printerColor = "Purple" - - # Get fan type from EEPROM - fanType = self.eepromGetInt("fanType") - - # Check if fan hasn't been set yet - if fanType == 0 or fanType == 0xFF : - - # Check if device is newer - if int(serialNumber[2 : 8]) >= 150602 : - - # Set default newer fan - fanName = "Shenzhew" + # Check if getting EEPROM was successful + if self.getEeprom(connection) : + + # Get firmware CRC from EEPROM + eepromCrc = self.eepromGetInt("firmwareCrc") + + # Request firmware CRC from chip + connection.write('C') + connection.write('A') + + # Get response + response = connection.read(4) + + # Get chip CRC + chipCrc = 0 + index = 3 + while index >= 0 : + chipCrc <<= 8 + chipCrc += int(ord(response[index])) + index -= 1 + + # Get firmware details + firmwareType, firmwareVersion, firmwareRelease = self.getFirmwareDetails() + + # Get serial number from EEPROM + serialNumber = self.eepromGetString("serialNumber") + + # Set printer color + color = serialNumber[0 : 2] + if color == "BK" : + self.printerColor = "Black" + elif color == "WH" : + self.printerColor = "White" + elif color == "BL" : + self.printerColor = "Blue" + elif color == "GR" : + self.printerColor = "Green" + elif color == "OR" : + self.printerColor = "Orange" + elif color == "CL" : + self.printerColor = "Clear" + elif color == "SL" : + self.printerColor = "Silver" + elif color == "PL" : + self.printerColor = "Purple" + + # Get fan type from EEPROM + fanType = self.eepromGetInt("fanType") + + # Check if fan hasn't been set yet + if fanType == 0 or fanType == 0xFF : + + # Check if device is newer + if int(serialNumber[2 : 8]) >= 150602 : + + # Set default newer fan + fanName = "Shenzhew" - # Otherwise - else : + # Otherwise + else : - # Set default older fan - fanName = "HengLiXin" + # Set default older fan + fanName = "HengLiXin" - # Check if setting fan failed - if not self.setFan(connection, fanName) : + # Check if setting fan failed + if not self.setFan(connection, fanName) : - # Set error - error = True + # Set error + error = True - # Check if an error occured - if error : + # Check if an error occured + if error : - # Display error - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Setting fan failed", header = "Error Status", confirm = True)) + # Display error + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Setting fan failed", header = "Error Status", confirm = True)) - # Otherwise - else : + # Otherwise + else : - # Set fan name - fanName = None - if fanType == 1 : - fanName = "HengLiXin" - elif fanType == 2 : - fanName = "Listener" - elif fanType == 3 : - fanName = "Shenzhew" - elif fanType == 4 : - fanName = "Xinyujie" + # Set fan name + fanName = None + if fanType == 1 : + fanName = "HengLiXin" + elif fanType == 2 : + fanName = "Listener" + elif fanType == 3 : + fanName = "Shenzhew" + elif fanType == 4 : + fanName = "Xinyujie" - # Check if updating fan failed - if fanName is not None and not self.setFan(connection, fanName) : + # Check if updating fan failed + if fanName is not None and not self.setFan(connection, fanName) : - # Set error - error = True + # Set error + error = True - # Display error - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating fan settings failed", header = "Error Status", confirm = True)) + # Display error + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating fan settings failed", header = "Error Status", confirm = True)) - # Check if printer uses 500mA extruder current - shortSerialNumber = serialNumber[0 : 13] - if not error and (shortSerialNumber == "BK15033001100" or shortSerialNumber == "BK15040201050" or shortSerialNumber == "BK15040301050" or shortSerialNumber == "BK15040602050" or shortSerialNumber == "BK15040801050" or shortSerialNumber == "BK15040802100" or shortSerialNumber == "GR15032702100" or shortSerialNumber == "GR15033101100" or shortSerialNumber == "GR15040601100" or shortSerialNumber == "GR15040701100" or shortSerialNumber == "OR15032701100" or shortSerialNumber == "SL15032601050") : + # Check if printer uses 500mA extruder current + shortSerialNumber = serialNumber[0 : 13] + if not error and (shortSerialNumber == "BK15033001100" or shortSerialNumber == "BK15040201050" or shortSerialNumber == "BK15040301050" or shortSerialNumber == "BK15040602050" or shortSerialNumber == "BK15040801050" or shortSerialNumber == "BK15040802100" or shortSerialNumber == "GR15032702100" or shortSerialNumber == "GR15033101100" or shortSerialNumber == "GR15040601100" or shortSerialNumber == "GR15040701100" or shortSerialNumber == "OR15032701100" or shortSerialNumber == "SL15032601050") : - # Check if setting extruder current failed - if not self.setExtruderCurrent(connection, 500) : - - # Set error - error = True + # Check if setting extruder current failed + if not self.setExtruderCurrent(connection, 500) : - # Display error - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating extruder current failed", header = "Error Status", confirm = True)) + # Set error + error = True + + # Display error + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating extruder current failed", header = "Error Status", confirm = True)) - # Check if using M3D or M3D Mod firmware and it's from before new bed orientation and adjustable backlash speed - if not error and firmwareType is not None and ((firmwareType == "M3D" and firmwareVersion < 2015080402) or (firmwareType == "M3D Mod" and firmwareVersion < 2115080402)) : + # Check if using M3D or M3D Mod firmware and it's from before new bed orientation and adjustable backlash speed + if not error and firmwareType is not None and ((firmwareType == "M3D" and firmwareVersion < 2015080402) or (firmwareType == "M3D Mod" and firmwareVersion < 2115080402)) : - # Set error to if zeroing out all bed offets in EEPROM failed - error = self.eepromSetInt(connection, "bedOffsetBackLeft", 0, self.eepromOffsets["bedHeightOffset"]["offset"] + self.eepromOffsets["bedHeightOffset"]["bytes"] - self.eepromOffsets["bedOffsetBackLeft"]["offset"]) + # Set error to if zeroing out all bed offets in EEPROM failed + error = self.eepromSetInt(connection, "bedOffsetBackLeft", 0, self.eepromOffsets["bedHeightOffset"]["offset"] + self.eepromOffsets["bedHeightOffset"]["bytes"] - self.eepromOffsets["bedOffsetBackLeft"]["offset"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if setting default backlash speed failed - error = self.eepromSetFloat(connection, "backlashSpeed", 1500) + # Set error to if setting default backlash speed failed + error = self.eepromSetFloat(connection, "backlashSpeed", 1500) - # Check if an error has occured - if error : + # Check if an error has occured + if error : - # Display error - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating version changes failed", header = "Error Status", confirm = True)) + # Display error + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating version changes failed", header = "Error Status", confirm = True)) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting backlash X failed - error = self.eepromKeepFloatWithinRange(connection, "backlashX", 0, 2, self.get_settings_defaults()["BacklashX"]) + # Set error to if limiting backlash X failed + error = self.eepromKeepFloatWithinRange(connection, "backlashX", 0, 2, self.get_settings_defaults()["BacklashX"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting backlash Y failed - error = self.eepromKeepFloatWithinRange(connection, "backlashY", 0, 2, self.get_settings_defaults()["BacklashY"]) + # Set error to if limiting backlash Y failed + error = self.eepromKeepFloatWithinRange(connection, "backlashY", 0, 2, self.get_settings_defaults()["BacklashY"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting backlash speed failed - error = self.eepromKeepFloatWithinRange(connection, "backlashSpeed", 1, 5000, self.get_settings_defaults()["BacklashSpeed"]) + # Set error to if limiting backlash speed failed + error = self.eepromKeepFloatWithinRange(connection, "backlashSpeed", 1, 5000, self.get_settings_defaults()["BacklashSpeed"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting back left orientation failed - error = self.eepromKeepFloatWithinRange(connection, "bedOrientationBackLeft", -3, 3, self.get_settings_defaults()["BackLeftOrientation"]) + # Set error to if limiting back left orientation failed + error = self.eepromKeepFloatWithinRange(connection, "bedOrientationBackLeft", -3, 3, self.get_settings_defaults()["BackLeftOrientation"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting back right orientation failed - error = self.eepromKeepFloatWithinRange(connection, "bedOrientationBackRight", -3, 3, self.get_settings_defaults()["BackRightOrientation"]) + # Set error to if limiting back right orientation failed + error = self.eepromKeepFloatWithinRange(connection, "bedOrientationBackRight", -3, 3, self.get_settings_defaults()["BackRightOrientation"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting front right orientation failed - error = self.eepromKeepFloatWithinRange(connection, "bedOrientationFrontRight", -3, 3, self.get_settings_defaults()["FrontRightOrientation"]) + # Set error to if limiting front right orientation failed + error = self.eepromKeepFloatWithinRange(connection, "bedOrientationFrontRight", -3, 3, self.get_settings_defaults()["FrontRightOrientation"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting front left orientation failed - error = self.eepromKeepFloatWithinRange(connection, "bedOrientationFrontLeft", -3, 3, self.get_settings_defaults()["FrontLeftOrientation"]) + # Set error to if limiting front left orientation failed + error = self.eepromKeepFloatWithinRange(connection, "bedOrientationFrontLeft", -3, 3, self.get_settings_defaults()["FrontLeftOrientation"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting back left offset failed - error = self.eepromKeepFloatWithinRange(connection, "bedOffsetBackLeft", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["BackLeftOffset"]) + # Set error to if limiting back left offset failed + error = self.eepromKeepFloatWithinRange(connection, "bedOffsetBackLeft", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["BackLeftOffset"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting back right offset failed - error = self.eepromKeepFloatWithinRange(connection, "bedOffsetBackRight", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["BackRightOffset"]) + # Set error to if limiting back right offset failed + error = self.eepromKeepFloatWithinRange(connection, "bedOffsetBackRight", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["BackRightOffset"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting front right offset failed - error = self.eepromKeepFloatWithinRange(connection, "bedOffsetFrontRight", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["FrontRightOffset"]) + # Set error to if limiting front right offset failed + error = self.eepromKeepFloatWithinRange(connection, "bedOffsetFrontRight", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["FrontRightOffset"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting front left offset failed - error = self.eepromKeepFloatWithinRange(connection, "bedOffsetFrontLeft", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["FrontLeftOffset"]) + # Set error to if limiting front left offset failed + error = self.eepromKeepFloatWithinRange(connection, "bedOffsetFrontLeft", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["FrontLeftOffset"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting bed height offset offset failed - error = self.eepromKeepFloatWithinRange(connection, "bedHeightOffset", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["BedHeightOffset"]) + # Set error to if limiting bed height offset offset failed + error = self.eepromKeepFloatWithinRange(connection, "bedHeightOffset", -sys.float_info.max, sys.float_info.max, self.get_settings_defaults()["BedHeightOffset"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting speed limit X failed - error = self.eepromKeepFloatWithinRange(connection, "speedLimitX", 120, 4800, self.get_settings_defaults()["SpeedLimitX"]) + # Set error to if limiting speed limit X failed + error = self.eepromKeepFloatWithinRange(connection, "speedLimitX", 120, 4800, self.get_settings_defaults()["SpeedLimitX"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting speed limit Y failed - error = self.eepromKeepFloatWithinRange(connection, "speedLimitY", 120, 4800, self.get_settings_defaults()["SpeedLimitY"]) + # Set error to if limiting speed limit Y failed + error = self.eepromKeepFloatWithinRange(connection, "speedLimitY", 120, 4800, self.get_settings_defaults()["SpeedLimitY"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting speed limit Z failed - error = self.eepromKeepFloatWithinRange(connection, "speedLimitZ", 30, 60, self.get_settings_defaults()["SpeedLimitZ"]) + # Set error to if limiting speed limit Z failed + error = self.eepromKeepFloatWithinRange(connection, "speedLimitZ", 30, 60, self.get_settings_defaults()["SpeedLimitZ"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting speed limit E positive failed - error = self.eepromKeepFloatWithinRange(connection, "speedLimitEPositive", 60, 600, self.get_settings_defaults()["SpeedLimitEPositive"]) + # Set error to if limiting speed limit E positive failed + error = self.eepromKeepFloatWithinRange(connection, "speedLimitEPositive", 60, 600, self.get_settings_defaults()["SpeedLimitEPositive"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting speed limit E negative failed - error = self.eepromKeepFloatWithinRange(connection, "speedLimitENegative", 60, 720, self.get_settings_defaults()["SpeedLimitENegative"]) + # Set error to if limiting speed limit E negative failed + error = self.eepromKeepFloatWithinRange(connection, "speedLimitENegative", 60, 720, self.get_settings_defaults()["SpeedLimitENegative"]) - # Check if using iMe firmware - if firmwareType == "iMe" : + # Check if using iMe firmware + if firmwareType == "iMe" : - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting last recorded X value failed - error = self.eepromKeepFloatWithinRange(connection, "lastRecordedXValue", -sys.float_info.max, sys.float_info.max, 54) + # Set error to if limiting last recorded X value failed + error = self.eepromKeepFloatWithinRange(connection, "lastRecordedXValue", -sys.float_info.max, sys.float_info.max, 54) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting last recorded Y value failed - error = self.eepromKeepFloatWithinRange(connection, "lastRecordedYValue", -sys.float_info.max, sys.float_info.max, 50) + # Set error to if limiting last recorded Y value failed + error = self.eepromKeepFloatWithinRange(connection, "lastRecordedYValue", -sys.float_info.max, sys.float_info.max, 50) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting X motor steps/mm failed - error = self.eepromKeepFloatWithinRange(connection, "xMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["XMotorStepsPerMm"]) + # Set error to if limiting X motor steps/mm failed + error = self.eepromKeepFloatWithinRange(connection, "xMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["XMotorStepsPerMm"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting Y motor steps/mm failed - error = self.eepromKeepFloatWithinRange(connection, "yMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["YMotorStepsPerMm"]) + # Set error to if limiting Y motor steps/mm failed + error = self.eepromKeepFloatWithinRange(connection, "yMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["YMotorStepsPerMm"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting Z motor steps/mm failed - error = self.eepromKeepFloatWithinRange(connection, "zMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["ZMotorStepsPerMm"]) + # Set error to if limiting Z motor steps/mm failed + error = self.eepromKeepFloatWithinRange(connection, "zMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["ZMotorStepsPerMm"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting E motor steps/mm failed - error = self.eepromKeepFloatWithinRange(connection, "eMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["EMotorStepsPerMm"]) + # Set error to if limiting E motor steps/mm failed + error = self.eepromKeepFloatWithinRange(connection, "eMotorStepsPerMm", sys.float_info.min, sys.float_info.max, self.get_settings_defaults()["EMotorStepsPerMm"]) - # Check if an error hasn't occured - if not error : + # Check if an error hasn't occured + if not error : - # Set error to if limiting last recorded Z value failed - error = self.eepromKeepFloatWithinRange(connection, "lastRecordedZValue", -sys.float_info.max, sys.float_info.max, 5) + # Set error to if limiting last recorded Z value failed + error = self.eepromKeepFloatWithinRange(connection, "lastRecordedZValue", -sys.float_info.max, sys.float_info.max, 5) - # Check if an error has occured - if error : + # Check if an error has occured + if error : - # Display error - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating EEPROM values failed", header = "Error Status", confirm = True)) + # Display error + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating EEPROM values failed", header = "Error Status", confirm = True)) - # Check if firmware is corrupt - if not error and eepromCrc != chipCrc : + # Check if firmware is corrupt + if not error and eepromCrc != chipCrc : - # Set current firmware type - if firmwareType is None : - currentFirmwareType = "M3D" - else : - currentFirmwareType = firmwareType + # Set current firmware type + if firmwareType is None : + currentFirmwareType = "M3D" + else : + currentFirmwareType = firmwareType - # Display message - self.messageResponse = None - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Firmware is corrupt. Update to " + currentFirmwareType + " firmware version " + self.providedFirmwares[self.getNewestFirmwareName(currentFirmwareType)]["Release"] + '?', header = "Firmware Status", response = True)) + # Display message + self.messageResponse = None + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Firmware is corrupt. Update to " + currentFirmwareType + " firmware version " + self.providedFirmwares[self.getNewestFirmwareName(currentFirmwareType)]["Release"] + '?', header = "Firmware Status", response = True)) - # Wait until response is obtained - while self.messageResponse is None : - time.sleep(0.01) + # Wait until response is obtained + while self.messageResponse is None : + time.sleep(0.01) - # Check if response was no - if not self.messageResponse : + # Check if response was no + if not self.messageResponse : - # Set error - error = True + # Set error + error = True - # Otherwise - else : + # Otherwise + else : - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware", header = "Firmware Status")) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware", header = "Firmware Status")) - # Check if updating firmware failed - if not self.updateToProvidedFirmware(connection, self.getNewestFirmwareName(currentFirmwareType)) : + # Check if updating firmware failed + if not self.updateToProvidedFirmware(connection, self.getNewestFirmwareName(currentFirmwareType)) : - # Set error - error = True + # Set error + error = True - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware failed", header = "Firmware Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware failed", header = "Firmware Status", confirm = True)) - # Otherwise - else : + # Otherwise + else : - # Send message - self.messageResponse = None - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Updating firmware was successful", header = "Firmware Status", confirm = True)) + # Send message + self.messageResponse = None + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Updating firmware was successful", header = "Firmware Status", confirm = True)) - # Wait until response is obtained - while self.messageResponse is None : - time.sleep(0.01) + # Wait until response is obtained + while self.messageResponse is None : + time.sleep(0.01) - # Otherwise check if firmware is outdated - elif not error and firmwareType is not None and firmwareVersion < int(self.providedFirmwares[self.getNewestFirmwareName(firmwareType)]["Version"]) : + # Otherwise check if firmware is outdated + elif not error and firmwareType is not None and firmwareVersion < int(self.providedFirmwares[self.getNewestFirmwareName(firmwareType)]["Version"]) : - # Set if firmware is incompatible - if firmwareType == "M3D" : - incompatible = firmwareVersion < 2015122112 - elif firmwareType == "M3D Mod" : - incompatible = firmwareVersion < 2115122112 - elif firmwareType == "iMe" : - incompatible = firmwareVersion < 1900000006 + # Set if firmware is incompatible + if firmwareType == "M3D" : + incompatible = firmwareVersion < 2015122112 + elif firmwareType == "M3D Mod" : + incompatible = firmwareVersion < 2115122112 + elif firmwareType == "iMe" : + incompatible = firmwareVersion < 1900000006 - # Check if printer is incompatible or not reconnecting to printer - if incompatible or not self.reconnectingToPrinter : + # Check if printer is incompatible or not reconnecting to printer + if incompatible or not self.reconnectingToPrinter : - # Display message - self.messageResponse = None - if incompatible : - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Firmware is incompatible. Update to " + firmwareType + " firmware version " + self.providedFirmwares[self.getNewestFirmwareName(firmwareType)]["Release"] + '?', header = "Firmware Status", response = True)) - else : - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Newer firmware available. Update to " + firmwareType + " firmware version " + self.providedFirmwares[self.getNewestFirmwareName(firmwareType)]["Release"] + '?', header = "Firmware Status", response = True)) + # Display message + self.messageResponse = None + if incompatible : + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Firmware is incompatible. Update to " + firmwareType + " firmware version " + self.providedFirmwares[self.getNewestFirmwareName(firmwareType)]["Release"] + '?', header = "Firmware Status", response = True)) + else : + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Newer firmware available. Update to " + firmwareType + " firmware version " + self.providedFirmwares[self.getNewestFirmwareName(firmwareType)]["Release"] + '?', header = "Firmware Status", response = True)) - # Wait until response is obtained - while self.messageResponse is None : - time.sleep(0.01) + # Wait until response is obtained + while self.messageResponse is None : + time.sleep(0.01) - # Check if response was no - if not self.messageResponse : + # Check if response was no + if not self.messageResponse : - # Set error if incompatible - if incompatible : - error = True + # Set error if incompatible + if incompatible : + error = True - # Otherwise - else : + # Otherwise + else : - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware", header = "Firmware Status")) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware", header = "Firmware Status")) - # Check if updating firmware failed - if not self.updateToProvidedFirmware(connection, self.getNewestFirmwareName(firmwareType)) : + # Check if updating firmware failed + if not self.updateToProvidedFirmware(connection, self.getNewestFirmwareName(firmwareType)) : - # Set error - error = True + # Set error + error = True - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware failed", header = "Firmware Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Updating firmware failed", header = "Firmware Status", confirm = True)) - # Otherwise - else : + # Otherwise + else : - # Send message - self.messageResponse = None - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Updating firmware was successful", header = "Firmware Status", confirm = True)) + # Send message + self.messageResponse = None + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Question", message = "Updating firmware was successful", header = "Firmware Status", confirm = True)) - # Wait until response is obtained - while self.messageResponse is None : - time.sleep(0.01) + # Wait until response is obtained + while self.messageResponse is None : + time.sleep(0.01) - # Check if no errors occured and getting EEPROM failed - if not error and not self.getEeprom(connection, True) : + # Check if no errors occured and getting EEPROM failed + if not error and not self.getEeprom(connection, True) : - # Set error - error = True + # Set error + error = True - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) - # Otherwise - else : + # Otherwise + else : - # Set error - error = True + # Set error + error = True - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) - # Close connection - connection.close() + # Check if connected to the printer + if connection is not None : + + # Close connection + connection.close() # Check if an error has occured if error : @@ -5615,7 +5900,7 @@ def on_printer_add_log(self, data) : try : self._printer._comm.close(False, False) - except TypeError : + except : pass self._printer.disconnect() @@ -5623,117 +5908,197 @@ def on_printer_add_log(self, data) : # Otherwise else : - # Connect to the printer - connection = serial.Serial(currentPort, currentBaudrate) - - # Save ports - self.savePorts(currentPort) + # Attempt to connect to the printer + try : + connection = serial.Serial(currentPort, currentBaudrate) + + # Otherwise + except : + + # Set error + error = True + + # Clear EEPROM + self.eeprom = None + + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + + # Check if an error hasn't occured + if not error : + + # Check if using OS X or Linux and the user lacks read/write access to the printer + if (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Set error + error = True + + # Clear EEPROM + self.eeprom = None + + # Close connection + connection.close() + + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "You don't have read/write access to " + str(port), header = "Connection Status", confirm = True)) + + # Check if an error hasn't occured + if not error : + + # Save ports + self.savePorts(currentPort) - # Attempt to put printer into G-code processing mode - connection.write("Q") - time.sleep(1) + # Attempt to put printer into G-code processing mode + connection.write("Q") + time.sleep(1) - # Close connection - connection.close() + # Close connection + connection.close() - # Set updated port - currentPort = self.getPort() + # Set updated port + currentPort = self.getPort() - # Check if printer wasn't found - if currentPort is None : + # Check if printer wasn't found + if currentPort is None : - # Clear EEPROM - self.eeprom = None + # Clear EEPROM + self.eeprom = None - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "No Micro 3D printer detected. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) - # Otherwise - else : + # Otherwise + else : - # Re-connect to printer - self._printer.connect(currentPort, currentBaudrate, currentProfile) + # Re-connect to printer + self._printer.connect(currentPort, currentBaudrate, currentProfile) - # Wait until connection is established - while not isinstance(self._printer.get_transport(), serial.Serial) : - time.sleep(0.01) + # Wait until connection is established + while not isinstance(self._printer.get_transport(), serial.Serial) : + if self._printer.is_closed_or_error() : + break + time.sleep(0.01) + + # Check if failed to connect to the printer + if self._printer.is_closed_or_error() : + + # Clear EEPROM + self.eeprom = None - # Remove serial timeout - self._printer.get_transport().timeout = None - if float(serial.VERSION) < 3 : - self._printer.get_transport().writeTimeout = None - else : - self._printer.get_transport().write_timeout = None + # Close connection + if self._printer._comm is not None : + + try : + self._printer._comm.close(False, False) + except : + pass + + self._printer.disconnect() + + # Otherwise + else : + + # Check if using OS X or Linux and the user lacks read/write access to the printer + if (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(currentPort, os.R_OK | os.W_OK) : + + # Clear EEPROM + self.eeprom = None + + # Close connection + if self._printer._comm is not None : + + try : + self._printer._comm.close(False, False) + except : + pass + + self._printer.disconnect() + + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "You don't have read/write access to " + str(port), header = "Connection Status", confirm = True)) + + # Otherwise + else : + + # Remove serial timeout + self._printer.get_transport().timeout = None + if float(serial.VERSION) < 3 : + self._printer.get_transport().writeTimeout = None + else : + self._printer.get_transport().write_timeout = None - # Check if communication layer has been established - if self._printer._comm is not None : + # Check if communication layer has been established + if self._printer._comm is not None : - # Set current firmware type - self.currentFirmwareType = self.getFirmwareDetails()[0] + # Set current firmware type + self.currentFirmwareType = self.getFirmwareDetails()[0] - # Save original write and read functions - self.originalWrite = self._printer.get_transport().write - self.originalRead = self._printer.get_transport().readline + # Save original write and read functions + self.originalWrite = self._printer.get_transport().write + self.originalRead = self._printer.get_transport().readline - # Overwrite write functions to process write function - self._printer.get_transport().write = self.processWrite + # Overwrite write functions to process write function + self._printer.get_transport().write = self.processWrite - # Delay - time.sleep(1) + # Delay + time.sleep(1) - # Clear invalid printer - self.invalidPrinter = False + # Clear invalid printer + self.invalidPrinter = False - try : + try : - # Request printer information - self._printer.get_transport().write("M115") + # Request printer information + self._printer.get_transport().write("M115") - # Overwrite read functions to process read function - self._printer.get_transport().readline = self.processRead + # Overwrite read functions to process read function + self._printer.get_transport().readline = self.processRead - # Send printer details - self.sendPrinterDetails() + # Send printer details + self.sendPrinterDetails() - # Set printer state to operational - self._printer._comm._changeState(self._printer._comm.STATE_OPERATIONAL) + # Set printer state to operational + self._printer._comm._changeState(self._printer._comm.STATE_OPERATIONAL) - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Connected To Printer")) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Connected To Printer")) - except Exception : + except : + + # Clear EEPROM + self.eeprom = None - # Close connection - if self._printer._comm is not None : + # Close connection + if self._printer._comm is not None : - try : - self._printer._comm.close(False, False) - except TypeError : - pass + try : + self._printer._comm.close(False, False) + except : + pass - self._printer.disconnect() + self._printer.disconnect() - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) - # Otherwise - else : + # Otherwise + else : - # Clear EEPROM - self.eeprom = None + # Clear EEPROM + self.eeprom = None - # Close connection - if self._printer._comm is not None : + # Close connection + if self._printer._comm is not None : - try : - self._printer._comm.close(False, False) - except TypeError : - pass + try : + self._printer._comm.close(False, False) + except : + pass - self._printer.disconnect() + self._printer.disconnect() - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + # Send message + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) # Clear reconnecting to printer self.reconnectingToPrinter = False @@ -7352,7 +7717,7 @@ def isSharpCornerForThermalBonding(self, point, refrence, angle) : value = math.acos((currentX * previousX + currentY * previousY) / denominator) # Check if value is not a number - except ValueError : + except : # Return false return False @@ -7400,7 +7765,7 @@ def isSharpCornerForWaveBonding(self, point, refrence) : value = math.acos((currentX * previousX + currentY + previousY) / denominator) # Check if value is not a number - except ValueError : + except : # Return false return False @@ -7560,7 +7925,7 @@ def preprocess(self, input, output = None, lastCommand = False) : value = [] # Loop forever - while True: + while True : # Check if outputting to a file if output is not None : @@ -8862,7 +9227,7 @@ def upload(self) : if "Slicer Profile Name" in flask.request.values and "Slicer Name" in flask.request.values and "Printer Profile Name" in flask.request.values and "Slicer Profile Content" in flask.request.values and "After Slicing Action" in flask.request.values : # Check if printing after slicing and a printer isn't connected - if flask.request.values["After Slicing Action"] != "none" and self._printer.get_state_string() == "Offline" : + if flask.request.values["After Slicing Action"] != "none" and self._printer.is_closed_or_error() : # Return error return flask.jsonify(dict(value = "Error")) @@ -9070,7 +9435,7 @@ def upload(self) : profile = profileManager.Profile.from_cura_ini(curaProfile) # Set profile to none if conversion failed - except Exception : + except : profile = None # Remove temporary files @@ -9108,7 +9473,7 @@ def upload(self) : profile = profileManager.Profile.from_slic3r_ini(slic3rProfile) # Set profile to none if conversion failed - except Exception : + except : profile = None # Remove temporary files @@ -9189,34 +9554,36 @@ def autoConnect(self, comm_instance, port, baudrate, read_timeout, *args, **kwar comm_instance._log("Connecting to: " + str(port)) # Create a connection - connection = None for i in xrange(5) : try : connection = serial.Serial(str(port), baudrate) break # If printer has just power-cycled it may not yet be ready - except Exception : + except : connection = None time.sleep(1) - # Check if using OS X or Linux and the user lacks read/write access to the printer - if (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(str(port), os.R_OK | os.W_OK) : + # Check if connecting to printer failed + if connection is None : # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "You don't have read/write access to " + str(port), header = "Connection Status", confirm = True)) + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) # Enable printer connect button self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Allow Connecting")) + + # Otherwise check if using OS X or Linux and the user lacks read/write access to the printer + elif (platform.uname()[0].startswith("Darwin") or platform.uname()[0].startswith("Linux")) and not os.access(str(port), os.R_OK | os.W_OK) : + + # Close connection + connection.close() # Clear connection connection = None - # Otherwise check if connecting to printer failed - elif connection is None : - # Send message - self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "Unable to connect to the printer. Try cycling the printer's power and try again.", header = "Connection Status", confirm = True)) + self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Show Message", message = "You don't have read/write access to " + str(port), header = "Connection Status", confirm = True)) # Enable printer connect button self._plugin_manager.send_plugin_message(self._identifier, dict(value = "Allow Connecting")) @@ -9267,7 +9634,7 @@ def stringToCFString(string) : # Set encoding try : encoding = CoreFoundation.kCFStringEncodingASCII - except AttributeError : + except : encoding = 0x600 # Convert string @@ -9305,7 +9672,7 @@ def assertionCreateWithName(framework, assertionType, assertionLevel, assertionR try : bus = dbus.SessionBus() - except dbus.DBusException : + except : self.linuxSleepService = None @@ -9317,25 +9684,25 @@ def assertionCreateWithName(framework, assertionType, assertionLevel, assertionR self.linuxSleepService = dbus.Interface(bus.get_object("org.gnome.ScreenSaver", "/org/gnome/ScreenSaver"), "org.gnome.ScreenSaver") self.linuxSleepPrevention = self.linuxSleepService.Inhibit("M33 Fio", "Disabled by M33 Fio") - except dbus.DBusException : + except : try : self.linuxSleepService = dbus.Interface(bus.get_object("org.gnome.ScreenSaver", "/ScreenSaver"), "org.gnome.ScreenSaver") self.linuxSleepPrevention = self.linuxSleepService.Inhibit("M33 Fio", "Disabled by M33 Fio") - except dbus.DBusException : + except : try: self.linuxSleepService = dbus.Interface(bus.get_object("org.freedesktop.ScreenSaver", "/org/freedesktop/ScreenSaver"), "org.freedesktop.ScreenSaver") self.linuxSleepPrevention = self.linuxSleepService.Inhibit("M33 Fio", "Disabled by M33 Fio") - except dbus.DBusException : + except : try : self.linuxSleepService = dbus.Interface(bus.get_object("org.freedesktop.ScreenSaver", "/ScreenSaver"), "org.freedesktop.ScreenSaver") self.linuxSleepPrevention = self.linuxSleepService.Inhibit("M33 Fio", "Disabled by M33 Fio") - except dbus.DBusException : + except : self.linuxSleepService = None @@ -9348,7 +9715,7 @@ def assertionCreateWithName(framework, assertionType, assertionLevel, assertionR try : self.linuxSleepPrevention = self.linuxSleepService.Inhibit("M33 Fio", "Disabled by M33 Fio") - except dbus.DBusException : + except : self.linuxSleepService = None diff --git a/octoprint_m33fio/static/css/m33fio.css b/octoprint_m33fio/static/css/m33fio.css index bce8a9b..8702a50 100644 --- a/octoprint_m33fio/static/css/m33fio.css +++ b/octoprint_m33fio/static/css/m33fio.css @@ -78,6 +78,10 @@ top: 9px; } +#settings_plugin_m33fio label.checkbox > span.windows { + top: 10px; +} + #settings_plugin_m33fio label.checkbox > span.osx { top: 0; } diff --git a/octoprint_m33fio/static/js/m33fio.js b/octoprint_m33fio/static/js/m33fio.js index 0892da1..b681b78 100755 --- a/octoprint_m33fio/static/js/m33fio.js +++ b/octoprint_m33fio/static/js/m33fio.js @@ -7522,10 +7522,10 @@ $(function() { }); }, 600); } - + // Check if printing after slicing, a printer is connected, and using a Micro 3D printer - if(afterSlicingAction == "print" && self.printerState.stateString() !== "Offline" && !self.settings.settings.plugins.m33fio.NotUsingAMicro3DPrinter()) { - + if(afterSlicingAction == "print" && self.printerState.isErrorOrClosed() !== true && !self.settings.settings.plugins.m33fio.NotUsingAMicro3DPrinter()) { + // Check if using on the fly pre-processing and changing settings before print if(self.settings.settings.plugins.m33fio.PreprocessOnTheFly() && self.settings.settings.plugins.m33fio.ChangeSettingsBeforePrint()) { @@ -7593,8 +7593,8 @@ $(function() { // Hide message hideMessage(); - // Don't slice file - button.prev('a').click(); + // Enable button + button.removeClass("disabled"); }); } @@ -13151,7 +13151,7 @@ $(function() { if(navigator.platform.indexOf("Win") != -1) // Fix Windows specific CSS issues - $("#control div.jog-panel.eeprom input[type=\"radio\"]").addClass("windows"); + $("#settings_plugin_m33fio label.checkbox > span, #control div.jog-panel.eeprom input[type=\"radio\"]").addClass("windows"); // Otherwise check if using OS X else if(navigator.platform.indexOf("Mac") != -1) diff --git a/octoprint_m33fio/webcam_server.py b/octoprint_m33fio/webcam_server.py index bc42734..2e018d5 100644 --- a/octoprint_m33fio/webcam_server.py +++ b/octoprint_m33fio/webcam_server.py @@ -150,7 +150,7 @@ def do_GET(self) : # Delay time.sleep(cameraFrameDelay) - except Exception: + except : break # Otherwise @@ -173,7 +173,7 @@ class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer) # Get IP address try : ipAddress = [l for l in ([ip for ip in socket.gethostbyname_ex(socket.gethostname())[2] if not ip.startswith("127.")][:1], [[(s.connect(("8.8.8.8", 53)), s.getsockname()[0], s.close()) for s in [socket.socket(socket.AF_INET, socket.SOCK_DGRAM)]][0][1]]) if l][0][0] - except Exception : + except : ipAddress = socket.gethostbyname(socket.gethostname()) # Display hosting information @@ -225,7 +225,7 @@ class ThreadedHTTPServer(SocketServer.ThreadingMixIn, BaseHTTPServer.HTTPServer) # Delay time.sleep(cameraFrameDelay) - except Exception : + except : break # Otherwise check if QTKit is usable diff --git a/setup.py b/setup.py index fd3a533..494ed40 100644 --- a/setup.py +++ b/setup.py @@ -6,7 +6,7 @@ plugin_identifier = "m33fio" plugin_package = "octoprint_%s" % plugin_identifier plugin_name = "OctoPrint-M33Fio" -plugin_version = "1.4" +plugin_version = "1.5" plugin_description = "Makes OctoPrint fully compatible with the Micro 3D printer" plugin_author = "donovan6000" plugin_author_email = "donovan6000@exploitkings.com"