public void Enqueue(String cmd, bool highPriority = false) { if (AssertConnected()) { Services.DispatcherServices.Invoke(() => { lock (_queueAccessLocker) { if (highPriority) { _toSendPriority.Enqueue(cmd); } else { _toSend.Enqueue(cmd); if (Settings.MachineType == FirmwareTypes.LagoVista_PnP || Settings.MachineType == FirmwareTypes.SimulatedMachine || Settings.MachineType == FirmwareTypes.Repeteir_PnP) { PendingQueue.Add(cmd); } } } }); } }
/// <summary> /// Send CTRL-X to the machine /// </summary> public void SoftReset() { if (AssertConnected()) { Mode = OperatingMode.Manual; lock (_queueAccessLocker) { _toSend.Clear(); _toSendPriority.Clear(); _sentQueue.Clear(); PendingQueue.Clear(); if (Settings.MachineType == FirmwareTypes.GRBL1_1) { _toSendPriority.Enqueue(((char)0x18).ToString()); } else if (Settings.MachineType == FirmwareTypes.Repeteir_PnP) { _toSendPriority.Enqueue("M112"); } Vacuum1On = false; Vacuum2On = false; SolendoidOn = false; } UnacknowledgedBytesSent = 0; } }
/// <summary> /// Returns all messages sent given a matching Message ID. /// </summary> /// <param name="MsgID"></param> private RequestState[] GetStatesByID(long MsgID) { // In case the id referenced the message id if (PendingQueue.TryRemove(MsgID, out var state)) { return new RequestState[] { state } } ; // In case the id is a container id var FromContainer = PendingQueue.Values .Where(x => x.ContainerID == MsgID) .Select(x => GetStatesByID(x.MessageID)) .Join(); if (FromContainer.Count() > 0) { return(FromContainer); } // In case the id refers to an ack var AlreadySend = SentAcks.Read() .Where(x => x.MessageID == MsgID) .ToArray(); if (AlreadySend.Count() > 0) { return(AlreadySend); } // When all else fails return(null); }
/// <summary> /// Cleanly disconnects the server. Pending requests are placed back in a sending queue to be resent upon reconnection /// </summary> public void Disconnect() { // Close the connection superficially CommunicationEstablished = false; try { // Stop the ack processing loop. Logger.Log <MTProtoSender>(Logger.Level.Debug, $"Trying to stop Ack Handler"); if (AckCancellation != null) { AckCancellation.Cancel(); } if (AckHandler != null) { AckHandler.Wait(); } // Close the connection to the server // ToDo: Should we also dispose? Connection.Disconnect(); // Remove any event handlers Logger.Log <MTProtoSender>(Logger.Level.Debug, $"Removing event handlers"); Connection.DataReceivedEvent -= Connection_DataReceivedEvent; // Place all the pending messages back in the queue to resend // Note: Leave pending acks alone. We will pick up where we left off later PendingQueue.Values.ToList().ForEach(x => SendQueue.Add(x)); PendingQueue.Clear(); } catch (Exception ex) { Logger.Log(Logger.Level.Error, $"An error occurred while disconnecting.\n\n{ex.Message}"); } }
public void Add(BeatmapsetPackage beatmapsetPackage) { PendingQueue.Enqueue(beatmapsetPackage); CheckDownloadersState(); }
private void ParseMessage(string fullMessageLine) { fullMessageLine = fullMessageLine.ToLower(); Debug.WriteLine(fullMessageLine); if (fullMessageLine.StartsWith("ok") || fullMessageLine.StartsWith("<ok:")) { if (GCodeFileManager.HasValidFile && Mode == OperatingMode.SendingGCodeFile) { lock (this) { GCodeFileManager.CommandAcknowledged(); lock (_queueAccessLocker) { if (_sentQueue.Any()) { var sentLine = _sentQueue.Dequeue(); UnacknowledgedBytesSent -= (sentLine.Length + 1); } } if (GCodeFileManager.IsCompleted) { Mode = OperatingMode.Manual; } } } else { lock (_queueAccessLocker) { if (PendingQueue.Count > 0) { if (Settings.MachineType == FirmwareTypes.Repeteir_PnP) { Services.DispatcherServices.Invoke(() => { PendingQueue.RemoveAt(0); }); } else { var responseRegEx = new Regex("<ok:(?'CODE'[A-Za-z0-9]+).*>"); var responseGCode = responseRegEx.Match(fullMessageLine); if (responseGCode.Success) { var code = responseGCode.Groups["CODE"].Value; if (PendingQueue[0].StartsWith(code.ToUpper())) { Debug.WriteLine($"MATCH =D -> TOP ITEM {PendingQueue[0]} - {code} "); Services.DispatcherServices.Invoke(() => { PendingQueue.RemoveAt(0); }); } else { Debug.WriteLine($"MISMATCH :( -> TOP ITEM {PendingQueue[0]} - {code} "); } } } } if (_sentQueue.Any()) { var sentLine = _sentQueue.Dequeue(); UnacknowledgedBytesSent -= (sentLine.Length + 1); return; } } LagoVista.Core.PlatformSupport.Services.Logger.Log(LagoVista.Core.PlatformSupport.LogLevel.Warning, "Machine_Work", "Received OK without anything in the Sent Buffer"); UnacknowledgedBytesSent = 0; } } else if (fullMessageLine != null) { if (fullMessageLine == "wait") { if (_isOnHold) { Debug.WriteLine("RECOVERREDDD!"); } _isOnHold = false; } else if (fullMessageLine.StartsWith("error:")) { var errorline = _sentQueue.Any() ? _sentQueue.Dequeue() : "?????"; var errNumbRegEx = new Regex("error:(?'ErrorCode'-?[0-9\\.]*)?"); var errMatch = errNumbRegEx.Match(fullMessageLine); if (errMatch.Success) { var strErrorCode = errMatch.Groups["ErrorCode"].Value; var err = GrblErrorProvider.Instance.GetErrorMessage(Convert.ToInt32(strErrorCode)); AddStatusMessage(StatusMessageTypes.Warning, err, MessageVerbosityLevels.Normal); } else { AddStatusMessage(StatusMessageTypes.Warning, $"{fullMessageLine}: {errorline}", MessageVerbosityLevels.Normal); } if (_sentQueue.Count != 0) { var sentLine = _sentQueue.Dequeue(); UnacknowledgedBytesSent -= sentLine.Length + 1; } else { if ((DateTime.Now - _connectTime).TotalMilliseconds > 200) { AddStatusMessage(StatusMessageTypes.Warning, $"Received <{fullMessageLine}> without anything in the Sent Buffer", MessageVerbosityLevels.Normal); } UnacknowledgedBytesSent = 0; } Mode = OperatingMode.Manual; } else if (fullMessageLine.StartsWith("<")) { if (Settings.MachineType == FirmwareTypes.LagoVista || Settings.MachineType == FirmwareTypes.LagoVista_PnP) { if (ParseLagoVistaLine(fullMessageLine)) { AddStatusMessage(StatusMessageTypes.ReceivedLine, fullMessageLine, MessageVerbosityLevels.Diagnostics); } } else if (ParseStatus(fullMessageLine)) { AddStatusMessage(StatusMessageTypes.ReceivedLine, fullMessageLine, MessageVerbosityLevels.Diagnostics); } else if (ParseLine(fullMessageLine)) { AddStatusMessage(StatusMessageTypes.ReceivedLine, fullMessageLine, MessageVerbosityLevels.Diagnostics); } else { AddStatusMessage(StatusMessageTypes.ReceivedLine, fullMessageLine); } } else if (fullMessageLine.StartsWith("[prb:")) { var probeResult = ProbingManager.ParseProbeLine(fullMessageLine); if (probeResult != null) { switch (Mode) { case OperatingMode.ProbingHeight: ProbingManager.ProbeCompleted(probeResult.Value); break; case OperatingMode.ProbingHeightMap: HeightMapManager.ProbeCompleted(probeResult.Value); break; default: AddStatusMessage(StatusMessageTypes.Warning, "Unexpected PRB return message."); break; } } } else if (fullMessageLine.StartsWith("[")) { UpdateStatus(fullMessageLine); AddStatusMessage(StatusMessageTypes.ReceivedLine, fullMessageLine); } else if (fullMessageLine.StartsWith("ALARM")) { AddStatusMessage(StatusMessageTypes.FatalError, fullMessageLine); Mode = OperatingMode.Manual; } else if (fullMessageLine.Length > 0) { if (!ParseLine(fullMessageLine)) { AddStatusMessage(StatusMessageTypes.ReceivedLine, fullMessageLine); } /* * Not sure why we would dequeue if we couldn't parse the line...may need to revisit * * lock (_queueAccessLocker) * { * if (_sentQueue.Any()) * { * var sentLine = _sentQueue.Dequeue(); * UnacknowledgedBytesSent -= (sentLine.Length + 1); * } * }*/ } } else { AddStatusMessage(StatusMessageTypes.Warning, $"Empty Response From Machine.", MessageVerbosityLevels.Normal); } }