From dd81a94133e1c5117e06e84cbddf45ffec30acfc Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Tue, 5 May 2020 00:35:57 +0300 Subject: Dashboard completed ? Remote job tracking. --- .../Behaviors/CircularProgressBarBehavior.cs | 38 ++++ .../Tango.FSE.Common/Behaviors/StyleBehavior.cs | 47 +++++ .../FSE/Tango.FSE.Common/Controls/ProgressRing.cs | 26 +++ .../Tango.FSE.Common/Controls/ProgressRing.xaml | 121 +++++++++++ .../Controls/ProgressRingDouble.cs | 17 ++ .../Controls/ProgressRingDouble.xaml | 23 +++ .../Controls/RunningJobRingProgress.xaml | 81 ++++++++ .../Controls/RunningJobRingProgress.xaml.cs | 50 +++++ .../Controls/RunningJobViewer.xaml | 225 +++++++++++++++++++++ .../Controls/RunningJobViewer.xaml.cs | 84 ++++++++ .../Converters/JobProgressToPositionConverter.cs | 36 ++++ .../FSE/Tango.FSE.Common/DashboardTile.cs | 1 + .../ExtensionMethods/ViewModelExtensionMethods.cs | 47 ++++- .../FSE/Tango.FSE.Common/FSEViewModel.cs | 7 + .../FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml | 2 +- .../Tango.FSE.Common/Images/transparent_small.jpg | Bin 0 -> 10743 bytes .../RemoteJob/IRemoteJobProvider.cs | 16 ++ .../RemoteJob/RemoteJobProgressEventArgs.cs | 19 ++ .../RemoteJob/RemoteJobStartedEventArgs.cs | 15 ++ .../RemoteJob/RemoteJobStoppedEventArgs.cs | 14 ++ .../FSE/Tango.FSE.Common/Resources/Colors.xaml | 2 + .../FSE/Tango.FSE.Common/Resources/Controls.xaml | 2 + .../FSE/Tango.FSE.Common/Resources/Converters.xaml | 1 + .../FSE/Tango.FSE.Common/Tango.FSE.Common.csproj | 34 ++++ .../Tango.FSE.UI/Images/Abstracts/lines_gray.png | Bin 0 -> 823198 bytes .../RemoteJob/DefaultRemoteJobProvider.cs | 128 ++++++++++++ .../FSE/Tango.FSE.UI/Tango.FSE.UI.csproj | 32 ++- .../FSE/Tango.FSE.UI/Tiles/Events/EventsTile.cs | 82 ++++++++ .../Tango.FSE.UI/Tiles/Events/EventsTileView.xaml | 4 +- .../Tango.FSE.UI/Tiles/Events/EventsTileViewVM.cs | 82 -------- .../FSE/Tango.FSE.UI/Tiles/Machine/MachineTile.cs | 29 +++ .../Tiles/Machine/MachineTileView.xaml | 4 +- .../Tiles/Machine/MachineTileViewVM.cs | 29 --- .../Tiles/MidTankLevels/MidTankLevelsTile.cs | 169 ++++++++++++++++ .../Tiles/MidTankLevels/MidTankLevelsTileView.xaml | 2 +- .../Tiles/MidTankLevels/MidTankLevelsTileViewVM.cs | 161 --------------- .../OverallTemperature/OverallTemperatureTile.cs | 71 +++++++ .../OverallTemperatureTileView.xaml | 4 +- .../OverallTemperatureTileViewVM.cs | 71 ------- .../Tiles/RemoteJob/RemoteJobProgressRingTile.cs | 33 +++ .../RemoteJob/RemoteJobProgressRingTileView.xaml | 14 ++ .../RemoteJobProgressRingTileView.xaml.cs | 28 +++ .../Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs | 111 ++++++++++ .../Tiles/RemoteJob/RemoteJobTileView.xaml | 17 ++ .../Tiles/RemoteJob/RemoteJobTileView.xaml.cs | 28 +++ .../FSE/Tango.FSE.UI/ViewModelLocator.cs | 4 + .../FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs | 10 +- .../FSE/Tango.FSE.UI/Views/DashboardView.xaml | 218 ++++++++++---------- .../FSE/Tango.FSE.UI/Views/EventsView.xaml | 2 +- .../RemoteJob/DefaultRemoteJobService.cs | 153 ++++++++++++++ .../RemoteJob/IRemoteJobService.cs | 14 ++ .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 4 +- .../PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs | 21 ++ .../PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs | 18 ++ .../Jobs/RemoteJobUpdateRequest.cs | 13 ++ .../Jobs/RemoteJobUpdateResponse.cs | 22 ++ .../PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj | 8 + .../PPC/Tango.PPC.UI/ViewModelLocator.cs | 3 + Software/Visual_Studio/Tango.Core/TangoProgress.cs | 23 ++- .../Tango.Integration/Operation/JobHandler.cs | 24 ++- 60 files changed, 2058 insertions(+), 486 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/CircularProgressBarBehavior.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/StyleBehavior.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Converters/JobProgressToPositionConverter.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/Images/transparent_small.jpg create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/IRemoteJobProvider.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobProgressEventArgs.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStartedEventArgs.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStoppedEventArgs.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Images/Abstracts/lines_gray.png create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJob/DefaultRemoteJobProvider.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTile.cs delete mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTile.cs delete mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTile.cs delete mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTile.cs delete mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileViewVM.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTile.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml create mode 100644 Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/DefaultRemoteJobService.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/IRemoteJobService.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateRequest.cs create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateResponse.cs (limited to 'Software') diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/CircularProgressBarBehavior.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/CircularProgressBarBehavior.cs new file mode 100644 index 000000000..24162d176 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/CircularProgressBarBehavior.cs @@ -0,0 +1,38 @@ +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.Shapes; + +namespace Tango.FSE.Common.Behaviors +{ + public class CircularProgressBarBehavior : StyleBehavior + { + public static readonly DependencyProperty StrokeThicknessProperty = + DependencyProperty.RegisterAttached("StrokeThickness", typeof(double), typeof(CircularProgressBarBehavior), new PropertyMetadata(3d)); + + public static double GetStrokeThickness(DependencyObject dependencyObject) + { + return (double)dependencyObject.GetValue(StrokeThicknessProperty); + } + + protected override void OnAttached() + { + base.OnAttached(); + + // ReSharper disable once CompareOfFloatsByEqualityOperator + var path = AssociatedObject.FindVisualChildren().FirstOrDefault(e => e.Name.Equals("Path")); + + if (path != null) + path.StrokeThickness = GetStrokeThickness(AssociatedObject); + } + + public static void SetStrokeThickness(DependencyObject dependencyObject, double value) + { + dependencyObject.SetValue(StrokeThicknessProperty, value); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/StyleBehavior.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/StyleBehavior.cs new file mode 100644 index 000000000..f8ff649ff --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Behaviors/StyleBehavior.cs @@ -0,0 +1,47 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Interactivity; + +namespace Tango.FSE.Common.Behaviors +{ + public class StyleBehavior : Behavior + where TComponent : System.Windows.DependencyObject + where TBehavior : StyleBehavior, new() + { + public static DependencyProperty IsEnabledForStyleProperty = + DependencyProperty.RegisterAttached("IsEnabledForStyle", typeof(bool), + typeof(StyleBehavior), new FrameworkPropertyMetadata(false, OnIsEnabledForStyleChanged)); + + public bool IsEnabledForStyle + { + get { return (bool)GetValue(IsEnabledForStyleProperty); } + set { SetValue(IsEnabledForStyleProperty, value); } + } + + private static void OnIsEnabledForStyleChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) + { + UIElement uie = d as UIElement; + + if (uie != null) + { + var behColl = Interaction.GetBehaviors(uie); + var existingBehavior = behColl.FirstOrDefault(b => b.GetType() == + typeof(TBehavior)) as TBehavior; + + if ((bool)e.NewValue == false && existingBehavior != null) + { + behColl.Remove(existingBehavior); + } + + else if ((bool)e.NewValue == true && existingBehavior == null) + { + behColl.Add(new TBehavior()); + } + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.cs new file mode 100644 index 000000000..9da818073 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Controls; + +namespace Tango.FSE.Common.Controls +{ + public class ProgressRing : ProgressBar + { + public double Thickness + { + get { return (double)GetValue(ThicknessProperty); } + set { SetValue(ThicknessProperty, value); } + } + public static readonly DependencyProperty ThicknessProperty = + DependencyProperty.Register("Thickness", typeof(double), typeof(ProgressRing), new PropertyMetadata(3.0)); + + static ProgressRing() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ProgressRing), new FrameworkPropertyMetadata(typeof(ProgressRing))); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.xaml new file mode 100644 index 000000000..ca33aab58 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRing.xaml @@ -0,0 +1,121 @@ + + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.cs new file mode 100644 index 000000000..36c0b60a3 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.cs @@ -0,0 +1,17 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; + +namespace Tango.FSE.Common.Controls +{ + public class ProgressRingDouble : ProgressRing + { + static ProgressRingDouble() + { + DefaultStyleKeyProperty.OverrideMetadata(typeof(ProgressRingDouble), new FrameworkPropertyMetadata(typeof(ProgressRingDouble))); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.xaml new file mode 100644 index 000000000..6466e37e3 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/ProgressRingDouble.xaml @@ -0,0 +1,23 @@ + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml new file mode 100644 index 000000000..d0121afa5 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml @@ -0,0 +1,81 @@ + + + + + + + + + + + + + + + + Completed + + + + + m + + + + + + + Getting ready... + + + + + + + + Time Left + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml.cs new file mode 100644 index 000000000..5e0f28419 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobRingProgress.xaml.cs @@ -0,0 +1,50 @@ +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; +using Tango.Integration.Operation; + +namespace Tango.FSE.Common.Controls +{ + /// + /// Interaction logic for RunningJobRingProgress.xaml + /// + public partial class RunningJobRingProgress : UserControl + { + /// + /// Gets or sets the running job status. + /// + public RunningJobStatus RunningJobStatus + { + get { return (RunningJobStatus)GetValue(RunningJobStatusProperty); } + set { SetValue(RunningJobStatusProperty, value); } + } + public static readonly DependencyProperty RunningJobStatusProperty = + DependencyProperty.Register("RunningJobStatus", typeof(RunningJobStatus), typeof(RunningJobRingProgress), new PropertyMetadata(null)); + + public bool IsRunning + { + get { return (bool)GetValue(IsRunningProperty); } + set { SetValue(IsRunningProperty, value); } + } + public static readonly DependencyProperty IsRunningProperty = + DependencyProperty.Register("IsRunning", typeof(bool), typeof(RunningJobRingProgress), new PropertyMetadata(false)); + + + + public RunningJobRingProgress() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml new file mode 100644 index 000000000..427a04c64 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml @@ -0,0 +1,225 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + job canceled + + + + + + + + + + job failed + + + + + + + + + + job completed + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml.cs new file mode 100644 index 000000000..4a970ffda --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Controls/RunningJobViewer.xaml.cs @@ -0,0 +1,84 @@ +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; +using Tango.BL.Entities; +using Tango.Integration.Operation; + +namespace Tango.FSE.Common.Controls +{ + /// + /// Interaction logic for RunningJobViewer.xaml + /// + public partial class RunningJobViewer : UserControl + { + /// + /// Maybe not necessary! + /// + public bool IsActive + { + get { return (bool)GetValue(IsActiveProperty); } + set { SetValue(IsActiveProperty, value); } + } + public static readonly DependencyProperty IsActiveProperty = + DependencyProperty.Register("IsActive", typeof(bool), typeof(RunningJobViewer), new PropertyMetadata(false)); + + /// + /// Gets or sets a value indicating whether summary markers. + /// + public bool DisplayMarkers + { + get { return (bool)GetValue(DisplayMarkersProperty); } + set { SetValue(DisplayMarkersProperty, value); } + } + public static readonly DependencyProperty DisplayMarkersProperty = + DependencyProperty.Register("DisplayMarkers", typeof(bool), typeof(RunningJobViewer), new PropertyMetadata(true)); + + /// + /// Gets or sets the job. + /// + public Job Job + { + get { return (Job)GetValue(JobProperty); } + set { SetValue(JobProperty, value); } + } + public static readonly DependencyProperty JobProperty = + DependencyProperty.Register("Job", typeof(Job), typeof(RunningJobViewer), new PropertyMetadata(null)); + + /// + /// Gets or sets the running job status. + /// + public RunningJobStatus RunningJobStatus + { + get { return (RunningJobStatus)GetValue(RunningJobStatusProperty); } + set { SetValue(RunningJobStatusProperty, value); } + } + public static readonly DependencyProperty RunningJobStatusProperty = + DependencyProperty.Register("RunningJobStatus", typeof(RunningJobStatus), typeof(RunningJobViewer), new PropertyMetadata(null)); + + public bool IsRunning + { + get { return (bool)GetValue(IsRunningProperty); } + set { SetValue(IsRunningProperty, value); } + } + public static readonly DependencyProperty IsRunningProperty = + DependencyProperty.Register("IsRunning", typeof(bool), typeof(RunningJobViewer), new PropertyMetadata(false)); + + + + public RunningJobViewer() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Converters/JobProgressToPositionConverter.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/Converters/JobProgressToPositionConverter.cs new file mode 100644 index 000000000..12f0c30db --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Converters/JobProgressToPositionConverter.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Data; + +namespace Tango.FSE.Common.Converters +{ + /// + /// Converts a job progress to X position using the specified UI element width. + /// + /// + public class JobProgressToPositionConverter : IMultiValueConverter + { + public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) + { + if (values.Length == 3 && values[1] != DependencyProperty.UnsetValue) + { + double progress = (double)values[0]; + double total = (double)values[1]; + double ui_width = (double)values[2]; + return (progress / total) * ui_width; + } + + return 0d; + } + + public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs index f3c8412c2..9d8b3b24e 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/DashboardTile.cs @@ -15,6 +15,7 @@ namespace Tango.FSE.Common public bool AutoContainerStyle { get; set; } = true; public bool AutoTitleStyle { get; set; } = true; public Dock AutoTitleAlignment { get; set; } = Dock.Left; + public double AutoTitleLineOffset { get; set; } = 30; public int Column { get; set; } public int Row { get; set; } public int ColumnSpan { get; set; } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs index 73ecd990b..d4f8fdfaa 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/ExtensionMethods/ViewModelExtensionMethods.cs @@ -35,14 +35,25 @@ public static class ViewModelExtensionMethods /// The property name. public static void SetFocus(this ViewModel vm, string propertyName) { - Application.Current.Dispatcher.BeginInvoke(new Action(() => + Application.Current.Dispatcher.BeginInvoke(new Action(async () => { - var element = FindElementByPropertyName(vm, Application.Current.MainWindow, propertyName); + await Task.Delay(200); - if (element != null) + var control = GetUserControl(vm, Application.Current.MainWindow); + + if (control != null) { - element.Focusable = true; - Keyboard.Focus(element); + var element = FindElementByPropertyName(vm, control, propertyName); + + if (element != null) + { + element.Focusable = true; + Keyboard.Focus(element); + } + else + { + Debug.WriteLine($"SetFocus: {propertyName} not found!"); + } } else { @@ -52,7 +63,31 @@ public static class ViewModelExtensionMethods }), DispatcherPriority.ApplicationIdle); } - private static FrameworkElement FindElementByPropertyName(ViewModel vm, UIElement parent, string propName) + private static UserControl GetUserControl(ViewModel vm, FrameworkElement parent) + { + var children = parent.FindVisualChildren(); + + foreach (var child in children) + { + if (child.DataContext == vm) + { + return child; + } + else + { + var innerChild = GetUserControl(vm, child); + + if (innerChild != null) + { + return innerChild; + } + } + } + + return null; + } + + private static FrameworkElement FindElementByPropertyName(ViewModel vm, FrameworkElement parent, string propName) { FrameworkElement foundChild = null; diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs index 4cebdef59..dbded7041 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/FSEViewModel.cs @@ -40,6 +40,7 @@ using Tango.FSE.Common.Firmware; using Tango.FSE.Common.Threading; using Tango.FSE.Common.Events; using Tango.FSE.Common.Tiles; +using Tango.FSE.Common.RemoteJob; namespace Tango.FSE.Common { @@ -177,6 +178,12 @@ namespace Tango.FSE.Common [TangoInject] public IEventsProvider EventsProvider { get; set; } + /// + /// Gets or sets the remote job provider. + /// + [TangoInject] + public IRemoteJobProvider RemoteJobProvider { get; set; } + /// /// Gets or sets the dashboard manager. /// diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml index 44bbad085..b2a61518f 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Graphs/RealTimeGraph.xaml @@ -89,7 +89,7 @@ - + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/transparent_small.jpg b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/transparent_small.jpg new file mode 100644 index 000000000..c682a4c7e Binary files /dev/null and b/Software/Visual_Studio/FSE/Tango.FSE.Common/Images/transparent_small.jpg differ diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/IRemoteJobProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/IRemoteJobProvider.cs new file mode 100644 index 000000000..65299eac9 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/IRemoteJobProvider.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.FSE.Common.RemoteJob +{ + public interface IRemoteJobProvider : INotifyApplicationStarted + { + event EventHandler RemoteJobStarted; + event EventHandler RemoteJobStopped; + + bool IsRemoteJobRunning { get; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobProgressEventArgs.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobProgressEventArgs.cs new file mode 100644 index 000000000..039bcfd15 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobProgressEventArgs.cs @@ -0,0 +1,19 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Shared.Jobs; + +namespace Tango.FSE.Common.RemoteJob +{ + public class RemoteJobProgressEventArgs : EventArgs + { + public RemoteJobProgress Progress { get; set; } + + public RemoteJobProgressEventArgs() + { + Progress = new RemoteJobProgress(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStartedEventArgs.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStartedEventArgs.cs new file mode 100644 index 000000000..001263044 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStartedEventArgs.cs @@ -0,0 +1,15 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Integration.Operation; + +namespace Tango.FSE.Common.RemoteJob +{ + public class RemoteJobStartedEventArgs : EventArgs + { + public JobHandler JobHandler { get; set; } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStoppedEventArgs.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStoppedEventArgs.cs new file mode 100644 index 000000000..ed71555d7 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteJob/RemoteJobStoppedEventArgs.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.PPC.Shared.Jobs; + +namespace Tango.FSE.Common.RemoteJob +{ + public class RemoteJobStoppedEventArgs : EventArgs + { + + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml index 5bfc5cc2b..792826d31 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Colors.xaml @@ -4,6 +4,7 @@ #202020 + #262626 #303030 #404040 #505050 @@ -46,6 +47,7 @@ + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml index 420af935c..99aeb7bf3 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Controls.xaml @@ -9,6 +9,8 @@ + + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml index c09ca61c2..019206d15 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml @@ -42,4 +42,5 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj index 86f163582..0d89c64ba 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Tango.FSE.Common.csproj @@ -100,6 +100,8 @@ + + @@ -121,10 +123,19 @@ MachineView.xaml + + + + RunningJobRingProgress.xaml + + + RunningJobViewer.xaml + + @@ -194,6 +205,10 @@ + + + + @@ -231,6 +246,22 @@ MSBuild:Compile Designer + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -463,6 +494,9 @@ + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/Abstracts/lines_gray.png b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/Abstracts/lines_gray.png new file mode 100644 index 000000000..3f2e42054 Binary files /dev/null and b/Software/Visual_Studio/FSE/Tango.FSE.UI/Images/Abstracts/lines_gray.png differ diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJob/DefaultRemoteJobProvider.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJob/DefaultRemoteJobProvider.cs new file mode 100644 index 000000000..586bf2105 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteJob/DefaultRemoteJobProvider.cs @@ -0,0 +1,128 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Core.DI; +using Tango.FSE.Common.Connection; +using Tango.FSE.Common.Notifications; +using Tango.FSE.Common.RemoteJob; +using Tango.Integration.Operation; +using Tango.PPC.Shared.Jobs; +using Tango.Transport; + +namespace Tango.FSE.UI.RemoteJob +{ + [TangoCreateWhenRegistered] + public class DefaultRemoteJobProvider : IRemoteJobProvider + { + private JobHandler _handler; + + public event EventHandler RemoteJobStarted; + public event EventHandler RemoteJobStopped; + + public bool IsRemoteJobRunning { get; private set; } + + [TangoInject] + private IMachineProvider MachineProvider { get; set; } + + [TangoInject] + private INotificationProvider NotificationProvider { get; set; } + + public void OnApplicationStarted() + { + MachineProvider.MachineConnected += MachineProvider_MachineConnected; + } + + private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) + { + init(); + } + + private void init() + { + try + { + MachineProvider.MachineOperator.SendGenericContinuousRequest(new RemoteJobUpdateRequest() + { + //Request + }, new TransportContinuousRequestConfig() + { + Timeout = TimeSpan.FromSeconds(30) + }).Subscribe((response) => + { + //Response + InvalidateJobResponse(response); + }, (ex) => + { + //Failed + NotificationProvider.PushErrorReportingSnackbar(ex, "Remote Job Module Error", "Remote job display failed to initialize."); + }, () => + { + //Completed ? (never) + }); + } + catch (Exception ex) + { + NotificationProvider.PushErrorReportingSnackbar(ex, "Remote Job Module Error", "Remote job display failed to initialize."); + } + } + + private void InvalidateJobResponse(RemoteJobUpdateResponse response) + { + var stage = response.Progress.Stage; + + if (stage == RemoteJobStage.None) + { + return; + } + + if (stage == RemoteJobStage.Started && !IsRemoteJobRunning) + { + _handler = new JobHandler(() => { }, response.Job.ToObservable(), null, response.ProcessParameters.ToObservable(), JobHandlerModes.SettingUp); + + IsRemoteJobRunning = true; + RemoteJobStarted?.Invoke(this, new RemoteJobStartedEventArgs() + { + JobHandler = _handler + }); + + return; + } + + if (_handler != null) + { + if (response.Progress.JobStatus != null) + { + _handler.RaiseStatusReceived(response.Progress.JobStatus); + } + + if (stage == RemoteJobStage.Failed && IsRemoteJobRunning) + { + IsRemoteJobRunning = false; + _handler.RaiseFailed(new Exception("Job failed")); + _handler = null; + } + else if (stage == RemoteJobStage.Aborted && IsRemoteJobRunning) + { + IsRemoteJobRunning = false; + _handler.RaiseCanceled(); + _handler = null; + } + else if (stage == RemoteJobStage.Completed && IsRemoteJobRunning) + { + IsRemoteJobRunning = false; + RemoteJobStopped?.Invoke(this, new RemoteJobStoppedEventArgs()); + _handler.RaiseCompleted(); + _handler = null; + } + } + } + + public void OnApplicationReady() + { + //Do Nothing. + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj index 933863104..a15d7cfda 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tango.FSE.UI.csproj @@ -285,6 +285,7 @@ + ExplorerControlDialog.xaml @@ -302,19 +303,27 @@ EventsTileView.xaml - + MachineTileView.xaml - + MidTankLevelsTileView.xaml - + OverallTemperatureTileView.xaml - + + + RemoteJobProgressRingTileView.xaml + + + + RemoteJobTileView.xaml + + @@ -429,6 +438,14 @@ Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + Designer MSBuild:Compile @@ -718,7 +735,12 @@ - + + + + + + call "$(DevEnvDir)..\..\vc\vcvarsall.bat" x86 diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTile.cs new file mode 100644 index 000000000..9730acd32 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTile.cs @@ -0,0 +1,82 @@ +using System; +using System.Collections.Generic; +using System.Collections.Specialized; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.BL.Enumerations; +using Tango.FSE.Common; + +namespace Tango.FSE.UI.Tiles.Events +{ + public class EventsTile : DashboardTile + { + private double _InfoEvents; + public double InfoEvents + { + get { return _InfoEvents; } + set { _InfoEvents = value; RaisePropertyChangedAuto(); } + } + + private double _warningEvents; + public double WarningEvents + { + get { return _warningEvents; } + set { _warningEvents = value; RaisePropertyChangedAuto(); } + } + + private double _errorEvents; + public double ErrorEvents + { + get { return _errorEvents; } + set { _errorEvents = value; RaisePropertyChangedAuto(); } + } + + private double _criticalEvents; + public double CriticalEvents + { + get { return _criticalEvents; } + set { _criticalEvents = value; RaisePropertyChangedAuto(); } + } + + private bool _canExecuteJob; + public bool CanExecuteJob + { + get { return _canExecuteJob; } + set { _canExecuteJob = value; RaisePropertyChangedAuto(); } + } + + public EventsTile() + { + Name = "Active Events"; + AutoContainerStyle = false; + AutoTitleAlignment = System.Windows.Controls.Dock.Right; + Column = 8; + Row = 0; + ColumnSpan = 4; + RowSpan = 6; + CanExecuteJob = true; + } + + public override void OnApplicationStarted() + { + EventsProvider.ActiveEvents.CollectionChanged += ActiveEvents_CollectionChanged; + } + + private void ActiveEvents_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) + { + InfoEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Info).Count(); + WarningEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Warning).Count(); + ErrorEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Error).Count(); + CriticalEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Critical).Count(); + + CanExecuteJob = !EventsProvider.ActiveEvents.Any(x => x.EventType.Actions.Contains(EventTypeActions.PreventJob)); + } + + public override FrameworkElement GetView() + { + return new EventsTileView(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml index ee3857a97..14116ab91 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileView.xaml @@ -8,7 +8,7 @@ xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common" xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:EventsTileViewVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:EventsTile, IsDesignTimeCreatable=False}"> @@ -46,7 +46,7 @@ - critical errors + critical diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileViewVM.cs deleted file mode 100644 index 0b9670a1d..000000000 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Events/EventsTileViewVM.cs +++ /dev/null @@ -1,82 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Collections.Specialized; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using Tango.BL.Enumerations; -using Tango.FSE.Common; - -namespace Tango.FSE.UI.Tiles.Events -{ - public class EventsTileViewVM : DashboardTile - { - private double _InfoEvents; - public double InfoEvents - { - get { return _InfoEvents; } - set { _InfoEvents = value; RaisePropertyChangedAuto(); } - } - - private double _warningEvents; - public double WarningEvents - { - get { return _warningEvents; } - set { _warningEvents = value; RaisePropertyChangedAuto(); } - } - - private double _errorEvents; - public double ErrorEvents - { - get { return _errorEvents; } - set { _errorEvents = value; RaisePropertyChangedAuto(); } - } - - private double _criticalEvents; - public double CriticalEvents - { - get { return _criticalEvents; } - set { _criticalEvents = value; RaisePropertyChangedAuto(); } - } - - private bool _canExecuteJob; - public bool CanExecuteJob - { - get { return _canExecuteJob; } - set { _canExecuteJob = value; RaisePropertyChangedAuto(); } - } - - public EventsTileViewVM() - { - Name = "Active Events"; - AutoContainerStyle = false; - AutoTitleAlignment = System.Windows.Controls.Dock.Right; - Column = 8; - Row = 0; - ColumnSpan = 4; - RowSpan = 6; - CanExecuteJob = true; - } - - public override void OnApplicationStarted() - { - EventsProvider.ActiveEvents.CollectionChanged += ActiveEvents_CollectionChanged; - } - - private void ActiveEvents_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e) - { - InfoEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Info).Count(); - WarningEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Warning).Count(); - ErrorEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Error).Count(); - CriticalEvents = EventsProvider.ActiveEvents.ToList().Where(x => x.Category == EventTypeCategories.Critical).Count(); - - CanExecuteJob = !EventsProvider.ActiveEvents.Any(x => x.EventType.Actions.Contains(EventTypeActions.PreventJob)); - } - - public override FrameworkElement GetView() - { - return new EventsTileView(); - } - } -} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTile.cs new file mode 100644 index 000000000..611c4d93e --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTile.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.FSE.Common; + +namespace Tango.FSE.UI.Tiles.Machine +{ + public class MachineTile : DashboardTile + { + public MachineTile() + { + Name = "Machine Configuration"; + AutoContainerStyle = false; + AutoTitleStyle = true; + Column = 0; + Row = 0; + ColumnSpan = 4; + RowSpan = 6; + } + + public override FrameworkElement GetView() + { + return new MachineTileView(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml index f87541676..625f0df7d 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileView.xaml @@ -6,8 +6,8 @@ xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" xmlns:local="clr-namespace:Tango.FSE.UI.Tiles.Machine" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MachineTileViewVM, IsDesignTimeCreatable=False}"> - + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MachineTile, IsDesignTimeCreatable=False}"> + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileViewVM.cs deleted file mode 100644 index ffa8e586a..000000000 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/Machine/MachineTileViewVM.cs +++ /dev/null @@ -1,29 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using Tango.FSE.Common; - -namespace Tango.FSE.UI.Tiles.Machine -{ - public class MachineTileViewVM : DashboardTile - { - public MachineTileViewVM() - { - Name = "Machine Configuration"; - AutoContainerStyle = false; - AutoTitleStyle = true; - Column = 0; - Row = 0; - ColumnSpan = 4; - RowSpan = 6; - } - - public override FrameworkElement GetView() - { - return new MachineTileView(); - } - } -} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTile.cs new file mode 100644 index 000000000..633a346e5 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTile.cs @@ -0,0 +1,169 @@ +using System; +using System.Collections.Generic; +using System.Diagnostics; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using Tango.BL.Entities; +using Tango.Core; +using Tango.Core.DI; +using Tango.Core.Helpers; +using Tango.FSE.Common; +using Tango.FSE.Common.Connection; +using Tango.Integration.Operation; +using Tango.PMR.MachineStatus; + +namespace Tango.FSE.UI.Tiles.MidTankLevels +{ + public class MidTankLevelsTile : DashboardTile + { + public class MidTankLevelModel : ExtendedObject + { + public double Max { get; set; } + + private double _level; + public double Level + { + get { return _level; } + set { _level = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsLow)); RaisePropertyChanged(nameof(IsEmpty)); } + } + + public bool IsLow + { + get { return Level <= MachineOperator.LOW_MIDTANK_LITERS; } + } + + public bool IsEmpty + { + get { return Level <= MachineOperator.EMPTY_MIDTANK_LITERS; } + } + + public IdsPack IDSPack { get; set; } + } + + private List _midTankLevels; + public List MidTankLevels + { + get { return _midTankLevels; } + set { _midTankLevels = value; RaisePropertyChangedAuto(); } + } + + public MidTankLevelsTile() + { + Name = "Mid Tank Levels"; + Column = 4; + Row = 0; + ColumnSpan = 4; + RowSpan = 3; + AutoContainerStyle = false; + + MidTankLevels = new List() + { + new MidTankLevelModel() + { + Level = 0.5, + Max = MachineOperator.MAX_MIDTANK_LITERS, + IDSPack = new IdsPack() + { + LiquidType = new LiquidType() + { + Color = ColorHelper.ColorToInteger(Colors.Cyan), + Name = "Cyan" + }, + }, + }, + new MidTankLevelModel() + { + Level = 0.2, + Max = MachineOperator.MAX_MIDTANK_LITERS, + IDSPack = new IdsPack() + { + LiquidType = new LiquidType() + { + Color = ColorHelper.ColorToInteger(Colors.Magenta), + Name = "Magenta" + }, + }, + }, + new MidTankLevelModel() + { + Level = 0.9, + Max = MachineOperator.MAX_MIDTANK_LITERS, + IDSPack = new IdsPack() + { + LiquidType = new LiquidType() + { + Color = ColorHelper.ColorToInteger(Colors.Yellow), + Name = "Yellow" + }, + }, + }, + new MidTankLevelModel() + { + Level = 0.1, + Max = MachineOperator.MAX_MIDTANK_LITERS, + IDSPack = new IdsPack() + { + LiquidType = new LiquidType() + { + Color = ColorHelper.ColorToInteger(Colors.Black), + Name = "Black" + }, + }, + } + }; + } + + public override FrameworkElement GetView() + { + return new MidTankLevelsTileView(); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + + MachineProvider.MachineOperator.MachineStatusChanged += MachineOperator_MachineStatusChanged; + MachineProvider.MachineConnected += MachineProvider_MachineConnected; + } + + private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) + { + MidTankLevels = MachineProvider.Machine.Configuration.NoneEmptyIdsPacks.OrderBy(x => x.PackIndex).Select(x => new MidTankLevelModel() + { + Max = MachineOperator.MAX_MIDTANK_LITERS, + IDSPack = x, + }).ToList(); + } + + private void MachineOperator_MachineStatusChanged(object sender, MachineStatus status) + { + UpdateMidTankLevels(status); + } + + private void UpdateMidTankLevels(MachineStatus status) + { + if (IsVisible) + { + try + { + foreach (var item in status.IDSPacksLevels) + { + var model = MidTankLevels.SingleOrDefault(x => x.IDSPack.PackIndex == item.Index); + + if (model != null) + { + model.Level = item.MidTankLevel; + } + } + } + catch + { + Debug.WriteLine("Error on update mid tank levels. (probably because of machine status arrived before machine connected event..)"); + } + } + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml index 6409e6015..fa3a5f853 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileView.xaml @@ -8,7 +8,7 @@ xmlns:resolution="clr-namespace:Tango.FSE.Common.Resolution;assembly=Tango.FSE.Common" xmlns:localConverters="clr-namespace:Tango.FSE.UI.Converters" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MidTankLevelsTileViewVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:MidTankLevelsTile, IsDesignTimeCreatable=False}"> diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileViewVM.cs deleted file mode 100644 index c643bedf6..000000000 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/MidTankLevels/MidTankLevelsTileViewVM.cs +++ /dev/null @@ -1,161 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Media; -using Tango.BL.Entities; -using Tango.Core; -using Tango.Core.DI; -using Tango.Core.Helpers; -using Tango.FSE.Common; -using Tango.FSE.Common.Connection; -using Tango.Integration.Operation; -using Tango.PMR.MachineStatus; - -namespace Tango.FSE.UI.Tiles.MidTankLevels -{ - public class MidTankLevelsTileViewVM : DashboardTile - { - public class MidTankLevelModel : ExtendedObject - { - public double Max { get; set; } - - private double _level; - public double Level - { - get { return _level; } - set { _level = value; RaisePropertyChangedAuto(); RaisePropertyChanged(nameof(IsLow)); RaisePropertyChanged(nameof(IsEmpty)); } - } - - public bool IsLow - { - get { return Level <= MachineOperator.LOW_MIDTANK_LITERS; } - } - - public bool IsEmpty - { - get { return Level <= MachineOperator.EMPTY_MIDTANK_LITERS; } - } - - public IdsPack IDSPack { get; set; } - } - - private List _midTankLevels; - public List MidTankLevels - { - get { return _midTankLevels; } - set { _midTankLevels = value; RaisePropertyChangedAuto(); } - } - - public MidTankLevelsTileViewVM() - { - Name = "Mid Tank Levels"; - Column = 4; - Row = 0; - ColumnSpan = 4; - RowSpan = 3; - AutoContainerStyle = false; - - MidTankLevels = new List() - { - new MidTankLevelModel() - { - Level = 0.5, - Max = MachineOperator.MAX_MIDTANK_LITERS, - IDSPack = new IdsPack() - { - LiquidType = new LiquidType() - { - Color = ColorHelper.ColorToInteger(Colors.Cyan), - Name = "Cyan" - }, - }, - }, - new MidTankLevelModel() - { - Level = 0.2, - Max = MachineOperator.MAX_MIDTANK_LITERS, - IDSPack = new IdsPack() - { - LiquidType = new LiquidType() - { - Color = ColorHelper.ColorToInteger(Colors.Magenta), - Name = "Magenta" - }, - }, - }, - new MidTankLevelModel() - { - Level = 0.9, - Max = MachineOperator.MAX_MIDTANK_LITERS, - IDSPack = new IdsPack() - { - LiquidType = new LiquidType() - { - Color = ColorHelper.ColorToInteger(Colors.Yellow), - Name = "Yellow" - }, - }, - }, - new MidTankLevelModel() - { - Level = 0.1, - Max = MachineOperator.MAX_MIDTANK_LITERS, - IDSPack = new IdsPack() - { - LiquidType = new LiquidType() - { - Color = ColorHelper.ColorToInteger(Colors.Black), - Name = "Black" - }, - }, - } - }; - } - - public override FrameworkElement GetView() - { - return new MidTankLevelsTileView(); - } - - public override void OnApplicationStarted() - { - base.OnApplicationStarted(); - - MachineProvider.MachineOperator.MachineStatusChanged += MachineOperator_MachineStatusChanged; - MachineProvider.MachineConnected += MachineProvider_MachineConnected; - } - - private void MachineProvider_MachineConnected(object sender, MachineConnectedEventArgs e) - { - MidTankLevels = MachineProvider.Machine.Configuration.NoneEmptyIdsPacks.OrderBy(x => x.PackIndex).Select(x => new MidTankLevelModel() - { - Max = MachineOperator.MAX_MIDTANK_LITERS, - IDSPack = x, - }).ToList(); - } - - private void MachineOperator_MachineStatusChanged(object sender, MachineStatus status) - { - UpdateMidTankLevels(status); - } - - private void UpdateMidTankLevels(MachineStatus status) - { - if (IsVisible) - { - foreach (var item in status.IDSPacksLevels) - { - var model = MidTankLevels.SingleOrDefault(x => x.IDSPack.PackIndex == item.Index); - - if (model != null) - { - model.Level = item.MidTankLevel; - } - } - } - } - } -} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTile.cs new file mode 100644 index 000000000..82552f830 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTile.cs @@ -0,0 +1,71 @@ +using RealTimeGraphX.DataPoints; +using RealTimeGraphX.WPF; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using Tango.FSE.Common; +using Tango.FSE.Common.Graphs; +using Tango.FSE.Common.Helpers; +using Tango.Integration.Operation; + +namespace Tango.FSE.UI.Tiles.OverallTemperature +{ + public class OverallTemperatureTile : DashboardTile + { + public WpfGraphController OverallTemperatureController { get; set; } + + public OverallTemperatureTile() + { + Name = "Overall Temperature"; + Column = 4; + Row = 3; + ColumnSpan = 4; + RowSpan = 3; + + OverallTemperatureController = new WpfGraphController(); + OverallTemperatureController.Range.MaximumY = 60; + OverallTemperatureController.Range.MaximumX = new DateTime(0).AddMinutes(1); + OverallTemperatureController.DataSeriesCollection.Add(new WpfGraphDataSeries() + { + Stroke = GraphHelper.GetGraphStrokeColor(), + Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.White), + }); + + OverallTemperatureController.PushData(DateTime.Now, 1); + } + + public override FrameworkElement GetView() + { + return new OverallTemperatureTileView(); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + + MachineProvider.MachineOperator.MachineStatusChanged += MachineOperator_MachineStatusChanged; + } + + private void MachineOperator_MachineStatusChanged(object sender, PMR.MachineStatus.MachineStatus status) + { + if (status.OverallTemperature <= MachineOperator.OVERALL_TEMPERATURE_OK) + { + OverallTemperatureController.DataSeriesCollection[0].Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.White); + } + else if (status.OverallTemperature > MachineOperator.OVERALL_TEMPERATURE_WARNING && status.OverallTemperature < MachineOperator.OVERALL_TEMPERATURE_ERROR) + { + OverallTemperatureController.DataSeriesCollection[0].Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.Orange); + } + else + { + OverallTemperatureController.DataSeriesCollection[0].Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.Red); + } + + OverallTemperatureController.PushData(DateTime.Now, status.OverallTemperature); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml index 5f9714c87..825f60ab9 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileView.xaml @@ -6,9 +6,9 @@ xmlns:local="clr-namespace:Tango.FSE.UI.Tiles.OverallTemperature" xmlns:graphs="clr-namespace:Tango.FSE.Common.Graphs;assembly=Tango.FSE.Common" mc:Ignorable="d" - d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:OverallTemperatureTileViewVM, IsDesignTimeCreatable=False}"> + d:DesignHeight="450" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=local:OverallTemperatureTile, IsDesignTimeCreatable=False}"> - + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileViewVM.cs deleted file mode 100644 index 05709e648..000000000 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/OverallTemperature/OverallTemperatureTileViewVM.cs +++ /dev/null @@ -1,71 +0,0 @@ -using RealTimeGraphX.DataPoints; -using RealTimeGraphX.WPF; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using System.Windows; -using System.Windows.Media; -using Tango.FSE.Common; -using Tango.FSE.Common.Graphs; -using Tango.FSE.Common.Helpers; -using Tango.Integration.Operation; - -namespace Tango.FSE.UI.Tiles.OverallTemperature -{ - public class OverallTemperatureTileViewVM : DashboardTile - { - public WpfGraphController OverallTemperatureController { get; set; } - - public OverallTemperatureTileViewVM() - { - Name = "Overall Temperature"; - Column = 4; - Row = 3; - ColumnSpan = 4; - RowSpan = 3; - - OverallTemperatureController = new WpfGraphController(); - OverallTemperatureController.Range.MaximumY = 60; - OverallTemperatureController.Range.MaximumX = new DateTime(0).AddMinutes(1); - OverallTemperatureController.DataSeriesCollection.Add(new WpfGraphDataSeries() - { - Stroke = GraphHelper.GetGraphStrokeColor(), - Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.White), - }); - - OverallTemperatureController.PushData(DateTime.Now, 1); - } - - public override FrameworkElement GetView() - { - return new OverallTemperatureTileView(); - } - - public override void OnApplicationStarted() - { - base.OnApplicationStarted(); - - MachineProvider.MachineOperator.MachineStatusChanged += MachineOperator_MachineStatusChanged; - } - - private void MachineOperator_MachineStatusChanged(object sender, PMR.MachineStatus.MachineStatus status) - { - if (status.OverallTemperature <= MachineOperator.OVERALL_TEMPERATURE_OK) - { - OverallTemperatureController.DataSeriesCollection[0].Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.White); - } - else if (status.OverallTemperature > MachineOperator.OVERALL_TEMPERATURE_WARNING && status.OverallTemperature < MachineOperator.OVERALL_TEMPERATURE_ERROR) - { - OverallTemperatureController.DataSeriesCollection[0].Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.Orange); - } - else - { - OverallTemperatureController.DataSeriesCollection[0].Fill = GraphHelper.GetGraphBrush(GraphHelper.GraphColor.Red); - } - - OverallTemperatureController.PushData(DateTime.Now, status.OverallTemperature); - } - } -} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTile.cs new file mode 100644 index 000000000..f5519ec48 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTile.cs @@ -0,0 +1,33 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using Tango.FSE.Common; +using Tango.Integration.Operation; + +namespace Tango.FSE.UI.Tiles.RemoteJob +{ + public class RemoteJobProgressRingTile : RemoteJobTile + { + public RemoteJobProgressRingTile() : base() + { + Name = "Remote Job Timer"; + AutoContainerStyle = false; + AutoTitleStyle = false; + AutoTitleAlignment = System.Windows.Controls.Dock.Right; + Column = 4; + Row = 6; + ColumnSpan = 4; + RowSpan = 4; + AutoTitleLineOffset = 60; + RunningJobStatus.RemainingTime = TimeSpan.Zero; + } + + public override FrameworkElement GetView() + { + return new RemoteJobProgressRingTileView(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml new file mode 100644 index 000000000..62e7c4798 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml @@ -0,0 +1,14 @@ + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml.cs new file mode 100644 index 000000000..4279f51b8 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobProgressRingTileView.xaml.cs @@ -0,0 +1,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.FSE.UI.Tiles.RemoteJob +{ + /// + /// Interaction logic for RemoteJobProgressRingTileView.xaml + /// + public partial class RemoteJobProgressRingTileView : UserControl + { + public RemoteJobProgressRingTileView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs new file mode 100644 index 000000000..cb99ef6ca --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTile.cs @@ -0,0 +1,111 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows; +using System.Windows.Media; +using Tango.BL.Entities; +using Tango.FSE.Common; +using Tango.Integration.Operation; +using Tango.PPC.Shared.Jobs; + +namespace Tango.FSE.UI.Tiles.RemoteJob +{ + public class RemoteJobTile : DashboardTile + { + private Job _job; + public Job Job + { + get { return _job; } + set { _job = value; RaisePropertyChangedAuto(); } + } + + private JobHandler _handler; + public JobHandler Handler + { + get { return _handler; } + set { _handler = value; RaisePropertyChangedAuto(); } + } + + private RunningJobStatus _runningJobStatus; + public RunningJobStatus RunningJobStatus + { + get { return _runningJobStatus; } + set { _runningJobStatus = value; RaisePropertyChangedAuto(); } + } + + private bool _isRunning; + public bool IsRunning + { + get { return _isRunning; } + set { _isRunning = value; RaisePropertyChangedAuto(); } + } + + public RemoteJobTile() + { + Name = "Remote Job"; + AutoTitleStyle = true; + AutoContainerStyle = false; + AutoTitleAlignment = System.Windows.Controls.Dock.Top; + Column = 0; + Row = 10; + ColumnSpan = 12; + RowSpan = 2; + + InitDemoJob(); + } + + private void InitDemoJob() + { + Job = new Job(); + Job.NumberOfUnits = 1; + Job.Name = "N/A"; + Job.AddSolidSegment(Color.FromRgb(70, 70, 70), 5); + Job.AddSolidSegment(Colors.Gray, 5); + Job.AddSolidSegment(Color.FromRgb(70, 70, 70), 5); + Job.AddSolidSegment(Colors.Gray, 5); + + Handler = new JobHandler(() => { }, Job, null, new ProcessParametersTable() { DyeingSpeed = 50 }, JobHandlerModes.SettingUp); + Handler.RaiseStatusReceived(new PMR.Printing.JobStatus() + { + Message = "Ready", + CurrentSegmentIndex = 0, + Progress = 0, + }); + + RunningJobStatus = Handler.Status; + } + + public override FrameworkElement GetView() + { + return new RemoteJobTileView(); + } + + public override void OnApplicationStarted() + { + base.OnApplicationStarted(); + + RemoteJobProvider.RemoteJobStarted += RemoteJobProvider_RemoteJobStarted; + RemoteJobProvider.RemoteJobStopped += RemoteJobProvider_RemoteJobStopped; + } + + private void RemoteJobProvider_RemoteJobStopped(object sender, Common.RemoteJob.RemoteJobStoppedEventArgs e) + { + IsRunning = false; + } + + private void RemoteJobProvider_RemoteJobStarted(object sender, Common.RemoteJob.RemoteJobStartedEventArgs e) + { + Handler = e.JobHandler; + Handler.StatusChanged += Handler_StatusChanged; + Job = e.JobHandler.Job; + IsRunning = true; + } + + private void Handler_StatusChanged(object sender, RunningJobStatus status) + { + RunningJobStatus = status; + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml new file mode 100644 index 000000000..ee05314ce --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml @@ -0,0 +1,17 @@ + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml.cs new file mode 100644 index 000000000..174fdfd01 --- /dev/null +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Tiles/RemoteJob/RemoteJobTileView.xaml.cs @@ -0,0 +1,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.FSE.UI.Tiles.RemoteJob +{ + /// + /// Interaction logic for RemoteJobTileView.xaml + /// + public partial class RemoteJobTileView : UserControl + { + public RemoteJobTileView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs index 04c298e5c..7f2c073f0 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModelLocator.cs @@ -56,6 +56,8 @@ using Tango.FSE.Common.Updates; using Tango.FSE.UI.Updates; using Tango.FSE.Common.Tiles; using Tango.FSE.UI.Tiles; +using Tango.FSE.Common.RemoteJob; +using Tango.FSE.UI.RemoteJob; namespace Tango.FSE.UI { @@ -89,6 +91,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); //TangoIOC.Default.Unregister(); @@ -121,6 +124,7 @@ namespace Tango.FSE.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs index 5cee1e8f1..586d57c0a 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/ViewModels/DashboardViewVM.cs @@ -21,10 +21,12 @@ namespace Tango.FSE.UI.ViewModels public override void OnApplicationStarted() { base.OnApplicationStarted(); - DashboardManager.Tiles.Add(new Tiles.Machine.MachineTileViewVM()); - DashboardManager.Tiles.Add(new Tiles.MidTankLevels.MidTankLevelsTileViewVM()); - DashboardManager.Tiles.Add(new Tiles.OverallTemperature.OverallTemperatureTileViewVM()); - DashboardManager.Tiles.Add(new Tiles.Events.EventsTileViewVM()); + DashboardManager.Tiles.Add(new Tiles.Machine.MachineTile()); + DashboardManager.Tiles.Add(new Tiles.MidTankLevels.MidTankLevelsTile()); + DashboardManager.Tiles.Add(new Tiles.OverallTemperature.OverallTemperatureTile()); + DashboardManager.Tiles.Add(new Tiles.Events.EventsTile()); + DashboardManager.Tiles.Add(new Tiles.RemoteJob.RemoteJobTile()); + DashboardManager.Tiles.Add(new Tiles.RemoteJob.RemoteJobProgressRingTile()); } } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml index 35668a10a..3cfcd53d3 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/DashboardView.xaml @@ -16,113 +16,123 @@ + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - + + + + + + + + + No Machine Connection + - - - - - - - - - - - No Machine Connection - - - - - - + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml index 6937856fe..8789cc05c 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/Views/EventsView.xaml @@ -183,7 +183,7 @@ - critical errors + critical diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/DefaultRemoteJobService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/DefaultRemoteJobService.cs new file mode 100644 index 000000000..33e002950 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/DefaultRemoteJobService.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.DTO; +using Tango.Core; +using Tango.Core.DI; +using Tango.Integration.ExternalBridge; +using Tango.Integration.Operation; +using Tango.PPC.Common.Connection; +using Tango.PPC.Common.ExternalBridge; +using Tango.PPC.Shared.Jobs; + +namespace Tango.PPC.Common.RemoteJob +{ + [TangoCreateWhenRegistered] + public class DefaultRemoteJobService : IRemoteJobService, IExternalBridgeRequestHandler + { + private class RunningJobUpdateClient + { + public String Token { get; set; } + public ExternalBridgeReceiver Receiver { get; set; } + public bool JobSent { get; set; } + } + + private List _clients; + private JobHandler _handler; + + public bool Enabled { get; set; } = true; + + private IMachineProvider MachineProvider { get; set; } + + public DefaultRemoteJobService(IPPCExternalBridgeService externalBridge, IMachineProvider machineProvider) + { + externalBridge.RegisterRequestHandler(this); + + MachineProvider = machineProvider; + + _clients = new List(); + MachineProvider.MachineOperator.PrintingStarted += MachineOperator_PrintingStarted; + } + + private async void MachineOperator_PrintingStarted(object sender, Integration.Operation.PrintingEventArgs e) + { + _handler = e.JobHandler; + + e.JobHandler.StatusChanged += JobHandler_StatusChanged; + e.JobHandler.Stopped += JobHandler_Stopped; + + var jobDTO = JobDTO.FromObservable(e.Job); + var processParametersDTO = ProcessParametersTableDTO.FromObservable(_handler.ProcessParameters); + + foreach (var client in _clients.ToList()) + { + try + { + RemoteJobProgress progress = new RemoteJobProgress(); + progress.Stage = RemoteJobStage.Started; + progress.JobStatus = _handler.JobStatus; + + await client.Receiver.SendGenericResponse(new RemoteJobUpdateResponse() + { + Job = jobDTO, + ProcessParameters = processParametersDTO, + Progress = progress + }, client.Token); + + client.JobSent = true; + } + catch { } + } + } + + private async void JobHandler_StatusChanged(object sender, RunningJobStatus e) + { + foreach (var client in _clients.ToList().Where(x => x.JobSent)) + { + try + { + await client.Receiver.SendGenericResponse(new RemoteJobUpdateResponse() + { + Progress = GetJobProgress(_handler) + }, client.Token); + } + catch { } + } + } + + private async void JobHandler_Stopped(object sender, EventArgs e) + { + foreach (var client in _clients.ToList().Where(x => x.JobSent)) + { + try + { + await client.Receiver.SendGenericResponse(new RemoteJobUpdateResponse() + { + Progress = GetJobProgress(_handler), + }, client.Token); + + client.JobSent = false; + } + catch { } + } + } + + private RemoteJobProgress GetJobProgress(JobHandler handler) + { + RemoteJobStage stage = RemoteJobStage.Running; + + if (_handler.Status.IsCanceled) + { + stage = RemoteJobStage.Aborted; + } + else if (_handler.Status.IsCompleted) + { + stage = RemoteJobStage.Completed; + } + else if (_handler.Status.IsFailed) + { + stage = RemoteJobStage.Failed; + } + + return new RemoteJobProgress() + { + Stage = stage, + JobStatus = handler.JobStatus, + }; + } + + [ExternalBridgeRequestHandlerMethod(typeof(RemoteJobUpdateRequest), RequestHandlerLoggingMode.LogRequestName)] + public async Task OnRunningJobUpdateRequest(RemoteJobUpdateRequest request, String token, ExternalBridgeReceiver receiver) + { + this.ThrowIfDisabled(); + + if (!_clients.ToList().Exists(x => x.Receiver == receiver)) + { + _clients.Add(new RunningJobUpdateClient() + { + Receiver = receiver, + Token = token + }); + } + + await receiver.SendGenericResponse(new RemoteJobUpdateResponse(), token); + } + + public void OnReceiverDisconnected(ExternalBridgeReceiver receiver) + { + _clients.RemoveAll(x => x.Receiver == receiver); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/IRemoteJobService.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/IRemoteJobService.cs new file mode 100644 index 000000000..e7bfdbec1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteJob/IRemoteJobService.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Integration.ExternalBridge; + +namespace Tango.PPC.Common.RemoteJob +{ + public interface IRemoteJobService : IPPCService + { + + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj index e97fd9d32..9bdba2c63 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Tango.PPC.Common.csproj @@ -173,6 +173,8 @@ + + @@ -460,7 +462,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs new file mode 100644 index 000000000..d91d612d1 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobProgress.cs @@ -0,0 +1,21 @@ +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.PPC.Shared.Jobs +{ + public class RemoteJobProgress + { + public RemoteJobStage Stage { get; set; } + public JobStatus JobStatus { get; set; } + + public RemoteJobProgress() + { + JobStatus = new JobStatus(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs new file mode 100644 index 000000000..5235b995b --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobStage.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Shared.Jobs +{ + public enum RemoteJobStage + { + None, + Started, + Running, + Failed, + Aborted, + Completed + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateRequest.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateRequest.cs new file mode 100644 index 000000000..1322031ac --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateRequest.cs @@ -0,0 +1,13 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.PPC.Shared.Jobs +{ + public class RemoteJobUpdateRequest + { + + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateResponse.cs new file mode 100644 index 000000000..0bb32d266 --- /dev/null +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Jobs/RemoteJobUpdateResponse.cs @@ -0,0 +1,22 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.DTO; +using Tango.Core; + +namespace Tango.PPC.Shared.Jobs +{ + public class RemoteJobUpdateResponse + { + public JobDTO Job { get; set; } + public ProcessParametersTableDTO ProcessParameters { get; set; } + public RemoteJobProgress Progress { get; set; } + + public RemoteJobUpdateResponse() + { + Progress = new RemoteJobProgress(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj index 153352c20..221cea81e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.Shared/Tango.PPC.Shared.csproj @@ -60,6 +60,10 @@ + + + + @@ -107,6 +111,10 @@ {A34EE0F0-649D-41C8-8489-B6F1CC6924EE} Tango.Core + + {E4927038-348D-4295-AAF4-861C58CB3943} + Tango.PMR + {997a961c-beda-4b56-aa0f-c39e532f7ffa} Tango.SystemInfo diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs index c146de51b..8b75b4517 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModelLocator.cs @@ -25,6 +25,7 @@ using Tango.PPC.Common.Performance; using Tango.PPC.Common.Printing; using Tango.PPC.Common.RemoteAssistance; using Tango.PPC.Common.RemoteDesktop; +using Tango.PPC.Common.RemoteJob; using Tango.PPC.Common.Storage; using Tango.PPC.Common.Synchronization; using Tango.PPC.Common.SystemInfo; @@ -88,6 +89,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); TangoIOC.Default.Unregister(); + TangoIOC.Default.Unregister(); if (App.StartupArgs.Contains("-webDebug")) { @@ -126,6 +128,7 @@ namespace Tango.PPC.UI TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); + TangoIOC.Default.Register(); TangoIOC.Default.Register(); TangoIOC.Default.Register(); diff --git a/Software/Visual_Studio/Tango.Core/TangoProgress.cs b/Software/Visual_Studio/Tango.Core/TangoProgress.cs index be684ece9..ccec0e546 100644 --- a/Software/Visual_Studio/Tango.Core/TangoProgress.cs +++ b/Software/Visual_Studio/Tango.Core/TangoProgress.cs @@ -10,7 +10,7 @@ namespace Tango.Core /// Represents a progress of some process. /// /// - public class TangoProgress where T : IComparable, IFormattable, IConvertible + public class TangoProgress where T : IComparable, IFormattable { /// /// Gets or sets the progress message. @@ -39,14 +39,21 @@ namespace Tango.Core { get { - double max = Convert.ToDouble(Maximum); - double value = Convert.ToDouble(Value); - - if (max > 0) + try { - return Math.Round(value / max * 100d, 0); + double max = Convert.ToDouble(Maximum); + double value = Convert.ToDouble(Value); + + if (max > 0) + { + return Math.Round(value / max * 100d, 0); + } + else + { + return 0; + } } - else + catch { return 0; } @@ -87,7 +94,7 @@ namespace Tango.Core /// /// /// - public class TangoProgressChangedEventArgs : EventArgs where T : IComparable, IFormattable, IConvertible + public class TangoProgressChangedEventArgs : EventArgs where T : IComparable, IFormattable { /// /// Gets or sets the progress. diff --git a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs index 96c2ea4c4..f0ed109cc 100644 --- a/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs +++ b/Software/Visual_Studio/Tango.Integration/Operation/JobHandler.cs @@ -88,6 +88,17 @@ namespace Tango.Integration.Operation #region Properties + private JobStatus _jobStatus; + /// + /// Gets or sets the current job status that was used to invalidate this handler. + /// + public JobStatus JobStatus + { + get { return _jobStatus; } + set { _jobStatus = value; RaisePropertyChangedAuto(); } + } + + /// /// Gets a value indicating whether this handler job has been canceled. /// @@ -144,7 +155,7 @@ namespace Tango.Integration.Operation /// Initializes a new instance of the class. /// /// The cancel action. - internal JobHandler(Action cancelAction, Job job, JobTicket jobTicket, ProcessParametersTable processParameters, JobHandlerModes mode) : this() + public JobHandler(Action cancelAction, Job job, JobTicket jobTicket, ProcessParametersTable processParameters, JobHandlerModes mode) : this() { _mode = mode; @@ -195,7 +206,7 @@ namespace Tango.Integration.Operation //Create all segments int segment_index = 1; - for (int j = 0; j < Job.NumberOfUnits; j++) + for (int j = 0; j < Math.Max(Job.NumberOfUnits, 1); j++) { for (int i = 0; i < _effectiveSegments.Count; i++) { @@ -231,7 +242,7 @@ namespace Tango.Integration.Operation /// Raises the status received event. /// /// The status. - internal void RaiseStatusReceived(JobStatus status) + public void RaiseStatusReceived(JobStatus status) { InvalidateJobProgress(status); } @@ -240,7 +251,7 @@ namespace Tango.Integration.Operation /// Raises the failed event. /// /// The ex. - internal void RaiseFailed(Exception ex) + public void RaiseFailed(Exception ex) { LogManager.Log($"Job failed at position {Status.Progress}/{Status.TotalProgress}..."); Status.IsFailed = true; @@ -253,7 +264,7 @@ namespace Tango.Integration.Operation /// /// Raises the completed event. /// - internal void RaiseCompleted() + public 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)... @@ -285,7 +296,7 @@ namespace Tango.Integration.Operation /// /// Raises the canceled event. /// - internal void RaiseCanceled() + public void RaiseCanceled() { LogManager.Log($"Job canceled at position {Status.Progress}/{Status.TotalProgress}..."); Status.IsCanceled = true; @@ -313,6 +324,7 @@ namespace Tango.Integration.Operation private void InvalidateJobProgress(JobStatus s) { + JobStatus = s; bool invalidProgress = false; if (_last_progress != s.Progress) -- cgit v1.3.1