From d26e810aa206bf850622ded5a0da76293cb12f13 Mon Sep 17 00:00:00 2001 From: Roy Ben Shabat Date: Sun, 12 Apr 2020 17:47:21 +0300 Subject: FSE TFP. --- .../Tango.FSE.Upgrade/Images/tfp_download.png | Bin 0 -> 1008 bytes .../Modules/Tango.FSE.Upgrade/Images/tfp_ready.png | Bin 0 -> 1282 bytes .../Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj | 4 + .../ViewModels/ApplicationUpgradeViewVM.cs | 2 +- .../ViewModels/FirmwareUpgradeViewVM.cs | 136 +++++++++++++++++++++ .../Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs | 22 ++-- .../Views/FirmwareUpgradeView.xaml | 132 +++++++++++++++++++- .../RemoteUpgrade/IRemoteUpgradeManager.cs | 16 ++- .../FSE/Tango.FSE.Common/Resources/Converters.xaml | 1 + .../RemoteUpgrade/DefaultRemoteUpgradeManager.cs | 69 ++++++++++- .../Converters/FilePathToFileNameConverter.cs | 36 ++++++ .../Tango.SharedUI/Tango.SharedUI.csproj | 3 +- .../Tango.Transport/Tango.Transport.csproj | 3 +- .../Tango.Transport/Web/StorageBlobStream.cs | 45 +++++++ 14 files changed, 446 insertions(+), 23 deletions(-) create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_download.png create mode 100644 Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_ready.png create mode 100644 Software/Visual_Studio/Tango.SharedUI/Converters/FilePathToFileNameConverter.cs create mode 100644 Software/Visual_Studio/Tango.Transport/Web/StorageBlobStream.cs (limited to 'Software/Visual_Studio') diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_download.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_download.png new file mode 100644 index 000000000..d536d4a73 Binary files /dev/null and b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_download.png differ diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_ready.png b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_ready.png new file mode 100644 index 000000000..3d25a5bdd Binary files /dev/null and b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Images/tfp_ready.png differ diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj index bae2811ac..daca836b7 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Tango.FSE.Upgrade.csproj @@ -206,6 +206,10 @@ + + + + diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs index cfe2e212c..c120b3f74 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/ApplicationUpgradeViewVM.cs @@ -118,7 +118,7 @@ namespace Tango.FSE.Upgrade.ViewModels catch (Exception ex) { LogManager.Log(ex, "Error retrieving tango versions."); - await NotificationProvider.ShowError($"Error retrieving Tango version.\n{ex.FlattenMessage()}"); + await NotificationProvider.ShowError($"Error retrieving Tango versions.\n{ex.FlattenMessage()}"); } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs index 4eecaaeb0..0a2d0fdb3 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/FirmwareUpgradeViewVM.cs @@ -3,11 +3,147 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using Tango.BL.Entities; +using Tango.Core.Commands; using Tango.FSE.Common; +using Tango.FSE.Common.RemoteUpgrade; namespace Tango.FSE.Upgrade.ViewModels { public class FirmwareUpgradeViewVM : FSEViewModel { + private List _tangoVersions; + public List TangoVersions + { + get { return _tangoVersions; } + set { _tangoVersions = value; RaisePropertyChangedAuto(); } + } + + private TangoVersion _selectedVersion; + public TangoVersion SelectedVersion + { + get { return _selectedVersion; } + set { _selectedVersion = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _tfpFileLocation; + public String TfpFileLocation + { + get { return _tfpFileLocation; } + set { _tfpFileLocation = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + private String _existingTfpFileLocation; + public String ExistingTfpFileLocation + { + get { return _existingTfpFileLocation; } + set { _existingTfpFileLocation = value; RaisePropertyChangedAuto(); } + } + + private RemoteUpgradeHandler _handler; + public RemoteUpgradeHandler Handler + { + get { return _handler; } + set { _handler = value; RaisePropertyChangedAuto(); } + } + + private bool _useExistingTfpFile; + public bool UseExistingTfpFile + { + get { return _useExistingTfpFile; } + set { _useExistingTfpFile = value; RaisePropertyChangedAuto(); InvalidateRelayCommands(); } + } + + public RelayCommand SelectTfpFileLocationCommand { get; set; } + + public RelayCommand SelectExistingTfpFileLocationCommand { get; set; } + + public RelayCommand GeneratePackageCommand { get; set; } + + public FirmwareUpgradeViewVM() + { + SelectTfpFileLocationCommand = new RelayCommand(SelectTfpFileLocation, () => SelectedVersion != null); + SelectExistingTfpFileLocationCommand = new RelayCommand(SelectExistingTfpFileLocation); + GeneratePackageCommand = new RelayCommand(GeneratePackage, () => SelectedVersion != null && (TfpFileLocation != null || (UseExistingTfpFile && ExistingTfpFileLocation != null))); + Handler = new RemoteUpgradeHandler(null) { Message = "Ready" }; + } + + public override void OnBeforeNavigatedTo() + { + base.OnBeforeNavigatedTo(); + + if (UseExistingTfpFile && !MachineProvider.IsConnected) + { + UseExistingTfpFile = false; + } + } + + private async void SelectTfpFileLocation() + { + String fileName = $"firmware_package_v{SelectedVersion.FirmwareVersion}.tfp"; + var result = await StorageProvider.SaveFile("Select firmware package location", "Tango Firmware Package|*.tfp", fileName, ".tfp"); + if (result) + { + TfpFileLocation = result.SelectedItem; + } + } + + private async void SelectExistingTfpFileLocation() + { + var result = await StorageProvider.OpenFile("Select existing firmware package file", "Tango Firmware Package|*.tfp"); + if (result) + { + ExistingTfpFileLocation = result.SelectedItem; + } + } + + public async override void OnNavigatedTo() + { + base.OnNavigatedTo(); + + if (TangoVersions == null) + { + try + { + TangoVersions = (await Services.TangoVersionsService.GetAllTangoVersions()).Take(10).ToList(); + SelectedVersion = TangoVersions.FirstOrDefault(); + } + catch (Exception ex) + { + LogManager.Log(ex, "Error retrieving tango versions."); + await NotificationProvider.ShowError($"Error retrieving Tango versions.\n{ex.FlattenMessage()}"); + } + } + } + + private async void GeneratePackage() + { + if (UseExistingTfpFile) + { + //Navigate to the firmware completion with the existing tfp file. + } + else + { + try + { + IsFree = false; + Handler = await RemoteUpgradeManager.CreateTfpFile(SelectedVersion, TfpFileLocation); + await Handler.WaitForCompletion(); + } + catch (OperationCanceledException) + { + //Aborted... + } + catch (Exception ex) + { + LogManager.Log("Error generating remote firmware upgrade package."); + await NotificationProvider.ShowError($"Error occurred while trying to generate the firmware upgrade package.\n{ex.FlattenMessage()}"); + } + finally + { + IsFree = true; + } + } + } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs index b6e719667..eebe39707 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/ViewModels/WelcomeViewVM.cs @@ -71,23 +71,23 @@ namespace Tango.FSE.Upgrade.ViewModels } } - private void StartUpgrade() + private async void StartUpgrade() { if (IsApplicationUpdate) { - NavigationManager.NavigateWithObject< - UpgradeModule, - ApplicationUpgradeView, - ApplicationUpgradeViewVM.NavigationObject> - (new ApplicationUpgradeViewVM.NavigationObject() - { - ApplicationUpgradeMode = IsUpdateConnectedMachine ? ApplicationUpgradeViewVM.ApplicationUpgradeMode.ConnectedMachine : ApplicationUpgradeViewVM.ApplicationUpgradeMode.OtherMachine, - SelectedMachine = IsUpdateConnectedMachine ? MachineProvider.Machine : SelectedMachine - }); + await NavigationManager.NavigateWithObject< + UpgradeModule, + ApplicationUpgradeView, + ApplicationUpgradeViewVM.NavigationObject> + (new ApplicationUpgradeViewVM.NavigationObject() + { + ApplicationUpgradeMode = IsUpdateConnectedMachine ? ApplicationUpgradeViewVM.ApplicationUpgradeMode.ConnectedMachine : ApplicationUpgradeViewVM.ApplicationUpgradeMode.OtherMachine, + SelectedMachine = IsUpdateConnectedMachine ? MachineProvider.Machine : SelectedMachine + }); } else { - //Navigate to firmware view. + await NavigationManager.NavigateTo(nameof(FirmwareUpgradeView)); } } } diff --git a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml index 38c7dc296..b899b4e04 100644 --- a/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml +++ b/Software/Visual_Studio/FSE/Modules/Tango.FSE.Upgrade/Views/FirmwareUpgradeView.xaml @@ -3,13 +3,139 @@ xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" + xmlns:controls="clr-namespace:Tango.FSE.Common.Controls;assembly=Tango.FSE.Common" xmlns:global="clr-namespace:Tango.FSE.Upgrade" + xmlns:autoComplete="clr-namespace:Tango.AutoComplete.Editors;assembly=Tango.AutoComplete" xmlns:vm="clr-namespace:Tango.FSE.Upgrade.ViewModels" xmlns:material="http://materialdesigninxaml.net/winfx/xaml/themes" xmlns:local="clr-namespace:Tango.FSE.Upgrade.Views" mc:Ignorable="d" - d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:FirmwareUpgradeViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.FirmwareUpgradeViewVM}" Background="{StaticResource FSE_PrimaryBackgroundBrush}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> - - + d:DesignHeight="720" d:DesignWidth="1280" d:DataContext="{d:DesignInstance Type=vm:FirmwareUpgradeViewVM, IsDesignTimeCreatable=False}" DataContext="{x:Static global:ViewModelLocator.FirmwareUpgradeViewVM}" Foreground="{StaticResource FSE_PrimaryForegroundBrush}"> + + + + + + + + Firmware Upgrade + + + You chose to perform a machine firmware upgrade. + + The upgrade is done by downloading the specified Tango system version below and composing a .tfp file (Tango Firmware Package). + + + + Once the .tfp file has been generated, you will be able to store that file on a removable storage which can be later inserted into a machine. + + In case you chose to upgrade the currently connected machine, you will be able to perform the upgrade remotely. + + + + + + + I want download and create a .tfp file from an existing version. + + + + + + + Select the desired firmware version + + + + + + () + + + + Firmware: + v + + + + + + + + + + Select where to save the firmware package (.tfp file) + + + + + + + + + + + + I already have the .tfp file and just want to upgrade the currently connected machine. (requires an active machine connection) + + + + + Select an existing .tfp file on your computer + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs index 98378585f..20bc9b3db 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/RemoteUpgrade/IRemoteUpgradeManager.cs @@ -14,17 +14,25 @@ namespace Tango.FSE.Common.RemoteUpgrade /// Creates a Tango Update Package for the current connected machine. /// /// The tango version. - /// The file path. + /// The file path. /// - Task CreateTupFile(TangoVersion tangoVersion, String filePath); + Task CreateTupFile(TangoVersion tangoVersion, String targetFilePath); /// /// Creates a Tango Update Package for specified machine. /// /// The tango version. /// The machine serial number. - /// The file path. + /// The file path. /// - Task CreateTupFile(TangoVersion tangoVersion, String serialNumber, String filePath); + Task CreateTupFile(TangoVersion tangoVersion, String serialNumber, String targetFilePath); + + /// + /// Creates a firmware upgrade package file. + /// + /// The tango version. + /// The file path. + /// + Task CreateTfpFile(TangoVersion tangoVersion, String targetFilePath); } } diff --git a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml index 19bf643c4..8c36100c1 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml +++ b/Software/Visual_Studio/FSE/Tango.FSE.Common/Resources/Converters.xaml @@ -34,4 +34,5 @@ + \ No newline at end of file diff --git a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs index 13ea597e1..83cf6ecf7 100644 --- a/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs +++ b/Software/Visual_Studio/FSE/Tango.FSE.UI/RemoteUpgrade/DefaultRemoteUpgradeManager.cs @@ -57,9 +57,9 @@ namespace Tango.FSE.UI.RemoteUpgrade /// Creates a Tango Update Package for the current connected machine. /// /// The tango version. - /// The file path. + /// The file path. /// - public Task CreateTupFile(TangoVersion tangoVersion, string filePath) + public Task CreateTupFile(TangoVersion tangoVersion, string targetFilePath) { if (MachineProvider.Machine == null) { @@ -323,5 +323,70 @@ namespace Tango.FSE.UI.RemoteUpgrade return Task.FromResult(handler); } + + /// + /// Creates a firmware upgrade package file. + /// + /// The tango version. + /// The file path. + /// + public Task CreateTfpFile(TangoVersion tangoVersion, string targetFilePath) + { + RemoteUpgradeHandler handler = new RemoteUpgradeHandler(() => { }); //Abort Action ? + + ThreadFactory.StartNew(() => + { + Thread.Sleep(100); + + LogManager.Log("Generating tfp file..."); + LogManager.Log($"Tfp file: '{targetFilePath}.'"); + + try + { + LogManager.Log("Initializing..."); + handler.UpdateProgress("Initializing..."); + + handler.UpdateProgress($"Downloading firmware version '{tangoVersion.FirmwareVersion}'..."); + + LogManager.Log("Connecting to machine service..."); + + LogManager.Log("Requesting version download from machine service..."); + var response = WebClient.DownloadTangoVersion(new DownloadTangoVersionRequest() { TangoVersionGuid = tangoVersion.Guid }).Result; + + LogManager.Log($"Machine service response:\n{response.ToJsonString()}"); + + using (StorageBlobStream blobZipStream = new StorageBlobStream(response.BlobAddress)) + { + using (ZipFile zip = ZipFile.Read(blobZipStream.OpenRead())) + { + var tfpEntry = zip.Entries.SingleOrDefault(x => x.FileName == "firmware_package.tfp"); + + using (FileStream targetStream = new FileStream(targetFilePath, FileMode.Create)) + { + tfpEntry.Extract(targetStream); + } + } + } + + handler.UpdateProgress("Completed", false, 100, 100); + LogManager.Log("TFP file generation completed successfully."); + + handler.RaiseCompleted(); + } + catch (Exception ex) + { + LogManager.Log(ex, "TFP file generation failed."); + handler.UpdateProgress("Failed", false, 0, 100); + handler.RaiseFailed(ex); + } + finally + { + //Nothing right now.. + } + + }); + + return Task.FromResult(handler); + } } } diff --git a/Software/Visual_Studio/Tango.SharedUI/Converters/FilePathToFileNameConverter.cs b/Software/Visual_Studio/Tango.SharedUI/Converters/FilePathToFileNameConverter.cs new file mode 100644 index 000000000..7c59f8de7 --- /dev/null +++ b/Software/Visual_Studio/Tango.SharedUI/Converters/FilePathToFileNameConverter.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Globalization; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Data; + +namespace Tango.SharedUI.Converters +{ + public class FilePathToFileNameConverter : IValueConverter + { + public object Convert(object value, Type targetType, object parameter, CultureInfo culture) + { + try + { + if (value != null) + { + return Path.GetFileName(value.ToString()); + } + } + catch + { + return value; + } + + 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 a649d0c1a..63bc3f833 100644 --- a/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj +++ b/Software/Visual_Studio/Tango.SharedUI/Tango.SharedUI.csproj @@ -112,6 +112,7 @@ + @@ -256,7 +257,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj index f83384097..8ed8c0345 100644 --- a/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj +++ b/Software/Visual_Studio/Tango.Transport/Tango.Transport.csproj @@ -151,6 +151,7 @@ + @@ -186,7 +187,7 @@ - + \ No newline at end of file diff --git a/Software/Visual_Studio/Tango.Transport/Web/StorageBlobStream.cs b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobStream.cs new file mode 100644 index 000000000..f4cbf7f62 --- /dev/null +++ b/Software/Visual_Studio/Tango.Transport/Web/StorageBlobStream.cs @@ -0,0 +1,45 @@ +using Microsoft.WindowsAzure.Storage.Blob; +using System; +using System.Collections.Generic; +using System.IO; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace Tango.Transport.Web +{ + public class StorageBlobStream : IDisposable + { + public CloudBlockBlob Blob { get; private set; } + private Stream _blobStream; + + public String Address { get; private set; } + + private StorageBlobStream(CloudBlockBlob blob) + { + Blob = blob; + } + + public StorageBlobStream(String blobAddress) : this(new CloudBlockBlob(new Uri(blobAddress))) + { + Address = blobAddress; + } + + public Stream OpenRead() + { + _blobStream = Blob.OpenRead(); + return _blobStream; + } + + public Stream OpenWrite() + { + _blobStream = Blob.OpenWrite(); + return _blobStream; + } + + public void Dispose() + { + _blobStream?.Dispose(); + } + } +} -- cgit v1.3.1