Predbat Home Battery Prediction

repository·main·Indexed 43 days ago

https://github.com/springfall2008/batpred

A Home Assistant integration for home battery prediction and automatic charging. It optimizes energy usage across various inverter brands, including GivEnergy, Solis, Huawei, SolarEdge, SigEnergy, FoxESS, Sofar, and Tesla Powerwall. Features include the AlertFeed component for weather-based battery management, synthetic and Octopus Energy load profiles, and tools for calculating annual costs and payback periods.

Tokens
239.6K
Snippets
422
Records
807
Agent score
54%

What's inside Predbat

  1. Overview of ML Load Prediction

    main

    Predbat features a machine learning component that uses a lightweight multi-layer perceptron (MLP) neural network to predict household energy consumption for the next 48 hours in 5-minute intervals.

    The model learns from:

    • Historical load patterns
    • Time-of-day and day-of-week patterns
    • Historical PV generation (optional)
    • Temperature forecasts (optional)
    • Historical and future energy import/export rates

    Key technical characteristics:

    • Implementation: Pure NumPy (no heavy deep learning frameworks required).
    • Architecture: Deep neural network with 3 hidden layers containing [512, 256, 64] neurons.
    • Optimization: Uses He initialization and AdamW weight decay.
    • Training Lifecycle: Automatically trains on historical data (requires $\ge$ 1 day, 7+ days recommended). It fine-tunes every 2 hours using the full dataset to adapt to changing patterns. It uses time-weighted training to prioritize recent data.
    • Persistence: The model persists across restarts and falls back gracefully if predictions are unreliable.
  2. Overview of Predbat

    main

    Predbat (also known as Batpred or Batman) is a home battery prediction and automatic charging system designed for Home Assistant. It supports a wide range of inverters, including:

    • GivEnergy
    • Solis
    • Huawei
    • SolarEdge
    • SigEnergy
    • FoxESS
    • Sofar
    • Tesla Powerwall
    • and many others.

    It aims to optimize home battery usage through intelligent prediction and automated charging logic.

  3. Implementation Plan: Bot PR Flow

    main

    The Bot PR Flow extends the existing issue-triage bot. When a GitHub issue is already triaged (marked with the BOT_TRIAGED label) and a user adds the BOT_PR label, the bot will automatically implement the fix/feature and open a draft PR for review.

    Architecture Overview

    • Orchestration: tools/triage_daemon.py performs a second poll specifically for issues labelled BOT_PR.
    • State Management: State is managed entirely via GitHub labels: BOT_TRIAGED, BOT_PR_OPENED, and BOT_PR_FAILED. No changes to state.json are required.
    • Execution: The flow uses a separate, more permissive tool allowlist for the /issue-pr skill invocation.
    • Success Criteria: Success is determined by re-checking for the existence of a PR, rather than the exit code of the tool invocation.

    Global Constraints for Implementation

    • Style: Use Black (256 chars) and Flake8 (250 chars) line lengths. Use British English (en-gb) for all prose and docstrings.
    • Naming: Use lower_case_with_underscores for variables.
    • Testing: 100% docstring coverage is required. All new code must have unit tests. tools/triage_daemon.py must have no dependency on apps/predbat.
  4. Enphase Cloud Integration Overview

    main

    The Enphase Cloud integration allows Predbat to provide full monitoring and battery control for Enphase IQ Battery (Encharge) systems via the Enphase Enlighten cloud. This enables Predbat to control an Enphase site as an inverter without requiring any local hardware access.

    Key Capabilities:

    • Monitoring: Tracks site SOC (State of Charge), available energy, max capacity, power limits, and solar/battery/grid energy flows.
    • Battery Control: Manages battery profiles (e.g., self-consumption, cost_savings, backup_only, ai_optimisation) and sets charge/discharge schedules.

    Scope Limitations:

    • Authentication: Supports password authentication only. Accounts using Email-OTP MFA are currently rejected.
    • Supported Hardware: Limited to Battery and Solar monitoring/control. Does not support EV chargers, heat pumps, tariffs, storm guard, or grid on/off control.
  5. Implementation Plan: AlphaESS Cloud Component

    main

    The AlphaESS Cloud Component allows monitoring and driving AlphaESS SMILE/Storion hybrid inverters via the AlphaESS Open API. This implementation uses a standalone ComponentBase subclass (alphaess.py) and a constants module (alphaess_const.py).

    Key Technical Details:

    • Authentication: Uses a native aiohttp client. Every request must be signed using sha512(appId + appSecret + timeStamp) in lower-case hex.
    • Control Logic: Predbat control entities map directly to AlphaESS schedule fields. The inverter handles the timing.
    • Polling Strategy: Uses a four-tier poll loop: static, config, power, and energy.
    • Write Gating: Writes are gated by change detection, a minimum interval, and Predbat's read-only switch.
    • Tech Stack: Python 3, aiohttp, hashlib, and Predbat's ComponentBase/MockBase/Storage components.
  6. What Predbat does and how it works

    main

    Predbat is a home battery automation program designed to minimize energy costs by automatically managing battery charging and discharging cycles.

    Core Functionality:

    • Automated Planning: Runs every 5 minutes and forecasts energy needs (default 48 hours via forecast_hours). It generates a plan (typically covering 24 hours after the first charge slot via forecast_plan_hours) to optimize cost.
    • Forecasting: Combines solar production forecasts (from Solcast, Open-Meteo, or Forecast.solar) with historical energy usage to predict house load and solar generation.
    • Inverter Control: Automatically programs both Hybrid and AC-coupled inverters with appropriate charging and discharging controls.
    • Cost Optimization: Uses energy pricing data (manual, Octopus Energy API/Home Assistant, Kraken, or spot-rate sensors like Energidataservice/Strømligning) to decide when to import/export energy.
    • Load Prediction: Predicts consumption using historical data or a trained neural network that learns time-of-day and day-of-week patterns.

    Key Features:

    • Export Management: Supports automatic planning of export slots to discharge the battery when export rates are high.
    • Load Management: Can manage EV charging or Solar Diverters, accounting for these loads in the house prediction.
    • VPP Support: Supports Axle VPP export events by standing aside during events.
    • Scenario Analysis: Includes tools to compare tariffs (compare.md) and project annual savings/payback via 'What If' scenarios (annual-prediction.md).
  7. Overview of Predbat's modular component architecture

    main

    Predbat is built using a modular component architecture. This design allows for specific functionalities—such as database management, cloud API integrations, web interfaces, and energy provider connections—to be isolated into individual components.

    Users can control the active feature set by enabling or disabling components independently within the apps.yaml configuration file.

  8. Overview of Annual Debug Plans

    main
    The Annual Debug Plans feature allows users to inspect the specific plan JSON for each sampled day within an annual results document. By enabling an opt-in debug flag, the engine captures the raw plan structure for every scenario and sampled day, embedding it directly into the annual results document. This enables the web UI to render individual scenarios using the existing client-side plan renderer without requiring new files on disk or additional storage overhead, as the plans travel within the existing results document through the standard Storage system.
  9. Understand the plan metric vs. optimizer ranking score

    main

    A critical distinction in Predbat is between the Plan Metric (the actual yardstick used to judge the quality of a full plan) and the Optimizer Ranking Score (the internal, adjusted score used by individual optimizers to pick a candidate within a single window).

    Why they differ

    Optimizers like optimise_charge_limit and optimise_export apply internal adjustments to their scores to break ties or favor specific behaviors. These adjustments are not present in the final plan metric.

    Common internal adjustments include:

    • Export Commitment Bonus: Applied to in-progress export commitments.
    • Tie-break weightings: Small values like -0.002 for off or -0.001 for 0% to prefer certain states in a tie.
    • Charge Limit adjustments: Specific weights (e.g., -0.003, -0.002, -0.001) and a metric_min_improvement factor.

    The Risk

    Because the internal ranking score is not identical to the plan metric, an optimizer might select a candidate that has a higher internal score but actually results in a lower total plan metric. The monotonic pass (via keep_window_change_if_improved) is designed to catch and block these regressions.

  10. AlphaESS Schedule Data Format

    main

    The AlphaESS control system uses a specific dictionary structure to represent battery schedules. This shape is used by both the control entities (for publishing to Home Assistant) and the payload builder (for writing to the inverter).

    Schedule Shape:

    • reserve: int (Battery reserve percentage)
    • charge: dict
      • enable: bool
      • soc: int (Target State of Charge)
      • power: int (Power in Watts)
      • start: str (Format HH:MM:SS)
      • end: str (Format HH:MM:SS)
    • export: dict (Same structure as charge)

    Note: Time strings must strictly follow the HH:MM:SS format to match the INVERTER_DEF requirements; otherwise, Predbat may replace them with dummy values.

    {
        "reserve": int,
        "charge": {
            "enable": bool, 
            "soc": int, 
            "power": int, 
            "start": "HH:MM:SS", 
            "end": "HH:MM:SS"
        }, 
        "export": {
            "enable": bool, 
            "soc": int, 
            "power": int, 
            "start": "HH:MM:SS", 
            "end": "HH:MM:SS"
        }
    }
  11. Understand the Permission Model for Triage and PR Flows

    main

    The triage_daemon uses a permission model to define which tools are allowed or disallowed during different execution modes. There are two primary modes:

    1. Read-only Triage: Uses ALLOWED_TOOLS and DISALLOWED_TOOLS. This mode is restricted to investigating issues, searching for duplicates, and posting triage comments without modifying the repository state.
    2. Push/PR Creation (/issue-pr): Uses ALLOWED_TOOLS_PR and DISALLOWED_TOOLS_PR. This mode is a superset of the triage mode, adding capabilities to git add, git commit, git push, gh pr create, and running ./run_pre_commit.

    Security Boundary: The model follows a "deny wins over allow" principle. Even if a broad permission like Bash(gh *) is allowed, specific dangerous subcommands (like gh pr merge* or gh auth*) are explicitly listed in the DISALLOWED_TOOLS sets to prevent unauthorized administrative actions.

  12. Use different value types in apps.yaml

    main

    Predbat configuration items support several types of values:

    • Fixed Values: Direct assignment of a value.
      • template: true
    • Home Assistant Entities: Assigning a string that matches a sensor name.
      • battery_temperature_history: sensor.givtcp_battery_stack_1_bms_temperature
    • Lists: A collection of values.
    • Variable Expansion: Using a variable defined earlier in the file (e.g., {dno_region}) within a string.
    • Regular Expressions: Using the re:(...) prefix to match Home Assistant entity names that follow a pattern rather than a fixed name. This is useful for integrations like Solcast or Octopus where IDs change.
    # Variable expansion example
    dno_region: "A"
    compare_list:
      - id: 'igo_fixed'
        rates_import_octopus_url: '...-{dno_region}/standard-unit-rates/'
    
    # Regular expression example
    metric_octopus_import: 're:(sensor.(octopus_energy_| )electricity_[0-9a-z]+_[0-9a-z]+_current_rate)'
    pv_forecast_d3: re:(sensor.(solcast_|)(pv_forecast_| )forecast_(day_3|d3))