Skip to content

Commit d402274

Browse files
committed
Add aux power override for SOC predictions
Introduce a global _OVERULE_AUX_POWER (kW) to allow forcing an estimated auxiliary power load during charging. When set > 0 the code now overrides computed aux_kw in several places (power reading updates, AC charging data updates, magic SOC aux updates, and reconnection restore) so the SOC predictor uses the supplied value instead of the vehicle-reported/BMW value. Set to 0 to keep existing behavior.
1 parent 3140cc4 commit d402274

1 file changed

Lines changed: 14 additions & 2 deletions

File tree

custom_components/cardata/coordinator.py

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -69,6 +69,8 @@
6969
# Pre-compiled regex for AC phase parsing (avoids recompilation on each message)
7070
_AC_PHASE_PATTERN = re.compile(r"(\d{1,2})")
7171

72+
_OVERULE_AUX_POWER = 0.3 # kW - estimated auxiliary power load during charging (for SOC prediction) - set to zero to use bmw values
73+
7274

7375
def _descriptor_float(state: DescriptorState | None) -> float | None:
7476
"""Extract a float from a descriptor state, returning None on failure."""
@@ -516,6 +518,8 @@ def _anchor_soc_session(self, vin: str, vehicle_state: dict[str, DescriptorState
516518
aux_kw = float(aux_state.value) / 1000.0
517519
except (TypeError, ValueError):
518520
pass
521+
if _OVERULE_AUX_POWER > 0:
522+
aux_kw = float(_OVERULE_AUX_POWER)
519523
self._soc_predictor.update_power_reading(vin, power_kw, aux_power_kw=aux_kw)
520524
except (TypeError, ValueError):
521525
pass
@@ -531,6 +535,8 @@ def _anchor_soc_session(self, vin: str, vehicle_state: dict[str, DescriptorState
531535
aux_kw = float(aux_state.value) / 1000.0
532536
except (TypeError, ValueError):
533537
pass
538+
if _OVERULE_AUX_POWER > 0:
539+
aux_kw = float(_OVERULE_AUX_POWER)
534540
if voltage and current:
535541
self._soc_predictor.update_ac_charging_data(vin, voltage, current, phases, aux_kw)
536542
else:
@@ -1049,6 +1055,8 @@ async def _async_handle_message_locked(
10491055
aux_kw = float(aux_state.value) / 1000.0 # Convert W to kW
10501056
except (TypeError, ValueError):
10511057
pass
1058+
if _OVERULE_AUX_POWER > 0:
1059+
aux_kw = float(_OVERULE_AUX_POWER)
10521060
self._soc_predictor.update_power_reading(vin, power_kw, aux_power_kw=aux_kw)
10531061
# Trigger predicted_soc and magic_soc sensor updates during charging
10541062
if self._soc_predictor.is_charging(vin):
@@ -1082,7 +1090,8 @@ async def _async_handle_message_locked(
10821090
aux_kw = float(aux_state.value) / 1000.0
10831091
except (TypeError, ValueError):
10841092
pass
1085-
1093+
if _OVERULE_AUX_POWER > 0:
1094+
aux_kw = float(_OVERULE_AUX_POWER)
10861095
# Delegate to predictor
10871096
if self._soc_predictor.update_ac_charging_data(vin, voltage, current, phases, aux_kw):
10881097
if self._soc_predictor.has_signaled_entity(vin):
@@ -1163,6 +1172,8 @@ async def _async_handle_message_locked(
11631172
if value is not None:
11641173
try:
11651174
aux_w = float(value)
1175+
if _OVERULE_AUX_POWER > 0:
1176+
aux_kw = float(_OVERULE_AUX_POWER)
11661177
self._magic_soc.update_aux_power(vin, aux_w / 1000.0)
11671178
except (TypeError, ValueError):
11681179
pass
@@ -1567,7 +1578,8 @@ async def async_handle_connection_event(self, status: str, reason: str | None =
15671578
aux_kw = float(aux_state.value) / 1000.0
15681579
except (TypeError, ValueError):
15691580
pass
1570-
1581+
if _OVERULE_AUX_POWER > 0:
1582+
aux_kw = float(_OVERULE_AUX_POWER)
15711583
self._soc_predictor.update_ac_charging_data(vin, voltage, current, phases, aux_kw)
15721584
_LOGGER.info(
15731585
"Reconnection: restored AC charging data for %s (%.1fV × %.1fA)",

0 commit comments

Comments
 (0)