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,6 +25,7 @@ public record StatusRecord
public required RelaysRecord? Relays { get; init; }
public required AmptStatus? PvOnDc { 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 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.Control;
using InnovEnergy.Lib.Protocols.Modbus.Channels;
using InnovEnergy.Lib.Time.Unix;
using InnovEnergy.Lib.Units;
using InnovEnergy.Lib.Utils;
using static InnovEnergy.Lib.Devices.Trumpf.SystemControl.DataTypes.SystemConfig;
@ -113,24 +114,25 @@ internal static class Program
return new StatusRecord
{
AcDc = acDc,
DcDc = dcDc,
Battery = battery,
Relays = relays,
GridMeter = gridMeter,
AcDc = acDc,
DcDc = dcDc,
Battery = battery,
Relays = relays,
GridMeter = gridMeter,
PvOnAcGrid = pvOnAcGrid,
PvOnAcIsland = pvOnAcIsland,
PvOnDc = pvOnDc,
PvOnAcGrid = pvOnAcGrid,
PvOnAcIsland = pvOnAcIsland,
PvOnDc = pvOnDc,
AcGridToAcIsland = gridBusToIslandBus,
LoadOnAcGrid = gridBusLoad,
LoadOnAcIsland = loadOnAcIsland,
LoadOnDc = dcLoad,
StateMachine = StateMachine.Default,
EssControl = EssControl.Default,
Config = Config.Load() // load from disk every iteration, so config can be changed while running
StateMachine = StateMachine.Default,
EssControl = EssControl.Default,
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;)
var alarmCondition = record.DetectAlarmStates();
if (alarmCondition is not null)
{
//stop the system
//return
alarmCondition.LogInfo();
}
record.ControlConstants();
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();
@ -313,17 +312,20 @@ internal static class Program
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 csv = status.ToCsv().LogInfo();
if (s3Config is null)
return false;
var csv = status.ToCsv();
var s3Path = timeStamp + ".csv";
var request = s3Config.CreatePutRequest(s3Path);
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)
{
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},
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
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 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 Strings Warnings => ParseWarnings().OrderBy(w => w).ToList();
@ -28,12 +28,17 @@ public partial class Battery48TlRecord
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
// When The battery is full charged (reached EOC) the Time Since TOC is set to 0
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);
@ -215,4 +220,3 @@ public partial class Battery48TlRecord
}
}
}

View File

@ -20,7 +20,11 @@ public partial class Battery48TlRecord
[InputRegister(999, Scale = 0.01)] private Double _CellsVoltage;
[InputRegister(1001, Scale = 0.01)] private Double _BusVoltage;
[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)] private UInt16 _BusCurrentHex;
[InputRegister(1053, Scale = 0.1)] private Double _Soc;
[InputRegister(1052)] private UInt16 _TimeSinceToc;

View File

@ -3,7 +3,8 @@ using System.Collections;
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 L2 { get; init; }
@ -20,22 +21,22 @@ public record Ac3Bus : IReadOnlyList<AcPhase>
L3 = AcPhase.Zero,
};
public IEnumerator<AcPhase> GetEnumerator()
{
yield return L1;
yield return L2;
yield return L3;
}
IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
public Int32 Count => 3;
public AcPhase this[Int32 index] => index switch
{
0 => L1, // it's retarded
1 => L2,
2 => L3,
_ => throw new ArgumentOutOfRangeException(nameof(index))
};
// public IEnumerator<AcPhase> GetEnumerator()
// {
// yield return L1;
// yield return L2;
// yield return L3;
// }
//
// IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
//
// public Int32 Count => 3;
//
// public AcPhase this[Int32 index] => index switch
// {
// 0 => L1, // it's retarded
// 1 => L2,
// 2 => L3,
// _ => throw new ArgumentOutOfRangeException(nameof(index))
// };
}