Skip to content

Refactor minute_data to utils and fix some issues with energy dashboard - #2826

Merged
springfall2008 merged 14 commits into
mainfrom
refactor1
Oct 25, 2025
Merged

springfall2008 merged 14 commits into
mainfrom
refactor1

Conversation

@springfall2008

Copy link
Copy Markdown
Owner

No description provided.

- Fix class info on GECloud/fox to allow energy flow in HA

Copilot AI 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.

Pull Request Overview

This PR refactors the minute_data family of functions from the fetch.py module into a new utils.py module, making them reusable across the codebase. Additionally, it fixes issues with energy dashboard sensors by adding proper state_class attributes.

  • Moved minute_data, minute_data_state, history_attribute_to_minute_data, and clean_incrementing_reverse functions to utils.py
  • Updated all call sites across multiple files to import and use these functions from utils
  • Added state_class: "total_increasing" to energy sensors in gecloud.py and fox.py for proper Home Assistant energy dashboard integration

Reviewed Changes

Copilot reviewed 12 out of 12 changed files in this pull request and generated 5 comments.

Show a summary per file
File Description
apps/predbat/utils.py Added four utility functions (minute_data, minute_data_state, history_attribute_to_minute_data, clean_incrementing_reverse) moved from fetch.py, and imported MAX_INCREMENT from config
apps/predbat/fetch.py Removed the four functions now in utils.py and updated imports to use them from utils
apps/predbat/unit_test.py Updated test calls to use minute_data from utils instead of as a method on my_predbat
apps/predbat/solcast.py Updated imports and function calls to use minute_data and history_attribute_to_minute_data from utils
apps/predbat/predheat.py Updated imports, removed self.minute_data assignment, and updated function calls to use minute_data from utils
apps/predbat/output.py Updated imports and function calls to use minute_data from utils
apps/predbat/octopus.py Updated imports and function calls to use minute_data from utils
apps/predbat/inverter.py Updated imports and function calls to use minute_data and minute_data_state from utils
apps/predbat/gecloud.py Added state_class: "total_increasing" to energy sensor definitions
apps/predbat/futurerate.py Updated imports, removed self.minute_data assignment, and updated function calls to use minute_data from utils
apps/predbat/fox.py Added device_class and state_class attributes to energy-related sensors
apps/predbat/predbat.py Updated version number to v8.27.0

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/predbat/utils.py
Get historical data for state (e.g. predbat status)
"""
mdata = {}
last_state = "unknown"

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

Variable last_state is initialized twice with different values (first as 'unknown' string on line 19, then as integer 0 on line 21). Remove the redundant initialization on line 19.

Suggested change
last_state = "unknown"

Copilot uses AI. Check for mistakes.
Comment thread apps/predbat/utils.py Outdated
rindex = 60 * 24 * days - minute - 1
state = mdata.get(rindex, state)
mdata[rindex] = state
minute += 1

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

The minute variable is incremented but never used. This line appears to be dead code since the loop already advances via the range iterator. Remove this line.

Suggested change
minute += 1

Copilot uses AI. Check for mistakes.
Comment thread apps/predbat/utils.py
try:
timestamp_key = str2time(key)
oldest_date = min(oldest_date, timestamp_key)
except (ValueError, TypeError) as e:

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

Exception variable e is captured but never used. Remove the exception variable: except (ValueError, TypeError):

Suggested change
except (ValueError, TypeError) as e:
except (ValueError, TypeError):

Copilot uses AI. Check for mistakes.
Comment thread apps/predbat/utils.py
Comment on lines +122 to +125
adata = {}
io_adjusted = None
newest_state = 0
prev_state = 0

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

[nitpick] The variables adata and io_adjusted have unclear initialization logic. If adjust_key is not provided, io_adjusted remains None but adata is always created as an empty dict. Consider initializing both based on whether they'll be used, or document why adata is always created.

Suggested change
adata = {}
io_adjusted = None
newest_state = 0
prev_state = 0
# adata and io_adjusted are only initialized if adjust_key is provided
adata = None
io_adjusted = None
newest_state = 0

Copilot uses AI. Check for mistakes.
Comment thread apps/predbat/fox.py Outdated
"friendly_name": f"Fox {sn} {name}",
}
# Set device and state class
if units in ['kWh', 'kW', 'W', 'W']:

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

The condition contains duplicate 'W' values in the list. This appears to be a typo. Based on the comment 'Set device and state class' and the attribute being set to 'energy', this should likely check for energy-related units only: if units in ['kWh', 'Wh']:

Suggested change
if units in ['kWh', 'kW', 'W', 'W']:
if units in ['kWh', 'Wh']:

Copilot uses AI. Check for mistakes.

Copilot AI 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.

Pull Request Overview

Copilot reviewed 13 out of 13 changed files in this pull request and generated 4 comments.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread apps/predbat/utils.py
Comment on lines +19 to +22
mdata = {}
last_state = "unknown"
newest_state = "unknown"
newest_age = 999999

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

The variable newest_state is initialized to "unknown" (string) on line 21, but later on line 64 it's assigned a state value which could be a string. However, on line 66 it's used to initialize the state variable for the forward fill loop. The initial value should remain consistent with the expected state type rather than switching between numeric initialization (as seen in the original code with newest_state = 0) and string initialization.

Copilot uses AI. Check for mistakes.
Comment thread apps/predbat/utils.py Outdated
history.append({"last_updated": key, "state": value})
max_age = now_utc - oldest_date
max_days = max(max_age.days, 1)
mdata, ignore_io_adjusted = minute_data(history, max_days, now_utc, "state", "last_updated", backwards=backwards, smoothing=False, scale=1.0, clean_increment=False, required_unit=None)

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

The variable ignore_io_adjusted suggests this return value is intentionally unused. Consider using _ as the variable name to make this intention explicit: mdata, _ = minute_data(...)

Suggested change
mdata, ignore_io_adjusted = minute_data(history, max_days, now_utc, "state", "last_updated", backwards=backwards, smoothing=False, scale=1.0, clean_increment=False, required_unit=None)
mdata, _ = minute_data(history, max_days, now_utc, "state", "last_updated", backwards=backwards, smoothing=False, scale=1.0, clean_increment=False, required_unit=None)

Copilot uses AI. Check for mistakes.
Comment thread apps/predbat/predheat.py Outdated
if data:
self.temperatures = self.minute_data(data, self.forecast_days, now_utc, "temperature", "datetime", backwards=False, smoothing=True, prev_last_updated_time=now_utc, last_state=self.external_temperature[0])
self.temperatures, ignore_io_adjusted = minute_data(
data, self.forecast_days, now_utc, "temperature", "datetime", backwards=False, smoothing=True, prev_last_updated_time=now_utc, last_state=self.external_temperature[0], max_increment=MAX_INCREMENT

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

Missing import for MAX_INCREMENT constant. The constant is used here but there's no corresponding import statement added to the file's imports section.

Copilot uses AI. Check for mistakes.
Comment thread apps/predbat/predheat.py
if history:
data_points = self.minute_data(history[0], self.max_days_previous, now_utc, "state", "last_updated", backwards=True, smoothing=smoothing, scale=scaling / total_count, clean_increment=incrementing, accumulate=data_points)
data_points, ignore_io_adjusted = minute_data(
history[0], self.max_days_previous, now_utc, "state", "last_updated", backwards=True, smoothing=smoothing, scale=scaling / total_count, clean_increment=incrementing, accumulate=data_points, max_increment=MAX_INCREMENT

Copilot AI Oct 25, 2025

Copy link

Choose a reason for hiding this comment

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

Missing import for MAX_INCREMENT constant. The constant is used here but there's no corresponding import statement added to the file's imports section.

Copilot uses AI. Check for mistakes.

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

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

It's defined at the top of the file

@springfall2008
springfall2008 merged commit da12ad4 into main Oct 25, 2025
1 check passed
@springfall2008
springfall2008 deleted the refactor1 branch October 25, 2025 21:05
gcoan pushed a commit to gcoan/batpred that referenced this pull request Sep 28, 2026
… are fetched (springfall2008#5286)

fetch_octopus_rates() replaced self.io_adjusted on every call, so the export
and gas fetches that follow the import fetch reset it to {} - every
BottlecapDave IOG user with metric_octopus_export or metric_octopus_gas set
lost all is_intelligent_adjusted markers. Regression from springfall2008#2826, which
dropped the old "only when adjust_key is set" guard.

Among other things this left dynamic_load_car_strip_feed_rates() with
nothing to strip, so a car cancelled by springfall2008#5229 still left its dispatch priced
cheap and the house battery was planned into it.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
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