From 09c1e15643f82b2187019025682b5da0bfbe1c1d Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Thu, 21 Nov 2019 09:20:44 +0200 Subject: Fixed issue with machine clone and device registration. Implemented device registration details and reset in Machine Designer. --- .../ViewModels/MainViewVM.cs | 21 +++++++++++++++++++++ 1 file changed, 21 insertions(+) (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index 5f2dcd00d..5fd086198 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -188,6 +188,12 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels /// Gets or sets the clone machine command. /// public RelayCommand CloneMachineCommand { get; set; } + + /// + /// Gets or sets the reset device registration command. + /// + public RelayCommand ResetDeviceRegistrationCommand { get; set; } + #endregion #region Constructors @@ -218,7 +224,9 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels AddSpoolCommand = new RelayCommand(AddNewSpool); RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null); CloneMachineCommand = new RelayCommand(CloneMachine, () => SelectedMachine != null); + ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration); } + #endregion #region Application Ready @@ -430,6 +438,9 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels ActiveMachine = ActiveMachine.Clone(); ActiveMachine.Name = ""; ActiveMachine.SerialNumber = ""; + ActiveMachine.IsDeviceRegistered = false; + ActiveMachine.DeviceId = null; + ActiveMachine.DeviceName = null; ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); } } @@ -690,6 +701,16 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } + private void ResetDeviceRegistration() + { + if (_notification.ShowQuestion("Are you sure you wish to reset this machine device registration?")) + { + ActiveMachine.IsDeviceRegistered = false; + ActiveMachine.DeviceId = null; + ActiveMachine.DeviceName = null; + } + } + #endregion private void CloneMachine() -- cgit v1.3.1 From a6e6af346bf160b4a83163a6f1b268920cf2005c Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 7 Dec 2019 20:10:55 +0200 Subject: Implemented machine updates history on machine designer. Related Work Items: #1618 --- Software/DB/PPC/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/PPC/Tango_log.ldf | Bin 53673984 -> 53673984 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../Tango.MachineStudio.MachineDesigner.csproj | 18 ++- .../ViewModels/MachineUpdateDetailsDialogVM.cs | 20 +++ .../ViewModels/MachineUpdatesViewVM.cs | 142 +++++++++++++++++++++ .../ViewModels/MainViewVM.cs | 13 +- .../Views/MachineDetailsView.xaml | 3 + .../Views/MachineUpdateDetailsDialog.xaml | 85 ++++++++++++ .../Views/MachineUpdateDetailsDialog.xaml.cs | 28 ++++ .../Views/MachineUpdatesView.xaml | 98 ++++++++++++++ .../Views/MachineUpdatesView.xaml.cs | 28 ++++ .../MachineSetup/MachineSetupManager.cs | 24 ++++ .../MachineUpdate/MachineUpdateManager.cs | 29 ++++- .../Web/MachineUpdateCompletedResponse.cs | 2 +- .../Builders/TangoUpdatesCollectionBuilder.cs | 26 ++++ .../Visual_Studio/Tango.BL/Entities/TangoUpdate.cs | 79 +++++++++++- .../Tango.BL/Enumerations/TangoUpdateStatuses.cs | 10 ++ Software/Visual_Studio/Tango.BL/Tango.BL.csproj | 3 +- .../Converters/StringEllipsisConverter.cs | 9 +- .../Converters/StringToOneLineConverter.cs | 50 ++++++++ .../Tango.SharedUI/Tango.SharedUI.csproj | 1 + 23 files changed, 658 insertions(+), 10 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs create mode 100644 Software/Visual_Studio/Tango.BL/Builders/TangoUpdatesCollectionBuilder.cs create mode 100644 Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/DB/PPC/Tango.mdf b/Software/DB/PPC/Tango.mdf index 5fc6097f0..de2de9f2b 100644 Binary files a/Software/DB/PPC/Tango.mdf and b/Software/DB/PPC/Tango.mdf differ diff --git a/Software/DB/PPC/Tango_log.ldf b/Software/DB/PPC/Tango_log.ldf index d987dddda..d7d04ca21 100644 Binary files a/Software/DB/PPC/Tango_log.ldf and b/Software/DB/PPC/Tango_log.ldf differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 8ea68035a..f50c8b7fb 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index d0c2d75ef..5b78ee141 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj index d80060831..6225bd7ad 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj @@ -89,6 +89,8 @@ + + @@ -97,6 +99,9 @@ HardwareConfigurationView.xaml + + MachineUpdateDetailsDialog.xaml + MachineCreationDialog.xaml @@ -122,6 +127,9 @@ MainView.xaml + + MachineUpdatesView.xaml + SpoolsView.xaml @@ -137,6 +145,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -169,6 +181,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -308,7 +324,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs new file mode 100644 index 000000000..49d410cdf --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdateDetailsDialogVM.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.SharedUI; + +namespace Tango.MachineStudio.MachineDesigner.ViewModels +{ + public class MachineUpdateDetailsDialogVM : DialogViewVM + { + private TangoUpdate _update; + public TangoUpdate Update + { + get { return _update; } + set { _update = value; RaisePropertyChangedAuto(); } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs new file mode 100644 index 000000000..7ff64c505 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs @@ -0,0 +1,142 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; +using Tango.BL; +using Tango.BL.Builders; +using Tango.BL.Entities; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.MachineDesigner.Views; +using Tango.SharedUI; + +namespace Tango.MachineStudio.MachineDesigner.ViewModels +{ + public class MachineUpdatesViewVM : ViewModel + { + private INotificationProvider _notification; + + #region Properties + + private Machine _machine; + public Machine Machine + { + get { return _machine; } + set { _machine = value; RaisePropertyChangedAuto(); } + } + + private List _updates; + public List Updates + { + get { return _updates; } + set { _updates = value; RaisePropertyChangedAuto(); } + } + + private ICollectionView _updatesView; + public ICollectionView UpdatesView + { + get { return _updatesView; } + set { _updatesView = value; RaisePropertyChangedAuto(); } + } + + + private TangoUpdate _selectedUpdate; + public TangoUpdate SelectedUpdate + { + get { return _selectedUpdate; } + set { _selectedUpdate = value; RaisePropertyChangedAuto(); OnSelectedUpdateChanged(); } + } + + private bool _displayMachineSetups; + public bool DisplayMachineSetups + { + get { return _displayMachineSetups; } + set { _displayMachineSetups = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool _displayApplicationUpdates; + public bool DisplayApplicationUpdates + { + get { return _displayApplicationUpdates; } + set { _displayApplicationUpdates = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private bool _displayDatabaseUpdates; + public bool DisplayDatabaseUpdates + { + get { return _displayDatabaseUpdates; } + set { _displayDatabaseUpdates = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + #endregion + + #region Constructors + + public MachineUpdatesViewVM() + { + DisplayApplicationUpdates = true; + DisplayMachineSetups = true; + DisplayDatabaseUpdates = true; + } + + public MachineUpdatesViewVM(INotificationProvider notificationProvider) : this() + { + _notification = notificationProvider; + } + + #endregion + + #region Public Methods + + public async Task Init(Machine machine, ObservablesContext context) + { + Machine = machine; + Updates = (await new TangoUpdatesCollectionBuilder(context).Set(x => x.MachineGuid == machine.Guid).BuildAsync()).OrderByDescending(x => x.StartDate).ToList(); + UpdatesView = CollectionViewSource.GetDefaultView(Updates); + UpdatesView.Filter = UpdatesFilter; + OnFilterChanged(); + } + + #endregion + + #region Private Methods + + private void OnFilterChanged() + { + if (UpdatesView != null) + { + UpdatesView.Refresh(); + } + } + + private bool UpdatesFilter(object obj) + { + TangoUpdate update = obj as TangoUpdate; + if (update != null) + { + if (!DisplayMachineSetups && update.IsSetup) return false; + if (!DisplayApplicationUpdates && update.IsUpdate) return false; + if (!DisplayDatabaseUpdates && update.IsDataBase) return false; + return true; + } + else + { + return false; + } + } + + private void OnSelectedUpdateChanged() + { + if (SelectedUpdate == null) return; + + var selectedUpdate = SelectedUpdate; + SelectedUpdate = null; + + _notification.ShowModalDialog(new MachineUpdateDetailsDialogVM() { Update = selectedUpdate }, (vm) => { }, () => { }); + } + + #endregion + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index 5fd086198..820950290 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -123,7 +123,6 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } private HardwareConfigurationViewVM _hardwareConfigurationViewVM; - public HardwareConfigurationViewVM HardwareConfigurationViewVM { get { return _hardwareConfigurationViewVM; } @@ -134,6 +133,13 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } + private MachineUpdatesViewVM _machineUpdatesViewVM; + public MachineUpdatesViewVM MachineUpdatesViewVM + { + get { return _machineUpdatesViewVM; } + set { _machineUpdatesViewVM = value; RaisePropertyChangedAuto(); } + } + #endregion @@ -225,6 +231,8 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null); CloneMachineCommand = new RelayCommand(CloneMachine, () => SelectedMachine != null); ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration); + + MachineUpdatesViewVM = new MachineUpdatesViewVM(_notification); } #endregion @@ -469,6 +477,9 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); + await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); + + ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged; View.NavigateTo(MachineDesignerNavigationView.MachineDetailsView); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml index 1f748fe9f..666a4ee4a 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml @@ -61,6 +61,9 @@ + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml new file mode 100644 index 000000000..9d60d36f8 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml @@ -0,0 +1,85 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.xaml.cs new file mode 100644 index 000000000..8bb051c51 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdateDetailsDialog.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.MachineStudio.MachineDesigner.Views +{ + /// + /// Interaction logic for MachineCreationDialog.xaml + /// + public partial class MachineUpdateDetailsDialog : UserControl + { + public MachineUpdateDetailsDialog() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml new file mode 100644 index 000000000..d9ea2cb44 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml @@ -0,0 +1,98 @@ + + + + + + + + + + + + + + + + + + + + + + + + + Machine Setups + Software Updates + Database Updates + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.xaml.cs new file mode 100644 index 000000000..d13ef2d0e --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineUpdatesView.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.MachineStudio.MachineDesigner.Views +{ + /// + /// Interaction logic for SpoolsView.xaml + /// + public partial class MachineUpdatesView : UserControl + { + public MachineUpdatesView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs index 10418fdcb..f1c722d96 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs @@ -17,6 +17,7 @@ using Tango.Core.ExtensionMethods; using Tango.Core.Helpers; using Tango.Core.IO; using Tango.Integration.Operation; +using Tango.Logging; using Tango.PMR.Synchronization; using Tango.PPC.Common.Application; using Tango.PPC.Common.Connection; @@ -42,6 +43,7 @@ namespace Tango.PPC.Common.MachineSetup private IUnifiedWriteFilterManager _uwf; private IOperationSystemManager _windows_manager; private PPCWebClient _client; + private List _logs; #region Events @@ -80,6 +82,18 @@ namespace Tango.PPC.Common.MachineSetup _remoteAssistance = remoteAssistance; _uwf = unifiedWriterFilterManager; _windows_manager = operationSystemManager; + + _logs = new List(); + LogManager.NewLog += LogManager_NewLog; + } + + #endregion + + #region Event Handlers + + private void LogManager_NewLog(object sender, LogItemBase e) + { + _logs.Add(e); } #endregion @@ -114,6 +128,7 @@ namespace Tango.PPC.Common.MachineSetup Token = response.NotifyCompletedToken, Status = BL.Enumerations.TangoUpdateStatuses.SetupFailed, FailedReason = ex.FlattenMessage(), + FailedLog = GetLogsStringAndClear(), }); } catch (Exception xx) @@ -144,6 +159,13 @@ namespace Tango.PPC.Common.MachineSetup } } + private String GetLogsStringAndClear() + { + String logsString = String.Join(Environment.NewLine, _logs.ToList().Select(x => x.ToString())); + _logs.Clear(); + return logsString; + } + #endregion #region Public Methods @@ -156,6 +178,8 @@ namespace Tango.PPC.Common.MachineSetup /// public async Task Setup(string serialNumber) { + _logs.Clear(); + TaskCompletionSource result = new TaskCompletionSource(); MachineSetupResponse setup_response = null; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs index f00efb22c..658c323de 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -16,6 +16,7 @@ using Tango.Core.Helpers; using Tango.Core.IO; using Tango.Integration.Operation; using Tango.Integration.Upgrade; +using Tango.Logging; using Tango.PMR.Synchronization; using Tango.PPC.Common.Application; using Tango.PPC.Common.Connection; @@ -34,8 +35,8 @@ namespace Tango.PPC.Common.MachineUpdate private IPPCApplicationManager _app_manager; private IMachineProvider _machineProvider; private IPackageRunner _packageRunner; - private INavigationManager _navigationManager; private PPCWebClient _client; + private List _logs; #region Events @@ -68,13 +69,16 @@ namespace Tango.PPC.Common.MachineUpdate /// Initializes a new instance of the class. /// /// The application manager. - public MachineUpdateManager(PPCWebClient ppcWebClient, IPPCApplicationManager applicationManager, IMachineProvider machineProvider, IPackageRunner packageRunner, INavigationManager navigationManager) + public MachineUpdateManager(PPCWebClient ppcWebClient, IPPCApplicationManager applicationManager, IMachineProvider machineProvider, IPackageRunner packageRunner) { _client = ppcWebClient; _machineProvider = machineProvider; _app_manager = applicationManager; _packageRunner = packageRunner; _packageRunner.PackageStateChanged += _packageRunner_PackageStateChanged; + + _logs = new List(); + LogManager.NewLog += LogManager_NewLog; } #endregion @@ -86,6 +90,11 @@ namespace Tango.PPC.Common.MachineUpdate UpdateProgress(e.PackageType == PackageType.Pre ? "Preparing" : "Finalizing", e.PackageName); } + private void LogManager_NewLog(object sender, LogItemBase e) + { + _logs.Add(e); + } + #endregion #region Private Methods @@ -142,6 +151,7 @@ namespace Tango.PPC.Common.MachineUpdate Token = response.NotifyCompletedToken, Status = BL.Enumerations.TangoUpdateStatuses.UpdateFailed, FailedReason = ex.FlattenMessage(), + FailedLog = GetLogsStringAndClear(), }); } catch (Exception xx) @@ -238,6 +248,7 @@ namespace Tango.PPC.Common.MachineUpdate Token = response.NotifyCompletedToken, Status = BL.Enumerations.TangoUpdateStatuses.DatabaseFailed, FailedReason = ex.FlattenMessage(), + FailedLog = GetLogsStringAndClear(), }).Result; } catch (Exception xx) @@ -247,6 +258,13 @@ namespace Tango.PPC.Common.MachineUpdate } } + private String GetLogsStringAndClear() + { + String logsString = String.Join(Environment.NewLine, _logs.ToList().Select(x => x.ToString())); + _logs.Clear(); + return logsString; + } + #endregion #region Public Methods @@ -266,6 +284,8 @@ namespace Tango.PPC.Common.MachineUpdate /// Database tango does not exists. public async Task Update(String serialNumber, bool setupFirmware, bool setupFPGA) { + _logs.Clear(); + TaskCompletionSource result = new TaskCompletionSource(); var localDataSource = SettingsManager.Default.GetOrCreate().DataSource; @@ -331,7 +351,7 @@ namespace Tango.PPC.Common.MachineUpdate UpdateProgress("Downloading software package", "Downloading...", false); - using (AutoFileDownloader downloader = new AutoFileDownloader(update_response.BlobAddress, update_response.CdnAddress + "123", tempFile)) + using (AutoFileDownloader downloader = new AutoFileDownloader(update_response.BlobAddress, update_response.CdnAddress, tempFile)) { await downloader.ResolveMode(); @@ -361,7 +381,6 @@ namespace Tango.PPC.Common.MachineUpdate //Extract software package. ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder); - LogManager.Log("Copying latest updater utility to application path..."); //Copy new updater utility to app path. File.Copy(Path.Combine(_newPackageTempFolder, "Tango.PPC.Updater.exe"), Path.Combine(PathHelper.GetStartupPath(), "Tango.PPC.Updater.exe"), true); @@ -571,6 +590,8 @@ namespace Tango.PPC.Common.MachineUpdate /// public Task UpdateDB(DbCompareResult dbCompareResult, String serialNumber) { + _logs.Clear(); + return Task.Factory.StartNew(() => { UpdateDBResponse update_response = null; diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineUpdateCompletedResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineUpdateCompletedResponse.cs index 1017ffdb2..72517d108 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineUpdateCompletedResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineUpdateCompletedResponse.cs @@ -10,6 +10,6 @@ namespace Tango.PPC.Common.Web { public class MachineUpdateCompletedResponse : WebResponseMessage { - public String ReportBlobAddress { get; set; } + } } diff --git a/Software/Visual_Studio/Tango.BL/Builders/TangoUpdatesCollectionBuilder.cs b/Software/Visual_Studio/Tango.BL/Builders/TangoUpdatesCollectionBuilder.cs new file mode 100644 index 000000000..5bc510474 --- /dev/null +++ b/Software/Visual_Studio/Tango.BL/Builders/TangoUpdatesCollectionBuilder.cs @@ -0,0 +1,26 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using System.Data.Entity; + +namespace Tango.BL.Builders +{ + public class TangoUpdatesCollectionBuilder : EntityCollectionBuilderBase + { + public TangoUpdatesCollectionBuilder(ObservablesContext context) : base(context) + { + + } + + //public virtual TangoUpdatesCollectionBuilder ForMachine(String machineGuid) + //{ + // return AddQueryStep(1, (query) => + // { + // return query.Where(x => x.MachineGuid == machineGuid); + // }); + //} + } +} diff --git a/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs b/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs index 076ba268f..5c254a6a9 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/TangoUpdate.cs @@ -11,7 +11,6 @@ namespace Tango.BL.Entities { public class TangoUpdate : TangoUpdateBase { - [NotMapped] [JsonIgnore] public TangoUpdateStatuses UpdateStatus @@ -27,6 +26,84 @@ namespace Tango.BL.Entities } } + [NotMapped] + [JsonIgnore] + public bool IsSetup + { + get + { + return + UpdateStatus == TangoUpdateStatuses.SetupStarted || + UpdateStatus == TangoUpdateStatuses.SetupCompleted || + UpdateStatus == TangoUpdateStatuses.SetupFailed; + } + } + + [NotMapped] + [JsonIgnore] + public bool IsUpdate + { + get + { + return + UpdateStatus == TangoUpdateStatuses.UpdateStarted || + UpdateStatus == TangoUpdateStatuses.UpdateCompleted || + UpdateStatus == TangoUpdateStatuses.UpdateFailed; + } + } + + [NotMapped] + [JsonIgnore] + public bool IsDataBase + { + get + { + return + UpdateStatus == TangoUpdateStatuses.DatabaseStarted || + UpdateStatus == TangoUpdateStatuses.DatabaseCompleted || + UpdateStatus == TangoUpdateStatuses.DatabaseFailed; + } + } + + [NotMapped] + [JsonIgnore] + public bool IsStarted + { + get + { + return + UpdateStatus == TangoUpdateStatuses.SetupStarted || + UpdateStatus == TangoUpdateStatuses.UpdateStarted || + UpdateStatus == TangoUpdateStatuses.DatabaseStarted; + } + } + + [NotMapped] + [JsonIgnore] + public bool IsCompleted + { + get + { + return + UpdateStatus == TangoUpdateStatuses.SetupCompleted || + UpdateStatus == TangoUpdateStatuses.UpdateCompleted || + UpdateStatus == TangoUpdateStatuses.DatabaseCompleted; + } + } + + [NotMapped] + [JsonIgnore] + public bool IsFailed + { + get + { + return + UpdateStatus == TangoUpdateStatuses.SetupFailed || + UpdateStatus == TangoUpdateStatuses.UpdateFailed || + UpdateStatus == TangoUpdateStatuses.DatabaseFailed; + } + } + protected override void OnStatusChanged(int status) { base.OnStatusChanged(status); diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs b/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs index ee657e0a9..30d324317 100644 --- a/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs +++ b/Software/Visual_Studio/Tango.BL/Enumerations/TangoUpdateStatuses.cs @@ -1,5 +1,6 @@ using System; using System.Collections.Generic; +using System.ComponentModel; using System.Linq; using System.Text; using System.Threading.Tasks; @@ -8,16 +9,25 @@ namespace Tango.BL.Enumerations { public enum TangoUpdateStatuses { + [Description("Setup started but did not complete")] SetupStarted = 0, + [Description("Setup completed successfully")] SetupCompleted = 1, + [Description("Setup failed")] SetupFailed = 2, + [Description("Software updated started but did not complete")] UpdateStarted = 100, + [Description("Software update completed successfully")] UpdateCompleted = 101, + [Description("Software update failed")] UpdateFailed = 102, + [Description("Database update started but did not complete")] DatabaseStarted = 200, + [Description("Database update completed successfully")] DatabaseCompleted = 201, + [Description("Database update failed")] DatabaseFailed = 202, } } diff --git a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj index 2bca408a4..ed134d37d 100644 --- a/Software/Visual_Studio/Tango.BL/Tango.BL.csproj +++ b/Software/Visual_Studio/Tango.BL/Tango.BL.csproj @@ -93,6 +93,7 @@ + @@ -565,7 +566,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/StringEllipsisConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/StringEllipsisConverter.cs index f5b4dea87..7e534d7f0 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Converters/StringEllipsisConverter.cs +++ b/Software/Visual_Studio/Tango.SharedUI/Converters/StringEllipsisConverter.cs @@ -14,7 +14,14 @@ namespace Tango.SharedUI.Converters { try { - return value.ToString().Ellipsis(System.Convert.ToInt32(parameter)); + if (value != null) + { + return value.ToString().Ellipsis(System.Convert.ToInt32(parameter)); + } + else + { + return value; + } } catch { diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs new file mode 100644 index 000000000..d130ebaaf --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Converters/StringToOneLineConverter.cs @@ -0,0 +1,50 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.SharedUI.Converters +{ + public class StringToOneLineConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + if (value != null) + { + string str = value.ToString(); + int newLineIndex = str.IndexOf(Environment.NewLine); + + if (newLineIndex == -1) + { + newLineIndex = str.IndexOf("\n"); + } + + string firstline = str; + + if (newLineIndex > 0) + { + firstline = str.Substring(0, newLineIndex); + } + + if (parameter != null) + { + firstline = firstline.Ellipsis(System.Convert.ToInt32(parameter)); + } + + return firstline; + } + else + { + return value; + } + } + + public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) + { + throw new NotImplementedException(); + } + } +} diff --git a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj index a65ac7322..3429bcb59 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -130,6 +130,7 @@ + -- cgit v1.3.1 From c7fa53084c674586ceee773ccbdc6b4c0a2ec7d4 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 9 Dec 2019 16:19:41 +0200 Subject: Implemented full TUP package update !!! --- .../FirmwareUpgrade/VersionFileDescriptor.proto | 1 - .../Tango.MachineStudio.MachineDesigner.csproj | 8 + .../ViewModels/MainViewVM.cs | 8 + .../ViewModels/TupViewVM.cs | 129 ++++++ .../Views/MachineDetailsView.xaml | 3 + .../Views/TupView.xaml | 60 +++ .../Views/TupView.xaml.cs | 28 ++ .../Tango.MachineStudio.Common.csproj | 17 +- .../Tup/TupFileBuilder.cs | 285 +++++++++++++ .../Tup/TupFileBuilderProgressEventArgs.cs | 16 + .../Web/DownloadLatestPPCVersionRequest.cs | 14 + .../Web/DownloadLatestPPCVersionResponse.cs | 21 + .../Web/MachineStudioWebClientBase.cs | 9 + .../Tango.MachineStudio.Common/packages.config | 1 + .../Tango.MachineStudio.UI.csproj | 6 +- .../MachineUpdate/IMachineUpdateManager.cs | 7 +- .../MachineUpdate/MachineUpdateManager.cs | 468 ++++++++++++++++++--- .../MachineUpdate/MachineUpdateResult.cs | 13 + .../MachineUpdate/UpdatePackageFile.cs | 13 - .../PPC/Tango.PPC.Common/Publish/PublishInfo.cs | 6 +- .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 1 - .../Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml | 12 +- .../Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs | 30 +- .../PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml | 5 +- Software/Visual_Studio/Tango.Core/DB/DbManager.cs | 33 +- .../FirmwareUpgrade/VersionFileDescriptor.cs | 37 +- .../ExaminerSequenceConfigurationRunner.cs | 9 + .../Tango.SQLExaminer/ExtensionMethods.cs | 21 + Software/Visual_Studio/Tango.SQLExaminer/Helper.cs | 2 +- .../Tango.SQLExaminer/Tango.SQLExaminer.csproj | 1 + .../SQLExaminer/SQLExaminer_TST.cs | 71 ++++ .../Controllers/MachineStudioController.cs | 65 +++ .../Controllers/PPCController.cs | 2 +- 33 files changed, 1257 insertions(+), 145 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs create mode 100644 Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs delete mode 100644 Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs create mode 100644 Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/PMR/Messages/FirmwareUpgrade/VersionFileDescriptor.proto b/Software/PMR/Messages/FirmwareUpgrade/VersionFileDescriptor.proto index ce44290a0..9e74cdee6 100644 --- a/Software/PMR/Messages/FirmwareUpgrade/VersionFileDescriptor.proto +++ b/Software/PMR/Messages/FirmwareUpgrade/VersionFileDescriptor.proto @@ -10,5 +10,4 @@ message VersionFileDescriptor string FileName = 1; string Version = 2; VersionFileDestination Destination = 3; - bytes CheckSum = 4; } \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj index 6225bd7ad..69cc75461 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Tango.MachineStudio.MachineDesigner.csproj @@ -93,6 +93,7 @@ + ColorCalibrationView.xaml @@ -130,6 +131,9 @@ MachineUpdatesView.xaml + + TupView.xaml + SpoolsView.xaml @@ -185,6 +189,10 @@ MSBuild:Compile Designer + + MSBuild:Compile + Designer + Designer MSBuild:Compile diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index 820950290..768f93de1 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -140,6 +140,12 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels set { _machineUpdatesViewVM = value; RaisePropertyChangedAuto(); } } + private TupViewVM _tupViewVM; + public TupViewVM TupViewVM + { + get { return _tupViewVM; } + set { _tupViewVM = value; RaisePropertyChangedAuto(); } + } #endregion @@ -233,6 +239,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration); MachineUpdatesViewVM = new MachineUpdatesViewVM(_notification); + TupViewVM = new TupViewVM(_notification); } #endregion @@ -478,6 +485,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); + TupViewVM.Init(ActiveMachine); ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs new file mode 100644 index 000000000..12ed09c75 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/TupViewVM.cs @@ -0,0 +1,129 @@ +using Microsoft.Win32; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.Tup; +using Tango.SharedUI; + +namespace Tango.MachineStudio.MachineDesigner.ViewModels +{ + public class TupViewVM : ViewModel + { + private INotificationProvider _notification; + + private String _latestVersion; + public String LatestVersion + { + get { return _latestVersion; } + set { _latestVersion = value; RaisePropertyChangedAuto(); } + } + + private Machine _machine; + public Machine Machine + { + get { return _machine; } + set { _machine = value; RaisePropertyChangedAuto(); } + } + + private String _filePath; + public String FilePath + { + get { return _filePath; } + set { _filePath = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private TupFileBuilderProgressEventArgs _progress; + public TupFileBuilderProgressEventArgs Progress + { + get { return _progress; } + set { _progress = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand CreateTupFileCommand { get; set; } + + public RelayCommand SelectFileCommand { get; set; } + + public TupViewVM() + { + + } + + public TupViewVM(INotificationProvider notification) : this() + { + _notification = notification; + CreateTupFileCommand = new RelayCommand(CreateTupFile, () => FilePath != null && IsFree); + SelectFileCommand = new RelayCommand(SelectFile); + } + + public void Init(Machine machine) + { + Machine = machine; + DisplayLatestPPCVersion(); + } + + private async void DisplayLatestPPCVersion() + { + TupFileBuilder builder = new TupFileBuilder(); + + try + { + LatestVersion = await builder.GetLatestPPCVersion(Machine.SerialNumber); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error retrieving latest PPC version."); + await Task.Delay(5000); + DisplayLatestPPCVersion(); + } + } + + private void SelectFile() + { + SaveFileDialog dlg = new SaveFileDialog(); + dlg.Title = "Select package location"; + dlg.Filter = "Tango Update Package Files|*.tup"; + dlg.DefaultExt = ".tup"; + dlg.FileName = LatestVersion == null ? $"{Machine.SerialNumber}_Update.tup" : $"{Machine.SerialNumber}_Update_v{LatestVersion}.tup"; + + if (dlg.ShowDialog().Value) + { + FilePath = dlg.FileName; + } + } + + private async void CreateTupFile() + { + try + { + LogManager.Log($"Generating TUP file to '{FilePath}'..."); + + IsFree = false; + TupFileBuilder builder = new TupFileBuilder(); + builder.Progress += Builder_Progress; + await builder.Build(Machine.SerialNumber, FilePath); + + LogManager.Log("TUP file generated successfully."); + _notification.ShowInfo("Tango update package created successfuly."); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error generating tup file."); + _notification.ShowError($"An error occurred while generating the .tup file.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private void Builder_Progress(object sender, TupFileBuilderProgressEventArgs e) + { + Progress = e; + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml index 666a4ee4a..bcca83ca5 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml @@ -64,6 +64,9 @@ + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml new file mode 100644 index 000000000..895a26ca0 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml @@ -0,0 +1,60 @@ + + + + + + + + + + + + + + + + + + + Create a complete update package (.tup) in order to update this machine offline using a removable storage device. + + The latest PPC version is + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.xaml.cs new file mode 100644 index 000000000..fe01296d8 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/TupView.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.MachineStudio.MachineDesigner.Views +{ + /// + /// Interaction logic for SpoolsView.xaml + /// + public partial class TupView : UserControl + { + public TupView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj index 7c0851d01..3ce667afe 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tango.MachineStudio.Common.csproj @@ -59,6 +59,9 @@ ..\..\Referenced Assemblies\SMO\Microsoft.SqlServer.AzureStorageEnum.dll + + ..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + @@ -83,6 +86,9 @@ + + Tup\PublishInfo.cs + GlobalVersionInfo.cs @@ -95,6 +101,10 @@ + + + + @@ -291,6 +301,10 @@ {8491d07b-c1f6-4b62-a412-41b9fd2d6538} Tango.SharedUI + + {e1e66ed9-597d-45fa-8048-de90a6930484} + Tango.SQLExaminer + {74e700b0-1156-4126-be40-ee450d3c3026} Tango.Transport @@ -387,10 +401,11 @@ + - + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs new file mode 100644 index 000000000..6dd8b82f7 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilder.cs @@ -0,0 +1,285 @@ +using Ionic.Zip; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading; +using System.Threading.Tasks; +using Tango.BL; +using Tango.Core; +using Tango.Core.DB; +using Tango.Core.DI; +using Tango.MachineStudio.Common.Web; +using Tango.SQLExaminer; +using Tango.Transport.Web; +using Tango.Core.ExtensionMethods; +using Tango.PPC.Common.Publish; +using Tango.Settings; +using Tango.Core.Components; +using System.Text.RegularExpressions; + +namespace Tango.MachineStudio.Common.Tup +{ + public class TupFileBuilder : ExtendedObject + { + public event EventHandler Progress; + + public Task Build(String serialNumber, String filePath) + { + return Task.Factory.StartNew(() => + { + String tempDbName = "Tango_TUP"; + var tempPackageFolder = TemporaryManager.CreateFolder(); + String tempBackupFolder = "C:\\MachineStudioTUP"; + String tempBackupFile = Path.Combine(tempBackupFolder, tempDbName + ".bak"); + var tempZipFile = TemporaryManager.CreateImaginaryFile(); + DbManager dbManager = null; + + LogManager.Log("Generating tup file..."); + LogManager.Log($"Tup file: '{filePath}.'"); + LogManager.Log($"Temporary db name: '{tempDbName}'."); + LogManager.Log($"Temporary package folder: '{tempPackageFolder}'."); + LogManager.Log($"Temporary db backup folder: '{tempBackupFolder}'."); + LogManager.Log($"Temporary db backup file: '{tempBackupFile}'."); + LogManager.Log($"Temporary zip file: '{tempZipFile}'."); + + try + { + LogManager.Log("Initializing..."); + + OnProgress("Initializing..."); + + Core.DataSource localDataSource = new Core.DataSource() + { + Address = "localhost\\SQLEXPRESS", + IntegratedSecurity = true, + Type = DataSourceType.SQLServer, + Catalog = null, + }; + + try + { + LogManager.Log($"Trying to connect via SQLEXPRESS:\n{localDataSource.ToJsonString()}"); + dbManager = DbManager.FromDataSource(localDataSource); + } + catch (Exception ex) + { + try + { + LogManager.Log(ex, "Could not connect using SQLEXPRESS. Trying local DB..."); + + CmdCommand command = new CmdCommand("sqllocaldb", "info \"MSSQLLocalDB\""); + var result = command.Run().Result; + + String pattern = "np:.+"; + Regex reg = new Regex(pattern); + var match = reg.Match(result.StandardOutput); + String address = match.ToString(); + if (address.Contains("np:")) + { + localDataSource.Address = address; + address = address.Trim().Replace("\r", ""); + } + else + { + throw new ArgumentException("Could not parse LocalDB address string."); + } + + LogManager.Log($"Trying to connect via LocalDB:\n{localDataSource.ToJsonString()}"); + dbManager = DbManager.FromDataSource(localDataSource); + } + catch (Exception x) + { + LogManager.Log(x, "Could not find any database service for this operation."); + throw x; + } + } + + + + OnProgress("Downloading latest PPC version..."); + + LogManager.Log("Connecting to machine service..."); + MachineStudioWebClient client = TangoIOC.Default.GetInstance(); + + LogManager.Log("Requesting latest PPC version from machine service..."); + var response = client.DownloadLatestPPCVersion(new DownloadLatestPPCVersionRequest() { SerialNumber = serialNumber }).Result; + + LogManager.Log($"Machine service response:\n{response.ToJsonString()}"); + + var remoteDataSource = response.DataSource; + + using (AutoFileDownloader downloader = new AutoFileDownloader(response.BlobAddress, response.CdnAddress, tempZipFile)) + { + downloader.Progress += (x, e) => + { + OnProgress($"Downloading latest PPC version '{response.Version}'...", false, e.Current, e.Total); + }; + + downloader.ResolveMode().GetAwaiter().GetResult(); + + LogManager.Log($"Downloading latest PPC version from: '{downloader.Address}'"); + + downloader.Download().Wait(); + } + + LogManager.Log("Extracting PPC version package..."); + + OnProgress("Extracting PPC package..."); + + using (ZipFile zip = new ZipFile(tempZipFile)) + { + int currentEntry = 0; + + zip.ExtractProgress += (x, args) => + { + if (args.EventType == ZipProgressEventType.Extracting_AfterExtractEntry) + { + OnProgress("Extracting PPC package...", false, currentEntry++, zip.Entries.Count); + } + }; + + zip.ExtractAll(tempPackageFolder); + } + + OnProgress("Extracting version information..."); + LogManager.Log("Extracting publish information..."); + PublishInfo publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(tempPackageFolder, "version.json"))); + LogManager.Log($"Publish Information:\n{publishInfo}"); + + LogManager.Log("Modifying publish information to custom tup file..."); + publishInfo.IsMachineTupPackage = true; + publishInfo.MachineSerialNumber = serialNumber; + publishInfo.MachineDeploymentSlot = SettingsManager.Default.GetOrCreate().DeploymentSlot; + + OnProgress("Creating temporary database..."); + + LogManager.Log($"Creating temporary db backup directory '{tempBackupFolder}'"); + + Directory.CreateDirectory(tempBackupFolder); + + LogManager.Log($"Creating new database: '{tempDbName}'"); + + //Create temp db + dbManager.Create(tempDbName, Path.Combine(tempBackupFolder, tempDbName + ".mdf")); + + OnProgress("Generating database snapshot..."); + + LogManager.Log("Starting database synchronization..."); + + Thread.Sleep(2000); + + localDataSource.Catalog = tempDbName; + + ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( + Path.Combine(tempPackageFolder, "Provision Scripts", "config.xml"), + Path.Combine(tempPackageFolder, "Provision Scripts"), + remoteDataSource, + localDataSource, + serialNumber); + + runner.ScriptExecuting += (x, item) => + { + LogManager.Log($"Executing script '{item.FileName}'..."); + OnProgress($"{item.Name}..."); + }; + + runner.Log += (x, log) => + { + LogManager.Log(log); + }; + + runner.Run().GetAwaiter().GetResult(); + + OnProgress("Generating database snapshot..."); + + if (File.Exists(tempBackupFile)) + { + LogManager.Log($"Deleting file '{tempBackupFile}'"); + File.Delete(tempBackupFile); + } + + LogManager.Log($"Generating backup for '{tempDbName}' to '{tempBackupFile}'..."); + + dbManager.Backup(tempDbName, tempBackupFile); + + OnProgress("Injecting database snapshot to PPC package..."); + + using (ZipFile zip = new ZipFile(tempZipFile)) + { + LogManager.Log($"Injecting file '{tempBackupFile}' to original package at '{tempZipFile}'..."); + zip.AddFile(tempBackupFile, "/"); + + LogManager.Log($"Injecting modified publish information..."); + zip.UpdateEntry("version.json", publishInfo.ToJson()); + + zip.Save(); + } + + LogManager.Log($"Copying '{tempZipFile}' to '{filePath}'..."); + + File.Copy(tempZipFile, filePath, true); + + OnProgress("Completed", false, 100, 100); + + LogManager.Log("TUP file generation completed successfully."); + } + catch (Exception ex) + { + LogManager.Log(ex, "TUP file generation failed."); + OnProgress("Failed", false, 0, 100); + throw ex; + } + finally + { + LogManager.Log($"Removing '{tempZipFile}'."); + tempZipFile.Delete(); + LogManager.Log($"Removing '{tempPackageFolder}'."); + tempPackageFolder.Delete(); + + try + { + LogManager.Log($"Removing database '{tempDbName}'."); + dbManager.SetOffline(tempDbName); + dbManager.SetOnline(tempDbName); + dbManager.Delete(tempDbName); + dbManager.Dispose(); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error removing temp database '{tempDbName}'."); + } + + try + { + LogManager.Log($"Removing '{tempBackupFolder}'."); + Directory.Delete(tempBackupFolder, true); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error removing folder '{tempBackupFolder}'."); + } + } + }); + } + + public async Task GetLatestPPCVersion(String serialNumber) + { + MachineStudioWebClient client = TangoIOC.Default.GetInstance(); + var response = await client.DownloadLatestPPCVersion(new DownloadLatestPPCVersionRequest() { SerialNumber = serialNumber }); + return response.Version; + } + + private void OnProgress(String message, bool isIntermediate = true, double progress = 0, double total = 100) + { + Progress?.Invoke(this, new TupFileBuilderProgressEventArgs() + { + Message = message, + IsIntermediate = isIntermediate, + Progress = progress, + Total = total, + }); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs new file mode 100644 index 000000000..ada69dd40 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Tup/TupFileBuilderProgressEventArgs.cs @@ -0,0 +1,16 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.MachineStudio.Common.Tup +{ + public class TupFileBuilderProgressEventArgs + { + public double Progress { get; set; } + public double Total { get; set; } + public bool IsIntermediate { get; set; } + public String Message { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs new file mode 100644 index 000000000..24d465e69 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionRequest.cs @@ -0,0 +1,14 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.Transport.Web; + +namespace Tango.MachineStudio.Common.Web +{ + public class DownloadLatestPPCVersionRequest : WebRequestMessage + { + public String SerialNumber { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.cs new file mode 100644 index 000000000..2cc6b731a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/DownloadLatestPPCVersionResponse.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.Transport.Web; + +namespace Tango.MachineStudio.Common.Web +{ + public class DownloadLatestPPCVersionResponse : WebResponseMessage + { + public String Version { get; set; } + + public String BlobAddress { get; set; } + + public String CdnAddress { get; set; } + + public DataSource DataSource { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs index 131f89515..c2d0dd3e6 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/Web/MachineStudioWebClientBase.cs @@ -94,5 +94,14 @@ namespace Tango.MachineStudio.Common.Web return Post("RefreshToken", request); } + /// + /// Executes the DownloadLatestPPCVersion action and returns Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionResponse. + /// + /// + public Task DownloadLatestPPCVersion(Tango.MachineStudio.Common.Web.DownloadLatestPPCVersionRequest request) + { + return Post("DownloadLatestPPCVersion", request); + } + } } diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config index f871776f5..6fd5091a8 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.Common/packages.config @@ -9,4 +9,5 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj index 991eb9da6..c6cf624b3 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Tango.MachineStudio.UI.csproj @@ -448,6 +448,10 @@ {8491d07b-c1f6-4b62-a412-41b9fd2d6538} Tango.SharedUI + + {e1e66ed9-597d-45fa-8048-de90a6930484} + Tango.SQLExaminer + {998f8471-dc1b-41b6-9d96-354e1b4e7a32} Tango.TFS @@ -661,7 +665,7 @@ if $(ConfigurationName) == Release RD /S /Q "$(TargetDir)ProtoCompilers\" - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs index 3655aa462..e11eab3a5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/IMachineUpdateManager.cs @@ -4,6 +4,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.PMR.Synchronization; +using Tango.PPC.Common.Publish; using Tango.PPC.Common.UpdatePackages; using Tango.PPC.Common.Web; @@ -43,14 +44,14 @@ namespace Tango.PPC.Common.MachineUpdate /// if set to true updates the embedded device firmware. /// if set to true updates the embedded device FPGA version and other parameters. /// - Task Update(String serialNumber, bool setupFirmware, bool setupFPGA); + Task Update(bool setupFirmware, bool setupFPGA); /// /// Performs a machine update using the specified software update package path. /// /// Name of the file. /// - Task UpdateFromTUP(String fileName); + Task UpdateFromTUP(String fileName, bool setupFirmware, bool setupFPGA); /// /// Checks if any update are available for the specified machine serial number. @@ -77,7 +78,7 @@ namespace Tango.PPC.Common.MachineUpdate /// /// The file path. /// - Task GetUpdatePackageFileInfo(String filePath); + Task GetUpdatePackageFileInfo(String filePath); /// /// Checks whether any post update packages needs to be installed. diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs index 5296a9f34..7e742ceb6 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateManager.cs @@ -22,6 +22,7 @@ using Tango.PMR.Synchronization; using Tango.PPC.Common.Application; using Tango.PPC.Common.Connection; using Tango.PPC.Common.Navigation; +using Tango.PPC.Common.Publish; using Tango.PPC.Common.UpdatePackages; using Tango.PPC.Common.Web; using Tango.Settings; @@ -117,7 +118,10 @@ namespace Tango.PPC.Common.MachineUpdate private void LogManager_NewLog(object sender, LogItemBase e) { - _logs.Add(e); + if (_isUpdating) + { + _logs.Add(e); + } } #endregion @@ -133,37 +137,80 @@ namespace Tango.PPC.Common.MachineUpdate }); } - private async void OnFailed(Exception ex, TaskCompletionSource completionSource, DownloadUpdateResponse response, bool performDatabaseRollback, String dbBackupFile, Tango.Core.DataSource localDataSource) + private async void OnFailed(Exception ex, TaskCompletionSource completionSource, DownloadUpdateResponse response, bool performDatabaseRollback, String dbBackupFile, String backupsFolder, String tempDbName, Tango.Core.DataSource localDataSource, String tempUpdatePackageFolder = null) { LogManager.Log(ex, "An error occurred in machine update."); - if (performDatabaseRollback) + await Task.Factory.StartNew(() => { - LogManager.Log("Rolling back database changes..."); - using (DbManager db = DbManager.FromDataSource(localDataSource)) + if (performDatabaseRollback) + { + LogManager.Log("Rolling back database changes..."); + + using (DbManager db = DbManager.FromDataSource(localDataSource)) + { + try + { + UpdateProgress("Rollback", "Rolling back database changes..."); + db.Restore(localDataSource.Catalog, dbBackupFile); + LogManager.Log("Database restored successfully."); + } + catch (Exception e) + { + LogManager.Log(e, "Could not rollback the database."); + } + finally + { + try + { + File.Delete(dbBackupFile); + } + catch { } + } + } + } + + if (tempDbName != null) { try { - UpdateProgress("Rollback", "Rolling back database changes..."); - await Task.Factory.StartNew(() => db.Restore(localDataSource.Catalog, dbBackupFile)); - LogManager.Log("Database restored successfully."); + LogManager.Log($"Removing temporary database '{tempDbName}'..."); + using (DbManager dbManager = DbManager.FromDataSource(localDataSource)) + { + dbManager.SetOffline(tempDbName); + dbManager.SetOnline(tempDbName); + dbManager.Delete(tempDbName); + } } - catch (Exception e) + catch (Exception exx) { - LogManager.Log(e, "Could not rollback the database."); - throw ex; + LogManager.Log(exx, "Error removing temporary database."); } - finally + } + + try + { + Directory.Delete(backupsFolder, true); + } + catch (Exception ee) + { + LogManager.Log(ee, $"Error deleting backups folder '{backupsFolder}'."); + } + + if (tempUpdatePackageFolder != null) + { + try { - try - { - File.Delete(dbBackupFile); - } - catch { } + Directory.Delete(tempUpdatePackageFolder, true); + } + catch (Exception eee) + { + LogManager.Log(eee, "Error removing temporary package folder."); } } - } + + }); completionSource.SetException(ex); @@ -188,13 +235,50 @@ namespace Tango.PPC.Common.MachineUpdate _isUpdating = false; } - private async void OnCompleted(MachineUpdateResult result, TaskCompletionSource completionSource, DownloadUpdateResponse response, String dbBackupFile) + private async void OnCompleted(MachineUpdateResult result, TaskCompletionSource completionSource, DownloadUpdateResponse response, String tempDbName, String backupsFolder, Core.DataSource localDataSource) { - try + await Task.Factory.StartNew(() => { - File.Delete(dbBackupFile); - } - catch { } + if (tempDbName != null) + { + try + { + LogManager.Log($"Removing temporary database '{tempDbName}'..."); + using (DbManager dbManager = DbManager.FromDataSource(localDataSource)) + { + dbManager.SetOffline(tempDbName); + dbManager.SetOnline(tempDbName); + dbManager.Delete(tempDbName); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error removing temporary database."); + } + } + + try + { + Directory.Delete(backupsFolder, true); + } + catch (Exception ex) + { + LogManager.Log(ex, $"Error deleting backups folder '{backupsFolder}'."); + } + + if (!result.RequiresBinariesUpdate) + { + try + { + Directory.Delete(result.UpdatePackagePath, true); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error removing temporary package folder."); + } + } + + }); completionSource.SetResult(result); @@ -315,7 +399,7 @@ namespace Tango.PPC.Common.MachineUpdate /// or /// /// Database tango does not exists. - public async Task Update(String serialNumber, bool setupFirmware, bool setupFPGA) + public async Task Update(bool setupFirmware, bool setupFPGA) { _logs.Clear(); @@ -325,6 +409,13 @@ namespace Tango.PPC.Common.MachineUpdate bool performDatabaseRollback = false; String dbBackupFile = null; DownloadUpdateResponse update_response = null; + String backupsFolder = "C:\\Backups"; + + //Create temporary folders for packages. + var _newPackageTempFolder = TemporaryManager.CreateFolder(); + _newPackageTempFolder.Persist = true; + + String serialNumber = _machineProvider.Machine.SerialNumber; try { @@ -371,10 +462,6 @@ namespace Tango.PPC.Common.MachineUpdate LogManager.Log($"Machine update response received: {Environment.NewLine}{update_response.ToJsonString()}"); - //Create temporary folders for packages. - var _newPackageTempFolder = TemporaryManager.CreateFolder(); - _newPackageTempFolder.Persist = true; - LogManager.Log($"Temporary package folder created: {_newPackageTempFolder}."); //Download software package. @@ -413,8 +500,12 @@ namespace Tango.PPC.Common.MachineUpdate UpdateProgress("Downloading software package", "Extracting package..."); LogManager.Log("Extracting downloaded zip file..."); - //Extract software package. - ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder); + + await Task.Factory.StartNew(() => + { + //Extract software package. + ZipFile.ExtractToDirectory(tempFile, _newPackageTempFolder); + }); LogManager.Log("Copying latest updater utility to application path..."); //Copy new updater utility to app path. @@ -464,8 +555,8 @@ namespace Tango.PPC.Common.MachineUpdate //Create Database Backup try { - Directory.CreateDirectory("C:\\Backups"); - dbBackupFile = $"C:\\Backups\\{Path.GetRandomFileName()}.bak"; + Directory.CreateDirectory(backupsFolder); + dbBackupFile = $"{backupsFolder}\\{Path.GetRandomFileName()}.bak"; LogManager.Log($"Creating database backup to '{dbBackupFile}'..."); await Task.Factory.StartNew(() => db.Backup(localDataSource.Catalog, dbBackupFile)); performDatabaseRollback = true; @@ -548,7 +639,7 @@ namespace Tango.PPC.Common.MachineUpdate handler.Failed += (_, ex) => { stream.Dispose(); - OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, localDataSource); + OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder); }; handler.Completed += (_, __) => { @@ -557,12 +648,12 @@ namespace Tango.PPC.Common.MachineUpdate OnCompleted(new MachineUpdateResult() { UpdatePackagePath = _newPackageTempFolder, - }, result, update_response, dbBackupFile); + }, result, update_response, null, backupsFolder, localDataSource); }; handler.Canceled += (_, __) => { stream.Dispose(); - OnFailed(new Exception("The operation has been canceled."), result, update_response, performDatabaseRollback, dbBackupFile, localDataSource); + OnFailed(new Exception("The operation has been canceled."), result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder); }; handler.Progress += (_, e) => { @@ -574,12 +665,12 @@ namespace Tango.PPC.Common.MachineUpdate OnCompleted(new MachineUpdateResult() { UpdatePackagePath = _newPackageTempFolder, - }, result, update_response, dbBackupFile); + }, result, update_response, null, backupsFolder, localDataSource); } } catch (Exception ex) { - OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, localDataSource); + OnFailed(ex, result, update_response, performDatabaseRollback, dbBackupFile, backupsFolder, null, localDataSource, _newPackageTempFolder); } return await result.Task; @@ -875,31 +966,284 @@ namespace Tango.PPC.Common.MachineUpdate /// /// Name of the file. /// - public Task UpdateFromTUP(string fileName) + public async Task UpdateFromTUP(string fileName, bool setupFirmware, bool setupFPGA) { - return Task.Factory.StartNew(() => + _logs.Clear(); + + TaskCompletionSource result = new TaskCompletionSource(); + + var localDataSource = SettingsManager.Default.GetOrCreate().DataSource; + bool performDatabaseRollback = false; + String dbBackupFile = null; + String tempDbName = "Tango_TUP"; + String tempDbFileName = tempDbName + ".bak"; + String backupsFolder = "C:\\Backups"; + bool replaceBinaries = false; + + String serialNumber = _machineProvider.Machine.SerialNumber; + + //Create temporary folders for packages. + var _newPackageTempFolder = TemporaryManager.CreateFolder(); + _newPackageTempFolder.Persist = true; + + try { - LogManager.Log($"Starting machine update from update package '{fileName}'..."); + _isUpdating = true; + + LogManager.Log($"Starting machine update for serial number {serialNumber}..."); - //Create temporary folders for packages. - var _newPackageTempFolder = TemporaryManager.CreateFolder(); - _newPackageTempFolder.Persist = true; + //Connecting to machine... + LogManager.Log("Verifying machine connection and state..."); - LogManager.Log("Extracting downloaded zip file..."); - //Extract software package. - ZipFile.ExtractToDirectory(fileName, _newPackageTempFolder); + UpdateProgress("Verifying machine state", "Initializing..."); + + await Task.Delay(1000); + + IMachineOperator op = _machineProvider.MachineOperator; + + if (setupFirmware) + { + LogManager.Log("Machine is configured to update firmware..."); + + if (op.State != Transport.TransportComponentState.Connected) + { + throw LogManager.Log(new InvalidOperationException("Could not perform an update while the machine is not connected.")); + } + if (op.Status != MachineStatuses.ReadyToDye) + { + throw LogManager.Log(new InvalidOperationException($"Could not perform an update while the machine is in {op.Status} status.")); + } + } + + UpdateProgress("Exploring package", "Extracting..."); + LogManager.Log("Extracting package..."); + + LogManager.Log($"Temporary package folder created: {_newPackageTempFolder}."); + + await Task.Factory.StartNew(() => + { + //Extract software package. + ZipFile.ExtractToDirectory(fileName, _newPackageTempFolder); + }); + + //Extracting publish info + UpdateProgress("Exploring package", "Verifying..."); + PublishInfo publishInfo = PublishInfo.FromJson(File.ReadAllText(Path.Combine(_newPackageTempFolder, "version.json"))); + + if (!publishInfo.IsMachineTupPackage) + { + throw new InvalidOperationException("The specified tup file is invalid. Updating a machine from a tup file requires a custom generated package."); + } + + if (publishInfo.MachineSerialNumber != serialNumber) + { + throw new InvalidOperationException("The specified tup file is invalid. The package was generated for a different machine."); + } + + if (publishInfo.MachineDeploymentSlot != SettingsManager.Default.GetOrCreate().DeploymentSlot) + { + throw new InvalidOperationException("The specified tup file is invalid. The package was generated on a different environment."); + } + + replaceBinaries = _app_manager.Version.ToString() != publishInfo.ApplicationVersion; LogManager.Log("Copying latest updater utility to application path..."); + //Copy new updater utility to app path. File.Copy(Path.Combine(_newPackageTempFolder, "Tango.PPC.Updater.exe"), Path.Combine(PathHelper.GetStartupPath(), "Tango.PPC.Updater.exe"), true); - LogManager.Log("Update operation completed!"); + //Run pre-update packages. + try + { + UpdateProgress("Preparing", "Running update packages..."); + LogManager.Log("Running pre-update packages..."); + var packagesFolder = Path.Combine(_newPackageTempFolder, "Packages"); - return new MachineUpdateResult() + Version updateVersion = new Version(1, 0, 0, 0); + try + { + updateVersion = Version.Parse(publishInfo.ApplicationVersion); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error parsing new version string for package runner."); + } + + await _packageRunner.Run(PackageType.Pre, updateVersion, packagesFolder); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error running pre-update packages..."); + } + + //Synchronize database + UpdateProgress("Updating Database", "Initializing..."); + + UpdateProgress("Updating Database", "Connecting to local database..."); + LogManager.Log("Initializing database manager..."); + DbManager db = DbManager.FromDataSource(localDataSource); + + LogManager.Log("Checking Tango database exists on the local machine..."); + if (!db.Exists(localDataSource.Catalog)) + { + throw new InvalidProgramException("Database tango does not exists."); + } + + UpdateProgress("Updating Database", "Creating database backup..."); + + //Create Database Backup + try + { + Directory.CreateDirectory(backupsFolder); + dbBackupFile = $"{backupsFolder}\\{Path.GetRandomFileName()}.bak"; + LogManager.Log($"Creating database backup to '{dbBackupFile}'..."); + await Task.Factory.StartNew(() => db.Backup(localDataSource.Catalog, dbBackupFile)); + performDatabaseRollback = true; + LogManager.Log("Database backup created successfully."); + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Update manager error while trying to create a database backup."); + } + + LogManager.Log("Extracting database file from package..."); + File.Copy(Path.Combine(_newPackageTempFolder, tempDbFileName), Path.Combine(backupsFolder, tempDbFileName)); + + LogManager.Log("Restoring package database as a new database..."); + db.RestoreAsNew(tempDbName, Path.Combine(backupsFolder, tempDbFileName), backupsFolder); + + Core.DataSource tempDbDataSource = new Core.DataSource(); + tempDbDataSource.Address = localDataSource.Address; + tempDbDataSource.IntegratedSecurity = localDataSource.IntegratedSecurity; + tempDbDataSource.Type = localDataSource.Type; + tempDbDataSource.Catalog = tempDbName; + + LogManager.Log("Disposing database manager."); + db.Dispose(); + + LogManager.Log($"Initializing {nameof(ExaminerSequenceConfigurationRunner)}..."); + + UpdateProgress("Updating Database", "Initializing update sequence..."); + + ExaminerSequenceConfigurationRunner runner = new ExaminerSequenceConfigurationRunner( + Path.Combine(_newPackageTempFolder, "Update Scripts", "config.xml"), + Path.Combine(_newPackageTempFolder, "Update Scripts"), + tempDbDataSource, + localDataSource, + serialNumber); + + runner.Log += (x, msg) => { - UpdatePackagePath = _newPackageTempFolder, + LogManager.Log(msg); + ProgressLog?.Invoke(this, msg); }; - }); + + runner.ScriptExecuting += (x, item) => + { + LogManager.Log($"Executing script {item.ToString()}..."); + UpdateProgress("Updating Database", item.Name + "..."); + }; + + LogManager.Log("Starting synchronization process..."); + + try + { + await runner.Run(); + LogManager.Log("Synchronization completed successfully!"); + UpdateProgress("Updating Database", "Database synchronization completed successfully."); + } + catch (Exception ex) + { + throw LogManager.Log(ex, "Update manager error while trying to synchronize database."); + } + + LogManager.Log("Getting setup firmware/fpga directly from db.."); + + using (var dbManager = DbManager.FromDataSource(localDataSource)) + { + try + { + String firmware = dbManager.GetValue($"SELECT TOP 1 * FROM MACHINES WHERE SERIAL_NUMBER = '{serialNumber}'", "SETUP_FIRMWARE"); + String fpga = dbManager.GetValue($"SELECT TOP 1 * FROM MACHINES WHERE SERIAL_NUMBER = '{serialNumber}'", "SETUP_FPGA"); + + setupFirmware = bool.Parse(firmware); + setupFPGA = bool.Parse(fpga); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error getting new values of SETUP_FIRMWARE and SETUP_FPGA."); + } + } + + //Updating firmware + if (setupFirmware) + { + UpdateProgress("Updating Firmware", "Connecting to firmware device..."); + LogManager.Log(""); + LogManager.Log("-------------------------------------------------------------------------"); + LogManager.Log("Updating Firmware..."); + + UpdateProgress("Updating Firmware", "Loading firmware package..."); + var tfpPath = Path.Combine(_newPackageTempFolder, "firmware_package.tfp"); + var stream = new FileStream(tfpPath, FileMode.Open); + + if (!_machineProvider.Machine.IsDemo) + { + if (setupFPGA) + { + op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU | FirmwareUpgradeModes.TFP_PACKAGE; + } + else + { + op.FirmwareUpgradeMode = FirmwareUpgradeModes.DFU; + } + } + else + { + op.FirmwareUpgradeMode = FirmwareUpgradeModes.TFP_PACKAGE; + } + + var handler = await op.UpgradeFirmware(stream); + handler.Failed += (_, ex) => + { + stream.Dispose(); + OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder); + }; + handler.Completed += (_, __) => + { + UpdateProgress("Updating Firmware", "Firmware update completed successfully."); + stream.Dispose(); + OnCompleted(new MachineUpdateResult() + { + UpdatePackagePath = _newPackageTempFolder, + RequiresBinariesUpdate = replaceBinaries, + }, result, null, tempDbName, backupsFolder, localDataSource); + }; + handler.Canceled += (_, __) => + { + stream.Dispose(); + OnFailed(new Exception("The operation has been canceled."), result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder); + }; + handler.Progress += (_, e) => + { + UpdateProgress("Updating Firmware", e.Message, false, e.Current, e.Total); + }; + } + else + { + OnCompleted(new MachineUpdateResult() + { + UpdatePackagePath = _newPackageTempFolder, + RequiresBinariesUpdate = replaceBinaries, + }, result, null, tempDbName, backupsFolder, localDataSource); + } + } + catch (Exception ex) + { + OnFailed(ex, result, null, performDatabaseRollback, dbBackupFile, backupsFolder, tempDbName, localDataSource, _newPackageTempFolder); + } + + return await result.Task; } /// @@ -907,25 +1251,23 @@ namespace Tango.PPC.Common.MachineUpdate /// /// The file path. /// - public Task GetUpdatePackageFileInfo(string filePath) + public Task GetUpdatePackageFileInfo(string filePath) { - return Task.Factory.StartNew(() => + return Task.Factory.StartNew(() => { - UpdatePackageFile file = new UpdatePackageFile(); - var tempFolder = TemporaryManager.CreateFolder(); - using (Ionic.Zip.ZipFile zip = new Ionic.Zip.ZipFile(filePath)) { - var appEntry = zip.Entries.SingleOrDefault(x => x.FileName == "Tango.PPC.UI.exe"); - appEntry.Extract(tempFolder); - } + var appEntry = zip.Entries.SingleOrDefault(x => x.FileName == "version.json"); + var reader = appEntry.OpenReader(); - FileVersionInfo info = FileVersionInfo.GetVersionInfo(Path.Combine(tempFolder, "Tango.PPC.UI.exe")); - file.Version = Version.Parse(info.ProductVersion); - - tempFolder.Delete(); + using (StreamReader stReader = new StreamReader(reader)) + { + String json = stReader.ReadToEnd(); + reader.Dispose(); - return file; + return PublishInfo.FromJson(json); + } + } }); } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs index 17ae394ee..85dd5b7d2 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/MachineUpdateResult.cs @@ -12,5 +12,18 @@ namespace Tango.PPC.Common.MachineUpdate /// Gets or sets the temporary update package path from which to get the last downloaded software version. /// public String UpdatePackagePath { get; set; } + + /// + /// Gets or sets a value indicating whether the application should replace it's binaries. + /// + public bool RequiresBinariesUpdate { get; set; } + + /// + /// Initializes a new instance of the class. + /// + public MachineUpdateResult() + { + RequiresBinariesUpdate = true; + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs deleted file mode 100644 index df496c3be..000000000 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineUpdate/UpdatePackageFile.cs +++ /dev/null @@ -1,13 +0,0 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; - -namespace Tango.PPC.Common.MachineUpdate -{ - public class UpdatePackageFile - { - public Version Version { get; set; } - } -} diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs index 77717254e..df5690a05 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Publish/PublishInfo.cs @@ -5,6 +5,7 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.PMR.FirmwareUpgrade; +using Tango.Web; namespace Tango.PPC.Common.Publish { @@ -13,6 +14,9 @@ namespace Tango.PPC.Common.Publish public String ApplicationVersion { get; set; } public VersionPackageDescriptor Firmware { get; set; } public String Comments { get; set; } + public bool IsMachineTupPackage { get; set; } + public String MachineSerialNumber { get; set; } + public DeploymentSlot MachineDeploymentSlot { get; set; } public PublishInfo() { @@ -24,7 +28,7 @@ namespace Tango.PPC.Common.Publish return JsonConvert.SerializeObject(this); } - public PublishInfo FromJson(String json) + public static PublishInfo FromJson(String json) { return JsonConvert.DeserializeObject(json); } 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 e3a23903e..d38b9c8e9 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 @@ -194,7 +194,6 @@ - diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml index 231f5dabb..a175b655e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Dialogs/UpdateFromFileView.xaml @@ -6,16 +6,16 @@ xmlns:local="clr-namespace:Tango.PPC.UI.Dialogs" xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" mc:Ignorable="d" - Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="550" Height="450" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}"> + Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DesignHeight="555" d:DesignWidth="560" Width="570" Height="700" d:DataContext="{d:DesignInstance Type=local:UpdateFromFileViewVM, IsDesignTimeCreatable=False}"> - - CANCEL - UPDATE - + + CANCEL + UPDATE + - UPDATE PACKAGE + Tango Update Package The selected file contains a software update package. Press 'UPDATE' to start updating your system. diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs index 0371e94da..c0654f643 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs @@ -10,6 +10,7 @@ using Tango.Core.Helpers; using Tango.Explorer; using Tango.PPC.Common; using Tango.PPC.Common.MachineUpdate; +using Tango.PPC.Common.Publish; using Tango.PPC.Common.Web; using Tango.PPC.UI.Dialogs; using Tango.PPC.UI.Notifications.NotificationItems; @@ -209,7 +210,7 @@ namespace Tango.PPC.UI.ViewModels try { - _update_result = await MachineUpdateManager.Update(MachineProvider.Machine.SerialNumber, _checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA); + _update_result = await MachineUpdateManager.Update(_checkUpdateResponse.SetupFirmware, _checkUpdateResponse.SetupFPGA); LogManager.Log("Machine update completed."); await NavigateTo(MachineUpdateView.UpdateCompletedView); } @@ -248,15 +249,15 @@ namespace Tango.PPC.UI.ViewModels { LogManager.Log("Completing machine update..."); - if (!IsDbUpdate) + if (IsDbUpdate || !_update_result.RequiresBinariesUpdate) { - String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); - ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath()); + LogManager.Log("Restarting Application..."); + ApplicationManager.Restart(); } else { - LogManager.Log("Restarting Application..."); - ApplicationManager.Restart(); + String updater_exe = Path.Combine(_update_result.UpdatePackagePath, "Tango.PPC.Updater.exe"); + ApplicationManager.UpdateApplication(updater_exe, PathHelper.GetStartupPath()); } } @@ -375,7 +376,7 @@ namespace Tango.PPC.UI.ViewModels private async void HandleSoftwareUpdatePackageLoaded(ExplorerFileItem fileItem) { - UpdatePackageFile packageFile = null; + PublishInfo packageFile = null; try { @@ -383,38 +384,33 @@ namespace Tango.PPC.UI.ViewModels } catch (Exception ex) { - LogManager.Log(ex, $"Error loading update package file from {fileItem.Path}."); + LogManager.Log(ex, $"Error loading publish info from {fileItem.Path}."); await NotificationProvider.ShowError("An error occurred while trying to load the selected software update package. Please make sure the package is valid."); return; } - if (ApplicationManager.Version <= packageFile.Version) - { - await NotificationProvider.ShowError($"The selected update package (v{packageFile.Version.ToString()}) contains an older software version."); - return; - } - UpdateFromFileViewVM vm = new UpdateFromFileViewVM(); - vm.Version = packageFile.Version.ToString(); + vm.Version = packageFile.ApplicationVersion; await NotificationProvider.ShowDialog(vm); if (vm.DialogResult) { await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView); - await NavigateTo(MachineUpdateView.UpdateFromPackageView); + await NavigateTo(MachineUpdateView.UpdateProgressView); LogManager.Log("Starting machine update from package..."); try { - _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path); + _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path, MachineProvider.Machine.SetupFirmware, MachineProvider.Machine.SetupFpga); LogManager.Log("Machine update from package completed."); await NavigateTo(MachineUpdateView.UpdateCompletedView); } catch (Exception ex) { LogManager.Log(ex, "Machine update from package failed."); + FailedError = ex.FlattenMessage(); await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml index fba8a599d..beb09be0d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineUpdateView.xaml @@ -194,8 +194,9 @@ CLOSE - - An error occurred while trying to update the machine. + + Update Failed + diff --git a/Software/Visual_Studio/Tango.Core/DB/DbManager.cs b/Software/Visual_Studio/Tango.Core/DB/DbManager.cs index 1d415fdb1..8601d67a0 100644 --- a/Software/Visual_Studio/Tango.Core/DB/DbManager.cs +++ b/Software/Visual_Studio/Tango.Core/DB/DbManager.cs @@ -65,9 +65,15 @@ namespace Tango.Core.DB #region Public Methods - public void Create(String name) + public void Create(String name, String filePath = null) { String command = String.Format("CREATE DATABASE {0}", name); + + if (filePath != null) + { + command = $"CREATE DATABASE {name} ON (name='{name}', filename='{filePath}')"; + } + SqlCommand cmd = new SqlCommand(command, _connection); cmd.ExecuteNonQuery(); } @@ -160,6 +166,13 @@ namespace Tango.Core.DB SetOnline(name); } + public void RestoreAsNew(String name, String file, String dbFolder) + { + String command = $"RESTORE DATABASE {name} FROM DISK='{file}' WITH MOVE '{name}' TO '{Path.Combine(dbFolder, name)}.mdf', MOVE '{name}_log' TO '{Path.Combine(dbFolder, name)}.ldf'"; + SqlCommand cmd = new SqlCommand(command, _connection); + cmd.ExecuteNonQuery(); + } + public void ClearDb() { if (!_connection.ConnectionString.ToLower().Contains("initial catalog")) @@ -265,6 +278,24 @@ EXEC sp_executesql @statement return cred; } + public String GetValue(String query, String columnName) + { + string sql = query; + var cm = new SqlCommand(sql, _connection); + var dr = cm.ExecuteReader(); + if (dr.Read()) + { + var value = dr[columnName]; + + if (value != null) + { + return value.ToString(); + } + } + + return null; + } + #endregion #region IDisposable diff --git a/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs b/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs index 98a6c2efc..96b0a8525 100644 --- a/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs +++ b/Software/Visual_Studio/Tango.PMR/FirmwareUpgrade/VersionFileDescriptor.cs @@ -23,16 +23,15 @@ namespace Tango.PMR.FirmwareUpgrade { byte[] descriptorData = global::System.Convert.FromBase64String( string.Concat( "ChtWZXJzaW9uRmlsZURlc2NyaXB0b3IucHJvdG8SGVRhbmdvLlBNUi5GaXJt", - "d2FyZVVwZ3JhZGUaHFZlcnNpb25GaWxlRGVzdGluYXRpb24ucHJvdG8ilAEK", + "d2FyZVVwZ3JhZGUaHFZlcnNpb25GaWxlRGVzdGluYXRpb24ucHJvdG8iggEK", "FVZlcnNpb25GaWxlRGVzY3JpcHRvchIQCghGaWxlTmFtZRgBIAEoCRIPCgdW", "ZXJzaW9uGAIgASgJEkYKC0Rlc3RpbmF0aW9uGAMgASgOMjEuVGFuZ28uUE1S", - "LkZpcm13YXJlVXBncmFkZS5WZXJzaW9uRmlsZURlc3RpbmF0aW9uEhAKCENo", - "ZWNrU3VtGAQgASgMQiUKI2NvbS50d2luZS50YW5nby5wbXIuZmlybXdhcmV1", - "cGdyYWRlYgZwcm90bzM=")); + "LkZpcm13YXJlVXBncmFkZS5WZXJzaW9uRmlsZURlc3RpbmF0aW9uQiUKI2Nv", + "bS50d2luZS50YW5nby5wbXIuZmlybXdhcmV1cGdyYWRlYgZwcm90bzM=")); descriptor = pbr::FileDescriptor.FromGeneratedCode(descriptorData, new pbr::FileDescriptor[] { global::Tango.PMR.FirmwareUpgrade.VersionFileDestinationReflection.Descriptor, }, new pbr::GeneratedClrTypeInfo(null, new pbr::GeneratedClrTypeInfo[] { - new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor), global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor.Parser, new[]{ "FileName", "Version", "Destination", "CheckSum" }, null, null, null) + new pbr::GeneratedClrTypeInfo(typeof(global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor), global::Tango.PMR.FirmwareUpgrade.VersionFileDescriptor.Parser, new[]{ "FileName", "Version", "Destination" }, null, null, null) })); } #endregion @@ -66,7 +65,6 @@ namespace Tango.PMR.FirmwareUpgrade { fileName_ = other.fileName_; version_ = other.version_; destination_ = other.destination_; - checkSum_ = other.checkSum_; } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -107,17 +105,6 @@ namespace Tango.PMR.FirmwareUpgrade { } } - /// Field number for the "CheckSum" field. - public const int CheckSumFieldNumber = 4; - private pb::ByteString checkSum_ = pb::ByteString.Empty; - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] - public pb::ByteString CheckSum { - get { return checkSum_; } - set { - checkSum_ = pb::ProtoPreconditions.CheckNotNull(value, "value"); - } - } - [global::System.Diagnostics.DebuggerNonUserCodeAttribute] public override bool Equals(object other) { return Equals(other as VersionFileDescriptor); @@ -134,7 +121,6 @@ namespace Tango.PMR.FirmwareUpgrade { if (FileName != other.FileName) return false; if (Version != other.Version) return false; if (Destination != other.Destination) return false; - if (CheckSum != other.CheckSum) return false; return true; } @@ -144,7 +130,6 @@ namespace Tango.PMR.FirmwareUpgrade { if (FileName.Length != 0) hash ^= FileName.GetHashCode(); if (Version.Length != 0) hash ^= Version.GetHashCode(); if (Destination != 0) hash ^= Destination.GetHashCode(); - if (CheckSum.Length != 0) hash ^= CheckSum.GetHashCode(); return hash; } @@ -167,10 +152,6 @@ namespace Tango.PMR.FirmwareUpgrade { output.WriteRawTag(24); output.WriteEnum((int) Destination); } - if (CheckSum.Length != 0) { - output.WriteRawTag(34); - output.WriteBytes(CheckSum); - } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -185,9 +166,6 @@ namespace Tango.PMR.FirmwareUpgrade { if (Destination != 0) { size += 1 + pb::CodedOutputStream.ComputeEnumSize((int) Destination); } - if (CheckSum.Length != 0) { - size += 1 + pb::CodedOutputStream.ComputeBytesSize(CheckSum); - } return size; } @@ -205,9 +183,6 @@ namespace Tango.PMR.FirmwareUpgrade { if (other.Destination != 0) { Destination = other.Destination; } - if (other.CheckSum.Length != 0) { - CheckSum = other.CheckSum; - } } [global::System.Diagnostics.DebuggerNonUserCodeAttribute] @@ -230,10 +205,6 @@ namespace Tango.PMR.FirmwareUpgrade { destination_ = (global::Tango.PMR.FirmwareUpgrade.VersionFileDestination) input.ReadEnum(); break; } - case 34: { - CheckSum = input.ReadBytes(); - break; - } } } } diff --git a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs index de146ead3..b9ee0cf7a 100644 --- a/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs +++ b/Software/Visual_Studio/Tango.SQLExaminer/ExaminerSequenceConfigurationRunner.cs @@ -24,6 +24,15 @@ namespace Tango.SQLExaminer public ExaminerSequenceConfiguration Configuration { get; private set; } + public ExaminerSequenceConfigurationRunner(ExaminerSequenceConfiguration sequenceConfiguration, String scriptsFolder, Core.DataSource source, Core.DataSource target, String machineSerialNumber) + { + ScriptsFolder = scriptsFolder; + Source = source; + Target = target; + MachineSerialNumber = machineSerialNumber; + Configuration = sequenceConfiguration; + } + public ExaminerSequenceConfigurationRunner(String sequenceFile, String scriptsFolder, Core.DataSource source, Core.DataSource target, String machineSerialNumber) { SequenceFile = sequenceFile; diff --git a/Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs b/Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs new file mode 100644 index 000000000..09a830ab3 --- /dev/null +++ b/Software/Visual_Studio/Tango.SQLExaminer/ExtensionMethods.cs @@ -0,0 +1,21 @@ +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.SQLExaminer; + +public static class ExtensionMethods +{ + public static String GetFilePath(this ExaminerConfigurationType type) + { + return Path.Combine(Helper.SQL_EXAMINER_CONFIG_FOLDER, type.ToString() + ".xml"); + } + + public static String GetFileName(this ExaminerConfigurationType type) + { + return type.ToString() + ".xml"; + } +} + diff --git a/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs b/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs index 5eb09b98c..3b4e238a7 100644 --- a/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs +++ b/Software/Visual_Studio/Tango.SQLExaminer/Helper.cs @@ -8,7 +8,7 @@ using Tango.Core.Helpers; namespace Tango.SQLExaminer { - internal static class Helper + public static class Helper { public static String SQL_EXAMINER_FOLDER = Path.Combine(AssemblyHelper.GetCurrentAssemblyFolder(), "SQLExaminer"); public static String SQL_EXAMINER_CONFIG_FOLDER = Path.Combine(SQL_EXAMINER_FOLDER, "Configurations"); diff --git a/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj b/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj index b71a30dc0..17dcb1b22 100644 --- a/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj +++ b/Software/Visual_Studio/Tango.SQLExaminer/Tango.SQLExaminer.csproj @@ -69,6 +69,7 @@ + diff --git a/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs b/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs index 9b0385c23..e3e49ac5e 100644 --- a/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs +++ b/Software/Visual_Studio/Tango.UnitTesting/SQLExaminer/SQLExaminer_TST.cs @@ -391,5 +391,76 @@ namespace Tango.UnitTesting.SQLExaminer //Should have no differences! Assert.IsFalse(data_report.HasDifferences); } + + [TestMethod] + public void Perform_Machine_Update_From_Backup() + { + String tempDbName = "Tango_TUP"; + + var source_db = GetSource("Tango"); + var target_db = GetSource(tempDbName); + + DbManager dbManager = DbManager.FromDataSource(source_db); + + //Create the backup for the tup file. + dbManager.Create(tempDbName); + + var configuration = GetFullConfiguration(); + + ExaminerSequenceConfigurationRunner runner = + new ExaminerSequenceConfigurationRunner( + configuration, + Tango.SQLExaminer.Helper.SQL_EXAMINER_CONFIG_FOLDER, + source_db, + target_db, + "1111"); + + runner.Run().GetAwaiter().GetResult(); + + String backupFile = "C:\\DB_Backups\\Tango_TEMP.bak"; + + dbManager.Backup(tempDbName, backupFile); + dbManager.SetOffline(tempDbName); + dbManager.SetOnline(tempDbName); + dbManager.Delete(tempDbName); + + //Now restore as different name + dbManager.RestoreAsNew(tempDbName, backupFile, "C:\\DB_Backups"); + } + + private ExaminerSequenceConfiguration GetFullConfiguration() + { + ExaminerSequenceConfiguration configuration = new ExaminerSequenceConfiguration(); + + configuration.Items.Add(new ExaminerSequenceItem() + { + Type = ExaminerSequenceItemType.Schema, + Direction = ExaminerSequenceItemDirection.SourceToTarget, + FileName = ExaminerConfigurationType.Schema.GetFileName(), + Index = 0, + Name = "Updating Schema", + }); + + configuration.Items.Add(new ExaminerSequenceItem() + { + Type = ExaminerSequenceItemType.Data, + Direction = ExaminerSequenceItemDirection.SourceToTarget, + FileName = ExaminerConfigurationType.OverrideData.GetFileName(), + Index = 1, + Name = "Updating Collections", + }); + + configuration.Items.Add(new ExaminerSequenceItem() + { + Type = ExaminerSequenceItemType.Data, + Direction = ExaminerSequenceItemDirection.SourceToTarget, + FileName = ExaminerConfigurationType.ProvisionMachine.GetFileName(), + Index = 2, + Name = "Configuring Machine", + RequiresSerialNumber = true, + }); + + return configuration; + } } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs index 2eeaa6e0e..378fc3eea 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/MachineStudioController.cs @@ -23,6 +23,10 @@ using Tango.Web.ActiveDirectory; using Tango.MachineService.Filters; using Tango.MachineService.Security; using Tango.Web.SQLServer; +using Tango.Core; +using Tango.Web.SMO; +using Tango.Core.DB; +using System.Threading.Tasks; namespace Tango.MachineService.Controllers { @@ -425,6 +429,67 @@ namespace Tango.MachineService.Controllers }; } + [HttpPost] + [JwtTokenFilter] + public DownloadLatestPPCVersionResponse DownloadLatestPPCVersion(DownloadLatestPPCVersionRequest request) + { + DownloadLatestPPCVersionResponse response = new DownloadLatestPPCVersionResponse(); + + using (ObservablesContext db = ObservablesContextHelper.CreateContext()) + { + var machine = db.Machines.SingleOrDefault(x => x.SerialNumber == request.SerialNumber); + + if (machine == null) + { + throw new AuthenticationException("The specified serial number could not be found."); + } + + var machine_version = db.MachineVersions.SingleOrDefault(x => x.Guid == machine.MachineVersionGuid); + + var latest_machine_version = db.TangoVersions.Where(x => x.MachineVersionGuid == machine_version.Guid).ToList().OrderByDescending(x => Version.Parse(x.Version)).FirstOrDefault(); + + response.Version = latest_machine_version.Version; + + var manager = new BlobStorageManager(); + var container = manager.GetContainer(MachineServiceConfig.TANGO_VERSIONS_CONTAINER); + var blob = container.GetBlockBlobReference(latest_machine_version.BlobName); + + response.BlobAddress = blob.GenerateReadSignature(TimeSpan.FromMinutes(60)); + + if (!String.IsNullOrWhiteSpace(MachineServiceConfig.CDN_ENDPOINT)) + { + response.CdnAddress = MachineServiceConfig.CDN_ENDPOINT + blob.Uri.AbsolutePath; + } + + DbCredentials credentials = new DbCredentials(); + + using (SmoManager smo = new SmoManager()) + { + credentials = smo.CreateRandomLoginAndUser(); + + Task.Delay(TimeSpan.FromMinutes(PPCController.SQL_TEMP_CREDENTIALS_EXP_MINUTS)).ContinueWith((x) => + { + using (SmoManager m = new SmoManager()) + { + m.DeleteLoginAndUser(credentials.UserName); + } + }); + } + + response.DataSource = new DataSource() + { + Address = MachineServiceConfig.DB_ADDRESS, + Catalog = MachineServiceConfig.DB_CATALOG, + UserName = credentials.UserName, + Password = credentials.Password, + IntegratedSecurity = false, + Type = DataSourceType.SQLServer, + }; + } + + return response; + } + #endregion } } diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 2dee09e69..0d9a2993b 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -32,7 +32,7 @@ namespace Tango.MachineService.Controllers private static List _pendingUploads; private static List _pendingUpdates; private ActiveDirectoryManager _ad_manager; - private const int SQL_TEMP_CREDENTIALS_EXP_MINUTS = 20; + public const int SQL_TEMP_CREDENTIALS_EXP_MINUTS = 20; public class TokenObject { -- cgit v1.3.1 From 76a028f95dc2bdb2aba4a58ca298268be32a5879 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 14 Dec 2019 19:04:41 +0200 Subject: Implemented sites module on MS. Implemented site selection on Machine Designer. --- Software/DB/TCC/TCC.mdf | Bin 8388608 -> 8388608 bytes Software/DB/TCC/TCC_log.ldf | Bin 8388608 -> 8388608 bytes Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../ViewModels/MainViewVM.cs | 21 ++- .../Views/MachineSettingsView.xaml | 3 + .../Modules/Tango.MachineStudio.Sites/App.xaml | 12 ++ .../Contracts/IMainView.cs | 20 +++ .../Images/machine_site.png | Bin 0 -> 207547 bytes .../Tango.MachineStudio.Sites/Models/SiteModel.cs | 18 ++ .../Tango.MachineStudio.Sites.csproj | 32 +++- .../ViewModels/MainViewVM.cs | 198 ++++++++++++++++++++- .../ViewModels/SiteDetailsViewVM.cs | 153 ++++++++++++++++ .../Tango.MachineStudio.Sites/Views/MainView.xaml | 6 +- .../Views/MainView.xaml.cs | 10 +- .../Views/SiteDetailsView.xaml | 170 ++++++++++++++++++ .../Views/SiteDetailsView.xaml.cs | 28 +++ .../Tango.MachineStudio.Sites/Views/SitesView.xaml | 76 ++++++++ .../Views/SitesView.xaml.cs | 28 +++ .../Modules/Tango.MachineStudio.Sites/app.config | 10 ++ .../Tango.MachineStudio.Sites/packages.config | 1 + Software/Visual_Studio/Tango.BL/Entities/Site.cs | 36 ++++ 22 files changed, 816 insertions(+), 6 deletions(-) create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml create mode 100644 Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/DB/TCC/TCC.mdf b/Software/DB/TCC/TCC.mdf index 37ed9b842..f77c2e733 100644 Binary files a/Software/DB/TCC/TCC.mdf and b/Software/DB/TCC/TCC.mdf differ diff --git a/Software/DB/TCC/TCC_log.ldf b/Software/DB/TCC/TCC_log.ldf index 616875f6b..048d3ccb0 100644 Binary files a/Software/DB/TCC/TCC_log.ldf and b/Software/DB/TCC/TCC_log.ldf differ diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 5650526a0..6af55afc8 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index 6a5c87335..33e76f9de 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index 768f93de1..fd31cd950 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -115,6 +115,21 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels set { _selectedSpool = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } } + private Site _selectedSite; + public Site SelectedSite + { + get { return _selectedSite; } + set { _selectedSite = value; RaisePropertyChangedAuto(); } + } + + private List _sites; + public List Sites + { + get { return _sites; } + set { _sites = value; RaisePropertyChangedAuto(); } + } + + private ColorCalibrationViewVM _colorCalibrationViewVM; public ColorCalibrationViewVM ColorCalibrationViewVM { @@ -474,6 +489,10 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } + Sites = await ActiveMachineAdapter.Context.Sites.ToListAsync(); + Sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); + SelectedSite = Sites.SingleOrDefault(x => x.Guid == ActiveMachine.SiteGuid); + ColorCalibrationViewVM = new ColorCalibrationViewVM(_notification, ActiveMachine, _activeMachineAdapter.Context) { Rmls = ActiveMachineAdapter.Rmls, @@ -487,7 +506,6 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); TupViewVM.Init(ActiveMachine); - ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged; View.NavigateTo(MachineDesignerNavigationView.MachineDetailsView); @@ -651,6 +669,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels ActiveMachine.ConfigurationGuid = ActiveMachine.Configuration.Guid; ActiveMachine.LastUpdated = DateTime.UtcNow; ActiveMachine.ProductionDate = DateTime.UtcNow; + ActiveMachine.SiteGuid = SelectedSite == null ? null : (SelectedSite.ID == -1 ? null : SelectedSite.Guid); ColorCalibrationViewVM.Save(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml index b6c1ba974..0a0c1ecef 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineSettingsView.xaml @@ -48,6 +48,9 @@ Organization + Site + + OS Key diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml new file mode 100644 index 000000000..01a064b05 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/App.xaml @@ -0,0 +1,12 @@ + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs new file mode 100644 index 000000000..67f57b28c --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Contracts/IMainView.cs @@ -0,0 +1,20 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.SharedUI; + +namespace Tango.MachineStudio.Sites.Contracts +{ + public enum SitesNavigationView + { + SitesView, + SiteDetailsView, + } + + public interface IMainView : IView + { + void NavigateTo(SitesNavigationView view); + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png new file mode 100644 index 000000000..9b22e53b0 Binary files /dev/null and b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Images/machine_site.png differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs new file mode 100644 index 000000000..007f8a3ad --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Models/SiteModel.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.SharedUI.Components; + +namespace Tango.MachineStudio.Sites.Models +{ + public class SiteModel : Site + { + public String Organization { get; set; } + public int MachineCount { get; set; } + public int CatalogCount { get; set; } + public int ThreadCount { get; set; } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj index 95f71baa8..ea9162ce2 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Tango.MachineStudio.Sites.csproj @@ -32,6 +32,12 @@ 4 + + ..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.dll + + + ..\..\..\packages\EntityFramework.6.2.0\lib\net45\EntityFramework.SqlServer.dll + ..\..\..\packages\Google.Protobuf.3.4.1\lib\net45\Google.Protobuf.dll @@ -48,6 +54,7 @@ ..\..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll + ..\..\..\packages\MahApps.Metro.1.5.0\lib\net45\System.Windows.Interactivity.dll @@ -66,8 +73,11 @@ + + + MainView.xaml @@ -75,10 +85,28 @@ GlobalVersionInfo.cs + + SiteDetailsView.xaml + + + SitesView.xaml + + + MSBuild:Compile + Designer + Designer MSBuild:Compile + + Designer + MSBuild:Compile + + + Designer + MSBuild:Compile + @@ -105,7 +133,9 @@ Settings.Designer.cs - + + + {f441feee-322a-4943-b566-110e12fd3b72} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs index d0be162dd..486c8b46f 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs @@ -4,15 +4,209 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.Core.Threading; using Tango.MachineStudio.Common; +using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Sites.Contracts; +using Tango.MachineStudio.Sites.Models; namespace Tango.MachineStudio.Sites.ViewModels { - public class MainViewVM : StudioViewModel + public class MainViewVM : StudioViewModel { + private ObservablesContext _db; + private INotificationProvider _notification; + private ActionTimer _filter_timer; + + private List _sites; + public List Sites + { + get { return _sites; } + set { _sites = value; RaisePropertyChangedAuto(); } + } + + private SiteModel _selectedSite; + public SiteModel SelectedSite + { + get { return _selectedSite; } + set { _selectedSite = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _filter; + public String Filter + { + get { return _filter; } + set { _filter = value; RaisePropertyChangedAuto(); OnFilterChanged(); } + } + + private SiteDetailsViewVM _siteDetailsViewVM; + public SiteDetailsViewVM SiteDetailsViewVM + { + get { return _siteDetailsViewVM; } + set { _siteDetailsViewVM = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand AddSiteCommand { get; set; } + + public RelayCommand RemoveSiteCommand { get; set; } + + public RelayCommand ManageSiteCommand { get; set; } + + public RelayCommand BackToSitesCommand { get; set; } + + public MainViewVM(INotificationProvider notificationProvider) + { + _notification = notificationProvider; + _filter_timer = new ActionTimer(TimeSpan.FromMilliseconds(500)); + + ManageSiteCommand = new RelayCommand(() => LoadSelectedSite(), () => SelectedSite != null); + BackToSitesCommand = new RelayCommand(() => { View.NavigateTo(SitesNavigationView.SitesView); }); + AddSiteCommand = new RelayCommand(AddNewSite); + RemoveSiteCommand = new RelayCommand(RemoveSelectedSite, () => SelectedSite != null); + } + + private async void RemoveSelectedSite() + { + if (!_notification.ShowQuestion("Are you sure you wish to remove the selected site?")) return; + + try + { + using (_notification.PushTaskItem("Removing site...")) + { + IsFree = false; + await Task.Factory.StartNew(() => + { + var site = _db.Sites.SingleOrDefault(x => x.Guid == SelectedSite.Guid); + site.Delete(_db); + _db.SaveChanges(); + Sites.Remove(SelectedSite); + LoadSites(); + }); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error removing site."); + _notification.ShowError($"Error removing site.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private async void AddNewSite() + { + try + { + String name = _notification.ShowTextInput("Enter site name", "name"); + if (String.IsNullOrWhiteSpace(name)) return; + + using (_notification.PushTaskItem("Creating site...")) + { + IsFree = false; + SiteDetailsViewVM = new SiteDetailsViewVM(); + SiteDetailsViewVM.Saved += SiteDetailsViewVM_Saved; + await SiteDetailsViewVM.Init(SelectedSite?.Guid, _notification, true, name); + View.NavigateTo(SitesNavigationView.SiteDetailsView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error creating site."); + _notification.ShowError($"Error creating site.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private async void LoadSelectedSite() + { + try + { + using (_notification.PushTaskItem("Loading site details...")) + { + IsFree = false; + SiteDetailsViewVM = new SiteDetailsViewVM(); + SiteDetailsViewVM.Saved += SiteDetailsViewVM_Saved; + await SiteDetailsViewVM.Init(SelectedSite.Guid, _notification, false); + View.NavigateTo(SitesNavigationView.SiteDetailsView); + } + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading site details."); + _notification.ShowError($"Error loading site details.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + + private void SiteDetailsViewVM_Saved(object sender, EventArgs e) + { + OnFilterChanged(); + View.NavigateTo(SitesNavigationView.SitesView); + } + + private void OnFilterChanged() + { + if (Filter != null) + { + _filter_timer.ResetReplace(() => + { + try + { + LoadSites(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error loading sites list."); + } + }); + } + } + + private void LoadSites() + { + using (_notification.PushTaskItem("Loading sites...")) + { + Sites = (from site in _db.Sites + join organization in _db.Organizations on site.OrganizationGuid equals organization.Guid + join sites_rmls in _db.SitesRmls on site.Guid equals sites_rmls.SiteGuid into rmls + join sites_catalogs in _db.SitesCatalogs on site.Guid equals sites_catalogs.SiteGuid into catalogs + join sites_machines in _db.Machines on site.Guid equals sites_machines.SiteGuid into machines + where Filter == null || Filter == "" || site.Name.ToLower().StartsWith(Filter.ToLower()) || organization.Name.ToLower().StartsWith(Filter.ToLower()) + select new + { + Site = site, + OrganizationName = organization.Name, + ThreadCount = rmls.Count(x => x.SiteGuid == site.Guid), + CatalogCount = catalogs.Count(x => x.SiteGuid == site.Guid), + MachineCount = machines.Count(x => x.SiteGuid == site.Guid) + }).Distinct().ToList().DistinctBy(x => x.Site.Guid).Select(x => new SiteModel() + { + Guid = x.Site.Guid, + ID = x.Site.ID, + Name = x.Site.Name, + Description = x.Site.Description, + ThreadCount = x.ThreadCount, + CatalogCount = x.CatalogCount, + MachineCount = x.MachineCount, + Organization = x.OrganizationName, + }).ToList(); + } + } + public override void OnApplicationReady() { - + _db = ObservablesContext.CreateDefault(); } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs new file mode 100644 index 000000000..0e4dcbb47 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs @@ -0,0 +1,153 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using Tango.BL; +using Tango.BL.Entities; +using Tango.Core.Commands; +using Tango.SharedUI; +using Tango.SharedUI.Components; +using System.Data.Entity; +using Tango.MachineStudio.Common.Notifications; + +namespace Tango.MachineStudio.Sites.ViewModels +{ + public class SiteDetailsViewVM : ViewModel + { + private ObservablesContext _db; + private INotificationProvider _notification; + + public event EventHandler Saved; + + private Site _site; + public Site Site + { + get { return _site; } + set { _site = value; RaisePropertyChangedAuto(); } + } + + private List _organizations; + public List Organizations + { + get { return _organizations; } + set { _organizations = value; RaisePropertyChangedAuto(); } + } + + private Organization _selectedOrganization; + public Organization SelectedOrganization + { + get { return _selectedOrganization; } + set { _selectedOrganization = value; RaisePropertyChangedAuto(); } + } + + private SelectedObjectCollection _rmls; + public SelectedObjectCollection Rmls + { + get { return _rmls; } + set { _rmls = value; RaisePropertyChangedAuto(); } + } + + private SelectedObjectCollection _catalogs; + public SelectedObjectCollection Catalogs + { + get { return _catalogs; } + set { _catalogs = value; RaisePropertyChangedAuto(); } + } + + private List _machines; + public List Machines + { + get { return _machines; } + set { _machines = value; RaisePropertyChangedAuto(); } + } + + public RelayCommand SaveCommand { get; set; } + + public SiteDetailsViewVM() + { + SaveCommand = new RelayCommand(Save, () => IsFree); + } + + public async Task Init(String siteGuid, INotificationProvider notification, bool isNew, string newSiteName = null) + { + _notification = notification; + + _db = ObservablesContext.CreateDefault(); + Organizations = await _db.Organizations.ToListAsync(); + + if (isNew) + { + Site = new Site(); + Site.Name = newSiteName; + Site.Description = "My site description"; + _db.Sites.Add(Site); + } + else + { + Site = await _db.Sites.SingleOrDefaultAsync(x => x.Guid == siteGuid); + } + + Machines = await _db.Machines.Where(x => x.SiteGuid == Site.Guid).Include(x => x.Organization).ToListAsync(); + + var site_rmls = await _db.SitesRmls.Where(x => x.SiteGuid == Site.Guid).ToListAsync(); + var site_catalogs = await _db.SitesCatalogs.Where(x => x.SiteGuid == Site.Guid).ToListAsync(); + + var rmls = await _db.Rmls.OrderBy(x => x.Name).ToListAsync(); + var catalogs = await _db.ColorCatalogs.OrderBy(x => x.Name).ToListAsync(); + + Rmls = new SelectedObjectCollection(rmls.ToObservableCollection(), rmls.Where(rml => site_rmls.Exists(siteRml => siteRml.RmlGuid == rml.Guid)).ToObservableCollection()); + Catalogs = new SelectedObjectCollection(catalogs.ToObservableCollection(), catalogs.Where(catalog => site_catalogs.Exists(siteCatalog => siteCatalog.CatalogGuid == catalog.Guid)).ToObservableCollection()); + + SelectedOrganization = Organizations.SingleOrDefault(x => x.Guid == Site.OrganizationGuid); + } + + private async void Save() + { + try + { + Site.OrganizationGuid = SelectedOrganization?.Guid; + + if (!Site.Validate(_db)) + { + _notification.ShowError(String.Join("\n", Site.ValidationErrors)); + return; + } + + IsFree = false; + + using (_notification.PushTaskItem("Saving site details...")) + { + var site_rmls = await _db.SitesRmls.Where(x => x.SiteGuid == Site.Guid).ToListAsync(); + var site_catalogs = await _db.SitesCatalogs.Where(x => x.SiteGuid == Site.Guid).ToListAsync(); + + _db.SitesRmls.RemoveRange(site_rmls); + _db.SitesCatalogs.RemoveRange(site_catalogs); + + foreach (var selectedRml in Rmls.SynchedSource) + { + _db.SitesRmls.Add(new SitesRml() { SiteGuid = Site.Guid, RmlGuid = selectedRml.Guid }); + } + + foreach (var selectedCatalog in Catalogs.SynchedSource) + { + _db.SitesCatalogs.Add(new SitesCatalog() { SiteGuid = Site.Guid, CatalogGuid = selectedCatalog.Guid }); + } + + await _db.SaveChangesAsync(); + } + _db.Dispose(); + Saved?.Invoke(this, new EventArgs()); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error saving site details."); + _notification.ShowError($"Error saving site details.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml index 80f9ae151..4ca82c4f7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml @@ -7,9 +7,13 @@ xmlns:vm="clr-namespace:Tango.MachineStudio.Sites.ViewModels" xmlns:global="clr-namespace:Tango.MachineStudio.Sites" xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - Comming soon... + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs index 75ced5ae2..c4f9995ce 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/MainView.xaml.cs @@ -12,17 +12,25 @@ using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; +using Tango.Core.DI; +using Tango.MachineStudio.Sites.Contracts; namespace Tango.MachineStudio.Sites.Views { /// /// Interaction logic for MainView.xaml /// - public partial class MainView : UserControl + public partial class MainView : UserControl, IMainView { public MainView() { InitializeComponent(); + TangoIOC.Default.Register(this); + } + + public void NavigateTo(SitesNavigationView view) + { + navigationControl.NavigateTo(view.ToString()); } } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml new file mode 100644 index 000000000..b3496a5e2 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml @@ -0,0 +1,170 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + PROPERTIES + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + SITE RML + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.xaml.cs new file mode 100644 index 000000000..03e9a2f75 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SiteDetailsView.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.MachineStudio.Sites.Views +{ + /// + /// Interaction logic for SiteDetailsView.xaml + /// + public partial class SiteDetailsView : UserControl + { + public SiteDetailsView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml new file mode 100644 index 000000000..437003a8a --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.xaml.cs new file mode 100644 index 000000000..e6a4a6fe6 --- /dev/null +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/Views/SitesView.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.MachineStudio.Sites.Views +{ + /// + /// Interaction logic for SitesView.xaml + /// + public partial class SitesView : UserControl + { + public SitesView() + { + InitializeComponent(); + } + } +} diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config index 97a204217..7b82e5f7c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/app.config @@ -1,5 +1,9 @@  + + +
+ @@ -72,4 +76,10 @@ + + + + + + \ No newline at end of file diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config index fd88f4804..e57143046 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/packages.config @@ -1,5 +1,6 @@  + diff --git a/Software/Visual_Studio/Tango.BL/Entities/Site.cs b/Software/Visual_Studio/Tango.BL/Entities/Site.cs index d88a00567..6e95aa39d 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/Site.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/Site.cs @@ -8,5 +8,41 @@ namespace Tango.BL.Entities { public class Site : SiteBase { + public override void Delete(ObservablesContext context) + { + base.Delete(context); + + var site_rmls = context.SitesRmls.Where(x => x.SiteGuid == Guid).ToList(); + var site_catalogs = context.SitesCatalogs.Where(x => x.SiteGuid == Guid).ToList(); + context.SitesRmls.RemoveRange(site_rmls); + context.SitesCatalogs.RemoveRange(site_catalogs); + context.Machines.Where(x => x.SiteGuid == Guid).ToList().ForEach(x => x.SiteGuid = null); + context.Sites.Remove(this); + } + + protected override void OnValidating(ObservablesContext context) + { + base.OnValidating(context); + + if (String.IsNullOrWhiteSpace(Name)) + { + InsertError(nameof(Name), "Site name is required"); + } + + if (Name != null && Name.Length > 100) + { + InsertError(nameof(Name), "The site name exceeds the maximum allowed characters."); + } + + if (Description != null && Description.Length > 200) + { + InsertError(nameof(Description), "The site description exceeds the maximum allowed characters."); + } + + if (OrganizationGuid == null) + { + InsertError(nameof(OrganizationGuid), "Site organization is required."); + } + } } } -- cgit v1.3.1 From 582c05b00aa1d0fd9086b4a245dcc987eee9fc39 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sat, 21 Dec 2019 19:14:00 +0200 Subject: Working some more on ActionLogs across MS. --- .../ViewModels/MainViewVM.cs | 4 +-- .../ViewModels/MainViewVM.cs | 10 +++--- .../ViewModels/MainViewVM.cs | 6 ++-- .../ViewModels/MainViewVM.cs | 32 +++++++++++++++-- .../ViewModels/MainViewVM.cs | 28 ++++++++++++++- .../ViewModels/MainViewVM.cs | 13 +++++-- .../ViewModels/SiteDetailsViewVM.cs | 42 +++++++++++++++++++--- Software/Visual_Studio/Tango.BL/DTO/CatDTO.cs | 10 ++++++ .../Visual_Studio/Tango.BL/DTO/ConfigurationDTO.cs | 21 +++++++++++ Software/Visual_Studio/Tango.BL/DTO/IdsPackDTO.cs | 25 ++++++++++--- Software/Visual_Studio/Tango.BL/DTO/MachineDTO.cs | 16 +++++++++ Software/Visual_Studio/Tango.BL/DTO/RmlDTO.cs | 4 +++ Software/Visual_Studio/Tango.BL/DTO/SiteDTO.cs | 25 +++++++++++++ Software/Visual_Studio/Tango.BL/DTO/SitesRmlDTO.cs | 6 +++- Software/Visual_Studio/Tango.BL/DTO/SpoolDTO.cs | 7 ++++ .../Tango.BL/Enumerations/ActionLogType.cs | 6 ++++ .../Controllers/PPCController.cs | 2 ++ 17 files changed, 230 insertions(+), 27 deletions(-) (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs index ae763167b..e306d0997 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Catalogs/ViewModels/MainViewVM.cs @@ -244,7 +244,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels { IsFree = false; await SelectedCatalog.DeleteCascadeAsync(_catalogsContext); - _actionLogManager.InsertLog(ActionLogType.CatalogDeleted, _authentication.CurrentUser, SelectedCatalog.Name, SelectedCatalog, "Catalog deleted using Machine Studio."); + _actionLogManager.InsertLog(ActionLogType.CatalogDeleted, _authentication.CurrentUser, SelectedCatalog.Name, SelectedCatalog, "Catalog deleted using Machine Studio.", false); SelectedCatalog = null; } catch (Exception ex) @@ -322,7 +322,7 @@ namespace Tango.MachineStudio.Catalogs.ViewModels await _activeCatalogContext.SaveChangesAsync(); var activeCatalogDTO = ColorCatalogDTO.FromObservable(ActiveCatalog); - _actionLogManager.InsertLog(ActionLogType.CatalogSaved, _authentication.CurrentUser, ActiveCatalog.Name, _catalogBeforeSave, activeCatalogDTO, "Catalog created using Machine Studio."); + _actionLogManager.InsertLog(ActionLogType.CatalogSaved, _authentication.CurrentUser, _catalogBeforeSave.Name, _catalogBeforeSave, activeCatalogDTO, "Catalog created using Machine Studio."); _catalogBeforeSave = activeCatalogDTO; await LoadCatalogs(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs index 8b235a13a..a641c87b6 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Developer/ViewModels/MainViewVM.cs @@ -1726,6 +1726,8 @@ namespace Tango.MachineStudio.Developer.ViewModels using (_notification.PushTaskItem("Saving Parameters Group...")) { + var processGroupBefore = ProcessParametersTablesGroupDTO.FromObservable(SelectedRML.GetActiveProcessGroup()); + using (var db = ObservablesContext.CreateDefault()) { var active_groups = db.ProcessParametersTablesGroups.Where(x => x.RmlGuid == SelectedRML.Guid && x.Active).ToList(); @@ -1753,8 +1755,6 @@ namespace Tango.MachineStudio.Developer.ViewModels tables.Add(newTable); } - var rmlBeforeDTO = RmlDTO.FromObservable(SelectedRML); - group.Active = true; group.ProcessParametersTables = tables.ToSynchronizedObservableCollection(); group.Rml = SelectedRML; @@ -1769,7 +1769,7 @@ namespace Tango.MachineStudio.Developer.ViewModels SelectedRML.ProcessParametersTablesGroups.Add(group); await SelectedRML.SaveAsync(_activeJobDbContext); - _actionLogManager.InsertLog(ActionLogType.RmlSaved, AuthenticationProvider.CurrentUser, SelectedRML.Name, rmlBeforeDTO, RmlDTO.FromObservable(SelectedRML), "Active process parameters changed from Machine Studio Research module."); + _actionLogManager.InsertLog(ActionLogType.RmlActiveProcessParametersChanged, AuthenticationProvider.CurrentUser, SelectedRML.Name, processGroupBefore, ProcessParametersTablesGroupDTO.FromObservable(SelectedRML.GetActiveProcessGroup()), "RML Active process parameters changed from Machine Studio Research module."); InvalidateLiquidFactorsAndProcessTables(); } @@ -2421,7 +2421,7 @@ namespace Tango.MachineStudio.Developer.ViewModels foreach (var job in SelectedJobs) { - _actionLogManager.InsertLog(ActionLogType.JobCreated, AuthenticationProvider.CurrentUser, job.Name, job, "Job created using Machine Studio."); + _actionLogManager.InsertLog(ActionLogType.JobCreated, AuthenticationProvider.CurrentUser, job.Name, job, "Job cloned using Machine Studio."); } CanWork = true; @@ -2664,7 +2664,7 @@ namespace Tango.MachineStudio.Developer.ViewModels foreach (var job in jobsToReport) { - _actionLogManager.InsertLog(ActionLogType.JobImported, AuthenticationProvider.CurrentUser, job.Name, job, "New job imported using Machine Studio."); + _actionLogManager.InsertLog(ActionLogType.JobImported, AuthenticationProvider.CurrentUser, job.Name, job, "Job imported using Machine Studio."); } IsFree = true; diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs index 7c95ce270..0a8780346 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.HardwareDesigner/ViewModels/MainViewVM.cs @@ -193,6 +193,8 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels _db.HardwareVersions.Add(hv); await _db.SaveChangesAsync(); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionImported, _authentication.CurrentUser, CurrentVersion.Name, CurrentVersion, "New hardware version imported using Machine Studio."); + RefreshVersions(); InvokeUI(() => @@ -436,7 +438,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels _db.SaveChanges(); var dtoAfter = HardwareVersionDTO.FromObservable(CurrentVersion); - _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionSaved, _authentication.CurrentUser, CurrentVersion.Name, _hwBeforeSave, dtoAfter, "Hardware Version saved using Machine Studio."); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionSaved, _authentication.CurrentUser, _hwBeforeSave.Name, _hwBeforeSave, dtoAfter, "Hardware Version saved using Machine Studio."); _hwBeforeSave = dtoAfter; RefreshVersions(); @@ -481,7 +483,7 @@ namespace Tango.MachineStudio.HardwareDesigner.ViewModels _db.HardwareVersions.Add(cloned); _db.SaveChanges(); - _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionCreated, _authentication.CurrentUser, cloned.Name, cloned, "New hardware version created (cloned) using Machine Studio."); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.HardwareVersionCreated, _authentication.CurrentUser, cloned.Name, cloned, "New hardware version cloned using Machine Studio."); RefreshVersions(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index fd31cd950..7b6ae7ef0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -25,14 +25,21 @@ using Tango.Core.Threading; using Tango.MachineStudio.RML.ViewModels; using Tango.Settings; using Tango.MachineStudio.RML.Models; +using Tango.BL.ActionLogs; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.DTO; namespace Tango.MachineStudio.MachineDesigner.ViewModels { public class MainViewVM : StudioViewModel { private INotificationProvider _notification; + private IActionLogManager _actionLogManager; + private IAuthenticationProvider _authentication; private ActionTimer _machines_action_timer; private ActionTimer _dispensers_action_timer; + private MachineDTO _machineBeforeSave; + private bool _isNewMachine; #region Properties @@ -233,10 +240,12 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels /// /// Initializes a new instance of the class. /// - public MainViewVM(INotificationProvider notification) + public MainViewVM(INotificationProvider notification, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { MachinesAdapter = new ObservablesStaticCollections(ObservablesContext.CreateDefault()); _notification = notification; + _authentication = authentication; + _actionLogManager = actionLogManager; _machines_action_timer = new ActionTimer(TimeSpan.FromMilliseconds(200)); _dispensers_action_timer = new ActionTimer(TimeSpan.FromMilliseconds(200)); @@ -428,6 +437,8 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels private async void LoadSelectedMachine(bool newMachine = false, bool clone = false, MachineVersion selectedVersion = null) { + _isNewMachine = false; + using (_notification.PushTaskItem("Loading machine details...")) { try @@ -462,9 +473,12 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels if (!newMachine) { ActiveMachine = (await new MachineBuilder(ActiveMachineAdapter.Context).Set(SelectedMachine.Guid).WithOrganization().WithConfiguration().WithSpools().BuildAsync()); + _machineBeforeSave = MachineDTO.FromObservable(ActiveMachine); + if (clone) { + _isNewMachine = true; ActiveMachine = ActiveMachine.Clone(); ActiveMachine.Name = ""; ActiveMachine.SerialNumber = ""; @@ -476,6 +490,8 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } else { + _isNewMachine = true; + if (selectedVersion == null) { ActiveMachine = new Machine(); @@ -668,16 +684,25 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels ActiveMachine.ConfigurationGuid = ActiveMachine.Configuration.Guid; ActiveMachine.LastUpdated = DateTime.UtcNow; - ActiveMachine.ProductionDate = DateTime.UtcNow; ActiveMachine.SiteGuid = SelectedSite == null ? null : (SelectedSite.ID == -1 ? null : SelectedSite.Guid); ColorCalibrationViewVM.Save(); var hwConfig = HardwareConfigurationViewVM.GetResultingHardwareConfiguration(); ActiveMachine.Configuration.SetHardwareConfiguration(hwConfig); - await ActiveMachineAdapter.Context.SaveChangesAsync(); + if (_isNewMachine) + { + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineCreated, _authentication.CurrentUser, ActiveMachine.Name, ActiveMachine, "New machine created using Machine Studio."); + } + else + { + var machineAfterDTO = MachineDTO.FromObservable(ActiveMachine); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineSaved, _authentication.CurrentUser, _machineBeforeSave.Name, _machineBeforeSave, machineAfterDTO, "Machine saved using Machine Studio."); + _machineBeforeSave = machineAfterDTO; + } + if (SelectedMachine != null) { await SelectedMachine.Reload(MachinesAdapter.Context); @@ -725,6 +750,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels IsFree = false; await SelectedMachine.DeleteCascadeAsync(MachinesAdapter.Context); MachinesAdapter.Context.Machines.Remove(SelectedMachine); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.MachineDeleted, _authentication.CurrentUser, SelectedMachine.Name, SelectedMachine, "Machine deleted using Machine Studio."); } catch (Exception ex) { diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs index 9939e4876..527159aa5 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.RML/ViewModels/MainViewVM.cs @@ -21,12 +21,18 @@ using Tango.MachineStudio.RML.Views; using Tango.PMR.ColorLab; using System.Data.Entity; using Tango.Core.ExtensionMethods; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.ActionLogs; +using Tango.BL.DTO; namespace Tango.MachineStudio.RML.ViewModels { public class MainViewVM : StudioViewModel { private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; + private RmlDTO _rmlBeforeSave; private ObservablesContext _rmls_context; private ObservablesContext _active_context; @@ -185,9 +191,11 @@ namespace Tango.MachineStudio.RML.ViewModels public RelayCommand ImportRMLFileCommand { get; set; } - public MainViewVM(INotificationProvider notificationProvider) + public MainViewVM(INotificationProvider notificationProvider, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { _notification = notificationProvider; + _authentication = authentication; + _actionLogManager = actionLogManager; ManageRmlCommand = new RelayCommand(() => LoadActiveRML(SelectedRML.Guid), () => SelectedRML != null); RemoveRmlCommand = new RelayCommand(RemoveSelectedRml, () => SelectedRML != null); CloneRmlCommand = new RelayCommand(CloneSelectedRml, () => SelectedRML != null); @@ -334,6 +342,8 @@ namespace Tango.MachineStudio.RML.ViewModels LiquidTypesRmls = LiquidTypesRmls, }; + _rmlBeforeSave = RmlDTO.FromObservable(ActiveRML); + View.NavigateTo(RmlNavigationView.RmlView); InvalidateRelayCommands(); @@ -423,6 +433,9 @@ namespace Tango.MachineStudio.RML.ViewModels _active_context.ProcessParametersTables.Add(group.ProcessParametersTables[0]); _active_context.Rmls.Add(rml); await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, rml.Name, rml, "Rml created using Machine Studio."); + LoadActiveRML(rml.Guid); IsFree = true; @@ -441,6 +454,9 @@ namespace Tango.MachineStudio.RML.ViewModels try { await SelectedRML.DeleteCascadeAsync(_rmls_context); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlDeleted, _authentication.CurrentUser, SelectedRML.Name, SelectedRML, "RML deleted from Machine Studio."); + LoadRmls(); } catch (Exception ex) @@ -504,6 +520,8 @@ namespace Tango.MachineStudio.RML.ViewModels context.Rmls.Add(cloned); await context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlCreated, _authentication.CurrentUser, cloned.Name, cloned, "RML cloned from Machine Studio."); } LoadRmls(); @@ -665,7 +683,13 @@ namespace Tango.MachineStudio.RML.ViewModels } } + var rmlAfter = RmlDTO.FromObservable(ActiveRML); + await _active_context.SaveChangesAsync(); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlSaved, _authentication.CurrentUser, _rmlBeforeSave.Name, _rmlBeforeSave, rmlAfter, "RML saved using Machine Studio."); + + _rmlBeforeSave = rmlAfter; } } catch (Exception ex) @@ -804,6 +828,8 @@ namespace Tango.MachineStudio.RML.ViewModels var rmlFile = await Rml.FromRmlFile(db, json); db.Rmls.Add(rmlFile); + + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.RmlImported, _authentication.CurrentUser, rmlFile.Name, rmlFile, "RML imported from Machine Studio."); } await db.SaveChangesAsync(); diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs index 486c8b46f..bcbcb6d16 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/MainViewVM.cs @@ -5,10 +5,12 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using Tango.BL; +using Tango.BL.ActionLogs; using Tango.BL.Entities; using Tango.Core.Commands; using Tango.Core.Threading; using Tango.MachineStudio.Common; +using Tango.MachineStudio.Common.Authentication; using Tango.MachineStudio.Common.Notifications; using Tango.MachineStudio.Sites.Contracts; using Tango.MachineStudio.Sites.Models; @@ -19,6 +21,8 @@ namespace Tango.MachineStudio.Sites.ViewModels { private ObservablesContext _db; private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; private ActionTimer _filter_timer; private List _sites; @@ -57,9 +61,11 @@ namespace Tango.MachineStudio.Sites.ViewModels public RelayCommand BackToSitesCommand { get; set; } - public MainViewVM(INotificationProvider notificationProvider) + public MainViewVM(INotificationProvider notificationProvider, IAuthenticationProvider authentication, IActionLogManager actionLogManager) { _notification = notificationProvider; + _authentication = authentication; + _actionLogManager = actionLogManager; _filter_timer = new ActionTimer(TimeSpan.FromMilliseconds(500)); ManageSiteCommand = new RelayCommand(() => LoadSelectedSite(), () => SelectedSite != null); @@ -82,6 +88,7 @@ namespace Tango.MachineStudio.Sites.ViewModels var site = _db.Sites.SingleOrDefault(x => x.Guid == SelectedSite.Guid); site.Delete(_db); _db.SaveChanges(); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.SiteDeleted, _authentication.CurrentUser, site.Name, site, "Site deleted using Machine Studio."); Sites.Remove(SelectedSite); LoadSites(); }); @@ -110,7 +117,7 @@ namespace Tango.MachineStudio.Sites.ViewModels IsFree = false; SiteDetailsViewVM = new SiteDetailsViewVM(); SiteDetailsViewVM.Saved += SiteDetailsViewVM_Saved; - await SiteDetailsViewVM.Init(SelectedSite?.Guid, _notification, true, name); + await SiteDetailsViewVM.Init(SelectedSite?.Guid, _notification, _authentication, _actionLogManager, true, name); View.NavigateTo(SitesNavigationView.SiteDetailsView); } } @@ -134,7 +141,7 @@ namespace Tango.MachineStudio.Sites.ViewModels IsFree = false; SiteDetailsViewVM = new SiteDetailsViewVM(); SiteDetailsViewVM.Saved += SiteDetailsViewVM_Saved; - await SiteDetailsViewVM.Init(SelectedSite.Guid, _notification, false); + await SiteDetailsViewVM.Init(SelectedSite.Guid, _notification, _authentication, _actionLogManager, false); View.NavigateTo(SitesNavigationView.SiteDetailsView); } } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs index 0e4dcbb47..73d4c49cb 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.Sites/ViewModels/SiteDetailsViewVM.cs @@ -10,6 +10,9 @@ using Tango.SharedUI; using Tango.SharedUI.Components; using System.Data.Entity; using Tango.MachineStudio.Common.Notifications; +using Tango.MachineStudio.Common.Authentication; +using Tango.BL.ActionLogs; +using Tango.BL.DTO; namespace Tango.MachineStudio.Sites.ViewModels { @@ -17,6 +20,10 @@ namespace Tango.MachineStudio.Sites.ViewModels { private ObservablesContext _db; private INotificationProvider _notification; + private IAuthenticationProvider _authentication; + private IActionLogManager _actionLogManager; + private bool _isNew; + private SiteDTO _siteBeforeSave; public event EventHandler Saved; @@ -69,9 +76,11 @@ namespace Tango.MachineStudio.Sites.ViewModels SaveCommand = new RelayCommand(Save, () => IsFree); } - public async Task Init(String siteGuid, INotificationProvider notification, bool isNew, string newSiteName = null) + public async Task Init(String siteGuid, INotificationProvider notification, IAuthenticationProvider authentication, IActionLogManager actionLogManager, bool isNew, string newSiteName = null) { _notification = notification; + _authentication = authentication; + _actionLogManager = actionLogManager; _db = ObservablesContext.CreateDefault(); Organizations = await _db.Organizations.ToListAsync(); @@ -82,9 +91,12 @@ namespace Tango.MachineStudio.Sites.ViewModels Site.Name = newSiteName; Site.Description = "My site description"; _db.Sites.Add(Site); + + _isNew = true; } else { + _isNew = false; Site = await _db.Sites.SingleOrDefaultAsync(x => x.Guid == siteGuid); } @@ -100,6 +112,8 @@ namespace Tango.MachineStudio.Sites.ViewModels Catalogs = new SelectedObjectCollection(catalogs.ToObservableCollection(), catalogs.Where(catalog => site_catalogs.Exists(siteCatalog => siteCatalog.CatalogGuid == catalog.Guid)).ToObservableCollection()); SelectedOrganization = Organizations.SingleOrDefault(x => x.Guid == Site.OrganizationGuid); + + _siteBeforeSave = SiteDTO.FromObservable(Site, site_rmls, site_catalogs, SelectedOrganization.Name); } private async void Save() @@ -121,20 +135,38 @@ namespace Tango.MachineStudio.Sites.ViewModels var site_rmls = await _db.SitesRmls.Where(x => x.SiteGuid == Site.Guid).ToListAsync(); var site_catalogs = await _db.SitesCatalogs.Where(x => x.SiteGuid == Site.Guid).ToListAsync(); - _db.SitesRmls.RemoveRange(site_rmls); - _db.SitesCatalogs.RemoveRange(site_catalogs); + //_db.SitesRmls.RemoveRange(site_rmls); + //_db.SitesCatalogs.RemoveRange(site_catalogs); + + //Remove site rmls. + site_rmls.ToList().Where(x => !Rmls.SynchedSource.ToList().Exists(y => y.Guid == x.RmlGuid)).ToList().ForEach(x => _db.SitesRmls.Remove(x)); + site_catalogs.ToList().Where(x => !Catalogs.SynchedSource.ToList().Exists(y => y.Guid == x.CatalogGuid)).ToList().ForEach(x => _db.SitesCatalogs.Remove(x)); - foreach (var selectedRml in Rmls.SynchedSource) + foreach (var selectedRml in Rmls.SynchedSource.Where(x => !site_rmls.Exists(y => y.RmlGuid == x.Guid))) { _db.SitesRmls.Add(new SitesRml() { SiteGuid = Site.Guid, RmlGuid = selectedRml.Guid }); } - foreach (var selectedCatalog in Catalogs.SynchedSource) + foreach (var selectedCatalog in Catalogs.SynchedSource.Where(x => !site_catalogs.Exists(y => y.CatalogGuid == x.Guid))) { _db.SitesCatalogs.Add(new SitesCatalog() { SiteGuid = Site.Guid, CatalogGuid = selectedCatalog.Guid }); } await _db.SaveChangesAsync(); + + var final_site_rmls = _db.SitesRmls.ToList(); + var final_site_catalogs = _db.SitesCatalogs.ToList(); + + if (_isNew) + { + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.SiteCreated, _authentication.CurrentUser, Site.Name, Site, "Site created using Machine Studio."); + } + else + { + SiteDTO siteAfter = SiteDTO.FromObservable(Site, final_site_rmls, final_site_catalogs, SelectedOrganization.Name); + _actionLogManager.InsertLog(BL.Enumerations.ActionLogType.SiteSaved, _authentication.CurrentUser, _siteBeforeSave.Name, _siteBeforeSave, siteAfter, "Site saved using Machine Studio."); + _siteBeforeSave = siteAfter; + } } _db.Dispose(); Saved?.Invoke(this, new EventArgs()); diff --git a/Software/Visual_Studio/Tango.BL/DTO/CatDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/CatDTO.cs index 43d24848b..b5dc8e264 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/CatDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/CatDTO.cs @@ -4,11 +4,21 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.BL.DTO { public class CatDTO : CatDTOBase { + [ObservableDTOProperty(MapsTo = nameof(Cat.LiquidType) + "." + nameof(Cat.LiquidType.Name))] + public String LiquidTypeName { get; set; } + [ObservableDTOProperty(MapsTo = nameof(Cat.Rml) + "." + nameof(Cat.Rml.Name))] + public String RmlName { get; set; } + + protected override string OnGetActionLogName() + { + return $"'{RmlName}' => '{LiquidTypeName}' Calibration"; + } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/ConfigurationDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/ConfigurationDTO.cs index 605a905db..75049fa88 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/ConfigurationDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/ConfigurationDTO.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.BL.DTO { @@ -11,9 +12,29 @@ namespace Tango.BL.DTO { public List IdsPacks { get; set; } + [ObservableDTOProperty(MapsTo = nameof(Configuration.ApplicationDisplayPanelVersion) + "." + nameof(Configuration.ApplicationDisplayPanelVersion.Name))] + public String ApplicationDisplayPanelVersionName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(Configuration.ApplicationFirmwareVersion) + "." + nameof(Configuration.ApplicationFirmwareVersion.Name))] + public String ApplicationFirmwareVersionName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(Configuration.ApplicationOsVersion) + "." + nameof(Configuration.ApplicationOsVersion.Name))] + public String ApplicationOsVersionName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(Configuration.EmbeddedFirmwareVersion) + "." + nameof(Configuration.EmbeddedFirmwareVersion.Name))] + public String EmbeddedFirmwareVersionName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(Configuration.HardwareVersion) + "." + nameof(Configuration.HardwareVersion.Name))] + public String HardwareVersionName { get; set; } + public ConfigurationDTO() { IdsPacks = new List(); } + + protected override string OnGetActionLogName() + { + return "Configuration"; + } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/IdsPackDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/IdsPackDTO.cs index 3ca1e798b..071eb8bdf 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/IdsPackDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/IdsPackDTO.cs @@ -4,15 +4,30 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.BL.DTO { public class IdsPackDTO : IdsPackDTOBase { - public CartridgeTypeDTO CartridgeType { get; set; } - public IdsPackFormulaDTO IdsPackFormula { get; set; } - public LiquidTypeDTO LiquidType { get; set; } - public MidTankTypeDTO MidTankType { get; set; } - public DispenserDTO Dispenser { get; set; } + [ObservableDTOProperty(MapsTo = nameof(IdsPack.CartridgeType) + "." + nameof(IdsPack.CartridgeType.Name))] + public String CartridgeTypeName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(IdsPack.IdsPackFormula) + "." + nameof(IdsPack.IdsPackFormula.Name))] + public String IdsPackFormulaName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(IdsPack.LiquidType) + "." + nameof(IdsPack.LiquidType.Name))] + public String LiquidTypeName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(IdsPack.MidTankType) + "." + nameof(IdsPack.MidTankType.Name))] + public String MidTankTypeName { get; set; } + + [ObservableDTOProperty(MapsTo = nameof(IdsPack.Dispenser) + "." + nameof(IdsPack.Dispenser.SerialNumber))] + public String DispenserSerialNumber { get; set; } + + protected override string OnGetActionLogName() + { + return $"IDS Pack '{PackIndex}'"; + } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/MachineDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/MachineDTO.cs index 41eca6693..43535074d 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/MachineDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/MachineDTO.cs @@ -9,6 +9,22 @@ namespace Tango.BL.DTO { public class MachineDTO : MachineDTOBase { + public ConfigurationDTO Configuration { get; set; } + //This is a bit more complicated to support. + //public List Cats { get; set; } + + public List Spools { get; set; } + + public MachineDTO() + { + //Cats = new List(); + Spools = new List(); + } + + protected override string OnGetActionLogName() + { + return $"Machine '{SerialNumber}'"; + } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/RmlDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/RmlDTO.cs index a221a760c..8931a4b3e 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/RmlDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/RmlDTO.cs @@ -4,6 +4,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.BL.DTO { @@ -13,6 +14,9 @@ namespace Tango.BL.DTO public List LiquidTypesRmls { get; set; } + [ObservableDTOProperty(MapsTo = nameof(Rml.Cct) + "." + nameof(Rml.Cct.FileName))] + public String CctFileName { get; set; } + public RmlDTO() { ProcessParametersTablesGroups = new List(); diff --git a/Software/Visual_Studio/Tango.BL/DTO/SiteDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/SiteDTO.cs index 320de2763..2ba9ca693 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/SiteDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/SiteDTO.cs @@ -4,11 +4,36 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.BL.DTO { public class SiteDTO : SiteDTOBase { + public List SiteRmls { get; set; } + public List SiteCatalogs { get; set; } + + public String OrganizationName { get; set; } + + public SiteDTO() + { + SiteRmls = new List(); + SiteCatalogs = new List(); + } + + public static SiteDTO FromObservable(Site observable, IEnumerable siteRmls, IEnumerable siteCatalogs, String organizationName) + { + SiteDTO dto = FromObservable(observable); + dto.OrganizationName = organizationName; + dto.SiteRmls = siteRmls.Select(x => SitesRmlDTO.FromObservable(x)).ToList(); + dto.SiteCatalogs = siteCatalogs.Select(x => SitesCatalogDTO.FromObservable(x)).ToList(); + return dto; + } + + protected override string OnGetActionLogName() + { + return $"Site '{Name}'"; + } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/SitesRmlDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/SitesRmlDTO.cs index 527d710d0..0a5089072 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/SitesRmlDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/SitesRmlDTO.cs @@ -4,11 +4,15 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.BL.DTO { public class SitesRmlDTO : SitesRmlDTOBase { - + protected override string OnGetActionLogName() + { + return $"RML '{RmlGuid}'"; + } } } diff --git a/Software/Visual_Studio/Tango.BL/DTO/SpoolDTO.cs b/Software/Visual_Studio/Tango.BL/DTO/SpoolDTO.cs index bf25d1e71..d6d79b1be 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/SpoolDTO.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/SpoolDTO.cs @@ -4,11 +4,18 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; namespace Tango.BL.DTO { public class SpoolDTO : SpoolDTOBase { + [ObservableDTOProperty(MapsTo = nameof(Spool.SpoolType) + "." + nameof(Spool.SpoolType.Name))] + public String SpoolTypeName { get; set; } + protected override string OnGetActionLogName() + { + return $"'{(SpoolTypeName != null ? SpoolTypeName : SpoolTypeGuid)}' Calibration"; + } } } diff --git a/Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs b/Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs index 5114538ef..76c790a9f 100644 --- a/Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs +++ b/Software/Visual_Studio/Tango.BL/Enumerations/ActionLogType.cs @@ -34,6 +34,8 @@ namespace Tango.BL.Enumerations HardwareVersionDeleted = 101, [Description("Hardware Version Saved")] HardwareVersionSaved = 102, + [Description("Hardware Version Imported")] + HardwareVersionImported = 103, //RML [Description("RML Created")] @@ -42,6 +44,10 @@ namespace Tango.BL.Enumerations RmlDeleted = 201, [Description("RML Saved")] RmlSaved = 202, + [Description("RML Imported")] + RmlImported = 203, + [Description("RML Active Process Parameters Changed")] + RmlActiveProcessParametersChanged = 204, //Jobs [Description("Job Created")] diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 10a732221..ade8f88bc 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -160,6 +160,8 @@ namespace Tango.MachineService.Controllers tangoUpdate.UpdateStatus = TangoUpdateStatuses.SetupStarted; db.TangoUpdates.Add(tangoUpdate); + machine.ProductionDate = DateTime.UtcNow; + db.SaveChanges(); _pendingUpdates.Add(new PPCPendingUpdate() -- cgit v1.3.1 From a4761335999936b8e1bd0091861b3b08ad3f6343 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Mon, 20 Jan 2020 13:11:40 +0200 Subject: Fixed main menu style. Fixed issues with machine prototype creation. Implemented "make prototype". --- .../ViewModels/HardwareConfigurationViewVM.cs | 23 ++++--- .../ViewModels/MainViewVM.cs | 73 ++++++++++++++++++++-- .../Views/MachineDetailsView.xaml | 2 +- .../Views/MachineSettingsView.xaml | 45 ++++++++----- .../Tango.MachineStudio.UI/Views/MainView.xaml | 2 +- .../Tango.BL/Entities/MachineVersion.cs | 23 ++++++- 6 files changed, 133 insertions(+), 35 deletions(-) (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs index 51d88c3f9..e29ba3b6f 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/HardwareConfigurationViewVM.cs @@ -92,16 +92,19 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { HardwareVersion hardwareVersion = configuration.HardwareVersion; - _hwConfig = configuration.GetHardwareConfiguration(); - - Collections.Clear(); - Collections.Add(CreateMotorsCollection(hardwareVersion)); - Collections.Add(CreateDancerCollection(hardwareVersion)); - Collections.Add(CreatePidCollection(hardwareVersion)); - Collections.Add(CreateWindersCollection(hardwareVersion)); - Collections.Add(CreateSpeedSensorsCollection(hardwareVersion)); - Collections.Add(CreateBlowersCollection(hardwareVersion)); - Collections.Add(CreateBreakSensorCollection(hardwareVersion)); + if (hardwareVersion != null) + { + _hwConfig = configuration.GetHardwareConfiguration(); + + Collections.Clear(); + Collections.Add(CreateMotorsCollection(hardwareVersion)); + Collections.Add(CreateDancerCollection(hardwareVersion)); + Collections.Add(CreatePidCollection(hardwareVersion)); + Collections.Add(CreateWindersCollection(hardwareVersion)); + Collections.Add(CreateSpeedSensorsCollection(hardwareVersion)); + Collections.Add(CreateBlowersCollection(hardwareVersion)); + Collections.Add(CreateBreakSensorCollection(hardwareVersion)); + } } private HardwareCollection CreateMotorsCollection(HardwareVersion hardwareVersion) diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index 7b6ae7ef0..8b0401dc7 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -228,6 +228,11 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels /// public RelayCommand ResetDeviceRegistrationCommand { get; set; } + /// + /// Gets or sets the make prototype command. + /// + public RelayCommand MakePrototypeCommand { get; set; } + #endregion #region Constructors @@ -261,6 +266,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels RemoveSpoolCommand = new RelayCommand(RemoveSpool, () => SelectedSpool != null); CloneMachineCommand = new RelayCommand(CloneMachine, () => SelectedMachine != null); ResetDeviceRegistrationCommand = new RelayCommand(ResetDeviceRegistration); + MakePrototypeCommand = new RelayCommand(MakePrototype); MachineUpdatesViewVM = new MachineUpdatesViewVM(_notification); TupViewVM = new TupViewVM(_notification); @@ -470,6 +476,8 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels ActiveMachineAdapter.MachineVersions = (await ActiveMachineAdapter.Context.MachineVersions.ToListAsync()).ToObservableCollection(); ActiveMachineAdapter.Organizations = (await ActiveMachineAdapter.Context.Organizations.ToListAsync()).ToObservableCollection(); + bool initHwConfig = true; + if (!newMachine) { ActiveMachine = (await new MachineBuilder(ActiveMachineAdapter.Context).Set(SelectedMachine.Guid).WithOrganization().WithConfiguration().WithSpools().BuildAsync()); @@ -500,8 +508,22 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } else { - ActiveMachine = selectedVersion.CreatePrototypeMachine(ActiveMachineAdapter.Context); - ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); + try + { + initHwConfig = false; + ActiveMachine = selectedVersion.CreatePrototypeMachine(ActiveMachineAdapter.Context); + ActiveMachineAdapter.Context.Machines.Add(ActiveMachine); + + HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); + var version = await new HardwareVersionBuilder(ActiveMachineAdapter.Context).Set(ActiveMachine.Configuration.HardwareVersionGuid).WithHardwareComponents().BuildAsync(); + HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); + } + catch (Exception ex) + { + _notification.ShowError($"Invalid machine version prototype.\n{ex.FlattenMessage()}"); + View.NavigateTo(MachineDesignerNavigationView.MachinesView); + return; + } } } @@ -516,8 +538,11 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels SelectedRML = ActiveMachineAdapter.Rmls.FirstOrDefault(), }; - HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); - HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); + if (initHwConfig) + { + HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); + HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); + } await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); TupViewVM.Init(ActiveMachine); @@ -549,6 +574,11 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { try { + if (HardwareConfigurationViewVM == null) + { + HardwareConfigurationViewVM = new HardwareConfigurationViewVM(_notification); + } + version = await new HardwareVersionBuilder(ActiveMachineAdapter.Context).Set(version.Guid).WithHardwareComponents().BuildAsync(); HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); } @@ -775,6 +805,41 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } + private async void MakePrototype() + { + if (ActiveMachine.MachineVersion == null) + { + _notification.ShowError("Machine version must be selected in order to make a prototype."); + return; + } + + if (_notification.ShowQuestion($"Are you sure you wish to make this machine configuration as a prototype for version '{ActiveMachine.MachineVersion.Name}' ?")) + { + using (_notification.PushTaskItem($"Making prototype machine for '{ActiveMachine.MachineVersion.Name}'...")) + { + try + { + IsFree = false; + + using (var db = ObservablesContext.CreateDefault()) + { + var machineVersion = await db.MachineVersions.SingleOrDefaultAsync(x => x.Guid == ActiveMachine.MachineVersionGuid); + await machineVersion.ApplyPrototypeMachine(ActiveMachine, db); + await db.SaveChangesAsync(); + } + } + catch (Exception ex) + { + _notification.ShowError($"Error making machine version prototype\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + } + } + #endregion private void CloneMachine() diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml index bcca83ca5..b3cef3083 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml @@ -23,7 +23,7 @@ - + - Device COM Port - - Auto Login @@ -109,7 +120,7 @@ - + diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml index 2d5a5c3aa..15f2a30e0 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/Views/MainView.xaml @@ -70,7 +70,7 @@ - + + @@ -33,12 +50,30 @@ - - - Please specify the machine version in order to prototype the new machine with default machine settings and configuartion. + + + Please specify the machine version in order to prototype the new machine with default machine settings and configuration. - + + + Serial Number + + + Name + + + + + Automatically generate 8 dispensers for this machine + (-1-8) + + + + + Dispenser max nl/cm + + diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml index b3cef3083..b2b770698 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MachineDetailsView.xaml @@ -5,11 +5,17 @@ xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:local="clr-namespace:Tango.MachineStudio.MachineDesigner.Views" xmlns:global="clr-namespace:Tango.MachineStudio.MachineDesigner" - xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes" + xmlns:converters="clr-namespace:Tango.SharedUI.Converters;assembly=Tango.SharedUI" xmlns:vm="clr-namespace:Tango.MachineStudio.MachineDesigner.ViewModels" xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> + + + + + @@ -61,10 +67,10 @@ - + - + diff --git a/Software/Visual_Studio/Tango.BL/Entities/MachineVersion.cs b/Software/Visual_Studio/Tango.BL/Entities/MachineVersion.cs index f9975cf32..3f386beb2 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/MachineVersion.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/MachineVersion.cs @@ -34,7 +34,8 @@ namespace Tango.BL.Entities .Ignore(() => machine.LoadedRmlGuid) .Ignore(() => machine.DeviceId) .Ignore(() => machine.DeviceName) - .Ignore(() => machine.IsDeviceRegistered), + .Ignore(() => machine.IsDeviceRegistered) + .Ignore(() => machine.SiteGuid), EntitySerializationFlags.IgnoreGuids | EntitySerializationFlags.IgnoreReferenceTypes); } @@ -56,7 +57,8 @@ namespace Tango.BL.Entities .Ignore(() => m.LoadedRmlGuid) .Ignore(() => m.DeviceId) .Ignore(() => m.DeviceName) - .Ignore(() => m.IsDeviceRegistered), + .Ignore(() => m.IsDeviceRegistered) + .Ignore(() => m.SiteGuid), EntitySerializationFlags.IgnoreGuids | EntitySerializationFlags.IgnoreReferenceTypes); -- cgit v1.3.1 From 287af6d4bed5333087cb9d702d20035b1ad9a326 Mon Sep 17 00:00:00 2001 From: Roy Ben-Shabat Date: Wed, 22 Jan 2020 16:38:48 +0200 Subject: Implemented team viewer join group. Prevent multiple power up dialogs from showing. Implement auto available dispenser assignment for machine creation. Sorting for machines and dispensers in Machine designer. Implemented new PPC factory reset with team viewer and device name change. Fixed "Exit To Shell" to open real explorer. Redesigned restarting system view. Updated power off animation. Updated loading animation. --- .../ViewModels/MachineUpdatesViewVM.cs | 2 + .../ViewModels/MainViewVM.cs | 60 +++++++++++++++------ .../Views/MainView.xaml | 2 +- .../ViewModels/SystemViewVM.cs | 37 +++++++++---- .../MachineSetup/MachineSetupManager.cs | 37 ++++++++----- .../OS/DefaultOperationSystemManager.cs | 22 ++++++++ .../Tango.PPC.Common/OS/IOperationSystemManager.cs | 11 ++++ .../DefaultRemoteAssistanceProvider.cs | 31 ++++++----- .../RemoteAssistance/IRemoteAssistanceProvider.cs | 3 +- .../PPC/Tango.PPC.Common/Tango.PPC.Common.csproj | 2 +- .../Tango.PPC.Common/Web/MachineSetupResponse.cs | 1 + .../PPC/Tango.PPC.UI/Images/loading_anim.gif | Bin 0 -> 798338 bytes .../PPC/Tango.PPC.UI/Images/power_off_2.gif | Bin 0 -> 32040 bytes .../PPCApplication/DefaultPPCApplicationManager.cs | 2 +- .../PPC/Tango.PPC.UI/Tango.PPC.UI.csproj | 4 +- .../PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs | 9 ++++ .../PPC/Tango.PPC.UI/Views/LoadingView.xaml | 11 ++-- .../PPC/Tango.PPC.UI/Views/MachineSetupView.xaml | 2 +- .../PPC/Tango.PPC.UI/Views/PowerOffView.xaml | 2 +- .../Tango.PPC.UI/Views/RestartingSystemView.xaml | 40 ++++++++++---- .../Tango.BL/ObservablesStaticCollections.cs | 40 +++++++------- .../Controllers/PPCController.cs | 3 +- 22 files changed, 224 insertions(+), 97 deletions(-) create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif create mode 100644 Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs index 41bcc2a87..616ad0a47 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MachineUpdatesViewVM.cs @@ -110,6 +110,8 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels DisplayMachineSetups = true; DisplayDatabaseUpdates = true; DisplaySynchronizations = true; + DisplayOfflineUpdates = true; + DisplayFirmwareUpgrades = true; RefreshCommand = new RelayCommand(Refresh, () => IsFree); } diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index 1bd790eb6..bd08e3e7c 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -298,7 +298,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { Task.Factory.StartNew(() => { - ActiveMachineAdapter.Dispensers = ActiveMachineAdapter.Context.Dispensers.Where(x => x.SerialNumber.ToLower().StartsWith(DispensersFilter.ToLower())).ToSynchronizedObservableCollection(); + ActiveMachineAdapter.Dispensers = ActiveMachineAdapter.Context.Dispensers.Where(x => x.SerialNumber.ToLower().StartsWith(DispensersFilter.ToLower())).OrderBy(x => x.SerialNumber).ToSynchronizedObservableCollection(); }); }); } @@ -545,32 +545,60 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels { for (int i = 0; i < 8; i++) { - Dispenser dispenser = new Dispenser(); - dispenser.SerialNumber = machineCreationDialogVM.SerialNumber + "-" + (i + 1); + var serial = machineCreationDialogVM.SerialNumber + "-" + (i + 1); + + var existingDispenser = await ActiveMachineAdapter.Context.Dispensers.Include(x => x.IdsPacks).SingleAsync(x => x.SerialNumber == serial); - if (newMachine) + if (existingDispenser != null) { - dispenser.NlPerPulse = machineCreationDialogVM.DispenserFactor; - dispenser.DispenserTypeGuid = ActiveMachineAdapter.DispenserTypes.First().Guid; + if (existingDispenser.IsInstalled) + { + _notification.ShowError($"Dispenser '{serial}' already exists. Cannot create machine."); + return; + } + else + { + if (!_notification.ShowErrorQuestion($"Dispenser '{serial}' already exists and is not installed. Do you wish to assign the existing dispenser to this machine?")) + { + return; + } + } } - else + + Dispenser dispenser = new Dispenser(); + + if (existingDispenser == null) { - var packBefore = machineConfigBeforeClone.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == i); + dispenser.SerialNumber = serial; - if (packBefore != null) + if (newMachine) { - dispenser.NlPerPulse = packBefore.Dispenser.NlPerPulse; - dispenser.DispenserTypeGuid = packBefore.Dispenser.DispenserType.Guid; + dispenser.NlPerPulse = machineCreationDialogVM.DispenserFactor; + dispenser.DispenserTypeGuid = ActiveMachineAdapter.DispenserTypes.First().Guid; } else { - continue; + var packBefore = machineConfigBeforeClone.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == i); + + if (packBefore != null) + { + dispenser.NlPerPulse = packBefore.Dispenser.NlPerPulse; + dispenser.DispenserTypeGuid = packBefore.Dispenser.DispenserType.Guid; + } + else + { + continue; + } } - } - dispenser.ProductionDate = DateTime.UtcNow; + dispenser.ProductionDate = DateTime.UtcNow; - ActiveMachineAdapter.Context.Dispensers.Add(dispenser); + ActiveMachineAdapter.Context.Dispensers.Add(dispenser); + } + else + { + dispenser = existingDispenser; + } var idsPack = ActiveMachine.Configuration.NoneEmptyIdsPacks.SingleOrDefault(x => x.PackIndex == i); @@ -950,7 +978,7 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels try { IsFree = false; - MachinesAdapter.Machines = MachinesAdapter.Context.Machines.Where(x => x.SerialNumber.StartsWith(Filter)).Include(x => x.Organization).Include(x => x.MachineVersion).ToSynchronizedObservableCollection(); + MachinesAdapter.Machines = MachinesAdapter.Context.Machines.Where(x => x.SerialNumber.StartsWith(Filter)).Include(x => x.Organization).Include(x => x.MachineVersion).OrderBy(x => x.SerialNumber).ToSynchronizedObservableCollection(); } catch { diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml index bc9b038dc..833086bf0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/Views/MainView.xaml @@ -9,7 +9,7 @@ xmlns:controls="clr-namespace:Tango.SharedUI.Controls;assembly=Tango.SharedUI" mc:Ignorable="d" d:DesignHeight="1080" d:DesignWidth="1920" Background="Transparent" d:DataContext="{d:DesignInstance Type=vm:MainViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.MainViewVM}"> - + diff --git a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Technician/ViewModels/SystemViewVM.cs b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Technician/ViewModels/SystemViewVM.cs index f3ffcda14..e0b8d278b 100644 --- a/Software/Visual_Studio/PPC/Modules/Tango.PPC.Technician/ViewModels/SystemViewVM.cs +++ b/Software/Visual_Studio/PPC/Modules/Tango.PPC.Technician/ViewModels/SystemViewVM.cs @@ -14,12 +14,14 @@ using Tango.PPC.Common; using Tango.PPC.Common.OS; using Tango.Settings; using System.Data.Entity; +using Tango.PPC.Common.UWF; namespace Tango.PPC.Technician.ViewModels { public class SystemViewVM : PPCViewModel { private IOperationSystemManager _os; + private IUnifiedWriteFilterManager _uwf; private Timer _statsTimer; private bool _resettingDevice; @@ -82,9 +84,10 @@ namespace Tango.PPC.Technician.ViewModels public RelayCommand ExitToExplorerCommand { get; set; } - public SystemViewVM(IOperationSystemManager os) + public SystemViewVM(IOperationSystemManager os, IUnifiedWriteFilterManager uwf) { _os = os; + _uwf = uwf; CPU = 0; RAM = 0; @@ -118,11 +121,30 @@ namespace Tango.PPC.Technician.ViewModels private async void FactoryReset() { - if (await NotificationProvider.ShowQuestion("Are you sure you want to reset this device and back to factory settings?")) + if (await NotificationProvider.ShowQuestion("Are you sure you want to reset this device back to factory settings?")) { Settings.ApplicationState = ApplicationStates.FactoryRestore; Settings.Save(); - ApplicationManager.Restart(); + try + { + NotificationProvider.SetGlobalBusyMessage("Disabling write filter protection..."); + await _uwf.Disable(); + await Task.Delay(2000); + NotificationProvider.ReleaseGlobalBusyMessage(); + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.RestartingSystemView); + await Task.Delay(4000); + _os.Restart(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error executing factory reset."); + NotificationProvider.ReleaseGlobalBusyMessage(); + await NotificationProvider.ShowError($"Error executing factory reset.\n{ex.FlattenMessage()}"); + } + finally + { + NotificationProvider.ReleaseGlobalBusyMessage(); + } } } @@ -138,6 +160,8 @@ namespace Tango.PPC.Technician.ViewModels { if (await NotificationProvider.ShowQuestion("Are you sure you want to restart the device?")) { + await NavigationManager.NavigateTo(Common.Navigation.NavigationView.RestartingSystemView); + await Task.Delay(4000); _os.Restart(); } } @@ -146,12 +170,7 @@ namespace Tango.PPC.Technician.ViewModels { if (await NotificationProvider.ShowQuestion("Close the application and start OS shell?")) { - Process.Start(new ProcessStartInfo() - { - UseShellExecute = true, - FileName = "explorer.exe", - }); - + _os.OpenShell(); ApplicationManager.ShutDown(); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs index 29daedb4c..2177efecc 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/MachineSetup/MachineSetupManager.cs @@ -235,10 +235,21 @@ namespace Tango.PPC.Common.MachineSetup Login(serialNumber).Wait(); + String deviceName = $"Tango-{serialNumber}-{settings.DeploymentSlot.ToString()}"; + LogManager.Log($"Settings device name: '{deviceName}'..."); + try + { + await _windows_manager.SetDeviceName(deviceName); + } + catch + { + throw new IOException("Error setting device name."); + } + MachineSetupRequest request = new MachineSetupRequest(); request.SerialNumber = serialNumber; request.DeviceID = await _windows_manager.GetDeviceId(); - request.DeviceName = await _windows_manager.GetDeviceName(); + request.DeviceName = deviceName; try { @@ -278,20 +289,20 @@ namespace Tango.PPC.Common.MachineSetup UpdateProgress("Activating operation system license", "Activating..."); await _windows_manager.Activate(setup_response.OSKey); } + } - if (setup_response.SetupRemoteAssistance) - { - LogManager.Log("Installing remote assistance..."); - UpdateProgress("Installing remote assistance", "Installing..."); - await _remoteAssistance.InstallRemoteAssistance(serialNumber, settings.DeploymentSlot.ToString()); - } + if (setup_response.SetupRemoteAssistance) + { + LogManager.Log("Installing remote assistance..."); + UpdateProgress("Installing remote assistance", "Installing..."); + await _remoteAssistance.InstallRemoteAssistance(serialNumber, setup_response.Organization, settings.DeploymentSlot.ToString()); + } - if (setup_response.SetupUWF) - { - LogManager.Log("Activating unified write filter..."); - UpdateProgress("Activating disk protection", "Activating..."); - await _uwf.Setup(); - } + if (setup_response.SetupUWF) + { + LogManager.Log("Activating unified write filter..."); + UpdateProgress("Activating disk protection", "Activating..."); + await _uwf.Setup(); } //Create temporary folders for packages. diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/DefaultOperationSystemManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/DefaultOperationSystemManager.cs index 2164a71c3..32fd74646 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/DefaultOperationSystemManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/DefaultOperationSystemManager.cs @@ -232,5 +232,27 @@ namespace Tango.PPC.Common.OS return Environment.MachineName; }); } + + /// + /// Sets the device host name. + /// + /// + public async Task SetDeviceName(String name) + { + var command = new CmdCommand("wmic", $"computersystem where caption='{Environment.MachineName}' rename '{name}'"); + await command.Run(); + } + + /// + /// Opens the operating system shell (explorer). + /// + public void OpenShell() + { + Process.Start(new ProcessStartInfo() + { + FileName = @"C:\Windows\Sysnative\cmd.exe", + Arguments = @"/c start /B explorer.exe" + }); + } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/IOperationSystemManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/IOperationSystemManager.cs index 3e24ffe72..4faef33f9 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/IOperationSystemManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/OS/IOperationSystemManager.cs @@ -56,6 +56,12 @@ namespace Tango.PPC.Common.OS /// Task GetDeviceName(); + /// + /// Sets the device host name. + /// + /// + Task SetDeviceName(String name); + /// /// Restarts the system. /// @@ -67,5 +73,10 @@ namespace Tango.PPC.Common.OS /// /// void Shutdown(); + + /// + /// Opens the operating system shell (explorer). + /// + void OpenShell(); } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/DefaultRemoteAssistanceProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/DefaultRemoteAssistanceProvider.cs index 65327e705..c266ba7c0 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/DefaultRemoteAssistanceProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/DefaultRemoteAssistanceProvider.cs @@ -96,8 +96,12 @@ namespace Tango.PPC.Common.RemoteAssistance /// Installs the remote assistance. /// /// The machine serial number. + /// The remote assistance group. + /// The machine working environment. /// - public async Task InstallRemoteAssistance(String machineSerialNumber, String environment) + /// + /// The remote assistance service was installed but could not be found. + public async Task InstallRemoteAssistance(String machineSerialNumber, String group, String environment) { try { @@ -106,26 +110,21 @@ namespace Tango.PPC.Common.RemoteAssistance throw new FileNotFoundException($"The remote assistance installer file could not be found at {_installer_path}."); } - if (!(await IsRemoteAssistanceInstalled())) - { - CmdCommand command = new CmdCommand("msiexec.exe", $"/i \"{_installer_path}\" /qn CUSTOMCONFIGID=ke43ann APITOKEN=4765529-gon1LwO1N1TTrlLI21ji ASSIGNMENTOPTIONS=\" --reassign --alias {"TANGO-" + machineSerialNumber}-{environment} --grant-easy-access\""); - command.Timeout = TimeSpan.FromSeconds(30); - await command.Run(); + String q = "\""; + //CmdCommand command = new CmdCommand("msiexec.exe", $"/i \"{_installer_path}\" /qn CUSTOMCONFIGID=ke43ann APITOKEN=4765529-gon1LwO1N1TTrlLI21ji ASSIGNMENTOPTIONS=\" --reassign --alias {"TANGO-" + machineSerialNumber}-{environment} --grant-easy-access\""); + CmdCommand command = new CmdCommand("msiexec.exe", $"/i {q}{_installer_path}{q} /qn CUSTOMCONFIGID=ke43ann APITOKEN=4765529-gon1LwO1N1TTrlLI21ji ASSIGNMENTOPTIONS={q} --group {q}{q} {group} {q}{q} --reassign --alias TANGO-{machineSerialNumber}-{environment} --grant-easy-access{q}"); + command.Timeout = TimeSpan.FromSeconds(30); + await command.Run(); - bool exist = await IsRemoteAssistanceInstalled(); + bool exist = await IsRemoteAssistanceInstalled(); - if (exist) - { - await DisableRemoteAssistance(); - } - else - { - throw new ApplicationException("The remote assistance service was installed but could not be found."); - } + if (exist) + { + await DisableRemoteAssistance(); } else { - LogManager.Log("Remote assistance is already installed."); + throw new ApplicationException("The remote assistance service was installed but could not be found."); } } catch (Exception ex) diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/IRemoteAssistanceProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/IRemoteAssistanceProvider.cs index 3d3b4e532..3b7d489e6 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/IRemoteAssistanceProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/RemoteAssistance/IRemoteAssistanceProvider.cs @@ -32,8 +32,9 @@ namespace Tango.PPC.Common.RemoteAssistance /// Installs the remote assistance. /// /// The machine serial number. + /// The remote assistance group. /// The machine working environment. /// - Task InstallRemoteAssistance(String machineSerialNumber, String environment); + Task InstallRemoteAssistance(String machineSerialNumber, String group, String environment); } } 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 7142f461b..6eda39722 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 @@ -421,7 +421,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs index a642eddf2..f5d03c6ce 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Web/MachineSetupResponse.cs @@ -31,5 +31,6 @@ namespace Tango.PPC.Common.Web public bool SetupFPGA { get; set; } public bool IsDemo { get; set; } public String DeviceComPort { get; set; } + public String Organization { get; set; } } } diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif new file mode 100644 index 000000000..793007cc4 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/loading_anim.gif differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif new file mode 100644 index 000000000..867107140 Binary files /dev/null and b/Software/Visual_Studio/PPC/Tango.PPC.UI/Images/power_off_2.gif differ diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs index 149fb549f..003938303 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/PPCApplication/DefaultPPCApplicationManager.cs @@ -242,7 +242,7 @@ namespace Tango.PPC.UI.PPCApplication { LogManager.Log("Application started with '-update_ok' startup arguments. The application has been successfully updated."); - if (settings.ApplicationState == ApplicationStates.PreSetup) + if (settings.ApplicationState == ApplicationStates.PreSetup || settings.ApplicationState == ApplicationStates.FactoryRestore) { isAfterSetup = true; LogManager.Log("System restart is required."); diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj index eef669d4f..467b68d8b 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Tango.PPC.UI.csproj @@ -428,6 +428,8 @@ + + @@ -691,7 +693,7 @@ if $(ConfigurationName) == Debug copy /Y "$(TargetDir)Packages" "$(TargetDir)" - + \ No newline at end of file diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs index f78a7f334..5c518f60d 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MainViewVM.cs @@ -31,6 +31,7 @@ namespace Tango.PPC.UI.ViewModels public class MainViewVM : PPCViewModel { private DispatcherTimer _date_timer; + private bool _isPowerUpDialogShown; private DateTime _currentDateTime; /// @@ -100,6 +101,12 @@ namespace Tango.PPC.UI.ViewModels private async void MachineOperator_PowerUpStarted(object sender, EventArgs e) { + if (_isPowerUpDialogShown) + { + LogManager.Log("Power up detected but power up dialog is already shown. Skipping..."); + return; + } + LogManager.Log("Power up detected, showing power up screen..."); if (!Settings.DisplayPowerUpScreen) @@ -136,7 +143,9 @@ namespace Tango.PPC.UI.ViewModels InvokeUI(async () => { + _isPowerUpDialogShown = true; await NotificationProvider.ShowDialog(vm); + _isPowerUpDialogShown = false; await Task.Factory.StartNew(() => { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml index 79d9cd54b..a917695af 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/LoadingView.xaml @@ -10,9 +10,9 @@ xmlns:touch="clr-namespace:Tango.Touch.Controls;assembly=Tango.Touch" xmlns:local="clr-namespace:Tango.PPC.UI.Views" mc:Ignorable="d" - d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:LoadingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoadingView}"> + d:DesignHeight="1280" d:DesignWidth="800" Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:LoadingViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.LoadingView}"> - + - - - + + + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml index 9437caac9..40b296d1e 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/MachineSetupView.xaml @@ -25,7 +25,7 @@ - + diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml index 9762ef621..22952a827 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/PowerOffView.xaml @@ -11,7 +11,7 @@ d:DesignHeight="1280" d:DesignWidth="800" Background="{StaticResource TangoPrimaryBackgroundBrush}" d:DataContext="{d:DesignInstance Type=vm:PowerOffViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.PowerOffViewVM}"> - + Machine is turning Off Do not unplug machine while turning off ABORT diff --git a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml index 996b1788d..dd4d2f5d5 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml +++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/Views/RestartingSystemView.xaml @@ -10,17 +10,37 @@ mc:Ignorable="d" d:DesignHeight="1280" d:DesignWidth="800" d:DataContext="{d:DesignInstance Type=vm:RestartingSystemViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.RestartingSystemViewVM}" Background="{StaticResource TangoPrimaryBackgroundBrush}"> - - - - - Setup completed. - - - - Restarting the system for the last time... - + + + + + + + + + diff --git a/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs b/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs index 1b45e959d..c12b622a4 100644 --- a/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs +++ b/Software/Visual_Studio/Tango.BL/ObservablesStaticCollections.cs @@ -56,73 +56,73 @@ namespace Tango.BL { if (!_initialized) { - progressLog.Invoke("Loading static collections..."); + progressLog?.Invoke("Loading static collections..."); db = ObservablesContext.CreateDefault(); WindingMethods = db.WindingMethods.ToObservableCollection(); - progressLog.Invoke("Loading color spaces..."); + progressLog?.Invoke("Loading color spaces..."); ColorSpaces = db.ColorSpaces.ToObservableCollection(); - progressLog.Invoke("Loading spools..."); + progressLog?.Invoke("Loading spools..."); SpoolTypes = db.SpoolTypes.ToObservableCollection(); - progressLog.Invoke("Loading event..."); + progressLog?.Invoke("Loading event..."); EventTypes = db.EventTypes.ToObservableCollection(); - progressLog.Invoke("Loading blowers..."); + progressLog?.Invoke("Loading blowers..."); HardwareBlowerTypes = db.HardwareBlowerTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); //HardwareBlowers = db.HardwareBlowers.ToObservableCollection(); - progressLog.Invoke("Loading break sensors..."); + progressLog?.Invoke("Loading break sensors..."); HardwareBreakSensorTypes = db.HardwareBreakSensorTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); //HardwareBreakSensors = db.HardwareBreakSensors.ToObservableCollection(); - progressLog.Invoke("Loading dancers..."); + progressLog?.Invoke("Loading dancers..."); HardwareDancerTypes = db.HardwareDancerTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); //HardwareDancers = db.HardwareDancers.ToObservableCollection(); - progressLog.Invoke("Loading motors..."); + progressLog?.Invoke("Loading motors..."); HardwareMotorTypes = db.HardwareMotorTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); //HardwareMotors = db.HardwareMotors.ToObservableCollection(); - progressLog.Invoke("Loading pid controls..."); + progressLog?.Invoke("Loading pid controls..."); HardwarePidControlTypes = db.HardwarePidControlTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); //HardwarePidControls = db.HardwarePidControls.ToObservableCollection(); - progressLog.Invoke("Loading speed sensors..."); + progressLog?.Invoke("Loading speed sensors..."); HardwareSpeedSensorTypes = db.HardwareSpeedSensorTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); //HardwareSpeedSensors = db.HardwareSpeedSensors.ToObservableCollection(); - progressLog.Invoke("Loading winders..."); + progressLog?.Invoke("Loading winders..."); HardwareWinderTypes = db.HardwareWinderTypes.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); //HardwareWinders = db.HardwareWinders.ToObservableCollection(); - progressLog.Invoke("Loading tech controllers..."); + progressLog?.Invoke("Loading tech controllers..."); TechControllers = db.TechControllers.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - progressLog.Invoke("Loading tech dispensers..."); + progressLog?.Invoke("Loading tech dispensers..."); TechDispensers = db.TechDispensers.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - progressLog.Invoke("Loading tech io's..."); + progressLog?.Invoke("Loading tech io's..."); TechIos = db.TechIos.ToObservableCollection(); - progressLog.Invoke("Loading tech monitors..."); + progressLog?.Invoke("Loading tech monitors..."); TechMonitors = db.TechMonitors.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - progressLog.Invoke("Loading tech valves..."); + progressLog?.Invoke("Loading tech valves..."); TechValves = db.TechValves.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - progressLog.Invoke("Loading tech heaters..."); + progressLog?.Invoke("Loading tech heaters..."); TechHeaters = db.TechHeaters.ToList().OrderByAlphaNumeric(x => x.Description).ToObservableCollection(); - progressLog.Invoke("Loading machines..."); + progressLog?.Invoke("Loading machines..."); Machines = db.Machines.Include(x => x.Organization).ToObservableCollection(); - progressLog.Invoke("Loading users..."); + progressLog?.Invoke("Loading users..."); Users = db.Users.Where(x => !x.Deleted).Include(x => x.Contact).ToObservableCollection(); - progressLog.Invoke("Loading machine versions..."); + progressLog?.Invoke("Loading machine versions..."); MachineVersions = db.MachineVersions.ToObservableCollection(); //Load later... diff --git a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs index 1bb025217..6ac2e3657 100644 --- a/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs +++ b/Software/Visual_Studio/Web/Tango.MachineService/Controllers/PPCController.cs @@ -71,7 +71,7 @@ namespace Tango.MachineService.Controllers { String machine_guid = RequestToken.Object.MachineGuid; - var machine = db.Machines.SingleOrDefault(x => x.Guid == machine_guid); + var machine = db.Machines.Include(x => x.Organization).SingleOrDefault(x => x.Guid == machine_guid); if (machine == null) { @@ -151,6 +151,7 @@ namespace Tango.MachineService.Controllers response.SetupUWF = machine.SetupUwf; response.SetupFirmware = machine.SetupFirmware; response.IsDemo = machine.IsDemo; + response.Organization = machine.Organization.Name; TangoUpdate tangoUpdate = new TangoUpdate(); tangoUpdate.ApplicationVersion = latest_machine_version.Version; -- cgit v1.3.1 From 58f79af3b62e7737191205e029ccdc8fb79c40cc Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Thu, 23 Jan 2020 16:53:51 +0200 Subject: Fixed a bug with none site for machine. Added Job run designation, source, uploading, heating time... --- Software/DB/Tango.mdf | Bin 75497472 -> 75497472 bytes Software/DB/Tango_log.ldf | Bin 22675456 -> 22675456 bytes .../ViewModels/MainViewVM.cs | 13 +- .../ViewModels/MainViewVM.cs | 1 + .../Connection/DefaultMachineProvider.cs | 1 + .../Visual_Studio/Tango.BL/DTO/JobRunDTOBase.cs | 16 +++ Software/Visual_Studio/Tango.BL/Entities/JobRun.cs | 22 +++ .../Visual_Studio/Tango.BL/Entities/JobRunBase.cs | 76 ++++++++++ .../Visual_Studio/Tango.DAL.Remote/DB/JOB_RUNS.cs | 2 + .../Tango.DAL.Remote/DB/RemoteADO.edmx | 6 + .../Tango.DAL.Remote/DB/RemoteADO.edmx.diagram | 156 ++++++++++----------- .../Tango.Emulations/Emulators/MachineEmulator.cs | 16 +-- .../JobRuns/BasicJobRunsLogger.cs | 20 ++- .../Tango.Integration/JobRuns/IJobRunsLogger.cs | 7 +- .../Tango.Integration/Operation/MachineOperator.cs | 30 ++++ .../Operation/PrintingEventArgs.cs | 3 + 16 files changed, 274 insertions(+), 95 deletions(-) (limited to 'Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs') diff --git a/Software/DB/Tango.mdf b/Software/DB/Tango.mdf index 92607a44c..8408613fb 100644 Binary files a/Software/DB/Tango.mdf and b/Software/DB/Tango.mdf differ diff --git a/Software/DB/Tango_log.ldf b/Software/DB/Tango_log.ldf index b0d5a8efe..a9a07d0c3 100644 Binary files a/Software/DB/Tango_log.ldf and b/Software/DB/Tango_log.ldf differ diff --git a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs index bd08e3e7c..e0d99d0f0 100644 --- a/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Modules/Tango.MachineStudio.MachineDesigner/ViewModels/MainViewVM.cs @@ -610,8 +610,10 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels } } - Sites = await ActiveMachineAdapter.Context.Sites.ToListAsync(); - Sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); + var sites = await ActiveMachineAdapter.Context.Sites.ToListAsync(); + sites.Insert(0, new Site() { Name = "NONE", ID = -1 }); + + Sites = sites; SelectedSite = Sites.SingleOrDefault(x => x.Guid == ActiveMachine.SiteGuid); ColorCalibrationViewVM = new ColorCalibrationViewVM(_notification, ActiveMachine, _activeMachineAdapter.Context) @@ -627,8 +629,11 @@ namespace Tango.MachineStudio.MachineDesigner.ViewModels HardwareConfigurationViewVM.Init(ActiveMachine.Configuration); } - await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); - TupViewVM.Init(ActiveMachine); + if (!IsNewMachine) + { + await MachineUpdatesViewVM.Init(ActiveMachine, ActiveMachineAdapter.Context); + TupViewVM.Init(ActiveMachine); + } ActiveMachine.Configuration.HardwareVersionChanged += Configuration_HardwareVersionChanged; diff --git a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs index ce3b825c8..23765de35 100644 --- a/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs +++ b/Software/Visual_Studio/MachineStudio/Tango.MachineStudio.UI/ViewModels/MainViewVM.cs @@ -464,6 +464,7 @@ namespace Tango.MachineStudio.UI.ViewModels x.SelectedMachine.EnableEventsNotification = x.EnableDiagnostics; x.SelectedMachine.UseKeepAlive = x.EnableKeepAlive; x.SelectedMachine.JobUnitsMethod = _settings.JobUnitsMethod; + x.SelectedMachine.JobRunsLogger.JobSource = BL.Enumerations.JobSource.Remote; if (x.SelectedMachine is ExternalBridgeTcpClient) { diff --git a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs index 9b818bd9d..0475f43ac 100644 --- a/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs +++ b/Software/Visual_Studio/PPC/Tango.PPC.Common/Connection/DefaultMachineProvider.cs @@ -84,6 +84,7 @@ namespace Tango.PPC.Common.Connection MachineOperator.EnableDiagnostics = true; MachineOperator.EnableEmbeddedDebugging = settings.EnableEmbeddedDebugLogs; MachineOperator.EnableAutomaticThreadLoading = settings.EnableAutomaticThreadLoading; + MachineOperator.JobRunsLogger.JobSource = BL.Enumerations.JobSource.Local; MachineOperator.FirmwareUpgradeMode = Integration.Upgrade.FirmwareUpgradeModes.DFU | Integration.Upgrade.FirmwareUpgradeModes.TFP_PACKAGE; diff --git a/Software/Visual_Studio/Tango.BL/DTO/JobRunDTOBase.cs b/Software/Visual_Studio/Tango.BL/DTO/JobRunDTOBase.cs index 83e04fde0..3542a7c08 100644 --- a/Software/Visual_Studio/Tango.BL/DTO/JobRunDTOBase.cs +++ b/Software/Visual_Studio/Tango.BL/DTO/JobRunDTOBase.cs @@ -53,6 +53,14 @@ namespace Tango.BL.DTO get; set; } + /// + /// job designation + /// + public Int32 JobDesignation + { + get; set; + } + /// /// job source /// @@ -133,6 +141,14 @@ namespace Tango.BL.DTO get; set; } + /// + /// gradient resolution cm + /// + public Int32 GradientResolutionCm + { + get; set; + } + /// /// liquid quantity string /// diff --git a/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs b/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs index 1c4f3a5cd..6afb493cf 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/JobRun.cs @@ -22,6 +22,28 @@ namespace Tango.BL.Entities set { Status = (int)value; } } + /// + /// Gets or sets the job designation. + /// + [NotMapped] + [JsonIgnore] + public JobDesignations Designation + { + get { return (JobDesignations)JobDesignation; } + set { JobDesignation = value.ToInt32(); RaisePropertyChangedAuto(); } + } + + /// + /// Gets or sets the job designation. + /// + [NotMapped] + [JsonIgnore] + public JobSource Source + { + get { return (JobSource)JobSource; } + set { JobSource = value.ToInt32(); RaisePropertyChangedAuto(); } + } + [NotMapped] [JsonIgnore] public List LiquidQuantities diff --git a/Software/Visual_Studio/Tango.BL/Entities/JobRunBase.cs b/Software/Visual_Studio/Tango.BL/Entities/JobRunBase.cs index 32efcdd9e..6aff11e23 100644 --- a/Software/Visual_Studio/Tango.BL/Entities/JobRunBase.cs +++ b/Software/Visual_Studio/Tango.BL/Entities/JobRunBase.cs @@ -29,6 +29,8 @@ namespace Tango.BL.Entities public event EventHandler JobNameChanged; + public event EventHandler JobDesignationChanged; + public event EventHandler JobSourceChanged; public event EventHandler JobStringChanged; @@ -49,6 +51,8 @@ namespace Tango.BL.Entities public event EventHandler IsGradientChanged; + public event EventHandler GradientResolutionCmChanged; + public event EventHandler LiquidQuantityStringChanged; public event EventHandler EndPositionChanged; @@ -159,6 +163,33 @@ namespace Tango.BL.Entities } } + protected Int32 _jobdesignation; + + /// + /// Gets or sets the jobrunbase job designation. + /// + + [Column("JOB_DESIGNATION")] + + public Int32 JobDesignation + { + get + { + return _jobdesignation; + } + + set + { + if (_jobdesignation != value) + { + _jobdesignation = value; + + OnJobDesignationChanged(value); + + } + } + } + protected Int32 _jobsource; /// @@ -431,6 +462,33 @@ namespace Tango.BL.Entities } } + protected Int32 _gradientresolutioncm; + + /// + /// Gets or sets the jobrunbase gradient resolution cm. + /// + + [Column("GRADIENT_RESOLUTION_CM")] + + public Int32 GradientResolutionCm + { + get + { + return _gradientresolutioncm; + } + + set + { + if (_gradientresolutioncm != value) + { + _gradientresolutioncm = value; + + OnGradientResolutionCmChanged(value); + + } + } + } + protected String _liquidquantitystring; /// @@ -548,6 +606,15 @@ namespace Tango.BL.Entities RaisePropertyChanged(nameof(JobName)); } + /// + /// Called when the JobDesignation has changed. + /// + protected virtual void OnJobDesignationChanged(Int32 jobdesignation) + { + JobDesignationChanged?.Invoke(this, jobdesignation); + RaisePropertyChanged(nameof(JobDesignation)); + } + /// /// Called when the JobSource has changed. /// @@ -638,6 +705,15 @@ namespace Tango.BL.Entities RaisePropertyChanged(nameof(IsGradient)); } + /// + /// Called when the GradientResolutionCm has changed. + /// + protected virtual void OnGradientResolutionCmChanged(Int32 gradientresolutioncm) + { + GradientResolutionCmChanged?.Invoke(this, gradientresolutioncm); + RaisePropertyChanged(nameof(GradientResolutionCm)); + } + /// /// Called when the LiquidQuantityString has changed. /// diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB_RUNS.cs b/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB_RUNS.cs index ca9dae507..482923dbc 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB_RUNS.cs +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/JOB_RUNS.cs @@ -21,6 +21,7 @@ namespace Tango.DAL.Remote.DB public string JOB_GUID { get; set; } public string USER_GUID { get; set; } public string JOB_NAME { get; set; } + public int JOB_DESIGNATION { get; set; } public int JOB_SOURCE { get; set; } public string JOB_STRING { get; set; } public System.DateTime START_DATE { get; set; } @@ -31,6 +32,7 @@ namespace Tango.DAL.Remote.DB public int STATUS { get; set; } public double JOB_LENGTH { get; set; } public bool IS_GRADIENT { get; set; } + public int GRADIENT_RESOLUTION_CM { get; set; } public string LIQUID_QUANTITY_STRING { get; set; } public double END_POSITION { get; set; } public string FAILED_MESSAGE { get; set; } diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx index f18c157ba..032d79b90 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx @@ -605,6 +605,7 @@ + @@ -615,6 +616,7 @@ + @@ -3871,6 +3873,7 @@ + @@ -3881,6 +3884,7 @@ + @@ -6318,6 +6322,7 @@ + @@ -6328,6 +6333,7 @@ + diff --git a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram index fb41299df..6763cdcc3 100644 --- a/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram +++ b/Software/Visual_Studio/Tango.DAL.Remote/DB/RemoteADO.edmx.diagram @@ -5,84 +5,84 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs index 6d0bdbfc4..5e6fdbc63 100644 --- a/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs +++ b/Software/Visual_Studio/Tango.Emulations/Emulators/MachineEmulator.cs @@ -852,16 +852,16 @@ namespace Tango.Emulations.Emulators private void HandleAbortJobRequest(TangoMessage request) { - if (_jobAbortCounter == 1) - { + //if (_jobAbortCounter == 1) + //{ _cancelJob = true; Transporter.SendResponse(new AbortJobResponse(), request.Container.Token); - _jobAbortCounter = 0; - } - else - { - _jobAbortCounter++; - } + // _jobAbortCounter = 0; + //} + //else + //{ + // _jobAbortCounter++; + //} } private void HandleMotorJoggingRequest(TangoMessage request) diff --git a/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs b/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs index ce175e3d2..bb6c81a82 100644 --- a/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs +++ b/Software/Visual_Studio/Tango.Integration/JobRuns/BasicJobRunsLogger.cs @@ -35,7 +35,12 @@ namespace Tango.Integration.JobRuns /// /// Gets or sets the job designations of which the logger should log (supports multiple flags). /// - public JobDesignations JobDesignation { get; set; } + public JobDesignations JobDesignationFilter { get; set; } + + /// + /// Gets or sets the job run source when logging job runs. + /// + public JobSource JobSource { get; set; } #endregion @@ -47,7 +52,7 @@ namespace Tango.Integration.JobRuns /// The machine operator. public BasicJobRunsLogger(IMachineOperator machineOperator) { - JobDesignation = JobDesignations.Default; + JobDesignationFilter = JobDesignations.Default | JobDesignations.SampleDye | JobDesignations.FineTuning; MachineOperator = machineOperator; Init(); } @@ -73,7 +78,7 @@ namespace Tango.Integration.JobRuns private bool ShouldLog() { - return IsStarted && _job != null && JobDesignation.HasFlag(_job.Designation); + return IsStarted && _job != null && JobDesignationFilter.HasFlag(_job.Designation); } private void InsertJobRun(PrintingEventArgs e, JobRunStatus status, Exception exception) @@ -90,17 +95,24 @@ namespace Tango.Integration.JobRuns { JobRun run = new JobRun(); + run.UserGuid = _job.UserGuid; run.StartDate = _start_date; + run.UploadingStartDate = e.UploadingStartTime; + run.HeatingStartDate = e.HeatingStartTime; + run.ActualStartDate = e.ActualStartTime; run.EndDate = DateTime.UtcNow; run.JobName = _job.Name; run.JobLength = _job.LengthIncludingNumberOfUnits; - run.JobSource = _job.Source; + run.Source = JobSource; + run.Designation = _job.Designation; run.JobGuid = _job.Guid; run.MachineGuid = _job.MachineGuid; run.JobRunStatus = status; run.EndPosition = e.JobHandler.Status.Progress; run.JobLength = e.JobHandler.Status.TotalProgress; run.LiquidQuantities = e.LiquidQuantities; + run.IsGradient = _job.Segments.Any(x => x.BrushStops.Count > 1); + run.GradientResolutionCm = MachineOperator.GradientGenerationConfiguration.ResolutionCM; run.JobString = _job.ToJobFileWhenLoaded().ToString(); if (exception != null) diff --git a/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs b/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs index 8c4174311..a5242c1a4 100644 --- a/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs +++ b/Software/Visual_Studio/Tango.Integration/JobRuns/IJobRunsLogger.cs @@ -21,7 +21,12 @@ namespace Tango.Integration.JobRuns /// /// Gets or sets the job designations of which the logger should log (supports multiple flags). /// - JobDesignations JobDesignation { get; set; } + JobDesignations JobDesignationFilter { get; set; } + + /// + /// Gets or sets the job run source when logging job runs. + /// + JobSource JobSource { get; set; } /// /// Gets a value indicating whether this instance is started. diff --git a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs index 2205fad8d..cd320e023 100644 --- a/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs +++ b/Software/Visual_Studio/Tango.Integration/Operation/MachineOperator.cs @@ -75,6 +75,9 @@ namespace Tango.Integration.Operation private List _currentJobLiquidQuantities; private DateTime _diagnosticsTime; private MachineStatus _machineStatusBeforeJobStart; + private DateTime? _jobUploadingStartDate; + private DateTime? _jobHeatingStartDate; + private DateTime? _jobActualStartDate; public static String EmbeddedLogsFolder { get; private set; } public static String EmbeddedLogsTag { get; private set; } @@ -1180,6 +1183,9 @@ namespace Tango.Integration.Operation PrintingCompleted?.Invoke(this, new PrintingEventArgs(handler, job) { LiquidQuantities = _currentJobLiquidQuantities.ToList(), + UploadingStartTime = _jobUploadingStartDate, + HeatingStartTime = _jobHeatingStartDate, + ActualStartTime = _jobActualStartDate, }); OnPrintingEnded(handler, job); @@ -1196,6 +1202,9 @@ namespace Tango.Integration.Operation PrintingFailed?.Invoke(this, new PrintingFailedEventArgs(handler, job, exception) { LiquidQuantities = _currentJobLiquidQuantities.ToList(), + UploadingStartTime = _jobUploadingStartDate, + HeatingStartTime = _jobHeatingStartDate, + ActualStartTime = _jobActualStartDate, }); OnPrintingEnded(handler, job); } @@ -1210,6 +1219,9 @@ namespace Tango.Integration.Operation PrintingAborted?.Invoke(this, new PrintingEventArgs(handler, job) { LiquidQuantities = _currentJobLiquidQuantities.ToList(), + UploadingStartTime = _jobUploadingStartDate, + HeatingStartTime = _jobHeatingStartDate, + ActualStartTime = _jobActualStartDate, }); OnPrintingEnded(handler, job); } @@ -1224,6 +1236,9 @@ namespace Tango.Integration.Operation PrintingEnded?.Invoke(this, new PrintingEventArgs(handler, job) { LiquidQuantities = _currentJobLiquidQuantities.ToList(), + UploadingStartTime = _jobUploadingStartDate, + HeatingStartTime = _jobHeatingStartDate, + ActualStartTime = _jobActualStartDate, }); } @@ -2291,6 +2306,9 @@ namespace Tango.Integration.Operation LogManager.Log($"Executing job '{job.Name}'..."); _currentJobLiquidQuantities = new List(); + _jobUploadingStartDate = null; + _jobHeatingStartDate = null; + _jobActualStartDate = null; RunningJob = null; RunningJobStatus = null; @@ -2568,6 +2586,7 @@ namespace Tango.Integration.Operation LogManager.Log($"Uploading job description file '{job_file_path}' of size: {ms.Length}"); TaskCompletionSource uploadCompletion = new TaskCompletionSource(); + _jobUploadingStartDate = DateTime.UtcNow; fileUploadHandler = await storage.UploadFile(job_file_path, ms); bool uploadCanceled = false; Exception uploadException = null; @@ -2631,6 +2650,10 @@ namespace Tango.Integration.Operation return; } } + else + { + _jobUploadingStartDate = DateTime.UtcNow; + } if (handler.IsCanceled) { @@ -2645,6 +2668,8 @@ namespace Tango.Integration.Operation bool responseLogged = false; bool completed = false; //Use this in case Shlomo is sending progress after completion. + _jobHeatingStartDate = DateTime.UtcNow; + SendContinuousRequest(request, null, ContinuousRequestTimeout.Add(TimeSpan.FromSeconds(3))).Subscribe((response) => { if (!completed) @@ -2658,6 +2683,11 @@ namespace Tango.Integration.Operation { UseKeepAlive = oldKeepAlive; } + + if (_jobActualStartDate == null) + { + _jobActualStartDate = DateTime.UtcNow; + } } if (!responseLogged) diff --git a/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs b/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs index d4c2ad4e8..f68204127 100644 --- a/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs +++ b/Software/Visual_Studio/Tango.Integration/Operation/PrintingEventArgs.cs @@ -13,6 +13,9 @@ namespace Tango.Integration.Operation public JobHandler JobHandler { get; private set; } public Job Job { get; private set; } public List LiquidQuantities { get; set; } + public DateTime? UploadingStartTime { get; set; } + public DateTime? HeatingStartTime { get; set; } + public DateTime? ActualStartTime { get; set; } public PrintingEventArgs(JobHandler jobHandler, Job job) { -- cgit v1.3.1