Add acDctoDclink in status record and CreateAvg function WIP
This commit is contained in:
parent
71fb914c41
commit
48e766bdde
|
@ -21,6 +21,7 @@ public record StatusRecord
|
||||||
public required AmptStatus? PvOnAcGrid { get; init; }
|
public required AmptStatus? PvOnAcGrid { get; init; }
|
||||||
public required AmptStatus? PvOnAcIsland { get; init; }
|
public required AmptStatus? PvOnAcIsland { get; init; }
|
||||||
public required AcPowerDevice? AcGridToAcIsland { get; init; }
|
public required AcPowerDevice? AcGridToAcIsland { get; init; }
|
||||||
|
public required DcPowerDevice? AcDcToDcLink { get; init; }
|
||||||
public required DcPowerDevice? LoadOnDc { get; init; }
|
public required DcPowerDevice? LoadOnDc { get; init; }
|
||||||
public required RelaysRecord? Relays { get; init; }
|
public required RelaysRecord? Relays { get; init; }
|
||||||
public required AmptStatus? PvOnDc { get; init; }
|
public required AmptStatus? PvOnDc { get; init; }
|
||||||
|
|
|
@ -72,6 +72,7 @@ internal static class Program
|
||||||
{
|
{
|
||||||
while (true)
|
while (true)
|
||||||
{
|
{
|
||||||
|
//CreateAverage();
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
await Run();
|
await Run();
|
||||||
|
@ -120,14 +121,18 @@ internal static class Program
|
||||||
var pvOnAcIsland = pvOnAcIslandDevice.Read();
|
var pvOnAcIsland = pvOnAcIslandDevice.Read();
|
||||||
|
|
||||||
var gridBusToIslandBus = Topology.CalculateGridBusToIslandBusPower(pvOnAcIsland, loadOnAcIsland, acDc);
|
var gridBusToIslandBus = Topology.CalculateGridBusToIslandBusPower(pvOnAcIsland, loadOnAcIsland, acDc);
|
||||||
|
|
||||||
var gridBusLoad = devices.LoadOnAcGrid.DeviceState == DeviceState.Disabled ?
|
var gridBusLoad = devices.LoadOnAcGrid.DeviceState == DeviceState.Disabled
|
||||||
new AcPowerDevice { Power = 0 } :
|
? new AcPowerDevice { Power = 0 }
|
||||||
Topology.CalculateGridBusLoad(gridMeter, pvOnAcGrid, gridBusToIslandBus);
|
: Topology.CalculateGridBusLoad(gridMeter, pvOnAcGrid, gridBusToIslandBus);
|
||||||
|
|
||||||
var dcLoad = devices.LoadOnDc.DeviceState == DeviceState.Disabled ?
|
var dcLoad = devices.LoadOnDc.DeviceState == DeviceState.Disabled
|
||||||
new DcPowerDevice() { Power = 0 } :
|
? new DcPowerDevice { Power = 0 }
|
||||||
Topology.CalculateDcLoad(acDc, pvOnDc, dcDc);
|
: Topology.CalculateDcLoad(acDc, pvOnDc, dcDc);
|
||||||
|
|
||||||
|
var acDcToDcLink = devices.LoadOnDc.DeviceState == DeviceState.Disabled ?
|
||||||
|
Topology.CalculateAcDcToDcLink(pvOnDc, dcDc, acDc)
|
||||||
|
: new DcPowerDevice{ Power = acDc.Dc.Power};
|
||||||
|
|
||||||
return new StatusRecord
|
return new StatusRecord
|
||||||
{
|
{
|
||||||
|
@ -136,32 +141,31 @@ internal static class Program
|
||||||
Battery = battery,
|
Battery = battery,
|
||||||
Relays = relays,
|
Relays = relays,
|
||||||
GridMeter = gridMeter,
|
GridMeter = gridMeter,
|
||||||
|
|
||||||
PvOnAcGrid = pvOnAcGrid,
|
PvOnAcGrid = pvOnAcGrid,
|
||||||
PvOnAcIsland = pvOnAcIsland,
|
PvOnAcIsland = pvOnAcIsland,
|
||||||
PvOnDc = pvOnDc,
|
PvOnDc = pvOnDc,
|
||||||
|
|
||||||
AcGridToAcIsland = gridBusToIslandBus,
|
AcGridToAcIsland = gridBusToIslandBus,
|
||||||
|
AcDcToDcLink = acDcToDcLink,
|
||||||
LoadOnAcGrid = gridBusLoad,
|
LoadOnAcGrid = gridBusLoad,
|
||||||
LoadOnAcIsland = loadOnAcIsland,
|
LoadOnAcIsland = loadOnAcIsland,
|
||||||
LoadOnDc = dcLoad,
|
LoadOnDc = dcLoad,
|
||||||
|
|
||||||
StateMachine = StateMachine.Default,
|
StateMachine = StateMachine.Default,
|
||||||
EssControl = EssControl.Default,
|
EssControl = EssControl.Default,
|
||||||
Log = new SystemLog{Led = LedState.Green, Message = null}, //TODO: Put real stuff
|
Log = new SystemLog { Led = LedState.Green, Message = null }, //TODO: Put real stuff
|
||||||
Config = config // load from disk every iteration, so config can be changed while running
|
Config = config // load from disk every iteration, so config can be changed while running
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
void WriteControl(StatusRecord r)
|
void WriteControl(StatusRecord r)
|
||||||
{
|
{
|
||||||
if (r.Relays is not null)
|
if (r.Relays is not null)
|
||||||
saliMaxRelaysDevice.Write(r.Relays);
|
saliMaxRelaysDevice.Write(r.Relays);
|
||||||
|
|
||||||
acDcDevices.Write(r.AcDc);
|
acDcDevices.Write(r.AcDc);
|
||||||
dcDcDevices.Write(r.DcDc);
|
dcDcDevices.Write(r.DcDc);
|
||||||
}
|
}
|
||||||
|
|
||||||
Console.WriteLine("press ctrl-c to stop");
|
Console.WriteLine("press ctrl-c to stop");
|
||||||
|
|
||||||
while (true)
|
while (true)
|
||||||
|
@ -180,23 +184,23 @@ internal static class Program
|
||||||
Watchdog.NotifyAlive();
|
Watchdog.NotifyAlive();
|
||||||
|
|
||||||
var record = ReadStatus();
|
var record = ReadStatus();
|
||||||
|
|
||||||
|
|
||||||
/*
|
// var i = 2;
|
||||||
var i = 2;
|
// if (record.Battery is not null)
|
||||||
if (record.Battery is not null)
|
// {
|
||||||
{
|
// foreach (var r in record.Battery.Devices)
|
||||||
foreach (var r in record.Battery.Devices)
|
// {
|
||||||
{
|
// //var y = r.BusCurrentHex;
|
||||||
var y = r.BusCurrentHex;
|
// //var x = r.CellsCurrentHex;
|
||||||
var x = r.CellsCurrentHex;
|
//
|
||||||
|
// r.FwVersion.WriteLine(" serial number " + i);
|
||||||
r.SerialNumber.WriteLine(" serial number " + i);
|
//
|
||||||
|
// ("--------------").WriteLine();
|
||||||
("--------------").WriteLine();
|
//
|
||||||
|
// i++;
|
||||||
i++;
|
// }
|
||||||
}
|
// }i
|
||||||
}*/
|
|
||||||
|
|
||||||
|
|
||||||
//record.Log = new SystemLog
|
//record.Log = new SystemLog
|
||||||
|
@ -215,8 +219,9 @@ internal static class Program
|
||||||
record.ControlConstants();
|
record.ControlConstants();
|
||||||
record.ControlSystemState();
|
record.ControlSystemState();
|
||||||
|
|
||||||
$"{DateTime.Now.ToUnixTime()} : {record.StateMachine.State}: {record.StateMachine.Message}".WriteLine().LogInfo();
|
$"{DateTime.Now.Round(UpdateInterval).ToUnixTime()} : {record.StateMachine.State}: {record.StateMachine.Message}".WriteLine()
|
||||||
|
.LogInfo();
|
||||||
|
|
||||||
var essControl = record.ControlEss().WriteLine().LogInfo();
|
var essControl = record.ControlEss().WriteLine().LogInfo();
|
||||||
|
|
||||||
record.EssControl = essControl;
|
record.EssControl = essControl;
|
||||||
|
@ -366,6 +371,107 @@ internal static class Program
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void CreateAverage()
|
||||||
|
{
|
||||||
|
string myDirectory = "LogDirectoryNew";
|
||||||
|
List<Dictionary<string, string>> csvDataList = new List<Dictionary<string, string>>();
|
||||||
|
|
||||||
|
// Get all CSV files in the specified directory
|
||||||
|
string[] csvFiles = Directory.GetFiles(myDirectory, "*.csv");
|
||||||
|
|
||||||
|
List<Double> socList = new List<Double>();
|
||||||
|
List<Double> pvPowerList = new List<Double>();
|
||||||
|
List<Double> batteryPowerList = new List<Double>();
|
||||||
|
|
||||||
|
foreach (var csvFile in csvFiles)
|
||||||
|
{
|
||||||
|
using (var reader = new StreamReader(csvFile))
|
||||||
|
{
|
||||||
|
// Read the CSV file and store data in dictionary
|
||||||
|
Dictionary<string, string> csvData = new Dictionary<string, string>();
|
||||||
|
|
||||||
|
while (!reader.EndOfStream)
|
||||||
|
{
|
||||||
|
var line = reader.ReadLine();
|
||||||
|
var values = line?.Split(';');
|
||||||
|
|
||||||
|
// Assuming there are always three columns (variable name and its value)
|
||||||
|
if (values is { Length: 3 })
|
||||||
|
{
|
||||||
|
String variableName = values[0].Trim();
|
||||||
|
String variableValue = values[1].Trim();
|
||||||
|
|
||||||
|
// Check if variableValue is a valid number
|
||||||
|
if (IsSoc(variableName))
|
||||||
|
{
|
||||||
|
// Add to the dictionary only if variableValue is a number
|
||||||
|
socList.Add(double.TryParse(variableValue, out double v)? v: 0);
|
||||||
|
}
|
||||||
|
if (IsPvPower(variableName))
|
||||||
|
{
|
||||||
|
// Add to the dictionary only if variableValue is a number
|
||||||
|
pvPowerList.Add(double.TryParse(variableValue, out double v)? v: 0);
|
||||||
|
}
|
||||||
|
if (IsBatteryPower(variableName))
|
||||||
|
{
|
||||||
|
// Add to the dictionary only if variableValue is a number
|
||||||
|
batteryPowerList.Add(double.TryParse(variableValue, out double v)? v: 0);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle cases where variableValue is not a valid number
|
||||||
|
// Console.WriteLine($"Invalid numeric value for variable {variableName}: {variableValue}");
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// Handle invalid CSV format
|
||||||
|
//Console.WriteLine($"Invalid format in file: {csvFile}");
|
||||||
|
//break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
double socAverage = CalculateAverage(socList);
|
||||||
|
double pvPowerAverage = CalculateAverage(pvPowerList);
|
||||||
|
double batteryPowerAverage = CalculateAverage(batteryPowerList);
|
||||||
|
|
||||||
|
// Print the stored CSV data for verification
|
||||||
|
|
||||||
|
Console.WriteLine($"SOC: {socAverage}");
|
||||||
|
Console.WriteLine($"PvPower: {pvPowerAverage}");
|
||||||
|
Console.WriteLine($"Battery: {batteryPowerAverage}");
|
||||||
|
|
||||||
|
Console.WriteLine("----------");
|
||||||
|
|
||||||
|
Console.WriteLine("CSV data reading and storage completed.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// Custom method to check if a string is numeric
|
||||||
|
private static bool IsSoc(string value)
|
||||||
|
{
|
||||||
|
return value == "/Battery/Soc";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsPvPower(string value)
|
||||||
|
{
|
||||||
|
return value == "/PvOnDc/Dc/Power";
|
||||||
|
}
|
||||||
|
|
||||||
|
private static bool IsBatteryPower(string value)
|
||||||
|
{
|
||||||
|
return value == "/Battery/Dc/Power";
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// Method to calculate average for a variableValue in a dictionary
|
||||||
|
static double CalculateAverage( List<Double> data)
|
||||||
|
{
|
||||||
|
// Calculate and return the moving average
|
||||||
|
double movingAverage = data.Average();
|
||||||
|
return movingAverage;
|
||||||
|
}
|
||||||
}
|
}
|
|
@ -54,8 +54,9 @@ namespace InnovEnergy.App.SaliMax;
|
||||||
// DC side
|
// DC side
|
||||||
// h + i - j - k = 0 [eq3]
|
// h + i - j - k = 0 [eq3]
|
||||||
//
|
//
|
||||||
// g = h assuming no losses in ACDC
|
// if Dc load not existing, h = i - k [eq4]
|
||||||
// k = l assuming no losses in DCDC
|
|
||||||
|
// k = l assuming no losses in DCDC // this is changed now l is equal total battery power
|
||||||
// j = h + i - k [eq3]
|
// j = h + i - k [eq3]
|
||||||
|
|
||||||
|
|
||||||
|
@ -69,7 +70,7 @@ public static class Topology
|
||||||
var e = status.PvOnAcIsland?.Dc.Power.Value;
|
var e = status.PvOnAcIsland?.Dc.Power.Value;
|
||||||
var f = status.LoadOnAcIsland?.Ac.Power.Active;
|
var f = status.LoadOnAcIsland?.Ac.Power.Active;
|
||||||
var g = status.AcDc.Dc.Power.Value;
|
var g = status.AcDc.Dc.Power.Value;
|
||||||
var h = g;
|
var h = status.AcDcToDcLink.Power.Value;
|
||||||
var i = status.PvOnDc?.Dc.Power.Value;
|
var i = status.PvOnDc?.Dc.Power.Value;
|
||||||
var k = status.DcDc.Dc.Link.Power.Value;
|
var k = status.DcDc.Dc.Link.Power.Value;
|
||||||
var l = status.Battery is not null ? status.Battery.Dc.Power.Value : 0;
|
var l = status.Battery is not null ? status.Battery.Dc.Power.Value : 0;
|
||||||
|
@ -483,6 +484,23 @@ public static class Topology
|
||||||
return new AcPowerDevice { Power = c };
|
return new AcPowerDevice { Power = c };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//We are fake using the ampt instead of PvOnAc, We dont have a Pv on Ac at the moment and we don't have it classes :TODO
|
||||||
|
public static DcPowerDevice? CalculateAcDcToDcLink(AmptStatus? pvOnDc, DcDcDevicesRecord? dcDc, AcDcDevicesRecord acDc)
|
||||||
|
{
|
||||||
|
var i = pvOnDc?.Dc.Power;
|
||||||
|
var k = dcDc?.Dc.Link.Power; // We dont check on the DcDc because this device is mandatory
|
||||||
|
var g = acDc?.Dc.Power;
|
||||||
|
|
||||||
|
if (i is null || k is null )
|
||||||
|
{
|
||||||
|
return new DcPowerDevice { Power = g };
|
||||||
|
}
|
||||||
|
|
||||||
|
var h = -(i - k); // [eq4]
|
||||||
|
|
||||||
|
return new DcPowerDevice { Power = h };
|
||||||
|
}
|
||||||
|
|
||||||
//We are fake using the ampt instead of PvOnAc, We dont have a Pv on Ac at the moment and we don't have it classes :TODO
|
//We are fake using the ampt instead of PvOnAc, We dont have a Pv on Ac at the moment and we don't have it classes :TODO
|
||||||
public static AcPowerDevice? CalculateGridBusToIslandBusPower(AmptStatus? pvOnAcIsland, EmuMeterRegisters? loadOnAcIsland, AcDcDevicesRecord? acDc)
|
public static AcPowerDevice? CalculateGridBusToIslandBusPower(AmptStatus? pvOnAcIsland, EmuMeterRegisters? loadOnAcIsland, AcDcDevicesRecord? acDc)
|
||||||
{
|
{
|
||||||
|
@ -511,40 +529,5 @@ public static class Topology
|
||||||
|
|
||||||
return new DcPowerDevice { Power = j};
|
return new DcPowerDevice { Power = j};
|
||||||
}
|
}
|
||||||
|
|
||||||
// public static (AcPowerDevice? acGridToAcIsland, AcPowerDevice? loadOnAcGrid, DcPowerDevice? dcPowerDevice)
|
|
||||||
//
|
|
||||||
// CalculateEnergyFlow(EmuMeterRegisters? gridMeter,
|
|
||||||
// AcPowerDevice pvOnAcGrid,
|
|
||||||
// AcPowerDevice pvOnAcIsland,
|
|
||||||
// EmuMeterRegisters? loadOnAcIsland,
|
|
||||||
// AcDcDevicesRecord acDc,
|
|
||||||
// AmptStatus? pvOnDc,
|
|
||||||
// DcDcDevicesRecord dcDc)
|
|
||||||
// {
|
|
||||||
// var gridPower = gridMeter?.Ac.Power.Active;
|
|
||||||
// var islandLoadPower = loadOnAcIsland?.Ac.Power.Active;
|
|
||||||
// var inverterAcPower = acDc.Ac.Power.Active;
|
|
||||||
// var inverterDcPower = acDc.Dc.Power;
|
|
||||||
//
|
|
||||||
// var a = gridPower;
|
|
||||||
// var b = pvOnAcGrid.Power.Active;
|
|
||||||
// var e = pvOnAcIsland.Power.Active;
|
|
||||||
// var f = islandLoadPower;
|
|
||||||
// var g = inverterAcPower;
|
|
||||||
// var h = inverterDcPower;
|
|
||||||
// var i = pvOnDc?.Dc.Power;
|
|
||||||
// var k = dcDc.Dc.Link.Power;
|
|
||||||
// var j = Sum(h, i, -k);
|
|
||||||
// var d = Sum(f, g, -e);
|
|
||||||
// var c = Sum(a, b, -d);
|
|
||||||
//
|
|
||||||
// var acGridToAcIsland = d is null ? null : new AcPowerDevice { Power = d.Value };
|
|
||||||
// var loadOnAcGrid = c is null ? null : new AcPowerDevice { Power = c.Value };
|
|
||||||
// var dcPowerDevice = j is null ? null : new DcPowerDevice { Power = j };
|
|
||||||
//
|
|
||||||
// return (acGridToAcIsland, loadOnAcGrid, dcPowerDevice);
|
|
||||||
// }
|
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue