Feature: add SoC & voltage thresholds for battery current limit
This changes the custom current limit so the custom limit is only applied when any of: - SoC is valid and not ignored and SoC < threshold - Voltage is valid and Voltage < threshold - Voltage is invalid Independently, if "Use Battery-Reported limit" is enabled and valid, it is applied (unless a lower custom limit already was applied).
This commit is contained in:
parent
d36b30ae0e
commit
2e85b420d5
@ -145,6 +145,8 @@ struct BATTERY_CONFIG_T {
|
|||||||
BatteryVoltageUnit MqttVoltageUnit;
|
BatteryVoltageUnit MqttVoltageUnit;
|
||||||
bool EnableDischargeCurrentLimit;
|
bool EnableDischargeCurrentLimit;
|
||||||
float DischargeCurrentLimit;
|
float DischargeCurrentLimit;
|
||||||
|
float DischargeCurrentLimitBelowSoc;
|
||||||
|
float DischargeCurrentLimitBelowVoltage;
|
||||||
bool UseBatteryReportedDischargeCurrentLimit;
|
bool UseBatteryReportedDischargeCurrentLimit;
|
||||||
char MqttDischargeCurrentTopic[MQTT_MAX_TOPIC_STRLEN + 1];
|
char MqttDischargeCurrentTopic[MQTT_MAX_TOPIC_STRLEN + 1];
|
||||||
char MqttDischargeCurrentJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
|
char MqttDischargeCurrentJsonPath[BATTERY_JSON_MAX_PATH_STRLEN + 1];
|
||||||
|
|||||||
@ -156,6 +156,8 @@
|
|||||||
#define BATTERY_JKBMS_POLLING_INTERVAL 5
|
#define BATTERY_JKBMS_POLLING_INTERVAL 5
|
||||||
#define BATTERY_ENABLE_DISCHARGE_CURRENT_LIMIT false
|
#define BATTERY_ENABLE_DISCHARGE_CURRENT_LIMIT false
|
||||||
#define BATTERY_DISCHARGE_CURRENT_LIMIT 0.0
|
#define BATTERY_DISCHARGE_CURRENT_LIMIT 0.0
|
||||||
|
#define BATTERY_DISCHARGE_CURRENT_LIMIT_BELOW_SOC 100.0
|
||||||
|
#define BATTERY_DISCHARGE_CURRENT_LIMIT_BELOW_VOLTAGE 60.0
|
||||||
#define BATTERY_USE_BATTERY_REPORTED_DISCHARGE_CURRENT_LIMIT false
|
#define BATTERY_USE_BATTERY_REPORTED_DISCHARGE_CURRENT_LIMIT false
|
||||||
|
|
||||||
#define HUAWEI_ENABLED false
|
#define HUAWEI_ENABLED false
|
||||||
|
|||||||
@ -91,14 +91,26 @@ float BatteryClass::getDischargeCurrentLimit()
|
|||||||
if (!config.Battery.EnableDischargeCurrentLimit) { return FLT_MAX; }
|
if (!config.Battery.EnableDischargeCurrentLimit) { return FLT_MAX; }
|
||||||
|
|
||||||
auto dischargeCurrentLimit = config.Battery.DischargeCurrentLimit;
|
auto dischargeCurrentLimit = config.Battery.DischargeCurrentLimit;
|
||||||
auto dischargeCurrentValid = dischargeCurrentLimit > 0.0f;
|
auto dischargeCurrentLimitValid = dischargeCurrentLimit > 0.0f;
|
||||||
|
auto dischargeCurrentLimitBelowSoc = config.Battery.DischargeCurrentLimitBelowSoc;
|
||||||
|
auto dischargeCurrentLimitBelowVoltage = config.Battery.DischargeCurrentLimitBelowVoltage;
|
||||||
|
auto statsSoCValid = getStats()->getSoCAgeSeconds() <= 60 && !config.PowerLimiter.IgnoreSoc;
|
||||||
|
auto statsSoC = statsSoCValid ? getStats()->getSoC() : 100.0; // fail open so we use voltage instead
|
||||||
|
auto statsVoltageValid = getStats()->getVoltageAgeSeconds() <= 60;
|
||||||
|
auto statsVoltage = statsVoltageValid ? getStats()->getVoltage() : 0.0; // fail closed
|
||||||
auto statsCurrentLimit = getStats()->getDischargeCurrentLimit();
|
auto statsCurrentLimit = getStats()->getDischargeCurrentLimit();
|
||||||
auto statsLimitValid = config.Battery.UseBatteryReportedDischargeCurrentLimit
|
auto statsLimitValid = config.Battery.UseBatteryReportedDischargeCurrentLimit
|
||||||
&& statsCurrentLimit >= 0.0f
|
&& statsCurrentLimit >= 0.0f
|
||||||
&& getStats()->getDischargeCurrentLimitAgeSeconds() <= 60;
|
&& getStats()->getDischargeCurrentLimitAgeSeconds() <= 60;
|
||||||
|
|
||||||
if (statsLimitValid && dischargeCurrentValid) {
|
|
||||||
|
if (statsSoC > dischargeCurrentLimitBelowSoc && statsVoltage > dischargeCurrentLimitBelowVoltage) {
|
||||||
|
// Above SoC and Voltage thresholds, ignore custom limit.
|
||||||
|
// Battery-provided limit will still be applied.
|
||||||
|
dischargeCurrentLimitValid = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (statsLimitValid && dischargeCurrentLimitValid) {
|
||||||
// take the lowest limit
|
// take the lowest limit
|
||||||
return min(statsCurrentLimit, dischargeCurrentLimit);
|
return min(statsCurrentLimit, dischargeCurrentLimit);
|
||||||
}
|
}
|
||||||
@ -107,7 +119,7 @@ float BatteryClass::getDischargeCurrentLimit()
|
|||||||
return statsCurrentLimit;
|
return statsCurrentLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (dischargeCurrentValid) {
|
if (dischargeCurrentLimitValid) {
|
||||||
return dischargeCurrentLimit;
|
return dischargeCurrentLimit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@ -88,6 +88,8 @@ void ConfigurationClass::serializeBatteryConfig(BatteryConfig const& source, Jso
|
|||||||
target["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;
|
target["mqtt_voltage_unit"] = config.Battery.MqttVoltageUnit;
|
||||||
target["enable_discharge_current_limit"] = config.Battery.EnableDischargeCurrentLimit;
|
target["enable_discharge_current_limit"] = config.Battery.EnableDischargeCurrentLimit;
|
||||||
target["discharge_current_limit"] = config.Battery.DischargeCurrentLimit;
|
target["discharge_current_limit"] = config.Battery.DischargeCurrentLimit;
|
||||||
|
target["discharge_current_limit_below_soc"] = config.Battery.DischargeCurrentLimitBelowSoc;
|
||||||
|
target["discharge_current_limit_below_voltage"] = config.Battery.DischargeCurrentLimitBelowVoltage;
|
||||||
target["use_battery_reported_discharge_current_limit"] = config.Battery.UseBatteryReportedDischargeCurrentLimit;
|
target["use_battery_reported_discharge_current_limit"] = config.Battery.UseBatteryReportedDischargeCurrentLimit;
|
||||||
target["mqtt_discharge_current_topic"] = config.Battery.MqttDischargeCurrentTopic;
|
target["mqtt_discharge_current_topic"] = config.Battery.MqttDischargeCurrentTopic;
|
||||||
target["mqtt_discharge_current_json_path"] = config.Battery.MqttDischargeCurrentJsonPath;
|
target["mqtt_discharge_current_json_path"] = config.Battery.MqttDischargeCurrentJsonPath;
|
||||||
@ -383,6 +385,8 @@ void ConfigurationClass::deserializeBatteryConfig(JsonObject const& source, Batt
|
|||||||
target.MqttVoltageUnit = source["mqtt_voltage_unit"] | BatteryVoltageUnit::Volts;
|
target.MqttVoltageUnit = source["mqtt_voltage_unit"] | BatteryVoltageUnit::Volts;
|
||||||
target.EnableDischargeCurrentLimit = source["enable_discharge_current_limit"] | BATTERY_ENABLE_DISCHARGE_CURRENT_LIMIT;
|
target.EnableDischargeCurrentLimit = source["enable_discharge_current_limit"] | BATTERY_ENABLE_DISCHARGE_CURRENT_LIMIT;
|
||||||
target.DischargeCurrentLimit = source["discharge_current_limit"] | BATTERY_DISCHARGE_CURRENT_LIMIT;
|
target.DischargeCurrentLimit = source["discharge_current_limit"] | BATTERY_DISCHARGE_CURRENT_LIMIT;
|
||||||
|
target.DischargeCurrentLimitBelowSoc = source["discharge_current_limit_below_soc"] | BATTERY_DISCHARGE_CURRENT_LIMIT_BELOW_SOC;
|
||||||
|
target.DischargeCurrentLimitBelowVoltage = source["discharge_current_limit_below_voltage"] | BATTERY_DISCHARGE_CURRENT_LIMIT_BELOW_VOLTAGE;
|
||||||
target.UseBatteryReportedDischargeCurrentLimit = source["use_battery_reported_discharge_current_limit"] | BATTERY_USE_BATTERY_REPORTED_DISCHARGE_CURRENT_LIMIT;
|
target.UseBatteryReportedDischargeCurrentLimit = source["use_battery_reported_discharge_current_limit"] | BATTERY_USE_BATTERY_REPORTED_DISCHARGE_CURRENT_LIMIT;
|
||||||
strlcpy(target.MqttDischargeCurrentTopic, source["mqtt_discharge_current_topic"] | "", sizeof(config.Battery.MqttDischargeCurrentTopic));
|
strlcpy(target.MqttDischargeCurrentTopic, source["mqtt_discharge_current_topic"] | "", sizeof(config.Battery.MqttDischargeCurrentTopic));
|
||||||
strlcpy(target.MqttDischargeCurrentJsonPath, source["mqtt_discharge_current_json_path"] | "", sizeof(config.Battery.MqttDischargeCurrentJsonPath));
|
strlcpy(target.MqttDischargeCurrentJsonPath, source["mqtt_discharge_current_json_path"] | "", sizeof(config.Battery.MqttDischargeCurrentJsonPath));
|
||||||
|
|||||||
@ -724,6 +724,10 @@
|
|||||||
"DischargeCurrentLimitConfiguration": "Einstellungen Entladestromlimit",
|
"DischargeCurrentLimitConfiguration": "Einstellungen Entladestromlimit",
|
||||||
"LimitDischargeCurrent": "Entladestrom limitieren",
|
"LimitDischargeCurrent": "Entladestrom limitieren",
|
||||||
"DischargeCurrentLimit": "max. Entladestrom",
|
"DischargeCurrentLimit": "max. Entladestrom",
|
||||||
|
"DischargeCurrentLimitBelowSoc": "Limitieren unter SoC",
|
||||||
|
"DischargeCurrentLimitBelowSocInfo": "Das Entladestromlimit wird nur unter dieser SoC-Schwelle angewendet (nicht verwendet falls 'Batterie SoC ignorieren' aktiviert ist).",
|
||||||
|
"DischargeCurrentLimitBelowVoltage": "Limitieren unter Spannung",
|
||||||
|
"DischargeCurrentLimitBelowVoltageInfo": "Das Entladestromlimit wird nur unter dieser Spannungs-Schwelle angewendet (wenn SoC ignoriert oder nicht verfügbar).",
|
||||||
"UseBatteryReportedDischargeCurrentLimit": "Von der Batterie übermitteltes Limit verwenden",
|
"UseBatteryReportedDischargeCurrentLimit": "Von der Batterie übermitteltes Limit verwenden",
|
||||||
"BatteryReportedDischargeCurrentLimitInfo": "<b>Hinweis:</b> Das niedrigste Limit wird angewendet, wobei das von der Batterie übermittelte Entladestromlimit nur verwendet wird, wenn in der letzten Minute ein Update eingegangen ist; andernfalls dient das zuvor festgelegte Limit als Fallback.",
|
"BatteryReportedDischargeCurrentLimitInfo": "<b>Hinweis:</b> Das niedrigste Limit wird angewendet, wobei das von der Batterie übermittelte Entladestromlimit nur verwendet wird, wenn in der letzten Minute ein Update eingegangen ist; andernfalls dient das zuvor festgelegte Limit als Fallback.",
|
||||||
"MqttDischargeCurrentTopic": "Topic für Entladestromlimit",
|
"MqttDischargeCurrentTopic": "Topic für Entladestromlimit",
|
||||||
|
|||||||
@ -727,6 +727,10 @@
|
|||||||
"DischargeCurrentLimitConfiguration": "Discharge Current Limit Settings",
|
"DischargeCurrentLimitConfiguration": "Discharge Current Limit Settings",
|
||||||
"LimitDischargeCurrent": "Limit Discharge Current",
|
"LimitDischargeCurrent": "Limit Discharge Current",
|
||||||
"DischargeCurrentLimit": "max. Discharge Current",
|
"DischargeCurrentLimit": "max. Discharge Current",
|
||||||
|
"DischargeCurrentLimitBelowSoc": "Apply limit below SoC",
|
||||||
|
"DischargeCurrentLimitBelowSocInfo": "The discharge current limit is not applied above this SoC (not used if 'Ignore Battery SoC' is enabled).",
|
||||||
|
"DischargeCurrentLimitBelowVoltage": "Apply limit below voltage",
|
||||||
|
"DischargeCurrentLimitBelowVoltageInfo": "The discharge current limit is not applied above this voltage (used if SoC ignored or unavailable).",
|
||||||
"UseBatteryReportedDischargeCurrentLimit": "Use Battery-Reported limit",
|
"UseBatteryReportedDischargeCurrentLimit": "Use Battery-Reported limit",
|
||||||
"BatteryReportedDischargeCurrentLimitInfo": "<b>Hint:</b> The lowest limit will be applied, with the battery-reported discharge current limit used only if an update was received in the last minute; otherwise, the previously specified limit will act as a fallback.",
|
"BatteryReportedDischargeCurrentLimitInfo": "<b>Hint:</b> The lowest limit will be applied, with the battery-reported discharge current limit used only if an update was received in the last minute; otherwise, the previously specified limit will act as a fallback.",
|
||||||
"MqttDischargeCurrentTopic": "Discharge Current Limit Value Topic",
|
"MqttDischargeCurrentTopic": "Discharge Current Limit Value Topic",
|
||||||
|
|||||||
@ -11,6 +11,8 @@ export interface BatteryConfig {
|
|||||||
mqtt_voltage_unit: number;
|
mqtt_voltage_unit: number;
|
||||||
enable_discharge_current_limit: boolean;
|
enable_discharge_current_limit: boolean;
|
||||||
discharge_current_limit: number;
|
discharge_current_limit: number;
|
||||||
|
discharge_current_limit_below_soc: number;
|
||||||
|
discharge_current_limit_below_voltage: number;
|
||||||
use_battery_reported_discharge_current_limit: boolean;
|
use_battery_reported_discharge_current_limit: boolean;
|
||||||
mqtt_discharge_current_topic: string;
|
mqtt_discharge_current_topic: string;
|
||||||
mqtt_discharge_current_json_path: string;
|
mqtt_discharge_current_json_path: string;
|
||||||
|
|||||||
@ -141,6 +141,28 @@
|
|||||||
postfix="A"
|
postfix="A"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
|
<InputElement
|
||||||
|
:label="$t('batteryadmin.DischargeCurrentLimitBelowSoc')"
|
||||||
|
v-model="batteryConfigList.discharge_current_limit_below_soc"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
max="100"
|
||||||
|
step="0.1"
|
||||||
|
postfix="%"
|
||||||
|
:tooltip="$t('batteryadmin.DischargeCurrentLimitBelowSocInfo')"
|
||||||
|
/>
|
||||||
|
|
||||||
|
<InputElement
|
||||||
|
:label="$t('batteryadmin.DischargeCurrentLimitBelowVoltage')"
|
||||||
|
v-model="batteryConfigList.discharge_current_limit_below_voltage"
|
||||||
|
type="number"
|
||||||
|
min="0"
|
||||||
|
max="60"
|
||||||
|
step="0.01"
|
||||||
|
postfix="V"
|
||||||
|
:tooltip="$t('batteryadmin.DischargeCurrentLimitBelowVoltageInfo')"
|
||||||
|
/>
|
||||||
|
|
||||||
<InputElement
|
<InputElement
|
||||||
:label="$t('batteryadmin.UseBatteryReportedDischargeCurrentLimit')"
|
:label="$t('batteryadmin.UseBatteryReportedDischargeCurrentLimit')"
|
||||||
v-model="batteryConfigList.use_battery_reported_discharge_current_limit"
|
v-model="batteryConfigList.use_battery_reported_discharge_current_limit"
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user