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"> <Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<RootNamespace>InnovEnergy.App.EmuMeterDriver</RootNamespace>
</PropertyGroup>
<Import Project="../InnovEnergy.App.props" /> <Import Project="../InnovEnergy.App.props" />
<ItemGroup> <ItemGroup>
@ -14,4 +19,6 @@
<PackageReference Include="CliWrap" Version="3.6.0" /> <PackageReference Include="CliWrap" Version="3.6.0" />
</ItemGroup> </ItemGroup>
</Project> </Project>

View File

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

View File

@ -188,7 +188,13 @@ public static class Controller
private static Boolean MustDoCalibrationCharge(this StatusRecord statusRecord) 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

@ -171,6 +171,16 @@ internal static class Program
var record = ReadStatus(); 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.ControlConstants();
record.ControlSystemState(); record.ControlSystemState();
@ -202,6 +212,36 @@ internal static class Program
// ReSharper disable once FunctionNeverReturns // 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) private static void ControlConstants(this StatusRecord r)
{ {

View File

@ -19,8 +19,6 @@ public class RelaysDevice
catch (Exception e) catch (Exception e)
{ {
$"Failed to read from {nameof(RelaysDevice)}\n{e}".LogError(); $"Failed to read from {nameof(RelaysDevice)}\n{e}".LogError();
// TODO: log
return null; 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 }; private static readonly JsonSerializerOptions JsonOptions = new() { WriteIndented = true };
public required Double MinSoc { get; set; } 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 PConstant { get; set; }
public required Double GridSetPoint { get; set; } public required Double GridSetPoint { get; set; }
public required Double BatterySelfDischargePower { 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() public static Config Default => new()
{ {
MinSoc = 20, MinSoc = 20,
LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS ForceCalibrationCharge = false,
PConstant = .5, PConstant = .5,
GridSetPoint = 0, GridSetPoint = 0,
BatterySelfDischargePower = 200, 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() public static Config Default => new()
{ {
MinSoc = 20, MinSoc = 20,
LastEoc = UnixTime.Epoch, // TODO: remove, use new LastEoc feature from BMS ForceCalibrationCharge = false,
PConstant = .5, PConstant = .5,
GridSetPoint = 0, GridSetPoint = 0,
BatterySelfDischargePower = 200, BatterySelfDischargePower = 200,

View File

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

View File

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

View File

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

View File

@ -35,22 +35,12 @@ public class TruConvertDcDcDevices
public DcDcDevicesRecord Read() public DcDcDevicesRecord Read()
{ {
SystemControlRegisters? scStatus;
try try
{ {
scStatus = _SystemControl.Read(); var scStatus = _SystemControl.Read();
} var n = scStatus.NumberOfConnectedSlaves;
catch (Exception e)
{
Console.WriteLine(e);
return DcDcDevicesRecord.Null;
}
var n = scStatus.NumberOfConnectedSlaves;
try
{
var dcDcRecords = _DcDcs var dcDcRecords = _DcDcs
.Take(n) .Take(n)
.Select(dcdc => dcdc.Read()) .Select(dcdc => dcdc.Read())
@ -61,7 +51,7 @@ public class TruConvertDcDcDevices
catch catch
{ {
"Failed to read DCDC data".WriteLine(); "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; namespace InnovEnergy.Lib.Units.Composite;
public record AcPower public record AcPower
{ {
public required ActivePower Active { get; init; } 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(Double p) => new AcPower { Active = p, Reactive = 0 };
public static implicit operator AcPower(Int32 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, };
} }