Merge remote-tracking branch 'origin/main'
This commit is contained in:
commit
315fab8463
|
@ -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>
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
@ -136,8 +136,8 @@ public readonly struct Nic
|
||||||
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
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -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)
|
||||||
{
|
{
|
||||||
|
|
|
@ -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;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,
|
||||||
|
|
|
@ -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);
|
||||||
|
|
||||||
|
|
|
@ -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_
|
||||||
{
|
{
|
||||||
|
|
|
@ -14,7 +14,7 @@ public class Battery48TlRecords
|
||||||
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; }
|
||||||
|
|
|
@ -35,22 +35,12 @@ public class TruConvertDcDcDevices
|
||||||
|
|
||||||
public DcDcDevicesRecord Read()
|
public DcDcDevicesRecord Read()
|
||||||
{
|
{
|
||||||
SystemControlRegisters? scStatus;
|
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
scStatus = _SystemControl.Read();
|
var scStatus = _SystemControl.Read();
|
||||||
}
|
|
||||||
catch (Exception e)
|
|
||||||
{
|
|
||||||
Console.WriteLine(e);
|
|
||||||
return DcDcDevicesRecord.Null;
|
|
||||||
}
|
|
||||||
|
|
||||||
var n = scStatus.NumberOfConnectedSlaves;
|
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>());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -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, };
|
||||||
}
|
}
|
Loading…
Reference in New Issue