using GalaSoft.MvvmLight.Ioc;
using RealTimeGraphEx.Controllers;
using RealTimeGraphEx.DataSeries;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using Tango.Core.Commands;
using Tango.Integration.Observables;
using Tango.MachineStudio.Common.Controls;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.Common.StudioApplication;
using Tango.SharedUI;
using System.Runtime.CompilerServices;
using System.Windows.Threading;
using Tango.Settings;
using Tango.MachineStudio.Developer.Views;
using Tango.Video.DirectCapture;
using Tango.Integration.Operators;
using Tango.PMR.Diagnostics;
using System.Reflection;
using Tango.PMR.Common;
using Tango.SharedUI.Helpers;
using Tango.Transport;
using Tango.Integration.Printing;
using Tango.Integration.Diagnostics;
using Microsoft.Win32;
using Tango.MachineStudio.Technician.ViewModels;
using Tango.MachineStudio.Common.Diagnostics;
using Tango.MachineStudio.Common.Video;
using Tango.Integration.Services;
using Tango.MachineStudio.Developer.Navigation;
using System.Data.Entity;
using Tango.MachineStudio.Common.Authentication;
using DeepEqual.Syntax;
namespace Tango.MachineStudio.Developer.ViewModels
{
///
/// Represents the developer module main view, view model.
///
///
public class MainViewVM : ViewModel, IShutdownRequestBlocker
{
private INotificationProvider _notification;
private TimeSpan _runningJobEstimatedDuration;
private Dictionary _controllers;
private int _fullScreenGraphIndex;
private JobHandler _jobHandler;
private DeveloperNavigationManager _navigation;
private ObservablesContext _dbJobContext;
private Job _jobFromList;
private bool _blockInvalidateCommands;
private IAuthenticationProvider _authentication;
#region Properties
private ObservableCollection _colorSpaces;
///
/// Gets or sets the color spaces.
///
public ObservableCollection ColorSpaces
{
get { return _colorSpaces; }
set { _colorSpaces = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection _rmls;
///
/// Gets or sets the RMLS.
///
public ObservableCollection Rmls
{
get { return _rmls; }
set { _rmls = value; RaisePropertyChangedAuto(); }
}
///
/// Gets or sets the application manager.
///
public IStudioApplicationManager ApplicationManager { get; set; }
///
/// Gets or sets the video capture provider.
///
public IVideoCaptureProvider VideoCaptureProvider { get; set; }
///
/// Gets or sets observable entites database the adapter.
///
public ObservablesEntitiesAdapter Adapter { get; set; }
protected Machine _selectedMachine;
///
/// Gets or sets the selected machine.
///
public Machine SelectedMachine
{
get { return _selectedMachine; }
set
{
_selectedMachine = value;
OnMachineChanged();
RaisePropertyChangedAuto();
InvalidateRelayCommands();
if (_selectedMachine != null)
{
_selectedMachine.Saved -= SelectedMachine_Saved;
_selectedMachine.Saved += SelectedMachine_Saved;
}
}
}
private List _liquidTypesRmls;
///
/// Gets or sets the liquid types RMLS.
///
public List LiquidTypesRmls
{
get { return _liquidTypesRmls; }
set { _liquidTypesRmls = value; RaisePropertyChangedAuto(); }
}
private ProcessParametersTablesGroup _rmlProcessParametersTablesGroup;
///
/// Gets or sets the RML process parameters table group (cloned).
///
public ProcessParametersTablesGroup RmlProcessParametersTableGroup
{
get { return _rmlProcessParametersTablesGroup; }
set
{ _rmlProcessParametersTablesGroup = value; RaisePropertyChangedAuto(); OnProcessParametersTableGroupChanged(); }
}
private ObservableCollection _groupsHistory;
///
/// Gets or sets the RML process parameters groups history.
///
public ObservableCollection GroupsHistory
{
get { return _groupsHistory; }
set { _groupsHistory = value; RaisePropertyChangedAuto(); }
}
private ProcessParametersTablesGroup _selectedGroupHistory;
///
/// Gets or sets the selected process parameters tables group history.
///
public ProcessParametersTablesGroup SelectedGroupHistory
{
get { return _selectedGroupHistory; }
set { _selectedGroupHistory = value; RaisePropertyChangedAuto(); OnSelectedGroupHistoryChanged(); }
}
private ProcessParametersTable _selectedProcessParametersTable;
///
/// Gets or sets the selected process parameters table.
///
public ProcessParametersTable SelectedProcessParametersTable
{
get { return _selectedProcessParametersTable; }
set { _selectedProcessParametersTable = value; RaisePropertyChangedAuto(); OnSelectedParametersTableChanged(); }
}
private Job _selectedJob;
///
/// Gets or sets the selected machine job.
///
public Job SelectedJob
{
get { return _selectedJob; }
set
{
_selectedJob = value;
RaisePropertyChangedAuto();
}
}
private ObservableCollection _selectedJobs;
///
/// Gets or sets the selected jobs.
///
public ObservableCollection SelectedJobs
{
get { return _selectedJobs; }
set { _selectedJobs = value; RaisePropertyChangedAuto(); }
}
private Segment _selectedSegment;
///
/// Gets or sets the job selected segment.
///
public Segment SelectedSegment
{
get { return _selectedSegment; }
set { _selectedSegment = value; RaisePropertyChangedAuto(); OnSelectedSegmentChanged(); }
}
private ObservableCollection _selectedSegments;
///
/// Gets or sets the selected segments.
///
public ObservableCollection SelectedSegments
{
get { return _selectedSegments; }
set { _selectedSegments = value; RaisePropertyChangedAuto(); }
}
private BrushStop _selectedBrushStop;
///
/// Gets or sets the selected segment selected brush stop.
///
public BrushStop SelectedBrushStop
{
get { return _selectedBrushStop; }
set { _selectedBrushStop = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection _selectedBrushStops;
///
/// Gets or sets the selected brush stops.
///
public ObservableCollection SelectedBrushStops
{
get { return _selectedBrushStops; }
set { _selectedBrushStops = value; RaisePropertyChangedAuto(); }
}
private Rml _selectedRML;
///
/// Gets or sets the selected RML.
///
public Rml SelectedRML
{
get { return _selectedRML; }
set
{
_selectedRML = value;
InvalidateLiquidFactorsAndProcessTables();
RaisePropertyChangedAuto();
InvalidateRelayCommands();
}
}
private bool _isSideBarOpened;
///
/// Gets or sets a value indicating whether the configuration panels are opened.
///
public bool IsSideBarOpened
{
get { return _isSideBarOpened; }
set { _isSideBarOpened = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection _availableGraphs;
///
/// Gets or sets the available sensors.
///
public ObservableCollection AvailableGraphs
{
get { return _availableGraphs; }
set { _availableGraphs = value; RaisePropertyChangedAuto(); }
}
private ObservableCollection _graphs;
///
/// Gets or sets the collection of displayed graph controls.
///
public ObservableCollection Graphs
{
get { return _graphs; }
set { _graphs = value; RaisePropertyChangedAuto(); }
}
private TimeSpan _estimatedDuration;
///
/// Gets or sets the estimated duration for the selected job.
///
public TimeSpan EstimatedDuration
{
get { return _estimatedDuration; }
set { _estimatedDuration = value; RaisePropertyChangedAuto(); }
}
private bool _isJobRunning;
///
/// Gets or sets a value indicating whether a job is currently running.
///
public bool IsJobRunning
{
get { return _isJobRunning; }
set { _isJobRunning = value; RaisePropertyChangedAuto(); }
}
private Job _runningJob;
///
/// Gets or sets the currently running job.
///
public Job RunningJob
{
get { return _runningJob; }
set { _runningJob = value; RaisePropertyChangedAuto(); }
}
private double _runningJobProgress;
///
/// Gets or sets the running job current progress.
///
public double RunningJobProgress
{
get { return _runningJobProgress; }
set { _runningJobProgress = value; RaisePropertyChangedAuto(); }
}
private TimeSpan _runningJobRemainingTime;
///
/// Gets or sets the job remaining time.
///
public TimeSpan RunningJobRemainingTime
{
get { return _runningJobRemainingTime; }
set { _runningJobRemainingTime = value; RaisePropertyChangedAuto(); }
}
private bool _isJobCompleted;
///
/// Gets or sets a value indicating whether the running job has completed successfully.
///
public bool IsJobCompleted
{
get { return _isJobCompleted; }
set { _isJobCompleted = value; RaisePropertyChangedAuto(); }
}
private bool _isJobFailed;
///
/// Gets or sets a value indicating whether the running job has failed.
///
public bool IsJobFailed
{
get { return _isJobFailed; }
set { _isJobFailed = value; RaisePropertyChangedAuto(); }
}
private bool _showJobStatus;
///
/// Gets or sets a value indicating whether to show all the relevant job status areas.
///
public bool ShowJobStatus
{
get { return _showJobStatus; }
set { _showJobStatus = value; RaisePropertyChangedAuto(); }
}
private bool _isJobCanceled;
///
/// Gets or sets a value indicating whether the last running job was canceled.
///
public bool IsJobCanceled
{
get { return _isJobCanceled; }
set { _isJobCanceled = value; RaisePropertyChangedAuto(); }
}
private IMachineOperator _machineOperator;
///
/// Gets or sets the machine operator.
///
public IMachineOperator MachineOperator
{
get { return _machineOperator; }
set { _machineOperator = value; RaisePropertyChangedAuto(); }
}
private IRealTimeGraph _fullScreenGraph;
///
/// Gets or sets the full screen graph.
///
public IRealTimeGraph FullScreenGraph
{
get { return _fullScreenGraph; }
set { _fullScreenGraph = value; RaisePropertyChangedAuto(); }
}
private List _runningJobSegments;
///
/// Gets or sets the running job segments.
///
public List RunningJobSegments
{
get { return _runningJobSegments; }
set { _runningJobSegments = value; RaisePropertyChangedAuto(); }
}
#endregion
#region Commands
///
/// Gets or sets the edit machine command.
///
public RelayCommand EditMachineCommand { get; set; }
///
/// Gets or sets the edit RML command.
///
public RelayCommand EditRMLCommand { get; set; }
///
/// Gets or sets the toggle side bar command.
///
public RelayCommand ToggleSideBarCommand { get; set; }
///
/// Gets or sets the save process parameters command.
///
public RelayCommand SaveProcessParametersCommand { get; set; }
///
/// Gets or sets the save liquid factors command.
///
public RelayCommand SaveLiquidFactorsCommand { get; set; }
///
/// Gets or sets the add segment command.
///
public RelayCommand AddSegmentCommand { get; set; }
///
/// Gets or sets the remove segment command.
///
public RelayCommand RemoveSegmentCommand { get; set; }
///
/// Gets or sets the add job command.
///
public RelayCommand AddJobCommand { get; set; }
///
/// Gets or sets the remove job command.
///
public RelayCommand RemoveJobCommand { get; set; }
///
/// Gets or sets the add brush stop command.
///
public RelayCommand AddBrushStopCommand { get; set; }
///
/// Gets or sets the remove brush stop command.
///
public RelayCommand RemoveBrushStopCommand { get; set; }
///
/// Gets or sets the save job command.
///
public RelayCommand SaveJobCommand { get; set; }
///
/// Gets or sets the discard job command.
///
public RelayCommand DiscardJobCommand { get; set; }
///
/// Gets or sets the start job command.
///
public RelayCommand StartJobCommand { get; set; }
///
/// Gets or sets the stop job command.
///
public RelayCommand StopJobCommand { get; set; }
///
/// Gets or sets the close job completion status command.
///
public RelayCommand CloseJobCompletionStatusCommand { get; set; }
///
/// Gets or sets the toggle camera command.
///
public RelayCommand ToggleCameraCommand { get; set; }
///
/// Gets or sets the exit full screen command.
///
public RelayCommand ExitFullScreenCommand { get; set; }
///
/// Gets or sets the load job command.
///
public RelayCommand LoadJobCommand { get; set; }
///
/// Gets or sets the duplicate job command.
///
public RelayCommand DuplicateJobCommand { get; set; }
#endregion
#region Constructors
///
/// Initializes a new instance of the class.
///
public MainViewVM(IMainView view) : base(view, true)
{
if (!this.DesignMode)
{
Adapter = ObservablesEntitiesAdapter.Instance;
AvailableGraphs = Adapter.TechMonitors.ToObservableCollection();
}
Graphs = new ObservableCollection();
_controllers = new Dictionary();
}
///
/// Initializes a new instance of the class.
///
/// The application manager.
/// The notification provider.
[PreferredConstructor]
public MainViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, IMainView view, IDiagnosticsFrameProvider diagnosticsFrameProvider, IVideoCaptureProvider videoCaptureProvider, DeveloperNavigationManager navigation, IAuthenticationProvider authentication) : this(view)
{
SelectedJobs = new ObservableCollection();
_authentication = authentication;
_notification = notificationProvider;
_navigation = navigation;
ApplicationManager = applicationManager;
VideoCaptureProvider = videoCaptureProvider;
diagnosticsFrameProvider.FrameReceived += DiagnosticsFrameProvider_FrameReceived;
//Initialize Commands...
EditMachineCommand = new RelayCommand(EditMachine, () => SelectedMachine != null);
EditRMLCommand = new RelayCommand(EditRML, () => SelectedRML != null);
ToggleSideBarCommand = new RelayCommand(() => IsSideBarOpened = !IsSideBarOpened);
SaveProcessParametersCommand = new RelayCommand(SaveProcessParameters, () => SelectedRML != null && SelectedRML.ProcessParametersTablesGroups.Count > 0);
SaveLiquidFactorsCommand = new RelayCommand(SaveLiquidFactors, () => SelectedRML != null);
AddSegmentCommand = new RelayCommand(AddSegment, () => SelectedJob != null);
RemoveSegmentCommand = new RelayCommand(RemoveSegment, () => SelectedSegment != null);
AddJobCommand = new RelayCommand(AddJob, () => SelectedMachine != null);
RemoveJobCommand = new RelayCommand(RemoveJob, () => SelectedJob != null);
AddBrushStopCommand = new RelayCommand(AddBrushStop, () => SelectedSegment != null);
RemoveBrushStopCommand = new RelayCommand(RemoveBrushStop, () => SelectedBrushStop != null);
SaveJobCommand = new RelayCommand(SaveJob, () => SelectedMachine != null);
DiscardJobCommand = new RelayCommand(DiscardJob, () => SelectedMachine != null);
StartJobCommand = new RelayCommand(StartJob, () => SelectedJob != null && !IsJobRunning);
StopJobCommand = new RelayCommand(StopJob, () => IsJobRunning);
CloseJobCompletionStatusCommand = new RelayCommand(CloseJobCompletionStatusBar);
ExitFullScreenCommand = new RelayCommand(ExitFullScreen);
LoadJobCommand = new RelayCommand(LoadJob, () => SelectedJob != null);
DuplicateJobCommand = new RelayCommand(DuplicateJob, () => SelectedJob != null);
ToggleCameraCommand = new RelayCommand(ToggleCamera);
ApplicationManager.ConnectedMachineChanged += ApplicationManager_ConnectedMachineChanged;
}
#endregion
#region Event Handlers
///
/// Handles the diagnostics provider frame received event.
///
/// The sender.
/// The response.
private void DiagnosticsFrameProvider_FrameReceived(object sender, PushDiagnosticsResponse response)
{
PopulateDiagnosticsData(response);
}
///
/// Handles the application manager connected machine changes event.
///
/// The sender.
/// The machine.
private void ApplicationManager_ConnectedMachineChanged(object sender, IExternalBridgeClient machine)
{
MachineOperator = machine;
}
///
/// Handles the Saved event of the SelectedMachine.
///
/// The source of the event.
/// The instance containing the event data.
private void SelectedMachine_Saved(object sender, EventArgs e)
{
InvalidateLiquidFactorsAndProcessTables();
SelectedMachine.Reload();
}
///
/// Handles the LengthChanged event of the SelectedJob.
///
/// The source of the event.
/// The instance containing the event data.
private void SelectedJob_LengthChanged(object sender, EventArgs e)
{
UpdateEstimatedDuration();
}
///
/// Handles the DyeingSpeedMinInkUptakeChanged event of the SelectedProcessParametersTable.
///
/// The source of the event.
/// The instance containing the event data.
private void SelectedProcessParametersTable_DyeingSpeedMinInkUptakeChanged(object sender, EventArgs e)
{
if (SelectedSegment != null)
{
foreach (var liquidVolume in SelectedSegment.BrushStops.SelectMany(x => x.LiquidVolumes))
{
liquidVolume.Invalidate();
}
}
UpdateEstimatedDuration();
}
#endregion
#region Virtual Methods
protected virtual void OnSelectedParametersTableChanged()
{
if (SelectedProcessParametersTable != null)
{
SelectedProcessParametersTable.DyeingSpeedMinInkUptakeChanged -= SelectedProcessParametersTable_DyeingSpeedMinInkUptakeChanged;
SelectedProcessParametersTable.DyeingSpeedMinInkUptakeChanged += SelectedProcessParametersTable_DyeingSpeedMinInkUptakeChanged;
}
SetSegmentBrushStopsLiquidVolumes(SelectedSegment);
}
///
/// Called when the process parameters table group has been changed
///
private void OnProcessParametersTableGroupChanged()
{
if (RmlProcessParametersTableGroup != null && RmlProcessParametersTableGroup.ProcessParametersTables.Count > 0)
{
SelectedProcessParametersTable = RmlProcessParametersTableGroup.ProcessParametersTables.First();
}
UpdateEstimatedDuration();
}
///
/// Called when the selected segment has been changed
///
protected virtual void OnSelectedSegmentChanged()
{
if (SelectedSegment != null)
{
SetSegmentBrushStopsLiquidVolumes(SelectedSegment);
SelectedBrushStop = SelectedSegment.BrushStops.FirstOrDefault();
}
}
///
/// Called when the selected group history has been changed
///
protected virtual void OnSelectedGroupHistoryChanged()
{
if (SelectedGroupHistory != null)
{
RmlProcessParametersTableGroup = SelectedGroupHistory.CloneGroup();
}
}
///
/// Called when the machine has been changed
///
protected virtual void OnMachineChanged()
{
InvalidateLiquidFactorsAndProcessTables();
}
#endregion
#region Private Methods
private async void DuplicateJob()
{
if (SelectedJobs.Count > 0)
{
using (_notification.PushTaskItem("Cloning selected jobs..."))
{
int index = SelectedMachine.Jobs.Max(x => x.JobIndex);
foreach (var job in SelectedJobs)
{
var cloned = job.Clone();
cloned.JobIndex = ++index;
SelectedMachine.Jobs.Add(cloned);
}
await SelectedMachine.SaveAsync();
}
}
}
private async void LoadJob()
{
if (SelectedJob != null)
{
SelectedSegments = new ObservableCollection();
SelectedBrushStops = new ObservableCollection();
SelectedRML = null;
SelectedSegment = null;
SelectedGroupHistory = null;
SelectedBrushStop = null;
SelectedProcessParametersTable = null;
RmlProcessParametersTableGroup = null;
using (_notification.PushTaskItem("Loading job details..."))
{
//await Task.Factory.StartNew(() =>
//{
_blockInvalidateCommands = false;
_dbJobContext = ObservablesContext.CreateDefault();
_dbJobContext.Configuration.LazyLoadingEnabled = true;
ColorSpaces = _dbJobContext.ColorSpaces.ToObservableCollection();
Rmls = _dbJobContext.Rmls.ToObservableCollection();
_jobFromList = SelectedJob;
_selectedJob = _dbJobContext.Jobs.SingleOrDefault(x => x.Guid == SelectedJob.Guid);
_selectedRML = SelectedJob.Rml;
_selectedSegment = SelectedJob.Segments.FirstOrDefault();
SelectedJob.LengthChanged -= SelectedJob_LengthChanged;
SelectedJob.LengthChanged += SelectedJob_LengthChanged;
SelectedJob = _selectedJob;
SelectedRML = _selectedRML;
SelectedSegment = _selectedSegment;
UpdateEstimatedDuration();
_blockInvalidateCommands = false;
InvalidateRelayCommands();
InvokeUI(() => _navigation.NavigateTo(DeveloperNavigationView.JobView));
//});
}
}
}
private async void SaveJob()
{
if (SelectedJob != null)
{
using (_notification.PushTaskItem("Saving job to database..."))
{
SelectedJob.LastUpdated = DateTime.UtcNow;
SelectedJob.Rml = SelectedRML;
await SelectedJob.SaveAsync(_dbJobContext);
_jobFromList = SelectedMachine.Jobs.SingleOrDefault(x => x.Guid == SelectedJob.Guid);
await _jobFromList.Reload();
foreach (var segment in _jobFromList.Segments)
{
await segment.Reload();
foreach (var stop in segment.BrushStops)
{
await stop.Reload();
}
}
}
}
}
private void DiscardJob()
{
//bool jobModified = !SelectedJob.WithDeepEqual(_jobFromList)
// .IgnoreSourceProperty(x => x.Machine)
// .IgnoreSourceProperty(x => x.JobRuns)
// .IgnoreSourceProperty(x => x.Parameters)
// .IgnoreSourceProperty(x => x.Rml)
// .IgnoreSourceProperty(x => x.User)
// .IgnoreSourceProperty(x => x.Segments)
// .Compare();
bool jobModified = !SelectedJob.CompareUsingJson(_jobFromList);
if (jobModified)
{
if (_notification.ShowQuestion("This will discard the current job changes. Are you sue?"))
{
_dbJobContext.Dispose();
_navigation.NavigateTo(DeveloperNavigationView.MachineJobSelectionView);
}
}
else
{
_dbJobContext.Dispose();
_navigation.NavigateTo(DeveloperNavigationView.MachineJobSelectionView);
}
}
private void ClearGraphs()
{
_controllers.ToList().ForEach(x => x.Value.Clear());
}
private void PopulateDiagnosticsData(PushDiagnosticsResponse data)
{
foreach (var prop in data.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance))
{
GraphControllerBase controller = null;
if (_controllers.TryGetValue(prop.Name, out controller))
{
if (controller is GraphController)
{
double[] arr = Enumerable.ToArray(prop.GetValue(data) as IEnumerable);
(controller as GraphController).PushData(arr);
}
else
{
DoubleArray[] arrayOfDoubles = Enumerable.ToArray(prop.GetValue(data) as IEnumerable);
(controller as GraphMultiController).PushData(arrayOfDoubles.Select(x => x.Data.ToList()).ToList());
}
}
}
}
private void ExitFullScreen()
{
if (FullScreenGraph != null)
{
FullScreenGraph.EnableToolBar = true;
Graphs.Insert(_fullScreenGraphIndex, FullScreenGraph);
FullScreenGraph = null;
}
}
private void StartFullScreenGraph(IRealTimeGraph graph)
{
graph.EnableToolBar = false;
_fullScreenGraphIndex = Graphs.IndexOf(graph);
Graphs.Remove(graph);
FullScreenGraph = graph;
}
private void ToggleCamera(CaptureDevice captureDevice)
{
if (captureDevice.Device != null)
{
captureDevice.IsStarted = !captureDevice.IsStarted;
}
}
private void CloseJobCompletionStatusBar()
{
_navigation.NavigateTo(DeveloperNavigationView.JobView);
IsJobCompleted = false;
IsJobFailed = false;
IsJobCanceled = false;
ShowJobStatus = false;
RunningJob = null;
}
private void StopJob()
{
IsJobRunning = false;
IsJobCanceled = true;
_jobHandler.Cancel();
}
private void FailJob()
{
IsJobRunning = false;
IsJobFailed = true;
}
private void CompleteJob()
{
IsJobRunning = false;
IsJobCompleted = true;
}
private void StartJob()
{
if (MachineOperator == null || MachineOperator.State != TransportComponentState.Connected)
{
_notification.ShowError("No machine connected. Could not execute the specified job.");
return;
}
if (SelectedProcessParametersTable == null)
{
_notification.ShowError("No process parameters table selected. Could not execute the specified job.");
return;
}
RunningJobRemainingTime = TimeSpan.Zero;
RunningJobProgress = 0;
IsJobFailed = false;
IsJobCanceled = false;
IsJobCompleted = false;
IsJobRunning = true;
ShowJobStatus = true;
RunningJob = SelectedJob;
_runningJobEstimatedDuration = EstimatedDuration;
RunningJobSegments = CreateRunningJobEffectiveSegments(RunningJob);
_navigation.NavigateTo(DeveloperNavigationView.RunningJobView);
_jobHandler = MachineOperator.Print(SelectedJob, SelectedProcessParametersTable);
_jobHandler.StatusReceived += (x, status) =>
{
RunningJobRemainingTime = _runningJobEstimatedDuration - TimeSpan.FromSeconds(RunningJobProgress / (SelectedProcessParametersTable.DyeingSpeed / 100d));
RunningJobProgress = status.Progress;
foreach (var segment in RunningJobSegments)
{
var previousSegmentsWithThis = RunningJobSegments.Where(s => RunningJobSegments.IndexOf(s) <= RunningJobSegments.IndexOf(segment)).ToList();
var segmentsDuration = TimeSpan.FromSeconds(previousSegmentsWithThis.Sum(s => s.Length) / (SelectedProcessParametersTable.DyeingSpeed / 100d));
var segmentDuration = TimeSpan.FromSeconds(segment.Length / (SelectedProcessParametersTable.DyeingSpeed / 100d));
TimeSpan remaining = segmentsDuration - TimeSpan.FromSeconds(RunningJobProgress / (SelectedProcessParametersTable.DyeingSpeed / 100d));
if (remaining >= TimeSpan.Zero)
{
segment.RemainingTime = remaining;
}
if (remaining < segmentDuration)
{
segment.Started = true;
}
if (remaining <= TimeSpan.Zero)
{
segment.Completed = true;
segment.Started = false;
}
}
};
_jobHandler.Failed += (x, ex) =>
{
FailJob();
InvokeUI(() =>
{
_notification.ShowError("Job failed. " + ex.Message);
});
};
_jobHandler.Completed += (x, e) =>
{
CompleteJob();
};
_jobHandler.Canceled += (x, y) =>
{
//Finally Canceled..
};
}
private void UpdateEstimatedDuration()
{
if (SelectedJob != null && SelectedProcessParametersTable != null && SelectedProcessParametersTable.DyeingSpeed > 0)
{
EstimatedDuration = TimeSpan.FromSeconds(SelectedJob.Length / (SelectedProcessParametersTable.DyeingSpeed / 100d));
}
}
private void SetSegmentBrushStopsLiquidVolumes(Segment segment)
{
if (!DesignMode && segment != null)
{
foreach (var stop in segment.BrushStops)
{
stop.SetLiquidVolumes(SelectedMachine.Configuration, SelectedRML, SelectedProcessParametersTable);
}
}
}
///
/// Saves the liquid factors.
///
private async void SaveLiquidFactors()
{
if (SelectedRML != null)
{
using (_notification.PushTaskItem("Saving Liquid Factors..."))
{
await SelectedRML.SaveAsync();
InvalidateLiquidFactorsAndProcessTables();
}
}
}
///
/// Navigates to the DB Module in order to edit the selected RML.
///
private void EditRML()
{
ApplicationManager.RequestModule("Data Base", SelectedRML);
}
///
/// Navigates to the Machine Designer Module in order to edit the selected machine.
///
private void EditMachine()
{
ApplicationManager.RequestModule("Machine Designer", SelectedMachine);
}
///
/// Saves the process parameters group.
///
private async void SaveProcessParameters()
{
var response = _notification.ShowTextInput("Enter Group Name", "Group Name");
if (response == null) return;
using (_notification.PushTaskItem("Saving Parameters Group..."))
{
ProcessParametersTablesGroup group = new ProcessParametersTablesGroup();
List tables = new List();
foreach (var table in RmlProcessParametersTableGroup.ProcessParametersTables)
{
var newTable = table.CloneEntity();
newTable.ProcessParametersTablesGroup = group;
tables.Add(newTable);
}
group.Active = true;
group.ProcessParametersTables = tables.ToObservableCollection();
group.Rml = SelectedRML;
group.Name = response;
group.SaveDate = DateTime.UtcNow;
foreach (var g in SelectedRML.ProcessParametersTablesGroups)
{
g.Active = false;
}
//String machineGuid = SelectedMachine.Guid;
//String rmlGuid = SelectedRML.Guid;
SelectedRML.ProcessParametersTablesGroups.Add(group);
await SelectedRML.SaveAsync();
//SelectedMachine = Adapter.Machines.SingleOrDefault(x => x.Guid == machineGuid);
//SelectedRML = Adapter.Rmls.SingleOrDefault(x => x.Guid == rmlGuid);
InvalidateLiquidFactorsAndProcessTables();
}
}
///
/// Invalidates the liquid factors and process parameters tables.
///
private void InvalidateLiquidFactorsAndProcessTables()
{
if (SelectedRML != null && SelectedMachine != null)
{
LiquidTypesRmls = SelectedMachine.Configuration.IdsPacks.OrderBy(x => x.PackIndex).Select(x => x.LiquidType).SelectMany(x => x.LiquidTypesRmls).Where(x => x.Rml.Guid == SelectedRML.Guid).ToList();
RmlProcessParametersTableGroup = SelectedRML.ProcessParametersTablesGroups.ToList().SingleOrDefault(x => x.Active);
_selectedGroupHistory = RmlProcessParametersTableGroup;
if (RmlProcessParametersTableGroup != null)
{
RmlProcessParametersTableGroup = RmlProcessParametersTableGroup.CloneGroup();
RmlProcessParametersTableGroup.ProcessParametersTables = RmlProcessParametersTableGroup.ProcessParametersTables.OrderBy(x => x.TableIndex).ToObservableCollection();
}
GroupsHistory = SelectedRML.ProcessParametersTablesGroups.OrderByDescending(x => x.SaveDate).OrderBy(x => !x.Active).ToObservableCollection();
RaisePropertyChangedAuto(nameof(SelectedGroupHistory));
}
}
///
/// Removes the selected segment.
///
private void RemoveSegment()
{
if (SelectedJob != null && SelectedSegment != null)
{
SelectedJob.Segments.Remove(SelectedSegment);
}
}
///
/// Adds a new segment.
///
private void AddSegment()
{
if (SelectedJob != null)
{
Segment seg = new Segment();
seg.Name = "Untitled Segment";
seg.Length = 1;
SelectedJob.Segments.Add(seg);
SelectedSegment = seg;
AddBrushStop();
}
}
///
/// Removes the selected job.
///
private async void RemoveJob()
{
if (SelectedMachine != null && SelectedJob != null)
{
if (_notification.ShowQuestion("Are you sure you want to delete the selected jobs?"))
{
SelectedJobs.ToList().ForEach(x =>
{
x.DefferedDelete();
});
await SelectedMachine.SaveAsync();
}
}
}
///
/// Adds a new job to the selected machine.
///
private void AddJob()
{
if (SelectedMachine != null)
{
String jobName = _notification.ShowTextInput("Please provide a job name", "Name");
if (!String.IsNullOrWhiteSpace(jobName))
{
Job newJob = new Job();
newJob.Name = jobName;
newJob.CreationDate = DateTime.UtcNow;
newJob.User = _authentication.CurrentUser;
newJob.Rml = Adapter.Rmls.FirstOrDefault();
SelectedJob = newJob;
LoadJob();
}
}
}
///
/// Removes the selected brush stop.
///
private void RemoveBrushStop()
{
if (SelectedBrushStop != null && SelectedSegment != null)
{
SelectedSegment.BrushStops.Remove(SelectedBrushStop);
if (SelectedSegment.BrushStops.Count > 1)
{
SelectedSegment.BrushStops.Last().OffsetPercent = 100;
}
SelectedSegment.BrushStops.ToList().ForEach(x => x.RaiseOffsetChanged());
}
}
///
/// Adds a new brush stop to the selected segment.
///
private void AddBrushStop()
{
if (SelectedSegment != null)
{
var stop = new BrushStop();
stop.OffsetPercent = 100;
stop.Segment = SelectedSegment;
stop.ColorSpace = Adapter.ColorSpaces.FirstOrDefault();
stop.Color = Colors.Black;
stop.SetLiquidVolumes(SelectedMachine.Configuration, SelectedRML, SelectedProcessParametersTable);
SelectedSegment.BrushStops.Add(stop);
SelectedSegment.BrushStops.ToList().ForEach(x => x.RaiseOffsetChanged());
}
}
private List CreateRunningJobEffectiveSegments(Job job)
{
List segments = new List();
foreach (var s in job.Segments)
{
s.Completed = false;
s.Started = false;
segments.Add(s);
if (job.EnableInterSegment && job.Segments.IndexOf(s) != job.Segments.Count - 1)
{
segments.Add(new Segment()
{
Length = job.InterSegmentLength,
BrushStops = new System.Collections.ObjectModel.ObservableCollection()
{
new BrushStop()
{
Color = Colors.White,
}
},
Started = false,
Completed = false
});
}
}
return segments;
}
#endregion
#region Override Methods
protected override void RaisePropertyChangedAuto([CallerMemberName] string caller = null)
{
base.RaisePropertyChangedAuto(caller);
if (!_blockInvalidateCommands)
{
InvalidateRelayCommands();
}
}
#endregion
#region Public Methods
///
/// Add sensor graph from available sensors to displayed graphs.
///
/// The sensor.
public void OnDropAvailableGraph(TechMonitor sensor)
{
if (Graphs.Count < 8)
{
IRealTimeGraph graphControl = null;
GraphControllerBase controller = null;
if (!sensor.MultiChannel)
{
graphControl = new RealTimeGraphControl();
controller = new GraphController();
graphControl.Controller = controller;
}
else
{
graphControl = new RealTimeGraphMultiControl();
controller = new GraphMultiController();
for (int i = 0; i < sensor.ChannelCount; i++)
{
var randomColor = new SolidColorBrush(Core.Helpers.ColorHelper.GetRandomColor());
(controller as GraphMultiController).AddSeries(new DataYSeries()
{
Name = sensor.Description.First().ToString() + (i + 1),
UseFillAndStroke = true,
Stroke = randomColor
});
}
graphControl.Controller = controller;
}
graphControl.Tag = sensor;
graphControl.SensorName = sensor.Description;
graphControl.SensorUnits = sensor.Units;
graphControl.InnerGraph.Minimum = sensor.Min;
graphControl.InnerGraph.Maximum = sensor.Max;
graphControl.InnerGraph.MaxPoints = Common.Helpers.GraphsHelper.GetMaxPoints(sensor.PointsPerFrame);
graphControl.GraphRemoveButtonPressed += (sender, _) =>
{
RemoveGraph(sender as IRealTimeGraph);
};
graphControl.GraphFullScreenButtonPressed += (sender, _) =>
{
StartFullScreenGraph(sender as IRealTimeGraph);
};
Graphs.Add(graphControl);
AvailableGraphs.Remove(sensor);
_controllers.Add(sensor.Name, controller);
}
else
{
_notification.ShowInfo("The maximum number of real-time graphs is eight. Please remove a graph to add another.");
}
}
///
/// Switch the brush stop position in the segment.
///
/// The dragged stop.
/// The dropped stop.
public void OnDropBrushStop(BrushStop draggedStop, BrushStop droppedStop)
{
SelectedSegment.BrushStops.Swap(draggedStop, droppedStop);
int tmpIndex = draggedStop.StopIndex;
draggedStop.StopIndex = droppedStop.StopIndex;
droppedStop.StopIndex = tmpIndex;
if (SelectedSegment.BrushStops.Count > 1)
{
SelectedSegment.BrushStops.First().OffsetPercent = 0;
SelectedSegment.BrushStops.Last().OffsetPercent = 100;
}
}
///
/// Removes the graph.
///
/// The graph.
public void RemoveGraph(IRealTimeGraph graph)
{
var sensor = graph.Tag as TechMonitor;
_controllers.Remove(sensor.Name);
graph.InnerGraph.Dispose();
Graphs.Remove(graph);
AvailableGraphs.Insert(0, sensor);
}
#endregion
#region IShutdownRequestBlocker
public Task OnShutdownRequest()
{
if (IsJobRunning)
{
InvokeUI(() =>
{
_notification.ShowWarning("Please stop the currently running job before closing the developer module.");
});
return Task.FromResult(false);
}
SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedMachineGuid = SelectedMachine != null ? SelectedMachine.Guid : null;
SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedJobGuid = SelectedJob != null ? SelectedJob.Guid : null;
return Task.FromResult(true);
}
#endregion
#region IMainView
protected override void OnViewAttached()
{
base.OnViewAttached();
if (SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedMachineGuid != null)
{
SelectedMachine = Adapter.Machines.SingleOrDefault(x => x.Guid == SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedMachineGuid);
}
if (SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedJobGuid != null && SelectedMachine != null)
{
SelectedJob = SelectedMachine.Jobs.SingleOrDefault(x => x.Guid == SettingsManager.Default.MachineStudio.DeveloperModule.LastSelectedJobGuid);
}
}
#endregion
}
}