Skip to content

feat: add rate adjust indicators to JSON plan#3662

Open
mgazza wants to merge 1 commit intomainfrom
feat/plan-json-rate-adjust-symbols
Open

feat: add rate adjust indicators to JSON plan#3662
mgazza wants to merge 1 commit intomainfrom
feat/plan-json-rate-adjust-symbols

Conversation

@mgazza
Copy link
Collaborator

@mgazza mgazza commented Mar 26, 2026

Summary

  • Adds import_rate_adjust and export_rate_adjust fields to each row in the JSON raw plan data (plan_html.attributes.raw)
  • Updates the built-in web UI plan renderer to show italic text with the appropriate symbol for estimated/replicated rates
  • Symbols match the existing adjust_symbol() behaviour from the legacy HTML plan: ? for copied, ? ⚖ for future rates, ? ⅆ for offset, = for user-set, ȣ for manual, ± for increment, $ for saving sessions

The JSON plan was missing this information — the legacy HTML plan showed it via adjust_symbol() but the JSON rows only had the rate values. Both the built-in web UI and external consumers (SaaS frontend) now have access to the adjust type.

Test plan

  • Verify rates beyond the 24h API window show italic with ? symbol in the web UI plan table
  • Verify confirmed rates (within API window) show normal text with no symbol
  • Verify plan_html.attributes.raw JSON rows contain import_rate_adjust / export_rate_adjust fields
  • Verify saving sessions, manual overrides show their respective symbols

🤖 Generated with Claude Code

The JSON raw plan data was missing the rate adjust type that the legacy
HTML plan used to show estimated/replicated rates (? symbols, italic).
Both the built-in web UI and SaaS frontend consume the JSON plan but
had no way to indicate which rates are confirmed vs estimated.

Adds import_rate_adjust and export_rate_adjust fields to each JSON row,
and updates the web UI renderer to display italic text with the
appropriate symbol (matching output.py adjust_symbol behaviour).

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
@mgazza mgazza requested a review from springfall2008 March 26, 2026 07:03
@mgazza
Copy link
Collaborator Author

mgazza commented Mar 26, 2026

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

🤖 Generated with Claude Code

Copy link
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

Adds rate-adjustment metadata to the JSON plan output so the built-in web UI (and external consumers) can display the same “rate source/adjustment” indicators that previously only existed in the legacy HTML plan.

Changes:

  • Add import_rate_adjust / export_rate_adjust fields to each JSON plan row (plan_html.attributes.raw.rows).
  • Update the built-in JSON plan renderer JS to display the corresponding symbol (matching Output.adjust_symbol) and italicize adjusted/replicated rates.

Reviewed changes

Copilot reviewed 2 out of 2 changed files in this pull request and generated 3 comments.

File Description
apps/predbat/output.py Emits per-row rate-adjust “type” fields into the JSON raw plan output.
apps/predbat/web_helper.py Renders the new adjust-type fields in the web UI plan table via symbol mapping + italics.

Comment on lines 1494 to +1501
# Json row
json_row = {}
json_row["time"] = rate_start.strftime(TIME_FORMAT)
json_row["slot_minute"] = minute # aligned slot minute used by the override system
json_row["import_rate"] = rate_value_import
json_row["export_rate"] = rate_value_export
json_row["import_rate_adjust"] = self.rate_import_replicated.get(minute, None)
json_row["export_rate_adjust"] = self.rate_export_replicated.get(minute, None)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

This PR changes the plan_html.attributes.raw JSON schema and the web UI renderer behavior, but there are no assertions in the existing tests that the generated raw_plan["rows"] include/propagate the new fields. Please add/update a unit test that calls publish_html_plan() and validates import_rate_adjust/export_rate_adjust are present and match the underlying rate_*_replicated values for at least one adjusted slot (e.g., copied/future/manual).

Copilot generated this review using guidance from repository custom instructions.
Comment on lines +1500 to +1501
json_row["import_rate_adjust"] = self.rate_import_replicated.get(minute, None)
json_row["export_rate_adjust"] = self.rate_export_replicated.get(minute, None)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

Adding import_rate_adjust/export_rate_adjust to every row (often as null) increases the size of predbat.plan_html's raw attribute. Home Assistant warns and may drop recording when state attributes exceed 16KB; consider omitting these keys when no adjustment exists (or moving adjustment info into a more compact structure) to reduce attribute bloat.

Suggested change
json_row["import_rate_adjust"] = self.rate_import_replicated.get(minute, None)
json_row["export_rate_adjust"] = self.rate_export_replicated.get(minute, None)
# Only include raw adjustment values when they actually exist to reduce attribute size
import_rate_adjust = self.rate_import_replicated.get(minute)
if import_rate_adjust is not None:
json_row["import_rate_adjust"] = import_rate_adjust
export_rate_adjust = self.rate_export_replicated.get(minute)
if export_rate_adjust is not None:
json_row["export_rate_adjust"] = export_rate_adjust

Copilot uses AI. Check for mistakes.
Comment on lines +1500 to +1501
json_row["import_rate_adjust"] = self.rate_import_replicated.get(minute, None)
json_row["export_rate_adjust"] = self.rate_export_replicated.get(minute, None)
Copy link

Copilot AI Mar 26, 2026

Choose a reason for hiding this comment

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

The new import_rate_adjust/export_rate_adjust fields are string “adjust types”, but the name is easy to confuse with the existing numeric *_rate_adjusted fields (especially for external consumers). Consider renaming to something explicit like import_rate_adjust_type / export_rate_adjust_type (and updating the renderer accordingly) to make the JSON schema self-describing.

Suggested change
json_row["import_rate_adjust"] = self.rate_import_replicated.get(minute, None)
json_row["export_rate_adjust"] = self.rate_export_replicated.get(minute, None)
json_row["import_rate_adjust_type"] = self.rate_import_replicated.get(minute, None)
json_row["export_rate_adjust_type"] = self.rate_export_replicated.get(minute, None)

Copilot uses AI. Check for mistakes.
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.

2 participants