using System.Diagnostics.CodeAnalysis; using System.Text.Json; namespace TestApp.Configuration { internal class ConfigurationManager { const string _CONFIGURATION_FILE_PATH = "/data/TestApp.json"; private Thread _FileWatcherThread; private FileInfo _LastFileInfo; private Settings _Settings; public Settings Settings { get => _Settings; [MemberNotNull(nameof(_Settings))] private set { _Settings = value; SettingsChanged?.Invoke(this, Settings); } } public ConfigurationManager() { _LastFileInfo = new FileInfo(_CONFIGURATION_FILE_PATH); LoadSettings(); _FileWatcherThread = new Thread(FileWatcherLoop) { IsBackground = true }; _FileWatcherThread.Start(); } private void FileWatcherLoop() { while (true) { var currentFileInfo = new FileInfo(_CONFIGURATION_FILE_PATH); if (ConfigFileChanged(currentFileInfo)) { LoadSettings(); _LastFileInfo = currentFileInfo; } Thread.Sleep(1000); } } private bool ConfigFileChanged(FileInfo currentFileInfo) { if (!currentFileInfo.Exists) { return _LastFileInfo.Exists; } if (!_LastFileInfo.Exists) { return true; } return currentFileInfo.LastWriteTimeUtc != _LastFileInfo.LastWriteTimeUtc; } [MemberNotNull(nameof(_Settings))] private void LoadSettings() { Console.WriteLine("(Re)Loading configuration file ..."); if (!File.Exists(_CONFIGURATION_FILE_PATH)) { InitDefaultSettings(); SaveSettings(); return; } try { var fileContent = File.ReadAllText(_CONFIGURATION_FILE_PATH); var fileSettings = JsonSerializer.Deserialize(fileContent) ?? throw new ArgumentNullException("Deserialization returned null"); Settings = fileSettings; } catch (Exception ex) { Console.WriteLine($"Error reading configuration file '{_CONFIGURATION_FILE_PATH}': {ex.Message}"); if (_Settings is null) { Console.WriteLine("Using build in default settings!"); InitDefaultSettings(); } } } private void SaveSettings() { try { var fileContent = JsonSerializer.Serialize(Settings); File.WriteAllText(_CONFIGURATION_FILE_PATH, fileContent); _LastFileInfo = new FileInfo(_CONFIGURATION_FILE_PATH); } catch (Exception ex) { Console.WriteLine($"Error saving configuration file '{_CONFIGURATION_FILE_PATH}': {ex.Message}"); } } [MemberNotNull(nameof(_Settings))] private void InitDefaultSettings() { Settings = new Settings() { ChargerDriver = Settings.DEFAULT_CHARGER_DRIVER, ChargerAddress = Settings.DEFAULT_CHARGER_ADDRESS, ChargerPort = Settings.DEFAULT_CHARGER_PORT, Mode = 1, ModeSettings = new ModeSettings[] { new ModeSettings { ProcessVariable = ProcessVariable.ActivePowerPositive, SetPoint = 32, NegativePid = new PidSetting() { KP = 0, KI = 1, KD = 0, }, PositivePid = new PidSetting() { KP = 0, KI = 1, KD = 0, } }, new ModeSettings { ProcessVariable = ProcessVariable.ActivePowerNegative, SetPoint = 100, NegativePid = new PidSetting() { KP = 0, KI = 1, KD = 0, }, PositivePid = new PidSetting() { KP = 0, KI = 1, KD = 0, } }, } }; } public event EventHandler? SettingsChanged; } }