Merge remote-tracking branch 'origin/main'

This commit is contained in:
Kim 2023-09-18 13:21:44 +02:00
commit 315fab8463
11 changed files with 84 additions and 42 deletions

View File

@ -1,5 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>InnovEnergy.App.EmuMeterDriver</RootNamespace>
</PropertyGroup>
<Import Project="../InnovEnergy.App.props" />
<ItemGroup>
@ -13,5 +18,7 @@
<ItemGroup>
<PackageReference Include="CliWrap" Version="3.6.0" />
</ItemGroup>
</Project>

View File

@ -12,7 +12,7 @@ public readonly struct Nic
private readonly JsonNode _Node;
public Nic(JsonNode node)
private Nic(JsonNode node)
{
_Node = node;
}
@ -134,11 +134,11 @@ public readonly struct Nic
.ExecuteBufferedAsync();
return JsonNode
.Parse(result.StandardOutput)!
.AsArray()
.Where(n=>n != null)
.Select(n=> new Nic(n!))
.ToList();
.Parse(result.StandardOutput)!
.AsArray()
.Where(n => n != null)
.Select(n => new Nic(n!))
.ToList();
}
catch
{

View File

@ -188,7 +188,13 @@ public static class Controller
private static Boolean MustDoCalibrationCharge(this StatusRecord statusRecord)
{
return statusRecord.Battery?.CalibrationChargeRequested ?? false;
var calibrationChargeForced = statusRecord.Config.ForceCalibrationCharge;
var batteryCalibrationChargeRequested = statusRecord.Battery?.CalibrationChargeRequested?? false ;
var mustDoCalibrationCharge = batteryCalibrationChargeRequested || calibrationChargeForced;
return mustDoCalibrationCharge;
}

View File

@ -170,6 +170,16 @@ internal static class Program
Watchdog.NotifyAlive();
var record = ReadStatus();
// If control Special Error return true, we must stop the system.(break;)
var specialErrorOccured = record.ControlSpecialError();
if (specialErrorOccured.Item1)
{
//stop the system
//return
specialErrorOccured.Item2.WriteLine();
}
record.ControlConstants();
record.ControlSystemState();
@ -202,6 +212,36 @@ internal static class Program
// ReSharper disable once FunctionNeverReturns
}
private static (Boolean, String) ControlSpecialError (this StatusRecord r) // to find a better name
{
// Those errors must not occurs. Stop the system in case this is happen.
var isSpecialErrorOccured = false;
var errorMessage = "No Error";
// 1. relay0 is open and K2 Close.
if (r.Relays is { K2ConnectIslandBusToGridBus: false, K2IslandBusIsConnectedToGridBus: true } )
{
isSpecialErrorOccured = true;
errorMessage = " Contradiction: R0 is opening the K2 but the K2 is still close ";
}
// 2. If K1 is open, K2 must be open .
if (r.Relays is { K1GridBusIsConnectedToGrid: false, K2IslandBusIsConnectedToGridBus: true } )
{
isSpecialErrorOccured = true;
errorMessage = " Contradiction: K1 is open but the K2 is still close ";
}
// 3. If FI error is occured, K2 must be open.
if (r.Relays is { FiError: true, K2IslandBusIsConnectedToGridBus: true } )
{
isSpecialErrorOccured = true;
errorMessage = " Contradiction: Fi error occured but the K2 is still close ";
}
return (isSpecialErrorOccured, errorMessage);
}
private static void ControlConstants(this StatusRecord r)
{
@ -228,7 +268,7 @@ internal static class Program
dcDevices.ForEach(d => d.Control.VoltageLimits.MaxBatteryVoltage = configFile.MaxChargeBatteryVoltage);
dcDevices.ForEach(d => d.Control.VoltageLimits.MinBatteryVoltage = configFile.MinDischargeBatteryVoltage);
dcDevices.ForEach(d => d.Control.ControlMode = DcControlMode.VoltageDroop);
r.DcDc.ResetAlarms();
r.AcDc.ResetAlarms();
}

View File

@ -19,8 +19,6 @@ public class RelaysDevice
catch (Exception e)
{
$"Failed to read from {nameof(RelaysDevice)}\n{e}".LogError();
// TODO: log
return null;
}
}

View File

@ -15,7 +15,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
public required Double MinSoc { get; set; }
public required UnixTime LastEoc { get; set; }
public required Boolean ForceCalibrationCharge { get; set; }
public required Double PConstant { get; set; }
public required Double GridSetPoint { get; set; }
public required Double BatterySelfDischargePower { get; set; }
@ -40,7 +40,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
public static Config Default => new()
{
MinSoc = 20,
LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS
ForceCalibrationCharge = false,
PConstant = .5,
GridSetPoint = 0,
BatterySelfDischargePower = 200,
@ -102,7 +102,7 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
public static Config Default => new()
{
MinSoc = 20,
LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS
ForceCalibrationCharge = false,
PConstant = .5,
GridSetPoint = 0,
BatterySelfDischargePower = 200,

View File

@ -7,6 +7,7 @@ namespace InnovEnergy.App.SaliMax;
public static class Watchdog
{
// "it is generally recommended to ignore the return value of this call. "
// ReSharper disable once StringLiteralTypo
[DllImport("libsystemd.so.0")]
private static extern Int32 sd_notify(Int32 unsetEnvironment, String state);

View File

@ -12,7 +12,6 @@ using Strings = IReadOnlyList<String>;
[SuppressMessage("ReSharper", "ConvertToAutoProperty")]
public partial class Battery48TlRecord
{
private UInt16 OneWeekInMinutes => 10080;
public Dc_ Dc => new Dc_(this);
public Leds_ Leds => new Leds_(this);
public Temperatures_ Temperatures => new Temperatures_(this);
@ -31,12 +30,12 @@ public partial class Battery48TlRecord
// Time since TOC is a counter from the last moment when the battery reached EOC
// When The battery is full charged (reached EOC) the Time Since TOC is set to 0
public UInt16 TimeSinceTOC => _TimeSinceToc;
public Current BusCurrent => _BusCurrent;
public Current HeatingCurrent => _BusCurrent - _CellsCurrent;
public DcPower HeatingPower => HeatingCurrent * Dc.Voltage;
public TimeSpan TimeSinceTOC => TimeSpan.FromMinutes(_TimeSinceToc);
public Current BusCurrent => _BusCurrent;
public Current HeatingCurrent => _BusCurrent - _CellsCurrent;
public DcPower HeatingPower => HeatingCurrent * Dc.Voltage;
public Boolean CalibrationChargeRequested => TimeSinceTOC > OneWeekInMinutes;
public Boolean CalibrationChargeRequested => TimeSinceTOC > TimeSpan.FromDays(7);
public readonly struct Leds_
{

View File

@ -6,15 +6,15 @@ namespace InnovEnergy.Lib.Devices.Battery48TL;
public class Battery48TlRecords
{
public required DcBus Dc { get; init; }
public required Boolean Eoc { get; init; }
public required IReadOnlyList<String> Warnings { get; init; }
public required IReadOnlyList<String> Alarms { get; init; }
public required Percent Soc { get; init; }
public required Percent CurrentMinSoc { get; init; }
public required Temperature Temperature { get; init; }
public required DcPower HeatingPower { get; init; }
public required UInt16 TimeSinceToc { get; init; }
public required DcBus Dc { get; init; }
public required Boolean Eoc { get; init; }
public required IReadOnlyList<String> Warnings { get; init; }
public required IReadOnlyList<String> Alarms { get; init; }
public required Percent Soc { get; init; }
public required Percent CurrentMinSoc { get; init; }
public required Temperature Temperature { get; init; }
public required DcPower HeatingPower { get; init; }
public required TimeSpan TimeSinceToc { get; init; }
public required Boolean CalibrationChargeRequested { get; init; }
public required IReadOnlyList<Battery48TlRecord> Devices { get; init; }

View File

@ -35,22 +35,12 @@ public class TruConvertDcDcDevices
public DcDcDevicesRecord Read()
{
SystemControlRegisters? scStatus;
try
{
scStatus = _SystemControl.Read();
}
catch (Exception e)
{
Console.WriteLine(e);
return DcDcDevicesRecord.Null;
}
var scStatus = _SystemControl.Read();
var n = scStatus.NumberOfConnectedSlaves;
var n = scStatus.NumberOfConnectedSlaves;
try
{
var dcDcRecords = _DcDcs
.Take(n)
.Select(dcdc => dcdc.Read())
@ -61,7 +51,7 @@ public class TruConvertDcDcDevices
catch
{
"Failed to read DCDC data".WriteLine();
return new DcDcDevicesRecord(scStatus, Array.Empty<DcDcRecord>());
return new DcDcDevicesRecord(null, Array.Empty<DcDcRecord>());
}
}

View File

@ -3,7 +3,6 @@ using static System.Math;
namespace InnovEnergy.Lib.Units.Composite;
public record AcPower
{
public required ActivePower Active { get; init; }
@ -31,4 +30,6 @@ public record AcPower
public static implicit operator AcPower(Double p) => new AcPower { Active = p, Reactive = 0 };
public static implicit operator AcPower(Int32 p) => new AcPower { Active = p, Reactive = 0 };
public static AcPower Zero => new AcPower { Active = 0, Reactive = 0, };
}