WIP
This commit is contained in:
144
TestApp/Configuration/ConfigurationManager.cs
Normal file
144
TestApp/Configuration/ConfigurationManager.cs
Normal file
@@ -0,0 +1,144 @@
|
||||
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<Settings>(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<Settings>? SettingsChanged;
|
||||
}
|
||||
}
|
||||
211
TestApp/Configuration/Settings.cs
Normal file
211
TestApp/Configuration/Settings.cs
Normal file
@@ -0,0 +1,211 @@
|
||||
namespace TestApp.Configuration
|
||||
{
|
||||
public class Settings
|
||||
{
|
||||
internal const string DEFAULT_CHARGER_DRIVER = "VestelEvc04";
|
||||
internal const string DEFAULT_CHARGER_ADDRESS = "192.168.178.100";
|
||||
internal const int DEFAULT_CHARGER_PORT = 512;
|
||||
|
||||
public string? ChargerDriver { get; set; }
|
||||
public string? ChargerAddress { get; set; }
|
||||
public int? ChargerPort { get; set; }
|
||||
|
||||
public int Mode { get; set; }
|
||||
|
||||
public ModeSettings[]? ModeSettings { get; set; }
|
||||
}
|
||||
|
||||
|
||||
public class PidSetting {
|
||||
public double KP { get; set; }
|
||||
public double KI { get; set; }
|
||||
public double KD { get; set; }
|
||||
}
|
||||
|
||||
public class ModeSettings {
|
||||
public ProcessVariable ProcessVariable { get; set; }
|
||||
public double SetPoint { get; set; }
|
||||
public PidSetting? PositivePid { get; set; }
|
||||
public PidSetting? NegativePid { get; set; }
|
||||
}
|
||||
|
||||
public enum ProcessVariable
|
||||
{
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerPositive,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyPositive,
|
||||
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerNegative,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyNegative,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerPositive,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyPositive,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerNegative,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyNegative,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerPositive,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyPositive,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerNegative,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyNegative,
|
||||
|
||||
/// <summary>in -</summary>
|
||||
PowerFactor,
|
||||
|
||||
/// <summary>in Hz</summary>
|
||||
SupplyFrequency,
|
||||
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerPositiveL1,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyPositiveL1,
|
||||
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerNegativeL1,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyNegativeL1,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerPositiveL1,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyPositiveL1,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerNegativeL1,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyNegativeL1,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerPositiveL1,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyPositiveL1,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerNegativeL1,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyNegativeL1,
|
||||
|
||||
/// <summary>in A</summary>
|
||||
CurrentL1,
|
||||
|
||||
/// <summary>in V</summary>
|
||||
VoltageL1,
|
||||
|
||||
/// <summary>in -</summary>
|
||||
PowerFactorL1,
|
||||
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerPositiveL2,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyPositiveL2,
|
||||
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerNegativeL2,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyNegativeL2,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerPositiveL2,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyPositiveL2,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerNegativeL2,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyNegativeL2,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerPositiveL2,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyPositiveL2,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerNegativeL2,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyNegativeL2,
|
||||
|
||||
/// <summary>in A</summary>
|
||||
CurrentL2,
|
||||
|
||||
/// <summary>in V</summary>
|
||||
VoltageL2,
|
||||
|
||||
/// <summary>in -</summary>
|
||||
PowerFactorL2,
|
||||
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerPositiveL3,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyPositiveL3,
|
||||
|
||||
/// <summary>in W</summary>
|
||||
ActivePowerNegativeL3,
|
||||
|
||||
/// <summary>in Wh</summary>
|
||||
ActiveEnergyNegativeL3,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerPositiveL3,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyPositiveL3,
|
||||
|
||||
/// <summary>in var</summary>
|
||||
ReactivePowerNegativeL3,
|
||||
|
||||
/// <summary>in varh</summary>
|
||||
ReactiveEnergyNegativeL3,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerPositiveL3,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyPositiveL3,
|
||||
|
||||
/// <summary>in VA</summary>
|
||||
ApparentPowerNegativeL3,
|
||||
|
||||
/// <summary>in VAh</summary>
|
||||
ApparentEnergyNegativeL3,
|
||||
|
||||
/// <summary>in A</summary>
|
||||
CurrentL3,
|
||||
|
||||
/// <summary>in V</summary>
|
||||
VoltageL3,
|
||||
|
||||
/// <summary>in -</summary>
|
||||
PowerFactorL3,
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user