Skip to content

Fix: float slot end crash in yesterday_reconstruct_car_slots (issue #3911)#3920

Merged
springfall2008 merged 2 commits into
mainfrom
fix/car_crash
May 13, 2026
Merged

Fix: float slot end crash in yesterday_reconstruct_car_slots (issue #3911)#3920
springfall2008 merged 2 commits into
mainfrom
fix/car_crash

Conversation

@springfall2008
Copy link
Copy Markdown
Owner

Problem

Fixes #3911 — crash introduced in v8.39.2: TypeError: 'float' object cannot be interpreted as an integer in yesterday_reconstruct_car_slots.

Root Cause

In plan.py, both plan_car_charging and plan_iboost_smart contain a length-clamping block that fires when the battery is nearly full and the charging window supplies more energy than needed:

percent = kwh_left / kwh_add
length = min(round(((length * percent) / 5) + 0.5, 0) * 5, end - start)
end = start + length

round(x, 0) in Python 3 returns a float (e.g. 4.0, not 4), so length and therefore end = start + length become floats (e.g. 1570.0). These float values are stored in the slot dict and later passed to range(start, end, PREDICT_STEP) in yesterday_reconstruct_car_slots, which raises TypeError because range requires integers.

Users with fractional car_charging_battery_size (e.g. 11.9) or iBoost iboost_max_energy values are most likely to hit the clamping path and trigger this crash.

Fix

Wrap the min(...) result with int() at both sites:

length = int(min(round(((length * percent) / 5) + 0.5, 0) * 5, end - start))

This is a minimal, targeted change — only the two clamping expressions are touched.

Tests

Added run_car_charging_slot_integer_test to test_car_charging_smart.py. Three new test cases (smart_int1/2/3_issue3911) confirm that:

  • battery_size=11.9, soc=9.9 (exact reporter config) — slot end is int
  • battery_size=11.9, soc=0.0 — all slots have int ends
  • battery_size=77.0, soc=74.3, loss=0.9 — different battery/loss combination

All existing tests continue to pass (./run_all --quick).

)

round(x, 0) returns a Python float (e.g. 4.0 not 4), so when
plan_car_charging / plan_iboost_smart clamp a slot length to the
remaining kWh, the computed end time becomes a float such as 1570.0.
range(start, float_end, step) then raises TypeError in
yesterday_reconstruct_car_slots.

Fix: wrap the min(...) expression with int() at both sites in plan.py
so slot start/end values are always integers.

Add regression tests to run_car_charging_smart_tests that verify all
slot end values are int when the length-clamping path is triggered
(battery_size=11.9 reproduces the exact reporter config).
Copilot AI review requested due to automatic review settings May 13, 2026 07:54
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

This PR fixes a crash in yesterday_reconstruct_car_slots caused by plan_car_charging (and similarly plan_iboost_smart) sometimes producing float start/end minute values after length-clamping, which later breaks range(start, end, step).

Changes:

  • Ensure clamped length values are converted to int in both plan_car_charging and plan_iboost_smart so resulting slot boundaries remain integer minutes.
  • Add regression tests in test_car_charging_smart.py to confirm plan_car_charging slot start/end are always int for configurations that previously triggered the float-end bug.

Reviewed changes

Copilot reviewed 3 out of 3 changed files in this pull request and generated 1 comment.

File Description
apps/predbat/plan.py Casts clamped slot lengths to int in car-charging and iBoost smart planning to prevent float minute boundaries.
apps/predbat/tests/test_car_charging_smart.py Adds regression coverage to ensure car charging slots always have integer start/end values.

Comment thread apps/predbat/plan.py
Comment on lines 4139 to 4144
# Scale down the number of minutes if the value exceeds the max
if kwh > iboost_left:
percent = iboost_left / kwh
length = min(round(((length * percent) / 5) + 0.5, 0) * 5, end - start)
length = int(min(round(((length * percent) / 5) + 0.5, 0) * 5, end - start))
end = start + length
hours = length / 60
@springfall2008 springfall2008 merged commit 77f1bd5 into main May 13, 2026
1 check passed
@springfall2008 springfall2008 deleted the fix/car_crash branch May 13, 2026 07:58
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.

Predbat crash after update to version 8.39.2

2 participants