aboutsummaryrefslogtreecommitdiffstats
path: root/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs
diff options
context:
space:
mode:
Diffstat (limited to 'Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs')
-rw-r--r--Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs536
1 files changed, 514 insertions, 22 deletions
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 01e67d3ce..5fe153ee9 100644
--- a/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs
+++ b/Software/Visual_Studio/PPC/Tango.PPC.UI/ViewModels/MachineUpdateViewVM.cs
@@ -1,22 +1,38 @@
using System;
using System.Collections.Generic;
+using System.Data.Entity;
using System.Diagnostics;
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.Commands;
+using Tango.Core.ExtensionMethods;
using Tango.Core.Helpers;
+using Tango.Core.Threading;
using Tango.Explorer;
+using Tango.Integration.ExternalBridge;
+using Tango.PMR.FirmwareUpgrade;
using Tango.PPC.Common;
+using Tango.PPC.Common.Application;
+using Tango.PPC.Common.ExternalBridge;
using Tango.PPC.Common.MachineUpdate;
+using Tango.PPC.Common.Navigation;
+using Tango.PPC.Common.Notifications;
+using Tango.PPC.Common.Publish;
using Tango.PPC.Common.Web;
+using Tango.PPC.Shared.RemoteUpgrade;
using Tango.PPC.UI.Dialogs;
+using Tango.PPC.UI.Notifications.NotificationItems;
using Tango.PPC.UI.ViewsContracts;
+using Tango.Transport;
namespace Tango.PPC.UI.ViewModels
{
- public class MachineUpdateViewVM : PPCViewModel<IMachineUpdateView>
+ public class MachineUpdateViewVM : PPCViewModel<IMachineUpdateView>, IExternalBridgeRequestHandler
{
public enum MachineUpdateView
{
@@ -36,6 +52,7 @@ namespace Tango.PPC.UI.ViewModels
private DbCompareResult _db_compare_result;
private bool _isChecking;
private CheckForUpdateResponse _checkUpdateResponse;
+ private UpdateAvailableNotificationItem _updateNotificationItem;
#region Properties
@@ -107,9 +124,10 @@ namespace Tango.PPC.UI.ViewModels
#region Constructors
- public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager)
+ public MachineUpdateViewVM(IMachineUpdateManager machineUpdateManager, IPPCExternalBridgeService externalBridge, IPPCApplicationManager applicationManager, INavigationManager navigationManager, INotificationProvider notificationProvider)
{
MachineUpdateManager = machineUpdateManager;
+ externalBridge.RegisterRequestHandler(this);
CompleteCommand = new RelayCommand(CompleteUpdate);
UpdateCommand = new RelayCommand(Update);
@@ -125,6 +143,13 @@ namespace Tango.PPC.UI.ViewModels
NavigationManager.NavigateTo(Common.Navigation.NavigationView.HomeModule);
NavigateTo(MachineUpdateView.UpdateCheckView);
});
+
+ machineUpdateManager.UpdateAvailable += MachineUpdateManager_UpdateAvailable;
+
+ NavigationManager = navigationManager;
+ NotificationProvider = notificationProvider;
+ ApplicationManager = applicationManager;
+ ApplicationManager.UpdaterFailed += ApplicationManager_UpdaterFailed;
}
#endregion
@@ -150,7 +175,28 @@ namespace Tango.PPC.UI.ViewModels
return;
}
- var response = await MachineUpdateManager.CheckForUpdate(MachineProvider.Machine.SerialNumber);
+ var response = await MachineUpdateManager.CheckForUpdate();
+
+ try
+ {
+ if (response.UsedNotExistingRmlsGuids.Count > 0)
+ {
+ using (ObservablesContext db = ObservablesContext.CreateDefault())
+ {
+ var arr = response.UsedNotExistingRmlsGuids.ToArray();
+ var jobs = await db.Jobs.Where(x => arr.Contains(x.RmlGuid)).ToListAsync();
+ FailedError = $"The following jobs must be removed or change thread type before the system can be updated:\n{String.Join("\n", jobs.Select(x => x.Name))}";
+ _isChecking = false;
+ await NavigateTo(MachineUpdateView.UpdateFailedView);
+ return;
+ }
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error on used RML check procedure.");
+ }
+
_checkUpdateResponse = response;
if (response.IsUpdateAvailable)
@@ -158,9 +204,19 @@ namespace Tango.PPC.UI.ViewModels
LatestVersion = response.Version;
await NavigateTo(MachineUpdateView.UpdateAvailableView);
}
+ else if (response.IsDatabaseUpdateAvailable)
+ {
+ IsDbUpdate = true;
+ _db_compare_result = new DbCompareResult()
+ {
+ RequiresUpdate = true,
+ UpdateDBResponse = response.UpdateDBResponse
+ };
+ await NavigateTo(MachineUpdateView.UpdateAvailableView);
+ }
else
{
- _db_compare_result = await MachineUpdateManager.UpdateDBCheck(MachineProvider.Machine.SerialNumber);
+ _db_compare_result = await MachineUpdateManager.UpdateDBCheck();
if (_db_compare_result.RequiresUpdate)
{
@@ -195,7 +251,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);
}
@@ -213,7 +269,7 @@ namespace Tango.PPC.UI.ViewModels
try
{
- await MachineUpdateManager.UpdateDB(_db_compare_result, MachineProvider.Machine.SerialNumber);
+ await MachineUpdateManager.UpdateDB(_db_compare_result);
LogManager.Log("Database update completed.");
await NavigateTo(MachineUpdateView.UpdateCompletedView);
}
@@ -234,15 +290,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());
}
}
@@ -275,15 +331,100 @@ namespace Tango.PPC.UI.ViewModels
base.OnApplicationReady();
StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Update.Extension, HandleSoftwareUpdatePackageLoaded);
+ StorageProvider.RegisterFileHandler(ExplorerFileDefinition.Firmware.Extension, HandleFirmwareUpgradeLoaded);
+
+ if (ApplicationManager.IsAfterUpdate)
+ {
+ RunPostUpdatePackages();
+ }
+ else
+ {
+ MachineUpdateManager.EnableAutoCheckForUpdates = true;
+ }
+ }
+
+ /// <summary>
+ /// Called when the navigation system has navigated to this VM view.
+ /// </summary>
+ public override void OnNavigatedTo()
+ {
+ base.OnNavigatedTo();
+
+ if (_updateNotificationItem != null)
+ {
+ _updateNotificationItem.Close();
+ _updateNotificationItem = null;
+ }
+ }
+
+ #endregion
+
+ #region Post Update Packages
+
+ private async void RunPostUpdatePackages()
+ {
+ await Task.Delay(1000);
+
+ LogManager.Log("Application was loaded after an update. Checking for required post-update packages...");
+
+ bool required = false;
+
+ try
+ {
+ required = await MachineUpdateManager.PostUpdatePackagesRequired();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error checking for post-update packages.");
+ }
+
+ if (required)
+ {
+ LogManager.Log("Post-update packages found and needs to be installed. Navigating to machine update and running post-update packages...");
+ await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView);
+ await NavigateTo(MachineUpdateView.UpdateProgressView);
+ try
+ {
+ var result = await MachineUpdateManager.RunPostUpdatePackages();
+
+ LogManager.Log("Post-update packages installed successfully.");
+
+ await Task.Delay(2000);
+
+ if (result.RestartRequired)
+ {
+ LogManager.Log("Restart required. Restarting...");
+ ApplicationManager.Restart();
+ }
+ else
+ {
+ await NavigationManager.NavigateTo(Common.Navigation.NavigationView.LayoutView);
+ }
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error occurred while running post-update packages.");
+ }
+ }
+ else
+ {
+ LogManager.Log("No post-update packages installation required.");
+ }
}
#endregion
#region Handle USB Update
- private async void HandleSoftwareUpdatePackageLoaded(ExplorerFileItem fileItem)
+ private async void HandleSoftwareUpdatePackageLoaded(List<ExplorerFileItem> fileItems)
{
- UpdatePackageFile packageFile = null;
+ var fileItem = fileItems.FirstOrDefault();
+
+ if (fileItem == null) return;
+
+ PublishInfo packageFile = null;
+
+ LogManager.Log("TUP file loaded from storage...");
try
{
@@ -291,43 +432,394 @@ 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)
+ UpdateFromFileViewVM vm = new UpdateFromFileViewVM();
+ vm.PublishInfo = packageFile;
+
+ LogManager.Log($"TUP publish info:\n{packageFile.ToJson()}");
+
+ LogManager.Log("Displaying TUP update dialog...");
+
+ await NotificationProvider.ShowDialog(vm);
+
+ if (vm.DialogResult)
{
- await NotificationProvider.ShowError($"The selected update package (v{packageFile.Version.ToString()}) contains an older software version.");
+ await NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView);
+ await NavigateTo(MachineUpdateView.UpdateProgressView);
+
+ LogManager.Log("Starting machine update from package...");
+
+ try
+ {
+ _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);
+ }
+ }
+ }
+
+ private async void HandleFirmwareUpgradeLoaded(List<ExplorerFileItem> fileItems)
+ {
+ var fileItem = fileItems.FirstOrDefault();
+
+ if (fileItem == null) return;
+
+ LogManager.Log("TFP file loaded from storage...");
+
+ VersionPackageDescriptor packageInfo;
+ FirmwareUpgradeFromFileViewVM vm = new FirmwareUpgradeFromFileViewVM();
+
+ try
+ {
+ using (FileStream st = File.OpenRead(fileItem.Path))
+ {
+ packageInfo = await MachineProvider.MachineOperator.GetFirmwarePackageInfo(st);
+ }
+
+ packageInfo.Validate();
+
+ vm.Version = packageInfo.GetMcuVersion().ToString();
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, $"Error loading package info from {fileItem.Path}.");
+ await NotificationProvider.ShowError($"An error occurred while trying to load the selected firmware upgrade package.\n{ex.FlattenMessage()}");
return;
}
- UpdateFromFileViewVM vm = new UpdateFromFileViewVM();
- vm.Version = packageFile.Version.ToString();
+
+ LogManager.Log($"TFP publish info:\n{packageInfo.ToJsonString()}");
+
+ LogManager.Log("Displaying TFP update dialog...");
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 firmware upgrade from package...");
+
+ try
+ {
+ await MachineUpdateManager.UpdateFromTFP(fileItem.Path);
+ LogManager.Log("Firmware upgrade from package completed.");
+ _update_result = new MachineUpdateResult()
+ {
+ RequiresBinariesUpdate = false,
+ };
+ await NavigateTo(MachineUpdateView.UpdateCompletedView);
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Firmware upgrade from package failed.");
+ FailedError = ex.FlattenMessage();
+ await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView);
+ }
+ }
+ }
+
+ #endregion
+
+ #region Auto Check For Update
+
+ private void MachineUpdateManager_UpdateAvailable(object sender, CheckForUpdateResponse e)
+ {
+ if (!IsVisible && _updateNotificationItem == null)
+ {
+ LogManager.Log($"New {(e.IsDatabaseUpdateAvailable ? "database updates" : "application version")} detected ({e.Version}). Pushing notification...");
+
+ InvokeUI(() =>
+ {
+ _updateNotificationItem = new UpdateAvailableNotificationItem();
+ _updateNotificationItem.Version = Version.Parse(e.Version).ToString(3);
+ _updateNotificationItem.IsDatabaseUpdate = e.IsDatabaseUpdateAvailable && !e.IsUpdateAvailable;
+ _updateNotificationItem.Pressed += (_, __) =>
+ {
+ if (MachineProvider.MachineOperator.IsPrinting)
+ {
+ NotificationProvider.ShowInfo("Cannot perform a machine update while the machine is dyeing.");
+ return;
+ }
+
+ _updateNotificationItem = null;
+
+ if (!IsVisible)
+ {
+ LogManager.Log("Update available notification pressed. Navigating to update view...");
+ NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView);
+ CheckForUpdates();
+ }
+ };
+ _updateNotificationItem.Closed += (_, __) =>
+ {
+ _updateNotificationItem = null;
+ };
+ NotificationProvider.PushNotification(_updateNotificationItem);
+ });
+ }
+ }
+
+ #endregion
+
+ #region Updater Failed
+
+ private void ApplicationManager_UpdaterFailed(object sender, EventArgs e)
+ {
+ InvokeUI(async () =>
+ {
+ try
+ {
+ await NavigationManager.NavigateTo(NavigationView.MachineUpdateView);
+ await NavigateTo(MachineUpdateView.UpdateProgressView);
+ await MachineUpdateManager.RestoreLastDatabaseBackup();
+ await Task.Delay(5000);
+ ApplicationManager.Restart();
+ }
+ catch (Exception ex)
+ {
+ await NotificationProvider.ShowError($"Could not restore the application to its previous state.\n{ex.FlattenMessage()}");
+ ApplicationManager.Restart();
+ }
+ });
+ }
+
+ #endregion
+
+ #region External Bridge Handler
+
+ [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteApplicationUpgradeRequest), RequestHandlerLoggingMode.LogRequestName)]
+ public async Task OnStartRemoteApplicationUpgradeRequest(StartRemoteApplicationUpgradeRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse(), token);
+
+ bool stopReporting = false;
+
+ try
+ {
+ ThreadFactory.StartNew(async () =>
+ {
+ while (!stopReporting)
+ {
+ if (MachineUpdateManager.Status != null)
+ {
+ try
+ {
+ await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse()
+ {
+ Progress = new TangoProgress<double>()
+ {
+ Message = MachineUpdateManager.Status.Message,
+ IsIndeterminate = MachineUpdateManager.Status.IsIntermediate,
+ Maximum = MachineUpdateManager.Status.Total,
+ Value = MachineUpdateManager.Status.Progress
+ },
+ }, token, new TransportResponseConfig() { Priority = QueuePriority.Low });
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error sending remote upgrade progress.");
+ }
+ }
+
+ Thread.Sleep(500);
+ }
+ });
+
+ InvokeUI(() =>
+ {
+ NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView);
+ NavigateTo(MachineUpdateView.UpdateProgressView);
+ });
LogManager.Log("Starting machine update from package...");
try
{
- _update_result = await MachineUpdateManager.UpdateFromTUP(fileItem.Path);
+ _update_result = await MachineUpdateManager.UpdateFromTUP(request.RemoteTupFilePath, request.SetupFirmware, request.SetupFPGA);
LogManager.Log("Machine update from package completed.");
- await NavigateTo(MachineUpdateView.UpdateCompletedView);
+ stopReporting = true;
+
+ InvokeUI(() =>
+ {
+ NavigateTo(MachineUpdateView.UpdateCompletedView);
+ });
}
catch (Exception ex)
{
LogManager.Log(ex, "Machine update from package failed.");
- await NavigateTo(MachineUpdateView.UpdateFailedFromPackageView);
+ FailedError = ex.FlattenMessage();
+
+ InvokeUI(() =>
+ {
+ NavigateTo(MachineUpdateView.UpdateFailedFromPackageView);
+ });
+
+ throw ex;
+ }
+
+ await receiver.SendGenericResponse(new StartRemoteApplicationUpgradeResponse()
+ {
+ Progress = new TangoProgress<double>("Completed", false, 100, 100),
+ }, token, new TransportResponseConfig()
+ {
+ Completed = true
+ });
+
+ try
+ {
+ File.Delete(request.RemoteTupFilePath);
+ }
+ catch { }
+
+ await Task.Delay(2000);
+
+ CompleteUpdate();
+ }
+ catch (Exception ex)
+ {
+ stopReporting = true;
+ await receiver.SendErrorResponse(ex, token);
+ }
+ finally
+ {
+ stopReporting = true;
+
+ try
+ {
+ File.Delete(request.RemoteTupFilePath);
}
+ catch { }
}
}
+ [ExternalBridgeRequestHandlerMethod(typeof(StartRemoteFirmwareUpgradeRequest), RequestHandlerLoggingMode.LogRequestName)]
+ public async Task OnStartRemoteFirmwareUpgradeRequest(StartRemoteFirmwareUpgradeRequest request, String token, ExternalBridgeReceiver receiver)
+ {
+ await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse(), token);
+
+ bool stopReporting = false;
+
+ try
+ {
+ ThreadFactory.StartNew(async () =>
+ {
+ while (!stopReporting)
+ {
+ if (MachineUpdateManager.Status != null)
+ {
+ try
+ {
+ await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse()
+ {
+ Progress = new TangoProgress<double>()
+ {
+ Message = MachineUpdateManager.Status.Message,
+ IsIndeterminate = MachineUpdateManager.Status.IsIntermediate,
+ Maximum = MachineUpdateManager.Status.Total,
+ Value = MachineUpdateManager.Status.Progress
+ }
+ }, token, new TransportResponseConfig() { Priority = QueuePriority.Low });
+ }
+ catch (Exception ex)
+ {
+ LogManager.Log(ex, "Error sending remote upgrade progress.");
+ }
+ }
+
+ Thread.Sleep(500);
+ }
+ });
+
+ InvokeUI(() =>
+ {
+ NavigationManager.NavigateTo(Common.Navigation.NavigationView.MachineUpdateView);
+ NavigateTo(MachineUpdateView.UpdateProgressView);
+ });
+
+ LogManager.Log("Starting firmware upgrade from package...");
+
+ try
+ {
+ await MachineUpdateManager.UpdateFromTFP(request.RemoteTfpFilePath);
+ stopReporting = true;
+ LogManager.Log("Firmware upgrade from package completed.");
+ _update_result = new MachineUpdateResult()
+ {
+ RequiresBinariesUpdate = false,
+ };
+
+ InvokeUI(() =>
+ {
+ NavigateTo(MachineUpdateView.UpdateCompletedView);
+ });
+ }
+ catch (Exception ex)
+ {
+ stopReporting = true;
+
+ LogManager.Log(ex, "Firmware upgrade from package failed.");
+ FailedError = ex.FlattenMessage();
+
+ InvokeUI(() =>
+ {
+ NavigateTo(MachineUpdateView.UpdateFailedFromPackageView);
+ });
+
+ throw ex;
+ }
+
+ await receiver.SendGenericResponse(new StartRemoteFirmwareUpgradeResponse()
+ {
+ Progress = new TangoProgress<double>("Completed", false, 100, 100),
+ }, token, new TransportResponseConfig()
+ {
+ Completed = true
+ });
+
+ try
+ {
+ File.Delete(request.RemoteTfpFilePath);
+ }
+ catch { }
+
+ await Task.Delay(2000);
+
+ CompleteUpdate();
+ }
+ catch (Exception ex)
+ {
+ stopReporting = true;
+ await receiver.SendErrorResponse(ex, token);
+ }
+ finally
+ {
+ stopReporting = true;
+
+ try
+ {
+ File.Delete(request.RemoteTfpFilePath);
+ }
+ catch { }
+ }
+ }
+
+ public void OnReceiverDisconnected(ExternalBridgeReceiver receiver)
+ {
+ //Do Nothing.
+ }
+
#endregion
}
}