diff --git a/include/Configuration.h b/include/Configuration.h index cc345643..f4a4a4a9 100644 --- a/include/Configuration.h +++ b/include/Configuration.h @@ -213,6 +213,7 @@ struct CONFIG_T { int32_t TargetPowerConsumptionHysteresis; int32_t LowerPowerLimit; int32_t UpperPowerLimit; + bool IgnoreSoc; uint32_t BatterySocStartThreshold; uint32_t BatterySocStopThreshold; float VoltageStartThreshold; diff --git a/include/defaults.h b/include/defaults.h index 7e1d7a0c..56030d9b 100644 --- a/include/defaults.h +++ b/include/defaults.h @@ -128,6 +128,7 @@ #define POWERLIMITER_TARGET_POWER_CONSUMPTION_HYSTERESIS 0 #define POWERLIMITER_LOWER_POWER_LIMIT 10 #define POWERLIMITER_UPPER_POWER_LIMIT 800 +#define POWERLIMITER_IGNORE_SOC false #define POWERLIMITER_BATTERY_SOC_START_THRESHOLD 80 #define POWERLIMITER_BATTERY_SOC_STOP_THRESHOLD 20 #define POWERLIMITER_VOLTAGE_START_THRESHOLD 50.0 diff --git a/src/Configuration.cpp b/src/Configuration.cpp index 5004b3cb..50968d40 100644 --- a/src/Configuration.cpp +++ b/src/Configuration.cpp @@ -191,6 +191,7 @@ bool ConfigurationClass::write() powerlimiter["target_power_consumption_hysteresis"] = config.PowerLimiter.TargetPowerConsumptionHysteresis; powerlimiter["lower_power_limit"] = config.PowerLimiter.LowerPowerLimit; powerlimiter["upper_power_limit"] = config.PowerLimiter.UpperPowerLimit; + powerlimiter["ignore_soc"] = config.PowerLimiter.IgnoreSoc; powerlimiter["battery_soc_start_threshold"] = config.PowerLimiter.BatterySocStartThreshold; powerlimiter["battery_soc_stop_threshold"] = config.PowerLimiter.BatterySocStopThreshold; powerlimiter["voltage_start_threshold"] = config.PowerLimiter.VoltageStartThreshold; @@ -435,6 +436,7 @@ bool ConfigurationClass::read() config.PowerLimiter.TargetPowerConsumptionHysteresis = powerlimiter["target_power_consumption_hysteresis"] | POWERLIMITER_TARGET_POWER_CONSUMPTION_HYSTERESIS; config.PowerLimiter.LowerPowerLimit = powerlimiter["lower_power_limit"] | POWERLIMITER_LOWER_POWER_LIMIT; config.PowerLimiter.UpperPowerLimit = powerlimiter["upper_power_limit"] | POWERLIMITER_UPPER_POWER_LIMIT; + config.PowerLimiter.IgnoreSoc = powerlimiter["ignore_soc"] | POWERLIMITER_IGNORE_SOC; config.PowerLimiter.BatterySocStartThreshold = powerlimiter["battery_soc_start_threshold"] | POWERLIMITER_BATTERY_SOC_START_THRESHOLD; config.PowerLimiter.BatterySocStopThreshold = powerlimiter["battery_soc_stop_threshold"] | POWERLIMITER_BATTERY_SOC_STOP_THRESHOLD; config.PowerLimiter.VoltageStartThreshold = powerlimiter["voltage_start_threshold"] | POWERLIMITER_VOLTAGE_START_THRESHOLD; diff --git a/src/PowerLimiter.cpp b/src/PowerLimiter.cpp index e7f2ea2d..56dc11e4 100644 --- a/src/PowerLimiter.cpp +++ b/src/PowerLimiter.cpp @@ -290,12 +290,13 @@ void PowerLimiterClass::loop() } if (_verboseLogging) { - MessageOutput.printf("[DPL::loop] battery interface %s, SoC: %d %%, StartTH: %d %%, StopTH: %d %%, SoC age: %d s\r\n", + MessageOutput.printf("[DPL::loop] battery interface %s, SoC: %d %%, StartTH: %d %%, StopTH: %d %%, SoC age: %d s, ignore: %s\r\n", (config.Battery.Enabled?"enabled":"disabled"), Battery.getStats()->getSoC(), config.PowerLimiter.BatterySocStartThreshold, config.PowerLimiter.BatterySocStopThreshold, - Battery.getStats()->getSoCAgeSeconds()); + Battery.getStats()->getSoCAgeSeconds(), + (config.PowerLimiter.IgnoreSoc?"yes":"no")); float dcVoltage = _inverter->Statistics()->getChannelFieldValue(TYPE_DC, (ChannelNum_t)config.PowerLimiter.InverterChannelId, FLD_UDC); MessageOutput.printf("[DPL::loop] dcVoltage: %.2f V, loadCorrectedVoltage: %.2f V, StartTH: %.2f V, StopTH: %.2f V\r\n", @@ -608,8 +609,10 @@ bool PowerLimiterClass::testThreshold(float socThreshold, float voltThreshold, { CONFIG_T& config = Configuration.get(); - // prefer SoC provided through battery interface - if (config.Battery.Enabled && socThreshold > 0.0 + // prefer SoC provided through battery interface, unless disabled by user + if (!config.PowerLimiter.IgnoreSoc + && config.Battery.Enabled + && socThreshold > 0.0 && Battery.getStats()->isValid() && Battery.getStats()->getSoCAgeSeconds() < 60) { return compare(Battery.getStats()->getSoC(), socThreshold); diff --git a/src/WebApi_powerlimiter.cpp b/src/WebApi_powerlimiter.cpp index 25cb42e2..df530ca8 100644 --- a/src/WebApi_powerlimiter.cpp +++ b/src/WebApi_powerlimiter.cpp @@ -45,6 +45,7 @@ void WebApiPowerLimiterClass::onStatus(AsyncWebServerRequest* request) root["target_power_consumption_hysteresis"] = config.PowerLimiter.TargetPowerConsumptionHysteresis; root["lower_power_limit"] = config.PowerLimiter.LowerPowerLimit; root["upper_power_limit"] = config.PowerLimiter.UpperPowerLimit; + root["ignore_soc"] = config.PowerLimiter.IgnoreSoc; root["battery_soc_start_threshold"] = config.PowerLimiter.BatterySocStartThreshold; root["battery_soc_stop_threshold"] = config.PowerLimiter.BatterySocStopThreshold; root["voltage_start_threshold"] = static_cast(config.PowerLimiter.VoltageStartThreshold * 100 +0.5) / 100.0; @@ -133,6 +134,7 @@ void WebApiPowerLimiterClass::onAdminPost(AsyncWebServerRequest* request) config.PowerLimiter.TargetPowerConsumptionHysteresis = root["target_power_consumption_hysteresis"].as(); config.PowerLimiter.LowerPowerLimit = root["lower_power_limit"].as(); config.PowerLimiter.UpperPowerLimit = root["upper_power_limit"].as(); + config.PowerLimiter.IgnoreSoc = root["ignore_soc"].as(); config.PowerLimiter.BatterySocStartThreshold = root["battery_soc_start_threshold"].as(); config.PowerLimiter.BatterySocStopThreshold = root["battery_soc_stop_threshold"].as(); config.PowerLimiter.VoltageStartThreshold = root["voltage_start_threshold"].as(); diff --git a/webapp/src/locales/de.json b/webapp/src/locales/de.json index ae442ec2..ddd458fb 100644 --- a/webapp/src/locales/de.json +++ b/webapp/src/locales/de.json @@ -595,17 +595,18 @@ "LowerPowerLimit": "Unteres Leistungslimit", "UpperPowerLimit": "Oberes Leistungslimit", "PowerMeters": "Leistungsmesser", + "IgnoreSoc": "Batterie SoC ignorieren", "BatterySocStartThreshold": "Akku SoC - Start", "BatterySocStopThreshold": "Akku SoC - Stop", "BatterySocSolarPassthroughStartThreshold": "Akku SoC - Start solar passthrough", - "BatterySocSolarPassthroughStartThresholdHint": "Wenn der Batterie SOC über diesem Limit ist wird die Inverter Leistung entsprechend der Victron MPPT Leistung gesetzt (abzüglich Effizienzkorrekturfaktor). Kann verwendet werden um überschüssige Solarleistung an das Netz zu liefern wenn die Batterie voll ist.", + "BatterySocSolarPassthroughStartThresholdHint": "Wenn der Batterie SoC über diesem Limit ist wird die Inverter Leistung entsprechend der Victron MPPT Leistung gesetzt (abzüglich Effizienzkorrekturfaktor). Kann verwendet werden um überschüssige Solarleistung an das Netz zu liefern wenn die Batterie voll ist.", "VoltageStartThreshold": "DC Spannung - Start", "VoltageStopThreshold": "DC Spannung - Stop", "VoltageSolarPassthroughStartThreshold": "DC Spannung - Start Solar-Passthrough", "VoltageSolarPassthroughStopThreshold": "DC Spannung - Stop Solar-Passthrough", "VoltageSolarPassthroughStartThresholdHint": "Wenn der Batteriespannung über diesem Limit ist wird die Inverter Leistung entsprechend der Victron MPPT Leistung gesetzt (abzüglich Effizienzkorrekturfaktor). Kann verwendet werden um überschüssige Solarleistung an das Netz zu liefern wenn die Batterie voll ist. Dieser Mode wird aktiv wenn das Start Spannungslimit überschritten wird und inaktiv wenn das Stop Spannungslimit unterschritten wird.", "VoltageLoadCorrectionFactor": "DC Spannung - Lastkorrekturfaktor", - "BatterySocInfo": "Hinweis: Die Akku SoC (State of Charge) Werte können nur benutzt werden, wenn die Batterie-Kommunikationsschnittstelle aktiviert ist. Wenn die Batterie innerhalb der letzten Minute keine Werte geschickt hat, werden als Fallback-Option die Spannungseinstellungen verwendet.", + "BatterySocInfo": "Hinweis: Die Akku SoC (State of Charge) Werte werden nur benutzt, wenn die Batterie-Kommunikationsschnittstelle innerhalb der letzten Minute gültige Werte geschickt hat. Andernfalls werden als Fallback-Option die Spannungseinstellungen verwendet.", "InverterIsBehindPowerMeter": "Welchselrichter ist hinter Leistungsmesser", "Battery": "DC / Akku", "VoltageLoadCorrectionInfo": "Hinweis: Wenn Leistung von der Batterie abgegeben wird, bricht normalerweise die Spannung etwas ein. Damit nicht vorzeitig der Wechelrichter ausgeschaltet wird sobald der \"Stop\"-Schwellenwert erreicht wird, wird der hier angegebene Korrekturfaktor mit einberechnet. Korrigierte Spannung = DC Spannung + (Aktuelle Leistung (W) * Korrekturfaktor).", diff --git a/webapp/src/locales/en.json b/webapp/src/locales/en.json index 668e095e..57cb9b05 100644 --- a/webapp/src/locales/en.json +++ b/webapp/src/locales/en.json @@ -601,9 +601,7 @@ "LowerPowerLimit": "Lower power limit", "UpperPowerLimit": "Upper power limit", "PowerMeters": "Power meter", - "MqttTopicPowerMeter1": "MQTT topic - Power meter #1", - "MqttTopicPowerMeter2": "MQTT topic - Power meter #2 (optional)", - "MqttTopicPowerMeter3": "MQTT topic - Power meter #3 (optional)", + "IgnoreSoc": "Ignore Battery SoC", "BatterySocStartThreshold": "Battery SoC - Start threshold", "BatterySocStopThreshold": "Battery SoC - Stop threshold", "BatterySocSolarPassthroughStartThreshold": "Battery SoC - Start threshold for full solar passthrough", @@ -614,7 +612,7 @@ "VoltageSolarPassthroughStopThreshold": "DC Voltage - Stop threshold for full solar passthrough", "VoltageSolarPassthroughStartThresholdHint": "Inverter power is set according to Victron MPPT power (minus efficiency factors) when full solar passthrough is active. Use this if you like to supply excess power to the grid when battery is full. This is started when battery voltage goes over this limit and stopped if voltage drops below stop limit.", "VoltageLoadCorrectionFactor": "DC Voltage - Load correction factor", - "BatterySocInfo": "Hint: The battery SoC (State of Charge) values can only be used if the battery communication interface is enabled. If the battery has not reported any SoC updates in the last minute, the voltage thresholds will be used as fallback.", + "BatterySocInfo": "Hint: The battery SoC (State of Charge) values are only used if the battery communication interface reported SoC updates in the last minute. Otherwise the voltage thresholds will be used as fallback.", "InverterIsBehindPowerMeter": "Inverter is behind Power meter", "Battery": "DC / Battery", "VoltageLoadCorrectionInfo": "Hint: When the power output is higher, the voltage is usually decreasing. In order to not stop the inverter too early (Stop treshold), a power factor can be specified here to correct this. Corrected voltage = DC Voltage + (Current power * correction factor).", diff --git a/webapp/src/locales/fr.json b/webapp/src/locales/fr.json index 7c845c74..4fbdc8d7 100644 --- a/webapp/src/locales/fr.json +++ b/webapp/src/locales/fr.json @@ -648,9 +648,7 @@ "LowerPowerLimit": "Lower power limit", "UpperPowerLimit": "Upper power limit", "PowerMeters": "Power meter", - "MqttTopicPowerMeter1": "MQTT topic - Power meter #1", - "MqttTopicPowerMeter2": "MQTT topic - Power meter #2 (optional)", - "MqttTopicPowerMeter3": "MQTT topic - Power meter #3 (optional)", + "IgnoreSoc": "Ignore Battery SoC", "BatterySocStartThreshold": "Battery SoC - Start threshold", "BatterySocStopThreshold": "Battery SoC - Stop threshold", "BatterySocSolarPassthroughStartThreshold": "Battery SoC - Start threshold for full solar passthrough", @@ -661,7 +659,7 @@ "VoltageSolarPassthroughStopThreshold": "DC Voltage - Stop threshold for full solar passthrough", "VoltageSolarPassthroughStartThresholdHint": "Inverter power is set according to Victron MPPT power (minus efficiency factors) when full solar passthrough is active. Use this if you like to supply excess power to the grid when battery is full. This is started when battery voltage goes over this limit and stopped if voltage drops below stop limit.", "VoltageLoadCorrectionFactor": "DC Voltage - Load correction factor", - "BatterySocInfo": "Hint: The battery SoC (State of Charge) values can only be used if the battery communication interface is enabled. If the battery has not reported any SoC updates in the last minute, the voltage thresholds will be used as fallback.", + "BatterySocInfo": "Hint: The battery SoC (State of Charge) values are only used if the battery communication interface reported SoC updates in the last minute. Otherwise the voltage thresholds will be used as fallback.", "InverterIsBehindPowerMeter": "Inverter is behind Power meter", "Battery": "DC / Battery", "VoltageLoadCorrectionInfo": "Hint: When the power output is higher, the voltage is usually decreasing. In order to not stop the inverter too early (Stop treshold), a power factor can be specified here to correct this. Corrected voltage = DC Voltage + (Current power * correction factor)." diff --git a/webapp/src/types/PowerLimiterConfig.ts b/webapp/src/types/PowerLimiterConfig.ts index 00b9a142..594361d7 100644 --- a/webapp/src/types/PowerLimiterConfig.ts +++ b/webapp/src/types/PowerLimiterConfig.ts @@ -11,6 +11,7 @@ export interface PowerLimiterConfig { target_power_consumption_hysteresis: number; lower_power_limit: number; upper_power_limit: number; + ignore_soc: boolean; battery_soc_start_threshold: number; battery_soc_stop_threshold: number; voltage_start_threshold: number; diff --git a/webapp/src/views/PowerLimiterAdminView.vue b/webapp/src/views/PowerLimiterAdminView.vue index 8f10a4cd..898cd4f6 100644 --- a/webapp/src/views/PowerLimiterAdminView.vue +++ b/webapp/src/views/PowerLimiterAdminView.vue @@ -142,7 +142,12 @@ -
+ + +
@@ -154,7 +159,7 @@
-
+
@@ -166,7 +171,7 @@
-
+
@@ -180,7 +185,7 @@
- +