Merge remote-tracking branch 'origin/main'

This commit is contained in:
Kim 2023-10-09 14:30:51 +02:00
commit bb2de9d0d4
9 changed files with 80 additions and 44 deletions

View File

@ -0,0 +1,8 @@
namespace InnovEnergy.App.SaliMax.Ess;
public enum LedState
{
Red,
Orange,
Green
}

View File

@ -25,7 +25,8 @@ public record StatusRecord
public required RelaysRecord? Relays { get; init; } public required RelaysRecord? Relays { get; init; }
public required AmptStatus? PvOnDc { get; init; } public required AmptStatus? PvOnDc { get; init; }
public required Config Config { get; init; } public required Config Config { get; init; }
public required SystemLog Log { get; set; } // TODO: init only
public required EssControl EssControl { get; set; } // TODO: init only public required EssControl EssControl { get; set; } // TODO: init only
public required StateMachine StateMachine { get; init; } public required StateMachine StateMachine { get; init; }
} }

View File

@ -0,0 +1,8 @@
namespace InnovEnergy.App.SaliMax.Ess;
public record SystemLog
{
public required String? Message { get; init; }
public required LedState Led { get; init; }
}

View File

@ -16,6 +16,7 @@ using InnovEnergy.Lib.Devices.Trumpf.TruConvertAc.DataTypes;
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc; using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc;
using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control; using InnovEnergy.Lib.Devices.Trumpf.TruConvertDc.Control;
using InnovEnergy.Lib.Protocols.Modbus.Channels; using InnovEnergy.Lib.Protocols.Modbus.Channels;
using InnovEnergy.Lib.Time.Unix;
using InnovEnergy.Lib.Units; using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Utils; using InnovEnergy.Lib.Utils;
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig; using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
@ -113,24 +114,25 @@ internal static class Program
return new StatusRecord return new StatusRecord
{ {
AcDc = acDc, AcDc = acDc,
DcDc = dcDc, DcDc = dcDc,
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,
LoadOnAcGrid = gridBusLoad, LoadOnAcGrid = gridBusLoad,
LoadOnAcIsland = loadOnAcIsland, LoadOnAcIsland = loadOnAcIsland,
LoadOnDc = dcLoad, LoadOnDc = dcLoad,
StateMachine = StateMachine.Default, StateMachine = StateMachine.Default,
EssControl = EssControl.Default, EssControl = EssControl.Default,
Config = Config.Load() // load from disk every iteration, so config can be changed while running Log = new SystemLog{Led = LedState.Green, Message = null}, //TODO: Put real stuff
Config = Config.Load() // load from disk every iteration, so config can be changed while running
}; };
} }
@ -174,18 +176,15 @@ internal static class Program
// If control Special Error return true, we must stop the system.(break;) // If control Special Error return true, we must stop the system.(break;)
var alarmCondition = record.DetectAlarmStates(); var alarmCondition = record.DetectAlarmStates();
if (alarmCondition is not null) if (alarmCondition is not null)
{ {
//stop the system
//return
alarmCondition.LogInfo(); alarmCondition.LogInfo();
} }
record.ControlConstants(); record.ControlConstants();
record.ControlSystemState(); record.ControlSystemState();
$"{record.StateMachine.State}: {record.StateMachine.Message}".LogInfo(); $"{UnixTime.Now} : {record.StateMachine.State}: {record.StateMachine.Message}".WriteLine().LogInfo();
var essControl = record.ControlEss().WriteLine().LogInfo(); var essControl = record.ControlEss().WriteLine().LogInfo();
@ -313,17 +312,20 @@ internal static class Program
sc.ResetAlarmsAndWarnings = true; sc.ResetAlarmsAndWarnings = true;
} }
private static async Task<Boolean> UploadCsv(StatusRecord status, DateTime timeStamp) private static async Task<Boolean> UploadCsv(StatusRecord status, UnixTime timeStamp)
{ {
var s3Config = status.Config.S3; var s3Config = status.Config.S3;
var csv = status.ToCsv().LogInfo();
if (s3Config is null) if (s3Config is null)
return false; return false;
var csv = status.ToCsv();
var s3Path = timeStamp + ".csv"; var s3Path = timeStamp + ".csv";
var request = s3Config.CreatePutRequest(s3Path); var request = s3Config.CreatePutRequest(s3Path);
var response = await request.PutAsync(new StringContent(csv)); var response = await request.PutAsync(new StringContent(csv));
// This is temporary for Wittman
//await File.WriteAllTextAsync("/var/www/html/status.csv", csv.SplitLines().Where(l => !l.Contains("Secret")).JoinLines());
if (response.StatusCode != 200) if (response.StatusCode != 200)
{ {
Console.WriteLine("ERROR: PUT"); Console.WriteLine("ERROR: PUT");

View File

@ -95,7 +95,15 @@ public class Config //TODO: let IE choose from config files (Json) and connect t
BatteryIp = new() { Host = "localhost", Port = 5007}, BatteryIp = new() { Host = "localhost", Port = 5007},
BatteryNodes = new []{ 2, 3, 4, 5, 6 } BatteryNodes = new []{ 2, 3, 4, 5, 6 }
}, },
S3 = null S3 = new()
{
Bucket = "1-3e5b3069-214a-43ee-8d85-57d72000c19d",
Region = "sos-ch-dk-2",
Provider = "exo.io",
ContentType = "text/plain; charset=utf-8",
Key = "EXO4ec5faf1a7650b79b5722fb5",
Secret = "LUxu1PGEA-POEIckoEyq6bYyz0RnenW6tmqccMKgkHQ"
},
}; };
#else #else
public static Config Default => new() public static Config Default => new()

View File

@ -20,7 +20,7 @@ public partial class Battery48TlRecord
public Boolean Eoc => Leds is { Green: On, Amber: Off, Blue : Off }; public Boolean Eoc => Leds is { Green: On, Amber: Off, Blue : Off };
public String SerialNumber => $"{_SerialNum1:X4} {_SerialNum2:X4} {_SerialNum3:X4} {_SerialNum4:X4}".TrimStart('0'); public String SerialNumber => $"{_SerialNum1:X4}{_SerialNum2:X4}{_SerialNum3:X4}{_SerialNum4:X4}".TrimEnd('0');
public String FwVersion => _FwVersion.ToString("X4"); public String FwVersion => _FwVersion.ToString("X4");
public Strings Warnings => ParseWarnings().OrderBy(w => w).ToList(); public Strings Warnings => ParseWarnings().OrderBy(w => w).ToList();
@ -28,12 +28,17 @@ public partial class Battery48TlRecord
public Percent Soc => _Soc; public Percent Soc => _Soc;
public Current BusCurrent => _BusCurrent;
public UInt16 BusCurrentHex => _BusCurrentHex;
public UInt16 CellsCurrentHex => _CellsCurrentHex;
public Current HeatingCurrent => _BusCurrent - _CellsCurrent;
public DcPower HeatingPower => HeatingCurrent * Dc.Voltage;
// 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 TimeSpan TimeSinceTOC => TimeSpan.FromMinutes(_TimeSinceToc); 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 > TimeSpan.FromDays(7); public Boolean CalibrationChargeRequested => TimeSinceTOC > TimeSpan.FromDays(7);
@ -214,5 +219,4 @@ public partial class Battery48TlRecord
return Math.Min(pLimit, 0); return Math.Min(pLimit, 0);
} }
} }
} }

View File

@ -20,7 +20,11 @@ public partial class Battery48TlRecord
[InputRegister(999, Scale = 0.01)] private Double _CellsVoltage; [InputRegister(999, Scale = 0.01)] private Double _CellsVoltage;
[InputRegister(1001, Scale = 0.01)] private Double _BusVoltage; [InputRegister(1001, Scale = 0.01)] private Double _BusVoltage;
[InputRegister(1000, Scale = 0.01, Offset = -10000)] private Double _CellsCurrent; [InputRegister(1000, Scale = 0.01, Offset = -10000)] private Double _CellsCurrent;
[InputRegister(1000)] private UInt16 _CellsCurrentHex;
[InputRegister(1062, Scale = 0.01, Offset = -10000)] private Double _BusCurrent; [InputRegister(1062, Scale = 0.01, Offset = -10000)] private Double _BusCurrent;
[InputRegister(1062)] private UInt16 _BusCurrentHex;
[InputRegister(1053, Scale = 0.1)] private Double _Soc; [InputRegister(1053, Scale = 0.1)] private Double _Soc;
[InputRegister(1052)] private UInt16 _TimeSinceToc; [InputRegister(1052)] private UInt16 _TimeSinceToc;

View File

@ -3,7 +3,8 @@ using System.Collections;
namespace InnovEnergy.Lib.Units.Composite; namespace InnovEnergy.Lib.Units.Composite;
public record Ac3Bus : IReadOnlyList<AcPhase> // removed to have it on S3. Find a better solution
public record Ac3Bus // : IReadOnlyList<AcPhase>
{ {
public required AcPhase L1 { get; init; } public required AcPhase L1 { get; init; }
public required AcPhase L2 { get; init; } public required AcPhase L2 { get; init; }
@ -20,22 +21,22 @@ public record Ac3Bus : IReadOnlyList<AcPhase>
L3 = AcPhase.Zero, L3 = AcPhase.Zero,
}; };
public IEnumerator<AcPhase> GetEnumerator() // public IEnumerator<AcPhase> GetEnumerator()
{ // {
yield return L1; // yield return L1;
yield return L2; // yield return L2;
yield return L3; // yield return L3;
} // }
//
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator(); // IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
//
public Int32 Count => 3; // public Int32 Count => 3;
//
public AcPhase this[Int32 index] => index switch // public AcPhase this[Int32 index] => index switch
{ // {
0 => L1, // it's retarded // 0 => L1, // it's retarded
1 => L2, // 1 => L2,
2 => L3, // 2 => L3,
_ => throw new ArgumentOutOfRangeException(nameof(index)) // _ => throw new ArgumentOutOfRangeException(nameof(index))
}; // };
} }