diff --git a/CSharpSerialPortWrapper.cs b/CSharpSerialPortWrapper.cs index ceb044ea9..43bbd1f67 100644 --- a/CSharpSerialPortWrapper.cs +++ b/CSharpSerialPortWrapper.cs @@ -36,7 +36,7 @@ namespace MatterHackers.SerialPortCommunication.FrostedSerial { private SerialPort port; - internal CSharpSerialPortWrapper(string serialPortName) + public CSharpSerialPortWrapper(string serialPortName) { if (FrostedSerialPortFactory.GetAppropriateFactory("RepRap").IsWindows) { diff --git a/MatterControl.Printing/GCode/GCodeFile.cs b/MatterControl.Printing/GCode/GCodeFile.cs index 3dc99a948..ce5d193c5 100644 --- a/MatterControl.Printing/GCode/GCodeFile.cs +++ b/MatterControl.Printing/GCode/GCodeFile.cs @@ -111,14 +111,12 @@ namespace MatterControl.Printing || lineString.StartsWith("; layer "); } - public static bool FileTooBigToLoad(string fileName) + public static bool FileTooBigToLoad(Stream fileStream) { - if (File.Exists(fileName) - && Is32Bit) + if (Is32Bit) { - FileInfo info = new FileInfo(fileName); // Let's make sure we can load a file this big - if (info.Length > Max32BitFileSize) + if (fileStream.Length > Max32BitFileSize) { // It is too big to load return true; @@ -172,20 +170,20 @@ namespace MatterControl.Printing return false; } - public static GCodeFile Load(string fileName, + public static GCodeFile Load(Stream fileStream, Vector4 maxAccelerationMmPerS2, Vector4 maxVelocityMmPerS, Vector4 velocitySameAsStopMmPerS, Vector4 speedMultiplier, CancellationToken cancellationToken) { - if (FileTooBigToLoad(fileName)) + if (FileTooBigToLoad(fileStream)) { - return new GCodeFileStreamed(fileName); + return new GCodeFileStreamed(fileStream); } else { - return GCodeMemoryFile.Load(fileName, + return GCodeMemoryFile.Load(fileStream, maxAccelerationMmPerS2, maxVelocityMmPerS, velocitySameAsStopMmPerS, diff --git a/MatterControlLib/Library/Export/GCodeExport.cs b/MatterControlLib/Library/Export/GCodeExport.cs index 37198073c..748de785a 100644 --- a/MatterControlLib/Library/Export/GCodeExport.cs +++ b/MatterControlLib/Library/Export/GCodeExport.cs @@ -356,7 +356,7 @@ namespace MatterHackers.MatterControl.Library.Export this.ApplyStreamPipelineAndExport( new GCodeFileStream( GCodeFile.Load( - gcodeFilename, + new StreamReader(gcodeFilename).BaseStream, new Vector4(maxAcceleration, maxAcceleration, maxAcceleration, maxAcceleration), new Vector4(maxVelocity, maxVelocity, maxVelocity, maxVelocity), new Vector4(jerkVelocity, jerkVelocity, jerkVelocity, jerkVelocity), diff --git a/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs b/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs index 07a44fb64..0a76b8151 100644 --- a/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs +++ b/MatterControlLib/PrinterCommunication/Io/GCodeSwitcher.cs @@ -28,6 +28,7 @@ either expressed or implied, of the FreeBSD Project. */ using System.Collections.Generic; +using System.IO; using System.Threading; using System.Threading.Tasks; using MatterControl.Printing; @@ -44,7 +45,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io private string lastLine = ""; - public GCodeSwitcher(string gcodeFilename, PrinterConfig printer, int startLine = 0) + public GCodeSwitcher(Stream gcodeStream, PrinterConfig printer, int startLine = 0) : base(printer) { var settings = this.printer.Settings; @@ -53,7 +54,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io var jerkVelocity = settings.GetValue(SettingsKey.jerk_velocity); var multiplier = settings.GetValue(SettingsKey.print_time_estimate_multiplier) / 100.0; - var fileStreaming = GCodeFile.Load(gcodeFilename, + var fileStreaming = GCodeFile.Load(gcodeStream, new Vector4(maxAcceleration, maxAcceleration, maxAcceleration, maxAcceleration), new Vector4(maxVelocity, maxVelocity, maxVelocity, maxVelocity), new Vector4(jerkVelocity, jerkVelocity, jerkVelocity, jerkVelocity), @@ -164,7 +165,7 @@ namespace MatterHackers.MatterControl.PrinterCommunication.Io var jerkVelocity = settings.GetValue(SettingsKey.jerk_velocity); var multiplier = settings.GetValue(SettingsKey.print_time_estimate_multiplier) / 100.0; - var switchToGCode = GCodeFile.Load(gcodeFilename, + var switchToGCode = GCodeFile.Load(new StreamReader(gcodeFilename).BaseStream, new Vector4(maxAcceleration, maxAcceleration, maxAcceleration, maxAcceleration), new Vector4(maxVelocity, maxVelocity, maxVelocity, maxVelocity), new Vector4(jerkVelocity, jerkVelocity, jerkVelocity, jerkVelocity), diff --git a/MatterControlLib/PrinterCommunication/PrinterConnection.cs b/MatterControlLib/PrinterCommunication/PrinterConnection.cs index bc002a088..59d95801a 100644 --- a/MatterControlLib/PrinterCommunication/PrinterConnection.cs +++ b/MatterControlLib/PrinterCommunication/PrinterConnection.cs @@ -1926,6 +1926,12 @@ You will then need to logout and log back in to the computer for the changes to private CancellationTokenSource printingCancellation; public async Task StartPrint(string gcodeFilename, PrintTask printTaskToUse = null, bool allowRecovery = true) + { + var gcodeStream = new StreamReader(gcodeFilename); + await StartPrint(gcodeStream.BaseStream, gcodeFilename, printTaskToUse, allowRecovery); + } + + public async Task StartPrint(Stream gcodeStream, string gcodeFileNameForTask = null, PrintTask printTaskToUse = null, bool allowRecovery = true) { if (!this.IsConnected || Printing) { @@ -1946,7 +1952,7 @@ You will then need to logout and log back in to the computer for the changes to await Task.Run(() => { // LoadGCodeToPrint - CreateStreamProcessors(gcodeFilename, this.RecoveryIsEnabled); + CreateStreamProcessors(gcodeStream, this.RecoveryIsEnabled); }); // DoneLoadingGCodeToPrint @@ -1968,7 +1974,8 @@ You will then need to logout and log back in to the computer for the changes to activePrintItem.PrintItem.Commit(); } - if (activePrintTask == null + if (gcodeFileNameForTask !=null + && activePrintTask == null && allowRecovery) { // TODO: Fix printerItemID int requirement @@ -1978,7 +1985,7 @@ You will then need to logout and log back in to the computer for the changes to PrinterId = this.Printer.Settings.ID.GetHashCode(), PrintName = activePrintItem.PrintItem.Name, PrintItemId = activePrintItem.PrintItem.Id, - PrintingGCodeFileName = gcodeFilename, + PrintingGCodeFileName = gcodeFileNameForTask, PrintComplete = false }; @@ -2171,7 +2178,7 @@ You will then need to logout and log back in to the computer for the changes to } } - private void CreateStreamProcessors(string gcodeFilename, bool recoveryEnabled) + private void CreateStreamProcessors(Stream gcodeStream, bool recoveryEnabled) { secondsSinceUpdateHistory = 0; lineSinceUpdateHistory = 0; @@ -2181,9 +2188,9 @@ You will then need to logout and log back in to the computer for the changes to GCodeStream accumulatedStream = null; - if (gcodeFilename != null) + if (gcodeStream != null) { - gCodeFileSwitcher = new GCodeSwitcher(gcodeFilename, Printer); + gCodeFileSwitcher = new GCodeSwitcher(gcodeStream, Printer); if (this.RecoveryIsEnabled && activePrintTask != null) // We are resuming a failed print (do lots of interesting stuff). @@ -2220,7 +2227,7 @@ You will then need to logout and log back in to the computer for the changes to accumulatedStream = new BabyStepsStream(Printer, accumulatedStream); - bool enableLineSpliting = gcodeFilename != null && Printer.Settings.GetValue(SettingsKey.enable_line_splitting); + bool enableLineSpliting = gcodeStream != null && Printer.Settings.GetValue(SettingsKey.enable_line_splitting); accumulatedStream = maxLengthStream = new MaxLengthStream(Printer, accumulatedStream, enableLineSpliting ? 1 : 2000); accumulatedStream = printLevelingStream = new PrintLevelingStream(Printer, accumulatedStream, true); diff --git a/Tests/MatterControl.Tests/MatterControl.Tests.csproj b/Tests/MatterControl.Tests/MatterControl.Tests.csproj index f3ebd1c36..e48deecca 100644 --- a/Tests/MatterControl.Tests/MatterControl.Tests.csproj +++ b/Tests/MatterControl.Tests/MatterControl.Tests.csproj @@ -84,6 +84,10 @@ {2af30557-fc50-4de3-ad1c-7eb57131a9c5} MatterControl.Common + + {b2b001ee-a142-4e20-acf8-ae4a9cb984f8} + MatterControl + {97d5ade3-c1b4-4b46-8a3e-718a4f7f079f} MatterControl.Printing diff --git a/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs b/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs index acf2a7fb7..0f608f07a 100644 --- a/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs +++ b/Tests/MatterControl.Tests/MatterControl/GCodeStreamTests.cs @@ -27,8 +27,13 @@ of the authors and should not be interpreted as representing official policies, either expressed or implied, of the FreeBSD Project. */ +using System; using System.Collections.Generic; using System.Diagnostics; +using System.IO; +using System.Text; +using System.Threading; +using System.Threading.Tasks; using MatterControl.Printing; using MatterHackers.Agg; using MatterHackers.Agg.Platform; @@ -37,6 +42,8 @@ using MatterHackers.MatterControl.Library.Export; using MatterHackers.MatterControl.PrinterCommunication.Io; using MatterHackers.MatterControl.SlicerConfiguration; using MatterHackers.MatterControl.Tests.Automation; +using MatterHackers.PrinterEmulator; +using MatterHackers.SerialPortCommunication.FrostedSerial; using MatterHackers.VectorMath; using NUnit.Framework; @@ -610,7 +617,7 @@ namespace MatterControl.Tests.MatterControl } [Test, Category("GCodeStream")] - public void ToolChangeHeatNoExtrusion() + public Task ToolChangeHeatNoExtrusion() { string[] inputLines = new string[] { @@ -663,8 +670,9 @@ namespace MatterControl.Tests.MatterControl PrinterConfig printer = SetupToolChangeSettings(); - var testStream = GCodeExport.GetExportStream(printer, new TestGCodeStream(printer, inputLines), true); - ValidateStreamResponse(expected, testStream); + ValidateStreamResponseWhilePrintingAsync(expected, printer, inputLines).GetAwaiter().GetResult(); + + return Task.CompletedTask; } private static PrinterConfig SetupToolChangeSettings() @@ -739,6 +747,62 @@ namespace MatterControl.Tests.MatterControl } } + private static async System.Threading.Tasks.Task ValidateStreamResponseWhilePrintingAsync(string[] expected, PrinterConfig printer, string[] inputGCode) + { + // make sure we are not getting feedback we don't have in the expected results + printer.Connection.MonitorPrinterTemperature = false; + + // set up our serial port finding + FrostedSerialPortFactory.GetPlatformSerialPort = (serialPortName) => + { + return new Emulator(); + }; + + int expectedIndex = 0; + + // register to listen to the printer responses + printer.Connection.LineSent += (s, actualLine) => + { + if (printer.Connection.Printing) + { + string expectedLine = expected[expectedIndex++]; + Assert.AreEqual(expectedLine, actualLine, "Unexpected response from testStream"); + } + }; + + // set up the emulator + printer.Settings.SetValue($"{Environment.MachineName}_com_port", "Emulator"); + // connect to the emulator + printer.Connection.Connect(); + var time = Stopwatch.StartNew(); + while (!printer.Connection.IsConnected + && time.ElapsedMilliseconds < (1000 * 60 * 3)) + { + Thread.Sleep(1000); + } + + // start a print + var inputStream = new MemoryStream(Encoding.ASCII.GetBytes(string.Join("\n", inputGCode))); + await printer.Connection.StartPrint(inputStream); + + // wait for the print to finish (or 3 minutes to pass) + time = Stopwatch.StartNew(); + while(//printer.Connection.Printing + //&& + time.ElapsedMilliseconds < (1000 * 60 * 3)) + { + Thread.Sleep(1000); + //printer.Connection.upda + } + + Assert.AreEqual(expectedIndex, expected.Length, "We should have seen all the expected lines"); + } + + private static void Connection_LineReceived(object sender, string e) + { + throw new System.NotImplementedException(); + } + [Test, Category("GCodeStream")] public void WriteReplaceStreamTests() {