diff options
Diffstat (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs')
| -rw-r--r-- | Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs | 292 |
1 files changed, 246 insertions, 46 deletions
diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs index 1b0ee0a56..6ccc1caa0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Technician/ViewModels/MachineTechViewVM.cs @@ -16,6 +16,7 @@ using System.Windows.Media; using Tango.Core.Helpers; using Tango.Editors; using Tango.Integration.Observables; +using Tango.Integration.Observables.Enumerations; using Tango.Integration.Operators; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Common.StudioApplication; @@ -28,6 +29,11 @@ using Tango.SharedUI; namespace Tango.MachineStudio.Technician.ViewModels { + /// <summary> + /// Represents the MachineTechView View Model. + /// </summary> + /// <seealso cref="Tango.SharedUI.ViewModel" /> + /// <seealso cref="Tango.MachineStudio.Common.StudioApplication.IShutdownListener" /> public class MachineTechViewVM : ViewModel, IShutdownListener { private List<PropertyInfo> _diagnoticsDataProperties; @@ -36,6 +42,8 @@ namespace Tango.MachineStudio.Technician.ViewModels private static object _elementsLock = new object(); private String _lastTechProjectFile; private INotificationProvider _notification; + private DateTime _lastDiagnosticsResponseUpdate; + private const int MIN_DIAGNOSTICS_UPDATE_MILI = 500; #region Properties @@ -109,26 +117,69 @@ namespace Tango.MachineStudio.Technician.ViewModels set { _hideMenu = value; RaisePropertyChangedAuto(); } } + private PushDiagnosticsResponse _currentDiagnosticsResponse; + /// <summary> + /// Gets or sets the current diagnostics response. + /// </summary> + public PushDiagnosticsResponse CurrentDiagnosticsResponse + { + get { return _currentDiagnosticsResponse; } + set { _currentDiagnosticsResponse = value; RaisePropertyChanged(nameof(CurrentDiagnosticsResponse)); } + } + + private int _currentDiagnosticsResponseSize; + /// <summary> + /// Gets or sets the size of the current diagnostics response. + /// </summary> + /// <value> + /// The size of the current diagnostics response. + /// </value> + public int CurrentDiagnosticsResponseSize + { + get { return _currentDiagnosticsResponseSize; } + set { _currentDiagnosticsResponseSize = value; RaisePropertyChanged(nameof(CurrentDiagnosticsResponseSize)); } + } + #endregion #region Commands + /// <summary> + /// Gets or sets the save as project command. + /// </summary> public RelayCommand SaveAsProjectCommand { get; set; } + /// <summary> + /// Gets or sets the save project command. + /// </summary> public RelayCommand SaveProjectCommand { get; set; } + /// <summary> + /// Gets or sets the open project command. + /// </summary> public RelayCommand OpenProjectCommand { get; set; } #endregion #region Constructors + /// <summary> + /// Initializes a new instance of the <see cref="MachineTechViewVM"/> class. + /// </summary> + /// <param name="applicationManager">The application manager.</param> + /// <param name="notificationProvider">The notification provider.</param> [PreferredConstructor] public MachineTechViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider) : this(applicationManager, notificationProvider, true) { } + /// <summary> + /// Initializes a new instance of the <see cref="MachineTechViewVM"/> class. + /// </summary> + /// <param name="applicationManager">The application manager.</param> + /// <param name="notificationProvider">The notification provider.</param> + /// <param name="loadLastProject">if set to <c>true</c> [load last project].</param> public MachineTechViewVM(IStudioApplicationManager applicationManager, INotificationProvider notificationProvider, bool loadLastProject) { _notification = notificationProvider; @@ -189,8 +240,19 @@ namespace Tango.MachineStudio.Technician.ViewModels #region Populate Diagnostics Data + /// <summary> + /// Populates the diagnostics data to the proper elements. + /// </summary> + /// <param name="data">The data.</param> private void PopulateDiagnosticsData(PushDiagnosticsResponse data) { + if (DateTime.Now > _lastDiagnosticsResponseUpdate.AddMilliseconds(MIN_DIAGNOSTICS_UPDATE_MILI)) + { + CurrentDiagnosticsResponse = data; + _lastDiagnosticsResponseUpdate = DateTime.Now; + CurrentDiagnosticsResponseSize = data.CalculateSize(); + } + lock (_elementsLock) { var elements = Elements.ToList(); @@ -207,19 +269,10 @@ namespace Tango.MachineStudio.Technician.ViewModels if (prop != null) { - monitorItem.Value = GetLastMonitorValue(monitorItem.TechMonitor, prop.GetValue(data)); + monitorItem.Value = GetDataLastValue(monitorItem.TechMonitor, prop.GetValue(data)); } } } - else if (item.GetType() == typeof(IOItem)) - { - IOItem ioItem = item as IOItem; - - if (ioItem.Port < data.GPIO.Count) - { - ioItem.EffectiveValue = data.GPIO[ioItem.Port]; - } - } else if (item.GetType() == typeof(MeterItem)) { MeterItem meterItem = item as MeterItem; @@ -230,7 +283,7 @@ namespace Tango.MachineStudio.Technician.ViewModels if (prop != null) { - meterItem.Value = GetLastMonitorValue(meterItem.TechMonitor, prop.GetValue(data)); + meterItem.Value = GetDataLastValue(meterItem.TechMonitor, prop.GetValue(data)); } } } @@ -246,7 +299,7 @@ namespace Tango.MachineStudio.Technician.ViewModels if (_singleControllers.TryGetValue(graphItem, out controller)) { - controller.PushData(GetSingleGraphValues(graphItem.TechMonitor, prop.GetValue(data))); + controller.PushData(GetDataArray(graphItem.TechMonitor, prop.GetValue(data))); } } } @@ -262,10 +315,32 @@ namespace Tango.MachineStudio.Technician.ViewModels if (_multiControllers.TryGetValue(graphItem, out controller)) { - controller.PushData(GetMultiGraphValues(graphItem.TechMonitor, prop.GetValue(data))); + controller.PushData(GetDataMatrix(graphItem.TechMonitor, prop.GetValue(data))); } } } + else if (item.GetType() == typeof(DigitalOutItem)) + { + DigitalOutItem digitalOutItem = item as DigitalOutItem; + + var digitalPin = data.DigitalPins.SingleOrDefault(x => x.Port == digitalOutItem.TechIo.Port); + + if (digitalPin != null) + { + digitalOutItem.EffectiveValue = digitalPin.Value; + } + } + else if (item.GetType() == typeof(DigitalInItem)) + { + DigitalInItem digitalInItem = item as DigitalInItem; + + var digitalPin = data.DigitalPins.SingleOrDefault(x => x.Port == digitalInItem.TechIo.Port); + + if (digitalPin != null) + { + digitalInItem.Value = digitalPin.Value; + } + } } } } @@ -274,7 +349,13 @@ namespace Tango.MachineStudio.Technician.ViewModels #region Private Methods - private double GetLastMonitorValue(TechMonitor monitor, object value) + /// <summary> + /// Gets the last data point from a protobuf repeated field. + /// </summary> + /// <param name="monitor">The monitor.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + private double GetDataLastValue(TechMonitor monitor, object value) { if (!monitor.MultiChannel) { @@ -288,12 +369,24 @@ namespace Tango.MachineStudio.Technician.ViewModels } } - private List<double> GetSingleGraphValues(TechMonitor monitor, object value) + /// <summary> + /// Gets the data array from a protobuf repeated field. + /// </summary> + /// <param name="monitor">The monitor.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + private List<double> GetDataArray(TechMonitor monitor, object value) { return (value as RepeatedField<double>).ToList(); } - private List<List<double>> GetMultiGraphValues(TechMonitor monitor, object value) + /// <summary> + /// Gets the data matrix from a protobuf repeated field of <see cref="DoubleArray"/>. + /// </summary> + /// <param name="monitor">The monitor.</param> + /// <param name="value">The value.</param> + /// <returns></returns> + private List<List<double>> GetDataMatrix(TechMonitor monitor, object value) { DoubleArray[] arrayOfDoubles = Enumerable.ToArray(value as IEnumerable<DoubleArray>); return arrayOfDoubles.Select(x => x.Data.ToList()).ToList(); @@ -303,6 +396,9 @@ namespace Tango.MachineStudio.Technician.ViewModels #region Virtual Methods + /// <summary> + /// Called when the disable rendering has been changed + /// </summary> protected virtual void OnDisableRenderingChanged() { foreach (var controller in _singleControllers) @@ -320,11 +416,20 @@ namespace Tango.MachineStudio.Technician.ViewModels #region Add/Remove Element + /// <summary> + /// Creates a new tech element by the specified bounds and the current selected element. + /// </summary> + /// <param name="bounds">The bounds.</param> public void CreateElement(Rect bounds) { CreateElement(SelectedTechItem, bounds); } + /// <summary> + /// Creates a new tech element by the specified tech item instance and bounds. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="bounds">The bounds.</param> private void CreateElement(TechItem item, Rect bounds) { if (item is MonitorItem) @@ -355,11 +460,6 @@ namespace Tango.MachineStudio.Technician.ViewModels var editor = CreateElement<DispenserElementEditor, DispenserItem, TechDispenser>(bounds, Adapter.TechDispensers.FirstOrDefault()); InitDispenserItem(editor.DispenserItem); } - else if (item is IOItem) - { - var editor = CreateElement<IOElementEditor, IOItem, int>(bounds, 0); - InitIOItem(editor.IOItem); - } else if (item is ThreadMotionItem) { var editor = CreateElement<ThreadMotionElementEditor, ThreadMotionItem, object>(bounds, null); @@ -370,8 +470,26 @@ namespace Tango.MachineStudio.Technician.ViewModels var editor = CreateElement<MotorGroupElementEditor, MotorGroupItem, object>(bounds, null); InitMotorGroupItem(editor.MotorGroupItem); } + else if (item is DigitalOutItem) + { + var editor = CreateElement<DigitalOutElementEditor, DigitalOutItem, TechIo>(bounds, Adapter.TechIos.Where(x => x.Type == IOType.DigitalOutput.ToInt32()).FirstOrDefault()); + InitDigitalOutItem(editor.DigitalOutItem); + } + else if (item is DigitalInItem) + { + CreateElement<DigitalInElementEditor, DigitalInItem, TechIo>(bounds, Adapter.TechIos.Where(x => x.Type == IOType.DigitalInput.ToInt32()).FirstOrDefault()); + } } + /// <summary> + /// Creates a new element by the specified editor type, tech item type, bounds and tech item constructor value. + /// </summary> + /// <typeparam name="Editor">The type of the editor.</typeparam> + /// <typeparam name="Tech">The type of the tech.</typeparam> + /// <typeparam name="Value">The type of the value.</typeparam> + /// <param name="bounds">The bounds.</param> + /// <param name="value">The value.</param> + /// <returns></returns> private Editor CreateElement<Editor, Tech, Value>(Rect bounds, Value value) where Editor : IElementEditor where Tech : TechItem { TechItem item = Activator.CreateInstance(typeof(Tech), new object[] { value }) as TechItem; @@ -380,6 +498,12 @@ namespace Tango.MachineStudio.Technician.ViewModels return (Editor)editor; } + /// <summary> + /// Creates a new element by the specified editor type and tech item instance. + /// </summary> + /// <typeparam name="Editor">The type of the editor.</typeparam> + /// <param name="item">The item.</param> + /// <returns></returns> private Editor CreateElement<Editor>(TechItem item) where Editor : IElementEditor { IElementEditor editor = Activator.CreateInstance(typeof(Editor), new object[] { item, item.GetBounds() }) as IElementEditor; @@ -387,6 +511,10 @@ namespace Tango.MachineStudio.Technician.ViewModels return (Editor)editor; } + /// <summary> + /// Adds a new tech item. + /// </summary> + /// <param name="item">The item.</param> private void AddTechItem(TechItem item) { if (item is MonitorItem) @@ -423,11 +551,6 @@ namespace Tango.MachineStudio.Technician.ViewModels var editor = CreateElement<DispenserElementEditor>(item); InitDispenserItem(editor.DispenserItem); } - else if (item is IOItem) - { - var editor = CreateElement<IOElementEditor>(item); - InitIOItem(editor.IOItem); - } else if (item is ThreadMotionItem) { var editor = CreateElement<ThreadMotionElementEditor>(item); @@ -438,8 +561,23 @@ namespace Tango.MachineStudio.Technician.ViewModels var editor = CreateElement<MotorGroupElementEditor>(item); InitMotorGroupItem(editor.MotorGroupItem); } + else if (item is DigitalOutItem) + { + (item as DigitalOutItem).TechIo = Adapter.TechIos.FirstOrDefault(x => x.Guid == item.ItemGuid); + var editor = CreateElement<DigitalOutElementEditor>(item); + InitDigitalOutItem(editor.DigitalOutItem); + } + else if (item is DigitalInItem) + { + (item as DigitalInItem).TechIo = Adapter.TechIos.FirstOrDefault(x => x.Guid == item.ItemGuid); + CreateElement<DigitalInElementEditor>(item); + } } + /// <summary> + /// Called when elements have been removed + /// </summary> + /// <param name="elements">The elements.</param> public void OnElementsRemoved(List<IElementEditor> elements) { //foreach (var element in elements) @@ -457,6 +595,10 @@ namespace Tango.MachineStudio.Technician.ViewModels //} } + /// <summary> + /// Called when elements have been pasted + /// </summary> + /// <param name="elements">The elements.</param> public void OnElementsPasted(List<IElementEditor> elements) { foreach (var element in elements) @@ -507,10 +649,10 @@ namespace Tango.MachineStudio.Technician.ViewModels var dispenser = element.HostedElement as DispenserItem; InitDispenserItem(dispenser); } - else if (element is IOElementEditor) + else if (element is DigitalOutItem) { - var ioItem = element.HostedElement as IOItem; - InitIOItem(ioItem); + var ioItem = element.HostedElement as DigitalOutItem; + InitDigitalOutItem(ioItem); } else if (element is ThreadMotionItem) { @@ -529,6 +671,10 @@ namespace Tango.MachineStudio.Technician.ViewModels #region Init Tech Items + /// <summary> + /// Initializes the motor item. + /// </summary> + /// <param name="item">The item.</param> private void InitMotorItem(MotorItem item) { item.ActionExecuted += async (x, action) => @@ -599,6 +745,10 @@ namespace Tango.MachineStudio.Technician.ViewModels }; } + /// <summary> + /// Initializes the dispenser item. + /// </summary> + /// <param name="item">The item.</param> private void InitDispenserItem(DispenserItem item) { item.ActionExecuted += async (x, action) => @@ -669,21 +819,11 @@ namespace Tango.MachineStudio.Technician.ViewModels }; } - private void InitIOItem(IOItem item) - { - item.ValueChanged += async (x, value) => - { - try - { - await MachineOperator.SetGPIOState(new SetGPIOStateRequest() { Port = item.Port, Value = value }); - } - catch (Exception ex) - { - //TODO: Show Exception. - } - }; - } - + /// <summary> + /// Initializes the single graph item. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="editor">The editor.</param> private void InitSingleGraphitem(SingleGraphItem item, SingleGraphElementEditor editor) { editor.InnerGraph.InnerGraph.MaxPoints = Common.Helpers.GraphsHelper.GetMaxPoints(item.TechMonitor.PointsPerFrame); @@ -695,6 +835,11 @@ namespace Tango.MachineStudio.Technician.ViewModels _singleControllers.Add(item, controller); } + /// <summary> + /// Initializes the multi graph item. + /// </summary> + /// <param name="item">The item.</param> + /// <param name="editor">The editor.</param> private void InitMultiGraphItem(MultiGraphItem item, MultiGraphElementEditor editor) { editor.InnerGraph.InnerGraph.MaxPoints = Common.Helpers.GraphsHelper.GetMaxPoints(item.TechMonitor.PointsPerFrame); @@ -717,6 +862,10 @@ namespace Tango.MachineStudio.Technician.ViewModels _multiControllers.Add(item, controller); } + /// <summary> + /// Initializes the thread motion item. + /// </summary> + /// <param name="item">The item.</param> private void InitThreadMotionItem(ThreadMotionItem item) { item.ActionExecuted += async (x, action) => @@ -742,6 +891,10 @@ namespace Tango.MachineStudio.Technician.ViewModels }; } + /// <summary> + /// Initializes the motor group item. + /// </summary> + /// <param name="item">The item.</param> private void InitMotorGroupItem(MotorGroupItem item) { item.ActionExecuted += async (x, action) => @@ -812,10 +965,32 @@ namespace Tango.MachineStudio.Technician.ViewModels }; } + /// <summary> + /// Initializes the digital out item. + /// </summary> + /// <param name="item">The item.</param> + private void InitDigitalOutItem(DigitalOutItem item) + { + item.ValueChanged += async (x, value) => + { + try + { + await MachineOperator.SetDigitalOut(new SetDigitalOutRequest() { Port = item.TechIo.Port, Value = value }); + } + catch (Exception ex) + { + //TODO: Show Exception. + } + }; + } + #endregion #region Public Methods + /// <summary> + /// Opens a file open dialog to select a project file. + /// </summary> public void OpenProject() { OpenFileDialog dlg = new OpenFileDialog(); @@ -828,12 +1003,20 @@ namespace Tango.MachineStudio.Technician.ViewModels } } + /// <summary> + /// Opens the specified project file path. + /// </summary> + /// <param name="fileName">File path.</param> public void OpenProjectFile(String fileName) { LoadProject(MachineTechViewProject.Load(fileName)); _lastTechProjectFile = fileName; } + /// <summary> + /// Loads the specified project. + /// </summary> + /// <param name="project">The project.</param> public void LoadProject(MachineTechViewProject project) { using (_notification.PushTaskItem("Loading technician project file...")) @@ -854,6 +1037,9 @@ namespace Tango.MachineStudio.Technician.ViewModels } } + /// <summary> + /// Opens the file save dialog for selecting a project file target. + /// </summary> private void SaveAsProject() { SaveFileDialog dlg = new SaveFileDialog(); @@ -866,16 +1052,23 @@ namespace Tango.MachineStudio.Technician.ViewModels } } + /// <summary> + /// Saves the current project to the specified file path. + /// </summary> + /// <param name="fileName">Name of the file.</param> private void SaveProjectFile(String fileName) { using (_notification.PushTaskItem("Saving technician project file...")) { - MachineTechViewProject project = CreateProjectFile(); + MachineTechViewProject project = GenerateProjectFile(); project.Save(fileName); _lastTechProjectFile = fileName; } } + /// <summary> + /// Saves the current opened project file. If not project file is opened will call <see cref="SaveAsProject"/>. + /// </summary> private void SaveProject() { if (File.Exists(_lastTechProjectFile)) @@ -888,7 +1081,11 @@ namespace Tango.MachineStudio.Technician.ViewModels } } - private MachineTechViewProject CreateProjectFile() + /// <summary> + /// Generates a project file from the current element setup. + /// </summary> + /// <returns></returns> + private MachineTechViewProject GenerateProjectFile() { MachineTechViewProject project = new MachineTechViewProject(); @@ -911,6 +1108,9 @@ namespace Tango.MachineStudio.Technician.ViewModels #region IShutdownListener + /// <summary> + /// Called when the application is about to terminate. + /// </summary> public void OnShuttingDown() { InvokeUINow(() => |
