Skip to content

logic: support minimum grid charge soc#356

Merged
MaStr merged 1 commit into
MaStr:mainfrom
filiplajszczak:logic-min-grid-charge-soc
Apr 30, 2026
Merged

logic: support minimum grid charge soc#356
MaStr merged 1 commit into
MaStr:mainfrom
filiplajszczak:logic-min-grid-charge-soc

Conversation

@filiplajszczak
Copy link
Copy Markdown
Contributor

@filiplajszczak filiplajszczak commented Apr 29, 2026

Add optional battery_control.min_grid_charge_soc as a ratio target, e.g. 0.55.

When set, batcontrol grid-charges toward that target when charging is economical. When unset, behavior is unchanged.

An expert option, battery_control_expert.preserve_min_grid_charge_soc, can additionally preserve that target as reserved energy during cheap/pre-expensive windows.

Applies to both DefaultLogic and NextLogic.

@MaStr
Copy link
Copy Markdown
Owner

MaStr commented Apr 29, 2026

Good idea.
I think we publish this parameter via MQTT, if set. Not necessarily for /set but to have it in influxDB for instance (via Telegraf).

@MaStr MaStr added this to the 0.8.0 milestone Apr 29, 2026
@MaStr
Copy link
Copy Markdown
Owner

MaStr commented Apr 29, 2026

And a wiki entry with a configuration example

@filiplajszczak filiplajszczak force-pushed the logic-min-grid-charge-soc branch from be5e265 to c0a1312 Compare April 29, 2026 17:55
@filiplajszczak
Copy link
Copy Markdown
Contributor Author

Pushed an update for the review notes:

  • publish min_grid_charge_soc / _percent via MQTT when configured
  • add HA discovery as a diagnostic sensor
  • add the sample config entry

I also prepared the wiki snippet locally and can push/update the wiki after this lands.

@MaStr
Copy link
Copy Markdown
Owner

MaStr commented Apr 29, 2026

min_grid_charge > max_charging_from_grid_limit won't be effective.
With stepping over max_charging limit, the recharge calculation won't result into a recharge_amount.

Either we give a warning at startup, or during optimizer run, that the values are note correlate together.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Adds an optional battery_control.min_grid_charge_soc ratio target that (when set) preserves battery energy below the target during cheap/pre-expensive windows and increases grid-charge energy toward that target when charging is already economical, for both DefaultLogic and NextLogic.

Changes:

  • Introduces min_grid_charge_soc into CalculationParameters, config loading, and MQTT publishing/discovery.
  • Updates DefaultLogic and NextLogic to apply the minimum SoC target both to discharge reservation and required grid recharge energy via shared CommonLogic helpers.
  • Adds/extends test coverage across MQTT API, core publishing behavior, and logic scenarios (including regression-style live cases).

Reviewed changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated no comments.

Show a summary per file
File Description
src/batcontrol/logic/logic_interface.py Adds min_grid_charge_soc to CalculationParameters with validation.
src/batcontrol/core.py Loads min_grid_charge_soc, passes it into calculation parameters, and publishes it via MQTT when set.
src/batcontrol/logic/common.py Adds shared helpers to apply min-grid-charge SoC to recharge target and discharge reserve.
src/batcontrol/logic/default.py Applies min-grid-charge SoC reserve + recharge target behavior in DefaultLogic.
src/batcontrol/logic/next.py Applies the same min-grid-charge SoC reserve + recharge target behavior in NextLogic.
src/batcontrol/mqtt_api.py Publishes min-grid-charge SoC (ratio + percent) and exposes a discovery sensor for the percent topic.
config/batcontrol_config_dummy.yaml Documents the new optional config parameter.
tests/batcontrol/test_core.py Verifies static MQTT publishing includes/omits min_grid_charge_soc depending on configuration.
tests/batcontrol/test_mqtt_api.py Verifies MQTT publish formatting and discovery message inclusion for min-grid-charge SoC.
tests/batcontrol/logic/test_default.py Adds DefaultLogic behavioral/unit tests for min-grid-charge SoC (including validation).
tests/batcontrol/logic/test_peak_shaving.py Refactors grid-charge test input helper and adds NextLogic min-grid-charge SoC tests.
tests/batcontrol/logic/test_min_grid_charge_soc_live_cases.py Adds regression-style scenario tests for both logics using realistic price/forecast sequences.

@filiplajszczak filiplajszczak force-pushed the logic-min-grid-charge-soc branch from c0a1312 to 9717200 Compare April 30, 2026 04:57
@filiplajszczak
Copy link
Copy Markdown
Contributor Author

Added a startup warning for this case.

If min_grid_charge_soc is configured above max_charging_from_grid_limit, batcontrol now logs that grid charging cannot reach the minimum SoC target and suggests either increasing max_charging_from_grid_limit or lowering min_grid_charge_soc.

I kept it warning-only, which is in line with other conflicting settings that do not crash startup but can otherwise result in a potentially confusing runtime state.

Copy link
Copy Markdown
Owner

@MaStr MaStr left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

General question about your intentions about reserving more then needed.

Comment thread src/batcontrol/logic/default.py
Comment thread src/batcontrol/logic/default.py
@MaStr
Copy link
Copy Markdown
Owner

MaStr commented Apr 30, 2026

https://discord.gg/tjJUCDeZ

This is an invite to a separate discord channel for development

@filiplajszczak filiplajszczak force-pushed the logic-min-grid-charge-soc branch from 9717200 to 225c26f Compare April 30, 2026 11:13
@filiplajszczak
Copy link
Copy Markdown
Contributor Author

I made the reserve side opt-in as an expert setting.

min_grid_charge_soc now provides the recharge target by default. If battery_control_expert.preserve_min_grid_charge_soc: true is set, it also raises reserved energy to that floor during cheap/pre-expensive windows.

This keeps the default behavior closer to the existing steering model while still allowing the preservation policy for users who explicitly want to avoid cheap-window discharge + later recharge cycling.

@filiplajszczak filiplajszczak requested a review from MaStr April 30, 2026 11:20
@MaStr MaStr requested review from Copilot and removed request for MaStr April 30, 2026 11:21
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

Copilot reviewed 12 out of 12 changed files in this pull request and generated 2 comments.

Comment thread src/batcontrol/core.py Outdated
Comment on lines +280 to +285
self.min_grid_charge_soc = self.batconfig.get(
'min_grid_charge_soc', None)
self.preserve_min_grid_charge_soc = False
if (self.min_grid_charge_soc is not None
and self.min_grid_charge_soc > self.max_charging_from_grid_limit):
logger.warning(
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

min_grid_charge_soc is read from config without type/range validation, but it's immediately compared to max_charging_from_grid_limit. If the YAML value is accidentally quoted (string) or otherwise non-numeric, this will raise a TypeError during Batcontrol initialization. Consider validating/coercing min_grid_charge_soc here (numeric, 0..1) and raising a clear RuntimeError/ValueError before using it (and before publishing to MQTT).

Copilot uses AI. Check for mistakes.
Comment thread src/batcontrol/logic/logic_interface.py Outdated
Comment on lines +48 to +54
def __post_init__(self):
if (self.min_grid_charge_soc is not None
and not 0 <= self.min_grid_charge_soc <= 1):
raise ValueError(
f"min_grid_charge_soc must be between 0 and 1 or None, "
f"got {self.min_grid_charge_soc}"
)
Copy link

Copilot AI Apr 30, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

CalculationParameters.__post_init__ checks the range of min_grid_charge_soc, but it doesn't validate the type first. If a config passes a non-numeric value (e.g., a quoted string from YAML), this will raise a TypeError instead of the intended ValueError with a helpful message. Consider adding an explicit numeric type check (similar to peak_shaving_price_limit) before the range comparison.

Copilot uses AI. Check for mistakes.
@filiplajszczak filiplajszczak force-pushed the logic-min-grid-charge-soc branch from 225c26f to 55d2cd3 Compare April 30, 2026 11:43
@filiplajszczak
Copy link
Copy Markdown
Contributor Author

Addressed the validation comments: min_grid_charge_soc is now parsed at config load, accepts numeric strings like "0.55", and raises clear ValueErrors for bool/non-numeric/out-of-range values. CalculationParameters also
has a defensive type check.

@filiplajszczak filiplajszczak requested a review from MaStr April 30, 2026 11:54
@MaStr MaStr merged commit ffe905e into MaStr:main Apr 30, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants