From 4bf63785bfbb8aa54a26d5d1d6b7ce98898937f6 Mon Sep 17 00:00:00 2001 From: "Jasper De Keukelaere (imec)" Date: Thu, 4 Jul 2024 18:02:01 +0200 Subject: [PATCH] feat: add menu and dedicated pages for instance and settings --- .../InstanceOperatingstateChip.razor | 27 + .../Components/InstancePowerButton.razor | 23 + .../Components/InstanceRunStopButton.razor | 21 + .../Components/SetIPSettingsDialog.razor | 365 +++++----- PLCsimAdvanced_Manager/MainLayout.razor | 24 + PLCsimAdvanced_Manager/Pages/Instance.razor | 633 ++++++++++++++++++ .../Pages/PlcOverview.razor | 53 +- PLCsimAdvanced_Manager/Pages/Settings.razor | 265 ++++++++ 8 files changed, 1177 insertions(+), 234 deletions(-) create mode 100644 PLCsimAdvanced_Manager/Components/InstanceOperatingstateChip.razor create mode 100644 PLCsimAdvanced_Manager/Components/InstancePowerButton.razor create mode 100644 PLCsimAdvanced_Manager/Components/InstanceRunStopButton.razor create mode 100644 PLCsimAdvanced_Manager/Pages/Instance.razor create mode 100644 PLCsimAdvanced_Manager/Pages/Settings.razor diff --git a/PLCsimAdvanced_Manager/Components/InstanceOperatingstateChip.razor b/PLCsimAdvanced_Manager/Components/InstanceOperatingstateChip.razor new file mode 100644 index 0000000..11cfa76 --- /dev/null +++ b/PLCsimAdvanced_Manager/Components/InstanceOperatingstateChip.razor @@ -0,0 +1,27 @@ +@using Siemens.Simatic.Simulation.Runtime +@using Color = MudBlazor.Color + +@switch (SelectedInstance.OperatingState) +{ +case EOperatingState.Off: + @SelectedInstance.OperatingState +break; +case EOperatingState.Run: + @SelectedInstance.OperatingState +break; +case EOperatingState.Stop: + @SelectedInstance.OperatingState +break; +case EOperatingState.InvalidOperatingState: + @SelectedInstance.OperatingState +break; +default: + @SelectedInstance.OperatingState +break; +} + +@code { + + [Parameter] public IInstance SelectedInstance { get; set; } + +} \ No newline at end of file diff --git a/PLCsimAdvanced_Manager/Components/InstancePowerButton.razor b/PLCsimAdvanced_Manager/Components/InstancePowerButton.razor new file mode 100644 index 0000000..25a009e --- /dev/null +++ b/PLCsimAdvanced_Manager/Components/InstancePowerButton.razor @@ -0,0 +1,23 @@ +@using Siemens.Simatic.Simulation.Runtime +@using Color = MudBlazor.Color +@inject ISnackbar Snackbar + + + +@if (SelectedInstance.OperatingState == EOperatingState.Off) +{ + +} +else if (SelectedInstance.OperatingState == EOperatingState.Run || SelectedInstance.OperatingState == EOperatingState.Stop) +{ + +} +else +{ + +} + + +@code { + [Parameter] public IInstance SelectedInstance { get; set; } +} \ No newline at end of file diff --git a/PLCsimAdvanced_Manager/Components/InstanceRunStopButton.razor b/PLCsimAdvanced_Manager/Components/InstanceRunStopButton.razor new file mode 100644 index 0000000..c51276b --- /dev/null +++ b/PLCsimAdvanced_Manager/Components/InstanceRunStopButton.razor @@ -0,0 +1,21 @@ +@using Siemens.Simatic.Simulation.Runtime +@using Color = MudBlazor.Color +@inject ISnackbar Snackbar + +@if (SelectedInstance.OperatingState == EOperatingState.Stop) +{ + +} +else if (SelectedInstance.OperatingState == EOperatingState.Run) +{ + +} +else +{ + +} +@code { + [Parameter] public IInstance SelectedInstance { get; set; } +} \ No newline at end of file diff --git a/PLCsimAdvanced_Manager/Components/SetIPSettingsDialog.razor b/PLCsimAdvanced_Manager/Components/SetIPSettingsDialog.razor index d0f1895..7226f2b 100644 --- a/PLCsimAdvanced_Manager/Components/SetIPSettingsDialog.razor +++ b/PLCsimAdvanced_Manager/Components/SetIPSettingsDialog.razor @@ -4,252 +4,245 @@ - - -@for (int i = 0; i < selectedInstance.ControllerIPSuite4.Length; i++) -{ - var index = i; - var t = $"X{i + 1}"; - - - - - - - - - - - - - - - - - - - @if (SimulationRuntimeManager.NetworkMode == ECommunicationMode.Non_Promiscuous) - { - switch (index+1) + + + @for (int i = 0; i < selectedInstance.ControllerIPSuite4.Length; i++) { - case 1: - - @foreach (var v in SimulationRuntimeManager.NetInterfaces) - { - @v.interfaceName - } - NO MAPPING - - - break; - case 2: - - @foreach (var v in SimulationRuntimeManager.NetInterfaces) + var index = i; + var t = $"X{i + 1}"; + + + + + + + + + + + + + + + + + + + @if (SimulationRuntimeManager.NetworkMode == ECommunicationMode.Non_Promiscuous) + { + switch (index + 1) { - @v.interfaceName + case 1: + + @foreach (var v in SimulationRuntimeManager.NetInterfaces) + { + @v.interfaceName + } + NO MAPPING + + + break; + case 2: + + @foreach (var v in SimulationRuntimeManager.NetInterfaces) + { + @v.interfaceName + } + NO MAPPING + + break; + + case 3: + + @foreach (var v in SimulationRuntimeManager.NetInterfaces) + { + @v.interfaceName + } + NO MAPPING + + break; } - NO MAPPING - - break; - - case 3: - - @foreach (var v in SimulationRuntimeManager.NetInterfaces) - { - @v.interfaceName } - NO MAPPING - - break; + } - - } - - } - + - Apply changes - - - @code { - [CascadingParameter] - MudDialogInstance MudDialog + Apply changes + + - { - get; - set; - } - - [Parameter] +@code { + [CascadingParameter] MudDialogInstance MudDialog { get; set; } -public IInstance selectedInstance { get; set; } + [Parameter] public IInstance selectedInstance { get; set; } -public List ips = new List(); -public List subnets = new List(); -public List gateways = new List(); + public List ips = new List(); + public List subnets = new List(); + public List gateways = new List(); -public List ipv4Masks = new List(); -public List subnetMask = new List(); -public List gatewayMask = new List(); + public List ipv4Masks = new List(); + public List subnetMask = new List(); + public List gatewayMask = new List(); -protected override void OnInitialized() -{ - base.OnInitialized(); - foreach (var ipSuite in selectedInstance.ControllerIPSuite4) + protected override void OnInitialized() { - ips.Add(ipSuite.IPAddress.IPString); - subnets.Add(ipSuite.SubnetMask.IPString); - gateways.Add(ipSuite.DefaultGateway.IPString); - ipv4Masks.Add(RegexMask.IPv4()); - subnetMask.Add(RegexMask.IPv4()); - gatewayMask.Add(RegexMask.IPv4()); + base.OnInitialized(); + foreach (var ipSuite in selectedInstance.ControllerIPSuite4) + { + ips.Add(ipSuite.IPAddress.IPString); + subnets.Add(ipSuite.SubnetMask.IPString); + gateways.Add(ipSuite.DefaultGateway.IPString); + ipv4Masks.Add(RegexMask.IPv4()); + subnetMask.Add(RegexMask.IPv4()); + gatewayMask.Add(RegexMask.IPv4()); + } } -} - -public string getInterfaceByIndex(int index) -{ - return SimulationRuntimeManager.NetInterfaces.FirstOrDefault(interf => interf.interfaceIndex == index).interfaceName; -} -public void setIp() -{ - for (int i = 0; i < selectedInstance.ControllerIPSuite4.Length; i++) + public string getInterfaceByIndex(int index) { - SIPSuite4 ipSuite = new SIPSuite4(); - ipSuite.IPAddress = new SIP { IPString = ips[i] }; - ipSuite.SubnetMask = new SIP { IPString = subnets[i] }; - ipSuite.DefaultGateway = new SIP { IPString = gateways[i] }; - selectedInstance.SetIPSuite((uint)i, ipSuite, true); + return SimulationRuntimeManager.NetInterfaces.FirstOrDefault(interf => interf.interfaceIndex == index).interfaceName; } - MudDialog.Close(); -} + public void setIp() + { + for (int i = 0; i < selectedInstance.ControllerIPSuite4.Length; i++) + { + SIPSuite4 ipSuite = new SIPSuite4(); + ipSuite.IPAddress = new SIP { IPString = ips[i] }; + ipSuite.SubnetMask = new SIP { IPString = subnets[i] }; + ipSuite.DefaultGateway = new SIP { IPString = gateways[i] }; + selectedInstance.SetIPSuite((uint)i, ipSuite, true); + } + + MudDialog.Close(); + } // NET INTERFACE MAPPING -string emptyString = ""; + string emptyString = ""; -public string getInterface(int index) -{ - switch (index) + public string getInterface(int index) { - case 1: - return interface_1; - - case 2: - return interface_2; - case 3: - return interface_3; - default: - return ""; + switch (index) + { + case 1: + return interface_1; + + case 2: + return interface_2; + case 3: + return interface_3; + default: + return ""; + } } -} -private string _interface_1; + private string _interface_1; -public string interface_1 -{ - get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE1)).interfaceName; - set + public string interface_1 { - try + get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE1)).interfaceName; + set { - if (value == emptyString) + try { - selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE1, 0); + if (value == emptyString) + { + selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE1, 0); + } + else + { + selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE1, value); + } + + _interface_1 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE1)).interfaceName; } - else + catch (Exception e) { - selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE1, value); + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); } - - _interface_1 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE1)).interfaceName; - } - catch (Exception e) - { - Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); } } -} -private string _interface_2; + private string _interface_2; -public string interface_2 -{ - get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE2)).interfaceName; - set + public string interface_2 { - try + get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE2)).interfaceName; + set { - if (value == emptyString) + try { - selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE2, 0); + if (value == emptyString) + { + selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE2, 0); + } + else + { + selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE2, value); + } + + _interface_2 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE2)).interfaceName; } - else + catch (Exception e) { - selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE2, value); + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); } - - _interface_2 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE2)).interfaceName; - } - catch (Exception e) - { - Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); } } -} -private string _interface_3; + private string _interface_3; -public string interface_3 -{ - get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE3)).interfaceName; - set + public string interface_3 { - try + get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE3)).interfaceName; + set { - if (value == emptyString) + try { - selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE3, 0); + if (value == emptyString) + { + selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE3, 0); + } + else + { + selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE3, value); + } + + _interface_3 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE3)).interfaceName; } - else + catch (Exception e) { - selectedInstance.SetNetInterfaceMapping(EPLCInterface.IE3, value); + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); } + } + } - _interface_3 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == selectedInstance.GetNetInterfaceMapping(EPLCInterface.IE3)).interfaceName; + public void setInterface(EPLCInterface interfaceID, uint value) + { + try + { + selectedInstance.SetNetInterfaceMapping(interfaceID, value); } catch (Exception e) { Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); } } -} -public void setInterface(EPLCInterface interfaceID, uint value) -{ - try + public void setInterface(EPLCInterface interfaceID, string value) { - selectedInstance.SetNetInterfaceMapping(interfaceID, value); - } - catch (Exception e) - { - Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); + try + { + selectedInstance.SetNetInterfaceMapping(interfaceID, value); + } + catch (Exception e) + { + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); + } } -} -public void setInterface(EPLCInterface interfaceID, string value) -{ - try - { - selectedInstance.SetNetInterfaceMapping(interfaceID, value); - } - catch (Exception e) - { - Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); - } -} } \ No newline at end of file diff --git a/PLCsimAdvanced_Manager/MainLayout.razor b/PLCsimAdvanced_Manager/MainLayout.razor index b59fcc6..228102c 100644 --- a/PLCsimAdvanced_Manager/MainLayout.razor +++ b/PLCsimAdvanced_Manager/MainLayout.razor @@ -1,5 +1,6 @@ @using MudBlazor @using Octokit +@using Siemens.Simatic.Simulation.Runtime @using Color = MudBlazor.Color @inherits LayoutComponentBase @inject IDialogService DialogService @@ -14,6 +15,8 @@ + + PLCSim Advanced Manager @@ -32,6 +35,16 @@ Check for update + + Overview + + @foreach(var context in SimulationRuntimeManager.RegisteredInstanceInfo) + { + @context.Name + } + + Settings + @Body @@ -40,6 +53,13 @@ @code { + private bool _open = false; + + private void ToggleDrawer() + { + _open = !_open; + } + string version = "0.0.6"; bool newVersionAvailable = false; @@ -58,6 +78,10 @@ }, }; + private string GetInstanceHref(string instanceName) + { + return $"instance/{instanceName}"; + } private void OpenPsaInfoDialog() { diff --git a/PLCsimAdvanced_Manager/Pages/Instance.razor b/PLCsimAdvanced_Manager/Pages/Instance.razor new file mode 100644 index 0000000..497666f --- /dev/null +++ b/PLCsimAdvanced_Manager/Pages/Instance.razor @@ -0,0 +1,633 @@ +@inject ISnackbar Snackbar +@page "/instance/{instanceName}" +@using Siemens.Simatic.Simulation.Runtime +@using Color = MudBlazor.Color + +
+
+
+ Instance view +
+ + + + + +
+ + @InstanceName + @* *@ + + + + + + MRES + + +
+
+ + + + Size Snapshots: @rootDirectorySize + + Create Snapshot + + + Name + Timestamp + Actions + + @foreach (var snapshot in GetSnapshots()) + { + var dir = snapshot; // Create a local copy to avoid issues with the foreach loop + var isRunning = SelectedInstance.OperatingState != EOperatingState.Off; + + + + + + + + @Path.GetFileName(snapshot) + + + + + + @File.GetLastWriteTime(snapshot).ToShortDateString()
@File.GetLastWriteTime(snapshot).ToShortTimeString() +
+
+ + + + + + + +
+ } +
+
+
+ + + @* *@ + + + + + PLC Family + @SelectedInstance.CPUType.ToString() + + + + + Name + @SelectedInstance.Info.Name + + + + + ID + @SelectedInstance.Info.ID + + + + + Controller Name + @SelectedInstance.ControllerName + + + + + License Status + @SelectedInstance.LicenseStatus + + + + + Controller Short Designation + @SelectedInstance.ControllerShortDesignation + + + + + Communication Interface + @SelectedInstance.CommunicationInterface.ToString() + + + + + Strict Motion Timing + + + + + + Operating Mode + @SelectedInstance.OperatingMode.ToString() + + + + + System Time + @SelectedInstance.SystemTime + + + + + Scale Factor + @SelectedInstance.ScaleFactor.ToString() + + + + + Overwrite Minimum Cycle Time + @SelectedInstance.OverwrittenMinimalCycleTime_ns.ToString() + + + + + Send Sync Event in Default Mode Enabled + @SelectedInstance.IsSendSyncEventInDefaultModeEnabled.ToString() + + + + + Storage Path + @SelectedInstance.StoragePath + + + + + + @* *@ + + + + + + @for (int i = 0; i < SelectedInstance.ControllerIPSuite4.Length; i++) + { + var index = i; + var t = $"X{i + 1}"; + + + + + + + + + + + + + + + + + + + @if (SimulationRuntimeManager.NetworkMode == ECommunicationMode.Non_Promiscuous) + { + switch (index + 1) + { + case 1: + + @foreach (var v in SimulationRuntimeManager.NetInterfaces) + { + @v.interfaceName + } + NO MAPPING + + + break; + case 2: + + @foreach (var v in SimulationRuntimeManager.NetInterfaces) + { + @v.interfaceName + } + NO MAPPING + + break; + + case 3: + + @foreach (var v in SimulationRuntimeManager.NetInterfaces) + { + @v.interfaceName + } + NO MAPPING + + break; + } + } + + } + + + Apply changes + + + +
+ + +
+ + + + + + + + + + + + + + + + + +
+ +
+
+ +@code { + [Parameter] public string InstanceName { get; set; } + + private IInstance SelectedInstance; + + + protected override async Task OnInitializedAsync() + { + OnSelectInstance(InstanceName); + + + base.OnInitialized(); + var path = Path.Combine(SelectedInstance.StoragePath, SnapshotFolder); + // Check if the directory exists, if not, create it + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + rootDirectorySize = GetDirectorySize(path); + watcher = new FileSystemWatcher(path) + { + NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName, + IncludeSubdirectories = true + }; + + watcher.Changed += OnChanged; + watcher.Created += OnChanged; + watcher.Deleted += OnChanged; + + watcher.EnableRaisingEvents = true; + + foreach (var ipSuite in SelectedInstance.ControllerIPSuite4) + + { + ips.Add(ipSuite.IPAddress.IPString); + subnets.Add(ipSuite.SubnetMask.IPString); + gateways.Add(ipSuite.DefaultGateway.IPString); + ipv4Masks.Add(RegexMask.IPv4()); + subnetMask.Add(RegexMask.IPv4()); + gatewayMask.Add(RegexMask.IPv4()); + } + } + + private void OnSelectInstance(string name) + { + try + { + SelectedInstance = SimulationRuntimeManager.CreateInterface(name); + SelectedInstance.OnOperatingStateChanged += OnSelectedInstanceOnOnOperatingStateChanged; + StateHasChanged(); + } + catch (Exception e) + { + Snackbar.Add($"Error while selecting instance {name}: {e.Message}", Severity.Error); + } + } + + private void OnSelectedInstanceOnOnOperatingStateChanged(IInstance inSender, ERuntimeErrorCode inErrorCode, DateTime inDateTime, EOperatingState inPrevState, EOperatingState inOperatingState) + { + if (inSender != SelectedInstance) + { + return; + } + + InvokeAsync(StateHasChanged); + } + + + private bool renameDialog; + private string newDirectoryName; + + + static string SnapshotFolder = "Snapshots"; + static string label; + private bool setNameDialog; + private string directoryToRename; + private string newSnapshotName; + private string rootDirectorySize; + private FileSystemWatcher watcher; + + // protected override void OnInitialized() + // { + // base.OnInitialized(); + // var path = Path.Combine(SelectedInstance.StoragePath, SnapshotFolder); + // // Check if the directory exists, if not, create it + // if (!Directory.Exists(path)) + // { + // Directory.CreateDirectory(path); + // } + // + // rootDirectorySize = GetDirectorySize(path); + // watcher = new FileSystemWatcher(path) + // { + // NotifyFilter = NotifyFilters.LastAccess | NotifyFilters.LastWrite | NotifyFilters.FileName | NotifyFilters.DirectoryName, + // IncludeSubdirectories = true + // }; + // + // watcher.Changed += OnChanged; + // watcher.Created += OnChanged; + // watcher.Deleted += OnChanged; + // + // watcher.EnableRaisingEvents = true; + // } + + private string[] GetSnapshots() + { + var path = Path.Combine(SelectedInstance.StoragePath, SnapshotFolder); + label = Path.Combine(path, "test"); + if (!Directory.Exists(path)) + { + return Array.Empty(); + } + + var snapshots = Directory.GetFiles(path); + var orderedSnapshots = snapshots.OrderByDescending(file => File.GetLastWriteTime(file)).ToArray(); + return orderedSnapshots; + } + + + private void OpenRenameDialog(string directory) + { + renameDialog = true; + directoryToRename = directory; + } + + private void CreateSnapshot() + { + try + { + var path = Path.Combine(SelectedInstance.StoragePath, SnapshotFolder); + if (!Directory.Exists(path)) + { + Directory.CreateDirectory(path); + } + + var fullpath = Path.Combine(path, newSnapshotName); + + SelectedInstance.ArchiveStorage(fullpath); + } + catch (Exception e) + { + Snackbar.Add($"Failed to create snapshot {newSnapshotName}. Error: {e.Message}", Severity.Error); + } + finally + { + setNameDialog = false; + } + } + + private void OnChanged(object sender, FileSystemEventArgs e) + { + InvokeAsync(() => + { + rootDirectorySize = GetDirectorySize(SimulationRuntimeManager.DefaultStoragePath); + StateHasChanged(); + }); + } + + private void RenameDirectory() + { + try + { + string newDirectoryPath = Path.Combine(Path.GetDirectoryName(directoryToRename), newDirectoryName); + Directory.Move(directoryToRename, newDirectoryPath); + Snackbar.Add($"Directory {directoryToRename} renamed to {newDirectoryName} successfully.", Severity.Success); + } + catch (Exception e) + { + Snackbar.Add($"Failed to rename directory {directoryToRename}. Error: {e.Message}", Severity.Error); + } + finally + { + renameDialog = false; + } + } + + + private string GetDirectorySize(string directory) + { + try + { + var directoryInfo = new DirectoryInfo(directory); + long sizeInBytes = directoryInfo.EnumerateFiles("*", SearchOption.AllDirectories).Sum(file => file.Length); + double sizeInKB = (double)sizeInBytes / 1024; + double sizeInMB = sizeInKB / 1024; + double sizeInGB = sizeInMB / 1024; + + if (sizeInGB > 1) + return $"{sizeInGB:0.##} GB"; + else if (sizeInMB > 1) + return $"{sizeInMB:0.##} MB"; + else + return $"{sizeInKB:0.##} KB"; + } + catch (Exception) + { + return "Size not available"; + } + } + + private void DeleteFile(string filePath) + { + try + { + File.Delete(filePath); + Snackbar.Add($"File {filePath} deleted successfully.", Severity.Success); + } + catch (Exception e) + { + Snackbar.Add($"Failed to delete file {filePath}. Error: {e.Message}", Severity.Error); + } + } + + + // IP settings + public List ips = new List(); + public List subnets = new List(); + public List gateways = new List(); + + public List ipv4Masks = new List(); + public List subnetMask = new List(); + public List gatewayMask = new List(); + + + public string getInterfaceByIndex(int index) + { + return SimulationRuntimeManager.NetInterfaces.FirstOrDefault(interf => interf.interfaceIndex == index).interfaceName; + } + + public void setIp() + { + for (int i = 0; i < SelectedInstance.ControllerIPSuite4.Length; i++) + { + SIPSuite4 ipSuite = new SIPSuite4(); + ipSuite.IPAddress = new SIP { IPString = ips[i] }; + ipSuite.SubnetMask = new SIP { IPString = subnets[i] }; + ipSuite.DefaultGateway = new SIP { IPString = gateways[i] }; + SelectedInstance.SetIPSuite((uint)i, ipSuite, true); + } + } + + +// NET INTERFACE MAPPING + string emptyString = ""; + + public string getInterface(int index) + { + switch (index) + { + case 1: + return interface_1; + + case 2: + return interface_2; + case 3: + return interface_3; + default: + return ""; + } + } + + private string _interface_1; + + public string interface_1 + { + get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == SelectedInstance.GetNetInterfaceMapping(EPLCInterface.IE1)).interfaceName; + set + { + try + { + if (value == emptyString) + { + SelectedInstance.SetNetInterfaceMapping(EPLCInterface.IE1, 0); + } + else + { + SelectedInstance.SetNetInterfaceMapping(EPLCInterface.IE1, value); + } + + _interface_1 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == SelectedInstance.GetNetInterfaceMapping(EPLCInterface.IE1)).interfaceName; + } + catch (Exception e) + { + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); + } + } + } + + private string _interface_2; + + public string interface_2 + { + get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == SelectedInstance.GetNetInterfaceMapping(EPLCInterface.IE2)).interfaceName; + set + { + try + { + if (value == emptyString) + { + SelectedInstance.SetNetInterfaceMapping(EPLCInterface.IE2, 0); + } + else + { + SelectedInstance.SetNetInterfaceMapping(EPLCInterface.IE2, value); + } + + _interface_2 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == SelectedInstance.GetNetInterfaceMapping(EPLCInterface.IE2)).interfaceName; + } + catch (Exception e) + { + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); + } + } + } + + private string _interface_3; + + public string interface_3 + { + get => SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == SelectedInstance.GetNetInterfaceMapping(EPLCInterface.IE3)).interfaceName; + set + { + try + { + if (value == emptyString) + { + SelectedInstance.SetNetInterfaceMapping(EPLCInterface.IE3, 0); + } + else + { + SelectedInstance.SetNetInterfaceMapping(EPLCInterface.IE3, value); + } + + _interface_3 = SimulationRuntimeManager.NetInterfaces.FirstOrDefault(i => i.interfaceIndex == SelectedInstance.GetNetInterfaceMapping(EPLCInterface.IE3)).interfaceName; + } + catch (Exception e) + { + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); + } + } + } + + public void setInterface(EPLCInterface interfaceID, uint value) + { + try + { + SelectedInstance.SetNetInterfaceMapping(interfaceID, value); + } + catch (Exception e) + { + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); + } + } + + public void setInterface(EPLCInterface interfaceID, string value) + { + try + { + SelectedInstance.SetNetInterfaceMapping(interfaceID, value); + } + catch (Exception e) + { + Snackbar.Add($"Error setting interface mapping: {e.Message}", Severity.Error); + } + } + +} \ No newline at end of file diff --git a/PLCsimAdvanced_Manager/Pages/PlcOverview.razor b/PLCsimAdvanced_Manager/Pages/PlcOverview.razor index f26111b..ecebbba 100644 --- a/PLCsimAdvanced_Manager/Pages/PlcOverview.razor +++ b/PLCsimAdvanced_Manager/Pages/PlcOverview.razor @@ -13,7 +13,7 @@
- PLC Instances + Overview All instances that are powered on must have the same communication interface (softbus/TCPIP)
@@ -57,38 +57,13 @@
- @if (context.OperatingState == EOperatingState.Off) - { - - } - else if (context.OperatingState == EOperatingState.Run || context.OperatingState == EOperatingState.Stop) - { - - } - else - { - - } - @if (context.OperatingState == EOperatingState.Stop) - { - - } - else if (context.OperatingState == EOperatingState.Run) - { - - } - else - { - - } + +
@try { - @context.Name - ; + @context.Name } catch (Exception e) { @@ -97,25 +72,7 @@
- @* @context.OperatingState *@ - @switch (context.OperatingState) - { - case EOperatingState.Off: - @context.OperatingState - break; - case EOperatingState.Run: - @context.OperatingState - break; - case EOperatingState.Stop: - @context.OperatingState - break; - case EOperatingState.InvalidOperatingState: - @context.OperatingState - break; - default: - @context.OperatingState - break; - } +
diff --git a/PLCsimAdvanced_Manager/Pages/Settings.razor b/PLCsimAdvanced_Manager/Pages/Settings.razor new file mode 100644 index 0000000..4064548 --- /dev/null +++ b/PLCsimAdvanced_Manager/Pages/Settings.razor @@ -0,0 +1,265 @@ +@page "/settings" +@using Siemens.Simatic.Simulation.Runtime +@using System.Net.NetworkInformation + +@using Color = MudBlazor.Color +@inject ISnackbar Snackbar + +
+
+ Settings + + + + + + + + + Initialization + @if (SimulationRuntimeManager.IsInitialized) + { + + } + else + { + + } + + + + + + Runtime Manager Available + @if (SimulationRuntimeManager.IsRuntimeManagerAvailable) + { + + } + else + { + + } + + + + + Strict Motion Timing + @SimulationRuntimeManager.StrictMotionTiming + + + + + + Version + @SimulationRuntimeManager.Version + + + + + Default Storage Path + @SimulationRuntimeManager.DefaultStoragePath + + + + + + + + + + + + Port + + + + @SimulationRuntimeManager.Port + + + + + + Remote Connection Info + + + + + @if (SimulationRuntimeManager.RemoteConnectionInfo.Length == 0) + { +
No Remote Connections
+ } + else + { + foreach (var v in SimulationRuntimeManager.RemoteConnectionInfo) + { +
@v.IP:@v.Port
+ } + } +
+
+
+
+ + +
+ +
+ +
+ +
+ + + + + All instances need to be powered off to make changes here. + + + + Network Mode + + + + + Single Adapter + Multiple Adapter + + + + + + + + + Net Interfaces + Reset Interfaces + + + + @if (SimulationRuntimeManager.NetworkMode == ECommunicationMode.Non_Promiscuous) + { + First set the binding on an instance before enabling here. + } + + + Interface + @* Interface Index *@ + Is Connected + Binding Enabled + @* MAC *@ + Address + Actions + + + + @v.interfaceName
+ @v.interfaceDescription +
+ @* @v.interfaceIndex *@ + + @if (v.isConnected) + { + + + + } + else + { + + + + } + + + @if (v.vSwitchBindingEnabled) + { + + + + } + else + { + + + + } + + @* @v.MACAddress *@ + + @foreach (var address in allNetworkInterfaces.Where(@interface => @interface.Name == v.interfaceName).SelectMany(@interface => @interface.GetIPProperties().UnicastAddresses).Where(@address => @address.Address.AddressFamily == System.Net.Sockets.AddressFamily.InterNetwork)) + { +
@address.Address
+ } +
+ + Set Binding + +
+
+
+
+
+ +
+ + +
+
+ +
+
+ +@code { + + NetworkInterface[] allNetworkInterfaces; + bool allInstancesPoweredOff; + + protected override void OnInitialized() + { + base.OnInitialized(); + allNetworkInterfaces = NetworkInterface.GetAllNetworkInterfaces(); + SimulationRuntimeManager.OnConfigurationChanged += OnSoftwareConfigurationChanged; + checkNoInstancePoweredOn(); + } + + + private void OnSoftwareConfigurationChanged(ERuntimeConfigChanged e, uint p1, uint p2, int p3) + { + switch (e) + { + case ERuntimeConfigChanged.ConnectionOpened: + Snackbar.Add($"Connection Opened to {p1}:{p2}", Severity.Success, + config => { config.HideIcon = true; }); + var ipRemoteRuntimeManager = p1; + var portRemoteRuntimeManager = p2; + break; + case ERuntimeConfigChanged.ConnectionClosed: + Snackbar.Add($"Connection closed {p1}:{p2}", Severity.Success, config => { config.HideIcon = true; }); + var ipRemoteRuntimeManager_x = p1; + var portRemoteRuntimeManager_x = p2; + break; + case ERuntimeConfigChanged.PortOpened: + Snackbar.Add($"Runtime Manager Port Opened {p1}", Severity.Success, + config => { config.HideIcon = true; }); + var openPort = p1; + break; + case ERuntimeConfigChanged.PortClosed: + Snackbar.Add($"Runtime Manager Port Closed", Severity.Success, config => { config.HideIcon = true; }); + break; + case ERuntimeConfigChanged.NetworkModeChanged: + Snackbar.Add($"Network mode changed", Severity.Success, config => { config.HideIcon = true; }); + break; + default: + Snackbar.Add(e.ToString(), Severity.Warning); + break; + } + + InvokeAsync(() => StateHasChanged()); + } + + private void checkNoInstancePoweredOn() + { + allInstancesPoweredOff = SimulationRuntimeManager.RegisteredInstanceInfo.All(instance => SimulationRuntimeManager.CreateInterface(instance.ID).OperatingState == EOperatingState.Off); + } + +} \ No newline at end of file