Skip to content

Comments

Load ML Improvements, Put back GivTCP Load #3392

Merged
springfall2008 merged 10 commits intomainfrom
fixes20
Feb 19, 2026
Merged

Load ML Improvements, Put back GivTCP Load #3392
springfall2008 merged 10 commits intomainfrom
fixes20

Conversation

@springfall2008
Copy link
Owner

No description provided.

Copilot AI review requested due to automatic review settings February 19, 2026 08:50
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

Updates Predbat’s example dashboard charts to include ML-based home load/power forecasting visuals, bumps the app version, and adjusts how inverter load power is derived from GivTCP REST data.

Changes:

  • Add two new ApexCharts examples for ML Home Load Forecast and ML Home Power Forecast (excluding EV) to the example chart template.
  • Bump Predbat version to v8.33.4.
  • Switch GivTCP REST load power source to Load_Power (instead of energy-balance-derived load).

Reviewed changes

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

File Description
templates/example_chart.yml Adds ML load/power forecast chart examples and related JS data_generators.
apps/predbat/predbat.py Version bump to v8.33.4.
apps/predbat/inverter.py Changes REST-derived load_power assignment to use Load_Power.
Comments suppressed due to low confidence (1)

apps/predbat/inverter.py:1108

  • Leftover commented-out debug logging should be removed or gated behind a real debug flag/config (commented code tends to accumulate and makes this hot path harder to read).
                # self.log("DEBUG: Power details from REST: {}".format(ppdetails))

Comment on lines +1348 to +1362
attribute: power_today_now
name: Home Power (Avg 1h)
type: line
yaxis_id: forecasts
color: black
stroke_width: 3
curve: smooth
opacity: 1
extend_to: now
show:
in_header: false
in_legend: false
group_by:
func: avg
duration: 6h
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

The label says "Home Power (Avg 1h)", but group_by.duration is set to 6h, so the displayed series won’t match the name. Either change the name or adjust the group_by duration to align with the label.

Copilot uses AI. Check for mistakes.
# Calculate load from energy balance instead of using inverter register (which is incorrect during grid charging)
# Load = PV + Grid + Battery (battery negative when charging, positive when discharging)
self.load_power = self.pv_power + self.grid_power + self.battery_power
self.load_power = float(ppdetails.get("Load_Power", 0.0))
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

Reading REST "Load_Power" directly changes semantics and breaks the existing assumption (and fixtures) that GivTCP load is unreliable during some modes (e.g., grid charging). The repo’s REST fixtures show Load_Power != PV_Power + Grid_Power + Battery_Power (e.g., coverage/cases/rest_v2.json has Load_Power=624 but balance=590; rest_v3.json has 197 vs balance=233), and tests assert the energy-balance value. Consider reverting to the balance calculation, or make using Load_Power an opt-in config with a safe fallback when it disagrees significantly with the energy balance.

Suggested change
self.load_power = float(ppdetails.get("Load_Power", 0.0))
# Derive load power from energy balance rather than trusting REST Load_Power directly
self.load_power = self.pv_power + self.grid_power + self.battery_power

Copilot uses AI. Check for mistakes.
Comment on lines +1160 to +1163
let res = []; for (const [key, value] of
Object.entries(entity.attributes.results)) { res.push([new
Date(key).getTime(), value]); } return res.sort((a, b) => { return a[0] -
b[0] })
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

This data_generator assumes entity.attributes.results is always present; if the entity is unavailable or the attribute is missing, Object.entries(undefined) will throw and the chart will break. Consider using the same guard used later in this file (e.g., default to {} / return [] when results is falsy).

Suggested change
let res = []; for (const [key, value] of
Object.entries(entity.attributes.results)) { res.push([new
Date(key).getTime(), value]); } return res.sort((a, b) => { return a[0] -
b[0] })
if (!entity || !entity.attributes || !entity.attributes.results) return [];
const res = [];
for (const [key, value] of Object.entries(entity.attributes.results || {})) {
res.push([new Date(key).getTime(), value]);
}
return res.sort((a, b) => a[0] - b[0]);

Copilot uses AI. Check for mistakes.
Comment on lines +1164 to +1185
- entity: sensor.predbat_load_ml_stats
attribute: load_today_h1
stroke_width: 2
color: green
curve: smooth
name: FC
opacity: 0.6
type: line
offset: "-1h"
extend_to: now
yaxis_id: forecasts
- entity: sensor.predbat_load_ml_stats
attribute: load_today_h8
stroke_width: 2
color: purple
curve: smooth
name: FC
opacity: 0.35
type: line
offset: "-8h"
extend_to: now
yaxis_id: forecasts
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

Legend/series names are duplicated (both the -1h and -8h series are named "FC"), which makes them indistinguishable in the legend/tooltip. Use distinct names (e.g., "FC -1h" and "FC -8h").

Copilot uses AI. Check for mistakes.
Comment on lines +1294 to +1315
- entity: sensor.predbat_load_ml_stats
attribute: power_today_h1
stroke_width: 2
color: green
curve: smooth
name: FC
opacity: 0.6
type: line
offset: "-1h"
extend_to: now
yaxis_id: forecasts
- entity: sensor.predbat_load_ml_stats
attribute: power_today_h8
stroke_width: 2
color: purple
curve: smooth
name: FC
opacity: 0.35
type: line
offset: "-8h"
extend_to: now
yaxis_id: forecasts
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

Legend/series names are duplicated here as well (both forecast-offset series are named "FC"), which makes it hard to tell them apart in the legend/tooltip. Use distinct names for the -1h vs -8h series.

Copilot uses AI. Check for mistakes.
Comment on lines +1332 to +1346
const res = [];
for (let i = 1; i < raw.length; i++) {
const [t1, e1] = raw[i-1]; // previous cumulative kWh
const [t2, e2] = raw[i]; // current cumulative kWh

const dt_hours = (t2 - t1) / 3600000; // ms → hours
if (dt_hours <= 0) continue;

const dE = e2 - e1; // kWh used during interval

const power_kw = dE / dt_hours;

res.push([t2, power_kw]);
}
return res;
Copy link

Copilot AI Feb 19, 2026

Choose a reason for hiding this comment

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

This cumulative-kWh → power conversion doesn’t guard against negative deltas (e2 < e1), which can happen if the cumulative series resets/backsteps and will produce misleading negative power spikes. Consider skipping negative dE values (similar to the later rolling-average generator) or otherwise handling resets explicitly.

Copilot uses AI. Check for mistakes.
…the existing architecture if keeping the larger network is preferred.

He initialisation for ReLU

The weight initialisation currently uses Xavier/Glorot (std = sqrt(2/(fan_in + fan_out))), which was designed for linear/tanh activations. Since the network uses ReLU, switching to He initialisation (std = sqrt(2/fan_in)) would better maintain activation variance through the layers.

#3388
@springfall2008 springfall2008 changed the title Example Load ML Chart, Put back GivTCP Load Load ML Improvements, Put back GivTCP Load Feb 19, 2026
@springfall2008 springfall2008 merged commit 1867d8f into main Feb 19, 2026
1 check passed
@springfall2008 springfall2008 deleted the fixes20 branch February 19, 2026 09:27
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