diff options
Diffstat (limited to 'Software/Visual_Studio/Tango.Integration/Operation')
21 files changed, 937 insertions, 2999 deletions
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); - } - } -} |
