aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs
diff options
context:
space:
mode:
authorRoy <Roy.mail.net@gmail.com>2022-11-13 03:46:12 +0200
committerRoy <Roy.mail.net@gmail.com>2022-11-13 03:46:12 +0200
commitd38bf750367c6d6cdda3a6a3efbdf3552aa85358 (patch)
tree000818a2a1e49d1e3decc630a94cf183bbaf2128 /Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs
parent8431040bf909ba65d5ce242b5fd2cc91005ba679 (diff)
downloadTango-d38bf750367c6d6cdda3a6a3efbdf3552aa85358.tar.gz
Tango-d38bf750367c6d6cdda3a6a3efbdf3552aa85358.zip
FSE Stats Module.
Extended job run structure. CSV export.
Diffstat (limited to 'Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs')
-rw-r--r--Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs486
1 files changed, 466 insertions, 20 deletions
diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs
index 2a14b7de1..c85a411e3 100644
--- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs
+++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Statistics/ViewModels/MainViewVM.cs
@@ -1,14 +1,24 @@
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
+using System.Data.Entity;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
+using System.Windows.Data;
+using Tango.BL;
+using Tango.BL.DTO;
+using Tango.BL.Entities;
using Tango.BL.Enumerations;
+using Tango.Core.Commands;
+using Tango.CSV;
using Tango.FSE.Common;
using Tango.FSE.Common.AutoComplete;
using Tango.FSE.Common.Navigation;
+using Tango.FSE.Common.Notifications;
+using Tango.FSE.Common.Statistics;
+using Tango.FSE.Statistics.Models;
using Tango.PPC.Shared.Statistics;
using Tango.SharedUI.Components;
using Tango.SharedUI.Helpers;
@@ -17,6 +27,48 @@ namespace Tango.FSE.Statistics.ViewModels
{
public class MainViewVM : FSEViewModel
{
+ private List<ProcessParametersTable> _processTables;
+
+ private DateTime _startSelectedDate;
+ public DateTime StartSelectedDate
+ {
+ get { return _startSelectedDate; }
+ set
+ {
+ _startSelectedDate = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ private DateTime _endSelectedDate;
+ public DateTime EndSelectedDate
+ {
+ get { return _endSelectedDate; }
+ set { _endSelectedDate = value; RaisePropertyChangedAuto(); }
+ }
+
+ protected Double _lengthLowerValue;
+ public Double LengthLowerValue
+ {
+ get { return _lengthLowerValue; }
+ set
+ {
+ _lengthLowerValue = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
+ protected Double _lengthUpperValue;
+ public Double LengthUpperValue
+ {
+ get { return _lengthUpperValue; }
+ set
+ {
+ _lengthUpperValue = value;
+ RaisePropertyChangedAuto();
+ }
+ }
+
private RequiredFiltersData _filtersData;
public RequiredFiltersData FiltersData
{
@@ -38,10 +90,82 @@ namespace Tango.FSE.Statistics.ViewModels
set { _selectedThreads = value; RaisePropertyChangedAuto(); }
}
+ private String _jobName;
+ public String JobName
+ {
+ get { return _jobName; }
+ set { _jobName = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _includeHeadCleaning;
+ public bool IncludeHeadCleaning
+ {
+ get { return _includeHeadCleaning; }
+ set { _includeHeadCleaning = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isSettingsBarOpened;
+ public bool IsSettingsBarOpened
+ {
+ get { return _isSettingsBarOpened; }
+ set { _isSettingsBarOpened = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _isFiltersAvailable;
+ public bool IsFiltersAvailable
+ {
+ get { return _isFiltersAvailable; }
+ set { _isFiltersAvailable = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); }
+ }
+
+ private List<StopModel> _stops;
+ public List<StopModel> Stops
+ {
+ get { return _stops; }
+ set { _stops = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsResultsAvailable)); InvalidateRelayCommands(); }
+ }
+
+ private ListCollectionView _stopView;
+ public ListCollectionView StopsView
+ {
+ get { return _stopView; }
+ set { _stopView = value; RaisePropertyChangedAuto(); }
+ }
+
+ private bool _jobNameExact;
+ public bool JobNameExact
+ {
+ get { return _jobNameExact; }
+ set { _jobNameExact = value; RaisePropertyChangedAuto(); }
+ }
+
+ public RelayCommand GetStatisticsCommand { get; set; }
+
public AutoCompleteSource<String> JobsAutoCompleteProvider { get; set; }
+ private StatsModel _stats;
+ public StatsModel Stats
+ {
+ get { return _stats; }
+ set { _stats = value; RaisePropertyChangedAuto(); }
+ }
+
+ public bool IsResultsAvailable
+ {
+ get { return Stops != null && Stops.Count > 0 && Stops[0].JobIndex != -1000; }
+ }
+
+ public RelayCommand<StopModel> ShowFailedMessageCommand { get; set; }
+
+ public RelayCommand ExportToCsvCommand { get; set; }
+
+
public MainViewVM()
{
+ IsSettingsBarOpened = true;
+
+ _processTables = new List<ProcessParametersTable>();
+
JobRunSelectedStatuses = new SelectedObjectCollection<JobRunStatus>(new ObservableCollection<JobRunStatus>()
{
JobRunStatus.Aborted,
@@ -58,15 +182,31 @@ namespace Tango.FSE.Statistics.ViewModels
JobRunSelectedStatuses.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses));
JobRunSelectedStatuses.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses));
- FiltersData = new RequiredFiltersData();
-
JobsAutoCompleteProvider = new AutoCompleteSource<string>(AutoCompleteJobs);
+
+ StartSelectedDate = DateTime.Now.AddYears(-7);
+ EndSelectedDate = DateTime.Now;
+ LengthUpperValue = 10000;
+
+ GetStatisticsCommand = new RelayCommand(GetStatistics, () => IsFiltersAvailable);
+
+ //Just for showing the columns :/
+ Stops = new List<StopModel>() { new StopModel() { JobRun = new JobRunDTO(), Job = new PresentationJob(), JobIndex = -1000 } };
+ var view = new ListCollectionView(Stops);
+ view.GroupDescriptions.Add(new PropertyGroupDescription("JobIndex"));
+ view.GroupDescriptions.Add(new PropertyGroupDescription("SegmentIndex"));
+ StopsView = view;
+
+ Stats = new StatsModel();
+
+ ShowFailedMessageCommand = new RelayCommand<StopModel>(ShowJobRunFailedMessage);
+ ExportToCsvCommand = new RelayCommand(ExportToCSV, () => IsResultsAvailable);
}
private List<String> AutoCompleteJobs(string key)
{
key = key ?? String.Empty;
- return FiltersData.Jobs.Where(x => x.ToLower().Contains(key.ToLower())).ToList();
+ return FiltersData.Jobs.Where(x => x != null).Where(x => x.ToLower().Contains(key.ToLower())).ToList();
}
public override void OnApplicationStarted()
@@ -86,32 +226,338 @@ namespace Tango.FSE.Statistics.ViewModels
});
}
- public async override void OnNavigatedTo()
+ public async override void OnApplicationReady()
{
- base.OnNavigatedTo();
- await LoadFiltersData();
- await LoadStatistics();
+ base.OnApplicationReady();
+
+ MachineProvider.MachineConnected += MachineProvider_MachineConnected;
+ MachineProvider.MachineDisconnected += MachineProvider_MachineDisconnected;
+
+ try
+ {
+ using (ObservablesContext db = ObservablesContext.CreateDefault())
+ {
+ _processTables = await db.ProcessParametersTables.ToListAsync();
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error loading process parameters tables for statistics.");
+ }
+ }
+
+ private void MachineProvider_MachineDisconnected(object sender, Common.Connection.MachineDisconnectedEventArgs e)
+ {
+
+ }
+
+ private async void MachineProvider_MachineConnected(object sender, Common.Connection.MachineConnectedEventArgs e)
+ {
+ if (MachineProvider.IsPPCAvailable && (e.DifferentFromPrevious || !IsFiltersAvailable))
+ {
+ await LoadFiltersData();
+ }
}
private async Task LoadFiltersData()
{
- FiltersData = await StatisticsProvider.GetRequiredFiltersData();
- SelectedThreads = new SelectedObjectCollection<ThreadFilterData>(FiltersData.Rmls.ToObservableCollection(), new ObservableCollection<ThreadFilterData>());
+ try
+ {
+ FiltersData = await StatisticsProvider.GetRequiredFiltersData();
+ SelectedThreads = new SelectedObjectCollection<ThreadFilterData>(FiltersData.Rmls.ToObservableCollection(), new ObservableCollection<ThreadFilterData>());
+ IsFiltersAvailable = true;
+ }
+ catch (Exception ex)
+ {
+ IsFiltersAvailable = false;
+ NotificationProvider.PushErrorReportingSnackbar(ex, "Statistics Module Error", "Error loading required statistics filter data.");
+ }
+ }
+
+ private async void GetStatistics()
+ {
+ StatisticsModel model = null;
+ try
+ {
+ using (var task = NotificationProvider.PushTaskItem("Getting statistics from the remote machine...", false))
+ {
+ await Task.Delay(3000);
+
+ Filters filters = new Filters();
+ filters.StartDateUTC = StartSelectedDate;
+ filters.EndDateUTC = EndSelectedDate;
+ filters.EndStatuses = JobRunSelectedStatuses.SynchedSource.Cast<int>().ToList();
+ filters.IncludeHeadCleaning = IncludeHeadCleaning;
+ filters.JobName = JobName;
+ filters.ExactJobName = JobNameExact;
+ filters.MinLength = (int)LengthLowerValue;
+ filters.MaxLength = (int)LengthUpperValue;
+ filters.RmlGuids = SelectedThreads.SynchedSource.Select(x => x.Guid).ToList();
+
+ model = await StatisticsProvider.GetStatistics(filters);
+
+ List<StopModel> stops = new List<StopModel>();
+
+ int jobIndex = 0;
+
+ foreach (var job in model.StatisticsResult.JobRuns.OrderByDescending(x => x.JobRun.StartDate))
+ {
+ var rmlName = FiltersData.Rmls.FirstOrDefault(x => x.Guid == job.JobRun.RmlGuid)?.Name;
+ var processTable = _processTables.FirstOrDefault(x => x.Guid == job.JobRun.ProcessParametersTableGuid);
+
+ jobIndex++;
+
+ foreach (var jobSegment in job.Job.Segments)
+ {
+ foreach (var jobStop in jobSegment.Stops)
+ {
+ StopModel stop = new StopModel();
+ stop.JobIndex = jobIndex;
+ stop.SegmentIndex = job.Job.Segments.IndexOf(jobSegment) + 1;
+ stop.ThreadName = rmlName;
+ stop.ProcessParameters = processTable;
+ stop.IsAdvancedMode = !BuildProvider.IsTwineStudio && CurrentUser.HasRole(Roles.FSETwineTechnician);
+
+ stop.ColorSpace = jobStop.ColorSpace;
+
+ stop.L = jobStop.L;
+ stop.A = jobStop.A;
+ stop.B = jobStop.B;
+
+ stop.Red = jobStop.Red;
+ stop.Green = jobStop.Green;
+ stop.Blue = jobStop.Blue;
+
+ stop.Cyan = jobStop.Cyan;
+ stop.Magenta = jobStop.Magenta;
+ stop.Yellow = jobStop.Yellow;
+ stop.Black = jobStop.Black;
+
+ stop.Catalog = jobStop.Catalog;
+ stop.CatalogItem = jobStop.CatalogItem;
+
+ stop.StartMeters = jobStop.StartMeters;
+
+ stop.Job = job.Job;
+ stop.JobRun = job.JobRun;
+ stop.Segment = jobSegment;
+
+ stop.LiquidVolumes = jobStop.LiquidVolumes;
+ stop.BestMatchR = jobStop.BestMatchR;
+ stop.BestMatchG = jobStop.BestMatchG;
+ stop.BestMatchB = jobStop.BestMatchB;
+
+ stop.ShowFailedMessageCommand = ShowFailedMessageCommand;
+
+ stops.Add(stop);
+ }
+ }
+ }
+
+ Stops = stops;
+
+ var view = new ListCollectionView(Stops);
+ view.GroupDescriptions.Add(new PropertyGroupDescription("JobIndex"));
+ view.GroupDescriptions.Add(new PropertyGroupDescription("SegmentIndex"));
+
+ StopsView = view;
+
+ var stats = new StatsModel();
+
+ try
+ {
+ stats.TotalRuns = model.StatisticsResult.JobRuns.Count;
+ stats.CompletedRuns = model.StatisticsResult.JobRuns.Count(x => x.JobRun.Status == (int)JobRunStatus.Completed);
+ stats.FailedRuns = model.StatisticsResult.JobRuns.Count(x => x.JobRun.Status == (int)JobRunStatus.Failed);
+ stats.AbortedRuns = model.StatisticsResult.JobRuns.Count(x => x.JobRun.Status == (int)JobRunStatus.Aborted);
+ stats.TotalDyeingLength = (int)model.StatisticsResult.JobRuns.Where(x => x.JobRun.EndPosition > 0).Select(x => x.JobRun.EndPosition).Sum();
+ stats.AverageDyeingLength = (int)model.StatisticsResult.JobRuns.Where(x => x.JobRun.EndPosition > 0).Select(x => x.JobRun.EndPosition).Average();
+
+ var timeRuns = model.StatisticsResult.JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.JobRun.EndDate != null && z.JobRun.ActualStartDate != null).ToList();
+
+ stats.TotalDyeingTime = TimeSpan.FromHours(timeRuns.Sum(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate.Value).TotalHours));
+ stats.AverageDyeingTime = TimeSpan.FromHours(timeRuns.Average(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate.Value).TotalHours));
+
+ List<LiquidQuantityModel> liquidQuantities = new List<LiquidQuantityModel>();
+
+ Dictionary<LiquidTypes, double> quantities = new Dictionary<LiquidTypes, double>();
+ quantities.Add(LiquidTypes.Cyan, 0);
+ quantities.Add(LiquidTypes.Magenta, 0);
+ quantities.Add(LiquidTypes.Yellow, 0);
+ quantities.Add(LiquidTypes.Black, 0);
+ quantities.Add(LiquidTypes.LightCyan, 0);
+ quantities.Add(LiquidTypes.LightMagenta, 0);
+ quantities.Add(LiquidTypes.LightYellow, 0);
+ quantities.Add(LiquidTypes.TransparentInk, 0);
+ quantities.Add(LiquidTypes.Lubricant, 0);
+
+ foreach (var stop in stops)
+ {
+ quantities[LiquidTypes.Cyan] += stop.JobRun.CyanQuantity;
+ quantities[LiquidTypes.Magenta] += stop.JobRun.MagentaQuantity;
+ quantities[LiquidTypes.Yellow] += stop.JobRun.YellowQuantity;
+ quantities[LiquidTypes.Black] += stop.JobRun.BlackQuantity;
+ quantities[LiquidTypes.LightCyan] += stop.JobRun.LightCyanQuantity;
+ quantities[LiquidTypes.LightMagenta] += stop.JobRun.LightMagentaQuantity;
+ quantities[LiquidTypes.LightYellow] += stop.JobRun.LightYellowQuantity;
+ quantities[LiquidTypes.TransparentInk] += stop.JobRun.TransparentQuantity;
+ quantities[LiquidTypes.Lubricant] += stop.JobRun.LubricantQuantity;
+ }
+
+ foreach (var item in quantities)
+ {
+ liquidQuantities.Add(new LiquidQuantityModel() { LiquidType = item.Key, Quantity = item.Value });
+ }
+
+ stats.LiquidQuantities = liquidQuantities;
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error generating statistics summaries.");
+ }
+
+ Stats = stats;
+
+ if (Stops.Count > 0)
+ {
+ await Task.Delay(1000);
+
+ IsSettingsBarOpened = false;
+
+ await Task.Delay(1000);
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ NotificationProvider.PushErrorReportingSnackbar(ex, "Statistics Module Error", "Error statistics from the remote machine.");
+ }
+ }
+
+ private async void ShowJobRunFailedMessage(StopModel stop)
+ {
+ await NotificationProvider.ShowError($"Job Failure Message:\n{stop.JobRun.FailedMessage}");
}
- private async Task LoadStatistics()
+ private async void ExportToCSV()
{
- Filters filters = new Filters();
- filters.StartDateUTC = DateTime.Now.AddYears(-1).ToUniversalTime();
- filters.EndDateUTC = DateTime.Now.ToUniversalTime();
- filters.EndStatuses = JobRunSelectedStatuses.SynchedSource.Cast<int>().ToList();
- filters.IncludeHeadCleaning = false;
- filters.JobName = null;
- filters.MinLength = 0;
- filters.MaxLength = 10000;
- filters.RmlGuids = SelectedThreads.SynchedSource.Select(x => x.Guid).ToList();
+ var result = await StorageProvider.SaveFile("Export To CSV File", "CSV Files|*.csv", $"{MachineProvider.Machine.SerialNumber}_JobRuns_{DateTime.Now.ToFileName()}.csv", ".csv");
+ if (result.Confirmed)
+ {
+ using (NotificationProvider.PushTaskItem("Exporting job runs to file..."))
+ {
+ await Task.Delay(1000);
+
+ try
+ {
+ CsvFile<CsvModel> csvFile = new CsvFile<CsvModel>(new CsvDestination(result.SelectedItem), new CsvDefinition()
+ {
+ Columns = new List<String>()
+ {
+ "Job Index",
+ "Job Name",
+ "Thread",
+ "Length",
+ "Start Time",
+ "Duration",
+ "End Position",
+ "Status",
+ "Segment Index",
+ "Offset",
+ "Color Space",
+ "Input Red",
+ "Input Green",
+ "Input Blue",
+ "Input L",
+ "Input A",
+ "Input B",
+ "Input Catalog",
+ "Input Catalog Item",
+ "Input Cyan",
+ "Input Magenta",
+ "Input Yellow",
+ "Input Black",
+ "Output Cyan",
+ "Output Magenta",
+ "Output Yellow",
+ "Output Black",
+ "Output Light Cyan",
+ "Output Light Magenta",
+ "Output Light Yellow",
+ "Output Transparent Ink",
+ "Output Lubricant",
+ "Failure Reason",
+ },
+ });
+
+ foreach (var stop in Stops.OrderBy(x => x.JobIndex).ToList())
+ {
+ CsvModel model = new CsvModel();
+ model.JobIndex = stop.JobIndex.ToString();
+ model.JobName = stop.JobRun.JobName;
+ model.Thread = stop.ThreadName;
+ model.Length = ((int)stop.JobRun.JobLength).ToString();
+ model.StartTime = stop.JobRun.StartDate.ToLocalTime().ToString();
+ model.Duration = stop.Duration.ToStringUnlimitedHours();
+ model.EndPosition = stop.JobRun.EndPosition.ToString();
+ model.Status = ((JobRunStatus)stop.JobRun.Status).ToString();
+ model.SegmentIndex = stop.SegmentIndex.ToString();
+ model.Offset = stop.StartMeters.ToString();
+ model.ColorSpace = stop.ColorSpace.ToString();
+
+ switch (stop.ColorSpace)
+ {
+ case ColorSpaces.RGB:
+ model.InputRed = stop.Red.ToString();
+ model.InputGreen = stop.Green.ToString();
+ model.InputBlue = stop.Blue.ToString();
+ break;
+ case ColorSpaces.LAB:
+ model.InputL = stop.L.ToString();
+ model.InputA = stop.A.ToString();
+ model.InputB = stop.B.ToString();
+ break;
+ case ColorSpaces.Catalog:
+ model.InputCatalog = stop.Catalog;
+ model.InputCatalogItem = stop.CatalogItem;
+ break;
+ case ColorSpaces.Volume:
+ model.InputCyan = stop.Cyan.ToString();
+ model.InputMagenta = stop.Magenta.ToString();
+ model.InputYellow = stop.Yellow.ToString();
+ model.InputBlack = stop.Black.ToString();
+ break;
+ }
+
+
+ model.OutputCyan = stop.CyanOutput.ToString();
+ model.OutputMagenta = stop.MagentaOutput.ToString();
+ model.OutputYellow = stop.YellowOutput.ToString();
+ model.OutputBlack = stop.BlackOutput.ToString();
+ model.OutputLightCyan = stop.LightCyanOutput.ToString();
+ model.OutputLightMagenta = stop.LightMagentaOutput.ToString();
+ model.OutputLightYellow = stop.LightYellowOutput.ToString();
+ model.OutputTransparentInk = stop.TransparentInkOutput.ToString();
+ model.OutputLubricant = stop.LubricantOutput.ToString();
+ model.FailureReason = stop.JobRun.FailedMessage;
+
+ csvFile.Append(model);
+ }
+
+ csvFile.Dispose();
- var model = await StatisticsProvider.GetStatistics(filters);
+ NotificationProvider.PushSnackbarItem(MessageType.Success, "Statistics File Export", true, "Export completed successfully.\nTap to open the file.", null, null, async () =>
+ {
+ await StorageProvider.ShowInExplorer(result.SelectedItem);
+ });
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error exporting csv file.");
+ await NotificationProvider.ShowError($"Error exporting the csv file.\n{ex.FlattenMessage()}");
+ }
+ }
+ }
}
}
}