public void CheckForKeys(FoundStringEventArgs e)
 {
     foreach (var pair in this.dictionaryOfCallbacks)
     {
         if (e.LineToCheck.StartsWith(pair.Key))
         {
             e.CallbackWasCalled = true;
             pair.Value(this, e);
         }
     }
 }
Example #2
0
 public void CheckForKeys(EventArgs e)
 {
     foreach (KeyValuePair <string, FoundStringEventHandler> pair in this.dictionaryOfCallBacks)
     {
         FoundStringEventArgs foundString = e as FoundStringEventArgs;
         if (foundString != null && foundString.LineToCheck.Contains(pair.Key))
         {
             foundString.CallbackWasCalled = true;
             pair.Value(this, e);
         }
     }
 }
        public void CheckForKeys(EventArgs e)
        {
            FoundStringEventArgs foundString = e as FoundStringEventArgs;

            if (foundString == null)
            {
                return;
            }

            foreach (var pair in this.dictionaryOfCallbacks)
            {
                if (foundString.LineToCheck.Contains(pair.Key))
                {
                    foundString.CallbackWasCalled = true;
                    pair.Value(this, e);
                }
            }
        }
		private void WriteToPrinter(string lineToWrite, string lineWithoutChecksum)
		{
			if (PrinterIsConnected || CommunicationState == CommunicationStates.AttemptingToConnect)
			{
				if (serialPort != null && serialPort.IsOpen)
				{
					FoundStringEventArgs foundStringEvent = new FoundStringEventArgs(lineWithoutChecksum);

					// If we get a home command, ask the printer where it is after sending it.
					if (lineWithoutChecksum.StartsWith("G28")
						|| lineWithoutChecksum.StartsWith("G29")
						|| lineWithoutChecksum.StartsWith("G92"))
					{
						SendLineToPrinterNow("M114");
					}


					// write data to communication
					{
						StringEventArgs currentEvent = new StringEventArgs(lineToWrite);
						if (PrinterIsPrinting)
						{
							string lineWidthoutCR = lineToWrite.Substring(0, lineToWrite.Length - 2);
							CommunicationUnconditionalToPrinter.CallEvents(this, new StringEventArgs("{0} [{1:0.000}]\n".FormatWith(lineWidthoutCR, timeSinceStartedPrint.Elapsed.TotalSeconds)));
						}
						else
						{
							CommunicationUnconditionalToPrinter.CallEvents(this, currentEvent);
						}

						if (lineWithoutChecksum != null)
						{
							WriteLineStartCallBacks.CheckForKeys(foundStringEvent);
							WriteLineContainsCallBacks.CheckForKeys(foundStringEvent);

							if (foundStringEvent.SendToDelegateFunctions)
							{
								WroteLine.CallEvents(this, currentEvent);
							}
						}
					}

					try
					{
						lock (locker)
						{
							serialPort.Write(lineToWrite);
							timeSinceLastWrite.Restart();
							timeHaveBeenWaitingForOK.Restart();
						}
						//Debug.Write("w: " + lineToWrite);
					}
					catch (IOException ex)
					{
						GuiWidget.BreakInDebugger(ex.Message);
						Trace.WriteLine("Error writing to printer: " + ex.Message);

						// Handle hardware disconnects by relaying the failure reason and shutting down open resources
						AbortConnectionAttempt("Connection Lost - " + ex.Message);
					}
					catch (TimeoutException e2)
					{
						GuiWidget.BreakInDebugger(e2.Message);
					}
					catch (UnauthorizedAccessException e3)
					{
						AbortConnectionAttempt(e3.Message);
					}
					catch (Exception e)
					{
						GuiWidget.BreakInDebugger(e.Message);
					}
				}
				else
				{
					OnConnectionFailed(null);
				}
			}
		}
        public void ReadFromPrinter(ReadThread readThreadHolder)
		{
			string dataLastRead = string.Empty;

			Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
			timeSinceLastReadAnything.Restart();
			// we want this while loop to be as fast as possible. Don't allow any significant work to happen in here
			while (CommunicationState == CommunicationStates.AttemptingToConnect
				|| (PrinterIsConnected && serialPort != null && serialPort.IsOpen && !Disconnecting && readThreadHolder.IsCurrentThread()))
			{
				if (PrinterIsPrinting
					&& PrinterIsConnected
					&& CommunicationState != CommunicationStates.PrintingFromSd)
				{
					TryWriteNextLineFromGCodeFile();
				}

				try
				{
					while (serialPort != null
						&& serialPort.BytesToRead > 0
						&& readThreadHolder.IsCurrentThread())
					{
						lock (locker)
						{
							string allDataRead = serialPort.ReadExisting();
							//Debug.Write("r: " + allDataRead);
							dataLastRead += allDataRead.Replace('\r', '\n');
							do
							{
								int returnPosition = dataLastRead.IndexOf('\n');

								// Abort if we're AttemptingToConnect, no newline was found in the accumulator string and there's too many non-ascii chars
								if (this.communicationState == CommunicationStates.AttemptingToConnect && returnPosition < 0)
								{
									int totalInvalid = dataLastRead.Count(c => c == '?');
									if (totalInvalid > MAX_INVALID_CONNECTION_CHARS)
									{
										AbortConnectionAttempt("Invalid printer response".Localize(), false);
									}
								}

								if (returnPosition < 0)
								{
									// there is no return keep getting characters
									break;
								}

								if (dataLastRead.Length > 0)
								{
									lastLineRead = dataLastRead.Substring(0, returnPosition);
									dataLastRead = dataLastRead.Substring(returnPosition + 1);

									// process this command
									{
										StringEventArgs currentEvent = new StringEventArgs(lastLineRead);
										if (PrinterIsPrinting)
										{
											CommunicationUnconditionalFromPrinter.CallEvents(this, new StringEventArgs("{0} [{1:0.000}]\n".FormatWith(lastLineRead, timeSinceStartedPrint.Elapsed.TotalSeconds)));
										}
										else
										{
											CommunicationUnconditionalFromPrinter.CallEvents(this, currentEvent);
										}

										FoundStringEventArgs foundResponse = new FoundStringEventArgs(currentEvent.Data);
										ReadLineStartCallBacks.CheckForKeys(foundResponse);
										ReadLineContainsCallBacks.CheckForKeys(foundResponse);

										if (foundResponse.SendToDelegateFunctions)
										{
											ReadLine.CallEvents(this, currentEvent);
										}
									}

									// If we've encountered a newline character and we're still in .AttemptingToConnect
									if (CommunicationState == CommunicationStates.AttemptingToConnect)
									{
										// TODO: This is an initial proof of concept for validating the printer response after DTR. More work is
										// needed to test this technique across existing hardware and/or edge cases where this simple approach
										// (initial line having more than 3 non-ASCII characters) may not be adequate or appropriate.
										// TODO: Revise the INVALID char count to an agreed upon threshold
										string[] segments = lastLineRead.Split('?');
										if (segments.Length <= MAX_INVALID_CONNECTION_CHARS)
										{
											CommunicationState = CommunicationStates.Connected;
											// new send any command that initialize this printer
											string connectGCode = ActiveSliceSettings.Instance.GetActiveValue("connect_gcode");
											SendLineToPrinterNow(connectGCode);
										}
										else
										{
											// Force port shutdown and cleanup
											AbortConnectionAttempt("Invalid printer response".Localize(), false);
										}
									}
								}
							} while (true);
						}
						timeSinceLastReadAnything.Restart();
					}

					Thread.Sleep(1);
				}
				catch (TimeoutException e)
				{
					Debug.Print(e.Message);
					GuiWidget.BreakInDebugger();
				}
				catch (IOException e2)
				{
					Debug.Print(e2.Message);
					GuiWidget.BreakInDebugger();
					OnConnectionFailed(null);
				}
				catch (InvalidOperationException ex)
				{
					Debug.Print(ex.Message);
					GuiWidget.BreakInDebugger();
					Debug.WriteLine(ex.Message);
					// this happens when the serial port closes after we check and before we read it.
				}
				catch (UnauthorizedAccessException e3)
				{
					Debug.Print(e3.Message);
					GuiWidget.BreakInDebugger();
					OnConnectionFailed(null);
				}
				catch (Exception e4)
				{
					Debug.Print(e4.Message);
					GuiWidget.BreakInDebugger();
					// Let's track this issue if possible.
					MatterControlApplication.Instance.ReportException(e4, this.GetType().Name, MethodBase.GetCurrentMethod().Name);
				}
			}
		}
		private void WriteRawToPrinter(string lineToWrite, string lineWithoutChecksum)
		{
			if (PrinterIsConnected || CommunicationState == CommunicationStates.AttemptingToConnect)
			{
				if (serialPort != null && serialPort.IsOpen)
				{
					FoundStringEventArgs foundStringEvent = new FoundStringEventArgs(lineWithoutChecksum);

					// If we get a home command, ask the printer where it is after sending it.
					if (lineWithoutChecksum.StartsWith("G28") // is a home
						|| lineWithoutChecksum.StartsWith("G29") // is a bed level
						|| lineWithoutChecksum.StartsWith("G92") // is a reset of printer position
						|| (lineWithoutChecksum.StartsWith("T") && !lineWithoutChecksum.StartsWith("T:"))) // is a switch extruder (verify this is the right time to ask this)
					{
						SendLineToPrinterNow("M114");
					}

					// write data to communication
					{
						StringEventArgs currentEvent = new StringEventArgs(lineToWrite);
						if (PrinterIsPrinting)
						{
							string lineWidthoutCR = lineToWrite.TrimEnd();
							CommunicationUnconditionalToPrinter.CallEvents(this, new StringEventArgs("{0} [{1:0.000}]\n".FormatWith(lineWidthoutCR, timeSinceStartedPrint.Elapsed.TotalSeconds)));
						}
						else
						{
							CommunicationUnconditionalToPrinter.CallEvents(this, currentEvent);
						}

						if (lineWithoutChecksum != null)
						{
							WriteLineStartCallBacks.CheckForKeys(foundStringEvent);
							WriteLineContainsCallBacks.CheckForKeys(foundStringEvent);

							if (foundStringEvent.SendToDelegateFunctions)
							{
								WroteLine.CallEvents(this, currentEvent);
							}
						}
					}

					try
					{
						lock (locker)
						{
							serialPort.Write(lineToWrite);
							if (false) // this is for debugging. Eventually it could be hooked up to a user config option so it can be turned on in the field.
							{
								timeSinceRecievedOk.Stop();
								if (!haveHookedDrawing)
								{
									sendTimeAfterOkGraph = new DataViewGraph(150, 150, 0, 30);
									MatterControlApplication.Instance.AddChild(sendTimeAfterOkGraph);
									haveHookedDrawing = true;
								}
								sendTimeAfterOkGraph.AddData("ok->send", timeSinceRecievedOk.ElapsedMilliseconds);
							}
							timeSinceLastWrite.Restart();
							timeHaveBeenWaitingForOK.Restart();
						}
						//Debug.Write("w: " + lineToWrite);
					}
					catch (IOException ex)
					{
						GuiWidget.BreakInDebugger(ex.Message);
						Trace.WriteLine("Error writing to printer: " + ex.Message);

						// Handle hardware disconnects by relaying the failure reason and shutting down open resources
						AbortConnectionAttempt("Connection Lost - " + ex.Message);
					}
					catch (TimeoutException e2)
					{
						GuiWidget.BreakInDebugger(e2.Message);
					}
					catch (UnauthorizedAccessException e3)
					{
						AbortConnectionAttempt(e3.Message);
					}
					catch (Exception e)
					{
						GuiWidget.BreakInDebugger(e.Message);
					}
				}
				else
				{
					OnConnectionFailed(null);
				}
			}
		}
		private void WriteToPrinter(string lineToWrite, string lineWithoutChecksum)
		{
			if (PrinterIsConnected || CommunicationState == CommunicationStates.AttemptingToConnect)
			{
				if (serialPort != null && serialPort.IsOpen)
				{
					FoundStringEventArgs foundStringEvent = new FoundStringEventArgs(lineWithoutChecksum);

					// write data to communication
					{
						StringEventArgs currentEvent = new StringEventArgs(lineToWrite);
						if (PrinterIsPrinting)
						{
							string lineWidthoutCR = lineToWrite.Substring(0, lineToWrite.Length - 2);
							CommunicationUnconditionalToPrinter.CallEvents(this, new StringEventArgs("{0} [{1:0.000}]\n".FormatWith(lineWidthoutCR, timeSinceStartedPrint.Elapsed.TotalSeconds)));
						}
						else
						{
							CommunicationUnconditionalToPrinter.CallEvents(this, currentEvent);
						}

						if (lineWithoutChecksum != null)
						{
							WriteLineStartCallBacks.CheckForKeys(foundStringEvent);
							WriteLineContainsCallBacks.CheckForKeys(foundStringEvent);

							if (foundStringEvent.SendToDelegateFunctions)
							{
								WroteLine.CallEvents(this, currentEvent);
							}
						}
					}

					try
					{
						using (TimedLock.Lock(this, "serialPort.Write"))
						{
                            serialPort.Write(lineToWrite);
                            timeSinceLastWrite.Restart();
                            timeHaveBeenWaitingForOK.Restart();

						}
						//Debug.Write("w: " + lineToWrite);
					}
					catch (IOException ex)
					{
						Debug.Print(ex.Message);
						GuiWidget.BreakInDebugger();
						Trace.WriteLine("Error writing to printer: " + ex.Message);

						// Handle hardware disconnects by relaying the failure reason and shutting down open resources
						AbortConnectionAttempt("Connection Lost - " + ex.Message);
					}
					catch (TimeoutException e2)
					{
						Debug.Print(e2.Message);
						GuiWidget.BreakInDebugger();
					}
					catch (Exception e)
					{
						Debug.Print(e.Message);
						GuiWidget.BreakInDebugger();
						// Let's track this issue if possible.
						MatterControlApplication.Instance.ReportException(e, this.GetType().Name, MethodBase.GetCurrentMethod().Name);
					}
				}
				else
				{
					OnConnectionFailed(null);
				}
			}
		}
        public void ReadFromPrinter()
        {
            Thread.CurrentThread.CurrentCulture = CultureInfo.InvariantCulture;
            timeSinceLastReadAnything.Restart();
            // we want this while loop to be as fast as possible. Don't allow any significant work to happen in here
            while (CommunicationState == CommunicationStates.AttemptingToConnect
                || (PrinterIsConnected && serialPort.IsOpen && !Disconnecting))
            {
                try
                {
                    while (serialPort != null 
                        && serialPort.BytesToRead > 0)
                    {
                        char nextChar = (char)serialPort.ReadChar();
                        using (TimedLock.Lock(this, "ReadFromPrinter"))
                        {
                            if (nextChar == '\r' || nextChar == '\n')
                            {
                                lastLineRead = lineBeingRead;
                                lineBeingRead = "";

                                // process this command
                                {
                                    StringEventArgs currentEvent = new StringEventArgs(lastLineRead);
                                    CommunicationUnconditionalFromPrinter.CallEvents(this, currentEvent);

                                    FoundStringEventArgs foundResponse = new FoundStringEventArgs(currentEvent.Data);
                                    ReadLineStartCallBacks.CheckForKeys(foundResponse);
                                    ReadLineContainsCallBacks.CheckForKeys(foundResponse);

                                    if (foundResponse.SendToDelegateFunctions)
                                    {
                                        ReadLine.CallEvents(this, currentEvent);
                                    }
                                }

                                if (CommunicationState == CommunicationStates.AttemptingToConnect)
                                {
                                    CommunicationState = CommunicationStates.Connected;
                                }
                            }
                            else
                            {
                                lineBeingRead += nextChar;
                            }
                            timeSinceLastReadAnything.Restart();
                        }
                    }

                    Thread.Sleep(1);
                }
                catch (TimeoutException)
                {
                }
                catch (IOException)
                {
                    OnConnectionFailed(null);
                }
                catch (InvalidOperationException)
                {
                    // this happens when the serial port closes after we check and before we read it.
                }
                catch (UnauthorizedAccessException)
                {
                    OnConnectionFailed(null);
                }
            }
        }
        void WriteToPrinter(string lineToWrite, string lineWithoutChecksum)
        {
            if (PrinterIsConnected || CommunicationState == CommunicationStates.AttemptingToConnect)
            {
                if (serialPort != null && serialPort.IsOpen)
                {
                    FoundStringEventArgs foundStringEvent = new FoundStringEventArgs(lineWithoutChecksum);

                    // write data to communication
                    {
                        StringEventArgs currentEvent = new StringEventArgs(lineToWrite);
                        CommunicationUnconditionalToPrinter.CallEvents(this, currentEvent);

                        if (lineWithoutChecksum != null)
                        {
                            WriteLineStartCallBacks.CheckForKeys(foundStringEvent);
                            WriteLineContainsCallBacks.CheckForKeys(foundStringEvent);

                            if (foundStringEvent.SendToDelegateFunctions)
                            {
                                WroteLine.CallEvents(this, currentEvent);
                            }
                        }
                    }

                    try
                    {
                        timeSinceLastReadAnything.Restart();
                        timeHaveBeenWaitingForOK.Restart();
                        serialPort.Write(lineToWrite);
                    }
                    catch (IOException)
                    {
                        OnConnectionFailed(null);
                    }
                    catch (TimeoutException)
                    {
                    }
                }
                else
                {
                    OnConnectionFailed(null);
                }
            }
        }