logic: support minimum grid charge soc#356
Conversation
|
Good idea. |
|
And a wiki entry with a configuration example |
be5e265 to
c0a1312
Compare
|
Pushed an update for the review notes:
I also prepared the wiki snippet locally and can push/update the wiki after this lands. |
|
min_grid_charge > max_charging_from_grid_limit won't be effective. Either we give a warning at startup, or during optimizer run, that the values are note correlate together. |
There was a problem hiding this comment.
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_socintoCalculationParameters, config loading, and MQTT publishing/discovery. - Updates
DefaultLogicandNextLogicto apply the minimum SoC target both to discharge reservation and required grid recharge energy via sharedCommonLogichelpers. - 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. |
c0a1312 to
9717200
Compare
|
Added a startup warning for this case. If 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. |
MaStr
left a comment
There was a problem hiding this comment.
General question about your intentions about reserving more then needed.
|
This is an invite to a separate discord channel for development |
9717200 to
225c26f
Compare
|
I made the reserve side opt-in as an expert setting.
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. |
| 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( |
There was a problem hiding this comment.
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).
| 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}" | ||
| ) |
There was a problem hiding this comment.
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.
225c26f to
55d2cd3
Compare
|
Addressed the validation comments: |
Add optional
battery_control.min_grid_charge_socas 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
DefaultLogicandNextLogic.