Skip to content

fix: show the battery SOC chart in the web UI with more than one battery - #1153

Open
LesIT1 wants to merge 1 commit into
davidusb-geek:masterfrom
LesIT1:fix/soc-chart-multi-battery
Open

LesIT1 wants to merge 1 commit into
davidusb-geek:masterfrom
LesIT1:fix/soc-chart-multi-battery

Conversation

@LesIT1

@LesIT1 LesIT1 commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

The problem

Since #1032, a result frame with number_of_batteries above 1 carries SOC_opt_<k> per battery and no bare SOC_opt column. get_injection_dict only looked for the bare column, so the web UI showed no SOC chart at all for multi-battery users. Powers and costs were still plotted, the SOC figure was simply missing.

The fix

get_injection_dict now collects SOC_opt and every SOC_opt_<k> column and plots them on the one SOC figure, one trace per battery. With one battery the same single column is plotted as before, same trace name, legend and colour. The column filter is exact (SOC_opt, or SOC_opt_ followed by digits), so nothing else that happens to start with SOC_opt is picked up.

The SOC figure used to borrow the palette sized for the power figure, which was harmless with one trace. With two batteries and a typical 9 to 16 power columns, both SOC traces would land on the first two samples of the jet ramp, two dark blues you can't tell apart. The palette is now sized to the SOC traces, the same way the thermal figure already does it. With one battery that is the same colour as before.

Not touched: the y-axis label says "Battery SOC (%)" while the column is a fraction, which predates this change.

Tests

Four new tests in tests/test_utils.py: one battery still gets the SOC figure, two batteries get the figure with both traces, the two traces get the two ends of the colour ramp, and a frame with no SOC column (plus a decoy column) gets no SOC figure. The two-battery test was proven to fail on the current master.

Context: this is one of the two small fixes I said I'd send in #1150 ahead of the multi-inverter work, which adds more per-device columns to the same chart.

Summary by Sourcery

Restore battery state-of-charge charting for multi-battery optimization results while preserving single-battery behavior.

Bug Fixes:

  • Restore the web UI battery SOC chart for multi-battery results by plotting per-battery SOC columns alongside the existing single-battery format.

Enhancements:

  • Use a SOC-specific colour palette sized to the number of battery traces so multiple traces remain visually distinct.
  • Restrict SOC column detection to the bare SOC column or numerically indexed per-battery columns.

Tests:

  • Add coverage for single-battery, multi-battery, missing/decoy SOC columns, and distinct multi-battery trace colours.

Since davidusb-geek#1032 a result frame with number_of_batteries above 1 carries
SOC_opt_<k> per battery and no bare SOC_opt, so get_injection_dict
found no SOC column and the web UI showed no SOC chart at all. Collect
SOC_opt and every SOC_opt_<k> column and plot them on the one figure,
with the palette sized to the SOC traces instead of borrowing the one
sized for the power columns. One battery renders exactly as before.
@sourcery-ai

sourcery-ai Bot commented Sep 30, 2026 •

Copy link
Copy Markdown
Contributor

Reviewer's Guide

Restores the web UI SOC chart for multi-battery result frames by discovering valid per-battery SOC columns, plotting each as a trace, and assigning a palette sized to the trace count while preserving single-battery behavior. New tests cover column filtering, chart generation, trace output, and distinct colors.

Flow diagram for SOC column discovery and plotting

flowchart TD
    A[get_injection_dict] --> B[Filter dataframe columns]
    B --> C{Valid SOC columns found?}
    C -->|No| D[No SOC figure]
    C -->|Yes| E[Build palette sized to SOC traces]
    E --> F[Plot each SOC column as a trace]
    F --> G[Render Battery SOC figure]
Loading

File-Level Changes

Change Details Files
Collect and render all valid battery SOC columns in the optional SOC chart, while preserving single-battery behavior.
  • Recognize the bare SOC_opt column and indexed SOC_opt_<digits> columns using an exact filter.
  • Generate one chart trace per matching SOC column.
  • Keep the existing chart output and single-battery trace naming behavior.
src/emhass/utils.py
Size the SOC chart color palette to its number of traces so multiple batteries receive visibly distinct colors.
  • Sample the jet color scale across the full range for multiple SOC traces.
  • Retain the prior color for the single-trace case.
src/emhass/utils.py
Add coverage for SOC chart presence, trace selection, and palette behavior across battery configurations.
  • Verify single-battery and multi-battery SOC charts and traces.
  • Verify missing SOC data and decoy column names do not create a chart.
  • Verify two SOC traces use the endpoints of the color ramp.
tests/test_utils.py

Tips and commands

Interacting with Sourcery

  • Trigger a new review: Comment @sourcery-ai review on the pull request.
  • Continue discussions: Reply directly to Sourcery's review comments.
  • Generate a GitHub issue from a review comment: Ask Sourcery to create an
    issue from a review comment by replying to it. You can also reply to a
    review comment with @sourcery-ai issue to create an issue from it.
  • Generate a pull request title: Write @sourcery-ai anywhere in the pull
    request title to generate a title at any time. You can also comment
    @sourcery-ai title on the pull request to (re-)generate the title at any time.
  • Generate a pull request summary: Write @sourcery-ai summary anywhere in
    the pull request body to generate a PR summary at any time exactly where you
    want it. You can also comment @sourcery-ai summary on the pull request to
    (re-)generate the summary at any time.
  • Generate reviewer's guide: Comment @sourcery-ai guide on the pull
    request to (re-)generate the reviewer's guide at any time.
  • Resolve all Sourcery comments: Comment @sourcery-ai resolve on the
    pull request to resolve all Sourcery comments. Useful if you've already
    addressed all the comments and don't want to see them anymore.
  • Dismiss all Sourcery reviews: Comment @sourcery-ai dismiss on the pull
    request to dismiss all existing Sourcery reviews. Especially useful if you
    want to start fresh with a new review - don't forget to comment
    @sourcery-ai review to trigger a new review!

Customizing Your Experience

Access your dashboard to:

  • Enable or disable review features such as the Sourcery-generated pull request
    summary, the reviewer's guide, and others.
  • Change the review language.
  • Add, remove or edit custom review instructions.
  • Adjust other review settings.

Getting Help

@sourcery-ai sourcery-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Hey - I've reviewed your changes and they look great!

Sourcery assessment

Approved.


Sourcery is free for open source - if you like our reviews please consider sharing them ✨

This branch has not been deployed

No deployments
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.

1 participant