diff --git a/CHANGELOG.md b/CHANGELOG.md
index 8184e08..fec8936 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -7,6 +7,12 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## [Unreleased]
+## [0.1.1] - 2024-08-02
+
+### Features
+- Add a settings tab in the instance view. It is now possible to enable "Register On Startup" and "Power On Startup". When this is enabled the instance will be registered or started when the manager exe is started.
+- Add a persistence.json file in the manager folder to store the settings.
+
## [0.1.0] - 2024-07-25
This is a major update with some new features and improvements, mainly for the UI.
diff --git a/PLCsimAdvanced_Manager/MainLayout.razor b/PLCsimAdvanced_Manager/MainLayout.razor
index dc69b50..4298048 100644
--- a/PLCsimAdvanced_Manager/MainLayout.razor
+++ b/PLCsimAdvanced_Manager/MainLayout.razor
@@ -59,7 +59,7 @@
_open = !_open;
}
- string version = "0.1.0";
+ string version = "0.1.1";
bool newVersionAvailable = false;
// protected override async Task OnInitializedAsync()
diff --git a/PLCsimAdvanced_Manager/Pages/Instance.razor b/PLCsimAdvanced_Manager/Pages/Instance.razor
index e594307..1ddbd5e 100644
--- a/PLCsimAdvanced_Manager/Pages/Instance.razor
+++ b/PLCsimAdvanced_Manager/Pages/Instance.razor
@@ -1,10 +1,12 @@
@inject ISnackbar Snackbar
@page "/instance/{instanceName}"
@using PLCsimAdvanced_Manager.Services
+@using PLCsimAdvanced_Manager.Services.Persistence
@using Siemens.Simatic.Simulation.Runtime
@using Color = MudBlazor.Color
@inject ManagerFacade managerFacade
@inject IDialogService DialogService
+@inject PersistenceHandler persistenceHandler
@@ -247,12 +249,12 @@
case "Invalid":
@word
break;
- case "ShuttingDown":
+ case "ShuttingDown":
+ @word
+ break;
+ case "Startup":
@word
break;
- case "Startup":
- @word
- break;
case "Booting":
@word
break;
@@ -271,12 +273,80 @@
+
+
+
+ On Startup
+ Actions to be taken on this instance, when starting up PLCsim Advanced Manager
+
+
+
+
+
+ Register On Startup
+
+
+
+
+
+ Power On Startup
+
+
+
+
+
+
+
+
+
+
@code {
+
+ private bool _registerOnStartup;
+ private bool _powerOnStartup;
+ private bool _runOnStartup;
+
+ public bool RegisterOnStartup
+ {
+ get => _registerOnStartup;
+ set
+ {
+ if (_registerOnStartup != value)
+ {
+ _registerOnStartup = value;
+ if (!value)
+ {
+ PowerOnStartup = false;
+ }
+ }
+ persistenceHandler.UpdateSettings(SelectedInstance.StoragePath, RegisterOnStartup, PowerOnStartup);
+ }
+ }
+
+ public bool PowerOnStartup
+ {
+ get => _powerOnStartup;
+ set
+ {
+ if (_powerOnStartup != value)
+ {
+ _powerOnStartup = value;
+ if (value)
+ {
+ RegisterOnStartup = true;
+ }
+ }
+ persistenceHandler.UpdateSettings(SelectedInstance.StoragePath, RegisterOnStartup, PowerOnStartup);
+ }
+ }
+
+
+
[Parameter] public string InstanceName { get; set; }
private IInstance SelectedInstance;
@@ -322,6 +392,15 @@
subnetMask.Add(RegexMask.IPv4());
gatewayMask.Add(RegexMask.IPv4());
}
+
+ var settings = persistenceHandler.ReadSettings(SelectedInstance.StoragePath);
+ if (settings != null)
+ {
+ _registerOnStartup = settings.RegisterOnStartup;
+ _powerOnStartup = settings.PowerOnOnStartup;
+ }
+
+
}
private void OnLogsUpdated()
diff --git a/PLCsimAdvanced_Manager/Program.cs b/PLCsimAdvanced_Manager/Program.cs
index fd4903d..33deed6 100644
--- a/PLCsimAdvanced_Manager/Program.cs
+++ b/PLCsimAdvanced_Manager/Program.cs
@@ -7,6 +7,8 @@
using MudBlazor.Services;
using PLCsimAdvanced_Manager.Services;
using PLCsimAdvanced_Manager.Services.Logger;
+using PLCsimAdvanced_Manager.Services.Persistence;
+using PLCsimAdvanced_Manager.Shared;
var builder = WebApplication.CreateBuilder(args);
@@ -37,6 +39,7 @@
builder.Services.AddSingleton();
builder.Services.AddSingleton();
builder.Services.AddSingleton();
+builder.Services.AddSingleton();
var app = builder.Build();
app.Services.GetService();
@@ -54,6 +57,8 @@
app.UseHsts();
}
+StartupTasks.GetPersistantSettings();
+
app.UseHttpsRedirection();
diff --git a/PLCsimAdvanced_Manager/Services/Persistence/PersistenceHandler.cs b/PLCsimAdvanced_Manager/Services/Persistence/PersistenceHandler.cs
new file mode 100644
index 0000000..dcddaea
--- /dev/null
+++ b/PLCsimAdvanced_Manager/Services/Persistence/PersistenceHandler.cs
@@ -0,0 +1,81 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Siemens.Simatic.Simulation.Runtime;
+
+namespace PLCsimAdvanced_Manager.Services.Persistence;
+
+public class PersistenceHandler
+{
+ private Persistence _persistence = new Persistence();
+ private PersistenceSettings _settings = new PersistenceSettings();
+ private string _filePath;
+
+ public PersistenceHandler()
+ {
+ }
+
+ private void setStuffRight(string directory)
+ {
+ var managerDirectory = Path.Combine(directory, "manager");
+ if (!Directory.Exists(managerDirectory))
+ {
+ Directory.CreateDirectory(managerDirectory);
+ }
+
+ _filePath = Path.Combine(managerDirectory, "persistence.json");
+ if (!File.Exists(_filePath))
+ {
+ _settings = new PersistenceSettings();
+ // create persistence.json file
+ _persistence = new Persistence
+ {
+ PersistenceSettings = _settings
+ };
+ var jsonString = JsonSerializer.Serialize(_persistence, new JsonSerializerOptions { WriteIndented = true });
+ File.WriteAllText(_filePath, jsonString);
+ }
+ }
+
+ public void UpdateSettings(string directory, bool registerOnStartup , bool powerOnOnStartup)
+ {
+ setStuffRight(directory);
+ _settings.RegisterOnStartup = registerOnStartup;
+ _settings.PowerOnOnStartup = powerOnOnStartup;
+ SaveSettings();
+ }
+
+ public PersistenceSettings? ReadSettings(string directory)
+ {
+ setStuffRight(directory);
+
+ PersistenceSettings? settings = new PersistenceSettings();
+ if (File.Exists(_filePath))
+ {
+ var settingContent = File.ReadAllText(_filePath);
+ var persistence = JsonSerializer.Deserialize(settingContent);
+ settings = persistence?.PersistenceSettings;
+ }
+
+ return settings;
+ }
+
+ private void SaveSettings()
+ {
+ _persistence.PersistenceSettings = _settings;
+ var jsonString = JsonSerializer.Serialize(_persistence, new JsonSerializerOptions { WriteIndented = true });
+ File.WriteAllText(_filePath, jsonString);
+ }
+}
+
+public class PersistenceSettings
+{
+ [JsonPropertyName("RegisterOnStartup")]
+ public bool RegisterOnStartup { get; set; } = false;
+
+ [JsonPropertyName("PowerOnOnStartup")] public bool PowerOnOnStartup { get; set; } = false;
+}
+
+public class Persistence
+{
+ [JsonPropertyName("Settings")] public PersistenceSettings PersistenceSettings { get; set; } = null;
+}
\ No newline at end of file
diff --git a/PLCsimAdvanced_Manager/Shared/StartupTasks.cs b/PLCsimAdvanced_Manager/Shared/StartupTasks.cs
new file mode 100644
index 0000000..940c835
--- /dev/null
+++ b/PLCsimAdvanced_Manager/Shared/StartupTasks.cs
@@ -0,0 +1,63 @@
+using System.Text.Json;
+using System.Text.Json.Serialization;
+using Siemens.Simatic.Simulation.Runtime;
+
+namespace PLCsimAdvanced_Manager.Shared;
+
+public static class StartupTasks
+{
+ public static void GetPersistantSettings()
+ {
+ var directories = Directory.GetDirectories(@SimulationRuntimeManager.DefaultStoragePath);
+ foreach (var directory in directories)
+ {
+ var managerDirectory = Path.Combine(directory, "manager");
+ if (Directory.Exists(managerDirectory))
+ {
+ var persistentSettingsFile = Path.Combine(managerDirectory, "persistence.json");
+ if (File.Exists(persistentSettingsFile))
+ {
+ var settingContent = File.ReadAllText(persistentSettingsFile);
+ var persistence = JsonSerializer.Deserialize(settingContent);
+ var settings = persistence?.PersistenceSettings;
+
+ // Use the autoStartup boolean value in your logic
+ if (settings?.RegisterOnStartup == true)
+ {
+ var instanceName = Path.GetFileName(directory);
+ try
+ {
+ var instance = SimulationRuntimeManager.RegisterInstance(instanceName);
+
+ if (settings.PowerOnOnStartup)
+ {
+ instance.PowerOn();
+
+ }
+ }
+ catch (Exception e)
+ {
+ Console.WriteLine($"There was an issue with registering the instance [{instanceName}]: {e.Message}");
+
+ }
+ }
+ }
+ }
+
+ }
+ }
+
+}
+
+
+public class PersistenceSettings
+{
+ [JsonPropertyName("RegisterOnStartup")] public bool RegisterOnStartup { get; set; } = false;
+ [JsonPropertyName("PowerOnOnStartup")] public bool PowerOnOnStartup { get; set; } = false;
+}
+
+public class Persistence
+{
+ [JsonPropertyName("Settings")] public PersistenceSettings PersistenceSettings { get; set; } = null;
+
+}
\ No newline at end of file
diff --git a/README.md b/README.md
index 8c75af9..e294710 100644
--- a/README.md
+++ b/README.md
@@ -6,8 +6,10 @@ Check the [**documentation**](https://jasperdekeuk.github.io/PLCsim-Advanced-Man
Download from [**releases**](https://github.com/jasperdekeuk/PLCsim-Advanced-Manager/releases)
+> [!WARNING]
+> The documentation is always behind. Download the latest version to see and play with all the features.
-Goals:
+Features:
- [x] Manage your PLCSIM Advanced instances remote in a **webserver**. This way you don't have to log in to the target PC, but can start
instances over the network
@@ -15,6 +17,7 @@ Goals:
- [x] **Read and write variables** from the PLC (DB/Inputs/Outputs)
- [x] **Advanced network setting**. Being able to set every interface of the instance to an interface of the host machine
- [x] Create **snapshots** and restore them
+- [x] Option for **auto start** instances on startup of PLCsim Advanced Manager. Either just register or completely start the instance when starting the manager application. (see instance settings)
- [ ] Easy **virtual commissioning** by e.g. setting buttons and lights in the UI to the PLC variables
- [ ] **Traces** on the variables for analysis