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 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)
|
||||
{
|
||||
//return EssMode.OptimizeSelfConsumption;
|
||||
|
||||
return s.StateMachine.State != 23 ? EssMode.Off
|
||||
: s.MustReachMinSoc() ? EssMode.ReachMinSoc
|
||||
: s.MustDoCalibrationCharge() ? EssMode.CalibrationCharge
|
||||
: s.GridMeter is null ? EssMode.NoGridMeter
|
||||
: EssMode.OptimizeSelfConsumption;
|
||||
}
|
||||
|
|
@ -147,26 +151,15 @@ public static class Controller
|
|||
EssMode.Off => 0,
|
||||
EssMode.OffGrid => 0,
|
||||
EssMode.NoGridMeter => 0,
|
||||
EssMode.CalibrationCharge => s.ControlInverterPower(chargePower),
|
||||
_ => 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)
|
||||
{
|
||||
// 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
|
||||
// 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
|
||||
|
||||
var batteries = s.GetBatteries();
|
||||
|
||||
|
|
@ -206,6 +199,54 @@ public static class Controller
|
|||
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)
|
||||
{
|
||||
return ControlPower
|
||||
|
|
|
|||
|
|
@ -68,8 +68,7 @@ internal static class Program
|
|||
private const UInt16 NbrOfFileToConcatenate = 30; // add this to config file
|
||||
private static UInt16 _fileCounter = 0;
|
||||
private static SalimaxAlarmState _salimaxAlarmState = SalimaxAlarmState.Green;
|
||||
private const String Port = "/dev/ttyUSB0";
|
||||
private static Boolean _oneTimeFlag = false;
|
||||
private const String Port = "/dev/ttyUSB0"; // move to a config file
|
||||
|
||||
static Program()
|
||||
{
|
||||
|
|
@ -314,108 +313,28 @@ internal static class Program
|
|||
var bAlarmList = new List<String>();
|
||||
var bWarningList = new List<String>();
|
||||
|
||||
if (record.Battery != null)
|
||||
if (record.Battery is { MonomerHighVoltageAlarm: true })
|
||||
{
|
||||
//_oneTimeFlag.WriteLine(" onetime flag");
|
||||
if (record.Battery?.MonomerHighVoltageAlarm == true /*&& !_oneTimeFlag*/) //this should be checked: the number 0
|
||||
warningList.Add(new AlarmOrWarning
|
||||
{
|
||||
//_oneTimeFlag = true;
|
||||
warningList.Add(new AlarmOrWarning
|
||||
{
|
||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "Charging Battery System",
|
||||
Description = "dynCCL Active: Max Battery Charging is 10 * N"
|
||||
});
|
||||
}
|
||||
|
||||
/* if (record.Battery?.MonomerLowVoltageAlarm == true && !_oneTimeFlag) //this should be checked: the number 10
|
||||
{
|
||||
_oneTimeFlag = true;
|
||||
warningList.Add(new AlarmOrWarning
|
||||
{
|
||||
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;
|
||||
}*/
|
||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
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
|
||||
{
|
||||
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"
|
||||
});
|
||||
}
|
||||
/*
|
||||
if (record.Battery != null)
|
||||
{
|
||||
var i = 0;
|
||||
|
||||
foreach (var battery in record.Battery.Devices)
|
||||
{
|
||||
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)
|
||||
if (alarmCondition is not null)
|
||||
{
|
||||
alarmCondition.WriteLine();
|
||||
|
||||
|
|
@ -428,49 +347,33 @@ internal static class Program
|
|||
});
|
||||
}
|
||||
|
||||
foreach (var alarm in record.AcDc.Alarms)
|
||||
{
|
||||
alarmList.Add(new AlarmOrWarning
|
||||
{
|
||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "AcDc",
|
||||
Description = alarm.ToString()
|
||||
});
|
||||
}
|
||||
alarmList.AddRange(record.AcDc.Alarms
|
||||
.Select(alarm => new AlarmOrWarning
|
||||
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "AcDc",
|
||||
Description = alarm.ToString() }));
|
||||
|
||||
foreach (var alarm in record.DcDc.Alarms)
|
||||
{
|
||||
alarmList.Add(new AlarmOrWarning
|
||||
{
|
||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "DcDc",
|
||||
Description = alarm.ToString()
|
||||
});
|
||||
}
|
||||
alarmList.AddRange(record.DcDc.Alarms
|
||||
.Select(alarm => new AlarmOrWarning
|
||||
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "DcDc",
|
||||
Description = alarm.ToString() }));
|
||||
|
||||
foreach (var warning in record.AcDc.Warnings)
|
||||
{
|
||||
warningList.Add(new AlarmOrWarning
|
||||
{
|
||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "AcDc",
|
||||
Description = warning.ToString()
|
||||
});
|
||||
}
|
||||
warningList.AddRange(record.AcDc.Warnings
|
||||
.Select(warning => new AlarmOrWarning
|
||||
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "AcDc",
|
||||
Description = warning.ToString() }));
|
||||
|
||||
foreach (var warning in record.DcDc.Warnings)
|
||||
{
|
||||
warningList.Add(new AlarmOrWarning
|
||||
{
|
||||
Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "DcDc",
|
||||
Description = warning.ToString()
|
||||
});
|
||||
}
|
||||
warningList.AddRange(record.DcDc.Warnings
|
||||
.Select(warning => new AlarmOrWarning
|
||||
{ Date = DateTime.Now.ToString("yyyy-MM-dd"),
|
||||
Time = DateTime.Now.ToString("HH:mm:ss"),
|
||||
CreatedBy = "DcDc",
|
||||
Description = warning.ToString() }));
|
||||
|
||||
_salimaxAlarmState = warningList.Any()
|
||||
? SalimaxAlarmState.Orange
|
||||
|
|
@ -480,7 +383,7 @@ internal static class Program
|
|||
? SalimaxAlarmState.Red
|
||||
: _salimaxAlarmState; // this will be replaced by LedState
|
||||
|
||||
TryParse(s3Bucket?.Split("-")[0], out var installationId);
|
||||
var installationId = GetInstallationId(s3Bucket ?? string.Empty);
|
||||
|
||||
var returnedStatus = new StatusMessage
|
||||
{
|
||||
|
|
@ -495,6 +398,12 @@ internal static class Program
|
|||
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
|
||||
{
|
||||
{ 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
|
||||
{
|
||||
maxBatteryChargingCurrentLiveByDcDc = 0;
|
||||
maxBatteryChargingCurrentLiveByDcDc = 0;
|
||||
maxBatteryDischargingCurrentLivebyDcDc = 0;
|
||||
}
|
||||
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.GridSetPoint = config.GridSetPoint * 1000; // converted from kW to W
|
||||
// status.Config.ForceCalibrationChargeState = config.CalibrationChargeState;
|
||||
//
|
||||
// if (config.CalibrationChargeState == CalibrationChargeType.RepetitivelyEvery)
|
||||
// {
|
||||
// status.Config.DayAndTimeForRepetitiveCalibration = config.CalibrationChargeDate;
|
||||
// }
|
||||
// else if (config.CalibrationChargeState == CalibrationChargeType.AdditionallyOnce)
|
||||
// {
|
||||
// status.Config.DayAndTimeForAdditionalCalibration = config.CalibrationChargeDate;
|
||||
// }
|
||||
|
||||
status.Config.ForceCalibrationChargeState = config.CalibrationChargeState;
|
||||
|
||||
if (config.CalibrationChargeState == CalibrationChargeType.RepetitivelyEvery)
|
||||
{
|
||||
status.Config.DayAndTimeForRepetitiveCalibration = config.CalibrationChargeDate;
|
||||
}
|
||||
else if (config.CalibrationChargeState == CalibrationChargeType.AdditionallyOnce)
|
||||
{
|
||||
status.Config.DayAndTimeForAdditionalCalibration = config.CalibrationChargeDate;
|
||||
}
|
||||
}
|
||||
}
|
||||
Loading…
Reference in New Issue