Add Calibration charge mode and clean code
This commit is contained in:
parent
bf37840d0d
commit
bbca604ce9
|
|
@ -11,12 +11,16 @@ public static class Controller
|
||||||
private static readonly Double MaxDischargePower = -8000; // By battery TODO: move to config
|
private static readonly Double MaxDischargePower = -8000; // By battery TODO: move to config
|
||||||
private static readonly Double MaxChargePower = 6000; // By battery TODO: move to config
|
private static readonly Double MaxChargePower = 6000; // By battery TODO: move to config
|
||||||
|
|
||||||
|
private static Boolean _hasRepetitiveCalibrationChargeChecked = false;
|
||||||
|
private static DateTime _nextDayAt10Am = DateTime.Now;
|
||||||
|
|
||||||
public static EssMode SelectControlMode(this StatusRecord s)
|
public static EssMode SelectControlMode(this StatusRecord s)
|
||||||
{
|
{
|
||||||
//return EssMode.OptimizeSelfConsumption;
|
//return EssMode.OptimizeSelfConsumption;
|
||||||
|
|
||||||
return s.StateMachine.State != 23 ? EssMode.Off
|
return s.StateMachine.State != 23 ? EssMode.Off
|
||||||
: s.MustReachMinSoc() ? EssMode.ReachMinSoc
|
: s.MustReachMinSoc() ? EssMode.ReachMinSoc
|
||||||
|
: s.MustDoCalibrationCharge() ? EssMode.CalibrationCharge
|
||||||
: s.GridMeter is null ? EssMode.NoGridMeter
|
: s.GridMeter is null ? EssMode.NoGridMeter
|
||||||
: EssMode.OptimizeSelfConsumption;
|
: EssMode.OptimizeSelfConsumption;
|
||||||
}
|
}
|
||||||
|
|
@ -147,26 +151,15 @@ public static class Controller
|
||||||
EssMode.Off => 0,
|
EssMode.Off => 0,
|
||||||
EssMode.OffGrid => 0,
|
EssMode.OffGrid => 0,
|
||||||
EssMode.NoGridMeter => 0,
|
EssMode.NoGridMeter => 0,
|
||||||
|
EssMode.CalibrationCharge => s.ControlInverterPower(chargePower),
|
||||||
_ => throw new ArgumentException(null, nameof(mode))
|
_ => throw new ArgumentException(null, nameof(mode))
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
// private static Boolean MustHeatBatteries(this StatusRecord s)
|
|
||||||
// {
|
|
||||||
// var batteries = s.GetBatteries();
|
|
||||||
//
|
|
||||||
// if (batteries.Count <= 0)
|
|
||||||
// return true; // batteries might be there but BMS is without power
|
|
||||||
//
|
|
||||||
// return batteries
|
|
||||||
// .Select(b => b.Temperatures.State)
|
|
||||||
// .Contains(TemperatureState.Cold);
|
|
||||||
// }
|
|
||||||
|
|
||||||
private static Double MaxBatteryChargePower(this StatusRecord s)
|
private static Double MaxBatteryChargePower(this StatusRecord s)
|
||||||
{
|
{
|
||||||
// This introduces a limit when we don't have communication with batteries
|
// This introduces a limit when we don't have communication with batteries,
|
||||||
// Otherwise the limit will be 0 and the batteries will be not heated
|
// Otherwise the limit will be 0, and the batteries will be not heated
|
||||||
|
|
||||||
var batteries = s.GetBatteries();
|
var batteries = s.GetBatteries();
|
||||||
|
|
||||||
|
|
@ -206,6 +199,54 @@ public static class Controller
|
||||||
return s.Battery?.Devices ?? Array.Empty<BatteryDeligreenRecord>();
|
return s.Battery?.Devices ?? Array.Empty<BatteryDeligreenRecord>();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Boolean MustDoCalibrationCharge(this StatusRecord statusRecord)
|
||||||
|
{
|
||||||
|
var calibrationChargeForced = statusRecord.Config.ForceCalibrationChargeState;
|
||||||
|
var additionalCalibrationRequired = AdditionalCalibrationDateHasBeenPassed(statusRecord.Config.DayAndTimeForAdditionalCalibration);
|
||||||
|
var repetitiveCalibrationRequired = RepetitiveCalibrationDateHasBeenPassed(statusRecord.Config.DayAndTimeForRepetitiveCalibration);
|
||||||
|
|
||||||
|
var mustDoCalibrationCharge = calibrationChargeForced == CalibrationChargeType.ChargePermanently ||
|
||||||
|
(calibrationChargeForced == CalibrationChargeType.AdditionallyOnce && additionalCalibrationRequired) ||
|
||||||
|
(calibrationChargeForced == CalibrationChargeType.RepetitivelyEvery && repetitiveCalibrationRequired);
|
||||||
|
|
||||||
|
Console.WriteLine("Next Repetitive calibration charge date is "+ statusRecord.Config.DayAndTimeForRepetitiveCalibration);
|
||||||
|
Console.WriteLine("Next Additional calibration charge date is "+ statusRecord.Config.DayAndTimeForAdditionalCalibration);
|
||||||
|
|
||||||
|
if (statusRecord.Battery is not null)
|
||||||
|
{
|
||||||
|
if (calibrationChargeForced == CalibrationChargeType.AdditionallyOnce && statusRecord.Battery.Eoc )
|
||||||
|
{
|
||||||
|
statusRecord.Config.ForceCalibrationChargeState = CalibrationChargeType.RepetitivelyEvery;
|
||||||
|
|
||||||
|
}
|
||||||
|
else if (calibrationChargeForced == CalibrationChargeType.RepetitivelyEvery && statusRecord.Battery.Eoc && _hasRepetitiveCalibrationChargeChecked)
|
||||||
|
{
|
||||||
|
statusRecord.Config.DayAndTimeForRepetitiveCalibration = statusRecord.Config.DayAndTimeForRepetitiveCalibration.AddDays(7);
|
||||||
|
_hasRepetitiveCalibrationChargeChecked = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return mustDoCalibrationCharge;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static Boolean RepetitiveCalibrationDateHasBeenPassed(DateTime calibrationChargeDate)
|
||||||
|
{
|
||||||
|
if (DateTime.Now >= calibrationChargeDate )
|
||||||
|
{
|
||||||
|
_hasRepetitiveCalibrationChargeChecked = true;
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
private static Boolean AdditionalCalibrationDateHasBeenPassed(DateTime calibrationChargeDate)
|
||||||
|
{
|
||||||
|
if (DateTime.Now >= calibrationChargeDate )
|
||||||
|
{
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
private static Double ControlGridPower(this StatusRecord status, Double targetPower)
|
private static Double ControlGridPower(this StatusRecord status, Double targetPower)
|
||||||
{
|
{
|
||||||
return ControlPower
|
return ControlPower
|
||||||
|
|
|
||||||
|
|
@ -68,8 +68,7 @@ internal static class Program
|
||||||
private const UInt16 NbrOfFileToConcatenate = 30; // add this to config file
|
private const UInt16 NbrOfFileToConcatenate = 30; // add this to config file
|
||||||
private static UInt16 _fileCounter = 0;
|
private static UInt16 _fileCounter = 0;
|
||||||
private static SalimaxAlarmState _salimaxAlarmState = SalimaxAlarmState.Green;
|
private static SalimaxAlarmState _salimaxAlarmState = SalimaxAlarmState.Green;
|
||||||
private const String Port = "/dev/ttyUSB0";
|
private const String Port = "/dev/ttyUSB0"; // move to a config file
|
||||||
private static Boolean _oneTimeFlag = false;
|
|
||||||
|
|
||||||
static Program()
|
static Program()
|
||||||
{
|
{
|
||||||
|
|
@ -314,108 +313,28 @@ internal static class Program
|
||||||
var bAlarmList = new List<String>();
|
var bAlarmList = new List<String>();
|
||||||
var bWarningList = new List<String>();
|
var bWarningList = new List<String>();
|
||||||
|
|
||||||
if (record.Battery != null)
|
if (record.Battery is { MonomerHighVoltageAlarm: true })
|
||||||
{
|
{
|
||||||
//_oneTimeFlag.WriteLine(" onetime flag");
|
warningList.Add(new AlarmOrWarning
|
||||||
if (record.Battery?.MonomerHighVoltageAlarm == true /*&& !_oneTimeFlag*/) //this should be checked: the number 0
|
|
||||||
{
|
{
|
||||||
//_oneTimeFlag = true;
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
warningList.Add(new AlarmOrWarning
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
{
|
CreatedBy = "Charging Battery System",
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
Description = "dynCCL Active: Max Battery Charging is 10 * N"
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
});
|
||||||
CreatedBy = "Charging Battery System",
|
}
|
||||||
Description = "dynCCL Active: Max Battery Charging is 10 * N"
|
if (record.Battery is { MonomerLowVoltageAlarm: true })
|
||||||
});
|
{
|
||||||
}
|
warningList.Add(new AlarmOrWarning
|
||||||
|
{
|
||||||
/* if (record.Battery?.MonomerLowVoltageAlarm == true && !_oneTimeFlag) //this should be checked: the number 10
|
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
{
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
_oneTimeFlag = true;
|
CreatedBy = "Battery System",
|
||||||
warningList.Add(new AlarmOrWarning
|
Description = "dynDCL Active: Max Battery Discharging is 10 * N"
|
||||||
{
|
});
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
|
||||||
CreatedBy = "Battery System",
|
|
||||||
Description = "dynDCL Active: Max Battery Discharging is 10 * N"
|
|
||||||
});
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
_oneTimeFlag = false;
|
|
||||||
}*/
|
|
||||||
}
|
}
|
||||||
/*
|
|
||||||
if (record.Battery != null)
|
|
||||||
{
|
|
||||||
var i = 0;
|
|
||||||
|
|
||||||
foreach (var battery in record.Battery.Devices)
|
if (alarmCondition is not null)
|
||||||
{
|
|
||||||
var devicesBatteryNode = record.Config.Devices.BatteryNodes[i];
|
|
||||||
|
|
||||||
if (battery.LimpBitMap == 0)
|
|
||||||
{
|
|
||||||
// "All String are Active".WriteLine();
|
|
||||||
}
|
|
||||||
else if (IsPowerOfTwo(battery.LimpBitMap))
|
|
||||||
{
|
|
||||||
"1 String is disabled".WriteLine();
|
|
||||||
Console.WriteLine(" ****************** ");
|
|
||||||
|
|
||||||
warningList.Add(new AlarmOrWarning
|
|
||||||
{
|
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
|
||||||
CreatedBy = "Battery node" + devicesBatteryNode,
|
|
||||||
Description = "1 String is disabled"
|
|
||||||
});
|
|
||||||
|
|
||||||
bWarningList.Add("/"+i+1 + "/1 String is disabled"); // battery id instead ( i +1 ) of node id: requested from the frontend
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
"2 or more string are disabled".WriteLine();
|
|
||||||
Console.WriteLine(" ****************** ");
|
|
||||||
|
|
||||||
alarmList.Add(new AlarmOrWarning
|
|
||||||
{
|
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
|
||||||
CreatedBy = "Battery node" + devicesBatteryNode,
|
|
||||||
Description = "2 or more string are disabled"
|
|
||||||
});
|
|
||||||
bAlarmList.Add(i +";2 or more string are disabled");
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var warning in record.Battery.Warnings)
|
|
||||||
{
|
|
||||||
warningList.Add(new AlarmOrWarning
|
|
||||||
{
|
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
|
||||||
CreatedBy = "Battery node" + devicesBatteryNode,
|
|
||||||
Description = warning
|
|
||||||
});
|
|
||||||
bWarningList.Add(i +";" + warning);
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var alarm in battery.Alarms)
|
|
||||||
{
|
|
||||||
alarmList.Add(new AlarmOrWarning
|
|
||||||
{
|
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
|
||||||
CreatedBy = "Battery node" + devicesBatteryNode,
|
|
||||||
Description = alarm
|
|
||||||
});
|
|
||||||
bWarningList.Add(i +";" + alarm);
|
|
||||||
}
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
}*/
|
|
||||||
|
|
||||||
if (alarmCondition is not null)
|
|
||||||
{
|
{
|
||||||
alarmCondition.WriteLine();
|
alarmCondition.WriteLine();
|
||||||
|
|
||||||
|
|
@ -428,49 +347,33 @@ internal static class Program
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
foreach (var alarm in record.AcDc.Alarms)
|
alarmList.AddRange(record.AcDc.Alarms
|
||||||
{
|
.Select(alarm => new AlarmOrWarning
|
||||||
alarmList.Add(new AlarmOrWarning
|
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
{
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
CreatedBy = "AcDc",
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
Description = alarm.ToString() }));
|
||||||
CreatedBy = "AcDc",
|
|
||||||
Description = alarm.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var alarm in record.DcDc.Alarms)
|
alarmList.AddRange(record.DcDc.Alarms
|
||||||
{
|
.Select(alarm => new AlarmOrWarning
|
||||||
alarmList.Add(new AlarmOrWarning
|
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
{
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
CreatedBy = "DcDc",
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
Description = alarm.ToString() }));
|
||||||
CreatedBy = "DcDc",
|
|
||||||
Description = alarm.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var warning in record.AcDc.Warnings)
|
warningList.AddRange(record.AcDc.Warnings
|
||||||
{
|
.Select(warning => new AlarmOrWarning
|
||||||
warningList.Add(new AlarmOrWarning
|
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
{
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
CreatedBy = "AcDc",
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
Description = warning.ToString() }));
|
||||||
CreatedBy = "AcDc",
|
|
||||||
Description = warning.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (var warning in record.DcDc.Warnings)
|
warningList.AddRange(record.DcDc.Warnings
|
||||||
{
|
.Select(warning => new AlarmOrWarning
|
||||||
warningList.Add(new AlarmOrWarning
|
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||||
{
|
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
CreatedBy = "DcDc",
|
||||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
Description = warning.ToString() }));
|
||||||
CreatedBy = "DcDc",
|
|
||||||
Description = warning.ToString()
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
_salimaxAlarmState = warningList.Any()
|
_salimaxAlarmState = warningList.Any()
|
||||||
? SalimaxAlarmState.Orange
|
? SalimaxAlarmState.Orange
|
||||||
|
|
@ -480,7 +383,7 @@ internal static class Program
|
||||||
? SalimaxAlarmState.Red
|
? SalimaxAlarmState.Red
|
||||||
: _salimaxAlarmState; // this will be replaced by LedState
|
: _salimaxAlarmState; // this will be replaced by LedState
|
||||||
|
|
||||||
TryParse(s3Bucket?.Split("-")[0], out var installationId);
|
var installationId = GetInstallationId(s3Bucket ?? string.Empty);
|
||||||
|
|
||||||
var returnedStatus = new StatusMessage
|
var returnedStatus = new StatusMessage
|
||||||
{
|
{
|
||||||
|
|
@ -495,6 +398,12 @@ internal static class Program
|
||||||
return returnedStatus;
|
return returnedStatus;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static Int32 GetInstallationId(String s3Bucket)
|
||||||
|
{
|
||||||
|
var part = s3Bucket.Split('-').FirstOrDefault();
|
||||||
|
return TryParse(part, out var id) ? id : 0; // is 0 a default safe value? check with Marios
|
||||||
|
}
|
||||||
|
|
||||||
private static String? DetectAlarmStates(this StatusRecord r) => r.Relays switch
|
private static String? DetectAlarmStates(this StatusRecord r) => r.Relays switch
|
||||||
{
|
{
|
||||||
{ K2ConnectIslandBusToGridBus: false, K2IslandBusIsConnectedToGridBus: true } => " Contradiction: R0 is opening the K2 but the K2 is still close ",
|
{ K2ConnectIslandBusToGridBus: false, K2IslandBusIsConnectedToGridBus: true } => " Contradiction: R0 is opening the K2 but the K2 is still close ",
|
||||||
|
|
@ -553,7 +462,7 @@ internal static class Program
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
maxBatteryChargingCurrentLiveByDcDc = 0;
|
maxBatteryChargingCurrentLiveByDcDc = 0;
|
||||||
maxBatteryDischargingCurrentLivebyDcDc = 0;
|
maxBatteryDischargingCurrentLivebyDcDc = 0;
|
||||||
}
|
}
|
||||||
inverters.ForEach(d => d.Control.Dc.MaxVoltage = devicesConfig.AcDc.MaxDcLinkVoltage);
|
inverters.ForEach(d => d.Control.Dc.MaxVoltage = devicesConfig.AcDc.MaxDcLinkVoltage);
|
||||||
|
|
@ -1001,15 +910,16 @@ internal static class Program
|
||||||
|
|
||||||
status.Config.MinSoc = config.MinimumSoC;
|
status.Config.MinSoc = config.MinimumSoC;
|
||||||
status.Config.GridSetPoint = config.GridSetPoint * 1000; // converted from kW to W
|
status.Config.GridSetPoint = config.GridSetPoint * 1000; // converted from kW to W
|
||||||
// status.Config.ForceCalibrationChargeState = config.CalibrationChargeState;
|
|
||||||
//
|
status.Config.ForceCalibrationChargeState = config.CalibrationChargeState;
|
||||||
// if (config.CalibrationChargeState == CalibrationChargeType.RepetitivelyEvery)
|
|
||||||
// {
|
if (config.CalibrationChargeState == CalibrationChargeType.RepetitivelyEvery)
|
||||||
// status.Config.DayAndTimeForRepetitiveCalibration = config.CalibrationChargeDate;
|
{
|
||||||
// }
|
status.Config.DayAndTimeForRepetitiveCalibration = config.CalibrationChargeDate;
|
||||||
// else if (config.CalibrationChargeState == CalibrationChargeType.AdditionallyOnce)
|
}
|
||||||
// {
|
else if (config.CalibrationChargeState == CalibrationChargeType.AdditionallyOnce)
|
||||||
// status.Config.DayAndTimeForAdditionalCalibration = config.CalibrationChargeDate;
|
{
|
||||||
// }
|
status.Config.DayAndTimeForAdditionalCalibration = config.CalibrationChargeDate;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Loading…
Reference in New Issue