aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/LoadingView.xaml.cs
blob: 15eba3cf870495b95046b79d1756b856f1dcfe84 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Tango.MachineStudio.UI.Views
{
    /// <summary>
    /// Interaction logic for LoadingView.xaml
    /// </summary>
    public partial class LoadingView : UserControl
    {
        public LoadingView()
        {
            InitializeComponent();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Tango.BL;
using Tango.BL.Builders;
using Tango.BL.Entities;
using Tango.BL.Enumerations;
using Tango.Core.Commands;
using Tango.MachineStudio.Common;
using Tango.MachineStudio.Common.Notifications;
using Tango.MachineStudio.Statistics.Models;
using Tango.SharedUI;
using Tango.SharedUI.Components;
using Tango.AutoComplete.Editors;
using System.Windows.Media;
using LiveCharts.Wpf;
using LiveCharts;
using Tango.BL.ValueObjects;

namespace Tango.MachineStudio.Statistics.ViewModels
{
    public class JobRunsViewVM : ViewModel
    {
        private INotificationProvider _notification;
        private List<Machine> _allMachines;
        private List<User> _allUsers;
        private List<RmlModel> _rmlsModels;

        #region Properties

        private ObservableCollection<JobRunModel> _jobRuns;
        /// <summary>
        /// Gets or sets the job runs. Contains filtered data of JobRunModel.
        /// </summary>
        public ObservableCollection<JobRunModel> JobRuns
        {
            get { return _jobRuns; }
            set
            {
                _jobRuns = value;
                RaisePropertyChangedAuto();
            }
        }

        private JobRunModel _selectedJobRun = null;
        /// <summary>
        /// Gets or sets the JobRunModel. Binding to selected item of grid items.
        /// </summary>
        public JobRunModel SelectedJobRun
        {
            get { return _selectedJobRun; }
            set
            {
                _selectedJobRun = value;
                RaisePropertyChangedAuto();
            }
        }

        private SelectedObjectCollection<Machine> _selectedMachines;
        /// <summary>
        /// Gets or sets the selected machines. Contains all available machines and selected machines. Binding to ComboBox Machines.
        /// </summary>
        public SelectedObjectCollection<Machine> SelectedMachines
        {
            get { return _selectedMachines; }
            set
            {
                _selectedMachines = value;
                RaisePropertyChangedAuto();
            }
        }

        private DateTime _startSelectedDate;
        /// <summary>
        /// Gets or sets the start selected date.
        /// </summary>
        public DateTime StartSelectedDate
        {
            get { return _startSelectedDate; }
            set { _startSelectedDate = value; RaisePropertyChangedAuto(); }
        }

        private DateTime _endSelectedDate;
        /// <summary>
        /// Gets or sets the end selected date.
        /// </summary>
        public DateTime EndSelectedDate
        {
            get { return _endSelectedDate; }
            set { _endSelectedDate = value; RaisePropertyChangedAuto(); }
        }

        protected Double _lengthLowerValue;
        /// <summary>
        /// Gets or sets the length lower value of Range Slider
        /// </summary>
        public Double LengthLowerValue
        {
            get { return _lengthLowerValue; }
            set
            {
                _lengthLowerValue = value;
                RaisePropertyChangedAuto();
            }
        }

        protected Double _lengthUpperValue;
        /// <summary>
        /// Gets or sets the length upper value of Range Slider.
        /// </summary>
        public Double LengthUpperValue
        {
            get { return _lengthUpperValue; }
            set
            {
                _lengthUpperValue = value;
                RaisePropertyChangedAuto();
            }
        }

        private SelectedObjectCollection<JobSource> _jobRunSelectedSources;
        /// <summary>
        /// Gets or sets the job run selected sources. Binding to ComboBox "Source".
        /// </summary>
        public SelectedObjectCollection<JobSource> JobRunSelectedSources
        {
            get { return _jobRunSelectedSources; }
            set { _jobRunSelectedSources = value; RaisePropertyChangedAuto(); }
        }

        private SelectedObjectCollection<JobRunStatus> _jobRunSelectedStatuses;
        /// <summary>
        /// Gets or sets the job run selected statuses. Binding to ComboBox "Status".
        /// </summary>
        public SelectedObjectCollection<JobRunStatus> JobRunSelectedStatuses
        {
            get { return _jobRunSelectedStatuses; }
            set { _jobRunSelectedStatuses = value; RaisePropertyChangedAuto(); }
        }

        public SelectedObjectCollection<bool> _isGradientSelection;
        /// <summary>
        /// Gets or sets the is gradient selection. Binding to ComboBox "IsGradient".
        /// </summary>
        public SelectedObjectCollection<bool> IsGradientSelection
        {
            get { return _isGradientSelection; }
            set
            {
                _isGradientSelection = value;
                RaisePropertyChangedAuto();
            }
        }

        private SelectedObjectCollection<RmlModel> _selectedThreads;
        /// <summary>
        /// Gets or sets the selected threads. Contains all available threads and selected threads. Binding to ComboBox "Thread".
        /// </summary>
        public SelectedObjectCollection<RmlModel> SelectedThreads
        {
            get { return _selectedThreads; }
            set
            {
                _selectedThreads = value;
                RaisePropertyChangedAuto();
            }
        }

        /// <summary>
        /// Gets or sets the JobRuns providers.
        /// </summary>
        public ISuggestionProvider JobsProvider { get; set; }

        private Job _selectedJob;
        /// <summary>
        /// Gets or sets the job.
        /// </summary>
        public Job SelectedJob
        {
            get { return _selectedJob; }
            set
            {
                _selectedJob = value;
                RaisePropertyChangedAuto();
            }
        }

        /// <summary>
        /// Gets or sets the statistics value collection. Class - container included calculated statistic values.
        /// </summary>
        public StatisticsValueCollection StatisticsValueCollection { get; set; }

        #endregion

        public RelayCommand LoadJobRunsCommand { get; set; }

        public JobRunsViewVM(INotificationProvider notificationProvider)
        {
            _notification = notificationProvider;
            JobRuns = new ObservableCollection<JobRunModel>();
            LoadJobRunsCommand = new RelayCommand(async () => await LoadJobRuns(), () => IsFree);
            LengthUpperValue = 5000.0;
            LengthLowerValue = 0.0;
            DateTime now = DateTime.Now;
            StartSelectedDate = now.AddMonths(-1);
            EndSelectedDate = now;

            JobRunSelectedSources = new SelectedObjectCollection<JobSource>(new ObservableCollection<JobSource>()
            {
                JobSource.Local,
                JobSource.Remote
            }, new ObservableCollection<JobSource>()
            {
                JobSource.Local,
                JobSource.Remote
            });
            JobRunSelectedSources.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources));
            JobRunSelectedSources.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedSources));

            JobRunSelectedStatuses = new SelectedObjectCollection<JobRunStatus>(new ObservableCollection<JobRunStatus>()
            {
                JobRunStatus.Aborted,
                JobRunStatus.Completed,
                JobRunStatus.Failed,

            }, new ObservableCollection<JobRunStatus>()
            {
                JobRunStatus.Aborted,
                JobRunStatus.Completed,
                JobRunStatus.Failed,

            });
            JobRunSelectedStatuses.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses));
            JobRunSelectedStatuses.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(JobRunSelectedStatuses));

            IsGradientSelection = new SelectedObjectCollection<bool>(new ObservableCollection<bool>
            {
                true,
                false
            }, new ObservableCollection<bool>
            {
                true,
                false
            });
            IsGradientSelection.SelectionChanged -= (x, y) => RaisePropertyChanged(nameof(IsGradientSelection));
            IsGradientSelection.SelectionChanged += (x, y) => RaisePropertyChanged(nameof(IsGradientSelection));
            JobsProvider = new SuggestionProvider((filter) =>
            {
                try
                {
                    if (filter != null)
                    {
                        using (ObservablesContext db = ObservablesContext.CreateDefault())
                        {
                            return db.Jobs.Where(x => x.Name != null && x.Name.ToLower().Contains(filter.ToLower())).ToList();
                        }
                    }
                    else
                    {
                        return new List<Job>();
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error loading jobs.");
                    return null;
                }
            });

            StatisticsValueCollection = new StatisticsValueCollection();
        }

        /// <summary>
        /// Initializes this instance. Called form main view VM in OnApplicationReady
        /// </summary>
        public async void Init()
        {
            using (_notification.PushTaskItem("Loading job runs..."))
            {
                try
                {
                    IsFree = false;

                    using (var db = ObservablesContext.CreateDefault())
                    {
                        _allMachines = await db.Machines.ToListAsync();
                        _allUsers = await db.Users.Include(x => x.Contact).ToListAsync();
                        _rmlsModels = await db.Rmls.Select(x => new RmlModel() { Name = x.Name, Guid = x.Guid }).ToListAsync();
                        SelectedMachines = new SelectedObjectCollection<Machine>(_allMachines.ToObservableCollection(), new ObservableCollection<Machine>());
                        SelectedThreads = new SelectedObjectCollection<RmlModel>(_rmlsModels.ToObservableCollection(), new ObservableCollection<RmlModel>());
                    }
                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error loading job runs.");
                }
                finally
                {
                    IsFree = true;
                }
            }
        }

        /// <summary>
        /// Loads the job runs by filters. 
        /// </summary>
        private async Task LoadJobRuns()
        {
            using (_notification.PushTaskItem("Loading job runs..."))
            {
                try
                {
                    IsFree = false;

                    using (var db = ObservablesContext.CreateDefault())
                    {
                        DateTime startUtc = StartSelectedDate.ToUniversalTime();
                        TimeSpan offsetTime = (EndSelectedDate.Date == DateTime.Now.Date) ? DateTime.Now.TimeOfDay : new TimeSpan(23, 59, 59);
                        DateTime endUtc = EndSelectedDate.ToUniversalTime() + offsetTime;
                        string jobName = SelectedJob == null ? "" : SelectedJob.Name;

                        var runs = await new JobRunsCollectionBuilder(db).Set(x => x.StartDate <= DbFunctions.TruncateTime(endUtc) && x.StartDate >= DbFunctions.TruncateTime(startUtc.Date))
                        .WithMachines(SelectedMachines.SynchedSource.ToList())
                        .WithJobSource(JobRunSelectedSources.SynchedSource)
                        .WithJobStatus(JobRunSelectedStatuses.SynchedSource)
                        .WithGradient(IsGradientSelection.SynchedSource)
                        .WithRmls(SelectedThreads.SynchedSource.Select(x => x.Guid).ToList())
                        .Query(y => y.Where(x => (String.IsNullOrEmpty(jobName) || x.JobName.ToLower().StartsWith(jobName.ToLower()))
                                                && (x.JobLength < LengthUpperValue && x.JobLength >= LengthLowerValue)))
                        .BuildListAsync();

                        var modelList = runs.Select(x => new JobRunModel()
                        {
                            JobRun = x,
                            Machine = _allMachines.FirstOrDefault(y => y.Guid == x.MachineGuid),
                            User = _allUsers.SingleOrDefault(y => y.Guid == x.UserGuid),
                            Rml = _rmlsModels.SingleOrDefault(y => y.Guid == x.RmlGuid),
                        }).OrderByDescending(x => x.JobRun.StartDate).ToList();

                        modelList.ForEach(x => x.Init());
                        JobRuns = modelList.ToObservableCollection();
                        GenerateStatistics();
                    }


                }
                catch (Exception ex)
                {
                    LogManager.Log(ex, "Error loading job runs.");
                }
                finally
                {
                    IsFree = true;
                }
            }
        }

        #region GenerateS_StatisticsValueCollection 

        /// <summary>
        /// Generates the statistics.
        /// </summary>
        protected void GenerateStatistics()
        {
            StatisticsValueCollection.Clean();
            GenerateTotalRunsCount();
            GenerateTotalRunsLength();
            GenerateTotalThreadConsumption();
            GenerateRunsDuration();
            GenerateAverageUploadDuration();
            GenerateAverageHeatingDuration();

            GeneratePieCharts();
            CreateThreadConsumptionPerThread();
            GenerateAllLiquidQuantities();
        }

        protected void GenerateTotalRunsCount()
        {//Total Runs: 
            int val =JobRuns.Where(z => z.JobRun.EndPosition > 0).Count();
            StatisticsValueCollection.AddStatisticsValue("Total Runs ", val, " ");
        }

        /// <summary>
        /// Generates the total length of the job runs.
        /// </summary>
        protected void GenerateTotalRunsLength()
        {
            double val = JobRuns.Where(z => z.JobRun.EndPosition > 0).Sum(x => x.JobRun.JobLength);
            StatisticsValueCollection.AddStatisticsValue("Total Runs Length", val, " m");
        }

        /// <summary>
        /// Generates the duration and average of the job runs.
        /// </summary>
        protected void GenerateRunsDuration()
        {
            var selection = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.JobRun.EndDate != null && z.JobRun.ActualStartDate != null);
            double val = selection.Sum(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate).Value.TotalHours);
            StatisticsValueCollection.AddStatisticsValue("Total Runs Duration", val, " hours");
            double average = selection.Average(x => (x.JobRun.EndDate - x.JobRun.ActualStartDate).Value.TotalMilliseconds);
            StatisticsValueCollection.AddStatisticsValue("Average Runs Duration", Math.Max(TimeSpan.FromMilliseconds(average).TotalHours, 0), " hours");
        }

        /// <summary>
        /// Generates the average upload duration of the job runs.
        /// </summary>
        protected void GenerateAverageUploadDuration()
        {
            var average = (long)JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.UploadDuration != null).Average(x => x.UploadDuration.Value.TotalMilliseconds);
            StatisticsValueCollection.AddStatisticsValue("Average Upload Duration", Math.Max(TimeSpan.FromMilliseconds(average).TotalMinutes, 0), " minutes");
        }

        /// <summary>
        /// Generates the average duration heating of the job runs.
        /// </summary>
        protected void GenerateAverageHeatingDuration()
        {
            var average = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.HeatingDuration != null && z.HeatingDuration.Value.Ticks > 0).Average(x => x.HeatingDuration.Value.TotalMilliseconds);
            StatisticsValueCollection.AddStatisticsValue("Average Heating Duration", Math.Max(TimeSpan.FromMilliseconds(average).TotalMinutes, 0), " minutes");
        }

        /// <summary>
        /// Generates the total thread consumption by EndPosition.
        /// </summary>
        protected void GenerateTotalThreadConsumption()
        {
            double val = JobRuns.Where(z => z.JobRun.EndPosition > 0).Sum(x => x.JobRun.EndPosition);
            StatisticsValueCollection.AddStatisticsValue("Actual Total Runs Length", val, " m");
        }

        /// <summary>
        /// Generates the pie charts in percentage: JobSource, JobRunStatus, Gradient.
        /// </summary>
        protected void GeneratePieCharts()
        {
            int PPCCount = JobRuns.Count(x => x.JobRun.Source == JobSource.Local);
            int MSCount = JobRuns.Count(x => x.JobRun.Source == JobSource.Remote);
            StatisticsValueCollection.GeneratePieJobSource(PPCCount, MSCount);

            int failedCount = JobRuns.Count(x => x.JobRun.JobRunStatus == JobRunStatus.Failed);
            int abortedCount = JobRuns.Count(x => x.JobRun.JobRunStatus == JobRunStatus.Aborted);
            int completedCount = JobRuns.Count(x => x.JobRun.JobRunStatus == JobRunStatus.Completed);
            StatisticsValueCollection.GeneratePieJobRunStatus(failedCount, abortedCount, completedCount);

            int gradientCount = JobRuns.Count(x => x.JobRun.IsGradient == true);
            int solidCount = JobRuns.Count(x => x.JobRun.IsGradient == false);
            StatisticsValueCollection.GeneratePieGradientSolid(gradientCount, solidCount);

        }

        /// <summary>
        /// Creates the thread consumption per thread.
        /// </summary>
        protected void CreateThreadConsumptionPerThread()
        {
            var temp = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.Rml != null).GroupBy(x => x.Rml.Name);
            List<StatisticsValue> result = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.Rml != null && !String.IsNullOrEmpty(z.Rml.Name)).GroupBy(x => x.Rml.Name).Select(y => new StatisticsValue { Name = y.Key, Value = y.Sum(x => x.JobRun.EndPosition), Unit = "m" }).ToList();
            StatisticsValueCollection.CreateThreadConsumptionPerThread(result);
        }

        /// <summary>
        /// Generates all liquid quantities.
        /// </summary>
        protected void GenerateAllLiquidQuantities()
        {
            var db_liquidQuantities = JobRuns.Where(z => z.JobRun.EndPosition > 0 && z.JobRun.LiquidQuantities.Count > 0).Select(y => y.JobRun.LiquidQuantities).ToList();
            List<JobRunLiquidQuantity> allLiquidQuantities = new List<JobRunLiquidQuantity>();

            foreach (LiquidTypes ltype in (LiquidTypes[])Enum.GetValues(typeof(LiquidTypes)))
            {
                var liquidQuantityByTypeList = db_liquidQuantities.Select(x => x.FirstOrDefault(y => y.LiquidType == ltype)).Where(x => x != null);
                var count = liquidQuantityByTypeList != null ? liquidQuantityByTypeList.Sum(x => x.Quantity) : 0;
                JobRunLiquidQuantity lq = new JobRunLiquidQuantity() { LiquidType = ltype, Quantity = count };
                allLiquidQuantities.Add(lq);
            }
            StatisticsValueCollection.GenerateStatisticsLiquidQuantity(allLiquidQuantities);
        }
        #endregion

    }
}