aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/Tango.Integration
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/Tango.Integration')
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs24
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs710
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs37
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs15
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs27
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs171
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs908
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs124
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRConfiguration.cs15
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs207
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeUsbClient.cs6
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs21
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs5
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs48
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/RequestHandlerLoggingMode.cs15
-rw-r--r--Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs22
-rw-r--r--Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs298
-rw-r--r--Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs60
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/CachedJobOperation.cs18
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/DefaultGradientGenerationConfiguration.cs84
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/DefaultMachineEventsStateProvider.cs12
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningEndedEventArgs.cs24
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningHandler.cs80
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningStatusChangedEventArgs.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/IMachineEventsStateProvider.cs2
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs180
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/InkFillingStatusChangedEventArgs.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/InsufficientLiquidQuantityException.cs16
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs496
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/JobLiquidQuantityCalculationMode.cs23
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs2784
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/MachineStatuses.cs20
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/PowerDownHandler.cs77
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/PowerDownStartedEventArgs.cs13
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/PowerDownStatusChangedEventArgs.cs14
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs8
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/RequestFailedEventArgs.cs22
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/ResumingJobEventArgs.cs8
-rw-r--r--Software/Visual_Studio/Tango.Integration/Operation/ThreadLoadingConfirmationRequiredEventArgs.cs27
-rw-r--r--Software/Visual_Studio/Tango.Integration/Storage/StorageDrive.cs2
-rw-r--r--Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs2
-rw-r--r--Software/Visual_Studio/Tango.Integration/Storage/StorageItem.cs3
-rw-r--r--Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs114
-rw-r--r--Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj28
-rw-r--r--Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeHandler.cs31
-rw-r--r--Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeProgressEventArgs.cs5
-rw-r--r--Software/Visual_Studio/Tango.Integration/packages.config1
48 files changed, 1658 insertions, 5191 deletions
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs
index e976898ef..2bfe60477 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeClientConnectedEventArgs.cs
@@ -9,30 +9,10 @@ namespace Tango.Integration.ExternalBridge
{
public class ExternalBridgeClientConnectedEventArgs : EventArgs
{
- private Action _confirmAction;
- private Action<String> _declineAction;
-
public ExternalBridgeLoginRequest Request { get; set; }
- public String Address { get; set; }
-
- public ApplicationInformation ApplicationInformation { get; set; }
-
- public ExternalBridgeClientConnectedEventArgs(Action confirmAction, Action<String> declineAction)
- {
- _confirmAction = confirmAction;
- _declineAction = declineAction;
- ApplicationInformation = new ApplicationInformation();
- }
-
- public void Confirm()
- {
- _confirmAction?.Invoke();
- }
+ public String IpAddress { get; set; }
- public void Decline(String reason)
- {
- _declineAction?.Invoke(reason);
- }
+ public bool Confirmed { get; set; }
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
deleted file mode 100644
index 143f21f42..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiver.cs
+++ /dev/null
@@ -1,710 +0,0 @@
-using Google.Protobuf;
-using System;
-using System.Collections.Generic;
-using System.Diagnostics;
-using System.Linq;
-using System.Net.Sockets;
-using System.Security.Authentication;
-using System.Text;
-using System.Threading;
-using System.Threading.Tasks;
-using Tango.Core;
-using Tango.Core.ExtensionMethods;
-using Tango.Integration.Operation;
-using Tango.PMR;
-using Tango.PMR.Common;
-using Tango.PMR.Debugging;
-using Tango.PMR.Diagnostics;
-using Tango.PMR.IFS;
-using Tango.PMR.Integration;
-using Tango.PMR.MachineStatus;
-using Tango.PMR.Power;
-using Tango.Transport;
-using Tango.Transport.Adapters;
-using Tango.Transport.Transporters;
-
-namespace Tango.Integration.ExternalBridge
-{
- public class ExternalBridgeReceiver : BasicTransporter
- {
- /// <summary>
- /// A dictionary containing the last time a user name has made a request or response.
- /// This is used to bypass the safety operations confirmation.
- /// FullName, Contact Time
- /// </summary>
- public static Dictionary<String, DateTime> LastSafetyLevelContactsTimes { get; private set; }
-
- #region Message Handler
-
- private class MessageHandler
- {
- public Action<MessageContainer> Method { get; set; }
- public bool RequiresLogin { get; set; }
- public ExternalBridgeLoginIntent LoginIntent { get; set; }
-
- public MessageHandler(Action<MessageContainer> method)
- {
- Method = method;
- }
-
- public MessageHandler(Action<MessageContainer> method, ExternalBridgeLoginIntent intent) : this(method)
- {
- RequiresLogin = true;
- LoginIntent = intent;
- }
- }
-
- #endregion
-
- private String _eventsToken;
- private String _machineStatusToken;
- private String _diagnosticsToken;
- private String _debugLogsToken;
- private String _applicationLogsToken;
- private String _inkFillingToken;
-
- private IMachineOperator _machineOperator;
- private Dictionary<MessageType, MessageHandler> _messageHandlers;
-
- #region Events
-
- public event EventHandler<ExternalBridgeReceiverLoginRequestEventArgs> LoginRequest;
- public event EventHandler<ColorProfileRequestEventArgs> ColorProfileRequest;
- public event EventHandler Disconnected;
- public event EventHandler<ExternalBridgeReceiverRequestReceivedEventArgs> ReceiverRequestReceived;
-
- #endregion
-
- #region Properties
-
- public bool AllowSafetyLevelOperations { get; set; }
-
- public bool RequiresDiagnostics { get; private set; }
- public bool RequiresDebugLogs { get; private set; }
- public bool RequiresEventsNotification { get; private set; }
- public bool RequiresMachineStatusUpdate { get; private set; }
- public bool RequiresApplicationLogs { get; private set; }
- public bool RequiresInkFillingStatus { get; private set; }
-
- public bool IsLoggedIn { get; private set; }
- public ExternalBridgeLoginIntent LoginIntent { get; private set; }
- public String UserName { get; private set; }
-
- private ExternalBridgeLoginRequest _loginInfo;
- public ExternalBridgeLoginRequest LoginInfo
- {
- get { return _loginInfo; }
- set { _loginInfo = value; RaisePropertyChangedAuto(); }
- }
-
- public bool IsLoggedInAndRequiresDiagnostics
- {
- get { return IsLoggedIn && (LoginIntent == ExternalBridgeLoginIntent.Diagnostics || LoginIntent == ExternalBridgeLoginIntent.FullControl); }
- }
-
-
- #endregion
-
- #region Constructors
-
- static ExternalBridgeReceiver()
- {
- LastSafetyLevelContactsTimes = new Dictionary<string, DateTime>();
- }
-
- public ExternalBridgeReceiver(IMachineOperator machineOperator)
- {
- ComponentName = $"External Bridge Receiver {_component_counter++}";
-
- FailsWithAdapter = true;
-
- _machineOperator = machineOperator;
-
- _messageHandlers = new Dictionary<MessageType, MessageHandler>();
- UseKeepAlive = false;
- KeepAliveTimeout = TimeSpan.FromSeconds(10);
- KeepAliveRetries = 4;
-
- _messageHandlers.Add(MessageType.ExternalBridgeLoginRequest, new MessageHandler(OnExternalBridgeLoginRequest));
- _messageHandlers.Add(MessageType.ExternalBridgeLogoutRequest, new MessageHandler(OnExternalBridgeLogoutRequest));
-
- _messageHandlers.Add(MessageType.ColorProfileRequest, new MessageHandler(OnColorProfileRequest));
-
- _messageHandlers.Add(MessageType.StartDiagnosticsRequest, new MessageHandler(OnStartDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StopDiagnosticsRequest, new MessageHandler(OnStopDiagnosticsRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartDebugLogRequest, new MessageHandler(OnStartDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StopDebugLogRequest, new MessageHandler(OnStopDebugLogRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartEventsNotificationRequest, new MessageHandler(OnStartEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StopEventsNotificationRequest, new MessageHandler(OnStopEventsNotificationRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, new MessageHandler(OnStartMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, new MessageHandler(OnStopMachineStatusUpdateRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartApplicationLogsRequest, new MessageHandler(OnStartApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics));
- _messageHandlers.Add(MessageType.StopApplicationLogsRequest, new MessageHandler(OnStopApplicationLogsRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.JobRequest, new MessageHandler(OnJobRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartPowerDownRequest, new MessageHandler(OnStartPowerDownRequest, ExternalBridgeLoginIntent.Diagnostics));
-
- _messageHandlers.Add(MessageType.StartInkFillingStatusRequest, new MessageHandler(OnStartInkFillingStatusRequest, ExternalBridgeLoginIntent.Diagnostics));
- }
-
- public ExternalBridgeReceiver(TcpClient tcpClient, IMachineOperator machineOperator) : this(machineOperator)
- {
- Adapter = new TcpTransportAdapter(tcpClient);
- }
-
- public ExternalBridgeReceiver(SignalRTransportAdapter signalRAdapter, IMachineOperator machineOperator) : this(machineOperator)
- {
- Adapter = signalRAdapter;
- }
-
- #endregion
-
- #region Override Methods
-
- protected override void OnRequestReceived(RequestReceivedEventArgs e)
- {
- base.OnRequestReceived(e);
-
- if (e.Handled) return;
-
- var container = e.Container;
-
- try
- {
- if (e.Container.Type == MessageType.ConfigureProtocolRequest)
- {
- var message = MessageFactory.ParseTangoMessageFromContainer<ConfigureProtocolRequest>(container);
- SendResponse(new ConfigureProtocolResponse() { Confirmed = true }, container.Token, new TransportResponseConfig() { Immediate = true, Priority = QueuePriority.High });
-
- Task.Factory.StartNew(() =>
- {
- Thread.Sleep(200);
- Adapter.EnableCompression = message.Message.EnableCompression;
- GenericProtocol = message.Message.GenericProtocol;
- });
- return;
- }
-
- if (!AllowSafetyLevelOperations)
- {
- if (ExternalBridgeService.SafetyLevelOperations.Contains(container.Type))
- {
- SendErrorResponse(new AuthenticationException("The specified action requires safety level permission that is not granted for the current session."), container.Token);
- return;
- }
- }
- else
- {
- if (UserName != null)
- {
- LastSafetyLevelContactsTimes[UserName] = DateTime.Now;
- }
- }
-
- if (_messageHandlers.ContainsKey(container.Type))
- {
- var handler = _messageHandlers[container.Type];
-
- if (handler.RequiresLogin && (!IsLoggedIn || (int)handler.LoginIntent > (int)LoginIntent))
- {
- SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token);
- return;
- }
-
- try
- {
- try
- {
- handler.Method.Invoke(container);
- }
- catch (Exception ex)
- {
- SendErrorResponse(ex, container.Token);
- }
- }
- catch (Exception ex)
- {
- if (ex is ResponseErrorException)
- {
- SendResponse((ex as ResponseErrorException).Container);
- }
- else
- {
- SendErrorResponse(ex, container.Token);
- }
- }
- }
- else
- {
- if (IsLoggedIn)
- {
- ExternalBridgeReceiverRequestReceivedEventArgs args = new ExternalBridgeReceiverRequestReceivedEventArgs();
- args.Container = container;
- ReceiverRequestReceived?.Invoke(this, args);
-
- if (!args.Handled)
- {
- OnAnyRequest(container);
- }
- }
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error occurred in processing request message on external bridge receiver.");
- }
- }
-
- protected override void OnFailed(Exception ex)
- {
- if (ex is KeepAliveException)
- {
- LogManager.Log("External bridge client has failed to provide a keep alive response. Disconnecting session...");
- }
-
- base.OnFailed(ex);
- OnDisconnected();
- }
-
- public async override Task Disconnect()
- {
- try
- {
- if (IsLoggedIn)
- {
- await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(3), ShouldLog = true });
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error sending an external bridge log out request.");
- }
- finally
- {
- ClearQueues();
- }
-
- try
- {
- IsLoggedIn = false;
- await base.Disconnect();
- }
- catch { }
-
- OnDisconnected();
- }
-
- #endregion
-
- #region Virtual Methods
-
- protected virtual void OnDisconnected()
- {
- Disconnected?.Invoke(this, new EventArgs());
- }
-
- #endregion
-
- #region Message Handlers
-
- protected virtual void OnExternalBridgeLoginRequest(MessageContainer container)
- {
- var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container);
-
- LogManager.Log($"External bridge login attempt:\nIntent: {request.Message.Intent}\nMessage:\n{request.Message.ToJsonString()}");
-
- ExternalBridgeReceiverLoginRequestEventArgs args = new ExternalBridgeReceiverLoginRequestEventArgs((machine, deviceInfo, applicationInfo) =>
- {
- //Confirm
- LogManager.Log("External bridge client has logged-in successfully.");
-
- IsLoggedIn = true;
- LoginIntent = request.Message.Intent;
- UserName = request.Message.UserName;
- LoginInfo = request.Message;
-
- var response = new ExternalBridgeLoginResponse();
- response.Authenticated = true;
- response.SerialNumber = machine.SerialNumber;
- response.DeviceInformation = deviceInfo;
- response.ApplicationInformation = applicationInfo;
-
- AllowSafetyLevelOperations = request.Message.RequireSafetyLevelOperations;
-
- SendResponse<ExternalBridgeLoginResponse>(response, container.Token);
-
- UpdateMachineOperatorStatus((UpdateStatus)_machineOperator.Status);
-
- UseKeepAlive = true;
-
- if (AllowSafetyLevelOperations && UserName != null)
- {
- LastSafetyLevelContactsTimes[UserName] = DateTime.Now;
- }
- },
- (reason) =>
- {
- //Decline
- SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.GeneralError, ErrorMessage = reason });
- Disconnect().GetAwaiter().GetResult();
- });
-
- args.Address = Adapter.Address;
- args.Request = request;
-
- LoginRequest?.Invoke(this, args);
- }
-
- protected virtual void OnExternalBridgeLogoutRequest(MessageContainer container)
- {
- try
- {
- SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex);
- }
- finally
- {
- OnDisconnected();
- ClearQueues();
- }
- }
-
- protected async virtual void OnAnyRequest(MessageContainer container)
- {
- if (!container.Continuous)
- {
- try
- {
- var response = await _machineOperator.SendRequest(container);
- await SendResponse(response);
- }
- catch (Exception ex)
- {
- await SendErrorResponse(ex, container.Token);
- }
- }
- else
- {
- try
- {
- _machineOperator.SendContinuousRequest(container).Subscribe((response) =>
- {
- if (State == TransportComponentState.Connected)
- {
- SendResponse(response);
- }
-
- }, (ex) =>
- {
- if (State == TransportComponentState.Connected)
- {
- if (ex is ResponseErrorException)
- {
- SendResponse((ex as ResponseErrorException).Container);
- }
- else if (ex is ContinuousResponseAbortedException)
- {
- SendResponse((ex as ContinuousResponseAbortedException).Container);
- }
- }
- });
- }
- catch (Exception ex)
- {
- await SendErrorResponse(ex, container.Token);
- }
- }
- }
-
- protected virtual void OnColorProfileRequest(MessageContainer container)
- {
- var request = MessageFactory.ParseTangoMessageFromContainer<ColorProfileRequest>(container);
-
- ColorProfileRequestEventArgs e = new ColorProfileRequestEventArgs(request, async () =>
- {
- //Approved.
- await SendResponse<ColorProfileResponse>(new ColorProfileResponse()
- {
- Approved = true
- }, container.Token);
- await Task.Delay(500);
- await base.Disconnect();
- },
- async () =>
- {
- //Declined.
- await SendResponse<ColorProfileResponse>(new ColorProfileResponse(), container.Token);
- await Task.Delay(500);
- await base.Disconnect();
- });
-
- ColorProfileRequest?.Invoke(this, e);
- }
-
- protected virtual void OnStartDiagnosticsRequest(MessageContainer container)
- {
- _diagnosticsToken = container.Token;
- SendResponse<StartDiagnosticsResponse>(new StartDiagnosticsResponse(), _diagnosticsToken);
- RequiresDiagnostics = true;
- }
-
- protected virtual void OnStopDiagnosticsRequest(MessageContainer container)
- {
- if (_diagnosticsToken != null)
- {
- RequiresDiagnostics = false;
- SendResponse<StartDiagnosticsResponse>(new StartDiagnosticsResponse(), _diagnosticsToken, new TransportResponseConfig() { Completed = true });
- _diagnosticsToken = null;
- SendResponse<StopDiagnosticsResponse>(new StopDiagnosticsResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartDebugLogRequest(MessageContainer container)
- {
- _debugLogsToken = container.Token;
- SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), _debugLogsToken);
- RequiresDebugLogs = true;
- }
-
- protected virtual void OnStopDebugLogRequest(MessageContainer container)
- {
- if (_debugLogsToken != null)
- {
- RequiresDebugLogs = false;
- SendResponse<StartDebugLogResponse>(new StartDebugLogResponse(), _debugLogsToken, new TransportResponseConfig() { Completed = true });
- _debugLogsToken = null;
- SendResponse<StopDebugLogResponse>(new StopDebugLogResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartEventsNotificationRequest(MessageContainer container)
- {
- _eventsToken = container.Token;
- SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), _eventsToken);
- RequiresEventsNotification = true;
- }
-
- protected virtual void OnStopEventsNotificationRequest(MessageContainer container)
- {
- if (_eventsToken != null)
- {
- RequiresEventsNotification = false;
- SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), _eventsToken, new TransportResponseConfig() { Completed = true });
- _eventsToken = null;
- SendResponse<StopEventsNotificationResponse>(new StopEventsNotificationResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartMachineStatusUpdateRequest(MessageContainer container)
- {
- _machineStatusToken = container.Token;
- SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), _machineStatusToken);
- RequiresMachineStatusUpdate = true;
- }
-
- protected virtual void OnStopMachineStatusUpdateRequest(MessageContainer container)
- {
- if (_machineStatusToken != null)
- {
- RequiresMachineStatusUpdate = false;
- SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), _machineStatusToken, new TransportResponseConfig() { Completed = true });
- _machineStatusToken = null;
- SendResponse<StopMachineStatusUpdateResponse>(new StopMachineStatusUpdateResponse(), container.Token);
- }
- }
-
- protected virtual void OnStartApplicationLogsRequest(MessageContainer container)
- {
- _applicationLogsToken = container.Token;
- SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), _applicationLogsToken);
- RequiresApplicationLogs = true;
- }
-
- protected virtual void OnStopApplicationLogsRequest(MessageContainer container)
- {
- if (_applicationLogsToken != null)
- {
- RequiresApplicationLogs = false;
- SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), _applicationLogsToken, new TransportResponseConfig() { Completed = true });
- _applicationLogsToken = null;
- SendResponse<StopApplicationLogsResponse>(new StopApplicationLogsResponse(), container.Token);
- }
- }
-
- protected virtual void OnJobRequest(MessageContainer container)
- {
- if (LoginIntent != ExternalBridgeLoginIntent.FullControl)
- {
- throw new InvalidOperationException($"Job execution is disabled while session intent is '{LoginIntent}'.");
- }
- if (_machineOperator.IsPrinting)
- {
- throw new InvalidOperationException($"Could not execute job while machine operator status is '{_machineOperator.Status}'.");
- }
- else
- {
- OnAnyRequest(container);
- }
- }
-
- protected virtual void OnStartPowerDownRequest(MessageContainer container)
- {
- SendResponse(new StartPowerDownResponse() { }, container.Token, new TransportResponseConfig() { ErrorCode = ErrorCode.ContinuousResponseAborted, ErrorMessage = "Power down request is not supported via external bridge." });
- }
-
- protected virtual void OnStartInkFillingStatusRequest(MessageContainer container)
- {
- _inkFillingToken = container.Token;
- UpdateInkFillingStatus(null);
- RequiresInkFillingStatus = true;
- }
-
- #endregion
-
- #region Continuous Updates
-
- public void UpdateDiagnostics(MessageContainer container)
- {
- try
- {
- if (AllowSafetyLevelOperations && UserName != null) //Usually all clients require diagnostics so we will update the last contact time here..
- {
- LastSafetyLevelContactsTimes[UserName] = DateTime.Now;
- }
-
- if (_diagnosticsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _diagnosticsToken;
- SendResponse(cloned);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateDebugLogs(MessageContainer container)
- {
- try
- {
- if (_debugLogsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _debugLogsToken;
- SendResponse(cloned, new TransportResponseConfig()
- {
- Priority = QueuePriority.Low,
- });
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateEvents(MessageContainer container)
- {
- try
- {
- if (_eventsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _eventsToken;
- SendResponse(cloned);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateMachineStatus(MessageContainer container)
- {
- try
- {
- if (_machineStatusToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _machineStatusToken;
- SendResponse(cloned);
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateApplicationLogs(MessageContainer container)
- {
- try
- {
- if (_applicationLogsToken != null)
- {
- var cloned = container.Clone();
- cloned.Token = _applicationLogsToken;
- SendResponse(cloned, new TransportResponseConfig() { Priority = QueuePriority.Low });
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateMachineOperatorStatus(UpdateStatus status)
- {
- try
- {
- SendRequest<UpdateStatusRequest, UpdateStatusResponse>(new UpdateStatusRequest()
- {
- Status = status,
- });
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- public void UpdateInkFillingStatus(MessageContainer container)
- {
- try
- {
- if (_inkFillingToken != null)
- {
- if (container == null)
- {
- container = new MessageContainer()
- {
- Continuous = true,
- Type = MessageType.StartInkFillingStatusResponse,
- Data = ByteString.CopyFrom((new StartInkFillingStatusResponse() { Status = _machineOperator.InkFillingStatus }).ToBytes())
- };
- }
- var cloned = container.Clone();
- cloned.Token = _inkFillingToken;
- SendResponse(cloned, new TransportResponseConfig());
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- #endregion
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs
deleted file mode 100644
index 1ea33dbce..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverLoginRequestEventArgs.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.BL.Entities;
-using Tango.PMR.Connection;
-using Tango.PMR.Integration;
-
-namespace Tango.Integration.ExternalBridge
-{
- public class ExternalBridgeReceiverLoginRequestEventArgs : EventArgs
- {
- private Action<Machine, DeviceInformation, ApplicationInformation> _confirm;
- private Action<String> _decline;
-
- public ExternalBridgeReceiverLoginRequestEventArgs(Action<Machine, DeviceInformation, ApplicationInformation> confirm, Action<String> decline)
- {
- _confirm = confirm;
- _decline = decline;
- }
-
- public ExternalBridgeLoginRequest Request { get; set; }
-
- public String Address { get; set; }
-
- public void Confirm(Machine machine, DeviceInformation deviceInformation, ApplicationInformation applicationInformation)
- {
- _confirm(machine, deviceInformation, applicationInformation);
- }
-
- public void Decline(String reason)
- {
- _decline(reason);
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs
deleted file mode 100644
index 682de264c..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeReceiverRequestReceivedEventArgs.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.PMR.Common;
-
-namespace Tango.Integration.ExternalBridge
-{
- public class ExternalBridgeReceiverRequestReceivedEventArgs
- {
- public MessageContainer Container { get; set; }
- public bool Handled { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs
deleted file mode 100644
index 7ddedb0b9..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeRequestHandlerMethodAttribute.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.PMR.Common;
-
-namespace Tango.Integration.ExternalBridge
-{
- [AttributeUsage(AttributeTargets.Method)]
- public class ExternalBridgeRequestHandlerMethodAttribute : Attribute
- {
- public Type Type { get; set; }
-
- public RequestHandlerLoggingMode LoggingMode { get; set; }
-
- public ExternalBridgeRequestHandlerMethodAttribute(Type type)
- {
- Type = type;
- }
-
- public ExternalBridgeRequestHandlerMethodAttribute(Type type, RequestHandlerLoggingMode loggingMode) : this(type)
- {
- LoggingMode = loggingMode;
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs
index 694502d2e..b84942643 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeScanner.cs
@@ -1,5 +1,4 @@
-using Microsoft.AspNet.SignalR.Client;
-using System;
+using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Diagnostics;
@@ -13,10 +12,8 @@ using System.Net.Sockets;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
-using Tango.BL.Entities;
using Tango.Core;
using Tango.Core.Helpers;
-using Tango.Integration.ExternalBridge.Web;
using Tango.Logging;
using Tango.PMR;
using Tango.PMR.Common;
@@ -34,15 +31,8 @@ namespace Tango.Integration.ExternalBridge
{
private Thread _tcpDiscoveryThread;
private Thread _usbDiscoveryThread;
- private Thread _signalRDiscoveryThread;
private UdpClient _server;
private IntegrationSettings _settings;
- private HubConnection _connection;
- private IHubProxy _proxy;
-
- public event EventHandler<IExternalBridgeClient> MachineDiscovered;
-
- public event EventHandler<IExternalBridgeClient> MachineLost;
private SynchronizedObservableCollection<IExternalBridgeClient> _availableMachines;
/// <summary>
@@ -54,16 +44,6 @@ namespace Tango.Integration.ExternalBridge
private set { _availableMachines = value; RaisePropertyChangedAuto(); }
}
- /// <summary>
- /// Gets or sets the SignalR configuration.
- /// </summary>
- public ExternalBridgeSignalRConfiguration SignalRConfiguration { get; set; }
-
- /// <summary>
- /// Gets or sets the known machines.
- /// </summary>
- public List<Machine> KnownMachines { get; set; }
-
private bool _isStarted;
/// <summary>
/// Gets or sets a value indicating whether this instance is started.
@@ -80,14 +60,8 @@ namespace Tango.Integration.ExternalBridge
public ExternalBridgeScanner()
{
_settings = SettingsManager.Default.GetOrCreate<IntegrationSettings>();
+ _server = new UdpClient(_settings.ExternalBridgeServiceDiscoveryPort);
AvailableMachines = new SynchronizedObservableCollection<IExternalBridgeClient>();
- KnownMachines = new List<Machine>();
- SignalRConfiguration = new ExternalBridgeSignalRConfiguration();
- }
-
- public ExternalBridgeScanner(List<Machine> knownMachines) : this()
- {
- KnownMachines = knownMachines;
}
/// <summary>
@@ -99,13 +73,6 @@ namespace Tango.Integration.ExternalBridge
{
LogManager.Log("External bridge scanner started...");
- if (_server == null)
- {
- _server = new UdpClient();
- _server.Client.SetSocketOption(SocketOptionLevel.Socket, SocketOptionName.ReuseAddress, true);
- _server.Client.Bind(new IPEndPoint(IPAddress.Any, _settings.ExternalBridgeServiceDiscoveryPort));
- }
-
IsStarted = true;
foreach (var machine in AvailableMachines.OfType<ExternalBridgeTcpClient>().ToList())
@@ -113,11 +80,6 @@ namespace Tango.Integration.ExternalBridge
AvailableMachines.Remove(machine);
}
- foreach (var machine in AvailableMachines.OfType<ExternalBridgeSignalRClient>().ToList())
- {
- AvailableMachines.Remove(machine);
- }
-
_tcpDiscoveryThread = new Thread(TcpDiscoveryThreadMethod);
_tcpDiscoveryThread.IsBackground = true;
_tcpDiscoveryThread.Start();
@@ -125,37 +87,6 @@ namespace Tango.Integration.ExternalBridge
_usbDiscoveryThread = new Thread(UsbDiscoveryThreadMethod);
_usbDiscoveryThread.IsBackground = true;
_usbDiscoveryThread.Start();
-
- if (SignalRConfiguration.Enabled)
- {
- try
- {
- _connection = new HubConnection(SignalRConfiguration.Address);
- _proxy = _connection.CreateHubProxy(SignalRConfiguration.Hub);
-
- bool signalRStarted = false;
-
- _connection.StateChanged += (x) =>
- {
- if (x.NewState == ConnectionState.Connected)
- {
- if (!signalRStarted)
- {
- signalRStarted = true;
- _signalRDiscoveryThread = new Thread(SignalRDiscoveryThreadMethod);
- _signalRDiscoveryThread.IsBackground = true;
- _signalRDiscoveryThread.Start();
- }
- }
- };
-
- _connection.Start();
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
}
}
@@ -187,9 +118,7 @@ namespace Tango.Integration.ExternalBridge
LogManager.Log("Found a new machine via USB " + device.Description);
ThreadsHelper.InvokeUINow(() =>
{
- var machine = new ExternalBridgeUsbClient(device.Port, device.Description, _settings.EmbeddedSerialBaudRate);
- AvailableMachines.Add(machine);
- MachineDiscovered?.Invoke(this, machine);
+ AvailableMachines.Add(new ExternalBridgeUsbClient(device.Port, device.Description, _settings.EmbeddedSerialBaudRate));
});
}
}
@@ -202,7 +131,7 @@ namespace Tango.Integration.ExternalBridge
/// <summary>
/// TCP discovery thread method.
/// </summary>
- //[DebuggerStepThrough]
+ [DebuggerStepThrough]
private void TcpDiscoveryThreadMethod()
{
while (IsStarted)
@@ -232,7 +161,6 @@ namespace Tango.Integration.ExternalBridge
{
LogManager.Log("Disconnected machine detected via TCP: " + disconnected_machine.SerialNumber);
AvailableMachines.Remove(disconnected_machine);
- MachineLost?.Invoke(this, disconnected_machine);
}
continue;
@@ -240,35 +168,14 @@ namespace Tango.Integration.ExternalBridge
if (!AvailableMachines.OfType<ExternalBridgeTcpClient>().ToList().Exists(x => x.SerialNumber == packet.SerialNumber && x.IPAddress == address))
{
- ExternalBridgeTcpClient newMachine = null;
- var knownMachine = KnownMachines.FirstOrDefault(x => x.SerialNumber == packet.SerialNumber);
+ ExternalBridgeTcpClient newMachine = new ExternalBridgeTcpClient(packet.SerialNumber, address);
- if (knownMachine == null && KnownMachines.Count == 0)
- {
- newMachine = new ExternalBridgeTcpClient(packet.SerialNumber, address);
- }
- else if (knownMachine != null)
- {
- newMachine = new ExternalBridgeTcpClient(knownMachine, address);
- }
+ LogManager.Log("Found a new machine via TCP " + newMachine.SerialNumber);
- if (newMachine != null)
+ ThreadsHelper.InvokeUINow(() =>
{
- LogManager.Log("Found a new machine via TCP " + newMachine.SerialNumber);
-
- ThreadsHelper.InvokeUINow(() =>
- {
- if (AvailableMachines.Count > 0)
- {
- AvailableMachines.Insert(1, newMachine);
- }
- else
- {
- AvailableMachines.Add(newMachine);
- }
- MachineDiscovered?.Invoke(this, newMachine);
- });
- }
+ AvailableMachines.Insert(1, newMachine);
+ });
}
}
catch (Exception ex)
@@ -278,65 +185,6 @@ namespace Tango.Integration.ExternalBridge
}
}
- private void SignalRDiscoveryThreadMethod()
- {
- while (IsStarted && SignalRConfiguration.Enabled)
- {
- if (_connection.State == ConnectionState.Connected)
- {
- try
- {
- var machines = _proxy.Invoke<List<MachineInfo>>("GetAvailableMachines").Result;
-
- foreach (var machine in AvailableMachines.OfType<ExternalBridgeSignalRClient>().ToList().Where(x => !machines.Exists(y => y.SerialNumber == x.SerialNumber)))
- {
- AvailableMachines.Remove(machine);
- MachineLost?.Invoke(this, machine);
- }
-
- foreach (var machine in machines.Where(x => !AvailableMachines.OfType<ExternalBridgeSignalRClient>().ToList().Exists(y => y.SerialNumber == x.SerialNumber)))
- {
- ExternalBridgeSignalRClient newMachine = null;
- var knownMachine = KnownMachines.FirstOrDefault(x => x.SerialNumber == machine.SerialNumber);
-
- if (knownMachine == null && KnownMachines.Count == 0)
- {
- newMachine = new ExternalBridgeSignalRClient(SignalRConfiguration.Address, SignalRConfiguration.Hub, machine);
- }
- else if (knownMachine != null)
- {
- newMachine = new ExternalBridgeSignalRClient(SignalRConfiguration.Address, SignalRConfiguration.Hub, knownMachine, machine);
- }
-
- if (newMachine != null)
- {
- LogManager.Log("Found a new machine via SignalR " + newMachine.SerialNumber);
-
- ThreadsHelper.InvokeUINow(() =>
- {
- if (AvailableMachines.Count > 0)
- {
- AvailableMachines.Insert(1, newMachine);
- }
- else
- {
- AvailableMachines.Add(newMachine);
- }
- MachineDiscovered?.Invoke(this, newMachine);
- });
- }
- }
- }
- catch (Exception ex)
- {
- Debug.WriteLine(ex);
- }
- }
-
- Thread.Sleep(5000);
- }
- }
-
private DateTime ParseDateTime(String dateTime)
{
try
@@ -360,7 +208,6 @@ namespace Tango.Integration.ExternalBridge
{
LogManager.Log("External bridge client failed or disposed. Removing from available machines...");
AvailableMachines.Remove(sender as IExternalBridgeClient);
- MachineLost?.Invoke(this, sender as IExternalBridgeClient);
}
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
index 4218f9e9a..7ad03f3a7 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeService.cs
@@ -21,41 +21,23 @@ using System.Security.Authentication;
using Tango.Settings;
using Tango.Core.ExtensionMethods;
using Tango.PMR.MachineStatus;
-using Tango.PMR.Power;
-using Tango.Core;
-using Microsoft.AspNet.SignalR.Client;
-using Tango.Integration.ExternalBridge.Web;
-using Tango.Core.Threading;
-using System.Diagnostics;
-using System.Reflection;
-using Newtonsoft.Json;
-using System.Collections.ObjectModel;
namespace Tango.Integration.ExternalBridge
{
- public class ExternalBridgeService : ExtendedObject, IExternalBridgeService
+ public class ExternalBridgeService : BasicTransporter, IExternalBridgeService
{
- private List<ExternalBridgeReceiver> _receivers;
private UdpDiscoveryService<ExternalBridgeUdpDiscoveryPacket> _discoveryService;
private TcpServer _tcpServer;
+ private bool _send_app_logs;
+ private String _app_logs_token;
+ private Dictionary<MessageType, Action<MessageContainer>> _messageHandlers;
private int _discovery_port = 8888; //Will be overridden by settings in constructor..
private int _external_bridge_port = 1984; //Will be overridden by settings in constructor..
- private HubConnection _connection;
- private IHubProxy _proxy;
- private bool _isSignalRConnected;
- private System.Timers.Timer _signalrPingTimer;
- private Dictionary<String, RequestHandler> _requestHandlers;
- private static JsonSerializerSettings _genericMessageSettings = new JsonSerializerSettings()
- {
- TypeNameHandling = TypeNameHandling.All
- };
-
- private class RequestHandler
- {
- public IExternalBridgeRequestHandler Handler { get; set; }
- public MethodInfo Method { get; set; }
- public RequestHandlerLoggingMode LoggingMode { get; set; }
- }
+ private String _eventsNotificationsToken;
+ private String _machineStatusUpdateToken;
+ private String _diagnosticsNotificationToken;
+ private String _debugLogsNotificationToken;
+ private bool _resend_diagnostics_and_debug;
#region Events
@@ -67,7 +49,7 @@ namespace Tango.Integration.ExternalBridge
/// <summary>
/// Occurs when the last client has been disconnected.
/// </summary>
- public event EventHandler FullControlSessionDisconnected;
+ public event EventHandler ClientDisconnected;
/// <summary>
/// Occurs when the service has received a new color profile request.
@@ -78,29 +60,6 @@ namespace Tango.Integration.ExternalBridge
#region Properties
- public static HashSet<MessageType> SafetyLevelOperations { get; private set; }
-
- /// <summary>
- /// Gets the collection of logged-in receivers.
- /// </summary>
- public List<ExternalBridgeReceiver> ActiveReceivers
- {
- get
- {
- return _receivers.Where(x => x.IsLoggedIn).ToList();
- }
- }
-
- /// <summary>
- /// Gets or sets the TCP transport adapter write mode when creating a TCP receiver.
- /// </summary>
- public TcpTransportAdapterWriteMode TcpTransportAdapterWriteMode { get; set; }
-
- /// <summary>
- /// Gets or sets the SignalR configuration.
- /// </summary>
- public ExternalBridgeSignalRConfiguration SignalRConfiguration { get; set; }
-
private IMachineOperator _machineOperator;
/// <summary>
/// Gets or sets the machine operator.
@@ -150,60 +109,45 @@ namespace Tango.Integration.ExternalBridge
}
}
- private bool _hasSessions;
+ private bool _isInSession;
/// <summary>
- /// Gets a value indicating whether there are any connected sessions.
+ /// Gets a value indicating whether a remote client is authenticated and in session.
/// </summary>
- public bool HasSessions
+ public bool IsInSession
{
- get { return _hasSessions; }
- private set { _hasSessions = value; RaisePropertyChangedAuto(); }
+ get { return _isInSession; }
+ private set { _isInSession = value; RaisePropertyChangedAuto(); }
}
- private ExternalBridgeReceiver _fullControlSessionReceiver;
/// <summary>
- /// Gets the current full control session receiver.
+ /// Gets the current session login intent.
/// </summary>
- public ExternalBridgeReceiver FullControlSessionReceiver
- {
- get { return _fullControlSessionReceiver; }
- private set { _fullControlSessionReceiver = value; RaisePropertyChangedAuto(); }
- }
+ public ExternalBridgeLoginIntent SessionIntent { get; private set; }
#endregion
#region Constructors
/// <summary>
- /// Initializes the <see cref="ExternalBridgeService"/> class.
- /// </summary>
- static ExternalBridgeService()
- {
- SafetyLevelOperations = new HashSet<MessageType>();
- }
-
- /// <summary>
/// Initializes a new instance of the <see cref="ExternalBridgeService"/> class.
/// </summary>
public ExternalBridgeService()
{
- _requestHandlers = new Dictionary<string, RequestHandler>();
-
- SignalRConfiguration = new ExternalBridgeSignalRConfiguration();
-
- TcpTransportAdapterWriteMode = TcpTransportAdapterWriteMode.Interval;
-
- _receivers = new List<ExternalBridgeReceiver>();
-
var settings = SettingsManager.Default.GetOrCreate<IntegrationSettings>();
_discovery_port = settings.ExternalBridgeServiceDiscoveryPort;
_external_bridge_port = settings.ExternalBridgeServicePort;
+ _messageHandlers = new Dictionary<MessageType, Action<MessageContainer>>();
+ RegisterMessageHandlers();
+
_tcpServer = new TcpServer(_external_bridge_port);
_tcpServer.ClientConnected += _tcpServer_ClientConnected;
LogManager.NewLog += LogManager_NewLog;
+
+ KeepAliveTimeout = TimeSpan.FromSeconds(5);
+ KeepAliveRetries = 2;
}
/// <summary>
@@ -252,12 +196,12 @@ namespace Tango.Integration.ExternalBridge
{
if (MachineOperator != null)
{
+ MachineOperator.StateChanged -= MachineOperator_StateChanged;
+ MachineOperator.StateChanged += MachineOperator_StateChanged;
MachineOperator.StatusChanged -= MachineOperator_StatusChanged;
MachineOperator.StatusChanged += MachineOperator_StatusChanged;
MachineOperator.PendingResponseReceived -= MachineOperator_PendingResponseReceived;
MachineOperator.PendingResponseReceived += MachineOperator_PendingResponseReceived;
- MachineOperator.EventsNotification -= MachineOperator_EventsNotification;
- MachineOperator.EventsNotification += MachineOperator_EventsNotification;
}
}
@@ -272,551 +216,603 @@ namespace Tango.Integration.ExternalBridge
/// <param name="e">The <see cref="ClientConnectedEventArgs"/> instance containing the event data.</param>
private async void _tcpServer_ClientConnected(object sender, ClientConnectedEventArgs e)
{
- LogManager.Log("External bridge TCP client connected from: " + e.Socket.GetIPAddress());
- ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(e.Socket, MachineOperator);
- (receiver.Adapter as TcpTransportAdapter).WriteMode = TcpTransportAdapterWriteMode;
- receiver.LoginRequest += Receiver_LoginRequest;
- receiver.ColorProfileRequest += Receiver_ColorProfileRequest;
- receiver.Disconnected += Receiver_Disconnected;
- receiver.ReceiverRequestReceived += Receiver_ReceiverRequestReceived;
- _receivers.Add(receiver);
- await receiver.Connect();
- RaisePropertyChanged(nameof(ActiveReceivers));
+ if (!IsInSession)
+ {
+ UseKeepAlive = false;
+ LogManager.Log("External bridge client connected from: " + e.Socket.GetIPAddress());
+ Adapter = new TcpTransportAdapter(e.Socket);
+ await Connect();
+ }
+ else
+ {
+ e.Socket.Dispose();
+ }
}
- private async void OnSignalRSessionCreated(String sessionID)
+ /// <summary>
+ /// Machines the operator state changed.
+ /// </summary>
+ /// <param name="sender">The sender.</param>
+ /// <param name="e">The e.</param>
+ private void MachineOperator_StateChanged(object sender, TransportComponentState e)
{
- try
+ //Do nothing right now.
+ if (e != TransportComponentState.Connected)
{
- LogManager.Log("External bridge SignalR client connected.");
-
- var adapter = new SignalRTransportAdapter(SignalRConfiguration.Address, SignalRConfiguration.Hub, SignalRTransportAdapterMode.JoinSession, Machine.SerialNumber, sessionID); ;
-
- ExternalBridgeReceiver receiver = new ExternalBridgeReceiver(adapter, MachineOperator);
- receiver.LoginRequest += Receiver_LoginRequest;
- receiver.ColorProfileRequest += Receiver_ColorProfileRequest;
- receiver.Disconnected += Receiver_Disconnected;
- receiver.ReceiverRequestReceived += Receiver_ReceiverRequestReceived;
- _receivers.Add(receiver);
- await receiver.Connect();
- RaisePropertyChanged(nameof(ActiveReceivers));
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error initializing SignalR ExternalBridgeReceiver when session created.");
+ _resend_diagnostics_and_debug = true;
}
}
- private void MachineOperator_StatusChanged(object sender, MachineStatuses status)
+ private async void MachineOperator_StatusChanged(object sender, MachineStatuses e)
{
- try
+ if (e == MachineStatuses.ReadyToDye && _machineOperator.State == TransportComponentState.Connected)
{
- _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics).ToList().ForEach(x => x.UpdateMachineOperatorStatus((UpdateStatus)status));
+ if (IsInSession && _resend_diagnostics_and_debug)
+ {
+ _resend_diagnostics_and_debug = false;
+
+ if (_diagnosticsNotificationToken != null)
+ {
+ var msg = MessageFactory.CreateTangoMessage<StartDiagnosticsRequest>(_diagnosticsNotificationToken);
+ _machineOperator.SendContinuousRequest<StartDiagnosticsRequest, StartDiagnosticsResponse>(msg);
+ }
+ if (_debugLogsNotificationToken != null)
+ {
+ var msg = MessageFactory.CreateTangoMessage<StartDebugLogRequest>(_debugLogsNotificationToken);
+ _machineOperator.SendContinuousRequest<StartDebugLogRequest, StartDebugLogResponse>(msg);
+ }
+ }
}
- catch (Exception ex)
+
+ if (IsInSession)
{
- LogManager.Log(ex, "Error updating status of external bridge service client.");
+ try
+ {
+ UpdateStatus s = (UpdateStatus)e;
+
+ await SendRequest<UpdateStatusRequest, UpdateStatusResponse>(new UpdateStatusRequest()
+ {
+ Status = s,
+ });
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error updating status of external bridge service client.");
+ }
}
}
private void LogManager_NewLog(object sender, Tango.Logging.LogItemBase e)
{
- var toSend = _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresApplicationLogs).ToList();
-
- if (_receivers.Count > 0)
+ if (State == TransportComponentState.Connected && _send_app_logs)
{
- var msg = MessageFactory.CreateTangoMessage<StartApplicationLogsResponse>(new StartApplicationLogsResponse()
+ try
{
- LogItem = ByteString.CopyFrom(e.Serialize())
- });
-
- msg.ToBytes();
-
- toSend.ToList().Where(x => x.State == TransportComponentState.Connected).ToList().ForEach(x => x.UpdateApplicationLogs(msg.Container));
+ SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse()
+ {
+ LogItem = ByteString.CopyFrom(e.Serialize())
+ }, _app_logs_token);
+ }
+ catch { }
}
}
+
private void MachineOperator_PendingResponseReceived(object sender, MessageContainer container)
{
OnOperatorResponseReceived(container);
}
- private void MachineOperator_EventsNotification(object sender, StartEventsNotificationResponse e)
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Starts this instance.
+ /// </summary>
+ public void Start()
{
- try
+ if (!IsStarted)
{
- MessageContainer container = new MessageContainer();
- container.Type = MessageType.StartEventsNotificationResponse;
- container.Continuous = true;
- container.Data = e.ToByteString();
+ _tcpServer.Start();
+ _discoveryService.Start();
- _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresEventsNotification).ToList().ForEach(x => x.UpdateEvents(container));
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error on external bridge machine events broadcast.");
+ IsStarted = true;
+ _enabled = true;
+ RaisePropertyChanged(nameof(Enabled));
}
}
- #endregion
-
- #region Receiver Events Handlers
-
- private void Receiver_Disconnected(object sender, EventArgs e)
+ /// <summary>
+ /// Stops this instance.
+ /// </summary>
+ public async void Stop()
{
- var receiver = sender as ExternalBridgeReceiver;
-
- receiver.LoginRequest -= Receiver_LoginRequest;
- receiver.ColorProfileRequest -= Receiver_ColorProfileRequest;
- receiver.Disconnected -= Receiver_Disconnected;
- receiver.ReceiverRequestReceived -= Receiver_ReceiverRequestReceived;
-
- _receivers.Remove(receiver);
-
- if (receiver.LoginIntent == ExternalBridgeLoginIntent.FullControl)
+ if (IsStarted)
{
- FullControlSessionDisconnected?.Invoke(this, new EventArgs());
- }
-
- HasSessions = _receivers.Count(x => x.IsLoggedIn) > 0;
+ _tcpServer.Stop();
+ _discoveryService.Stop();
- FullControlSessionReceiver = _receivers.SingleOrDefault(x => x.IsLoggedIn && x.LoginIntent == ExternalBridgeLoginIntent.FullControl);
+ IsStarted = false;
+ IsInSession = false;
+ _enabled = false;
+ RaisePropertyChanged(nameof(Enabled));
- //Notify request handlers about this receiver disconnected.
- foreach (var requestHandler in _requestHandlers.ToList().Select(x => x.Value.Handler))
- {
try
{
- requestHandler.OnReceiverDisconnected(receiver);
+ await Disconnect();
}
- catch { } //Ignore exceptions on handler.
+ catch { }
}
-
- RaisePropertyChanged(nameof(ActiveReceivers));
}
- private void Receiver_ColorProfileRequest(object sender, ColorProfileRequestEventArgs e)
+ /// <summary>
+ /// Disconnects the current remote client session.
+ /// </summary>
+ public async void DisconnectSession()
{
- ColorProfileRequest?.Invoke(this, e);
+ await Disconnect();
}
- private void Receiver_LoginRequest(object sender, ExternalBridgeReceiverLoginRequestEventArgs e)
- {
- var request = e.Request;
-
- if (request.Intent == ExternalBridgeLoginIntent.FullControl && _receivers.Any(x => x.IsLoggedIn && x.LoginIntent == ExternalBridgeLoginIntent.FullControl))
- {
- e.Decline("Only one full control client is allowed.");
- return;
- }
-
- if (request.Intent == ExternalBridgeLoginIntent.FullControl && MachineOperator.IsPrinting)
- {
- e.Decline($"External bridge client login failed because the machine is currently printing and '{ExternalBridgeLoginIntent.FullControl}' intent was requested.");
- return;
- }
-
- ExternalBridgeClientConnectedEventArgs args = null;
-
- args = new ExternalBridgeClientConnectedEventArgs(() =>
- {
- //Confirmed
- e.Confirm(Machine, MachineOperator.DeviceInformation, args.ApplicationInformation);
- HasSessions = true;
-
- if (request.Intent == ExternalBridgeLoginIntent.FullControl)
- {
- FullControlSessionReceiver = sender as ExternalBridgeReceiver;
- }
-
- RaisePropertyChanged(nameof(ActiveReceivers));
- }, (reason) =>
- {
- //Declined
- e.Decline(reason);
- });
+ #endregion
- args.Request = request;
- args.Address = e.Address;
- ConnectionRequest?.Invoke(this, args);
- }
+ #region Override Methods
- private void Receiver_ReceiverRequestReceived(object sender, ExternalBridgeReceiverRequestReceivedEventArgs e)
+ protected override void OnRequestReceived(MessageContainer container)
{
- ExternalBridgeReceiver receiver = sender as ExternalBridgeReceiver;
+ base.OnRequestReceived(container);
- if (e.Container.Type == MessageType.GenericRequest || _requestHandlers.ContainsKey(e.Container.Type.ToString()))
+ try
{
- e.Handled = true;
-
- ThreadFactory.StartNew(() =>
+ if (Enabled)
{
- try
+ if (container.Type == MessageType.ConnectRequest || container.Type == MessageType.DisconnectRequest)
{
- var message = MessageFactory.ExtractMessageFromContainer(e.Container);
-
- if (e.Container.Type != MessageType.GenericRequest) //Handle standard PMR messages.
+ //Do nothing !
+ }
+ else
+ {
+ if (IsInSession)
{
- var handler = _requestHandlers[e.Container.Type.ToString()];
-
- if (handler.Method.ReturnType == typeof(Task))
+ if (container.Type == MessageType.ExternalBridgeLoginRequest)
{
- ((Task)handler.Method.Invoke(handler.Handler, new object[]
- {
- message,
- e.Container.Token,
- sender,
- })).Wait();
+ SendErrorResponse(new AuthenticationException("Machine is already in session."), container.Token);
+ return;
}
- else
- {
- handler.Method.Invoke(handler.Handler, new object[]
- {
- message,
- e.Container.Token,
- sender,
- });
- }
- }
- else //Handle GenericRequest with inner JSON/BSON formated generic message.
- {
- var genericType = Type.GetType((message as GenericRequest).Type);
- if (genericType != null)
+ if (_messageHandlers.ContainsKey(container.Type))
{
try
{
- if (_requestHandlers.ContainsKey(genericType.FullName))
+ try
{
- var innerMessage = GenericMessageSerializer.DeserializeFromByteString(genericType, (message as GenericRequest).Data, receiver.GenericProtocol);
-
- var handler = _requestHandlers[genericType.FullName];
-
- if (handler.LoggingMode == RequestHandlerLoggingMode.LogRequestName || handler.LoggingMode == RequestHandlerLoggingMode.LogRequestNameAndContent)
- {
- String content = ".";
-
- if (handler.LoggingMode == RequestHandlerLoggingMode.LogRequestNameAndContent)
- {
- content = $":\n{innerMessage.ToJsonString()}";
- }
-
- LogManager.Log($"'{innerMessage.GetType().Name}' received on '{handler.Method.DeclaringType.Name}.{handler.Method.Name}'{content}");
- }
-
- if (handler.Method.ReturnType == typeof(Task))
- {
- ((Task)handler.Method.Invoke(handler.Handler, new object[]
- {
- innerMessage,
- e.Container.Token,
- sender,
- })).Wait();
- }
- else
- {
- handler.Method.Invoke(handler.Handler, new object[]
- {
- innerMessage,
- e.Container.Token,
- sender,
- });
- }
+ _messageHandlers[container.Type](container);
}
- else
+ catch (Exception ex)
{
- receiver.SendErrorResponse(new NotSupportedException("Request message not supported on this PPC version."), e.Container.Token);
+ SendErrorResponse(ex, container.Token);
}
}
catch (Exception ex)
{
- LogManager.Log(ex.GetFirstIfAggregate(), $"Error invoking external bridge handler for request '{genericType.Name}'.");
-
- try
+ if (ex is ResponseErrorException)
{
- receiver.SendErrorResponse(ex.GetFirstIfAggregate(), e.Container.Token);
+ SendResponse((ex as ResponseErrorException).Container);
+ }
+ else
+ {
+ SendErrorResponse(ex, container.Token);
}
- catch { }
}
}
else
{
- receiver.SendErrorResponse(new NotSupportedException("Request message not supported on this PPC version."), e.Container.Token);
+ OnAnyRequest(container);
}
}
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, $"An error occurred while trying or invoking an external bridge request handler for '{e.Container.Type}'.");
- try
+ else
{
- receiver.SendErrorResponse(ex.GetFirstIfAggregate(), e.Container.Token);
+ if (container.Type == MessageType.ExternalBridgeLoginRequest)
+ {
+ OnExternalBridgeLoginRequest(container);
+ }
+ else if (container.Type == MessageType.ColorProfileRequest)
+ {
+ OnColorProfileRequest(container);
+ }
}
- catch { }
}
- });
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, String.Format("An error occurred while processing a request message '{0}' from the remote host.", container.Type));
}
}
- #endregion
+ public async override Task Disconnect()
+ {
+ _send_app_logs = false;
- #region Public Methods
+ try
+ {
+ if (IsInSession)
+ {
+ await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutRequest(), TimeSpan.FromSeconds(0.5));
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error sending an external bridge log out request.");
+ }
+ finally
+ {
+ ClearQueues();
+ }
- /// <summary>
- /// Starts this instance.
- /// </summary>
- public void Start()
+ OnClientDisconnected();
+ }
+
+ protected override void OnFailed(Exception ex)
{
- if (!IsStarted)
+ if (ex is KeepAliveException)
{
- LogManager.Log("Starting external bridge service...");
+ LogManager.Log("External bridge client has failed to provide a keep alive response. Disconnecting session...");
+ }
+
+ base.OnFailed(ex);
+ }
+ #endregion
+
+ #region Virtual Methods
+
+ protected async virtual void OnClientDisconnected()
+ {
+ _eventsNotificationsToken = null;
+ _machineStatusUpdateToken = null;
+ _diagnosticsNotificationToken = null;
+ _debugLogsNotificationToken = null;
+ IsInSession = false;
+ _send_app_logs = false;
- LogManager.Log("Starting TCP server...");
+ if (MachineOperator.State == TransportComponentState.Connected)
+ {
try
{
- _tcpServer.Start();
+ await MachineOperator.SendRequest(new StopDiagnosticsRequest());
}
catch (Exception ex)
{
- LogManager.Log(ex, "Error starting external bridge TCP server.");
+ LogManager.Log(ex);
}
- LogManager.Log("Starting discovery service...");
try
{
- _discoveryService.Start();
+ await MachineOperator.SendRequest(new StopDebugLogRequest());
}
catch (Exception ex)
{
- LogManager.Log(ex, "Error starting external bridge discovery service.");
+ LogManager.Log(ex);
}
+ }
- if (SignalRConfiguration.Enabled)
- {
- StartSignalR();
- }
+ ClientDisconnected?.Invoke(this, new EventArgs());
- IsStarted = true;
- _enabled = true;
- RaisePropertyChanged(nameof(Enabled));
+ try
+ {
+ await base.Disconnect();
}
+ catch (Exception ex)
+ {
+ LogManager.Log(ex);
+ }
+
+ LogManager.Log("External bridge client disconnected.");
}
- private void StartSignalR()
+ protected virtual void OnOperatorResponseReceived(MessageContainer container)
{
- if (!_enabled || _isSignalRConnected) return;
-
try
{
- try
- {
- if (_connection != null)
- {
- _connection.Dispose();
- }
- }
- catch { }
-
- LogManager.Log("Starting SignalR service...");
-
- _connection = new HubConnection(SignalRConfiguration.Address);
- _proxy = _connection.CreateHubProxy(SignalRConfiguration.Hub);
- _proxy.On<String>("OnSessionCreated", OnSignalRSessionCreated);
- _connection.Start();
- _connection.StateChanged += (x) =>
+ if (IsInSession)
{
- if (x.NewState == ConnectionState.Connected)
+ if (container.Type == MessageType.StartEventsNotificationResponse)
{
- try
+ if (_eventsNotificationsToken != null)
{
- LogManager.Log("External Bridge Service SignalR Connected. Registering machine...");
-
- _proxy.Invoke("RegisterMachine", new MachineInfo()
- {
- SerialNumber = Machine.SerialNumber,
- Organization = Machine.Organization.Name,
- });
-
- _isSignalRConnected = true;
-
- if (_signalrPingTimer == null)
- {
- _signalrPingTimer = new System.Timers.Timer(TimeSpan.FromMinutes(5).TotalMilliseconds);
- _signalrPingTimer.Elapsed += _signalrPingTimer_Elapsed;
- _signalrPingTimer.Start();
- }
+ container.Token = _eventsNotificationsToken;
+ SendResponse(container);
}
- catch (Exception ex)
+ }
+ if (container.Type == MessageType.StartMachineStatusUpdateResponse)
+ {
+ if (_machineStatusUpdateToken != null)
{
- LogManager.Log(ex, "Error registering machine via SignalR.");
+ container.Token = _machineStatusUpdateToken;
+ SendResponse(container);
}
}
- else if (x.NewState == ConnectionState.Disconnected)
+ else if (container.Type == MessageType.StartDiagnosticsResponse)
{
- _isSignalRConnected = false;
-
- if (Enabled)
+ if (_diagnosticsNotificationToken != null)
{
- LogManager.Log("External Bridge Service SignalR Disconnected/Failed. Reconnecting in 1 minute...");
- TimeoutTask.StartNew(StartSignalR, TimeSpan.FromMinutes(1));
+ container.Token = _diagnosticsNotificationToken;
+ SendResponse(container);
}
}
- else if (x.NewState == ConnectionState.Reconnecting)
+ else if (container.Type == MessageType.StartDebugLogResponse)
{
- LogManager.Log("External Bridge Service SignalR Connection Lost. Reconnecting...");
- //Will go invoke state change again with "connected" if successful...
+ if (_debugLogsNotificationToken != null)
+ {
+ container.Token = _debugLogsNotificationToken;
+ SendResponse(container);
+ }
}
- };
+ }
}
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error initializing External Bridge SignalR. Will try again in 5 minutes...");
+ catch { }
+ }
- TimeoutTask.StartNew(StartSignalR, TimeSpan.FromMinutes(5));
- }
+ #endregion
+
+ #region Message Handlers
+
+ private void RegisterMessageHandlers()
+ {
+ _messageHandlers.Add(MessageType.ExternalBridgeLogoutRequest, OnExternalBridgeLogoutRequest);
+
+ _messageHandlers.Add(MessageType.StartApplicationLogsRequest, OnStartApplicationLogsRequest);
+ _messageHandlers.Add(MessageType.StopApplicationLogsRequest, OnStopApplicationLogsRequest);
+
+ _messageHandlers.Add(MessageType.JobRequest, OnJobRequest);
+
+ //Events
+ _messageHandlers.Add(MessageType.StartEventsNotificationRequest, OnStartEventsNotificationRequest);
+ _messageHandlers.Add(MessageType.StopEventsNotificationRequest, OnStopEventsNotificationRequest);
+
+ //Machine Status
+ _messageHandlers.Add(MessageType.StartMachineStatusUpdateRequest, OnStartMachineStatusUpdateRequest);
+ _messageHandlers.Add(MessageType.StopMachineStatusUpdateRequest, OnStopMachineStatusUpdateRequest);
+
+ //Diagnostics
+ _messageHandlers.Add(MessageType.StartDiagnosticsRequest, OnStartDiagnosticsRequest);
+
+ //Debug Logs
+ _messageHandlers.Add(MessageType.StartDebugLogRequest, OnStartDebugLogRequest);
}
- private async void _signalrPingTimer_Elapsed(object sender, System.Timers.ElapsedEventArgs e)
+ protected virtual async void OnAnyRequest(MessageContainer container)
{
- if (Enabled && SignalRConfiguration.Enabled)
+ if (SessionIntent == ExternalBridgeLoginIntent.ColorProfile)
{
- if (_proxy != null)
- {
- try
- {
- var result = await _proxy.Invoke<String>("Ping");
- }
- catch
- {
- Debug.WriteLine("Error pinging to machine service via SignalR.");
- }
- }
+ await SendErrorResponse(new AuthenticationException("The specified intent does not grant the specified action."), container.Token);
+ return;
}
- }
- /// <summary>
- /// Stops this instance.
- /// </summary>
- public async void Stop()
- {
- if (IsStarted)
+ if (!container.Continuous)
{
try
{
- _tcpServer.Stop();
- _discoveryService.Stop();
+ var response = await MachineOperator.SendRequest(container);
+ await SendResponse(response);
}
+ //catch (TimeoutException)
+ //{
+
+ //}
catch (Exception ex)
{
- LogManager.Log(ex, "Error disposing TCP discovery services.");
+ await SendErrorResponse(ex, container.Token);
}
-
- foreach (var receiver in _receivers.ToList())
+ }
+ else
+ {
+ try
{
- try
+ MachineOperator.SendContinuousRequest(container).Subscribe((response) =>
{
- await receiver.Disconnect();
- }
- catch (Exception ex)
+ if (Enabled && IsInSession)
+ {
+ SendResponse(response);
+ }
+
+ }, (ex) =>
{
- LogManager.Log(ex, $"Error disconnecting receiver {receiver.ComponentName}.");
- }
+ if (Enabled)
+ {
+ if (ex is ResponseErrorException)
+ {
+ SendResponse((ex as ResponseErrorException).Container);
+ }
+ }
+ });
+ }
+ catch (Exception ex)
+ {
+ await SendErrorResponse(ex, container.Token);
}
+ }
+ }
- _enabled = false;
+ protected async virtual void OnExternalBridgeLoginRequest(MessageContainer container)
+ {
+ var request = MessageFactory.ParseTangoMessageFromContainer<ExternalBridgeLoginRequest>(container);
+
+ LogManager.Log($"External bridge login attempt:\nIntent: {request.Message.Intent}\nMessage:\n{request.Message.ToJsonString()}");
- if (SignalRConfiguration.Enabled)
+ if (MachineOperator.Status != MachineStatuses.Printing || request.Message.Intent != ExternalBridgeLoginIntent.FullControl)
+ {
+ ExternalBridgeClientConnectedEventArgs args = new ExternalBridgeClientConnectedEventArgs();
+ args.Request = request;
+ args.IpAddress = Adapter.Address;
+ ConnectionRequest?.Invoke(this, args);
+
+ var response = new ExternalBridgeLoginResponse();
+ response.Authenticated = args.Confirmed;
+ response.SerialNumber = Machine.SerialNumber;
+ response.DeviceInformation = MachineOperator.DeviceInformation;
+
+ IsInSession = args.Confirmed;
+
+ if (IsInSession)
{
- try
- {
- _isSignalRConnected = false;
- await _proxy.Invoke("UnregisterMachine");
- _connection.Stop();
- _connection.Dispose();
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error disposing SignalR connection.");
- }
+ LogManager.Log("External bridge client has logged-in successfully.");
+ UseKeepAlive = true;
+ MachineOperator.EnableDiagnostics = false;
+ MachineOperator.EnableEmbeddedDebugging = false;
+ SessionIntent = request.Message.Intent;
+ }
+ else
+ {
+ LogManager.Log("External bridge client login failed, invalid password.");
}
- IsStarted = false;
- HasSessions = false;
- RaisePropertyChanged(nameof(Enabled));
+ await SendResponse<ExternalBridgeLoginResponse>(response, container.Token, null, null, IsInSession ? null : "Invalid password or intent.");
+ }
+ else
+ {
+ LogManager.Log($"External bridge client login failed because the machine is currently printing and '{ExternalBridgeLoginIntent.FullControl}' intent was requested.");
+ await SendResponse<ExternalBridgeLoginResponse>(new ExternalBridgeLoginResponse(), container.Token, false, ErrorCode.GeneralError, $"Machine connection with '{ExternalBridgeLoginIntent.FullControl}' intent is not permitted while printing.");
}
}
- /// <summary>
- /// Disconnects the current remote client session.
- /// </summary>
- public async void DisconnectFullControlSession()
+ protected async virtual void OnExternalBridgeLogoutRequest(MessageContainer container)
{
- var sessionReceiver = _receivers.SingleOrDefault(x => x.IsLoggedIn && x.LoginIntent == ExternalBridgeLoginIntent.FullControl);
- if (sessionReceiver != null)
+ try
+ {
+ await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token);
+ }
+ catch (Exception ex)
{
- await sessionReceiver.Disconnect();
+ LogManager.Log(ex);
}
+ finally
+ {
+ ClearQueues();
+ }
+
+ OnClientDisconnected();
}
- #endregion
+ protected virtual void OnStartApplicationLogsRequest(MessageContainer container)
+ {
+ if (SessionIntent == ExternalBridgeLoginIntent.Diagnostics || SessionIntent == ExternalBridgeLoginIntent.FullControl)
+ {
+ _app_logs_token = container.Token;
+ _send_app_logs = true;
+ SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse(), container.Token);
+ }
+ else
+ {
+ throw new AuthenticationException("The specified intent does not grant the specified action.");
+ }
+ }
- #region Virtual Methods
+ protected virtual void OnStopApplicationLogsRequest(MessageContainer container)
+ {
+ if (SessionIntent == ExternalBridgeLoginIntent.Diagnostics || SessionIntent == ExternalBridgeLoginIntent.FullControl)
+ {
+ _send_app_logs = false;
+ SendResponse<StopApplicationLogsResponse>(new StopApplicationLogsResponse() { }, container.Token);
+ SendResponse<StartApplicationLogsResponse>(new StartApplicationLogsResponse() { }, _app_logs_token, true);
+ }
+ else
+ {
+ throw new AuthenticationException("The specified intent does not grant the specified action.");
+ }
+ }
- protected virtual void OnOperatorResponseReceived(MessageContainer container)
+ protected virtual void OnJobRequest(MessageContainer container)
{
- try
+ if (SessionIntent != ExternalBridgeLoginIntent.FullControl)
{
- switch (container.Type)
- {
- case MessageType.StartDiagnosticsResponse:
- _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresDiagnostics).ToList().ForEach(x => x.UpdateDiagnostics(container));
- break;
- case MessageType.StartDebugLogResponse:
- _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresDebugLogs).ToList().ForEach(x => x.UpdateDebugLogs(container));
- break;
- case MessageType.StartEventsNotificationResponse:
- //_receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresEventsNotification).ToList().ForEach(x => x.UpdateEvents(container));
- break;
- case MessageType.StartMachineStatusUpdateResponse:
- _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresMachineStatusUpdate).ToList().ForEach(x => x.UpdateMachineStatus(container));
- break;
- case MessageType.StartInkFillingStatusResponse:
- _receivers.ToList().Where(x => x.IsLoggedInAndRequiresDiagnostics && x.RequiresInkFillingStatus).ToList().ForEach(x => x.UpdateInkFillingStatus(container));
- break;
- }
+ throw new InvalidOperationException($"Job execution is disabled while session intent is '{SessionIntent}'.");
+ }
+ if (MachineOperator.Status != MachineStatuses.ReadyToDye)
+ {
+ throw new InvalidOperationException($"Could not execute job while machine operator status is '{MachineOperator.Status}'.");
+ }
+ else
+ {
+ OnAnyRequest(container);
}
- catch { }
}
- #endregion
+ protected virtual void OnStartEventsNotificationRequest(MessageContainer container)
+ {
+ _eventsNotificationsToken = container.Token;
+ SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), container.Token);
+ }
+
+ protected virtual void OnStopEventsNotificationRequest(MessageContainer container)
+ {
+ if (_eventsNotificationsToken != null)
+ {
+ SendResponse<StartEventsNotificationResponse>(new StartEventsNotificationResponse(), _eventsNotificationsToken, true);
+ _eventsNotificationsToken = null;
+ SendResponse<StopEventsNotificationResponse>(new StopEventsNotificationResponse(), container.Token);
+ }
+ }
- #region Handlers Registration
+ protected virtual void OnStartMachineStatusUpdateRequest(MessageContainer container)
+ {
+ _machineStatusUpdateToken = container.Token;
+ SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), container.Token);
+ }
- public void RegisterRequestHandler(IExternalBridgeRequestHandler handler)
+ protected virtual void OnStopMachineStatusUpdateRequest(MessageContainer container)
{
- foreach (var method in handler.GetType().GetMethods())
+ if (_machineStatusUpdateToken != null)
{
- var att = method.GetCustomAttribute<ExternalBridgeRequestHandlerMethodAttribute>();
- if (att != null)
- {
- _requestHandlers.Add(att.Type is IMessage ? att.Type.Name : att.Type.FullName, new RequestHandler()
- {
- Handler = handler,
- Method = method,
- LoggingMode = att.LoggingMode,
- });
- }
+ SendResponse<StartMachineStatusUpdateResponse>(new StartMachineStatusUpdateResponse(), _machineStatusUpdateToken, true);
+ _machineStatusUpdateToken = null;
+ SendResponse<StopMachineStatusUpdateResponse>(new StopMachineStatusUpdateResponse(), container.Token);
+ }
+ }
+
+ protected virtual void OnStartDiagnosticsRequest(MessageContainer container)
+ {
+ if (_diagnosticsNotificationToken == null)
+ {
+ _diagnosticsNotificationToken = container.Token;
+ _machineOperator.SendContinuousRequest(container);
}
}
- public void UnregisterRequestHandler(IExternalBridgeRequestHandler handler)
+ protected virtual void OnStartDebugLogRequest(MessageContainer container)
{
- foreach (var h in _requestHandlers.Where(x => x.Value.Handler == handler).ToList())
+ if (_debugLogsNotificationToken == null)
{
- _requestHandlers.Remove(h.Key);
+ _debugLogsNotificationToken = container.Token;
+ _machineOperator.SendContinuousRequest(container);
}
}
+ private void OnColorProfileRequest(MessageContainer container)
+ {
+ var request = MessageFactory.ParseTangoMessageFromContainer<ColorProfileRequest>(container);
+
+ ColorProfileRequestEventArgs e = new ColorProfileRequestEventArgs(request, async () =>
+ {
+ //Approved.
+ await SendResponse<ColorProfileResponse>(new ColorProfileResponse()
+ {
+ Approved = true
+ }, container.Token);
+ await Task.Delay(500);
+ await base.Disconnect();
+ },
+ async () =>
+ {
+ //Declined.
+ await SendResponse<ColorProfileResponse>(new ColorProfileResponse(), container.Token);
+ await Task.Delay(500);
+ await base.Disconnect();
+ });
+
+ ColorProfileRequest?.Invoke(this, e);
+ }
+
#endregion
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs
deleted file mode 100644
index a8f01437c..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRClient.cs
+++ /dev/null
@@ -1,124 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Security.Authentication;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.BL;
-using Tango.BL.Entities;
-using Tango.Integration.ExternalBridge.Web;
-using Tango.Integration.Operation;
-using Tango.PMR.Integration;
-using Tango.Settings;
-using Tango.Transport;
-using Tango.Transport.Adapters;
-
-namespace Tango.Integration.ExternalBridge
-{
- public class ExternalBridgeSignalRClient : ExternalBridgeTcpClient
- {
- public ExternalBridgeSignalRClient(String url, String hub, MachineInfo machineInfo)
- {
- ComponentName = $"External Bridge SignalR Client {_component_counter++}";
-
- SerialNumber = machineInfo.SerialNumber;
- IPAddress = machineInfo.IPAddress;
- Machine = ObservablesStaticCollections.Instance.Machines.SingleOrDefault(x => x.SerialNumber == SerialNumber);
- Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapterMode.CreateSession, SerialNumber, null, IPAddress);
-
- KeepAliveTimeout = TimeSpan.FromSeconds(5);
- KeepAliveRetries = 2;
- UseKeepAlive = false;
- }
-
- public ExternalBridgeSignalRClient(String url, String hub, Machine machine, MachineInfo machineInfo)
- {
- ComponentName = $"External Bridge SignalR Client {_component_counter++}";
-
- SerialNumber = machine.SerialNumber;
- IPAddress = machineInfo.IPAddress;
- Machine = machine;
- Adapter = new SignalRTransportAdapter(url, hub, SignalRTransportAdapterMode.CreateSession, SerialNumber, null, IPAddress);
-
- KeepAliveTimeout = TimeSpan.FromSeconds(5);
- KeepAliveRetries = 2;
- UseKeepAlive = false;
- }
-
- /// <summary>
- /// Connects to a remote external bridge service using the specified login.
- /// </summary>
- /// <param name="login">The login request.</param>
- /// <param name="protocol">Optional protocol configuration.</param>
- /// <returns></returns>
- /// <exception cref="AuthenticationException"></exception>
- public override async Task Connect(ExternalBridgeLoginRequest login, ConfigureProtocolRequest protocol = null)
- {
- if (State != TransportComponentState.Connected)
- {
- try
- {
- Adapter.EnableCompression = false;
- GenericProtocol = GenericMessageProtocol.Json;
-
- await Adapter.Connect();
-
- State = TransportComponentState.Connected;
- StartThreads();
-
- LogManager.Log($"{ComponentName}: External Bridge SignalR Client Connected...");
-
- TimeSpan? timeout = null;
-
- if (login.RequireSafetyLevelOperations)
- {
- timeout = TimeSpan.FromSeconds(35);
- }
-
- var response = await SendRequest<ExternalBridgeLoginRequest, ExternalBridgeLoginResponse>(login, new TransportRequestConfig() { ShouldLog = true, Timeout = timeout });
-
- if (protocol != null)
- {
- try
- {
- var configureResponse = await SendRequest<ConfigureProtocolRequest, ConfigureProtocolResponse>(protocol, new TransportRequestConfig() { ShouldLog = true });
- if (configureResponse.Message.Confirmed)
- {
- await Task.Delay(500);
- Adapter.EnableCompression = protocol.EnableCompression;
- GenericProtocol = protocol.GenericProtocol;
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, $"{ComponentName}: Could not configure remote machine protocol. Could be an old PPC version.");
- }
- }
-
- ApplicationInformation = response.Message.ApplicationInformation;
-
- SessionLogger.CreateSession();
-
- DeviceInformation = response.Message.DeviceInformation;
- if (!response.Message.Authenticated)
- {
- await Adapter.Disconnect();
- throw new AuthenticationException(response.Container.ErrorMessage);
- }
- }
- catch (Exception ex)
- {
- try
- {
- await Adapter.Disconnect();
- }
- catch { }
-
- throw ex;
- }
-
- ApplyContinuousChannelsConfiguration();
- }
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRConfiguration.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRConfiguration.cs
deleted file mode 100644
index cd511aa9b..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeSignalRConfiguration.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.Integration.ExternalBridge
-{
- public class ExternalBridgeSignalRConfiguration
- {
- public bool Enabled { get; set; }
- public String Address { get; set; }
- public String Hub { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs
index 0b2a0c608..8acff77d4 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeTcpClient.cs
@@ -14,7 +14,6 @@ using Tango.PMR;
using Tango.PMR.Common;
using Tango.PMR.Connection;
using Tango.PMR.Integration;
-using Tango.PMR.MachineStatus;
using Tango.Settings;
using Tango.Transport;
using Tango.Transport.Adapters;
@@ -31,8 +30,6 @@ namespace Tango.Integration.ExternalBridge
{
private bool _logs_sent;
- public event EventHandler<LogItemBase> ApplicationLogAvailable;
-
#region Properties
private String _serialNumber;
@@ -74,113 +71,54 @@ namespace Tango.Integration.ExternalBridge
}
}
- public bool InjectApplicationLogsToDefaultLogManager { get; set; } = true;
-
/// <summary>
/// Gets a value indicating whether this client requires authentication.
/// </summary>
public bool RequiresAuthentication => true;
- /// <summary>
- /// Gets or sets the login request message when using <see cref="Connect"/>.
- /// </summary>
- public ExternalBridgeLoginRequest LoginRequest { get; set; }
-
- /// <summary>
- /// Gets or sets the configure protocol request message when using <see cref="Connect"/>.
- /// </summary>
- public ConfigureProtocolRequest ConfigureProtocolRequest { get; set; }
-
- private ApplicationInformation _applicationInformation;
- /// <summary>
- /// Gets or sets the remote application information (PPC).
- /// </summary>
- public ApplicationInformation ApplicationInformation
- {
- get { return _applicationInformation; }
- protected set { _applicationInformation = value; RaisePropertyChangedAuto(); }
- }
-
#endregion
- /// <summary>
- /// Connects to a remote external bridge service using the specified <see cref="LoginRequest"/>.
- /// </summary>
- /// <param name="login">The login.</param>
- /// <returns></returns>
- /// <exception cref="AuthenticationException">The machine password is invalid.</exception>
public override Task Connect()
{
- if (LoginRequest == null)
- {
- throw new InvalidOperationException("No LoginRequest was not specified.");
- }
- return Connect(LoginRequest, ConfigureProtocolRequest);
+ throw new NotImplementedException("External Bridge TCP client must connect through the dedicated connect method.");
}
/// <summary>
/// Connects to a remote external bridge service using the specified login.
/// </summary>
- /// <param name="login">The login request.</param>
- /// <param name="protocol">Optional protocol configuration.</param>
+ /// <param name="login">The login.</param>
/// <returns></returns>
- /// <exception cref="AuthenticationException"></exception>
- public virtual async Task Connect(ExternalBridgeLoginRequest login, ConfigureProtocolRequest protocol = null)
+ /// <exception cref="AuthenticationException">The machine password is invalid.</exception>
+ public async Task Connect(ExternalBridgeLoginRequest login)
{
if (State != TransportComponentState.Connected)
{
try
{
- Adapter.EnableCompression = false;
- GenericProtocol = GenericMessageProtocol.Json;
-
+ Adapter = new TcpTransportAdapter(IPAddress, SettingsManager.Default.GetOrCreate<IntegrationSettings>().ExternalBridgeServicePort);
await Adapter.Connect();
State = TransportComponentState.Connected;
StartThreads();
- LogManager.Log($"{ComponentName}: External Bridge TCP Client Connected...");
+ LogManager.Log("External Bridge TCP Client Connected...");
- TimeSpan? timeout = null;
- if (login.RequireSafetyLevelOperations)
- {
- timeout = TimeSpan.FromSeconds(35);
- }
-
- var response = await SendRequest<ExternalBridgeLoginRequest, ExternalBridgeLoginResponse>(login, new TransportRequestConfig() { ShouldLog = true, Timeout = timeout });
-
- if (protocol != null)
- {
- try
- {
- var configureResponse = await SendRequest<ConfigureProtocolRequest, ConfigureProtocolResponse>(protocol, new TransportRequestConfig() { ShouldLog = true });
- if (configureResponse.Message.Confirmed)
- {
- await Task.Delay(500);
- Adapter.EnableCompression = protocol.EnableCompression;
- GenericProtocol = protocol.GenericProtocol;
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, $"{ComponentName}: Could not configure remote machine protocol. Could be an old PPC version.");
- }
- }
-
- ApplicationInformation = response.Message.ApplicationInformation;
-
- SessionLogger.CreateSession();
+ LogRequestSent(login);
+ var response = await SendRequest<ExternalBridgeLoginRequest, ExternalBridgeLoginResponse>(login);
DeviceInformation = response.Message.DeviceInformation;
if (!response.Message.Authenticated)
{
await Adapter.Disconnect();
throw new AuthenticationException(response.Container.ErrorMessage);
}
+
+ Status = MachineStatuses.ReadyToDye;
}
catch (Exception ex)
{
+ LogRequestFailed(login, ex);
try
{
await Adapter.Disconnect();
@@ -190,23 +128,15 @@ namespace Tango.Integration.ExternalBridge
throw ex;
}
- ApplyContinuousChannelsConfiguration();
+ OnEnableDiagnosticsChanged(EnableDiagnostics);
+ OnEnableEmbeddedDebuggingChanged(EnableEmbeddedDebugging);
+ OnEnableEventsNotification(EnableEventsNotification);
+ OnEnableApplicationLogsChanged(EnableApplicationLogs);
+ OnEnableMachineStatusUpdatesChanged(EnableMachineStatusUpdates);
}
}
- protected virtual void ApplyContinuousChannelsConfiguration()
- {
- OnEnableDiagnosticsChanged(EnableDiagnostics);
- OnEnableEmbeddedDebuggingChanged(EnableEmbeddedDebugging);
- OnEnableEventsNotification(EnableEventsNotification);
- OnEnableApplicationLogsChanged(EnableApplicationLogs);
- OnEnableMachineStatusUpdatesChanged(EnableMachineStatusUpdates);
- OnEnableInkFillingStatus(EnableInkFillingStatus);
- //TODO: Uncomment this only when Machine Studio enables automatic thread loading (ExternalBridgeTCPClient).
- //OnEnableAutomaticThreadLoadingChanged(EnableAutomaticThreadLoading);
- }
-
- protected async void OnEnableApplicationLogsChanged(bool value)
+ private async void OnEnableApplicationLogsChanged(bool value)
{
if (value && State == TransportComponentState.Connected && !_logs_sent)
{
@@ -215,13 +145,14 @@ namespace Tango.Integration.ExternalBridge
bool responseLogged = false;
_logs_sent = true;
- SendContinuousRequest<StartApplicationLogsRequest, StartApplicationLogsResponse>(request, new TransportContinuousRequestConfig() { ShouldLog = true }).ObserveOn(new NewThreadScheduler())
+ SendContinuousRequest<StartApplicationLogsRequest, StartApplicationLogsResponse>(request).ObserveOn(new NewThreadScheduler())
.Subscribe
(
(response) =>
{
if (!responseLogged)
{
+ LogResponseReceived(response.Message);
responseLogged = true;
}
@@ -230,11 +161,18 @@ namespace Tango.Integration.ExternalBridge
(ex) =>
{
_logs_sent = false;
+
+ if (!(ex is ContinuousResponseAbortedException))
+ {
+ LogRequestFailed(request, ex);
+ }
},
() =>
{
_logs_sent = false;
});
+
+ LogRequestSent(request);
}
else if (_logs_sent)
{
@@ -246,9 +184,14 @@ namespace Tango.Integration.ExternalBridge
try
{
- var res = await SendRequest<StopApplicationLogsRequest, StopApplicationLogsResponse>(req, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(req);
+ var res = await SendRequest<StopApplicationLogsRequest, StopApplicationLogsResponse>(req);
+ LogResponseReceived(res.Message);
+ }
+ catch (Exception ex)
+ {
+ LogRequestFailed(req, ex);
}
- catch { }
}
}
}
@@ -261,13 +204,7 @@ namespace Tango.Integration.ExternalBridge
{
LogItemBase log = LogItemBase.Deserialize(response.Message.LogItem.ToArray());
log.LogObject = "External Bridge";
-
- if (InjectApplicationLogsToDefaultLogManager)
- {
- LogManager.Log(log);
- }
-
- ApplicationLogAvailable?.Invoke(this, log);
+ LogManager.Log(log);
}
}
catch (Exception ex)
@@ -281,32 +218,27 @@ namespace Tango.Integration.ExternalBridge
if (State == TransportComponentState.Connected)
{
ExternalBridgeLogoutRequest request = new ExternalBridgeLogoutRequest();
+ LogRequestSent(request);
try
{
- var response = await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(request, new TransportRequestConfig() { ShouldLog = true });
- }
- catch { }
+ var response = await SendRequest<ExternalBridgeLogoutRequest, ExternalBridgeLogoutResponse>(request);
+ LogResponseReceived(response.Message);
- Status = MachineStatuses.Standby;
+ Status = MachineStatuses.Standby;
+ }
+ catch (Exception ex)
+ {
+ LogRequestFailed(request, ex);
+ }
}
State = TransportComponentState.Disconnected;
-
- NotifyContinuousRequestMessagesDisconnection();
-
- SessionLogger.EndSession();
-
if (Adapter != null)
{
await Adapter.Disconnect();
}
- LogManager.Log($"{ComponentName} disconnected.");
- }
-
- internal ExternalBridgeTcpClient()
- {
-
+ LogManager.Log("External Bridge TCP client disconnected.");
}
/// <summary>
@@ -316,34 +248,13 @@ namespace Tango.Integration.ExternalBridge
/// <param name="ipAddress">The machine IP address.</param>
public ExternalBridgeTcpClient(String serialNumber, String ipAddress)
{
- ComponentName = $"External Bridge TCP Client {_component_counter++}";
SerialNumber = serialNumber;
-
- if (ObservablesStaticCollections.Instance.IsInitialized)
- {
- Machine = ObservablesStaticCollections.Instance.Machines.SingleOrDefault(x => x.SerialNumber == serialNumber);
- }
- IPAddress = ipAddress;
- KeepAliveTimeout = TimeSpan.FromSeconds(5);
- KeepAliveRetries = 2;
- UseKeepAlive = false;
- EnableDiagnostics = true;
-
- Adapter = new TcpTransportAdapter(IPAddress, SettingsManager.Default.GetOrCreate<IntegrationSettings>().ExternalBridgeServicePort);
- }
-
- public ExternalBridgeTcpClient(Machine machine, String ipAddress)
- {
- ComponentName = $"External Bridge TCP Client {_component_counter++}";
- Machine = machine;
- SerialNumber = Machine.SerialNumber;
+ Machine = ObservablesStaticCollections.Instance.Machines.SingleOrDefault(x => x.SerialNumber == serialNumber);
IPAddress = ipAddress;
KeepAliveTimeout = TimeSpan.FromSeconds(5);
KeepAliveRetries = 2;
UseKeepAlive = false;
EnableDiagnostics = true;
-
- Adapter = new TcpTransportAdapter(IPAddress, SettingsManager.Default.GetOrCreate<IntegrationSettings>().ExternalBridgeServicePort);
}
/// <summary>
@@ -361,22 +272,13 @@ namespace Tango.Integration.ExternalBridge
/// Called when a new request has been received.
/// </summary>
/// <param name="request">The request.</param>
- protected async override void OnRequestReceived(RequestReceivedEventArgs e)
+ protected async override void OnRequestReceived(MessageContainer request)
{
- base.OnRequestReceived(e);
-
- var container = e.Container;
+ base.OnRequestReceived(request);
- if (container.Type == MessageType.ExternalBridgeLogoutRequest)
+ if (request.Type == MessageType.ExternalBridgeLogoutRequest)
{
- try
- {
- await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), container.Token);
- }
- catch { }
-
- await Task.Delay(2000);
-
+ await SendResponse<ExternalBridgeLogoutResponse>(new ExternalBridgeLogoutResponse(), request.Token);
try
{
State = TransportComponentState.Disconnected;
@@ -387,19 +289,10 @@ namespace Tango.Integration.ExternalBridge
LogManager.Log("External Bridge TCP client disconnected by the remote host.");
}
catch { }
-
- SessionLogger.EndSession();
SessionClosed?.Invoke(this, new EventArgs());
-
- NotifyContinuousRequestMessagesDisconnection();
}
}
- protected override void OnMachineStateChanged(MachineState state)
- {
- //Do Nothing...
- }
-
/// <summary>
/// Occurs when the remote host has closed the session.
/// </summary>
@@ -408,7 +301,7 @@ namespace Tango.Integration.ExternalBridge
/// <summary>
/// Gets the database machine associated with this client.
/// </summary>
- public Machine Machine { get; protected set; }
+ public Machine Machine { get; private set; }
/// <summary>
/// Sets the database machine.
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeUsbClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeUsbClient.cs
index d7246fe7b..0767d73d5 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeUsbClient.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/ExternalBridgeUsbClient.cs
@@ -68,11 +68,6 @@ namespace Tango.Integration.ExternalBridge
}
/// <summary>
- /// Gets or sets a value indicating whether transport compression is required by the remote machine.
- /// </summary>
- public bool CompressionEnabled { get; set; }
-
- /// <summary>
/// Connects the transport component.
/// </summary>
/// <returns></returns>
@@ -98,7 +93,6 @@ namespace Tango.Integration.ExternalBridge
/// <param name="device">The device.</param>
public ExternalBridgeUsbClient(String comPort, String device,UsbSerialBaudRates baudRate = UsbSerialBaudRates.BR_115200)
{
- ComponentName = $"External Bridge USB Client {_component_counter++}";
ComPort = comPort;
Device = device;
BaudRate = baudRate;
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs
deleted file mode 100644
index 753afc899..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeRequestHandler.cs
+++ /dev/null
@@ -1,21 +0,0 @@
-using Google.Protobuf;
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.Integration.ExternalBridge
-{
- /// <summary>
- /// Represents an <see cref="IExternalBridgeService"/> request handler.
- /// </summary>
- public interface IExternalBridgeRequestHandler
- {
- /// <summary>
- /// Called when any of the external bridge clients (receivers) has disconnected.
- /// </summary>
- /// <param name="receiver">The receiver.</param>
- void OnReceiverDisconnected(ExternalBridgeReceiver receiver);
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs
index aaf7efc2d..7d35963d4 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeSecureClient.cs
@@ -21,9 +21,8 @@ namespace Tango.Integration.ExternalBridge
/// <summary>
/// Connects to a remote external bridge service using the specified login.
/// </summary>
- /// <param name="login">The login request.</param>
- /// <param name="protocol">Optional protocol configuration.</param>
+ /// <param name="login">The login.</param>
/// <returns></returns>
- Task Connect(ExternalBridgeLoginRequest login, ConfigureProtocolRequest protocol = null);
+ Task Connect(ExternalBridgeLoginRequest login);
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
index c7d2c8d5c..c0b41fd00 100644
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
+++ b/Software/Visual_Studio/Tango.Integration/ExternalBridge/IExternalBridgeService.cs
@@ -1,7 +1,5 @@
-using Google.Protobuf;
-using System;
+using System;
using System.Collections.Generic;
-using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
@@ -9,27 +7,21 @@ using Tango.BL.Entities;
using Tango.Integration.Operation;
using Tango.PMR.Integration;
using Tango.Transport;
-using Tango.Transport.Adapters;
using Tango.Transport.Transporters;
namespace Tango.Integration.ExternalBridge
{
- public interface IExternalBridgeService
+ public interface IExternalBridgeService : ITransporter
{
/// <summary>
- /// Gets the collection of logged-in receivers.
- /// </summary>
- List<ExternalBridgeReceiver> ActiveReceivers { get; }
-
- /// <summary>
/// Occurs when a new client is waiting for authentication.
/// </summary>
event EventHandler<ExternalBridgeClientConnectedEventArgs> ConnectionRequest;
/// <summary>
- /// Occurs when the current full control session has disconnected.
+ /// Occurs when the last client has been disconnected.
/// </summary>
- event EventHandler FullControlSessionDisconnected;
+ event EventHandler ClientDisconnected;
/// <summary>
/// Occurs when the service has received a new color profile request.
@@ -47,21 +39,6 @@ namespace Tango.Integration.ExternalBridge
Machine Machine { get; set; }
/// <summary>
- /// Gets or sets the SignalR configuration.
- /// </summary>
- ExternalBridgeSignalRConfiguration SignalRConfiguration { get; set; }
-
- /// <summary>
- /// Gets the current full control session receiver.
- /// </summary>
- ExternalBridgeReceiver FullControlSessionReceiver { get; }
-
- /// <summary>
- /// Gets or sets the TCP transport adapter write mode when creating a TCP receiver.
- /// </summary>
- TcpTransportAdapterWriteMode TcpTransportAdapterWriteMode { get; set; }
-
- /// <summary>
/// Gets a value indicating whether this instance is started.
/// </summary>
bool IsStarted { get; }
@@ -72,9 +49,9 @@ namespace Tango.Integration.ExternalBridge
bool Enabled { get; set; }
/// <summary>
- /// Gets a value indicating whether there are any connected sessions.
+ /// Gets a value indicating whether a remote client is authenticated and in session.
/// </summary>
- bool HasSessions { get; }
+ bool IsInSession { get; }
/// <summary>
/// Starts this instance.
@@ -89,18 +66,11 @@ namespace Tango.Integration.ExternalBridge
/// <summary>
/// Disconnects the current remote client session.
/// </summary>
- void DisconnectFullControlSession();
-
- /// <summary>
- /// Registers the request handler.
- /// </summary>
- /// <param name="handler">The handler.</param>
- void RegisterRequestHandler(IExternalBridgeRequestHandler handler);
+ void DisconnectSession();
/// <summary>
- /// Unregisters the request handler.
+ /// Gets the current session login intent.
/// </summary>
- /// <param name="handler">The handler.</param>
- void UnregisterRequestHandler(IExternalBridgeRequestHandler handler);
+ ExternalBridgeLoginIntent SessionIntent { get; }
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/RequestHandlerLoggingMode.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/RequestHandlerLoggingMode.cs
deleted file mode 100644
index c4b07e173..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/RequestHandlerLoggingMode.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.Integration.ExternalBridge
-{
- public enum RequestHandlerLoggingMode
- {
- None,
- LogRequestName,
- LogRequestNameAndContent,
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs b/Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs
deleted file mode 100644
index cccc24c35..000000000
--- a/Software/Visual_Studio/Tango.Integration/ExternalBridge/Web/MachineInfo.cs
+++ /dev/null
@@ -1,22 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.PMR.Integration;
-using Tango.Transport;
-
-namespace Tango.Integration.ExternalBridge.Web
-{
- public class MachineInfo
- {
- public String SerialNumber { get; set; }
- public String Organization { get; set; }
- public String IPAddress { get; set; }
-
- public MachineInfo()
- {
- IPAddress = "Unknown";
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs b/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs
index 64ad60db5..bacae9324 100644
--- a/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs
+++ b/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
-using Tango.BL.Builders;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.Core;
@@ -18,8 +17,8 @@ namespace Tango.Integration.JobRuns
/// <seealso cref="Tango.Integration.JobRuns.IJobRunsLogger" />
public class BasicJobRunsLogger : ExtendedObject, IJobRunsLogger
{
+ private DateTime _start_date;
private Job _job;
- private Machine _defaultMachine;
#region Properties
@@ -36,12 +35,7 @@ namespace Tango.Integration.JobRuns
/// <summary>
/// Gets or sets the job designations of which the logger should log (supports multiple flags).
/// </summary>
- public JobDesignations JobDesignationFilter { get; set; }
-
- /// <summary>
- /// Gets or sets the job run source when logging job runs.
- /// </summary>
- public JobSource JobSource { get; set; }
+ public JobDesignations JobDesignation { get; set; }
#endregion
@@ -53,7 +47,7 @@ namespace Tango.Integration.JobRuns
/// <param name="machineOperator">The machine operator.</param>
public BasicJobRunsLogger(IMachineOperator machineOperator)
{
- JobDesignationFilter = JobDesignations.Default | JobDesignations.SampleDye | JobDesignations.FineTuning;
+ JobDesignation = JobDesignations.Default;
MachineOperator = machineOperator;
Init();
}
@@ -75,15 +69,38 @@ namespace Tango.Integration.JobRuns
MachineOperator.PrintingAborted += Machine_PrintingAborted;
MachineOperator.PrintingFailed -= Machine_PrintingFailed;
MachineOperator.PrintingFailed += Machine_PrintingFailed;
- MachineOperator.HeadCleaningEnded += MachineOperator_HeadCleaningEnded;
}
private bool ShouldLog()
{
- return IsStarted && _job != null && JobDesignationFilter.HasFlag(_job.Designation);
+ return IsStarted && _job != null && JobDesignation.HasFlag(_job.Designation);
+ }
+
+ #endregion
+
+ #region Public Methods
+
+ /// <summary>
+ /// Starts the logger.
+ /// </summary>
+ public void Start()
+ {
+ IsStarted = true;
+ }
+
+ /// <summary>
+ /// Stops the logger.
+ /// </summary>
+ public void Stop()
+ {
+ IsStarted = false;
}
- private void InsertJobRun(PrintingEventArgs e, JobRunStatus status, Exception exception)
+ #endregion
+
+ #region Event Handlers
+
+ private void Machine_PrintingFailed(object sender, PrintingFailedEventArgs e)
{
if (ShouldLog())
{
@@ -95,65 +112,15 @@ namespace Tango.Integration.JobRuns
{
using (var db = ObservablesContext.CreateDefault())
{
- JobRun run = new JobRun();
-
- run.UserGuid = _job.UserGuid;
- run.StartDate = e.StartDate;
- run.UploadingStartDate = e.UploadingStartTime;
- run.HeatingStartDate = e.HeatingStartTime;
- run.ActualStartDate = e.ActualStartTime;
- run.EndDate = DateTime.UtcNow;
- run.JobName = _job.Name;
- run.Source = JobSource;
- run.Designation = _job.Designation;
- run.JobGuid = _job.Guid;
- run.RmlGuid = _job.RmlGuid;
- run.MachineGuid = _job.MachineGuid;
- run.JobRunStatus = status;
- run.EndPosition = e.JobHandler.Status.Progress;
- //run.JobLength = _job.LengthIncludingNumberOfUnits; //Should I use this or the below ??
- run.JobLength = e.JobHandler.Status.TotalProgress;
- run.LiquidQuantities = e.LiquidQuantities;
- run.IsGradient = _job.Segments.Any(x => x.BrushStops.Count > 1);
- run.GradientResolutionCm = MachineOperator.GradientGenerationConfiguration.ResolutionCM;
- run.JobString = _job.ToJobFileWhenLoaded().ToString();
-
- //Set individual liquid quantities
-
- //Cyan
- var cyan = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Cyan);
- run.CyanQuantity = cyan != null ? cyan.Quantity : 0;
-
- //Magenta
- var magenta = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Magenta);
- run.MagentaQuantity = magenta != null ? magenta.Quantity : 0;
-
- //Yellow
- var yellow = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Yellow);
- run.YellowQuantity = yellow != null ? yellow.Quantity : 0;
-
- //Black
- var black = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Black);
- run.BlackQuantity = black != null ? black.Quantity : 0;
-
- //TI
- var ti = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.TransparentInk);
- run.TransparentQuantity = ti != null ? ti.Quantity : 0;
-
- //Lubricant
- var lubricant = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Lubricant);
- run.LubricantQuantity = lubricant != null ? lubricant.Quantity : 0;
-
- //Cleaner
- var cleaner = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Cleaner);
- run.CleanerQuantity = cleaner != null ? cleaner.Quantity : 0;
-
- if (exception != null)
+ db.JobRuns.Add(new JobRun()
{
- run.FailedMessage = exception.FlattenMessage();
- }
-
- db.JobRuns.Add(run);
+ StartDate = _start_date,
+ EndDate = DateTime.UtcNow,
+ JobGuid = _job.Guid,
+ JobRunStatus = JobRunStatus.Failed,
+ EndPosition = e.JobHandler.Status.Progress,
+ FailedMessage = e.Exception.Message,
+ });
e.Job.LastRun = DateTime.UtcNow;
_job.LastRun = DateTime.UtcNow;
@@ -170,158 +137,103 @@ namespace Tango.Integration.JobRuns
}
catch (Exception ex)
{
- LogManager.Log(ex, "Error logging the last job run to the database.");
+ LogManager.Log(ex, "Error logging the current job run to the database.");
}
});
}
}
}
- private void InsertHeadCleaningJobRun(HeadCleaningEndedEventArgs e)
+ private void Machine_PrintingAborted(object sender, PrintingEventArgs e)
{
- if (IsStarted && _defaultMachine != null)
+ if (ShouldLog())
{
- Task.Factory.StartNew(() =>
+ if (e.Job.Guid == _job.Guid)
{
- try
+ Task.Factory.StartNew(() =>
{
- using (var db = ObservablesContext.CreateDefault())
+ try
{
- JobRun run = new JobRun();
-
- run.IsHeadCleaning = true;
- run.StartDate = e.StartDate;
- run.UploadingStartDate = e.StartDate;
- run.HeatingStartDate = e.StartDate;
- run.ActualStartDate = e.StartDate;
- run.EndDate = DateTime.UtcNow;
- run.JobName = "HEAD CLEANING";
- run.Source = JobSource;
- run.MachineGuid = _defaultMachine.Guid;
- run.JobRunStatus = e.Status;
- run.EndPosition = e.EndPosition;
- run.JobLength = e.Length;
- run.LiquidQuantities = e.LiquidQuantities;
-
- //Set individual liquid quantities
-
- //Cyan
- var cyan = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Cyan);
- run.CyanQuantity = cyan != null ? cyan.Quantity : 0;
-
- //Magenta
- var magenta = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Magenta);
- run.MagentaQuantity = magenta != null ? magenta.Quantity : 0;
-
- //Yellow
- var yellow = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Yellow);
- run.YellowQuantity = yellow != null ? yellow.Quantity : 0;
-
- //Black
- var black = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Black);
- run.BlackQuantity = black != null ? black.Quantity : 0;
-
- //TI
- var ti = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.TransparentInk);
- run.TransparentQuantity = ti != null ? ti.Quantity : 0;
-
- //Lubricant
- var lubricant = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Lubricant);
- run.LubricantQuantity = lubricant != null ? lubricant.Quantity : 0;
+ using (var db = ObservablesContext.CreateDefault())
+ {
+ db.JobRuns.Add(new JobRun()
+ {
+ StartDate = _start_date,
+ EndDate = DateTime.UtcNow,
+ JobGuid = _job.Guid,
+ EndPosition = e.JobHandler.Status.Progress,
+ JobRunStatus = JobRunStatus.Aborted,
+ });
- //Cleaner
- var cleaner = run.LiquidQuantities.SingleOrDefault(x => x.LiquidType == LiquidTypes.Cleaner);
- run.CleanerQuantity = cleaner != null ? cleaner.Quantity : 0;
+ e.Job.LastRun = DateTime.UtcNow;
+ _job.LastRun = DateTime.UtcNow;
- //if (exception != null)
- //{
- // run.FailedMessage = exception.FlattenMessage();
- //}
+ var job = db.Jobs.SingleOrDefault(x => x.Guid == _job.Guid);
- db.JobRuns.Add(run);
+ if (job != null)
+ {
+ job.LastRun = DateTime.UtcNow;
+ }
- db.SaveChanges();
+ db.SaveChanges();
+ }
}
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error logging the last head cleaning job run to the database.");
- }
- });
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error logging the current job run to the database.");
+ }
+ });
+ }
}
}
- #endregion
-
- #region Public Methods
-
- /// <summary>
- /// Starts the logger.
- /// </summary>
- public void Start()
- {
- IsStarted = true;
- }
-
- /// <summary>
- /// Stops the logger.
- /// </summary>
- public void Stop()
- {
- IsStarted = false;
- }
-
- /// <summary>
- /// Sets the head cleaning parameters.
- /// </summary>
- /// <param name="machine">The machine.</param>
- public void SetDefaultMachine(Machine machine)
- {
- _defaultMachine = machine;
- }
-
- #endregion
-
- #region Event Handlers
-
- private void Machine_PrintingFailed(object sender, PrintingFailedEventArgs e)
- {
- InsertJobRun(e, JobRunStatus.Failed, e.Exception);
- }
-
- private void Machine_PrintingAborted(object sender, PrintingEventArgs e)
- {
- InsertJobRun(e, JobRunStatus.Aborted, null);
- }
-
private void Machine_PrintingCompleted(object sender, PrintingEventArgs e)
{
- InsertJobRun(e, JobRunStatus.Completed, null);
- }
-
- private async void Machine_PrintingStarted(object sender, PrintingEventArgs e)
- {
- _job = e.Job;
-
- if (e.IsResumed)
+ if (ShouldLog())
{
- try
+ if (e.Job.Guid == _job.Guid)
{
- using (ObservablesContext db = ObservablesContext.CreateDefault())
+ Task.Factory.StartNew(() =>
{
- _job = await new JobBuilder(db).Set(e.Job.Guid).WithConfiguration().WithSegments().WithBrushStops().BuildAsync();
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error loading resumed job from database.");
+ try
+ {
+ using (var db = ObservablesContext.CreateDefault())
+ {
+ db.JobRuns.Add(new JobRun()
+ {
+ StartDate = _start_date,
+ EndDate = DateTime.UtcNow,
+ JobGuid = _job.Guid,
+ EndPosition = e.JobHandler.Status.Progress,
+ JobRunStatus = JobRunStatus.Completed,
+ });
+
+ e.Job.LastRun = DateTime.UtcNow;
+ _job.LastRun = DateTime.UtcNow;
+
+ var job = db.Jobs.SingleOrDefault(x => x.Guid == _job.Guid);
+
+ if (job != null)
+ {
+ job.LastRun = DateTime.UtcNow;
+ }
+
+ db.SaveChanges();
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error logging the current job run to the database.");
+ }
+ });
}
}
}
- private void MachineOperator_HeadCleaningEnded(object sender, HeadCleaningEndedEventArgs e)
+ private void Machine_PrintingStarted(object sender, PrintingEventArgs e)
{
- InsertHeadCleaningJobRun(e);
+ _job = e.Job;
+ _start_date = DateTime.UtcNow;
}
#endregion
diff --git a/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs b/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs
index 386298bb9..8c4174311 100644
--- a/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs
+++ b/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs
@@ -3,7 +3,6 @@ using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
-using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.Integration.Operation;
@@ -22,12 +21,7 @@ namespace Tango.Integration.JobRuns
/// <summary>
/// Gets or sets the job designations of which the logger should log (supports multiple flags).
/// </summary>
- JobDesignations JobDesignationFilter { get; set; }
-
- /// <summary>
- /// Gets or sets the job run source when logging job runs.
- /// </summary>
- JobSource JobSource { get; set; }
+ JobDesignations JobDesignation { get; set; }
/// <summary>
/// Gets a value indicating whether this instance is started.
@@ -43,11 +37,5 @@ namespace Tango.Integration.JobRuns
/// Stops the logger.
/// </summary>
void Stop();
-
- /// <summary>
- /// Sets the head cleaning parameters.
- /// </summary>
- /// <param name="machine">The machine.</param>
- void SetDefaultMachine(Machine machine);
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs b/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs
index 7e3e45c54..98a3ac543 100644
--- a/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs
+++ b/Software/Visual_Studio/Tango.Integration/Logging/EmbeddedLogFileParser.cs
@@ -21,7 +21,7 @@ namespace Tango.Integration.Logging
FileLogger logger = MachineOperator.EmbeddedLogManager.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
String logFile = logger != null ? logger.LogFile : null;
- HashSet<string> dateStrings = new HashSet<string>();
+
if (Directory.Exists(MachineOperator.EmbeddedLogsFolder))
{
foreach (var file in Directory.GetFiles(MachineOperator.EmbeddedLogsFolder, "*.log").Where(x => x != logFile))
@@ -29,20 +29,8 @@ namespace Tango.Integration.Logging
try
{
String dateString = Path.GetFileNameWithoutExtension(file).Replace(MachineOperator.EmbeddedLogsTag + "-", "");
- int indexPos = dateString.IndexOf(FileLogger.FILE_SET_EXTENSION);
- int indexOfFile = 0;
- if (indexPos > 0)
- {
- string fileNameIndex = dateString.Substring(indexPos + FileLogger.FILE_SET_EXTENSION.Length);
- int.TryParse(fileNameIndex, out indexOfFile);
- dateString = dateString.Substring(0, indexPos);
- }
- if (!dateStrings.Contains(dateString))
- {
- dateStrings.Add(dateString);
- DateTime date = DateTime.ParseExact(dateString, "dd-MM-yyyy_HH-mm-ss", CultureInfo.InvariantCulture);
- logFiles.Add(new LogFile() { DateTime = date, File = file, PartOfSet = indexOfFile > 0, });
- }
+ DateTime date = DateTime.ParseExact(dateString, "dd-MM-yyyy_HH-mm-ss", CultureInfo.InvariantCulture);
+ logFiles.Add(new LogFile() { DateTime = date, File = file });
}
catch (Exception ex)
{
@@ -57,33 +45,8 @@ namespace Tango.Integration.Logging
public List<EmbeddedLogItem> Parse(LogFile logFile)
{
List<EmbeddedLogItem> logItems = new List<EmbeddedLogItem>();
- List<LogFile> logFiles = new List<LogFile>();
- FileLogger logger = LogManager.Default.RegisteredLoggers.FirstOrDefault(x => x.GetType() == typeof(FileLogger)) as FileLogger;
- if (logFile.PartOfSet)
- {
- string fileName = Path.GetFileNameWithoutExtension(logFile.File);
- string extension = Path.GetExtension(logFile.File);
- int indexPos = fileName.IndexOf(FileLogger.FILE_SET_EXTENSION);
- if (indexPos > 0)
- {
- fileName = fileName.Substring(0, indexPos);
- }
- string[] fileEntries = Directory.GetFiles(FileLogger.DefaultLogsFolder, $"{fileName}*{extension}").Where(x => Path.GetFileName(x).StartsWith(logger.Tag) && x != logger.LogFile).OrderBy(x => x).ToArray();
- foreach (var file in fileEntries)
- {
- Parse(file, logFile.DateTime, ref logItems);
- }
- }
- else
- {
- Parse(logFile.File, logFile.DateTime, ref logItems);
- }
- return logItems;
- }
- public void Parse(string file, DateTime datetime, ref List<EmbeddedLogItem> logItems)
- {
- String text = File.ReadAllText(file);
+ String text = File.ReadAllText(logFile.File);
var logs = Regex.Split(text, @"(\[\d{2}:\d{2}:\d{2}.\d{2}\])");
for (int i = 1; i < logs.Length; i += 2)
@@ -99,13 +62,13 @@ namespace Tango.Integration.Logging
{
Category = (PMR.Debugging.DebugLogCategory)Enum.Parse(typeof(PMR.Debugging.DebugLogCategory), entries[1]),
FileName = entries[3],
- LineNumber = int.Parse(entries[5]),
- ModuleId = int.Parse(entries[7]),
- Filter = int.Parse(entries[9]),
+ LineNumber = uint.Parse(entries[5]),
+ ModuleId = uint.Parse(entries[7]),
+ Filter = uint.Parse(entries[9]),
Message = new String(entries[10].Skip(2).ToArray())
});
- item.TimeStamp = new DateTime(datetime.Year, datetime.Month, datetime.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
+ item.TimeStamp = new DateTime(logFile.DateTime.Year, logFile.DateTime.Month, logFile.DateTime.Day, date.Hour, date.Minute, date.Second, date.Millisecond);
logItems.Add(item);
}
@@ -114,13 +77,8 @@ namespace Tango.Integration.Logging
LogManager.Default.Log(ex, "Could not parse log line: " + logs[i]);
}
}
- }
- public List<EmbeddedLogItem> Parse(string file, DateTime fileDate)
- {
- List<EmbeddedLogItem> logs = new List<EmbeddedLogItem>();
- Parse(file, fileDate, ref logs);
- return logs;
+ return logItems;
}
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/CachedJobOperation.cs b/Software/Visual_Studio/Tango.Integration/Operation/CachedJobOperation.cs
deleted file mode 100644
index cca0ca516..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/CachedJobOperation.cs
+++ /dev/null
@@ -1,18 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.BL.DTO;
-using Tango.PMR.MachineStatus;
-
-namespace Tango.Integration.Operation
-{
- public class CachedJobOperation
- {
- public JobDTO JobDTO { get; set; }
- public MachineStatus MachineStatus { get; set; }
- public ProcessParametersTableDTO ProcessParametersDTO { get; set; }
- public ConfigurationDTO MachineConfigurationDTO { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/DefaultGradientGenerationConfiguration.cs b/Software/Visual_Studio/Tango.Integration/Operation/DefaultGradientGenerationConfiguration.cs
index ef275479b..1f8cf6ada 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/DefaultGradientGenerationConfiguration.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/DefaultGradientGenerationConfiguration.cs
@@ -9,7 +9,6 @@ using Tango.BL.Enumerations;
using Tango.ColorConversion;
using Tango.Core;
using Tango.Core.ExtensionMethods;
-using Tango.PMR.ColorLab;
namespace Tango.Integration.Operation
{
@@ -57,8 +56,6 @@ namespace Tango.Integration.Operation
ResolutionCM = 500;
}
- #region Standard Method
-
/// <summary>
/// Creates a collection of brush stops representing the required gradient steps.
/// </summary>
@@ -69,11 +66,6 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public List<BrushStop> Generate(Segment segment, Job job, ProcessParametersTable processParameters, Action<PreparingJobProgressEventArgs> progress = null)
{
- if (processParameters.ProcessParametersTablesGroup.Rml.UseColorLibGradients)
- {
- return GenerateUsingColorLib(segment, job, processParameters, progress);
- }
-
aborted = false;
List<BrushStop> stops = new List<BrushStop>();
@@ -100,18 +92,16 @@ namespace Tango.Integration.Operation
stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
}
- if ((stop.BrushColorSpace == ColorSpaces.RGB || stop.BrushColorSpace == ColorSpaces.LAB) && !stop.IsTransparent && !stop.IsWhite)
+ if (stop.BrushColorSpace == ColorSpaces.RGB || stop.BrushColorSpace == ColorSpaces.LAB)
{
- var output = converter.Convert(stop, false);
+ var output = converter.Convert(segment.Job, stop.Color, false);
output.ApplyOnBrushStop(stop, processParameters);
}
}
var refStop = clonedStops.First().Clone(segment);
- decimal segment_length = (decimal)segment.Length;
-
- for (decimal cm = 0; cm <= segment_length; cm += (ResolutionCM / 100M))
+ for (double cm = 0; cm <= segment.Length; cm += (ResolutionCM / 100d))
{
if (aborted) return stops;
@@ -137,7 +127,7 @@ namespace Tango.Integration.Operation
{
Job = job,
Total = job.Segments.Sum(x => x.Length),
- Progress = previousSegmentsLength + (double)cm,
+ Progress = previousSegmentsLength + cm,
});
}
@@ -240,72 +230,6 @@ namespace Tango.Integration.Operation
return color;
}
- #endregion
-
- #region ColorLib Method
-
- public List<BrushStop> GenerateUsingColorLib(Segment segment, Job job, ProcessParametersTable processParameters, Action<PreparingJobProgressEventArgs> progress = null)
- {
- aborted = false;
-
- List<BrushStop> stops = segment.BrushStops.Select(x => x.Clone()).ToList();
-
- var refStop = segment.BrushStops.First().Clone(segment);
-
- IColorConverter converter = new DefaultColorConverter();
-
- foreach (var stop in stops)
- {
- if (aborted) return stops;
-
- if (stop.LiquidVolumes == null)
- {
- stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
- }
- }
-
- var conversionOutput = converter.GenerateGradient(stops, segment.Length, job.Rml, job.Machine.Configuration);
-
- List<BrushStop> newStops = new List<BrushStop>();
-
- int stopIndex = 1;
-
- foreach (var stop in conversionOutput.Stops)
- {
- var newStop = refStop.Clone(segment);
-
- newStop.OffsetPercent = stop.Offset * 100d;
- newStop.OffsetMeters = segment.Length * stop.Offset;
- newStop.StopIndex = stopIndex++;
-
- newStop.SetVolume(LiquidTypes.Cyan, GetStopVolume(stop, PMR.ColorLab.LiquidType.Cyan));
- newStop.SetVolume(LiquidTypes.Magenta, GetStopVolume(stop, PMR.ColorLab.LiquidType.Magenta));
- newStop.SetVolume(LiquidTypes.Yellow, GetStopVolume(stop, PMR.ColorLab.LiquidType.Yellow));
- newStop.SetVolume(LiquidTypes.Black, GetStopVolume(stop, PMR.ColorLab.LiquidType.Black));
-
- newStop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
-
- newStops.Add(newStop);
- }
-
- progress?.Invoke(new PreparingJobProgressEventArgs()
- {
- Job = job,
- Total = 100,
- Progress = 100,
- });
-
- return newStops;
- }
-
- private double GetStopVolume(GradientOutputStop stop, PMR.ColorLab.LiquidType liquidType)
- {
- var liquid = stop.OutputLiquids.SingleOrDefault(x => x.LiquidType == liquidType);
- return liquid != null ? liquid.Volume : 0;
- }
-
- #endregion
-
/// <summary>
/// Aborts the current generation.
/// </summary>
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/DefaultMachineEventsStateProvider.cs b/Software/Visual_Studio/Tango.Integration/Operation/DefaultMachineEventsStateProvider.cs
index 79b6e59cb..8c376ea3e 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/DefaultMachineEventsStateProvider.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/DefaultMachineEventsStateProvider.cs
@@ -16,11 +16,11 @@ namespace Tango.Integration.Operation
/// <seealso cref="Tango.Integration.Operation.IMachineEventsStateProvider" />
public class DefaultMachineEventsStateProvider : ExtendedObject, IMachineEventsStateProvider
{
- private ReadOnlyObservableCollection<MachinesEvent> _events;
+ private ReadOnlyCollection<MachinesEvent> _events;
/// <summary>
/// Gets the current machine events.
/// </summary>
- public ReadOnlyObservableCollection<MachinesEvent> Events
+ public ReadOnlyCollection<MachinesEvent> Events
{
get
{
@@ -64,7 +64,7 @@ namespace Tango.Integration.Operation
/// </summary>
public DefaultMachineEventsStateProvider()
{
- _events = new ReadOnlyObservableCollection<MachinesEvent>(new ObservableCollection<MachinesEvent>());
+ _events = new ReadOnlyCollection<MachinesEvent>(new Collection<MachinesEvent>());
}
/// <summary>
@@ -79,7 +79,7 @@ namespace Tango.Integration.Operation
List<MachinesEvent> newEvents = receivedEvents.Where(x => !_events.ToList().Exists(y => y.Type == x.Type)).ToList();
List<MachinesEvent> oldEvents = _events.Where(x => !receivedEvents.Exists(y => y.Type == x.Type)).ToList();
- _events = new ReadOnlyObservableCollection<MachinesEvent>(new ObservableCollection<MachinesEvent>(receivedEvents));
+ _events = new ReadOnlyCollection<MachinesEvent>(receivedEvents);
if (newEvents.Count > 0)
{
@@ -93,7 +93,7 @@ namespace Tango.Integration.Operation
if (newEvents.Count > 0 || oldEvents.Count > 0)
{
RaisePropertyChanged(nameof(Events));
- OnEventsChanged(_events);
+ OnEventsChanged(newEvents.Concat(oldEvents));
}
OnEventsReceived(_events);
@@ -142,7 +142,7 @@ namespace Tango.Integration.Operation
/// </summary>
public void Reset()
{
- _events = new ReadOnlyObservableCollection<MachinesEvent>(new ObservableCollection<MachinesEvent>(new List<MachinesEvent>()));
+ _events = new ReadOnlyCollection<MachinesEvent>(new List<MachinesEvent>());
RaisePropertyChanged(nameof(Events));
OnEventsChanged(new List<MachinesEvent>());
}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningEndedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningEndedEventArgs.cs
deleted file mode 100644
index 0929c1254..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningEndedEventArgs.cs
+++ /dev/null
@@ -1,24 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.BL.Enumerations;
-using Tango.BL.ValueObjects;
-
-namespace Tango.Integration.Operation
-{
- public class HeadCleaningEndedEventArgs : EventArgs
- {
- public List<JobRunLiquidQuantity> LiquidQuantities { get; set; }
- public DateTime StartDate { get; set; }
- public double EndPosition { get; set; }
- public double Length { get; set; }
- public JobRunStatus Status { get; set; }
-
- public HeadCleaningEndedEventArgs()
- {
- LiquidQuantities = new List<JobRunLiquidQuantity>();
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningHandler.cs b/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningHandler.cs
deleted file mode 100644
index d82666a60..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningHandler.cs
+++ /dev/null
@@ -1,80 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.Core;
-using Tango.PMR.Printing;
-
-namespace Tango.Integration.Operation
-{
- public class HeadCleaningHandler : ExtendedObject
- {
- private Action _abortAction;
-
- public event EventHandler<HeadCleaningStatusChangedEventArgs> StatusChanged;
- public event EventHandler<Exception> Failed;
- public event EventHandler Completed;
-
- private StartHeadCleaningResponse _status;
- public StartHeadCleaningResponse Status
- {
- get { return _status; }
- set { _status = value; RaisePropertyChangedAuto(); }
- }
-
- public HeadCleaningHandler(Action abortAction)
- {
- _abortAction = abortAction;
-
- Status = new StartHeadCleaningResponse()
- {
- Total = 100,
- Progress = 0,
- Status = "Initializing..."
- };
- }
-
- internal void RaiseStatusChanged(StartHeadCleaningResponse status)
- {
- OnStatusChanged(status);
- }
-
- internal void RaiseFailed(Exception ex)
- {
- OnFailed(ex);
- }
-
- internal void RaiseCompleted()
- {
- OnCompleted();
- }
-
- private void OnStatusChanged(StartHeadCleaningResponse status)
- {
- Status = status;
- StatusChanged?.Invoke(this, new HeadCleaningStatusChangedEventArgs()
- {
- Status = status
- });
- }
-
- private void OnCompleted()
- {
- Completed?.Invoke(this, new EventArgs());
- }
-
- private void OnFailed(Exception ex)
- {
- Failed?.Invoke(this, ex);
- }
-
- public Task Abort()
- {
- return Task.Factory.StartNew(() =>
- {
- _abortAction.Invoke();
- });
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningStatusChangedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningStatusChangedEventArgs.cs
deleted file mode 100644
index 6ec55ce21..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/HeadCleaningStatusChangedEventArgs.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.PMR.Printing;
-
-namespace Tango.Integration.Operation
-{
- public class HeadCleaningStatusChangedEventArgs : EventArgs
- {
- public StartHeadCleaningResponse Status { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/IMachineEventsStateProvider.cs b/Software/Visual_Studio/Tango.Integration/Operation/IMachineEventsStateProvider.cs
index e6084c12a..2cf00904f 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/IMachineEventsStateProvider.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/IMachineEventsStateProvider.cs
@@ -17,7 +17,7 @@ namespace Tango.Integration.Operation
/// <summary>
/// Gets the current machine events.
/// </summary>
- ReadOnlyObservableCollection<MachinesEvent> Events { get; }
+ ReadOnlyCollection<MachinesEvent> Events { get; }
/// <summary>
/// Gets or sets a value indicating whether this instance has events.
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs b/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs
index e7d3cd0e8..733f7a981 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/IMachineOperator.cs
@@ -23,9 +23,6 @@ using Tango.PMR.FirmwareUpgrade;
using Tango.Integration.JobRuns;
using Tango.Integration.Emergency;
using Tango.PMR.MachineStatus;
-using Tango.PMR.ThreadLoading;
-using Tango.PMR.Power;
-using Tango.PMR.IFS;
namespace Tango.Integration.Operation
{
@@ -51,21 +48,11 @@ namespace Tango.Integration.Operation
JobUnitsMethods JobUnitsMethod { get; set; }
/// <summary>
- /// Gets or sets the way of calculating how much liquid was spent during the job.
- /// </summary>
- JobLiquidQuantityCalculationMode JobLiquidQuantityCalculationMode { get; set; }
-
- /// <summary>
/// Gets the current machine status.
/// </summary>
MachineStatuses Status { get; }
/// <summary>
- /// Gets a value indicating whether the machine is connected and status is not disconnected.
- /// </summary>
- bool IsConnected { get; }
-
- /// <summary>
/// Gets or sets a value indicating whether to enable liquid quantity validation before starting the job.
/// The validation is done using the reported <see cref="MachineStatus"/>.
/// </summary>
@@ -77,16 +64,6 @@ namespace Tango.Integration.Operation
MachineStatus MachineStatus { get; }
/// <summary>
- /// Gets the current thread loading status.
- /// </summary>
- StartThreadLoadingResponse ThreadLoadingStatus { get; }
-
- /// <summary>
- /// Gets the ink filling status.
- /// </summary>
- InkFillingStatus InkFillingStatus { get; }
-
- /// <summary>
/// Gets or sets the firmware upgrade mode.
/// </summary>
FirmwareUpgradeModes FirmwareUpgradeMode { get; set; }
@@ -122,11 +99,6 @@ namespace Tango.Integration.Operation
bool CanPrint { get; }
/// <summary>
- /// Gets or sets the general continuous request timeout.
- /// </summary>
- TimeSpan ContinuousRequestTimeout { get; set; }
-
- /// <summary>
/// Occurs when the machine <see cref="Status"/> has changed.
/// </summary>
event EventHandler<MachineStatuses> StatusChanged;
@@ -167,94 +139,49 @@ namespace Tango.Integration.Operation
event EventHandler<ResumingJobEventArgs> ResumingJob;
/// <summary>
- /// Occurs when there is new diagnostics data available.
+ /// Occurs when a request has been sent.
/// </summary>
- event EventHandler<StartDiagnosticsResponse> DiagnosticsDataAvailable;
+ event EventHandler<IMessage> RequestSent;
/// <summary>
- /// Occurs when an events notification has been received from the embedded device.
+ /// Occurs when a request response has been received.
/// </summary>
- event EventHandler<StartEventsNotificationResponse> EventsNotification;
+ event EventHandler<IMessage> ResponseReceived;
/// <summary>
- /// Occurs when a new debug log is available.
+ /// Occurs when a response has been sent.
/// </summary>
- event EventHandler<StartDebugLogResponse> DebugLogAvailable;
+ event EventHandler<IMessage> ResponseSent;
/// <summary>
- /// Occurs when machine embedded device status has changed.
+ /// Occurs when a request has failed.
/// </summary>
- event EventHandler<MachineStatus> MachineStatusChanged;
+ event EventHandler<RequestFailedEventArgs> RequestFailed;
/// <summary>
- /// Occurs when a new cartridge validation request has been received.
- /// </summary>
- event EventHandler<CartridgeValidationEventArgs> CartridgeValidationRequestReceived;
-
- /// <summary>
- /// Occurs when the machine was connected and device has reported IsAfterReset.
- /// </summary>
- event EventHandler FirmwareStarted;
-
- /// <summary>
- /// Occurs when the power up sequence has started.
- /// </summary>
- event EventHandler<StartPowerUpResponse> PowerUpStarted;
-
- /// <summary>
- /// Occurs when the power up sequence progress has changed.
- /// </summary>
- event EventHandler<StartPowerUpResponse> PowerUpProgress;
-
- /// <summary>
- /// Occurs when power up sequence has completed successfully.
- /// </summary>
- event EventHandler<StartPowerUpResponse> PowerUpCompleted;
-
- /// <summary>
- /// Occurs when power up sequence has failed.
- /// </summary>
- event EventHandler<StartPowerUpResponse> PowerUpFailed;
-
- /// <summary>
- /// Occurs when power up sequence has ended. Could be due to no response to the request!
- /// </summary>
- event EventHandler PowerUpEnded;
-
- /// <summary>
- /// Occurs when power down has started.
- /// </summary>
- event EventHandler<PowerDownStartedEventArgs> PowerDownStarted;
-
- /// <summary>
- /// Occurs when the thread loading status has changed.
- /// </summary>
- event EventHandler<StartThreadLoadingResponse> ThreadLoadingStatusChanged;
-
- /// <summary>
- /// Occurs when a thread loading confirmation is required.
+ /// Occurs when there is new diagnostics data available.
/// </summary>
- event EventHandler<ThreadLoadingConfirmationRequiredEventArgs> ThreadLoadingConfirmationRequired;
+ event EventHandler<StartDiagnosticsResponse> DiagnosticsDataAvailable;
/// <summary>
- /// Occurs when thread loading has completed.
+ /// Occurs when an events notification has been received from the embedded device.
/// </summary>
- event EventHandler<StartThreadLoadingResponse> ThreadLoadingCompleted;
+ event EventHandler<StartEventsNotificationResponse> EventsNotification;
/// <summary>
- /// Occurs when thread loading has failed.
+ /// Occurs when a new debug log is available.
/// </summary>
- event EventHandler<StartThreadLoadingResponse> ThreadLoadingFailed;
+ event EventHandler<StartDebugLogResponse> DebugLogAvailable;
/// <summary>
- /// Occurs when a head cleaning job has ended.
+ /// Occurs when machine embedded device status has changed.
/// </summary>
- event EventHandler<HeadCleaningEndedEventArgs> HeadCleaningEnded;
+ event EventHandler<MachineStatus> MachineStatusChanged;
/// <summary>
- /// Occurs when the ink filling status has changed.
+ /// Occurs when a new cartridge validation request has been received.
/// </summary>
- event EventHandler<InkFillingStatusChangedEventArgs> InkFillingStatusChanged;
+ event EventHandler<CartridgeValidationEventArgs> CartridgeValidationRequestReceived;
/// <summary>
/// Gets or sets a value indicating whether direct the embedded device to send diagnostics messages.
@@ -282,21 +209,6 @@ namespace Tango.Integration.Operation
bool EnableMachineStatusUpdates { get; set; }
/// <summary>
- /// Gets or sets a value indicating whether to enable automatic thread loading support.
- /// </summary>
- bool EnableAutomaticThreadLoading { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether to enable the power sequence tracking.
- /// </summary>
- bool EnablePowerUpSequence { get; set; }
-
- /// <summary>
- /// Gets or sets a value indicating whether to enable the ink/waste filling status channel.
- /// </summary>
- bool EnableInkFillingStatus { get; set; }
-
- /// <summary>
/// Gets the last process parameters table sent to the embedded device.
/// </summary>
ProcessParametersTable CurrentProcessParameters { get; }
@@ -331,6 +243,15 @@ namespace Tango.Integration.Operation
Task<JobHandler> Print(Job job);
/// <summary>
+ /// Executes a print stub for emulating a full job.
+ /// The process parameters table will be calculated using color conversion gamut region.
+ /// This method cannot accept brush stops with 'Volume' as color space.
+ /// </summary>
+ /// <param name="job">The job.</param>
+ /// <returns></returns>
+ Task<JobHandler> PrintStub(Job job);
+
+ /// <summary>
/// Prints the specified job using the specified job parameters.
/// </summary>
/// <param name="job">The job.</param>
@@ -476,12 +397,6 @@ namespace Tango.Integration.Operation
Task<StubFpgaWriteRegResponse> Reset();
/// <summary>
- /// Directs the embedded device to switch to stand-by mode.
- /// </summary>
- /// <returns></returns>
- Task StandBy();
-
- /// <summary>
/// Resets the device through the DFU channel.
/// </summary>
/// <returns></returns>
@@ -491,9 +406,8 @@ namespace Tango.Integration.Operation
/// Upgrades the firmware.
/// </summary>
/// <param name="tfpStream">The TFP stream (Tango Firmware Package File).</param>
- /// <param name="isEmulated">Specify whether the connected machine is emulated and to skip the actual DFU interface.</param>
/// <returns></returns>
- Task<FirmwareUpgradeHandler> UpgradeFirmware(Stream tfpStream, bool isEmulated = false);
+ Task<FirmwareUpgradeHandler> UpgradeFirmware(Stream tfpStream);
/// <summary>
/// Directs the embedded device to validate the last uploaded firmware package.
@@ -519,43 +433,5 @@ namespace Tango.Integration.Operation
/// </summary>
/// <returns></returns>
StorageManager CreateStorageManager();
-
- /// <summary>
- /// Turns off the machine.
- /// </summary>
- /// <returns></returns>
- Task<PowerDownHandler> PowerDown();
-
- /// <summary>
- /// Starts a manual head cleaning process.
- /// </summary>
- /// <returns></returns>
- Task<HeadCleaningHandler> PerformHeadCleaning();
-
- /// <summary>
- /// Starts the automatic thread loading process.
- /// </summary>
- /// <returns></returns>
- Task StartThreadLoading();
-
- /// <summary>
- /// Continues the current thread loading.
- /// </summary>
- /// <param name="processParameters">The process parameters.</param>
- /// <returns></returns>
- Task ContinueThreadLoading(ProcessParametersTable processParameters);
-
- /// <summary>
- /// Attempts to jog the thread in order to check whether there are no thread breaking issues.
- /// </summary>
- /// <returns></returns>
- Task AttemptThreadJogging();
-
- /// <summary>
- /// Emulates a hardware event that will last for the specified timeout.
- /// </summary>
- /// <param name="ev">Type of the event.</param>
- /// <param name="timeout">The timeout.</param>
- void PushEmulatedEvent(Event ev, TimeSpan timeout);
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/InkFillingStatusChangedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/InkFillingStatusChangedEventArgs.cs
deleted file mode 100644
index e674dc777..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/InkFillingStatusChangedEventArgs.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.PMR.IFS;
-
-namespace Tango.Integration.Operation
-{
- public class InkFillingStatusChangedEventArgs : EventArgs
- {
- public InkFillingStatus Status { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/InsufficientLiquidQuantityException.cs b/Software/Visual_Studio/Tango.Integration/Operation/InsufficientLiquidQuantityException.cs
index 797d4f498..a1c18370b 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/InsufficientLiquidQuantityException.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/InsufficientLiquidQuantityException.cs
@@ -14,25 +14,11 @@ namespace Tango.Integration.Operation
public IdsPack IdsPack { get; set; }
public int Current { get; set; }
public int Required { get; set; }
- public int Maximum { get; set; }
public bool IsValid
{
get { return Current >= Required; }
}
-
- public bool IsOverMax
- {
- get { return Required > Maximum; }
- }
-
- public String Message { get; set; }
- public IDSPackLevel()
- {
- Maximum = 130000000;
- Required = 0;
- Current = 0;
- }
}
public InsufficientLiquidQuantityException(String message) : base(message)
@@ -41,7 +27,5 @@ namespace Tango.Integration.Operation
}
public List<IDSPackLevel> IdsPackLevels { get; internal set; }
-
-
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs
index fce815bc3..4b0066d7f 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs
@@ -17,15 +17,13 @@ namespace Tango.Integration.Operation
/// <seealso cref="Tango.Core.ExtendedObject" />
public class JobHandler : ExtendedObject
{
- protected Action _cancelAction;
- protected List<Segment> _effectiveSegments;
- protected String _lastStatusMessage;
- protected int _last_unit;
- protected bool _finalizing;
- protected JobHandlerModes _mode;
- protected double _last_progress;
- protected const int PROGRESS_REPORT_RANGE_METERS = 5;
- protected bool loggedContinueMessage;
+ private Action _cancelAction;
+ private List<Segment> _effectiveSegments;
+ private String _lastStatusMessage;
+ private int _last_unit;
+ private bool _finalizing;
+ private JobHandlerModes _mode;
+ private double _last_progress;
#region Events
@@ -79,40 +77,15 @@ namespace Tango.Integration.Operation
/// </summary>
public event EventHandler<SpoolChangeRequiredEventArgs> SpoolChangeRequired;
- /// <summary>
- /// Occurs when <see cref="CanCancel"/> has changed.
- /// </summary>
- public event EventHandler CanCancelChanged;
-
#endregion
#region Properties
- private JobStatus _jobStatus;
- /// <summary>
- /// Gets or sets the current job status that was used to invalidate this handler.
- /// </summary>
- public JobStatus JobStatus
- {
- get { return _jobStatus; }
- set { _jobStatus = value; RaisePropertyChangedAuto(); }
- }
-
/// <summary>
/// Gets a value indicating whether this handler job has been canceled.
/// </summary>
public bool IsCanceled { get; internal set; }
- private bool _canCancel;
- /// <summary>
- /// Gets a value indicating whether the job can be canceled.
- /// </summary>
- public bool CanCancel
- {
- get { return _canCancel; }
- internal set { _canCancel = value; RaisePropertyChangedAuto(); CanCancelChanged?.Invoke(this, new EventArgs()); }
- }
-
/// <summary>
/// Gets the process parameters.
/// </summary>
@@ -147,14 +120,14 @@ namespace Tango.Integration.Operation
/// </summary>
public JobHandler()
{
- CanCancel = true;
+
}
/// <summary>
/// Initializes a new instance of the <see cref="JobHandler"/> class.
/// </summary>
/// <param name="cancelAction">The cancel action.</param>
- public JobHandler(Action cancelAction, Job job, JobTicket jobTicket, ProcessParametersTable processParameters, JobHandlerModes mode) : this()
+ internal JobHandler(Action cancelAction, Job job, JobTicket jobTicket, ProcessParametersTable processParameters, JobHandlerModes mode) : this()
{
_mode = mode;
@@ -171,7 +144,7 @@ namespace Tango.Integration.Operation
_effectiveSegments = Job.EffectiveSegments.ToList();
- _cancelAction = () => { cancelAction(); };
+ _cancelAction = () => { IsCanceled = true; cancelAction(); };
Status = new RunningJobStatus();
@@ -205,7 +178,7 @@ namespace Tango.Integration.Operation
//Create all segments
int segment_index = 1;
- for (int j = 0; j < Math.Max(Job.NumberOfUnits, 1); j++)
+ for (int j = 0; j < Job.NumberOfUnits; j++)
{
for (int i = 0; i < _effectiveSegments.Count; i++)
{
@@ -241,7 +214,7 @@ namespace Tango.Integration.Operation
/// Raises the status received event.
/// </summary>
/// <param name="status">The status.</param>
- public void RaiseStatusReceived(JobStatus status)
+ internal void RaiseStatusReceived(JobStatus status)
{
InvalidateJobProgress(status);
}
@@ -250,11 +223,10 @@ namespace Tango.Integration.Operation
/// Raises the failed event.
/// </summary>
/// <param name="ex">The ex.</param>
- public void RaiseFailed(Exception ex)
+ internal void RaiseFailed(Exception ex)
{
- LogManager.Log($"Job failed at position {Status.Progress}/{Status.TotalProgress}...");
Status.IsFailed = true;
- RaiseStatusChanged();
+ StatusChanged?.Invoke(this, Status);
RaisePropertyChanged(nameof(Status));
Failed?.Invoke(this, ex);
Stopped?.Invoke(this, new EventArgs());
@@ -263,36 +235,13 @@ namespace Tango.Integration.Operation
/// <summary>
/// Raises the completed event.
/// </summary>
- public void RaiseCompleted()
+ internal void RaiseCompleted()
{
- //This will compensate on any missing progress from Shlomo, but also will tell the wrong progress if job is really completed with a large progress mistake.
- // Might be worth to compensate only on small drifts like the below (ProgressMinusSettingsUp)...
- //InvalidateJobProgress(new JobStatus()
- //{
- // Progress = Status.TotalProgress,
- // CurrentSegmentIndex = 0,
- //});
-
- LogManager.Log($"Job completed at position {Status.Progress}/{Status.TotalProgress}...");
-
- //If drift is smaller than 10cm auto correct it.
- if (Math.Abs(Status.TotalProgressMinusSettingUp - Status.ProgressMinusSettingUp) < 0.1)
- {
- LogManager.Log($"Job completed with a small drift in the progress minus setting up calculation. ({Status.ProgressMinusSettingUp}/{Status.TotalProgressMinusSettingUp}). Compensating...");
- Status.ProgressMinusSettingUp = Status.TotalProgressMinusSettingUp;
- }
- //If the overall progress is correct? Fix the minus setting up. There is a problem with the delta calc!
- else if (Status.Progress == Status.TotalProgress)
- {
- LogManager.Log($"Job completed with a small drift in the progress minus setting up calculation but the overall progress seems OK. ({Status.ProgressMinusSettingUp}/{Status.TotalProgressMinusSettingUp}). Compensating...");
- Status.ProgressMinusSettingUp = Status.TotalProgressMinusSettingUp;
- }
-
Status.Segments.Last().Completed = true;
Status.RemainingUnits = 0;
Status.IsFinalizing = false;
Status.IsCompleted = true;
- RaiseStatusChanged();
+ StatusChanged?.Invoke(this, Status);
RaisePropertyChanged(nameof(Status));
Completed?.Invoke(this, new EventArgs());
Stopped?.Invoke(this, new EventArgs());
@@ -301,11 +250,10 @@ namespace Tango.Integration.Operation
/// <summary>
/// Raises the canceled event.
/// </summary>
- public void RaiseCanceled()
+ internal void RaiseCanceled()
{
- LogManager.Log($"Job canceled at position {Status.Progress}/{Status.TotalProgress}...");
Status.IsCanceled = true;
- RaiseStatusChanged();
+ StatusChanged?.Invoke(this, Status);
RaisePropertyChanged(nameof(Status));
Canceled?.Invoke(this, new EventArgs());
Stopped?.Invoke(this, new EventArgs());
@@ -327,342 +275,71 @@ namespace Tango.Integration.Operation
#region Private Methods
- //protected virtual void InvalidateJobProgress(JobStatus s)
- //{
- // JobStatus = s;
- // bool invalidProgress = false;
-
- // if (_last_progress != s.Progress)
- // {
- // if (s.Progress <= PROGRESS_REPORT_RANGE_METERS || s.Progress >= Status.TotalProgress - PROGRESS_REPORT_RANGE_METERS)
- // {
- // LogManager.Log($"Updating job progress {s.Progress}/{Status.TotalProgress}...");
- // }
- // else if (!loggedContinueMessage)
- // {
- // loggedContinueMessage = true;
- // LogManager.Log($"Progress logging will continue {PROGRESS_REPORT_RANGE_METERS} meters before completion...");
- // }
- // }
-
- // if (s.Progress < 0)
- // {
- // LogManager.Log($"Invalid job progress received '{s.Progress}'.", LogCategory.Error);
- // invalidProgress = true;
- // }
-
- // if (s.Progress > Status.TotalProgress)
- // {
- // LogManager.Log($"Invalid job progress received '{s.Progress}' while total progress is '{Status.TotalProgress}'.", LogCategory.Error);
- // invalidProgress = true;
- // }
-
- // if (s.Progress < _last_progress)
- // {
- // LogManager.Log($"Invalid job progress received '{s.Progress}' while last progress was '{_last_progress}'.");
- // invalidProgress = true;
- // }
-
- // if (invalidProgress)
- // {
- // return;
- // }
-
- // _last_progress = s.Progress;
-
- // //Job Status
- // if (IsCanceled)
- // {
- // Status.IsCanceled = IsCanceled;
- // RaiseStatusChanged();
- // return;
- // }
-
- // List<Segment> unit_segments = new List<Segment>();
- // double delta = s.Progress - Status.Progress;
-
- // Status.Progress = s.Progress;
- // Status.RemainingTime = Status.TotalTime - Job.TranslateProgressToTime(Status.Progress, ProcessParameters);
- // Status.RemainingProgress = Status.TotalProgress - Status.Progress;
-
- // if (Status.SettingUpProgress < Status.SettingUpTotalProgress)
- // {
- // Status.SettingUpProgress += delta;
- // }
- // else
- // {
- // if (Status.IsSettingUp && Status.Progress > 0)
- // {
- // Status.IsSettingUp = false;
- // }
-
- // Status.ProgressMinusSettingUp += delta;
- // }
-
- // if (s.Progress < Job.LengthIncludingNumberOfUnits || _mode == JobHandlerModes.SettingUp)
- // {
- // Status.ProgressWithoutFinalization += delta;
-
- // unit_segments = _effectiveSegments.ToList();
-
- // if (Job.EnableInterSegment && Job.NumberOfUnits > 1 && Status.RemainingUnits > 1)
- // {
- // unit_segments.Add(Job.CreateInterSegment(Job.InterSegmentLength));
- // }
-
- // if (unit_segments.Count != Status.CurrentUnitSegments.Count)
- // {
- // Status.CurrentUnitSegments = unit_segments;
- // }
-
- // Status.CurrentUnitTotalProgress = Status.RemainingUnits > 1 && Job.EnableInterSegment ? Job.Length + (Job.InterSegmentLength) : Job.Length;
-
- // if (_mode == JobHandlerModes.Finalization)
- // {
- // Status.CurrentUnitProgress += delta;
- // }
- // else
- // {
- // if (!Status.IsSettingUp)
- // {
- // Status.CurrentUnitProgress += delta;
- // }
- // }
-
- // if (Status.CurrentUnitProgress >= Status.CurrentUnitTotalProgress)
- // {
- // Status.CurrentUnitProgress = 0;
- // Status.CurrentUnit++;
- // }
-
- // Status.RemainingUnits = Job.NumberOfUnits - Status.CurrentUnit;
-
- // if (s.Message != _lastStatusMessage && s.Message != String.Empty)
- // {
- // Status.Message = s.Message;
- // }
- // else
- // {
- // Status.Message = null;
- // }
-
- // _lastStatusMessage = s.Message;
-
- // RaiseStatusChanged();
-
- // //Segments Completion
-
- // if (Status.CurrentUnit > _last_unit)
- // {
- // foreach (var segment in Status.CurrentUnitSegments)
- // {
- // segment.Started = false;
- // segment.Completed = false;
- // }
-
- // if (Job.NumberOfUnits > 1)
- // {
- // RaiseUnitCompleted(_last_unit);
- // }
- // }
-
- // _last_unit = Status.CurrentUnit;
-
-
- // for (int i = 0; i < Status.CurrentUnitSegments.Count; i++)
- // {
- // Segment segment = Status.CurrentUnitSegments[i];
- // double previousSegmentsLengthWithThis = Status.CurrentUnitSegments.Take(i + 1).Sum(x => x.LengthWithFactor);
- // TimeSpan segmentsDuration = Job.TranslateProgressToTime(previousSegmentsLengthWithThis, ProcessParameters);
- // TimeSpan segmentRemainingTime = segmentsDuration - Job.TranslateProgressToTime(Status.CurrentUnitProgress, ProcessParameters);
-
- // if (i == 0 && Status.CurrentUnitProgress > 0)
- // {
- // if (!segment.Started)
- // {
- // segment.Started = true;
- // RaiseSegmentStarted(segment);
- // }
- // }
-
- // if (Status.CurrentUnitProgress >= previousSegmentsLengthWithThis)
- // {
- // if (!segment.Completed)
- // {
- // segment.Completed = true;
- // RaiseSegmentCompleted(segment);
- // }
-
- // if (i < Status.CurrentUnitSegments.Count - 1)
- // {
- // if (!Status.CurrentUnitSegments[i + 1].Started)
- // {
- // Status.CurrentUnitSegments[i + 1].Started = true;
- // RaiseSegmentStarted(Status.CurrentUnitSegments[i + 1]);
- // }
- // }
- // }
-
- // if (segment.Started && !segment.Completed)
- // {
- // segment.RemainingTime = segmentRemainingTime;
- // }
- // }
-
-
- // //Set Segment Completion for All Segments List
- // for (int i = 0; i < Status.Segments.Count; i++)
- // {
- // Segment segment = Status.Segments[i];
- // double previousSegmentsLengthWithThis = Status.Segments.Take(i + 1).Sum(x => x.LengthWithFactor);
- // TimeSpan segmentsDuration = Job.TranslateProgressToTime(previousSegmentsLengthWithThis, ProcessParameters);
- // TimeSpan segmentRemainingTime = segmentsDuration - Job.TranslateProgressToTime(Status.Progress, ProcessParameters);
-
- // segment.Progress = Math.Min(Math.Max((previousSegmentsLengthWithThis - segment.Length - Status.Progress) * -1, 0), segment.Length);
-
- // if (i == 0 && Status.Progress > 0)
- // {
- // if (!segment.Started)
- // {
- // segment.Started = true;
- // Status.CurrentSegment = segment;
- // }
- // }
-
- // if (Status.Progress >= previousSegmentsLengthWithThis)
- // {
- // if (!segment.Completed)
- // {
- // segment.Completed = true;
- // }
-
- // if (i < Status.Segments.Count - 1)
- // {
- // if (!Status.Segments[i + 1].Started)
- // {
- // Status.Segments[i + 1].Started = true;
- // Status.CurrentSegment = Status.Segments[i + 1];
- // }
- // }
- // }
-
- // if (segment.Started && !segment.Completed)
- // {
- // segment.RemainingTime = segmentRemainingTime;
- // }
- // }
- // }
- // else
- // {
- // //Finalizing
- // if (!_finalizing)
- // {
- // _finalizing = true;
- // Status.IsFinalizing = true;
- // var last_Segment = _effectiveSegments.Last().Clone();
- // last_Segment.Length = ProcessParameters.DryerBufferLengthMeters;
- // Status.CurrentUnitSegments = new List<Segment> { last_Segment };
- // Status.CurrentUnitTotalProgress = last_Segment.Length;
- // Status.CurrentUnitProgress = 0;
- // Status.ProgressWithoutFinalization = Status.TotalProgressWithoutFinalization;
- // RaiseFinalizing();
- // }
-
- // Status.CurrentUnitProgress += delta;
- // Status.FinalizingProgress += delta;
- // }
- //}
-
- protected virtual void InvalidateJobProgress(JobStatus s)
+ private void InvalidateJobProgress(JobStatus s)
{
- JobStatus = s;
+ bool invalidProgress = false;
- if (_last_progress != s.Progress)
- {
- if (s.Progress <= PROGRESS_REPORT_RANGE_METERS || s.Progress >= Status.TotalProgress - PROGRESS_REPORT_RANGE_METERS)
- {
- LogManager.Log($"Updating job progress {s.Progress}/{Status.TotalProgress}...");
- }
- else if (!loggedContinueMessage)
- {
- loggedContinueMessage = true;
- LogManager.Log($"Progress logging will continue {PROGRESS_REPORT_RANGE_METERS} meters before completion...");
- }
- }
+ LogManager.Log($"Updating job progress {s.Progress}/{Status.TotalProgress}...");
if (s.Progress < 0)
{
LogManager.Log($"Invalid job progress received '{s.Progress}'.", LogCategory.Error);
- return;
+ invalidProgress = true;
}
if (s.Progress > Status.TotalProgress)
{
LogManager.Log($"Invalid job progress received '{s.Progress}' while total progress is '{Status.TotalProgress}'.", LogCategory.Error);
- return;
+ invalidProgress = true;
}
if (s.Progress < _last_progress)
{
LogManager.Log($"Invalid job progress received '{s.Progress}' while last progress was '{_last_progress}'.");
+ invalidProgress = true;
+ }
+
+ if (invalidProgress)
+ {
+ return;
}
_last_progress = s.Progress;
+ //Job Status
+ if (IsCanceled)
+ {
+ Status.IsCanceled = IsCanceled;
+ StatusChanged?.Invoke(this, Status);
+ return;
+ }
+
List<Segment> unit_segments = new List<Segment>();
+ double delta = s.Progress - Status.Progress;
Status.Progress = s.Progress;
Status.RemainingTime = Status.TotalTime - Job.TranslateProgressToTime(Status.Progress, ProcessParameters);
Status.RemainingProgress = Status.TotalProgress - Status.Progress;
- if (s.Progress < Status.SettingUpTotalProgress || Status.SettingUpProgress < Status.SettingUpTotalProgress)
+ if (Status.SettingUpProgress < Status.SettingUpTotalProgress)
{
- Status.SettingUpProgress = Math.Min(s.Progress, this.Status.SettingUpTotalProgress);
- Status.IsSettingUp = true;
+ Status.SettingUpProgress += delta;
}
- if (s.Progress >= Status.SettingUpTotalProgress)
+ else
{
if (Status.IsSettingUp && Status.Progress > 0)
{
Status.IsSettingUp = false;
}
- Status.ProgressMinusSettingUp = s.Progress - this.Status.SettingUpTotalProgress;
+ Status.ProgressMinusSettingUp += delta;
}
- int units = (int)Math.Max(Job.NumberOfUnits, 1);
-
if (s.Progress < Job.LengthIncludingNumberOfUnits || _mode == JobHandlerModes.SettingUp)
{
- Status.ProgressWithoutFinalization = s.Progress;
+ Status.ProgressWithoutFinalization += delta;
unit_segments = _effectiveSegments.ToList();
- Status.CurrentUnitProgress = 0.0;
- double previousUnitsLengthWithoutThis = 0.0;
- for (int index = 0; index < units; ++index)
- {
- Status.CurrentUnit = index;
- double unitLength = !Job.EnableInterSegment || index >= units - 1 ? Job.Length : Job.Length + Job.InterSegmentLength;
- if (_mode == JobHandlerModes.Finalization)
- {
- if (s.Progress < unitLength + previousUnitsLengthWithoutThis)
- {
- Status.CurrentUnitProgress = s.Progress - previousUnitsLengthWithoutThis;
- break;
- }
- }
- else if (s.Progress <= previousUnitsLengthWithoutThis + unitLength + Status.SettingUpProgress)
- {
- if (!Status.IsSettingUp)
- {
- Status.CurrentUnitProgress = s.Progress - previousUnitsLengthWithoutThis - this.Status.SettingUpProgress;
- break;
- }
- break;
- }
- previousUnitsLengthWithoutThis += unitLength;
- }
- Status.RemainingUnits = this.Job.NumberOfUnits - this.Status.CurrentUnit;
if (Job.EnableInterSegment && Job.NumberOfUnits > 1 && Status.RemainingUnits > 1)
{
@@ -676,6 +353,26 @@ namespace Tango.Integration.Operation
Status.CurrentUnitTotalProgress = Status.RemainingUnits > 1 && Job.EnableInterSegment ? Job.Length + (Job.InterSegmentLength) : Job.Length;
+ if (_mode == JobHandlerModes.Finalization)
+ {
+ Status.CurrentUnitProgress += delta;
+ }
+ else
+ {
+ if (!Status.IsSettingUp)
+ {
+ Status.CurrentUnitProgress += delta;
+ }
+ }
+
+ if (Status.CurrentUnitProgress >= Status.CurrentUnitTotalProgress)
+ {
+ Status.CurrentUnitProgress = 0;
+ Status.CurrentUnit++;
+ }
+
+ Status.RemainingUnits = Job.NumberOfUnits - Status.CurrentUnit;
+
if (s.Message != _lastStatusMessage && s.Message != String.Empty)
{
Status.Message = s.Message;
@@ -687,10 +384,10 @@ namespace Tango.Integration.Operation
_lastStatusMessage = s.Message;
-
- RaiseStatusChanged();
+ StatusChanged?.Invoke(this, Status);
//Segments Completion
+
if (Status.CurrentUnit > _last_unit)
{
foreach (var segment in Status.CurrentUnitSegments)
@@ -701,7 +398,7 @@ namespace Tango.Integration.Operation
if (Job.NumberOfUnits > 1)
{
- RaiseUnitCompleted(_last_unit);
+ UnitCompleted?.Invoke(this, _last_unit);
}
}
@@ -720,7 +417,7 @@ namespace Tango.Integration.Operation
if (!segment.Started)
{
segment.Started = true;
- RaiseSegmentStarted(segment);
+ SegmentStarted?.Invoke(this, segment);
}
}
@@ -729,7 +426,7 @@ namespace Tango.Integration.Operation
if (!segment.Completed)
{
segment.Completed = true;
- RaiseSegmentCompleted(segment);
+ SegmentCompleted?.Invoke(this, segment);
}
if (i < Status.CurrentUnitSegments.Count - 1)
@@ -737,7 +434,7 @@ namespace Tango.Integration.Operation
if (!Status.CurrentUnitSegments[i + 1].Started)
{
Status.CurrentUnitSegments[i + 1].Started = true;
- RaiseSegmentStarted(Status.CurrentUnitSegments[i + 1]);
+ SegmentStarted?.Invoke(this, Status.CurrentUnitSegments[i + 1]);
}
}
}
@@ -748,6 +445,7 @@ namespace Tango.Integration.Operation
}
}
+
//Set Segment Completion for All Segments List
for (int i = 0; i < Status.Segments.Count; i++)
{
@@ -803,60 +501,12 @@ namespace Tango.Integration.Operation
Status.CurrentUnitTotalProgress = last_Segment.Length;
Status.CurrentUnitProgress = 0;
Status.ProgressWithoutFinalization = Status.TotalProgressWithoutFinalization;
- RaiseFinalizing();
+ Finalizing?.Invoke(this, new EventArgs());
}
- Status.CurrentUnitProgress = s.Progress - Job.LengthIncludingNumberOfUnits;
- Status.FinalizingProgress = s.Progress - Status.TotalProgressWithoutFinalization;
- }
- }
-
- #endregion
-
- #region Protected Methods
-
- protected void RaiseStatusChanged()
- {
- StatusChanged?.Invoke(this, Status);
- }
-
- protected void RaiseSegmentStarted(Segment segment)
- {
- if (segment.IsInterSegment)
- {
- LogManager.Log($"Inter Segment started.");
- }
- else
- {
- LogManager.Log($"Segment {segment.SegmentIndex} of unit {Status.CurrentUnit + 1} started...");
- }
-
- SegmentStarted?.Invoke(this, segment);
- }
-
- protected void RaiseSegmentCompleted(Segment segment)
- {
- if (segment.IsInterSegment)
- {
- LogManager.Log($"Inter Segment completed.");
+ Status.CurrentUnitProgress += delta;
+ Status.FinalizingProgress += delta;
}
- else
- {
- LogManager.Log($"Segment {segment.SegmentIndex} of unit {Status.CurrentUnit + 1} completed.");
- }
- SegmentCompleted?.Invoke(this, segment);
- }
-
- protected void RaiseUnitCompleted(int unit)
- {
- LogManager.Log($"Unit {unit + 1} completed...");
- UnitCompleted?.Invoke(this, unit);
- }
-
- protected void RaiseFinalizing()
- {
- LogManager.Log($"Finalizing...");
- Finalizing?.Invoke(this, new EventArgs());
}
#endregion
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/JobLiquidQuantityCalculationMode.cs b/Software/Visual_Studio/Tango.Integration/Operation/JobLiquidQuantityCalculationMode.cs
deleted file mode 100644
index 0c2cc1bb3..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/JobLiquidQuantityCalculationMode.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.Integration.Operation
-{
- /// <summary>
- /// Represents a machine operator liquid quantity calculation mode which will determine the amount of liquid spent when job has stopped.
- /// </summary>
- public enum JobLiquidQuantityCalculationMode
- {
- /// <summary>
- /// Calculates the liquid quantities using the <see cref="PMR.MachineStatus.MachineStatus.IDSPacksLevels"/> before and after job run.
- /// </summary>
- MachineStatus,
- /// <summary>
- /// Calculates the liquid quantities using the job details, stop position and an integral.
- /// </summary>
- Integral
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs
index bce386bfe..180db3b1d 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs
@@ -40,11 +40,6 @@ using Tango.Integration.Emergency;
using Tango.PMR.MachineStatus;
using Newtonsoft.Json;
using Tango.PMR.Integration;
-using System.Globalization;
-using Tango.PMR.Power;
-using Tango.PMR.ThreadLoading;
-using Tango.BL.DTO;
-using Tango.PMR.IFS;
namespace Tango.Integration.Operation
{
@@ -58,39 +53,17 @@ namespace Tango.Integration.Operation
public const String FIRMWARE_UPGRADE_FOLDER_NAME = "UpgradePackage";
public const String FIRMWARE_UPGRADE_CONFIG_FILE_NAME = "package.cfg";
public const String JOB_DESCRIPTION_FILE_NAME = "job_segments.jdf";
-
public const int MAX_DISPENSER_NANOLITER = 130000000;
- public const double MAX_MIDTANK_LITERS = 1.8;
- public const double EMPTY_MIDTANK_LITERS = 0.2;
- public const double LOW_MIDTANK_LITERS = 0.3;
- public const double OVERALL_TEMPERATURE_OK = 35;
- public const double OVERALL_TEMPERATURE_WARNING = 35;
- public const double OVERALL_TEMPERATURE_ERROR = 40;
private bool _diagnosticsSent;
private bool _eventsSent;
private bool _debugSent;
private bool _machineStatusSent;
- private bool _inkFillingStatusSent;
- private bool _threadLoadingSent;
+ private EmbeddedLogItem _last_embedded_debug_log;
private static RunningJobStatus _last_job_status;
- private bool _isPowerDownRequestInProgress;
- private bool _isHeadCleaningInProgress;
- private List<BL.ValueObjects.JobRunLiquidQuantity> _lastJobLiquidQuantities;
- private DateTime _diagnosticsTime;
- private MachineStatus _machineStatusBeforeJobStart;
- private Configuration _machineConfiguration;
-
- private DateTime _jobStartDate;
- private DateTime? _jobUploadingStartDate;
- private DateTime? _jobHeatingStartDate;
- private DateTime? _jobActualStartDate;
- private List<Event> _emulatedEvents;
public static String EmbeddedLogsFolder { get; private set; }
public static String EmbeddedLogsTag { get; private set; }
- public static SessionFileLogger SessionLogger { get; set; }
- public static String CachedJobOperationFile { get; set; }
#region Constructors
@@ -109,15 +82,6 @@ namespace Tango.Integration.Operation
FileLogger fileLogger = new FileLogger(EmbeddedLogsFolder, EmbeddedLogsTag) { Enabled = true };
EmbeddedLogManager.RegisterLogger(fileLogger);
}
-
- if (SessionLogger == null)
- {
- SessionLogger = new SessionFileLogger();
- LogManager.Default.RegisterLogger(SessionLogger);
- }
-
-
- CachedJobOperationFile = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.ApplicationData), "Twine", "Tango", "Job Resume", Path.GetFileNameWithoutExtension(AppDomain.CurrentDomain.FriendlyName), "CachedJobOperation.cache");
}
/// <summary>
@@ -125,15 +89,12 @@ namespace Tango.Integration.Operation
/// </summary>
public MachineOperator() : base()
{
- _emulatedEvents = new List<Event>();
- ComponentName = $"Machine Operator {_component_counter++}";
DeviceInformation = new DeviceInformation();
MachineEventsStateProvider = new DefaultMachineEventsStateProvider();
JobRunsLogger = new BasicJobRunsLogger(this);
JobRunsLogger.Start();
EnableEventsNotification = true;
EnableMachineStatusUpdates = true;
- EnableInkFillingStatus = true;
EnableJobResume = true;
LogEmbeddedDebuggingToFile = true;
FirmwareUpgradeMode = FirmwareUpgradeModes.DFU | FirmwareUpgradeModes.TFP_PACKAGE;
@@ -141,8 +102,6 @@ namespace Tango.Integration.Operation
EmergencyNotificationProvider = new UsbEmergencyNotificationProvider("COM1");
EnableJobLiquidQuantityValidation = true;
FailsWithAdapter = true;
- ContinuousRequestTimeout = TimeSpan.FromSeconds(2);
- ResetInkFllingStatus();
}
/// <summary>
@@ -189,6 +148,26 @@ namespace Tango.Integration.Operation
public event EventHandler<CartridgeValidationEventArgs> CartridgeValidationRequestReceived;
/// <summary>
+ /// Occurs when a request has been sent.
+ /// </summary>
+ public event EventHandler<IMessage> RequestSent;
+
+ /// <summary>
+ /// Occurs when a response has been sent.
+ /// </summary>
+ public event EventHandler<IMessage> ResponseSent;
+
+ /// <summary>
+ /// Occurs when a request has timed out.
+ /// </summary>
+ public event EventHandler<RequestFailedEventArgs> RequestFailed;
+
+ /// <summary>
+ /// Occurs when a request response has been received.
+ /// </summary>
+ public event EventHandler<IMessage> ResponseReceived;
+
+ /// <summary>
/// Reports about the job printing preparation progress.
/// </summary>
public event EventHandler<PreparingJobProgressEventArgs> PreparingJobProgress;
@@ -223,89 +202,11 @@ namespace Tango.Integration.Operation
/// </summary>
public event EventHandler<ResumingJobEventArgs> ResumingJob;
- /// <summary>
- /// Occurs when the machine was connected and device has reported IsAfterReset.
- /// </summary>
- public event EventHandler FirmwareStarted;
-
- /// <summary>
- /// Occurs when power down has started.
- /// </summary>
- public event EventHandler<PowerDownStartedEventArgs> PowerDownStarted;
-
- /// <summary>
- /// Occurs when the thread loading status has changed.
- /// </summary>
- public event EventHandler<StartThreadLoadingResponse> ThreadLoadingStatusChanged;
-
- /// <summary>
- /// Occurs when a thread loading confirmation is required.
- /// </summary>
- public event EventHandler<ThreadLoadingConfirmationRequiredEventArgs> ThreadLoadingConfirmationRequired;
-
- /// <summary>
- /// Occurs when thread loading has completed.
- /// </summary>
- public event EventHandler<StartThreadLoadingResponse> ThreadLoadingCompleted;
-
- /// <summary>
- /// Occurs when thread loading has failed.
- /// </summary>
- public event EventHandler<StartThreadLoadingResponse> ThreadLoadingFailed;
-
- /// <summary>
- /// Occurs when the power up sequence has started.
- /// </summary>
- public event EventHandler<StartPowerUpResponse> PowerUpStarted;
-
- /// <summary>
- /// Occurs when the power up sequence progress has changed.
- /// </summary>
- public event EventHandler<StartPowerUpResponse> PowerUpProgress;
-
- /// <summary>
- /// Occurs when power up sequence has completed successfully.
- /// </summary>
- public event EventHandler<StartPowerUpResponse> PowerUpCompleted;
-
- /// <summary>
- /// Occurs when power up sequence has failed.
- /// </summary>
- public event EventHandler<StartPowerUpResponse> PowerUpFailed;
-
- /// <summary>
- /// Occurs when power up sequence has ended. Could be due to no response to the request!
- /// </summary>
- public event EventHandler PowerUpEnded;
-
- /// <summary>
- /// Occurs when a head cleaning job has ended.
- /// </summary>
- public event EventHandler<HeadCleaningEndedEventArgs> HeadCleaningEnded;
-
- /// <summary>
- /// Occurs when the ink filling status has changed.
- /// </summary>
- public event EventHandler<InkFillingStatusChangedEventArgs> InkFillingStatusChanged;
-
#endregion
#region Properties
/// <summary>
- /// Gets or sets a value indicating whether to create a new designated session log file each successful connection.
- /// This log file will contain standard logs that have occurred between the last connection and disconnection states.
- /// </summary>
- public static bool EnableSessionLogFile
- {
- get { return SessionLogger.Enabled; }
- set
- {
- SessionLogger.Enabled = value;
- }
- }
-
- /// <summary>
/// Gets or sets the job handling mode.
/// </summary>
public JobHandlerModes JobHandlingMode { get; set; }
@@ -320,11 +221,6 @@ namespace Tango.Integration.Operation
/// </summary>
public JobUnitsMethods JobUnitsMethod { get; set; }
- /// <summary>
- /// Gets or sets the way of calculating how much liquid was spent during the job.
- /// </summary>
- public JobLiquidQuantityCalculationMode JobLiquidQuantityCalculationMode { get; set; }
-
private MachineStatuses _status;
/// <summary>
/// Gets the current machine status.
@@ -341,20 +237,11 @@ namespace Tango.Integration.Operation
OnStatusChanged(value);
RaisePropertyChanged(nameof(IsPrinting));
RaisePropertyChanged(nameof(CanPrint));
- RaisePropertyChanged(nameof(IsConnected));
LogManager.Log("Machine operator status changed: " + _status);
}
}
}
- /// <summary>
- /// Gets a value indicating whether the machine is connected and status is not disconnected.
- /// </summary>
- public bool IsConnected
- {
- get { return State == TransportComponentState.Connected && Status != MachineStatuses.Disconnected; }
- }
-
private MachineStatus _machineStatus;
/// <summary>
/// Gets the machine embedded device status.
@@ -362,27 +249,7 @@ namespace Tango.Integration.Operation
public MachineStatus MachineStatus
{
get { return _machineStatus; }
- private set { _machineStatus = value; RaisePropertyChangedAuto(); }
- }
-
- private InkFillingStatus _inkFillingStatus;
- /// <summary>
- /// Gets or sets the ink filling status.
- /// </summary>
- public InkFillingStatus InkFillingStatus
- {
- get { return _inkFillingStatus; }
- private set { _inkFillingStatus = value; RaisePropertyChangedAuto(); }
- }
-
- private StartThreadLoadingResponse _threadLoadingStatus;
- /// <summary>
- /// Gets the current thread loading status.
- /// </summary>
- public StartThreadLoadingResponse ThreadLoadingStatus
- {
- get { return _threadLoadingStatus; }
- private set { _threadLoadingStatus = value; RaisePropertyChangedAuto(); }
+ set { _machineStatus = value; RaisePropertyChangedAuto(); }
}
/// <summary>
@@ -414,7 +281,7 @@ namespace Tango.Integration.Operation
{
get
{
- return Status == MachineStatuses.ReadyToDye || Status == MachineStatuses.PowerUp || Status == MachineStatuses.Standby;
+ return Status == MachineStatuses.ReadyToDye;
}
}
@@ -520,36 +387,6 @@ namespace Tango.Integration.Operation
}
}
- private bool _enableInkFillingStatus;
- public bool EnableInkFillingStatus
- {
- get { return _enableInkFillingStatus; }
- set
- {
- if (_enableInkFillingStatus != value)
- {
- _enableInkFillingStatus = value;
- RaisePropertyChangedAuto();
- OnEnableInkFillingStatus(value);
- }
- }
- }
-
- private bool _enableAutomaticThreadLoading;
- /// <summary>
- /// Gets or sets a value indicating whether to enable automatic thread loading support.
- /// </summary>
- public bool EnableAutomaticThreadLoading
- {
- get { return _enableAutomaticThreadLoading; }
- set
- {
- _enableAutomaticThreadLoading = value;
- RaisePropertyChangedAuto();
- OnEnableAutomaticThreadLoadingChanged(value);
- }
- }
-
private bool _enableJobResume;
/// <summary>
/// Gets or sets a value indicating whether to check whether a job is in progress after connection was successful.
@@ -579,16 +416,6 @@ namespace Tango.Integration.Operation
}
}
- private bool _enablePowerUpSequence;
- /// <summary>
- /// Gets or sets a value indicating whether to enable the power sequence tracking.
- /// </summary>
- public bool EnablePowerUpSequence
- {
- get { return _enablePowerUpSequence; }
- set { _enablePowerUpSequence = value; RaisePropertyChangedAuto(); }
- }
-
/// <summary>
/// Gets or sets the machine events state provider used to get notifications about current machine events and errors.
/// </summary>
@@ -634,11 +461,6 @@ namespace Tango.Integration.Operation
/// </summary>
public IEmergencyNotificationProvider EmergencyNotificationProvider { get; set; }
- /// <summary>
- /// Gets or sets the general continuous request timeout.
- /// </summary>
- public TimeSpan ContinuousRequestTimeout { get; set; }
-
#endregion
#region Virtual Methods
@@ -656,34 +478,33 @@ namespace Tango.Integration.Operation
bool responseLogged = false;
_diagnosticsSent = true;
- LogManager.Log($"Sending '{nameof(StartDiagnosticsRequest)}'...");
-
- SendContinuousRequest<StartDiagnosticsRequest, StartDiagnosticsResponse>(request, new TransportContinuousRequestConfig() { ShouldLog = false }).ObserveOn(new NewThreadScheduler()).Subscribe(
+ SendContinuousRequest<StartDiagnosticsRequest, StartDiagnosticsResponse>(request).ObserveOn(new NewThreadScheduler()).Subscribe(
(response) =>
{
+ OnDiagnosticsDataAvailable(response);
+
if (!responseLogged)
{
- _diagnosticsTime = DateTime.Now;
+ LogResponseReceived(response.Message);
responseLogged = true;
}
- else
- {
- _diagnosticsTime = _diagnosticsTime.Add(TimeSpan.FromMilliseconds(response.Message.ElapsedMilli));
- }
-
- response.Message.DateTime = _diagnosticsTime.ToString("MM/dd/yyyy HH:mm:ss.fff");
-
- OnDiagnosticsDataAvailable(response);
},
(ex) =>
{
_diagnosticsSent = false;
+
+ if (!(ex is ContinuousResponseAbortedException))
+ {
+ LogRequestFailed(request, ex);
+ }
},
() =>
{
_diagnosticsSent = false;
LogManager.Log("Diagnostics response completed!?", LogCategory.Warning);
});
+
+ LogRequestSent(request);
}
else if (_diagnosticsSent)
{
@@ -695,9 +516,14 @@ namespace Tango.Integration.Operation
try
{
- var res = await SendRequest<StopDiagnosticsRequest, StopDiagnosticsResponse>(req, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(req);
+ var res = await SendRequest<StopDiagnosticsRequest, StopDiagnosticsResponse>(req);
+ LogResponseReceived(res.Message);
+ }
+ catch (Exception ex)
+ {
+ LogRequestFailed(req, ex);
}
- catch { }
}
}
}
@@ -715,25 +541,33 @@ namespace Tango.Integration.Operation
bool responseLogged = false;
_eventsSent = true;
- SendContinuousRequest<StartEventsNotificationRequest, StartEventsNotificationResponse>(request, new TransportContinuousRequestConfig() { ShouldLog = true }).ObserveOn(new NewThreadScheduler()).Subscribe(
+ SendContinuousRequest<StartEventsNotificationRequest, StartEventsNotificationResponse>(request).ObserveOn(new NewThreadScheduler()).Subscribe(
(response) =>
{
OnEventsNotification(response);
if (!responseLogged)
{
+ LogResponseReceived(response.Message);
responseLogged = true;
}
},
(ex) =>
{
_eventsSent = false;
+
+ if (!(ex is ContinuousResponseAbortedException))
+ {
+ LogRequestFailed(request, ex);
+ }
},
() =>
{
_eventsSent = false;
LogManager.Log("Events Notification response completed!?", LogCategory.Warning);
});
+
+ LogRequestSent(request);
}
else if (_eventsSent)
{
@@ -745,9 +579,14 @@ namespace Tango.Integration.Operation
try
{
- var res = await SendRequest<StopEventsNotificationRequest, StopEventsNotificationResponse>(req, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(req);
+ var res = await SendRequest<StopEventsNotificationRequest, StopEventsNotificationResponse>(req);
+ LogResponseReceived(res.Message);
+ }
+ catch (Exception ex)
+ {
+ LogRequestFailed(req, ex);
}
- catch { }
}
}
}
@@ -765,13 +604,14 @@ namespace Tango.Integration.Operation
bool responseLogged = false;
_debugSent = true;
- SendContinuousRequest<StartDebugLogRequest, StartDebugLogResponse>(request, new TransportContinuousRequestConfig() { ShouldLog = true }).ObserveOn(new NewThreadScheduler())
+ SendContinuousRequest<StartDebugLogRequest, StartDebugLogResponse>(request).ObserveOn(new NewThreadScheduler())
.Subscribe
(
(response) =>
{
if (!responseLogged)
{
+ LogResponseReceived(response.Message);
responseLogged = true;
}
@@ -780,11 +620,18 @@ namespace Tango.Integration.Operation
(ex) =>
{
_debugSent = false;
+
+ if (!(ex is ContinuousResponseAbortedException))
+ {
+ LogRequestFailed(request, ex);
+ }
},
() =>
{
_debugSent = false;
});
+
+ LogRequestSent(request);
}
else if (_debugSent)
{
@@ -796,9 +643,14 @@ namespace Tango.Integration.Operation
try
{
- var res = await SendRequest<StopDebugLogRequest, StopDebugLogResponse>(req, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(req);
+ var res = await SendRequest<StopDebugLogRequest, StopDebugLogResponse>(req);
+ LogResponseReceived(res.Message);
+ }
+ catch (Exception ex)
+ {
+ LogRequestFailed(req, ex);
}
- catch { }
}
}
}
@@ -816,25 +668,33 @@ namespace Tango.Integration.Operation
bool responseLogged = false;
_machineStatusSent = true;
- SendContinuousRequest<StartMachineStatusUpdateRequest, StartMachineStatusUpdateResponse>(request, new TransportContinuousRequestConfig() { ShouldLog = true }).ObserveOn(new NewThreadScheduler()).Subscribe(
+ SendContinuousRequest<StartMachineStatusUpdateRequest, StartMachineStatusUpdateResponse>(request).ObserveOn(new NewThreadScheduler()).Subscribe(
(response) =>
{
OnMachineStatusChanged(response);
if (!responseLogged)
{
+ LogResponseReceived(response.Message);
responseLogged = true;
}
},
(ex) =>
{
_machineStatusSent = false;
+
+ if (!(ex is ContinuousResponseAbortedException))
+ {
+ LogRequestFailed(request, ex);
+ }
},
() =>
{
_machineStatusSent = false;
LogManager.Log("Machine status update response completed!?", LogCategory.Warning);
});
+
+ LogRequestSent(request);
}
else if (_machineStatusSent)
{
@@ -846,98 +706,14 @@ namespace Tango.Integration.Operation
try
{
- var res = await SendRequest<StopMachineStatusUpdateRequest, StopMachineStatusUpdateResponse>(req, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(req);
+ var res = await SendRequest<StopMachineStatusUpdateRequest, StopMachineStatusUpdateResponse>(req);
+ LogResponseReceived(res.Message);
}
- catch { }
- }
- }
- }
-
- /// <summary>
- /// Called when the enable ink filling status has been changed.
- /// </summary>
- /// <param name="value">if set to <c>true</c> [value].</param>
- protected virtual void OnEnableInkFillingStatus(bool value)
- {
- if (value && State == TransportComponentState.Connected && !_inkFillingStatusSent)
- {
- var request = new StartInkFillingStatusRequest();
-
- bool responseLogged = false;
- _inkFillingStatusSent = true;
-
- SendContinuousRequest<StartInkFillingStatusRequest, StartInkFillingStatusResponse>(request, new TransportContinuousRequestConfig() { ShouldLog = true }).ObserveOn(new NewThreadScheduler()).Subscribe(
- (response) =>
- {
- OnInkFillingStatusChanged(response);
-
- if (!responseLogged)
- {
- responseLogged = true;
- }
- },
- (ex) =>
- {
- _inkFillingStatusSent = false;
- },
- () =>
- {
- _inkFillingStatusSent = false;
- LogManager.Log("Ink filling status response completed!?", LogCategory.Warning);
- });
- }
- else if (_inkFillingStatusSent)
- {
- _inkFillingStatusSent = false;
- }
- }
-
- /// <summary>
- /// Called when the enable automatic thread loading has been changed
- /// </summary>
- /// <param name="value">if set to <c>true</c> [value].</param>
- protected virtual async void OnEnableAutomaticThreadLoadingChanged(bool value)
- {
- if (value && State == TransportComponentState.Connected && !_threadLoadingSent)
- {
- var request = new StartThreadLoadingRequest();
-
- bool responseLogged = false;
- _threadLoadingSent = true;
-
- SendContinuousRequest<StartThreadLoadingRequest, StartThreadLoadingResponse>(request, new TransportContinuousRequestConfig() { ShouldLog = true }).ObserveOn(new NewThreadScheduler()).Subscribe(
- (response) =>
- {
- OnThreadLoadingStatusChanged(response);
-
- if (!responseLogged)
- {
- responseLogged = true;
- }
- },
- (ex) =>
- {
- _threadLoadingSent = false;
- },
- () =>
- {
- _threadLoadingSent = false;
- LogManager.Log("Thread loading response completed!?", LogCategory.Warning);
- });
- }
- else if (_threadLoadingSent)
- {
- _threadLoadingSent = false;
-
- if (State == TransportComponentState.Connected)
- {
- var req = new StopThreadLoadingRequest();
-
- try
+ catch (Exception ex)
{
- var res = await SendRequest<StopThreadLoadingRequest, StopThreadLoadingResponse>(req, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestFailed(req, ex);
}
- catch { }
}
}
}
@@ -959,17 +735,7 @@ namespace Tango.Integration.Operation
{
if (MachineEventsStateProvider != null)
{
- var events = response.Events;
-
- foreach (var emulated in _emulatedEvents)
- {
- if (!events.Any(x => x.Type == emulated.Type))
- {
- events.Add(emulated);
- }
- }
-
- MachineEventsStateProvider.ApplyEvents(events);
+ MachineEventsStateProvider.ApplyEvents(response.Events);
}
EventsNotification?.Invoke(this, response);
@@ -981,16 +747,30 @@ namespace Tango.Integration.Operation
/// <param name="data">The sensors data.</param>
protected virtual void OnDebugLogAvailable(StartDebugLogResponse data)
{
- if (LogEmbeddedDebuggingToFile && EmbeddedLogManager != null)
+ if (_last_embedded_debug_log == null || _last_embedded_debug_log.DebugLogResponse.Message != data.Message)
{
- EmbeddedLogManager.Log(new EmbeddedLogItem(data));
+ _last_embedded_debug_log = new EmbeddedLogItem(data);
+
+ if (LogEmbeddedDebuggingToFile && EmbeddedLogManager != null)
+ {
+ EmbeddedLogManager.Log(_last_embedded_debug_log);
+ }
+
+ DebugLogAvailable?.Invoke(this, data);
}
+ else
+ {
+ _last_embedded_debug_log.Repeated++;
- DebugLogAvailable?.Invoke(this, data);
+ if (LogEmbeddedDebuggingToFile && EmbeddedLogManager != null)
+ {
+ EmbeddedLogManager.Log(new EmbeddedLogItem(data));
+ }
+ }
}
/// <summary>
- /// Called when the machine status has been updated.
+ /// Called when the machine status has been update
/// </summary>
/// <param name="response">The response.</param>
protected virtual void OnMachineStatusChanged(StartMachineStatusUpdateResponse response)
@@ -1004,188 +784,87 @@ namespace Tango.Integration.Operation
if (changed)
{
- OnMachineStateChanged(MachineStatus.State);
- }
- }
-
- /// <summary>
- /// Called when ink filling status has been changed.
- /// </summary>
- /// <param name="response">The response.</param>
- protected virtual void OnInkFillingStatusChanged(StartInkFillingStatusResponse response)
- {
- if (response.Status == null || response.Status.CartridgesStatuses == null || response.Status.CartridgesStatuses.Count == 0) return;
+ LogManager.Log($"Machine State Changed: {MachineStatus.State}.");
- int index = -1;
- bool raiseChange = false;
-
- foreach (var remoteCartridge in response.Status.CartridgesStatuses)
- {
- index++;
-
- if (remoteCartridge.Cartridge == null)
- {
- LogManager.Log($"Remote cartridge arrived with null cartridge at position [{index}] and will be ignored.", LogCategory.Error);
- continue;
- }
-
- var localCartridge = InkFillingStatus.CartridgesStatuses.SingleOrDefault(x => x.Cartridge.Index == remoteCartridge.Cartridge.Index && x.Cartridge.Slot == remoteCartridge.Cartridge.Slot);
-
- if (localCartridge != null)
+ switch (MachineStatus.State)
{
- if (localCartridge.State != remoteCartridge.State)
- {
- localCartridge.State = remoteCartridge.State;
- LogManager.Log($"{localCartridge.Cartridge.Slot} Cartridge '{localCartridge.Cartridge.Index}' state changed: '{localCartridge.State}' => '{remoteCartridge.State}'.");
- }
-
- if (remoteCartridge.Cartridge.Tag != null)
- {
- LogManager.Log($"{localCartridge.Cartridge.Slot} Cartridge '{localCartridge.Cartridge.Index}' Tag arrived:\n{remoteCartridge.Cartridge.Tag.ToJsonString()}");
- }
-
- localCartridge.Message = remoteCartridge.Message;
- localCartridge.ProgressPercentage = remoteCartridge.ProgressPercentage;
-
- raiseChange = true;
- }
- else
- {
- LogManager.Log($"Could not locate local cartridge with slot '{remoteCartridge.Cartridge.Slot}' and index '{remoteCartridge.Cartridge.Index}'.", LogCategory.Error);
+ case MachineState.Initializing:
+ Status = MachineStatuses.Service;
+ break;
+ //case MachineState.PreparingJob:
+ // Status = MachineStatuses.GettingReady;
+ // break;
+ case MachineState.Ready:
+ Status = MachineStatuses.ReadyToDye;
+ break;
+ //case MachineState.Sleep:
+ // Status = MachineStatuses.Standby;
+ // break;
+ case MachineState.PowerOff:
+ Status = MachineStatuses.ShuttingDown;
+ break;
+ case MachineState.Error:
+ Status = MachineStatuses.Error;
+ break;
}
}
-
- if (raiseChange)
- {
- RaisePropertyChanged(nameof(InkFillingStatus));
- InkFillingStatusChanged?.Invoke(this, new InkFillingStatusChangedEventArgs() { Status = InkFillingStatus });
- }
}
/// <summary>
- /// Called when the machine state has been changed.
+ /// Called when the request has been sent
/// </summary>
- /// <param name="state">The state.</param>
- protected async virtual void OnMachineStateChanged(MachineState state)
+ /// <param name="response">The request.</param>
+ protected virtual void OnRequestSent(IMessage request)
{
- LogManager.Log($"Machine State Changed: {state}.");
-
- if (IsPrinting)
- {
- LogManager.Log($"Machine state change will not affect the machine operator status as it is now in a '{Status}' status.", LogCategory.Warning);
- return;
- }
-
- switch (state)
- {
- case MachineState.PowerUp:
- Status = MachineStatuses.PowerUp;
- break;
- //case MachineState.PreparingJob:
- // Status = MachineStatuses.GettingReady;
- // break;
- case MachineState.Ready:
- Status = MachineStatuses.ReadyToDye;
- break;
- case MachineState.Sleep:
- Status = MachineStatuses.Standby;
- break;
- case MachineState.PowerOff:
- Status = MachineStatuses.ShuttingDown;
- if (!_isPowerDownRequestInProgress)
- {
- try
- {
- await PowerDown();
- }
- catch { }
- }
- break;
- case MachineState.Error:
- //Status = MachineStatuses.Error;
- break;
- }
+ RequestSent?.Invoke(this, request);
}
/// <summary>
- /// Called when the thread loading status has been changed.
+ /// Called when the response has been received
/// </summary>
/// <param name="response">The response.</param>
- protected virtual void OnThreadLoadingStatusChanged(StartThreadLoadingResponse response)
+ protected virtual void OnResponseReceived(IMessage response)
{
- bool changed = (ThreadLoadingStatus == null || response.State != ThreadLoadingStatus.State || response.ErrorReason != ThreadLoadingStatus.ErrorReason);
-
- if (changed)
- {
- ThreadLoadingStatus = response;
- ThreadLoadingStatusChanged?.Invoke(this, response);
-
- LogManager.Log($"Thread Loading Status Changed: {ThreadLoadingStatus.State}.");
-
- switch (ThreadLoadingStatus.State)
- {
- case ThreadLoadingState.ReadyForLoading:
-
- LogManager.Log("Thread loading is ready for loading. Invoking confirmation event...");
-
- ThreadLoadingConfirmationRequired?.Invoke(this, new ThreadLoadingConfirmationRequiredEventArgs((processTable) =>
- {
- //Confirm Action
- try
- {
- var process = processTable.ToProcessParametersPMR();
- LogManager.Log($"Thread loading confirmation received with process parameters:\n{process.ToJsonString()}");
- LogManager.Log("Sending continue thread loading request...");
- var r = SendRequest<ContinueThreadLoadingRequest, ContinueThreadLoadingResponse>(new ContinueThreadLoadingRequest()
- {
- ProcessParameters = process,
- }, new TransportRequestConfig() { ShouldLog = true }).Result;
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error confirming thread loading sequence.");
- }
- })
- {
- Status = ThreadLoadingStatus,
- });
- break;
- case ThreadLoadingState.Completed:
- ThreadLoadingCompleted?.Invoke(this, ThreadLoadingStatus);
- break;
- case ThreadLoadingState.FinalizationError:
- case ThreadLoadingState.PreparationError:
- ThreadLoadingFailed?.Invoke(this, ThreadLoadingStatus);
- break;
- }
- }
+ ResponseReceived?.Invoke(this, response);
}
/// <summary>
/// Called when a new request has been received.
/// </summary>
/// <param name="container">The request.</param>
- protected override void OnRequestReceived(RequestReceivedEventArgs e)
+ protected override void OnRequestReceived(MessageContainer container)
{
- base.OnRequestReceived(e);
-
- if (e.Handled) return;
-
- var container = e.Container;
+ base.OnRequestReceived(container);
if (container.Type == MessageType.CartridgeValidationRequest)
{
- e.Handled = true;
OnCartridgeValidationRequestReceived(container.Token, MessageFactory.ExtractMessageFromContainer<CartridgeValidationRequest>(container));
}
else if (container.Type == MessageType.UpdateStatusRequest)
{
- e.Handled = true;
OnUpdateStatusRequestReceived(container.Token, MessageFactory.ExtractMessageFromContainer<UpdateStatusRequest>(container));
}
}
/// <summary>
+ /// Called when the response has been sent
+ /// </summary>
+ /// <param name="response">The response.</param>
+ protected virtual void OnResponseSent(IMessage response)
+ {
+ ResponseSent?.Invoke(this, response);
+ }
+
+ /// <summary>
+ /// Called when the request has been failed
+ /// </summary>
+ /// <param name="request">The request.</param>
+ protected virtual void OnRequestFailed(IMessage request, Exception exception)
+ {
+ RequestFailed?.Invoke(this, new RequestFailedEventArgs(request, exception));
+ }
+
+ /// <summary>
/// Called when the machine status has been changed
/// </summary>
/// <param name="status">The status.</param>
@@ -1241,115 +920,7 @@ namespace Tango.Integration.Operation
LogManager.Log(ex);
}
- try
- {
- SendResponse<UpdateStatusResponse>(new UpdateStatusResponse(), token);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error sending UpdateStatus response.");
- }
- }
-
- /// <summary>
- /// Called when the printing has been started.
- /// </summary>
- /// <param name="handler">The handler.</param>
- /// <param name="job">The job.</param>
- protected virtual void OnPrintingStarted(JobHandler handler, Job job, bool isResumed = false)
- {
- PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, job)
- {
- StartDate = _jobStartDate,
- IsResumed = isResumed
- });
- }
-
- /// <summary>
- /// Called when the printing has been completed.
- /// </summary>
- /// <param name="handler">The handler.</param>
- /// <param name="job">The job.</param>
- protected virtual void OnPrintingCompleted(JobHandler handler, Job job)
- {
- PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, job)
- {
- LiquidQuantities = _lastJobLiquidQuantities.ToList(),
- StartDate = _jobStartDate,
- UploadingStartTime = _jobUploadingStartDate,
- HeatingStartTime = _jobHeatingStartDate,
- ActualStartTime = _jobActualStartDate,
- });
-
- OnPrintingEnded(handler, job);
- }
-
- /// <summary>
- /// Called when the printing has been failed.
- /// </summary>
- /// <param name="handler">The handler.</param>
- /// <param name="job">The job.</param>
- /// <param name="exception">The exception.</param>
- protected virtual void OnPrintingFailed(JobHandler handler, Job job, Exception exception)
- {
- PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, job, exception)
- {
- LiquidQuantities = _lastJobLiquidQuantities.ToList(),
- StartDate = _jobStartDate,
- UploadingStartTime = _jobUploadingStartDate,
- HeatingStartTime = _jobHeatingStartDate,
- ActualStartTime = _jobActualStartDate,
- });
- OnPrintingEnded(handler, job);
- }
-
- /// <summary>
- /// Called when the printing has been aborted.
- /// </summary>
- /// <param name="handler">The handler.</param>
- /// <param name="job">The job.</param>
- protected virtual void OnPrintingAborted(JobHandler handler, Job job)
- {
- PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, job)
- {
- LiquidQuantities = _lastJobLiquidQuantities.ToList(),
- StartDate = _jobStartDate,
- UploadingStartTime = _jobUploadingStartDate,
- HeatingStartTime = _jobHeatingStartDate,
- ActualStartTime = _jobActualStartDate,
- });
- OnPrintingEnded(handler, job);
- }
-
- /// <summary>
- /// Called when the printing has been ended.
- /// </summary>
- /// <param name="handler">The handler.</param>
- /// <param name="job">The job.</param>
- protected virtual void OnPrintingEnded(JobHandler handler, Job job)
- {
- PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, job)
- {
- LiquidQuantities = _lastJobLiquidQuantities.ToList(),
- StartDate = _jobStartDate,
- UploadingStartTime = _jobUploadingStartDate,
- HeatingStartTime = _jobHeatingStartDate,
- ActualStartTime = _jobActualStartDate,
- });
- }
-
- protected virtual void OnHeadCleaningEnded(HeadCleaningHandler handler, JobRunStatus status)
- {
- SaveLastJobLiquidQuantities(null, null, null, null);
-
- HeadCleaningEnded?.Invoke(this, new HeadCleaningEndedEventArgs()
- {
- StartDate = _jobStartDate,
- Length = handler.Status.Total,
- EndPosition = handler.Status.Progress,
- Status = status,
- LiquidQuantities = _lastJobLiquidQuantities.ToList(),
- });
+ SendResponse<UpdateStatusResponse>(new UpdateStatusResponse());
}
#endregion
@@ -1370,23 +941,7 @@ namespace Tango.Integration.Operation
_debugSent = false;
_eventsSent = false;
_machineStatusSent = false;
-
- if (Status != MachineStatuses.Disconnected)
- {
- Status = MachineStatuses.Disconnected;
- ResetEvents();
- ResetInkFllingStatus();
- }
- }
- }
-
- private void ResetEvents()
- {
- if (MachineEventsStateProvider != null)
- {
- LogManager.Log("Resetting active events...");
- _emulatedEvents.Clear();
- MachineEventsStateProvider.Reset();
+ Status = MachineStatuses.Disconnected;
}
}
@@ -1398,30 +953,28 @@ namespace Tango.Integration.Operation
{
if (Status == MachineStatuses.Upgrading) return;
- Status = MachineStatuses.Disconnected;
-
- if (MachineStatus != null)
- {
- MachineStatus.State = MachineState.Ready;
- }
-
- SessionLogger.EndSession();
-
if (State == TransportComponentState.Connected)
{
DisconnectRequest request = new DisconnectRequest();
+ LogRequestSent(request);
try
{
- var response = await SendRequest<DisconnectRequest, DisconnectResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ var response = await SendRequest<DisconnectRequest, DisconnectResponse>(request);
+ LogResponseReceived(response.Message);
Status = MachineStatuses.Disconnected;
}
- catch { }
+ catch (Exception ex)
+ {
+ LogRequestFailed(request, ex);
+ }
}
- ResetEvents();
- ResetInkFllingStatus();
+ if (MachineEventsStateProvider != null)
+ {
+ MachineEventsStateProvider.Reset();
+ }
await base.Disconnect();
}
@@ -1447,14 +1000,12 @@ namespace Tango.Integration.Operation
Password = "1234",
UnixTime = DateTimeOffset.UtcNow.ToUnixTimeSeconds()
};
+ LogRequestSent(request);
try
{
- var response = await SendRequest<ConnectRequest, ConnectResponse>(request, new TransportRequestConfig() { ShouldLog = true });
-
- SessionLogger.CreateSession();
-
- _isPowerDownRequestInProgress = false;
+ var response = await SendRequest<ConnectRequest, ConnectResponse>(request);
+ LogResponseReceived(response.Message);
if (Status != MachineStatuses.Upgrading)
{
@@ -1472,27 +1023,15 @@ namespace Tango.Integration.Operation
OnEnableEmbeddedDebuggingChanged(EnableEmbeddedDebugging);
OnEnableEventsNotification(EnableEventsNotification);
OnEnableMachineStatusUpdatesChanged(EnableMachineStatusUpdates);
- OnEnableAutomaticThreadLoadingChanged(EnableAutomaticThreadLoading);
- OnEnableInkFillingStatus(EnableInkFillingStatus);
-
- if (EnablePowerUpSequence)
- {
- TrackPowerUpSequence();
- }
if (EnableJobResume)
{
ResumeJob();
}
-
- if (response.Message.IsAfterReset)
- {
- FirmwareStarted?.Invoke(this, new EventArgs());
- }
}
catch (Exception ex)
{
- SessionLogger.EndSession();
+ LogRequestFailed(request, ex);
await base.Disconnect();
throw ex;
}
@@ -1507,202 +1046,35 @@ namespace Tango.Integration.Operation
#region Private Methods
- private void ResetInkFllingStatus()
- {
- if (InkFillingStatus == null)
- {
- var status = new InkFillingStatus();
-
- for (int i = 0; i < 8; i++)
- {
- status.CartridgesStatuses.Add(new CartridgeStatus()
- {
- Cartridge = new Cartridge()
- {
- Index = i,
- Slot = CartridgeSlot.Ink,
- },
- State = CartridgeState.Absent
- });
- }
-
- status.CartridgesStatuses.Add(new CartridgeStatus()
- {
- Cartridge = new Cartridge() { Index = 0, Slot = CartridgeSlot.WasteMiddle },
- State = CartridgeState.Absent
- });
-
- status.CartridgesStatuses.Add(new CartridgeStatus()
- {
- Cartridge = new Cartridge() { Index = 1, Slot = CartridgeSlot.WasteLower },
- State = CartridgeState.Absent
- });
-
- InkFillingStatus = status;
- }
- else
- {
- foreach (var cartridge in InkFillingStatus.CartridgesStatuses)
- {
- cartridge.ProgressPercentage = 0;
- cartridge.Message = String.Empty;
- cartridge.State = CartridgeState.Absent;
- }
- }
-
- InkFillingStatusChanged?.Invoke(this, new InkFillingStatusChangedEventArgs() { Status = InkFillingStatus });
- }
-
- private void SaveCachedJobOperation(Job job)
- {
- try
- {
- LogManager.Log("Caching current job operation...");
- CachedJobOperation cache = new CachedJobOperation();
- cache.JobDTO = JobDTO.FromObservable(job);
- cache.MachineStatus = MachineStatus;
- cache.ProcessParametersDTO = ProcessParametersTableDTO.FromObservable(CurrentProcessParameters);
- cache.MachineConfigurationDTO = ConfigurationDTO.FromObservable(job.Machine.Configuration);
- var json = JsonConvert.SerializeObject(cache);
- Directory.CreateDirectory(Path.GetDirectoryName(CachedJobOperationFile));
- File.WriteAllText(CachedJobOperationFile, json);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error caching job operation for job resume.");
- }
- }
-
- private CachedJobOperation LoadCachedJobOperation()
- {
- try
- {
- LogManager.Log("Loading last cached job operation...");
- String json = File.ReadAllText(CachedJobOperationFile);
- CachedJobOperation cache = JsonConvert.DeserializeObject<CachedJobOperation>(json);
- return cache;
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error loading cache of last job operation for job resume.");
- return null;
- }
- }
-
- private void TrackPowerUpSequence()
- {
- LogManager.Log("Starting power up sequence tracking...");
-
- bool started = false;
- bool completed = false;
- PowerUpState lastState = PowerUpState.None;
-
- SendContinuousRequest<StartPowerUpRequest, StartPowerUpResponse>(new StartPowerUpRequest(), new TransportContinuousRequestConfig()
- {
- ShouldLog = true,
- Timeout = TimeSpan.FromSeconds(5)
- }).Subscribe((response) =>
- {
- if (!started)
- {
- started = true;
- PowerUpStarted?.Invoke(this, response);
- }
-
- PowerUpProgress?.Invoke(this, response);
-
- var state = response.Message.State;
-
- if (state != lastState)
- {
- LogManager.Log($"Power up sequence state changed to '{state}'...");
-
- switch (state)
- {
- case PowerUpState.Error:
- completed = true;
- LogManager.Log($"Power up sequence failed with state '{state}'. ({response.Message.Message})");
- PowerUpFailed?.Invoke(this, response);
- PowerUpEnded?.Invoke(this, new EventArgs());
- break;
- case PowerUpState.Cancelled:
- completed = true;
- LogManager.Log($"Power up sequence canceled with state '{state}'. ({response.Message.Message})");
- PowerUpEnded?.Invoke(this, new EventArgs());
- break;
- case PowerUpState.MachineReadyToDye:
- completed = true;
- LogManager.Log($"Power up sequence completed successfully with state '{state}'. ({response.Message.Message})");
- PowerUpCompleted?.Invoke(this, response);
- PowerUpEnded?.Invoke(this, new EventArgs());
- break;
- }
-
- lastState = state;
- }
-
- }, (ex) =>
- {
- if (!completed)
- {
- completed = true;
- LogManager.Log(ex, "Power up sequence tracking failed.");
- PowerUpEnded?.Invoke(this, new EventArgs());
- }
- }, () =>
- {
- if (!completed)
- {
- completed = true;
- PowerUpEnded?.Invoke(this, new EventArgs());
- }
- });
- }
-
private async void ResumeJob()
{
LogManager.Log("Checking if a job is in progress...");
try
{
- var res = await SendRequest<CurrentJobRequest, CurrentJobResponse>(new CurrentJobRequest(), new TransportRequestConfig() { ShouldLog = true });
+ var res = await SendRequest<CurrentJobRequest, CurrentJobResponse>(new CurrentJobRequest());
if (res.Message.IsJobInProgress)
{
- LogManager.Log("Job is in progress. Trying to resume job...");
- CachedJobOperation cache = LoadCachedJobOperation();
-
- if (cache == null)
- {
- LogManager.Log("Cannot resume current job with no cached operation.", LogCategory.Error);
- return;
- }
+ JobTicket jobTicket = res.Message.JobTicket;
- Job job = null;
- Configuration configuration = null;
- ProcessParametersTable processParameters = null;
+ ProcessParametersTable processParameters = new ProcessParametersTable();
+ jobTicket.ProcessParameters.MapPrimitivesTo(processParameters);
- try
- {
- processParameters = cache.ProcessParametersDTO.ToObservable();
- job = cache.JobDTO.ToObservable();
- configuration = cache.MachineConfigurationDTO.ToObservable();
- _machineStatusBeforeJobStart = cache.MachineStatus;
- CurrentProcessParameters = processParameters;
- }
- catch (Exception ex)
+ ResumingJobEventArgs args = new ResumingJobEventArgs((job) =>
{
- LogManager.Log(ex, "Error deserializing cache job operation. Aborting resume.");
- return;
- }
-
- JobTicket jobTicket = res.Message.JobTicket;
+ if (Status != MachineStatuses.ReadyToDye)
+ {
+ throw new InvalidOperationException("Could not print while status = " + Status);
+ }
- ResumingJobEventArgs args = new ResumingJobEventArgs(() =>
- {
RunningJob = null;
RunningJobStatus = null;
+ var originalJob = job;
+
+ CurrentProcessParameters = processParameters;
+
var request = new ResumeCurrentJobRequest();
JobHandler handler = null;
@@ -1711,125 +1083,109 @@ namespace Tango.Integration.Operation
{
try
{
- if (handler.CanCancel)
- {
- handler.CanCancel = false;
- handler.IsCanceled = true;
- LogManager.Log("Aborting current job...");
- var result = await SendRequest<AbortJobRequest, AbortJobResponse>(new AbortJobRequest(), new TransportRequestConfig() { ShouldLog = true });
- SaveLastJobLiquidQuantities(job, configuration, processParameters, handler);
- OnPrintingAborted(handler, job);
- handler.RaiseCanceled();
- if (Status != MachineStatuses.Disconnected)
- {
- Status = MachineStatuses.ReadyToDye;
- }
- }
+ var result = await SendRequest<AbortJobRequest, AbortJobResponse>(new AbortJobRequest());
+ PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ handler.RaiseCanceled();
}
catch (Exception ex)
{
- handler.CanCancel = true;
LogManager.Log(ex, "Failed to cancel job.");
}
- }, job, jobTicket, processParameters, JobHandlingMode);
+ }, originalJob, jobTicket, processParameters, JobHandlingMode);
handler.StatusChanged += (x, s) =>
{
RunningJobStatus = s;
};
-
- _jobStartDate = DateTime.UtcNow;
- _jobUploadingStartDate = _jobStartDate;
- _jobHeatingStartDate = _jobStartDate;
- _jobActualStartDate = null;
+ LogRequestSent(request);
bool responseLogged = false;
- bool completed = false;
Thread.Sleep(500); //Just wait maybe Shlomo is getting this message to fast after restart ?
+ bool completed = false;
- SendContinuousRequest<ResumeCurrentJobRequest, ResumeCurrentJobResponse>(request, new TransportContinuousRequestConfig() { ContinuousTimeout = ContinuousRequestTimeout, ShouldLog = true }).Subscribe((response) =>
- {
- if (!completed)
- {
- handler.RaiseStatusReceived(response.Message.Status);
- _last_job_status = handler.Status;
-
- if (response.Message.Status.Progress > 0)
- {
- if (_jobActualStartDate == null)
- {
- _jobActualStartDate = DateTime.UtcNow;
- }
- }
-
- if (!responseLogged)
- {
- Status = MachineStatuses.GettingReady;
- responseLogged = true;
- RunningJob = job;
- OnPrintingStarted(handler, job, true);
- }
-
- if (JobHandlingMode == JobHandlerModes.SettingUp)
- {
- if (response.Message.Status.Progress > CurrentProcessParameters.DryerBufferLengthMeters)
- {
- if (!completed)
- {
- Status = MachineStatuses.Printing;
- }
- }
- }
- else
- {
- if (response.Message.Status.Progress > 0)
- {
- if (!completed)
- {
- Status = MachineStatuses.Printing;
- }
- }
- }
- }
- }, (ex) =>
- {
- if (!completed)
- {
- completed = true;
-
- if (Status != MachineStatuses.Disconnected)
- {
- Status = MachineStatuses.ReadyToDye;
- }
+ SendContinuousRequest<ResumeCurrentJobRequest, ResumeCurrentJobResponse>(request, null, TimeSpan.FromSeconds(2)).Subscribe((response) =>
+ {
+ if (!completed)
+ {
+ if (!responseLogged)
+ {
+ if (_last_job_status != null)
+ {
+ _last_job_status.IsCanceled = false;
+ _last_job_status.IsCompleted = false;
+ _last_job_status.IsFailed = false;
+ handler.Status = _last_job_status;
+ }
+ }
- if (!handler.IsCanceled)
- {
- SaveLastJobLiquidQuantities(job, configuration, processParameters, handler);
+ handler.RaiseStatusReceived(response.Message.Status);
- Exception finalException = ex;
+ if (!responseLogged)
+ {
+ Status = MachineStatuses.GettingReady;
+ responseLogged = true;
+ RunningJob = originalJob;
+ PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ LogResponseReceived(response.Message);
+ }
- if (ex is ContinuousResponseAbortedException continuousException)
- {
- finalException = new ContinuousResponseAbortedException($"Job aborted by the embedded device ({continuousException.Container.ErrorMessage}).");
- }
+ if (JobHandlingMode == JobHandlerModes.SettingUp)
+ {
+ if (response.Message.Status.Progress > processParameters.DryerBufferLengthMeters)
+ {
+ if (!completed)
+ {
+ Status = MachineStatuses.Printing;
+ }
+ }
+ }
+ else
+ {
+ if (response.Message.Status.Progress > 0)
+ {
+ if (!completed)
+ {
+ Status = MachineStatuses.Printing;
+ }
+ }
+ }
+ }
+ }, (ex) =>
+ {
+ if (!completed)
+ {
+ completed = true;
+ if (!(ex is ContinuousResponseAbortedException))
+ {
+ Status = MachineStatuses.ReadyToDye;
- OnPrintingFailed(handler, job, finalException);
- handler.RaiseFailed(finalException);
- }
- }
- }, () =>
- {
- if (!completed)
- {
- completed = true;
- Status = MachineStatuses.ReadyToDye;
- SaveLastJobLiquidQuantities(job, configuration, processParameters, handler);
- OnPrintingCompleted(handler, job);
- handler.RaiseCompleted();
- }
- });
+ if (!handler.IsCanceled)
+ {
+ PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, originalJob, ex));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ handler.RaiseFailed(ex);
+ LogRequestFailed(request, ex);
+ }
+ }
+ else
+ {
+ Status = MachineStatuses.ReadyToDye;
+ }
+ }
+ }, () =>
+ {
+ if (!completed)
+ {
+ completed = true;
+ Status = MachineStatuses.ReadyToDye;
+ PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ handler.RaiseCompleted();
+ }
+ });
return handler;
});
@@ -1845,6 +1201,42 @@ namespace Tango.Integration.Operation
}
/// <summary>
+ /// Logs the request sent.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ protected void LogRequestSent(IMessage message)
+ {
+ if (!(message is FileChunkUploadRequest) && !(message is FileDownloadRequest))
+ {
+ LogManager.Log(String.Format("Sending request '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString()));
+ OnRequestSent(message);
+ }
+ }
+
+ /// <summary>
+ /// Logs the request failed.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ protected void LogRequestFailed(IMessage message, Exception ex)
+ {
+ LogManager.Log(String.Format("Request failed '{0}'...{1}{2}{1}{3}", message.GetType().Name, Environment.NewLine, message.ToJsonString(), ex.ToString()), LogCategory.Error);
+ OnRequestFailed(message, ex);
+ }
+
+ /// <summary>
+ /// Logs the response received.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ protected void LogResponseReceived(IMessage message)
+ {
+ if (!(message is FileChunkUploadResponse) && !(message is FileDownloadResponse))
+ {
+ LogManager.Log(String.Format("Response received '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString()));
+ OnResponseReceived(message);
+ }
+ }
+
+ /// <summary>
/// Creates a PMR job segment.
/// </summary>
/// <param name="segment">The segment.</param>
@@ -1862,25 +1254,11 @@ namespace Tango.Integration.Operation
if (GradientGenerationConfiguration != null && GradientGenerationConfiguration.IsEnabled && segment.BrushStops.Count > 1)
{
LogManager.Log($"Generate segment {segment.SegmentIndex} gradient...");
- try
- {
- stops = GradientGenerationConfiguration.Generate(segment, job, processParameters, (e) =>
- {
- PreparingJobProgress?.Invoke(this, e);
- });
- }
- catch (Exception ex)
- {
- throw new InvalidOperationException($"Error occurred while trying to generate a gradient.\n{ex.Message}");
- }
- LogManager.Log($"Gradient generated.");
-
- PreparingJobProgress?.Invoke(this, new PreparingJobProgressEventArgs()
+ stops = GradientGenerationConfiguration.Generate(segment, job, processParameters, (e) =>
{
- Job = job,
- Total = job.Segments.Sum(x => x.Length),
- Progress = job.Segments.Sum(x => x.Length),
+ PreparingJobProgress?.Invoke(this, e);
});
+ LogManager.Log($"Gradient generated.");
}
foreach (var stop in stops)
@@ -1949,11 +1327,12 @@ namespace Tango.Integration.Operation
request.JobTicket = ticket;
+ LogRequestSent(request);
bool responseLogged = false;
var previous_segments_length = job.Segments.Where(x => x.SegmentIndex < segment.SegmentIndex).Sum(x => x.Length);
- SendContinuousRequest<JobRequest, JobResponse>(request, new TransportContinuousRequestConfig() { ContinuousTimeout = ContinuousRequestTimeout, ShouldLog = true }).Subscribe((response) =>
+ SendContinuousRequest<JobRequest, JobResponse>(request, null, TimeSpan.FromSeconds(2)).Subscribe((response) =>
{
response.Message.Status.Progress += previous_segments_length;
@@ -1964,7 +1343,8 @@ namespace Tango.Integration.Operation
responseLogged = true;
Status = MachineStatuses.Printing;
RunningJob = handler.Job;
- OnPrintingStarted(handler, handler.Job);
+ PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, handler.Job));
+ LogResponseReceived(response.Message);
}
}, (ex) =>
@@ -1975,8 +1355,10 @@ namespace Tango.Integration.Operation
if (!handler.IsCanceled)
{
- OnPrintingFailed(handler, handler.Job, ex);
+ PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, handler.Job, ex));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, handler.Job));
handler.RaiseFailed(ex);
+ LogRequestFailed(request, ex);
}
}
else
@@ -1988,7 +1370,8 @@ namespace Tango.Integration.Operation
if (segment == job.OrderedSegments.Last())
{
Status = MachineStatuses.ReadyToDye;
- OnPrintingCompleted(handler, handler.Job);
+ PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, handler.Job));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, handler.Job));
handler.RaiseCompleted();
}
else
@@ -1998,7 +1381,8 @@ namespace Tango.Integration.Operation
ContinueSingleSpoolJob(segment.GetNextSegment(), job, processParameters, handler);
}, () =>
{
- OnPrintingAborted(handler, handler.Job);
+ PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, handler.Job));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, handler.Job));
Status = MachineStatuses.ReadyToDye;
handler.RaiseCanceled();
});
@@ -2008,8 +1392,6 @@ namespace Tango.Integration.Operation
private void ValidateJobLiquidQuantity(Job job, ProcessParametersTable processParameters, Configuration configuration)
{
- LogManager.Log("Validating job liquid quantities...");
-
Dictionary<int, double> liquidQuantities = new Dictionary<int, double>();
foreach (var pack in configuration.NoneEmptyIdsPacks.OrderBy(x => x.PackIndex))
@@ -2017,8 +1399,6 @@ namespace Tango.Integration.Operation
liquidQuantities.Add(pack.PackIndex, 0);
}
- int resolution = GradientGenerationConfiguration.ResolutionCM;
-
for (int i = 0; i < Math.Max(job.NumberOfUnits, 1); i++)
{
for (int segmentIndex = 0; segmentIndex < job.Segments.Count; segmentIndex++)
@@ -2026,177 +1406,6 @@ namespace Tango.Integration.Operation
var segment = job.Segments[segmentIndex];
var segment_length_cm = segment.Length * 100d;
- List<BrushStop> orderedBrushCollection = segment.BrushStops.OrderBy(x => x.OffsetMeters).ToList();
-
- int solid_gradient_oeff = orderedBrushCollection.Count == 1 ? 1 : 2;
- double prev_offset_cm = 0;
-
- for (int brushIndex = 0; brushIndex < orderedBrushCollection.Count; brushIndex++)
- {
- var brush = orderedBrushCollection[brushIndex];
- double brush_length_centimeters = 0d;
- double brush_offset_cm = 0;
-
- if ((brushIndex + 1) < orderedBrushCollection.Count)
- {
- brush_offset_cm = (brush.OffsetMeters * 100d);
- double next_brush_offset_cm = (orderedBrushCollection[brushIndex + 1].OffsetMeters * 100d);
- brush_length_centimeters = ((next_brush_offset_cm - brush_offset_cm) + (brush_offset_cm - prev_offset_cm));
-
- if (brushIndex == 0)
- {
- // add a resolution step for first brush
- brush_length_centimeters += resolution;
- }
- }
- else//last brush or solid brush
- {
- brush_length_centimeters = (segment_length_cm - prev_offset_cm);
- if (orderedBrushCollection.Count > 1)
- {
- // add a resolution for last brush , not solid brush
- brush_length_centimeters -= resolution;
- }
- }
-
- prev_offset_cm = brush_offset_cm;
-
- foreach (var liquidVolumes in brush.LiquidVolumes)
- {
- liquidQuantities[liquidVolumes.IdsPack.PackIndex] += liquidVolumes.NanoliterPerCentimeter * (brush_length_centimeters / solid_gradient_oeff);
- }
- }
- }
- }
-
- if (MachineStatus != null)
- {
- var exception = new InsufficientLiquidQuantityException($"Insufficient liquids level.");
-
- bool shouldThrow = false;
-
- foreach (var liquidQuantity in liquidQuantities)
- {
- int index = liquidQuantity.Key;
- var packLevel = MachineStatus.IDSPacksLevels.SingleOrDefault(x => x.Index == index);
- var idsPack = configuration.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == index);
-
- if (packLevel != null)
- {
- var idsLevel = new InsufficientLiquidQuantityException.IDSPackLevel()
- {
- IdsPack = idsPack,
- Current = packLevel.DispenserLevel,
- Required = (int)liquidQuantities[index],
- Maximum = MAX_DISPENSER_NANOLITER,
- };
-
- LogManager.Log($"Required {idsLevel.IdsPack.LiquidType.Type}: {idsLevel.Required}, Current: {idsLevel.Current}");
-
- if (idsLevel.Required > idsLevel.Current)
- {
- shouldThrow = true;
- string display_value = (((double)(idsLevel.Required - idsLevel.Current) / 1000000)).ToString("N2", CultureInfo.InvariantCulture);
- idsLevel.Message = $"Missing {display_value} CC to complete the job.";
-
- if (idsLevel.Required > idsLevel.Maximum)
- {
- display_value = (((double)(idsLevel.Required - idsLevel.Maximum)) / 1000000).ToString("N2", CultureInfo.InvariantCulture);
- idsLevel.Message = $"Required ink exceeds the maximum capacity of the dispenser by {display_value} CC. Please reduce the segment length.";
- }
- }
-
- exception.IdsPackLevels.Add(idsLevel);
- }
- else
- {
- LogManager.Log($"Could not validate required liquid quantity for job. Missing IDS Pack level at index {index}.", LogCategory.Warning);
- }
- }
-
- if (shouldThrow)
- {
- LogManager.Log("Liquid quantity validation failed due to insufficient quantity. Throwing exception...");
-
- exception.IdsPackLevels = exception.IdsPackLevels.OrderBy(x => x.IdsPack.PackIndex).ToList();
-
- throw LogManager.Log(exception, JsonConvert.SerializeObject(exception.IdsPackLevels.Select(x => new
- {
- Liquid = x.IdsPack.LiquidType.Name,
- x.Required,
- x.Current
- }).ToList()));
- }
- }
- else
- {
- LogManager.Log("Could not validate required liquid quantity for job. No machine status received", LogCategory.Warning);
- }
- }
-
- /// <summary>
- /// Assign the liquid quantities spent by the last job using the job and the handler last status.
- /// </summary>
- /// <param name="job">The job.</param>
- /// <param name="configuration">The configuration.</param>
- /// <param name="handler">The handler.</param>
- private void SaveLastJobLiquidQuantities(Job job, Configuration configuration, ProcessParametersTable processParameters, JobHandler handler)
- {
- if (configuration == null)
- {
- configuration = _machineConfiguration;
- }
-
- try
- {
- _lastJobLiquidQuantities = new List<BL.ValueObjects.JobRunLiquidQuantity>();
-
- if (JobLiquidQuantityCalculationMode == JobLiquidQuantityCalculationMode.MachineStatus)
- {
- foreach (var pack in configuration.NoneEmptyIdsPacks.ToList())
- {
- var packLevelAfter = MachineStatus.IDSPacksLevels.SingleOrDefault(x => x.Index == pack.PackIndex);
- var packLevelBefore = _machineStatusBeforeJobStart.IDSPacksLevels.SingleOrDefault(x => x.Index == pack.PackIndex);
-
- if (packLevelAfter != null && packLevelBefore != null)
- {
- _lastJobLiquidQuantities.Add(new BL.ValueObjects.JobRunLiquidQuantity()
- {
- LiquidType = pack.LiquidType.Type,
- Quantity = packLevelBefore.DispenserLevel - packLevelAfter.DispenserLevel,
- });
- }
- }
- }
- else
- {
- _lastJobLiquidQuantities = CreateJobRunLiquidQuantities(job, configuration, processParameters, handler.Status.Progress, handler.Status.TotalProgress);
- }
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, LogCategory.Critical, "Error saving last job liquid quantities.");
- }
- }
-
- private void ValidateJobLiquidQuantity(JobTicket ticket, ProcessParametersTable processParameters, Configuration configuration)
- {
- LogManager.Log("Validating job liquid quantity...");
-
- Dictionary<int, double> liquidQuantities = new Dictionary<int, double>();
-
- foreach (var pack in configuration.NoneEmptyIdsPacks.OrderBy(x => x.PackIndex))
- {
- liquidQuantities.Add(pack.PackIndex, 0);
- }
-
- for (int i = 0; i < Math.Max(ticket.NumberOfUnits, 1); i++)
- {
- for (int segmentIndex = 0; segmentIndex < ticket.Segments.Count; segmentIndex++)
- {
- var segment = ticket.Segments[segmentIndex];
- var segment_length_cm = segment.Length * 100d;
-
var stop_count = segment.BrushStops.Count - (segment.BrushStops.Count == 1 ? 0 : 1);
var stop_length_centimeters = segment_length_cm / stop_count;
@@ -2204,9 +1413,9 @@ namespace Tango.Integration.Operation
{
var stop = segment.BrushStops[stopIndex];
- foreach (var dispenser in stop.Dispensers)
+ foreach (var liquidVolumes in stop.LiquidVolumes)
{
- liquidQuantities[dispenser.Index] += dispenser.NanoliterPerCentimeter * stop_length_centimeters;
+ liquidQuantities[liquidVolumes.IdsPack.PackIndex] += liquidVolumes.NanoliterPerCentimeter * stop_length_centimeters;
}
}
}
@@ -2230,8 +1439,7 @@ namespace Tango.Integration.Operation
{
IdsPack = idsPack,
Current = packLevel.DispenserLevel,
- Required = (int)liquidQuantities[index],
- Maximum = MAX_DISPENSER_NANOLITER,
+ Required = (int)liquidQuantities[index]
};
if (liquidQuantities[index] > packLevel.DispenserLevel)
@@ -2266,139 +1474,6 @@ namespace Tango.Integration.Operation
#endregion
- #region Public Static Methods
-
- /// <summary>
- /// Creates the job run liquid quantities.
- /// </summary>
- /// <param name="job">The job.</param>
- /// <param name="configuration">The configuration.</param>
- /// <param name="processParameters">The process parameters.</param>
- /// <param name="position">The position.</param>
- /// <param name="length">The length.</param>
- /// <param name="gradientResolution">The gradient resolution.</param>
- /// <returns></returns>
- public static List<BL.ValueObjects.JobRunLiquidQuantity> CreateJobRunLiquidQuantities(Job job, Configuration configuration, ProcessParametersTable processParameters, double position, double length)
- {
- var units = Math.Max(job.NumberOfUnits, 1);
-
- var effectiveSegments = new List<Segment>();
- for (int i = 0; i < units; i++)
- {
- if (i > 0 && job.EnableInterSegment)
- {
- effectiveSegments.Add(Job.CreateInterSegment(job.InterSegmentLength));
- }
-
- foreach (var segment in job.EffectiveSegments)
- {
- effectiveSegments.Add(segment.Clone(job));
- }
- }
-
- effectiveSegments.Add(Job.CreateInterSegment(processParameters.DryerBufferLengthMeters));
-
- double total = length;
- double position_cm = position * 100d;
- double total_length = 0;
-
- Dictionary<int, double> liquidQuantities = new Dictionary<int, double>();
-
- foreach (var pack in configuration.NoneEmptyIdsPacks.OrderBy(x => x.PackIndex))
- {
- liquidQuantities.Add(pack.PackIndex, 0);
- }
-
- bool stop_calc = false;
-
- for (int segmentIndex = 0; segmentIndex < effectiveSegments.Count && !stop_calc; segmentIndex++)
- {
- var segment = effectiveSegments[segmentIndex];
- var segment_length_cm = segment.Length * 100d;
-
- List<BrushStop> orderedBrushCollection = segment.BrushStops.OrderBy(x => x.OffsetMeters).ToList();
-
- int solid_gradient_oeff = orderedBrushCollection.Count == 1 ? 1 : 2;
- double prev_offset_cm = 0;
- double delta_brushLenghtToStopPosition = 0d;
-
- double position_interval_centimeters = 0d;//interval for calculation where the stop occurred
- for (int brushIndex = 0; brushIndex < orderedBrushCollection.Count && !stop_calc; brushIndex++)
- {
- var brush = orderedBrushCollection[brushIndex];
- double brush_length_centimeters = 0d;
- double brush_offset_cm = 0;
-
- if ((brushIndex + 1) < orderedBrushCollection.Count)
- {
- brush_offset_cm = (brush.OffsetMeters * 100d);
- double next_brush_offset_cm = (orderedBrushCollection[brushIndex + 1].OffsetMeters * 100d);
- brush_length_centimeters = (next_brush_offset_cm - prev_offset_cm);
- double brush_length_centimeters_before_calc = brush_length_centimeters;
-
- if (delta_brushLenghtToStopPosition > 0)//calculate second brush
- {
- brush_length_centimeters = ((position_interval_centimeters - delta_brushLenghtToStopPosition) * (position_interval_centimeters - delta_brushLenghtToStopPosition)) / position_interval_centimeters;
- stop_calc = true;
- }
- else if (total_length + prev_offset_cm + brush_length_centimeters > position_cm)//calculate first brush
- {
- position_interval_centimeters = brush_length_centimeters;
- delta_brushLenghtToStopPosition = (total_length + prev_offset_cm + brush_length_centimeters) - position_cm;
- brush_length_centimeters = brush_length_centimeters - (delta_brushLenghtToStopPosition * delta_brushLenghtToStopPosition / brush_length_centimeters);
- }
- }
- else//last brush or solid brush
- {
- brush_length_centimeters = (segment_length_cm - prev_offset_cm);
- if (delta_brushLenghtToStopPosition > 0)//second brush
- {
- brush_length_centimeters = ((position_interval_centimeters - delta_brushLenghtToStopPosition) * (position_interval_centimeters - delta_brushLenghtToStopPosition)) / position_interval_centimeters;
- stop_calc = true;
- }
- else if (orderedBrushCollection.Count == 1 && (total_length + segment_length_cm) > position_cm)// solid brush
- {
- brush_length_centimeters = position_cm - total_length;
- stop_calc = true;
- }
- }
-
- prev_offset_cm = brush_offset_cm;
-
- if (brush.LiquidVolumes != null)
- {
- foreach (var liquidVolumes in brush.LiquidVolumes)
- {
- liquidQuantities[liquidVolumes.IdsPack.PackIndex] += liquidVolumes.NanoliterPerCentimeter * (brush_length_centimeters / solid_gradient_oeff);
- }
- }
- }
- total_length += segment_length_cm;
- }
-
- List<BL.ValueObjects.JobRunLiquidQuantity> quantities = new List<BL.ValueObjects.JobRunLiquidQuantity>();
-
- foreach (var liquidQuantity in liquidQuantities)
- {
- int index = liquidQuantity.Key;
- var idsPack = configuration.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == index);
-
- if (idsPack != null)
- {
- quantities.Add(new BL.ValueObjects.JobRunLiquidQuantity()
- {
- LiquidType = idsPack.LiquidType.Type,
- Quantity = (int)liquidQuantities[index],
- });
- }
- }
-
- return quantities;
- }
-
-
- #endregion
-
#region Public Methods
/// <summary>
@@ -2426,16 +1501,7 @@ namespace Tango.Integration.Operation
throw new NullReferenceException("Could not locate an active process parameters tables group for RML " + job.Rml.Name);
}
- ProcessParametersTable processParameters = null;
-
- try
- {
- processParameters = converter.GetRecommendedProcessParameters(job);
- }
- catch (Exception ex)
- {
- throw LogManager.Log(new InvalidOperationException($"An error occurred while trying to resolve the recommended process parameters.\n{ex.Message}"));
- }
+ var processParameters = converter.GetRecommendedProcessParameters(job);
if (processParameters == null)
{
@@ -2445,104 +1511,104 @@ namespace Tango.Integration.Operation
//Perform color correction
foreach (var stop in jobSegments.SelectMany(x => x.BrushStops))
{
- //if (stop.LiquidVolumes == null || stop.BrushColorSpace == ColorSpaces.Volume)
- //{
- if (stop.BrushColorSpace == ColorSpaces.RGB || stop.BrushColorSpace == ColorSpaces.LAB)
+ if (stop.LiquidVolumes == null)
{
- var output = converter.Convert(stop, false);
-
- //TODO: Restore this when Mirta conversion is working as expected.
- //if (suggestions.OutOfGamut)
- //{
- // throw new InvalidOperationException("Cannot print a brush stop which is out of gamut.");
- //}
-
- stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
-
- foreach (var outputLiquid in output.SingleCoordinates.OutputLiquids)
+ if (stop.BrushColorSpace == ColorSpaces.RGB || stop.BrushColorSpace == ColorSpaces.LAB)
{
- var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack.LiquidType.Code == outputLiquid.LiquidType.ToInt32());
+ var output = converter.Convert(stop, false);
- if (liquidVolume == null)
- {
- throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + outputLiquid.LiquidType + "'.");
- }
+ //TODO: Restore this when Mirta conversion is working as expected.
+ //if (suggestions.OutOfGamut)
+ //{
+ // throw new InvalidOperationException("Cannot print a brush stop which is out of gamut.");
+ //}
- liquidVolume.Volume = outputLiquid.Volume;
- }
- }
- else if (stop.BrushColorSpace == ColorSpaces.Catalog)
- {
- if (stop.ColorCatalogsItem != null)
- {
stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
+ foreach (var outputLiquid in output.SingleCoordinates.OutputLiquids)
{
- var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.LiquidType == LiquidTypes.Cyan);
+ var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack.LiquidType.Code == outputLiquid.LiquidType.ToInt32());
if (liquidVolume == null)
{
- throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Cyan + "'.");
+ throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + outputLiquid.LiquidType + "'.");
}
- liquidVolume.Volume = stop.ColorCatalogsItem.Cyan;
+ liquidVolume.Volume = outputLiquid.Volume;
}
-
+ }
+ else if (stop.BrushColorSpace == ColorSpaces.Catalog)
+ {
+ if (stop.ColorCatalogsItem != null)
{
- var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.LiquidType == LiquidTypes.Magenta);
+ stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
- if (liquidVolume == null)
+ if (stop.ColorCatalogsItem.Cyan > 0)
{
- throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Magenta + "'.");
- }
+ var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack.LiquidType.Code == LiquidTypes.Cyan.ToInt32());
- liquidVolume.Volume = stop.ColorCatalogsItem.Magenta;
- }
+ if (liquidVolume == null)
+ {
+ throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Cyan + "'.");
+ }
- {
- var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.LiquidType == LiquidTypes.Yellow);
+ liquidVolume.Volume = stop.ColorCatalogsItem.Cyan;
+ }
- if (liquidVolume == null)
+ if (stop.ColorCatalogsItem.Magenta > 0)
{
- throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Yellow + "'.");
- }
+ var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack.LiquidType.Code == LiquidTypes.Magenta.ToInt32());
- liquidVolume.Volume = stop.ColorCatalogsItem.Yellow;
- }
+ if (liquidVolume == null)
+ {
+ throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Magenta + "'.");
+ }
- {
- var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.LiquidType == LiquidTypes.Black);
+ liquidVolume.Volume = stop.ColorCatalogsItem.Magenta;
+ }
- if (liquidVolume == null)
+ if (stop.ColorCatalogsItem.Yellow > 0)
{
- throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Black + "'.");
+ var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack.LiquidType.Code == LiquidTypes.Yellow.ToInt32());
+
+ if (liquidVolume == null)
+ {
+ throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Yellow + "'.");
+ }
+
+ liquidVolume.Volume = stop.ColorCatalogsItem.Yellow;
}
- liquidVolume.Volume = stop.ColorCatalogsItem.Black;
+ if (stop.ColorCatalogsItem.Black > 0)
+ {
+ var liquidVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack.LiquidType.Code == LiquidTypes.Black.ToInt32());
+
+ if (liquidVolume == null)
+ {
+ throw new NullReferenceException("Liquid volume not found for color conversion output liquid '" + LiquidTypes.Black + "'.");
+ }
+
+ liquidVolume.Volume = stop.ColorCatalogsItem.Black;
+ }
+ }
+ else
+ {
+ throw new InvalidOperationException($"No catalog item specified for segment color.");
}
}
- else if (!stop.IsTransparent)
+ else if (stop.BrushColorSpace == ColorSpaces.Volume)
{
- throw new InvalidOperationException($"No catalog item specified for segment color.");
+ stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
}
else
{
- stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
+ throw new InvalidOperationException($"Unsupported color space {stop.BrushColorSpace}.");
}
}
- else if (stop.BrushColorSpace == ColorSpaces.Volume)
- {
- stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
- }
- else
- {
- throw new InvalidOperationException($"Unsupported color space {stop.BrushColorSpace}.");
- }
- //}
if (job.EnableLubrication)
{
- var lubricantVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack != null && x.IdsPack.LiquidType != null && x.LiquidType == LiquidTypes.Lubricant);
+ var lubricantVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack != null && x.IdsPack.LiquidType != null && x.IdsPack.LiquidType.Code == LiquidTypes.Lubricant.ToInt32());
if (lubricantVolume != null)
{
@@ -2564,26 +1630,13 @@ namespace Tango.Integration.Operation
{
return Task.Factory.StartNew(() =>
{
- if (!CanPrint)
+ if (Status != MachineStatuses.ReadyToDye)
{
throw new InvalidOperationException("Could not print while status = " + Status);
}
- _jobStartDate = DateTime.UtcNow;
-
LogManager.Log($"Executing job '{job.Name}'...");
- if (MachineStatus == null)
- {
- LogManager.Log("Aborting job execution. No machine status received yet.");
- throw new InvalidOperationException("Cannot execute a job before at least one machine status has been received.");
- }
-
- _lastJobLiquidQuantities = new List<BL.ValueObjects.JobRunLiquidQuantity>();
- _jobUploadingStartDate = null;
- _jobHeatingStartDate = null;
- _jobActualStartDate = null;
-
RunningJob = null;
RunningJobStatus = null;
@@ -2592,59 +1645,10 @@ namespace Tango.Integration.Operation
job.NumberOfUnits = 1;
}
- if (job.EnableLubrication)
- {
- LogManager.Log("Job lubrication is enabled. Settings all brush stops to 100% lubricant.");
-
- try
- {
- foreach (var stop in job.Segments.SelectMany(x => x.BrushStops).Where(x => x.BrushColorSpace != ColorSpaces.Volume))
- {
- var lubricantVolume = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack != null && x.IdsPack.LiquidType != null && x.LiquidType == LiquidTypes.Lubricant);
-
- if (lubricantVolume != null)
- {
- lubricantVolume.Volume = 100;
- }
- }
- }
- catch (Exception ex)
- {
- System.Diagnostics.Debugger.Break();
- LogManager.Log(ex, "Error in setting automatic lubrication volumes.");
- }
- }
- else
- {
- LogManager.Log("Job lubrication is disabled.");
- }
-
- //Modify transparent/white brush stops. (Transparent/white stops should be all zeros and 100% TI)
- LogManager.Log("Modifying all transparent/white brush stops...");
- foreach (var stop in job.Segments.SelectMany(x => x.BrushStops).Where(x => x.IsTransparent || x.IsWhite).ToList())
- {
- foreach (var liquidVolume in stop.LiquidVolumes.Where(x => x.LiquidType != LiquidTypes.TransparentInk && x.LiquidType != LiquidTypes.Lubricant).ToList())
- {
- liquidVolume.Volume = 0;
- }
-
- var tiLiquid = stop.LiquidVolumes.SingleOrDefault(x => x.IdsPack != null && x.IdsPack.LiquidType != null && x.LiquidType == LiquidTypes.TransparentInk);
-
- if (tiLiquid != null)
- {
- tiLiquid.Volume = 100;
- }
- }
-
- //Validate liquid quantities..
if (EnableJobLiquidQuantityValidation)
{
ValidateJobLiquidQuantity(job, processParameters, job.Machine.Configuration);
}
- else
- {
- LogManager.Log("Liquid quantity validation is disabled. Skipping...");
- }
var originalJob = job;
var clonedJob = job.Clone();
@@ -2683,94 +1687,57 @@ namespace Tango.Integration.Operation
if (JobUnitsMethod == JobUnitsMethods.Device)
{
- ticket.NumberOfUnits = (uint)Math.Max(job.NumberOfUnits, 1);
+ ticket.NumberOfUnits = (uint)job.NumberOfUnits;
}
- //Spool parameters
ticket.Spool = new JobSpool();
+
job.SpoolType.MapPrimitivesTo(ticket.Spool);
- ticket.Spool.JobSpoolType = (JobSpoolType)job.SpoolType.Code;
- //Override spool parameters from RML Spool calibration
- var rmlSpool = job.Rml.RmlsSpools.FirstOrDefault(x => x.SpoolType.Guid == job.SpoolType.Guid);
- if (rmlSpool != null)
+ var spool = job.Machine.Spools.SingleOrDefault(x => x.SpoolType == job.SpoolType);
+
+ if (spool == null)
{
- ticket.Spool.RotationsPerPassage = rmlSpool.RotationsPerPassage != null ? rmlSpool.RotationsPerPassage.Value : ticket.Spool.RotationsPerPassage;
- ticket.Spool.Length = rmlSpool.Length != null ? rmlSpool.Length.Value : ticket.Spool.Length;
- ticket.Spool.BackingRate = rmlSpool.BackingRate != null ? rmlSpool.BackingRate.Value : ticket.Spool.BackingRate;
- ticket.Spool.BottomBackingRate = rmlSpool.BottomBackingRate != null ? rmlSpool.BottomBackingRate.Value : ticket.Spool.BottomBackingRate;
+ throw new InvalidOperationException("Job spool type is not registered with this machine.");
}
-
- //Override spool parameters from Machine Spool calibration
- var machineSpool = job.Machine.Spools.FirstOrDefault(x => x.SpoolType.Guid == job.SpoolType.Guid);
- if (machineSpool != null)
+ else
{
- ticket.Spool.LimitSwitchStartPointOffset = machineSpool.LimitSwitchStartPointOffset != null ? machineSpool.LimitSwitchStartPointOffset.Value : ticket.Spool.LimitSwitchStartPointOffset;
+ spool.MapPrimitivesTo(ticket.Spool);
}
- //Thread Parameters
- ticket.ThreadParameters = new ThreadParameters();
- job.Rml.MapPrimitivesTo(ticket.ThreadParameters);
+ ticket.Spool.JobSpoolType = (JobSpoolType)job.SpoolType.Code;
ProcessParameters process = new ProcessParameters();
processParameters.MapPrimitivesTo(process);
ticket.ProcessParameters = process;
- //Head Cleaning Parameters
- ticket.HeadCleaningParameters = new HeadCleaningParameters();
- ticket.HeadCleaningParameters.CleanerFlow = job.Rml.CleanerFlow;
- ticket.HeadCleaningParameters.ArcHeadCleaningMotorSpeed = job.Rml.ArcHeadCleaningMotorSpeed;
-
JobHandler handler = null;
- StorageFileHandler fileUploadHandler = null;
+ bool canceled = false;
bool requestSent = false;
handler = new JobHandler(async () =>
{
try
{
- if (handler.CanCancel)
+ if (!canceled)
{
- handler.CanCancel = false;
- handler.IsCanceled = true;
- LogManager.Log("Aborting current job...");
+ canceled = true;
LogManager.Log($"Aborting current gradient generation...");
GradientGenerationConfiguration.AbortCurrentGeneration();
- if (fileUploadHandler != null)
+ if (requestSent)
{
- LogManager.Log("Job is currently uploading. Aborting file upload...");
- await fileUploadHandler.Cancel();
- fileUploadHandler = null;
- LogManager.Log("Job upload canceled.");
- OnPrintingAborted(handler, clonedJob);
- handler.RaiseCanceled();
- if (Status != MachineStatuses.Disconnected)
- {
- Status = MachineStatuses.ReadyToDye;
- }
+ var result = await SendRequest<AbortJobRequest, AbortJobResponse>(new AbortJobRequest());
}
- else
- {
- if (requestSent)
- {
- var result = await SendRequest<AbortJobRequest, AbortJobResponse>(new AbortJobRequest(), new TransportRequestConfig() { ShouldLog = true });
- }
- SaveLastJobLiquidQuantities(clonedJob, originalJob.Machine.Configuration, processParameters, handler);
- OnPrintingAborted(handler, clonedJob);
- handler.RaiseCanceled();
- if (Status != MachineStatuses.Disconnected)
- {
- Status = MachineStatuses.ReadyToDye;
- }
- }
+ PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, clonedJob));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, clonedJob));
+ handler.RaiseCanceled();
}
}
catch (Exception ex)
{
- handler.CanCancel = true;
LogManager.Log(ex, "Failed to cancel job.");
}
}, clonedJob, ticket, processParameters, JobHandlingMode);
@@ -2788,15 +1755,9 @@ namespace Tango.Integration.Operation
ThreadFactory.StartNew(async () =>
{
- if (handler.IsCanceled)
- {
- Status = MachineStatuses.ReadyToDye;
- return;
- }
-
Status = MachineStatuses.GettingReady;
RunningJob = clonedJob;
- OnPrintingStarted(handler, clonedJob);
+ PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, clonedJob));
Thread.Sleep(100);
@@ -2827,28 +1788,6 @@ namespace Tango.Integration.Operation
}
}
- //Log Job Outline (Only first and last brush stops if gradient).
- var ticketToLog = ticket.Clone();
- ticketToLog.UploadStrategy = JobUploadStrategy;
- ticketToLog.Segments.Clear();
-
- foreach (var seg in ticket.Segments)
- {
- JobSegment segmentToLog = new JobSegment();
-
- segmentToLog.Length = seg.Length;
- segmentToLog.BrushStops.Add(seg.BrushStops.First());
-
- if (seg.BrushStops.Count > 1)
- {
- segmentToLog.BrushStops.Add(seg.BrushStops.Last());
- }
-
- ticketToLog.Segments.Add(segmentToLog);
- }
-
- LogManager.Log($"Job outline for '{job.Name}':\n{ticketToLog.ToJsonString()}");
-
if (handler.IsCanceled)
{
Status = MachineStatuses.ReadyToDye;
@@ -2886,13 +1825,10 @@ namespace Tango.Integration.Operation
request.JobTicket = ticket.Clone();
request.JobTicket.UploadStrategy = JobUploadStrategy;
- LogManager.Log($"Job upload method is set to {JobUploadStrategy}...");
+ //Use this if you want to log the entire job...
+ var logRequest = request.Clone();
- if (handler.IsCanceled)
- {
- Status = MachineStatuses.ReadyToDye;
- return;
- }
+ LogManager.Log($"Job upload method is set to {JobUploadStrategy}...");
var oldKeepAlive = UseKeepAlive;
@@ -2914,21 +1850,9 @@ namespace Tango.Integration.Operation
Message = "Uploading job description file...",
});
- if (handler.IsCanceled)
- {
- Status = MachineStatuses.ReadyToDye;
- return;
- }
-
LogManager.Log("Creating storage API manager...");
var storage = CreateStorageManager();
- if (handler.IsCanceled)
- {
- Status = MachineStatuses.ReadyToDye;
- return;
- }
-
//Suppress keep alive while job uploads.
//storage.SuppressKeepAliveWhileFileUploads = true;
UseKeepAlive = false; //This is a work around for Shlomo not managing to keep alive while parsing the file.
@@ -2947,183 +1871,346 @@ namespace Tango.Integration.Operation
String job_file_path = Path.Combine(storageInfo.Root, JOB_DESCRIPTION_FILE_NAME);
- LogManager.Log($"Uploading job description file '{job_file_path}' of size: {ms.Length} bytes...");
+ LogManager.Log($"Uploading job description file '{job_file_path}' of size: {ms.Length}");
+ await storage.UploadFileSync(job_file_path, ms);
+ LogManager.Log("Job upload completed successfully.");
- TaskCompletionSource<object> uploadCompletion = new TaskCompletionSource<object>();
- _jobUploadingStartDate = DateTime.UtcNow;
- fileUploadHandler = await storage.UploadFile(job_file_path, ms);
- bool uploadCanceled = false;
- Exception uploadException = null;
- fileUploadHandler.Canceled += (_, __) =>
- {
- uploadCanceled = true;
- uploadCompletion.SetResult(true);
- };
- fileUploadHandler.Completed += (_, __) =>
- {
- uploadCompletion.SetResult(true);
- };
- fileUploadHandler.Failed += (_, e) =>
+ ms.Dispose();
+
+ request.JobTicket.JobDescriptionFile = job_file_path;
+ }
+ catch (Exception ex)
+ {
+ UseKeepAlive = oldKeepAlive;
+ Status = MachineStatuses.ReadyToDye;
+ PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, clonedJob, ex));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, clonedJob));
+ handler.RaiseFailed(ex);
+ LogRequestFailed(request, ex);
+ return;
+ }
+ }
+
+ if (handler.IsCanceled)
+ {
+ UseKeepAlive = oldKeepAlive;
+ Status = MachineStatuses.ReadyToDye;
+ return;
+ }
+
+ LogRequestSent(request);
+ bool responseLogged = false;
+ bool completed = false; //Use this in case Shlomo is sending progress after completion.
+
+ SendContinuousRequest<JobRequest, JobResponse>(request, null, TimeSpan.FromSeconds(2)).Subscribe((response) =>
+ {
+ if (!completed)
+ {
+ handler.RaiseStatusReceived(response.Message.Status);
+ _last_job_status = handler.Status;
+
+ if (response.Message.Status.Progress > 0)
{
- uploadCompletion.SetException(e);
- };
+ if (oldKeepAlive != UseKeepAlive)
+ {
+ UseKeepAlive = oldKeepAlive;
+ }
+ }
- try
+ if (!responseLogged)
{
- await uploadCompletion.Task;
+ requestSent = true;
+ responseLogged = true;
+ LogResponseReceived(response.Message);
}
- catch (Exception ue)
+
+ if (JobHandlingMode == JobHandlerModes.SettingUp)
{
- if (uploadException != null)
- {
- throw uploadException;
- }
- else
+ if (response.Message.Status.Progress > processParameters.DryerBufferLengthMeters)
{
- throw ue;
+ if (!completed)
+ {
+ Status = MachineStatuses.Printing;
+ }
}
}
- finally
+ else
{
- try
+ if (response.Message.Status.Progress > 0)
{
- fileUploadHandler = null;
- ms.Dispose();
+ if (!completed)
+ {
+ Status = MachineStatuses.Printing;
+ }
}
- catch { }
}
+ }
+
+ }, (ex) =>
+ {
+ if (!completed)
+ {
+ completed = true;
- if (uploadCanceled)
+ UseKeepAlive = oldKeepAlive;
+
+ if (!(ex is ContinuousResponseAbortedException))
{
- return;
+ Status = MachineStatuses.ReadyToDye;
+
+ if (!handler.IsCanceled)
+ {
+ PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, clonedJob, ex));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, clonedJob));
+ handler.RaiseFailed(ex);
+ LogRequestFailed(request, ex);
+ }
}
else
{
- LogManager.Log("Job upload completed successfully.");
+ Status = MachineStatuses.ReadyToDye;
}
-
- request.JobTicket.JobDescriptionFile = job_file_path;
}
- catch (Exception ex)
+ }, () =>
+ {
+ if (!completed)
{
+ completed = true;
+
UseKeepAlive = oldKeepAlive;
+
Status = MachineStatuses.ReadyToDye;
- OnPrintingFailed(handler, clonedJob, ex);
- handler.RaiseFailed(ex);
- return;
+ PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, clonedJob));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, clonedJob));
+ handler.RaiseCompleted();
}
+ });
+ });
+
+ return handler;
+
+ });
+ }
+
+ /// <summary>
+ /// Executes a print stub for emulating a full job.
+ /// The process parameters table will be calculated using color conversion gamut region.
+ /// This method cannot accept brush stops with 'Volume' as color space.
+ /// </summary>
+ /// <param name="job">The job.</param>
+ /// <returns></returns>
+ /// <exception cref="InvalidOperationException">
+ /// Cannot print a brush stop with volume color space when process parameters table has not been specified.
+ /// or
+ /// Could not print while status = " + Status
+ /// </exception>
+ /// <exception cref="NullReferenceException">
+ /// Job RML is null
+ /// or
+ /// Could not locate an active process parameters tables group for RML " + job.Rml.Name
+ /// or
+ /// Could not locate process parameters table index " + processParametersTableIndex + " in group " + processGroup.Name + " for RML " + job.Rml.Name
+ /// or
+ /// Liquid volume not found for color conversion output liquid '" + outputLiquid.LiquidType + "'.
+ /// </exception>
+ public Task<JobHandler> PrintStub(Job job)
+ {
+ return Task.Factory.StartNew<JobHandler>(() =>
+ {
+
+ //Check not brush stop has color space 'Volume'.
+ if (job.Segments.SelectMany(x => x.BrushStops).ToList().Exists(x => x.ColorSpace.Code == ColorSpaces.Volume.ToInt32()))
+ {
+ throw new InvalidOperationException("Cannot print a brush stop with volume color space when process parameters table has not been specified.");
+ }
+
+ //Get least common process parameters table index.
+ int processParametersTableIndex = 0;
+
+ if (job.Rml == null)
+ {
+ throw new NullReferenceException("Job RML is null");
+ }
+
+ var processGroup = job.Rml.ProcessParametersTablesGroups.FirstOrDefault(x => x.Active);
+
+ if (processGroup == null)
+ {
+ throw new NullReferenceException("Could not locate an active process parameters tables group for RML " + job.Rml.Name);
+ }
+
+ var processParameters = processGroup.ProcessParametersTables.FirstOrDefault(x => x.TableIndex == processParametersTableIndex);
+
+ if (processParameters == null)
+ {
+ throw new NullReferenceException("Could not locate process parameters table index " + processParametersTableIndex + " in group " + processGroup.Name + " for RML " + job.Rml.Name);
+ }
+
+ //Perform color correction
+ foreach (var stop in job.Segments.SelectMany(x => x.BrushStops))
+ {
+ if (stop.LiquidVolumes == null)
+ {
+ stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
}
- else
+
+ foreach (var liquidVolume in stop.LiquidVolumes)
{
- _jobUploadingStartDate = DateTime.UtcNow;
+ liquidVolume.Volume = 10;
}
+ }
- if (handler.IsCanceled)
+ if (Status != MachineStatuses.ReadyToDye)
+ {
+ throw new InvalidOperationException("Could not print while status = " + Status);
+ }
+
+ RunningJob = null;
+ RunningJobStatus = null;
+
+ var originalJob = job;
+
+ CurrentProcessParameters = processParameters;
+
+ StubJobRequest request = new StubJobRequest();
+
+ if (job.NumberOfUnits < 1)
+ {
+ job.NumberOfUnits = 1;
+ }
+
+ job = job.Clone();
+
+ var segments = job.OrderedSegments.ToList();
+
+ for (int i = 0; i < job.NumberOfUnits - 1; i++)
+ {
+ foreach (var s in segments)
{
- UseKeepAlive = oldKeepAlive;
- Status = MachineStatuses.ReadyToDye;
- return;
+ job.Segments.Add(s);
}
+ }
- _machineStatusBeforeJobStart = MachineStatus.Clone();
+ JobTicket ticket = new JobTicket();
+ ticket.Guid = originalJob.Guid;
+ ticket.EnableInterSegment = job.EnableInterSegment;
+ ticket.InterSegmentLength = job.InterSegmentLength;
+ ticket.Length = job.Length;
+ ticket.WindingMethod = (JobWindingMethod)job.WindingMethod.Code;
+ ticket.Spool = new JobSpool();
- SaveCachedJobOperation(clonedJob); //Cache job and machine status for job resume!
+ job.SpoolType.MapPrimitivesTo(ticket.Spool);
+ ticket.Spool.JobSpoolType = (JobSpoolType)job.SpoolType.Code;
- bool responseLogged = false;
- bool completed = false; //Use this in case Shlomo is sending progress after completion.
+ ProcessParameters process = new ProcessParameters();
+ processParameters.MapPrimitivesTo(process);
+ ticket.ProcessParameters = process;
- _jobHeatingStartDate = DateTime.UtcNow;
+ foreach (var segment in job.OrderedSegments)
+ {
+ JobSegment jobSegment = new JobSegment();
+ jobSegment.Length = segment.LengthWithFactor;
+ jobSegment.Name = segment.Name;
- SendContinuousRequest<JobRequest, JobResponse>(request, new TransportContinuousRequestConfig() { ContinuousTimeout = ContinuousRequestTimeout.Add(TimeSpan.FromSeconds(3)), ShouldLog = true }).Subscribe((response) =>
- {
- if (!completed)
- {
- handler.RaiseStatusReceived(response.Message.Status);
- _last_job_status = handler.Status;
+ foreach (var stop in segment.BrushStops)
+ {
+ JobBrushStop jobStop = new JobBrushStop();
+ jobStop.Index = stop.StopIndex;
+ jobStop.OffsetPercent = stop.OffsetPercent;
+ jobStop.OffsetMeters = stop.OffsetMeters;
- if (response.Message.Status.Progress > 0)
- {
- if (oldKeepAlive != UseKeepAlive)
- {
- UseKeepAlive = oldKeepAlive;
- }
+ if (stop.LiquidVolumes == null)
+ {
+ stop.SetLiquidVolumes(job.Machine.Configuration, job.Rml, processParameters);
+ }
- if (_jobActualStartDate == null)
- {
- _jobActualStartDate = DateTime.UtcNow;
- }
- }
+ foreach (var liquidVolume in stop.LiquidVolumes)
+ {
+ JobDispenser dispenser = new JobDispenser();
+ dispenser.Index = liquidVolume.IdsPack.PackIndex;
+ dispenser.Volume = liquidVolume.Volume;
+ dispenser.DispenserLiquidType = (DispenserLiquidType)liquidVolume.IdsPack.LiquidType.Code;
+ dispenser.DispenserStepDivision = (DispenserStepDivision)liquidVolume.DispenserStepDivision;
- if (!responseLogged)
- {
- requestSent = true;
- responseLogged = true;
- }
+ dispenser.NanoliterPerPulse = liquidVolume.IdsPack.Dispenser.NlPerPulse;
- if (JobHandlingMode == JobHandlerModes.SettingUp)
- {
- if (response.Message.Status.Progress > processParameters.DryerBufferLengthMeters)
- {
- if (!completed)
- {
- Status = MachineStatuses.Printing;
- }
- }
- }
- else
- {
- if (response.Message.Status.Progress > 0)
- {
- if (!completed)
- {
- Status = MachineStatuses.Printing;
- }
- }
- }
- }
+ dispenser.LiquidMaxNanoliterPerCentimeter = liquidVolume.LiquidMaxNanoliterPerCentimeter;
+ dispenser.NanoliterPerCentimeter = liquidVolume.NanoliterPerCentimeter;
+ dispenser.NanolitterPerSecond = liquidVolume.NanoliterPerSecond;
+ dispenser.PulsePerSecond = liquidVolume.PulsePerSecond;
- }, (ex) =>
- {
- if (!completed)
- {
- completed = true;
+ jobStop.Dispensers.Add(dispenser);
+ }
- UseKeepAlive = oldKeepAlive;
+ jobSegment.BrushStops.Add(jobStop);
+ }
- if (Status != MachineStatuses.Disconnected)
- {
- Status = MachineStatuses.ReadyToDye;
- }
+ ticket.Segments.Add(jobSegment);
+ }
- if (!handler.IsCanceled)
- {
- SaveLastJobLiquidQuantities(originalJob, originalJob.Machine.Configuration, processParameters, handler);
+ request.JobTicket = ticket;
- Exception finalException = ex;
+ JobHandler handler = null;
- if (ex is ContinuousResponseAbortedException continuousException)
- {
- finalException = new ContinuousResponseAbortedException($"Job aborted by the embedded device ({continuousException.Container.ErrorMessage}).");
- }
+ handler = new JobHandler(async () =>
+ {
+ try
+ {
+ var result = await SendRequest<StubAbortJobRequest, StubAbortJobResponse>(new StubAbortJobRequest());
+ PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ handler.RaiseCanceled();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Failed to cancel job.");
+ }
+ }, originalJob, ticket, processParameters, JobHandlingMode);
- OnPrintingFailed(handler, originalJob, finalException);
- handler.RaiseFailed(finalException);
- }
- }
- }, () =>
- {
- if (!completed)
- {
- completed = true;
+ handler.StatusChanged += (x, s) =>
+ {
+ RunningJobStatus = s;
+ };
+
+ LogRequestSent(request);
+ bool responseLogged = false;
- UseKeepAlive = oldKeepAlive;
+ SendContinuousRequest<StubJobRequest, StubJobResponse>(request, null, TimeSpan.FromSeconds(2)).Subscribe((response) =>
+ {
+ handler.RaiseStatusReceived(response.Message.Status);
+
+ if (!responseLogged)
+ {
+ responseLogged = true;
+ Status = MachineStatuses.Printing;
+ RunningJob = originalJob;
+ PrintingStarted?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ LogResponseReceived(response.Message);
+ }
+ }, (ex) =>
+ {
+ if (!(ex is ContinuousResponseAbortedException))
+ {
+ Status = MachineStatuses.ReadyToDye;
- Status = MachineStatuses.ReadyToDye;
- SaveLastJobLiquidQuantities(clonedJob, originalJob.Machine.Configuration, processParameters, handler);
- OnPrintingCompleted(handler, clonedJob);
- handler.RaiseCompleted();
- }
- });
+ if (!handler.IsCanceled)
+ {
+ PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, originalJob, ex));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ handler.RaiseFailed(ex);
+ LogRequestFailed(request, ex);
+ }
+ }
+ else
+ {
+ Status = MachineStatuses.ReadyToDye;
+ }
+ }, () =>
+ {
+ Status = MachineStatuses.ReadyToDye;
+ PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, originalJob));
+ handler.RaiseCompleted();
});
return handler;
@@ -3147,10 +2234,13 @@ namespace Tango.Integration.Operation
try
{
CurrentProcessParameters = processParameters;
- response = await SendRequest<UploadProcessParametersRequest, UploadProcessParametersResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ response = await SendRequest<UploadProcessParametersRequest, UploadProcessParametersResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3165,8 +2255,6 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<UploadHardwareConfigurationResponse> UploadHardwareConfiguration(HardwareVersion hardwareVersion, Configuration configuration)
{
- _machineConfiguration = configuration;
-
try
{
hardwareVersion = configuration.GetHardwareConfiguration().Merge(hardwareVersion);
@@ -3251,14 +2339,14 @@ namespace Tango.Integration.Operation
try
{
- LogManager.Log($"Sending '{nameof(UploadHardwareConfigurationRequest)}'...");
- LogManager.Log($"{nameof(UploadHardwareConfigurationRequest)} request:\n{request.HardwareConfiguration.ToJsonString()}", LogCategory.Debug);
-
CurrentHardwareConfiguration = hardwareConfiguration;
- response = await SendRequest<UploadHardwareConfigurationRequest, UploadHardwareConfigurationResponse>(request, new TransportRequestConfig() { ShouldLog = false });
+ LogRequestSent(request);
+ response = await SendRequest<UploadHardwareConfigurationRequest, UploadHardwareConfigurationResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3276,10 +2364,13 @@ namespace Tango.Integration.Operation
try
{
- response = await SendRequest<MotorJoggingRequest, MotorJoggingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ response = await SendRequest<MotorJoggingRequest, MotorJoggingResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3293,7 +2384,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<MotorAbortJoggingResponse> StopMotorJogging(MotorAbortJoggingRequest request)
{
- return await SendRequest<MotorAbortJoggingRequest, MotorAbortJoggingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<MotorAbortJoggingRequest, MotorAbortJoggingResponse>(request);
}
/// <summary>
@@ -3303,7 +2395,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public IObservable<MotorHomingResponse> StartMotorHoming(MotorHomingRequest request)
{
- return SendContinuousRequest<MotorHomingRequest, MotorHomingResponse>(request, new TransportContinuousRequestConfig() { ContinuousTimeout = ContinuousRequestTimeout, ShouldLog = true }).Select(x => x.Message);
+ LogRequestSent(request);
+ return SendContinuousRequest<MotorHomingRequest, MotorHomingResponse>(request, null, TimeSpan.FromSeconds(5)).Select(x => x.Message);
}
/// <summary>
@@ -3313,7 +2406,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<MotorAbortHomingResponse> StopMotorHoming(MotorAbortHomingRequest request)
{
- return await SendRequest<MotorAbortHomingRequest, MotorAbortHomingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<MotorAbortHomingRequest, MotorAbortHomingResponse>(request);
}
/// <summary>
@@ -3323,7 +2417,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<DispenserJoggingResponse> StartDispenserJogging(DispenserJoggingRequest request)
{
- return await SendRequest<DispenserJoggingRequest, DispenserJoggingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<DispenserJoggingRequest, DispenserJoggingResponse>(request);
}
/// <summary>
@@ -3333,7 +2428,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<DispenserAbortJoggingResponse> StopDispenserJogging(DispenserAbortJoggingRequest request)
{
- return await SendRequest<DispenserAbortJoggingRequest, DispenserAbortJoggingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<DispenserAbortJoggingRequest, DispenserAbortJoggingResponse>(request);
}
/// <summary>
@@ -3343,7 +2439,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public IObservable<DispenserHomingResponse> StartDispenserHoming(DispenserHomingRequest request)
{
- return SendContinuousRequest<DispenserHomingRequest, DispenserHomingResponse>(request, new TransportContinuousRequestConfig() { ContinuousTimeout = ContinuousRequestTimeout, ShouldLog = true }).Select(x => x.Message);
+ LogRequestSent(request);
+ return SendContinuousRequest<DispenserHomingRequest, DispenserHomingResponse>(request, null, TimeSpan.FromSeconds(5)).Select(x => x.Message);
}
/// <summary>
@@ -3353,7 +2450,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<DispenserAbortHomingResponse> StopDispenserHoming(DispenserAbortHomingRequest request)
{
- return await SendRequest<DispenserAbortHomingRequest, DispenserAbortHomingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<DispenserAbortHomingRequest, DispenserAbortHomingResponse>(request);
}
/// <summary>
@@ -3363,7 +2461,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<SetDigitalOutResponse> SetDigitalOut(SetDigitalOutRequest request)
{
- return await SendRequest<SetDigitalOutRequest, SetDigitalOutResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<SetDigitalOutRequest, SetDigitalOutResponse>(request);
}
/// <summary>
@@ -3373,7 +2472,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<ThreadJoggingResponse> StartThreadJogging(ThreadJoggingRequest request)
{
- return await SendRequest<ThreadJoggingRequest, ThreadJoggingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<ThreadJoggingRequest, ThreadJoggingResponse>(request);
}
/// <summary>
@@ -3383,7 +2483,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<ThreadAbortJoggingResponse> StopThreadJogging(ThreadAbortJoggingRequest request)
{
- return await SendRequest<ThreadAbortJoggingRequest, ThreadAbortJoggingResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<ThreadAbortJoggingRequest, ThreadAbortJoggingResponse>(request);
}
/// <summary>
@@ -3393,7 +2494,8 @@ namespace Tango.Integration.Operation
/// <returns></returns>
public async Task<SetComponentValueResponse> SetComponentValue(SetComponentValueRequest request)
{
- return await SendRequest<SetComponentValueRequest, SetComponentValueResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<SetComponentValueRequest, SetComponentValueResponse>(request);
}
/// <summary>
@@ -3414,10 +2516,13 @@ namespace Tango.Integration.Operation
try
{
- response = await SendRequest<SetHeaterStateRequest, SetHeaterStateResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ response = await SendRequest<SetHeaterStateRequest, SetHeaterStateResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3443,10 +2548,13 @@ namespace Tango.Integration.Operation
try
{
- response = await SendRequest<SetBlowerStateRequest, SetBlowerStateResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ response = await SendRequest<SetBlowerStateRequest, SetBlowerStateResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3470,10 +2578,13 @@ namespace Tango.Integration.Operation
try
{
- response = await SendRequest<SetValveStateRequest, SetValveStateResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ response = await SendRequest<SetValveStateRequest, SetValveStateResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3488,7 +2599,8 @@ namespace Tango.Integration.Operation
public async Task<ResolveEventResponse> ResolveEvent(PMR.Diagnostics.EventType eventType)
{
ResolveEventRequest request = new ResolveEventRequest() { Type = eventType };
- return await SendRequest<ResolveEventRequest, ResolveEventResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ return await SendRequest<ResolveEventRequest, ResolveEventResponse>(request);
}
/// <summary>
@@ -3508,10 +2620,13 @@ namespace Tango.Integration.Operation
Value = 0x0
};
- response = await SendRequest<StubFpgaWriteRegRequest, StubFpgaWriteRegResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ response = await SendRequest<StubFpgaWriteRegRequest, StubFpgaWriteRegResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3525,10 +2640,13 @@ namespace Tango.Integration.Operation
Value = 0x1
};
- response = await SendRequest<StubFpgaWriteRegRequest, StubFpgaWriteRegResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ LogRequestSent(request);
+ response = await SendRequest<StubFpgaWriteRegRequest, StubFpgaWriteRegResponse>(request);
+ LogResponseReceived(response);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -3536,16 +2654,6 @@ namespace Tango.Integration.Operation
}
/// <summary>
- /// Directs the embedded device to switch to stand-by mode.
- /// </summary>
- /// <returns></returns>
- public async Task StandBy()
- {
- LogManager.Log("Switching to stand-by mode...");
- await SendRequest<StandByRequest, StandByResponse>(new StandByRequest(), new TransportRequestConfig() { ShouldLog = true });
- }
-
- /// <summary>
/// Resets the device through the DFU channel.
/// </summary>
/// <returns></returns>
@@ -3608,10 +2716,8 @@ namespace Tango.Integration.Operation
/// Upgrades the firmware.
/// </summary>
/// <param name="tfpStream">The TFP stream (Tango Firmware Package File).</param>
- /// <param name="isEmulated">Specify whether the connected machine is emulated and to skip the actual DFU interface.</param>
/// <returns></returns>
- /// <exception cref="InvalidOperationException"></exception>
- public virtual async Task<FirmwareUpgradeHandler> UpgradeFirmware(Stream tfpStream, bool isEmulated = false)
+ public async Task<FirmwareUpgradeHandler> UpgradeFirmware(Stream tfpStream)
{
bool cancel = false;
ZipFile zip = null;
@@ -3626,60 +2732,33 @@ namespace Tango.Integration.Operation
try
{
- LogManager.Log("Starting firmware upgrade...");
- LogManager.Log($"Firmware upgrade flags: {String.Join(", ", FirmwareUpgradeMode.GetFlags<FirmwareUpgradeModes>().Select(x => x.ToString()))}");
-
- if (!CanPrint)
+ if (Status != MachineStatuses.ReadyToDye)
{
throw LogManager.Log(new InvalidOperationException($"Could not perform firmware upgrade while operator status is '{Status}'."));
}
- LogManager.Log("Extracting tfp package...");
var package_info = await GetFirmwarePackageInfo(tfpStream);
tfpStream.Position = 0;
- LogManager.Log("Validating TFP package...");
- package_info.Validate();
-
- LogManager.Log("Reading zip stream...");
zip = ZipFile.Read(tfpStream);
- double packageUploadTotal = 0;
-
- try
- {
- packageUploadTotal = zip.Entries.Sum(x => x.UncompressedSize);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error calculating total package upload bytes.");
- }
-
- LogManager.Log("Creating storage manager...");
var storage = CreateStorageManager();
- LogManager.Log("Getting storage drive information...");
var drive = await storage.GetStorageDrive();
- LogManager.Log($"Storage drive info:\n{drive.ToJsonString()}");
- LogManager.Log("Getting root folder...");
var root = await storage.GetRootFolder();
- LogManager.Log($"Root folder: '{root.Path}'");
var existing_folder = root.Items.SingleOrDefault(x => x.Name == FIRMWARE_UPGRADE_FOLDER_NAME);
if (existing_folder != null)
{
- LogManager.Log("Root folder exists. Deleting...");
await storage.DeleteItem(existing_folder);
}
String package_folder = Path.Combine(drive.Root, FIRMWARE_UPGRADE_FOLDER_NAME);
- LogManager.Log($"Creating new folder: '{package_folder}'.");
await storage.CreateFolder(package_folder);
List<StorageFileHandler> handlers = new List<StorageFileHandler>();
List<ZipEntry> entries = zip.Entries.ToList();
List<Stream> streams = new List<Stream>();
- LogManager.Log("Disabling keep alive...");
var keepAlive = UseKeepAlive;
UseKeepAlive = false;
@@ -3702,102 +2781,49 @@ namespace Tango.Integration.Operation
{
if (FirmwareUpgradeMode.HasFlag(FirmwareUpgradeModes.DFU))
{
- if (package_info.ContainsMcu())
- {
- LogManager.Log("DFU enabled. Starting upgrade via DFU...");
- LogManager.Log("Extracting MCU file...");
- ZipEntry mcuEntry = null;
- try
- {
- mcuEntry = entries.Single(x => x.FileName == package_info.FileDescriptors.Single(y => y.Destination == VersionFileDestination.Mcu).FileName);
- entries.Remove(mcuEntry);
- }
- catch (Exception ex)
- {
- LogManager.Log(ex, "Error extracting MCU file from package.");
- upgradeHandler.RaiseFailed(new IOException("Error retrieving MCU file from package.", ex));
- return;
- }
-
- MemoryStream ms = new MemoryStream();
- mcuEntry.Extract(ms);
- ms.Position = 0;
- byte[] data = ms.ToArray();
- ms.Dispose();
+ var mcuEntry = zip.Entries.Single(x => x.FileName == package_info.FileDescriptors.Single(y => y.Destination == VersionFileDestination.Mcu).FileName);
+ MemoryStream ms = new MemoryStream();
+ mcuEntry.Extract(ms);
+ ms.Position = 0;
+ byte[] data = ms.ToArray();
+ ms.Dispose();
- FirmwareUpgradeManager upgradeManager = new FirmwareUpgradeManager();
- upgradeManager.UpgradeProgress += (sender, e) =>
- {
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Upgrading, e.State.ToDescription(), false, e.Total, e.Progress);
- };
-
- LogManager.Log("Disconnecting adapter...");
- Adapter.Disconnect().Wait();
+ FirmwareUpgradeManager upgradeManager = new FirmwareUpgradeManager();
+ upgradeManager.UpgradeProgress += (sender, e) =>
+ {
+ upgradeHandler.Total = (long)e.Total;
+ upgradeHandler.RaiseProgress((long)e.Progress, FirmwareUpgradeStatus.Upgrading, e.State.ToDescription());
+ };
- ResetEvents();
- ResetInkFllingStatus();
+ Adapter.Disconnect().Wait();
- try
- {
- if (!isEmulated)
- {
- LogManager.Log("Upgrading...");
- upgradeManager.PerformUpgrade(data).Wait();
- }
- else
- {
- LogManager.Log("Upgrading (emulated)...");
- Thread.Sleep(3000);
- }
- }
- catch (Exception ex)
- {
- LogManager.Log("Firmware upgrade failed while doing DFU upload. We need to destroy the whole transport layer.", LogCategory.Error);
- Status = MachineStatuses.Disconnected;
- upgradeHandler.RaiseFailed(ex);
- OnFailed(ex);
- return;
- }
+ if (MachineEventsStateProvider != null)
+ {
+ MachineEventsStateProvider.Reset();
+ }
- LogManager.Log("Waiting for the device...");
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Upgrading, "Waiting for the device...");
- Thread.Sleep(5000);
+ upgradeManager.PerformUpgrade(data).Wait();
- LogManager.Log("Reconnecting adapter...");
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Upgrading, "Connecting...");
- Adapter.Connect().Wait();
+ upgradeHandler.RaiseProgress(100, FirmwareUpgradeStatus.Upgrading, "Waiting for the device...");
+ Thread.Sleep(5000);
- Connect().Wait();
+ upgradeHandler.RaiseProgress(100, FirmwareUpgradeStatus.Upgrading, "Connecting...");
+ Adapter.Connect().Wait();
+ Connect().Wait();
- LogManager.Log("Connected...");
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Upgrading, "Connected.");
- Thread.Sleep(2000);
+ upgradeHandler.RaiseProgress(100, FirmwareUpgradeStatus.Upgrading, "Connected.");
+ Thread.Sleep(2000);
- LogManager.Log("Waiting...");
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Upgrading, "Waiting...");
- Thread.Sleep(2000);
+ upgradeHandler.RaiseProgress(100, FirmwareUpgradeStatus.Upgrading, "Waiting...");
+ Thread.Sleep(2000);
- Status = MachineStatuses.Upgrading;
- }
- else
- {
- LogManager.Log("DFU is enabled but no MCU file was found on the package. Skipping...");
- }
+ Status = MachineStatuses.Upgrading;
}
- //Upload tfp package only if specified in flag && package info contains more files other than the mcu bin file.
if (FirmwareUpgradeMode.HasFlag(FirmwareUpgradeModes.TFP_PACKAGE))
{
- if (package_info.ContainsNoneMcu())
- {
- LogManager.Log("TFP package is enabled. Starting upload...");
- uploadNext();
- }
- else
- {
- LogManager.Log("TFP package is enabled but no other files other than the MCU file were found on the package. Skipping...");
- postActivation();
- }
+ upgradeHandler.Total = zip.Entries.Sum(x => x.UncompressedSize);
+ uploadNext();
}
else
{
@@ -3821,8 +2847,6 @@ namespace Tango.Integration.Operation
var entry = entries.First();
entries.Remove(entry);
- LogManager.Log($"Uploading file '{entry.FileName}'...");
-
var reader = entry.OpenReader();
streams.Add(reader);
@@ -3839,7 +2863,7 @@ namespace Tango.Integration.Operation
return;
}
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Uploading, $"Uploading '{entry.FileName}'...", false, packageUploadTotal, upgradeHandler.Current + e.Delta);
+ upgradeHandler.RaiseProgress(upgradeHandler.Current + e.Delta, FirmwareUpgradeStatus.Uploading, $"Uploading '{entry.FileName}'...");
};
}
catch (Exception ex)
@@ -3858,12 +2882,11 @@ namespace Tango.Integration.Operation
{
try
{
- LogManager.Log("Validating version...");
streams.ForEach(x => x.Dispose());
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Validating, "Validating version...");
+ upgradeHandler.RaiseProgress(upgradeHandler.Total, FirmwareUpgradeStatus.Validating, "Validating version...");
var validateRequest = new ValidateVersionRequest();
validateRequest.Path = package_folder;
- var validateResponse = SendRequest<ValidateVersionRequest, ValidateVersionResponse>(validateRequest, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(10), ShouldLog = true }).Result;
+ var validateResponse = SendRequest<ValidateVersionRequest, ValidateVersionResponse>(validateRequest, TimeSpan.FromSeconds(10)).Result;
activate();
}
catch (Exception ex)
@@ -3876,42 +2899,10 @@ namespace Tango.Integration.Operation
{
try
{
- TaskCompletionSource<object> activationCompletion = new TaskCompletionSource<object>();
-
- bool completed = false;
-
- LogManager.Log("Activating version...");
-
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Activating, "Activating version...");
-
+ upgradeHandler.RaiseProgress(upgradeHandler.Total, FirmwareUpgradeStatus.Activating, "Activating version...");
var activateRequest = new ActivateVersionRequest();
activateRequest.Path = package_folder;
-
- SendContinuousRequest<ActivateVersionRequest, ActivateVersionResponse>(activateRequest, new TransportContinuousRequestConfig() { Timeout = TimeSpan.FromSeconds(10), ContinuousTimeout = TimeSpan.FromSeconds(10), ShouldLog = true })
- .Subscribe((response) =>
- {
- if (!completed && response.Message.Progress > 0)
- {
- upgradeHandler.RaiseProgress(FirmwareUpgradeStatus.Activating, "Activating version...", false, response.Message.Total, response.Message.Progress);
- }
- }, (ex) =>
- {
- if (!completed)
- {
- completed = true;
- activationCompletion.SetException(ex);
- }
- }, () =>
- {
- if (!completed)
- {
- completed = true;
- activationCompletion.SetResult(true);
- }
- });
-
- var result = activationCompletion.Task.GetAwaiter().GetResult();
-
+ var activateResponse = SendRequest<ActivateVersionRequest, ActivateVersionResponse>(activateRequest, TimeSpan.FromSeconds(10)).Result;
postActivation();
}
catch (Exception ex)
@@ -3922,10 +2913,8 @@ namespace Tango.Integration.Operation
postActivation = new Action(() =>
{
- LogManager.Log("Firmware upgrade completed.");
upgradeHandler.RaiseCompleted();
Status = MachineStatuses.ReadyToDye;
- LogManager.Log("Enabling keep alive...");
UseKeepAlive = keepAlive;
});
@@ -3975,7 +2964,7 @@ namespace Tango.Integration.Operation
{
var validateRequest = new ValidateVersionRequest();
validateRequest.Path = path;
- await SendRequest<ValidateVersionRequest, ValidateVersionResponse>(validateRequest, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(10), ShouldLog = true });
+ await SendRequest<ValidateVersionRequest, ValidateVersionResponse>(validateRequest, TimeSpan.FromSeconds(10));
}
/// <summary>
@@ -3986,200 +2975,7 @@ namespace Tango.Integration.Operation
{
var activateRequest = new ActivateVersionRequest();
activateRequest.Path = path;
- await SendRequest<ActivateVersionRequest, ActivateVersionResponse>(activateRequest, new TransportRequestConfig() { Timeout = TimeSpan.FromSeconds(10), ShouldLog = true });
- }
-
- /// <summary>
- /// Turns off the machine.
- /// </summary>
- /// <returns></returns>
- public Task<PowerDownHandler> PowerDown()
- {
- if (_isPowerDownRequestInProgress)
- {
- throw new InvalidOperationException("Machine power down is already in progress.");
- }
-
- _isPowerDownRequestInProgress = true;
-
- PowerDownHandler handler = new PowerDownHandler(new Task(() =>
- {
- _isPowerDownRequestInProgress = false;
- Thread.Sleep(2000);
- var r = SendRequest<AbortPowerDownRequest, AbortPowerDownResponse>(new AbortPowerDownRequest(), new TransportRequestConfig() { ShouldLog = true }).Result;
- }));
-
- Task.Factory.StartNew(() =>
- {
- Thread.Sleep(100);
-
- bool firstResponse = true;
-
- SendContinuousRequest<StartPowerDownRequest, StartPowerDownResponse>(new StartPowerDownRequest(), new TransportContinuousRequestConfig() { ContinuousTimeout = TimeSpan.FromSeconds(2), ShouldLog = true }).ObserveOn(new NewThreadScheduler()).Subscribe((response) =>
- {
- if (firstResponse)
- {
- firstResponse = false;
- Status = MachineStatuses.ShuttingDown;
- }
-
- handler.RaiseStatusChanged(response);
- }, (ex) =>
- {
- if (_isPowerDownRequestInProgress)
- {
- _isPowerDownRequestInProgress = false;
- LogManager.Log(ex, "Power down error.");
- handler.RaiseFailed(ex);
- }
- }, () =>
- {
- if (_isPowerDownRequestInProgress)
- {
- _isPowerDownRequestInProgress = false;
- handler.RaiseCompleted();
- }
- });
- });
-
- PowerDownStarted?.Invoke(this, new PowerDownStartedEventArgs()
- {
- Handler = handler,
- });
-
- return Task.FromResult(handler);
- }
-
- /// <summary>
- /// Turns off the machine.
- /// </summary>
- /// <returns></returns>
- public Task<HeadCleaningHandler> PerformHeadCleaning()
- {
- if (_isHeadCleaningInProgress)
- {
- throw new InvalidOperationException("Head cleaning is already in progress.");
- }
-
- if (!CanPrint)
- {
- throw new InvalidOperationException($"Cannot perform head cleaning while machine status is '{Status}'.");
- }
-
- _isHeadCleaningInProgress = true;
- bool _completed = false;
-
- HeadCleaningHandler handler = null;
- handler = new HeadCleaningHandler(() =>
- {
- _isHeadCleaningInProgress = false;
- Thread.Sleep(1000);
-
- if (!_completed)
- {
- _completed = true;
- OnHeadCleaningEnded(handler, JobRunStatus.Aborted);
- }
-
- var r = SendRequest<AbortHeadCleaningRequest, AbortHeadCleaningResponse>(new AbortHeadCleaningRequest(), new TransportRequestConfig() { ShouldLog = true }).Result;
- });
-
- Task.Factory.StartNew(() =>
- {
- Thread.Sleep(100);
-
- _lastJobLiquidQuantities = new List<BL.ValueObjects.JobRunLiquidQuantity>();
- _machineStatusBeforeJobStart = MachineStatus.Clone();
-
- bool firstResponse = true;
- _jobStartDate = DateTime.UtcNow;
-
- SendContinuousRequest<StartHeadCleaningRequest, StartHeadCleaningResponse>(new StartHeadCleaningRequest(), new TransportContinuousRequestConfig() { ContinuousTimeout = TimeSpan.FromSeconds(5), ShouldLog = true }).ObserveOn(new NewThreadScheduler()).Subscribe((response) =>
- {
- if (firstResponse)
- {
- firstResponse = false;
- }
-
- handler.RaiseStatusChanged(response);
- }, (ex) =>
- {
- if (!(ex is ContinuousResponseAbortedException))
- {
- _isHeadCleaningInProgress = false;
- LogManager.Log(ex, "Head cleaning error.");
- handler.RaiseFailed(ex);
- }
-
- if (!_completed)
- {
- _completed = true;
- OnHeadCleaningEnded(handler, JobRunStatus.Failed);
- }
- }, () =>
- {
- _isHeadCleaningInProgress = false;
- handler.RaiseCompleted();
-
- if (!_completed)
- {
- _completed = true;
- OnHeadCleaningEnded(handler, JobRunStatus.Completed);
- }
- });
- });
-
- return Task.FromResult(handler);
- }
-
- /// <summary>
- /// Starts the automatic thread loading process.
- /// </summary>
- /// <returns></returns>
- public async Task StartThreadLoading()
- {
- var response = await SendRequest<TryThreadLoadingRequest, TryThreadLoadingResponse>(new TryThreadLoadingRequest());
- }
-
- /// <summary>
- /// Continues the current thread loading.
- /// </summary>
- /// <param name="processParameters">The process parameters.</param>
- /// <returns></returns>
- public async Task ContinueThreadLoading(ProcessParametersTable processParameters)
- {
- var process = processParameters.ToProcessParametersPMR();
- var r = await SendRequest<ContinueThreadLoadingRequest, ContinueThreadLoadingResponse>(new ContinueThreadLoadingRequest()
- {
- ProcessParameters = process,
- }, new TransportRequestConfig() { ShouldLog = true });
- }
-
- /// <summary>
- /// Attempts to jog the thread in order to check whether there are no thread breaking issues.
- /// </summary>
- /// <returns></returns>
- public async Task AttemptThreadJogging()
- {
- var r = await SendRequest<AttemptThreadJoggingRequest, AttemptThreadJoggingResponse>(new AttemptThreadJoggingRequest()
- {
-
- }, new TransportRequestConfig() { ShouldLog = true, Timeout = TimeSpan.FromSeconds(20) });
- }
-
- /// <summary>
- /// Emulates a hardware event that will last for the specified timeout.
- /// </summary>
- /// <param name="ev">Type of the event.</param>
- /// <param name="timeout">The timeout.</param>
- public async void PushEmulatedEvent(Event ev, TimeSpan timeout)
- {
- if (!_emulatedEvents.Exists(x => x.Type == ev.Type))
- {
- _emulatedEvents.Add(ev);
- await Task.Delay(timeout);
- _emulatedEvents.Remove(ev);
- }
+ await SendRequest<ActivateVersionRequest, ActivateVersionResponse>(activateRequest, TimeSpan.FromSeconds(10));
}
#endregion
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/MachineStatuses.cs b/Software/Visual_Studio/Tango.Integration/Operation/MachineStatuses.cs
index fb21b27fa..14774f73a 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/MachineStatuses.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/MachineStatuses.cs
@@ -10,24 +10,22 @@ namespace Tango.Integration.Operation
public enum MachineStatuses
{
[Description("Disconnected")]
- Disconnected = 0,
- [Description("Getting Ready")]
- PowerUp = 1,
+ Disconnected,
[Description("Standby")]
- Standby = 2,
+ Standby,
[Description("Ready To Dye")]
- ReadyToDye = 3,
+ ReadyToDye,
[Description("Getting Ready")]
- GettingReady = 4,
+ GettingReady,
[Description("Dyeing")]
- Printing = 5,
+ Printing,
[Description("Service")]
- Service = 6,
+ Service,
[Description("Upgrading")]
- Upgrading = 7,
+ Upgrading,
[Description("Shutting Down")]
- ShuttingDown = 8,
+ ShuttingDown,
[Description("Error")]
- Error = 9,
+ Error,
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/PowerDownHandler.cs b/Software/Visual_Studio/Tango.Integration/Operation/PowerDownHandler.cs
deleted file mode 100644
index 03593d6c6..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/PowerDownHandler.cs
+++ /dev/null
@@ -1,77 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.Core;
-using Tango.PMR.Power;
-
-namespace Tango.Integration.Operation
-{
- public class PowerDownHandler : ExtendedObject
- {
- private Task _abortTask;
-
- public event EventHandler<PowerDownStatusChangedEventArgs> StatusChanged;
- public event EventHandler<Exception> Failed;
- public event EventHandler Completed;
-
- private StartPowerDownResponse _status;
- public StartPowerDownResponse Status
- {
- get { return _status; }
- set { _status = value; RaisePropertyChangedAuto(); }
- }
-
- internal PowerDownHandler(Task abortTask)
- {
- _abortTask = abortTask;
-
- Status = new StartPowerDownResponse()
- {
- Message = "Powering down...",
- State = PowerDownState.None,
- };
- }
-
- internal void RaiseStatusChanged(StartPowerDownResponse status)
- {
- OnStatusChanged(status);
- }
-
- internal void RaiseFailed(Exception ex)
- {
- OnFailed(ex);
- }
-
- internal void RaiseCompleted()
- {
- OnCompleted();
- }
-
- private void OnStatusChanged(StartPowerDownResponse status)
- {
- Status = status;
- StatusChanged?.Invoke(this, new PowerDownStatusChangedEventArgs()
- {
- Status = status
- });
- }
-
- private void OnCompleted()
- {
- Completed?.Invoke(this, new EventArgs());
- }
-
- private void OnFailed(Exception ex)
- {
- Failed?.Invoke(this, ex);
- }
-
- public async Task Abort()
- {
- _abortTask.Start();
- await _abortTask;
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/PowerDownStartedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/PowerDownStartedEventArgs.cs
deleted file mode 100644
index 7dcd4fb39..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/PowerDownStartedEventArgs.cs
+++ /dev/null
@@ -1,13 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-
-namespace Tango.Integration.Operation
-{
- public class PowerDownStartedEventArgs : EventArgs
- {
- public PowerDownHandler Handler { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/PowerDownStatusChangedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/PowerDownStatusChangedEventArgs.cs
deleted file mode 100644
index 5c64b41a2..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/PowerDownStatusChangedEventArgs.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.PMR.Power;
-
-namespace Tango.Integration.Operation
-{
- public class PowerDownStatusChangedEventArgs : EventArgs
- {
- public StartPowerDownResponse Status { get; set; }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs
index ff2fc4623..fe8a573a5 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs
@@ -4,7 +4,6 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL.Entities;
-using Tango.BL.ValueObjects;
namespace Tango.Integration.Operation
{
@@ -12,16 +11,9 @@ namespace Tango.Integration.Operation
{
public JobHandler JobHandler { get; private set; }
public Job Job { get; private set; }
- public List<JobRunLiquidQuantity> LiquidQuantities { get; set; }
- public DateTime StartDate { get; set; }
- public DateTime? UploadingStartTime { get; set; }
- public DateTime? HeatingStartTime { get; set; }
- public DateTime? ActualStartTime { get; set; }
- public bool IsResumed { get; set; }
public PrintingEventArgs(JobHandler jobHandler, Job job)
{
- LiquidQuantities = new List<JobRunLiquidQuantity>();
JobHandler = jobHandler;
Job = job;
}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/RequestFailedEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/RequestFailedEventArgs.cs
new file mode 100644
index 000000000..e946dd0c1
--- /dev/null
+++ b/Software/Visual_Studio/Tango.Integration/Operation/RequestFailedEventArgs.cs
@@ -0,0 +1,22 @@
+using Google.Protobuf;
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using System.Text;
+using System.Threading.Tasks;
+
+namespace Tango.Integration.Operation
+{
+ public class RequestFailedEventArgs : EventArgs
+ {
+ public IMessage Message { get; set; }
+
+ public Exception Exception { get; set; }
+
+ public RequestFailedEventArgs(IMessage message, Exception exception)
+ {
+ Message = message;
+ Exception = exception;
+ }
+ }
+}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/ResumingJobEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/ResumingJobEventArgs.cs
index 55728f799..6a8546350 100644
--- a/Software/Visual_Studio/Tango.Integration/Operation/ResumingJobEventArgs.cs
+++ b/Software/Visual_Studio/Tango.Integration/Operation/ResumingJobEventArgs.cs
@@ -9,18 +9,18 @@ namespace Tango.Integration.Operation
{
public class ResumingJobEventArgs : EventArgs
{
- private Func<JobHandler> _approveAction;
+ private Func<Job,JobHandler> _approveAction;
public String JobGuid { get; set; }
- public ResumingJobEventArgs(Func<JobHandler> approveAction)
+ public ResumingJobEventArgs(Func<Job, JobHandler> approveAction)
{
_approveAction = approveAction;
}
- public JobHandler Approve()
+ public JobHandler Approve(Job job)
{
- return _approveAction();
+ return _approveAction(job);
}
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Operation/ThreadLoadingConfirmationRequiredEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/ThreadLoadingConfirmationRequiredEventArgs.cs
deleted file mode 100644
index e5594dd01..000000000
--- a/Software/Visual_Studio/Tango.Integration/Operation/ThreadLoadingConfirmationRequiredEventArgs.cs
+++ /dev/null
@@ -1,27 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Tango.BL.Entities;
-using Tango.PMR.ThreadLoading;
-
-namespace Tango.Integration.Operation
-{
- public class ThreadLoadingConfirmationRequiredEventArgs : EventArgs
- {
- private Action<ProcessParametersTable> _confirm;
-
- public StartThreadLoadingResponse Status { get; set; }
-
- internal ThreadLoadingConfirmationRequiredEventArgs(Action<ProcessParametersTable> confirm)
- {
- _confirm = confirm;
- }
-
- public void Confirm(ProcessParametersTable processTable)
- {
- _confirm.Invoke(processTable);
- }
- }
-}
diff --git a/Software/Visual_Studio/Tango.Integration/Storage/StorageDrive.cs b/Software/Visual_Studio/Tango.Integration/Storage/StorageDrive.cs
index 91dce12f5..28f390bc9 100644
--- a/Software/Visual_Studio/Tango.Integration/Storage/StorageDrive.cs
+++ b/Software/Visual_Studio/Tango.Integration/Storage/StorageDrive.cs
@@ -7,7 +7,7 @@ using Tango.Core;
namespace Tango.Integration.Storage
{
- public class StorageDrive : StorageItem
+ public class StorageDrive : ExtendedObject
{
public long Capacity { get; set; }
public long FreeSpace { get; set; }
diff --git a/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs b/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs
index 54bc7232b..eaa209e65 100644
--- a/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs
+++ b/Software/Visual_Studio/Tango.Integration/Storage/StorageFileHandler.cs
@@ -65,8 +65,6 @@ namespace Tango.Integration.Storage
internal set { _total = value; RaisePropertyChangedAuto(); }
}
- public bool IsPaused { get; set; }
-
public Task Cancel()
{
return Task.Factory.StartNew(() =>
diff --git a/Software/Visual_Studio/Tango.Integration/Storage/StorageItem.cs b/Software/Visual_Studio/Tango.Integration/Storage/StorageItem.cs
index 6894f7111..eb7e56adb 100644
--- a/Software/Visual_Studio/Tango.Integration/Storage/StorageItem.cs
+++ b/Software/Visual_Studio/Tango.Integration/Storage/StorageItem.cs
@@ -22,12 +22,11 @@ namespace Tango.Integration.Storage
{
get { return System.IO.Path.GetFileName(Path); }
}
-
public String Parent
{
get
{
- if (Path == "/" || Path == null) return null;
+ if (Path == "/") return null;
String root = System.IO.Path.GetPathRoot(Path);
var parent = Directory.GetParent(Path);
diff --git a/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs b/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs
index 5dd975463..7db7433fa 100644
--- a/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs
+++ b/Software/Visual_Studio/Tango.Integration/Storage/StorageManager.cs
@@ -5,7 +5,6 @@ using System.Collections.ObjectModel;
using System.IO;
using System.Linq;
using System.Text;
-using System.Threading;
using System.Threading.Tasks;
using Tango.Core;
using Tango.Core.Commands;
@@ -89,6 +88,37 @@ namespace Tango.Integration.Storage
#endregion
+ #region Protected Methods
+
+ /// <summary>
+ /// Logs the request sent.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ protected void LogRequestSent(IMessage message)
+ {
+ LogManager.Log(String.Format("Sending request '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString()), LogCategory.Debug);
+ }
+
+ /// <summary>
+ /// Logs the request failed.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ protected void LogRequestFailed(IMessage message, Exception ex)
+ {
+ LogManager.Log(String.Format("Request failed '{0}'...{1}{2}{1}{3}", message.GetType().Name, Environment.NewLine, message.ToJsonString(), ex.ToString()), LogCategory.Error);
+ }
+
+ /// <summary>
+ /// Logs the response received.
+ /// </summary>
+ /// <param name="message">The message.</param>
+ protected void LogResponseReceived(IMessage message)
+ {
+ LogManager.Log(String.Format("Response received '{0}'...{1}{2}", message.GetType().Name, Environment.NewLine, message.ToJsonString()), LogCategory.Debug);
+ }
+
+ #endregion
+
#region Public Methods
/// <summary>
@@ -104,10 +134,11 @@ namespace Tango.Integration.Storage
try
{
- response = await _transporter.SendRequest<GetStorageInfoRequest, GetStorageInfoResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ response = await _transporter.SendRequest<GetStorageInfoRequest, GetStorageInfoResponse>(request);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -158,10 +189,11 @@ namespace Tango.Integration.Storage
try
{
- response = await _transporter.SendRequest<GetFilesRequest, GetFilesResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ response = await _transporter.SendRequest<GetFilesRequest, GetFilesResponse>(request);
}
catch (Exception ex)
{
+ LogRequestFailed(request, ex);
throw ex;
}
@@ -214,7 +246,7 @@ namespace Tango.Integration.Storage
request.Path = path;
request.Length = stream.Length;
- var fileUploadResponse = await _transporter.SendRequest<FileUploadRequest, FileUploadResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ var fileUploadResponse = await _transporter.SendRequest<FileUploadRequest, FileUploadResponse>(request);
String uploadId = fileUploadResponse.Message.UploadID;
long max_length = fileUploadResponse.Message.MaxChunkLength;
@@ -246,31 +278,24 @@ namespace Tango.Integration.Storage
{
if (!canceled)
{
- if (!handler.IsPaused)
- {
- byte[] buffer = new byte[Math.Min(max_length, stream.Length - stream.Position)];
- stream.Read(buffer, 0, buffer.Length);
+ byte[] buffer = new byte[Math.Min(max_length, stream.Length - stream.Position)];
+ stream.Read(buffer, 0, buffer.Length);
- FileChunkUploadRequest chunk = new FileChunkUploadRequest();
- chunk.UploadID = uploadId;
- chunk.Path = path;
- chunk.Buffer = ByteString.CopyFrom(buffer);
+ FileChunkUploadRequest chunk = new FileChunkUploadRequest();
+ chunk.UploadID = uploadId;
+ chunk.Path = path;
+ chunk.Buffer = ByteString.CopyFrom(buffer);
- var chunk_response = _transporter.SendRequest<FileChunkUploadRequest, FileChunkUploadResponse>(chunk, new TransportRequestConfig() { Priority = QueuePriority.Low }).Result;
+ var chunk_response = _transporter.SendRequest<FileChunkUploadRequest, FileChunkUploadResponse>(chunk).Result;
- if (chunk_response.Message.IsCanceled)
- {
- canceled = true;
- handler.RaiseFailed(new IOException("The storage device controller has canceled the current upload."));
- return;
- }
-
- handler.Current = stream.Position;
- }
- else
+ if (chunk_response.Message.IsCanceled)
{
- Thread.Sleep(100);
+ canceled = true;
+ handler.RaiseFailed(new IOException("The storage device controller has canceled the current upload."));
+ return;
}
+
+ handler.Current = stream.Position;
}
else
{
@@ -337,7 +362,7 @@ namespace Tango.Integration.Storage
FileDownloadRequest request = new FileDownloadRequest();
request.FileName = file.Path;
- var fileDownloadResponse = await _transporter.SendRequest<FileDownloadRequest, FileDownloadResponse>(request, new TransportRequestConfig() { ShouldLog = true });
+ var fileDownloadResponse = await _transporter.SendRequest<FileDownloadRequest, FileDownloadResponse>(request);
String download_id = fileDownloadResponse.Message.DownloadID;
long max_length = fileDownloadResponse.Message.MaxChunkLength;
@@ -358,32 +383,25 @@ namespace Tango.Integration.Storage
{
if (!canceled)
{
- if (!handler.IsPaused)
- {
- FileChunkDownloadRequest chunk = new FileChunkDownloadRequest();
- chunk.DownloadID = download_id;
- chunk.FileName = file.Path;
- chunk.Position = stream.Length;
+ FileChunkDownloadRequest chunk = new FileChunkDownloadRequest();
+ chunk.DownloadID = download_id;
+ chunk.FileName = file.Path;
+ chunk.Position = stream.Length;
- var chunk_response = _transporter.SendRequest<FileChunkDownloadRequest, FileChunkDownloadResponse>(chunk, new TransportRequestConfig() { Priority = QueuePriority.Low }).Result;
+ var chunk_response = _transporter.SendRequest<FileChunkDownloadRequest, FileChunkDownloadResponse>(chunk).Result;
- if (chunk_response.Message.IsCanceled)
- {
- canceled = true;
- handler.RaiseFailed(new IOException("The storage device controller has canceled the current download."));
- return;
- }
+ if (chunk_response.Message.IsCanceled)
+ {
+ canceled = true;
+ handler.RaiseFailed(new IOException("The storage device controller has canceled the current download."));
+ return;
+ }
- byte[] buffer = chunk_response.Message.Buffer.ToByteArray();
- stream.Write(buffer, 0, buffer.Length);
+ byte[] buffer = chunk_response.Message.Buffer.ToByteArray();
+ stream.Write(buffer, 0, buffer.Length);
- handler.Current = stream.Length;
- }
- else
- {
- Thread.Sleep(100);
- }
+ handler.Current = stream.Length;
}
else
{
@@ -418,7 +436,7 @@ namespace Tango.Integration.Storage
{
Path = item.Path,
Attribute = item.Attribute,
- }, new TransportRequestConfig() { ShouldLog = true });
+ });
}
/// <summary>
@@ -432,7 +450,7 @@ namespace Tango.Integration.Storage
{
Path = path,
Attribute = FileAttribute.Directory,
- }, new TransportRequestConfig() { ShouldLog = true });
+ });
}
#endregion
diff --git a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
index 591cd282a..6b8d4ee8d 100644
--- a/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
+++ b/Software/Visual_Studio/Tango.Integration/Tango.Integration.csproj
@@ -42,9 +42,6 @@
<Reference Include="Ionic.Zip, Version=1.9.1.8, Culture=neutral, PublicKeyToken=edbe51ad942a3f5c, processorArchitecture=MSIL">
<HintPath>..\packages\Ionic.Zip.1.9.1.8\lib\Ionic.Zip.dll</HintPath>
</Reference>
- <Reference Include="Microsoft.AspNet.SignalR.Client, Version=2.4.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
- <HintPath>..\packages\Microsoft.AspNet.SignalR.Client.2.4.1\lib\net45\Microsoft.AspNet.SignalR.Client.dll</HintPath>
- </Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
@@ -54,7 +51,6 @@
<Reference Include="System.ComponentModel.DataAnnotations" />
<Reference Include="System.Core" />
<Reference Include="System.Management" />
- <Reference Include="System.Net.Http.WebRequest" />
<Reference Include="System.Reactive.Core, Version=3.0.3000.0, Culture=neutral, PublicKeyToken=94bc3704cddfc263, processorArchitecture=MSIL">
<HintPath>..\packages\System.Reactive.Core.3.1.1\lib\net46\System.Reactive.Core.dll</HintPath>
</Reference>
@@ -99,39 +95,20 @@
<Compile Include="ExtensionMethods\IExternalBridgeClientExtensions.cs" />
<Compile Include="ExternalBridge\ColorProfileRequestEventArgs.cs" />
<Compile Include="ExternalBridge\ExternalBridgeClientConnectedEventArgs.cs" />
- <Compile Include="ExternalBridge\ExternalBridgeReceiver.cs" />
- <Compile Include="ExternalBridge\ExternalBridgeReceiverLoginRequestEventArgs.cs" />
- <Compile Include="ExternalBridge\ExternalBridgeReceiverRequestReceivedEventArgs.cs" />
- <Compile Include="ExternalBridge\ExternalBridgeRequestHandlerMethodAttribute.cs" />
- <Compile Include="ExternalBridge\IExternalBridgeRequestHandler.cs" />
- <Compile Include="ExternalBridge\ExternalBridgeSignalRConfiguration.cs" />
- <Compile Include="ExternalBridge\ExternalBridgeSignalRClient.cs" />
- <Compile Include="ExternalBridge\RequestHandlerLoggingMode.cs" />
- <Compile Include="ExternalBridge\Web\MachineInfo.cs" />
<Compile Include="IntegrationSettings.cs" />
<Compile Include="JobRuns\BasicJobRunsLogger.cs" />
<Compile Include="JobRuns\IJobRunsLogger.cs" />
<Compile Include="Logging\EmbeddedLogFileParser.cs" />
- <Compile Include="Operation\CachedJobOperation.cs" />
<Compile Include="Operation\CartridgeValidationEventArgs.cs" />
<Compile Include="Operation\DefaultMachineEventsStateProvider.cs" />
<Compile Include="Logging\EmbeddedLogItem.cs" />
<Compile Include="Operation\DefaultGradientGenerationConfiguration.cs" />
- <Compile Include="Operation\HeadCleaningEndedEventArgs.cs" />
- <Compile Include="Operation\HeadCleaningHandler.cs" />
- <Compile Include="Operation\HeadCleaningStatusChangedEventArgs.cs" />
<Compile Include="Operation\IGradientGenerationConfiguration.cs" />
- <Compile Include="Operation\InkFillingStatusChangedEventArgs.cs" />
<Compile Include="Operation\InsufficientLiquidQuantityException.cs" />
<Compile Include="Operation\JobDescriptionFile.cs" />
- <Compile Include="Operation\JobLiquidQuantityCalculationMode.cs" />
<Compile Include="Operation\JobUnitsMethods.cs" />
- <Compile Include="Operation\PowerDownHandler.cs" />
- <Compile Include="Operation\PowerDownStartedEventArgs.cs" />
- <Compile Include="Operation\PowerDownStatusChangedEventArgs.cs" />
<Compile Include="Operation\PreparingJobProgressEventArgs.cs" />
<Compile Include="Operation\SpoolChangeRequiredEventArgs.cs" />
- <Compile Include="Operation\ThreadLoadingConfirmationRequiredEventArgs.cs" />
<Compile Include="Upgrade\FirmwareUpgradeHandler.cs" />
<Compile Include="Upgrade\FirmwareUpgradeModes.cs" />
<Compile Include="Upgrade\FirmwareUpgradeProgressEventArgs.cs" />
@@ -144,6 +121,7 @@
<Compile Include="Operation\JobHandler.cs" />
<Compile Include="Operation\MachineStatuses.cs" />
<Compile Include="Operation\PrintingEventArgs.cs" />
+ <Compile Include="Operation\RequestFailedEventArgs.cs" />
<Compile Include="Operation\ResumingJobEventArgs.cs" />
<Compile Include="Operation\RunningJobStatus.cs" />
<Compile Include="ExternalBridge\ExternalBridgeScanner.cs" />
@@ -204,10 +182,6 @@
<Project>{d8f1ad85-526a-4f50-b6dc-d437af63d8d8}</Project>
<Name>Tango.Settings</Name>
</ProjectReference>
- <ProjectReference Include="..\Tango.SystemInfo\Tango.SystemInfo.csproj">
- <Project>{997a961c-beda-4b56-aa0f-c39e532f7ffa}</Project>
- <Name>Tango.SystemInfo</Name>
- </ProjectReference>
<ProjectReference Include="..\Tango.Transport\Tango.Transport.csproj">
<Project>{74e700b0-1156-4126-be40-ee450d3c3026}</Project>
<Name>Tango.Transport</Name>
diff --git a/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeHandler.cs b/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeHandler.cs
index dd42693c4..774824b49 100644
--- a/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeHandler.cs
+++ b/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeHandler.cs
@@ -19,8 +19,6 @@ namespace Tango.Integration.Upgrade
internal FirmwareUpgradeHandler()
{
- IsIndeterminate = true;
- Total = 100;
Message = "Initializing...";
}
@@ -43,8 +41,8 @@ namespace Tango.Integration.Upgrade
private set { _status = value; RaisePropertyChangedAuto(); }
}
- private double _current;
- public double Current
+ private long _current;
+ public long Current
{
get { return _current; }
internal set
@@ -53,20 +51,13 @@ namespace Tango.Integration.Upgrade
}
}
- private double _total;
- public double Total
+ private long _total;
+ public long Total
{
get { return _total; }
internal set { _total = value; RaisePropertyChangedAuto(); }
}
- private bool _isIndeterminate;
- public bool IsIndeterminate
- {
- get { return _isIndeterminate; }
- set { _isIndeterminate = value; RaisePropertyChangedAuto(); }
- }
-
public Task Cancel()
{
return Task.Factory.StartNew(() =>
@@ -80,27 +71,28 @@ namespace Tango.Integration.Upgrade
internal void RaiseCompleted()
{
- RaiseProgress(FirmwareUpgradeStatus.Completed, "Firmware upgrade completed.", false, 100, 100);
+ Status = FirmwareUpgradeStatus.Completed;
+ Message = "Completed.";
Completed?.Invoke(this, new EventArgs());
}
internal void RaiseCanceled()
{
- RaiseProgress(FirmwareUpgradeStatus.Canceled, "Firmware upgrade canceled by user.", false, 100, 0);
+ Status = FirmwareUpgradeStatus.Canceled;
+ Message = "Canceled.";
Canceled?.Invoke(this, new EventArgs());
}
internal void RaiseFailed(Exception ex)
{
- RaiseProgress(FirmwareUpgradeStatus.Failed, "Firmware upgrade failed.", false, 100, 0);
+ Status = FirmwareUpgradeStatus.Failed;
+ Message = "Failed.";
Failed?.Invoke(this, ex);
}
- internal void RaiseProgress(FirmwareUpgradeStatus status, String message, bool isIndeterminate = true, double total = 100, double current = 0)
+ internal void RaiseProgress(long current, FirmwareUpgradeStatus status, String message)
{
- Total = total;
Current = current;
- IsIndeterminate = isIndeterminate;
Status = status;
Message = message;
@@ -110,7 +102,6 @@ namespace Tango.Integration.Upgrade
Status = Status,
Total = Total,
Message = Message,
- IsIndeterminate = IsIndeterminate
});
}
}
diff --git a/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeProgressEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeProgressEventArgs.cs
index 8315f4026..fa4f4cc96 100644
--- a/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeProgressEventArgs.cs
+++ b/Software/Visual_Studio/Tango.Integration/Upgrade/FirmwareUpgradeProgressEventArgs.cs
@@ -8,9 +8,8 @@ namespace Tango.Integration.Upgrade
{
public class FirmwareUpgradeProgressEventArgs : EventArgs
{
- public double Current { get; set; }
- public double Total { get; set; }
- public bool IsIndeterminate { get; set; }
+ public long Current { get; set; }
+ public long Total { get; set; }
public FirmwareUpgradeStatus Status { get; set; }
public String Message { get; set; }
}
diff --git a/Software/Visual_Studio/Tango.Integration/packages.config b/Software/Visual_Studio/Tango.Integration/packages.config
index 542b7a059..56f5092b2 100644
--- a/Software/Visual_Studio/Tango.Integration/packages.config
+++ b/Software/Visual_Studio/Tango.Integration/packages.config
@@ -3,7 +3,6 @@
<package id="EntityFramework" version="6.2.0" targetFramework="net461" />
<package id="Google.Protobuf" version="3.4.1" targetFramework="net46" />
<package id="Ionic.Zip" version="1.9.1.8" targetFramework="net461" />
- <package id="Microsoft.AspNet.SignalR.Client" version="2.4.1" targetFramework="net461" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net461" />
<package id="System.Reactive" version="3.1.1" targetFramework="net46" />
<package id="System.Reactive.Core" version="3.1.1" targetFramework="net46" />