Skip to content

fix: never pass an empty feed-in forecast to the optimizer#98

Open
bvweerd wants to merge 1 commit into
devfrom
claude/functionality-bug-review-cfa5uw-feed-in-empty
Open

fix: never pass an empty feed-in forecast to the optimizer#98
bvweerd wants to merge 1 commit into
devfrom
claude/functionality-bug-review-cfa5uw-feed-in-empty

Conversation

@bvweerd

@bvweerd bvweerd commented Jul 14, 2026

Copy link
Copy Markdown
Owner

Description

When the feed-in sensor publishes at a finer interval than the grid price sensor and has less than one full grid-price period of data left (e.g. two remaining 15-min feed-in entries against hourly grid prices), resample_forecast() computes target_steps = 30 // 60 = 0 and returns [].

That empty list slipped through: the padding block is guarded by if resampled_feed_in and len(...) < n_steps, so an empty series was neither padded nor replaced, and reached optimize_battery_schedule as []. Inside the DP an empty (non-None) feed-in list means every step falls back to the grid buy price and terminal_price becomes 0 — precisely the fallback the project's feed-in invariant forbids (CLAUDE.md: "Never return None to optimizer — falls back to CONF_FIXED_FEED_IN_PRICE"), making PV arbitrage look unprofitable and dumping the terminal value of stored energy for that run.

Fix: when resampling yields an empty series, fall back to [fixed_feed_in_price] * len(resampled_prices) — the same fallback already used for an unavailable feed-in sensor.

Type of change

  • fix: Bug fix (patch version bump)
  • feat: New feature (minor version bump)
  • feat!: / BREAKING CHANGE: Breaking change (major version bump)
  • chore: / docs: / ci: Maintenance or documentation (no version bump)

Checklist

  • Commit title follows Conventional Commits (feat:, fix:, chore:, etc.)
  • Tests added or updated where applicable
  • Documentation updated if needed
  • CI is green (local: pytest + pre-commit + mypy pass)
  • PR targets the dev branch (not main, unless this is a hotfix)

Screenshots / Logs (optional)

New test: test_feed_in_forecast_empty_after_resample_uses_fixed_price.

🤖 Generated with Claude Code

https://claude.ai/code/session_01XWQRQEJXUxbp2CGFS18U9i


Generated by Claude Code

When the feed-in sensor publishes at a finer interval than the grid price
sensor and has less than one full grid-price period of data left (e.g.
30 min of 15-min feed-in entries against hourly grid prices),
resample_forecast() returns an empty list. The empty list bypassed the
padding logic and reached the optimizer, where every step fell back to the
grid buy price and the terminal value of stored energy became 0 — exactly
the fallback the feed-in invariant forbids, making PV arbitrage look
unprofitable for that run.

Fall back to the fixed feed-in price when resampling yields an empty
series, the same fallback used for an unavailable feed-in sensor.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01XWQRQEJXUxbp2CGFS18U9i
@github-actions github-actions Bot added the bug Something isn't working as expected label Jul 14, 2026
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working as expected

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants