Skip to content

isystemsautomation/ha-solar-energy-controller

Repository files navigation

Solar Energy Controller

HACS Home Assistant Version Issues

A PID-based control integration for Home Assistant that regulates a numeric output entity based on a measured process value and a setpoint, with optional grid import/export limiting.

Designed for energy flow control scenarios such as inverter power limiting, load control, EV charging, or grid balancing.


About

Solar Energy Controller is an open-source PID control integration for Home Assistant, designed to provide flexible energy flow control for solar and grid-connected systems. This integration enables precise control of energy systems through a normalized, percent-based PID algorithm that works across different sensor types and units.

The integration is developed and maintained as an open-source project. For more information, visit the GitHub repository.


Supported Devices

This integration is generic and does not talk directly to a specific hardware brand or model. It works with any devices that expose the required Home Assistant entities.

Known Supported Setups

The following types of setups are known to work well with Solar Energy Controller, as long as they expose compatible entities:

  • Solar inverters with a numeric power limit entity (e.g., number.inverter_max_power) and power sensor (e.g., sensor.solar_power)
  • EV chargers with a numeric current or power limit entity (e.g., number.ev_charger_limit) and power/current sensors
  • Battery systems where charge/discharge power can be controlled via a number/input_number entity
  • Smart relays or load controllers that expose a numeric control for power/current/percentage
  • Any energy or load control scenario where:
    • The process value (PV) is available as a sensor, number, or input_number
    • The setpoint (SP) is available as a number or input_number
    • The output (actuator) is a number or input_number entity

Note: The integration does not depend on a specific inverter/charger brand. As long as the device is already integrated into Home Assistant and exposes compatible entities, it can be used.

Known Unsupported / Not Recommended Setups

The following setups are not supported or not recommended:

  • Devices that do not expose a numeric control entity (e.g., only switch or binary_sensor without a number/input_number output)
  • On/off-only devices where control is purely binary (no numeric output to regulate)
  • High-speed real-time control systems that require sub-second response (e.g., motor drives, fast robotics)
  • Devices that are not integrated into Home Assistant or do not provide entities for PV/SP/Output

If you are unsure whether your device is supported, check if you can:

  • Read the measurement you want to control (PV) as a sensor, number, or input_number
  • Write a numeric value to a number or input_number entity that affects the device (Output)
  • Optionally read grid power as a sensor, number, or input_number for the grid limiter

Features

  • PID controller (Kp / Ki / Kd)
  • Internal 0–100% normalized control
  • Percent-based PID tuning (unit- and device-independent)
  • Anti-windup with tracking
  • Derivative on measurement
  • Multiple runtime modes:
    • Automatic setpoint
    • Manual setpoint
    • Manual output
    • Hold
  • Optional grid import/export limiter
  • Optional output rate limiting
  • Fully configurable from the Home Assistant UI

How the Controller Works

The controller internally normalizes PV, SP, and Grid Power to a 0–100% range using configured raw min/max values:

  • PV (Process Value) → 0–100%
  • SP (Setpoint) → 0–100%
  • GRID (Grid Power) → 0–100% (used only when limiter is enabled)
  • PID OUT → 0–100%

The PID algorithm always operates in percent, while:

  • Sensors continue to display raw, real-world values
  • The output entity receives scaled real-world values (based on your output min/max)

This makes the controller:

  • stable across different sensors and units (W, A, V, %, etc.)
  • predictable to tune
  • resilient when changing devices (only ranges change)

PID Gains (Percent-Based Tuning)

Kp, Ki, and Kd are tuned in percent space.

What this means:

  • 100% PID output represents your configured maximum output
  • PV/SP/Grid units do not matter (because values are normalized before PID)
  • Gains do not need re-scaling when you change sensor ranges or units

Installation

Prerequisites

  • Home Assistant 2023.9.0 or later
  • HACS (Home Assistant Community Store) installed and configured

If you don't have HACS installed yet:

  1. Follow the HACS installation guide
  2. Restart Home Assistant
  3. Complete the HACS setup wizard

Installation Steps

  1. In HACS, go to Integrations → ⋮ → Custom repositories
  2. Add this repository URL: https://github.com/isystemsautomation/ha-solar-energy-controller and select Integration as the category
  3. Click Add and wait for the repository to be added
  4. Search for Solar Energy Controller in HACS
  5. Click Download to install the integration
  6. Restart Home Assistant
  7. Go to Settings → Devices & Services → Add Integration
  8. Search for Solar Energy Controller and follow the setup wizard

Removal

To remove the Solar Energy Controller integration:

  1. Go to Settings → Devices & Services
  2. Find Solar Energy Controller in the list of integrations
  3. Click on the integration entry
  4. Click the (three dots) menu in the top right corner
  5. Select Delete and confirm the removal
  6. (Optional) To remove the integration files from HACS:
    • Go to HACS → Integrations
    • Find Solar Energy Controller
    • Click Remove
  7. Restart Home Assistant to complete the removal

Note: Removing the integration will delete all configuration entries and entities. Any automations or scripts that reference these entities will need to be updated.


Initial Configuration

During setup you select the entities used by the controller and define their operating ranges for normalization.

Installation Parameters

The following parameters are required during the initial setup:

Name:

  • Description: A friendly name for this controller instance (e.g., "Solar Inverter Controller", "EV Charger PID").
  • Where to find: Choose any descriptive name that helps you identify this controller in Home Assistant.

Process Value Entity (PV):

  • Description: The entity that provides the measured process value that the PID controller will regulate. This is the "sensor" that tells you the current state.
  • Where to find: Go to Settings → Devices & Services → Entities and search for your sensor. Examples: sensor.solar_power, sensor.grid_voltage, number.current_setpoint.
  • Supported domains: sensor, number, input_number
  • Example: If controlling solar inverter power, this would be your power sensor (e.g., sensor.solar_inverter_power).

Setpoint Entity (SP):

  • Description: The entity that provides the target setpoint value. The PID controller will try to keep the process value equal to this setpoint.
  • Where to find: Go to Settings → Devices & Services → Entities and search for your setpoint entity. This is typically a number or input_number entity that you can set manually or via automation.
  • Supported domains: number, input_number
  • Example: If you want to maintain 5000W, create an input_number entity (e.g., input_number.target_power) and set it to 5000.

Output Entity:

  • Description: The entity that the PID controller will write to. This is the "actuator" that controls your system (e.g., inverter power limit, charger current).
  • Where to find: Go to Settings → Devices & Services → Entities and search for your output entity. This must be a number or input_number entity that accepts numeric values.
  • Supported domains: number, input_number
  • Example: If controlling an inverter, this would be the power limit entity (e.g., number.inverter_max_power).

Grid Power Entity:

  • Description: The entity that provides grid power measurement (signed import/export). Required if you plan to use the grid limiter feature.
  • Where to find: Go to Settings → Devices & Services → Entities and search for your grid power sensor. This should be a sensor that reports positive values when importing from grid and negative when exporting.
  • Supported domains: sensor, number, input_number
  • Example: sensor.grid_power where positive = importing, negative = exporting.

PV min / max:

  • Description: The minimum and maximum expected values for the process value in raw units. These define the range used to normalize the PV to 0–100% internally.
  • Where to find: Check your process value sensor's typical operating range. For example, if your power sensor reads 0–10000W, set min=0, max=10000.
  • Default: -5000.0 to 5000.0
  • Example: If your PV sensor measures power in watts and ranges from 0W to 10000W, set PV min=0, PV max=10000.

SP min / max:

  • Description: The minimum and maximum expected values for the setpoint in raw units. These define the range used to normalize the SP to 0–100% internally.
  • Where to find: Check what range your setpoint entity accepts. This should match the range you want to control.
  • Default: -5000.0 to 5000.0
  • Example: If your setpoint can be set from 0W to 10000W, set SP min=0, SP max=10000.

Grid min / max:

  • Description: The minimum and maximum expected values for grid power in raw units. These define the range used to normalize grid power to 0–100% internally (used by the grid limiter).
  • Where to find: Check your grid power sensor's typical operating range. For example, if your grid sensor reads -5000W (export) to +5000W (import), set min=-5000, max=5000.
  • Default: -5000.0 to 5000.0
  • Example: If your grid sensor measures from -10000W (export) to +10000W (import), set Grid min=-10000, Grid max=10000.

Note: These min/max ranges are used only to scale signals internally to 0–100% for PID calculation. They do not limit the actual sensor values or output. Invalid entity domains are rejected during setup.


Wiring & PID Direction

After installation, you can configure signal interpretation and controller behavior.

Options

  • Process Value Entity – Entity providing the measured process value
    • Supported domains: sensor, number, input_number
  • Setpoint Entity – Entity providing the target setpoint
    • Supported domains: number, input_number
  • Output Entity – Entity to be controlled by the PID
    • Supported domains: number, input_number
  • Grid Power Entity – Entity providing grid power measurement
    • Supported domains: sensor, number, input_number
  • Invert PV – Flips the sign of the process value if your meter reports the opposite direction (default: disabled)
  • Invert SP – Flips the setpoint sign (default: disabled)
  • Invert Grid Power – Flips grid power sign to match hardware conventions (default: disabled)
  • PID mode
    • Direct – Increasing error increases output (default)
    • Reverse – Increasing error decreases output
  • Update interval – Control loop execution interval in seconds (default: 10, minimum: 1)
  • PV min/max – Scaling range for process value normalization in raw units (default: -5000.0 to 5000.0)
  • SP min/max – Scaling range for setpoint normalization in raw units (default: -5000.0 to 5000.0)
  • Grid min/max – Scaling range for grid power normalization in raw units (default: -5000.0 to 5000.0)

Runtime Controls

Runtime controls allow switching modes and manually overriding behavior.

Runtime Modes

Mode Description
AUTO SP PID controls output using normalized percent PV/SP (default)
MANUAL SP User sets setpoint manually (raw units), PID remains active
MANUAL OUT User directly controls output (raw units)
HOLD Output frozen at last value

Mode transitions use bumpless transfer to avoid output jumps.

Runtime Parameters

  • Enabled – Master enable/disable switch for the controller (default: enabled)
  • Runtime mode – Current operating mode (AUTO SP, MANUAL SP, MANUAL OUT, HOLD)
  • Manual SP value – Manual setpoint value in raw units (only active in MANUAL SP mode)
  • Manual OUT value – Manual output value in raw units (only active in MANUAL OUT mode)

Live Sensors & PID Internals

The integration exposes detailed runtime sensors for transparency and tuning.

Sensors

  • Effective SP (raw units)
  • PV value (raw units)
  • Output (raw units)
  • Output (pre rate limit)
  • Error (percent domain)
  • Grid power (raw units)
  • P / I / D terms (percent domain)
  • Limiter state (diagnostic)
  • Status

Note: PV/SP/Output sensors show raw values. PID calculations are performed internally in percent.


Configuration Parameters

All tuning and limiter parameters are available as number and switch entities.

PID & Limits

  • Kp, Ki, Kd – PID gains (percent-based tuning)
    • Kp: Proportional gain (default: 1.0)
    • Ki: Integral gain (default: 0.1)
    • Kd: Derivative gain (default: 0.0)
  • PID deadband – Deadband in percent (default: 0.0)
    • Output changes only when error exceeds this threshold
  • Min output – Minimum output value in raw units (default: 0.0)
  • Max output – Maximum output value in raw units (default: 11000.0)

Grid Limiter

  • Grid limiter enabled – Enable/disable grid power limiting (default: disabled)
  • Grid limiter type – Import or export limiting
    • Import: Limits when importing from grid
    • Export: Limits when exporting to grid
  • Grid limiter limit – Limit threshold in raw units (default: 1000.0)
  • Grid limiter deadband – Deadband in raw units (default: 50.0)
    • Hysteresis to prevent oscillation around the limit

Rate Limiter

  • Rate limiter enabled – Enable/disable output rate limiting (default: disabled)
  • Rate limit – Maximum output change rate in raw units per second (default: 0.0)
    • Prevents sudden output changes

Advanced Parameters

  • Max output step – Maximum allowed output step change (default: 0.0, disabled)
    • Limits the maximum change per update cycle
  • Output epsilon – Minimum output change threshold (default: 0.0, disabled)
    • Output only changes if the difference exceeds this value

Diagnostic Information

Additional diagnostic entities help understand controller behavior.

Diagnostic Entities

  • Limiter state
  • Output (pre rate limit)

Status Sensor Values

The Status sensor may report:

  • running
  • disabled
  • hold
  • manual_out
  • missing_input
  • invalid_output
  • grid_power_unavailable
  • limiting_import
  • limiting_export
  • output_write_failed

These reflect internal controller state and error conditions.


Data Updates

The Solar Energy Controller integration uses a polling-based data update mechanism. The integration periodically reads the current state of the configured entities (Process Value, Setpoint, Grid Power, and Output) and recalculates the PID output.

Update Mechanism

  • Polling-based: The integration actively polls Home Assistant entity states at regular intervals
  • Default polling interval: 10 seconds
  • Configurable: The update interval can be adjusted in the integration options (minimum: 1 second)
  • Dynamic updates: Changes to the update interval are applied immediately without requiring a restart

How It Works

  1. At each update cycle, the coordinator:

    • Reads the current state of the Process Value (PV) entity
    • Reads the current state of the Setpoint (SP) entity
    • Reads the current state of the Grid Power entity (if configured)
    • Reads the current state of the Output entity
    • Normalizes all values to 0–100% using the configured min/max ranges
    • Calculates the PID output based on the error (SP - PV)
    • Applies grid limiter and rate limiter constraints
    • Writes the new output value to the Output entity
  2. The update interval determines how frequently this cycle repeats

Limitations

  • Polling overhead: More frequent updates (lower interval) increase Home Assistant state reads and writes
  • Entity availability: If any required entity becomes unavailable, the controller will log the issue and continue with the last known values where appropriate
  • Not real-time: Due to polling, there is a delay between actual changes in sensor values and controller response (up to the update interval)
  • Designed for slow systems: The integration is optimized for energy systems with seconds-level dynamics, not millisecond-level real-time control

Recommended Settings

  • Energy systems (solar, grid, EV charging): 10–30 seconds (default: 10 seconds)
  • Faster response needed: 5–10 seconds (increases system load)
  • Very slow systems: 30–60 seconds (reduces system load)

Examples

The following automation examples demonstrate common use cases for the Solar Energy Controller integration.

Example 1: Adjust Setpoint Based on Solar Production

Automatically adjust the setpoint based on available solar power:

automation:
  - alias: "Adjust PID Setpoint Based on Solar"
    trigger:
      - platform: numeric_state
        entity_id: sensor.solar_power
        above: 0
    condition:
      - condition: state
        entity_id: select.charger_pid_runtime_mode
        state: "AUTO SP"
    action:
      - service: number.set_value
        target:
          entity_id: number.charger_pid_setpoint
        data:
          value: "{{ states('sensor.solar_power') | float }}"

Example 2: Disable Controller During Night

Disable the controller when solar production is zero (nighttime):

automation:
  - alias: "Disable PID Controller at Night"
    trigger:
      - platform: numeric_state
        entity_id: sensor.solar_power
        below: 100
    condition:
      - condition: state
        entity_id: switch.charger_pid_enabled
        state: "on"
    action:
      - service: switch.turn_off
        target:
          entity_id: switch.charger_pid_enabled

Example 3: Enable Grid Limiter During Peak Hours

Automatically enable the grid limiter during peak electricity hours:

automation:
  - alias: "Enable Grid Limiter During Peak Hours"
    trigger:
      - platform: time
        at: "14:00:00"  # Start of peak hours
    action:
      - service: switch.turn_on
        target:
          entity_id: switch.charger_pid_grid_limiter_enabled
      - service: number.set_value
        target:
          entity_id: number.charger_pid_grid_limiter_limit
        data:
          value: 1000  # Limit to 1000W import

  - alias: "Disable Grid Limiter After Peak Hours"
    trigger:
      - platform: time
        at: "22:00:00"  # End of peak hours
    action:
      - service: switch.turn_off
        target:
          entity_id: switch.charger_pid_grid_limiter_enabled

Example 4: Switch to Manual Mode When Battery is Low

Switch to manual output mode and set a low output value when battery is low:

automation:
  - alias: "Switch to Manual Mode When Battery Low"
    trigger:
      - platform: numeric_state
        entity_id: sensor.battery_soc
        below: 20
    condition:
      - condition: state
        entity_id: select.charger_pid_runtime_mode
        state: "AUTO SP"
    action:
      - service: select.select_option
        target:
          entity_id: select.charger_pid_runtime_mode
        data:
          option: "MANUAL OUT"
      - service: number.set_value
        target:
          entity_id: number.charger_pid_manual_out_value
        data:
          value: 1000  # Set low output (1000W)

Example 5: Monitor Controller Status

Send a notification when the controller encounters an error:

automation:
  - alias: "Notify on PID Controller Error"
    trigger:
      - platform: state
        entity_id: sensor.charger_pid_status
        to:
          - "missing_input"
          - "invalid_output"
          - "output_write_failed"
    action:
      - service: notify.mobile_app
        data:
          title: "PID Controller Alert"
          message: "Controller status: {{ states('sensor.charger_pid_status') }}"

Note: Replace entity IDs (e.g., charger_pid_*) with your actual entity names. Entity names are based on the name you gave your controller instance during setup.


Troubleshooting

Cannot complete setup: “Entity not found” / “Entity unavailable”

  • Symptom: The configuration form shows errors like entity_not_found or entity_unavailable for PV, SP, Output, or Grid entities.
  • Description: The selected entities either do not exist in Home Assistant or are currently unavailable / unknown.
  • Resolution:
    1. Go to Settings → Devices & Services → Entities and verify that the selected entities exist and have valid states.
    2. Ensure the underlying integrations (e.g., inverter, charger, meter) are loaded and working.
    3. Refresh the entity list in the config flow (close and reopen the flow) and reselect the entities.
    4. If the entity is often unavailable, fix the underlying integration before using it with the controller.

Controller status shows missing_input or grid_power_unavailable

  • Symptom: The Status sensor reports missing_input or grid_power_unavailable, and the controller does not regulate as expected.
  • Description: One or more required inputs (PV, SP, Output, Grid) are missing or unavailable.
  • Resolution:
    1. Check the Status sensor and the individual PV/SP/Output/Grid sensors to see which one is unavailable or unknown.
    2. Fix the upstream integration (e.g., restore communication with the inverter or meter).
    3. Verify the configured entities in Settings → Devices & Services → Solar Energy Controller → Configure.
    4. Once all inputs are available again, the controller will automatically resume normal operation.

Controller does not change output

  • Symptom: The Output entity remains constant even when PV/SP change.
  • Description: The controller may be disabled, in HOLD mode, or limited by rate/step constraints.
  • Resolution:
    1. Check the Enabled switch entity and ensure it is turned on.
    2. Verify the Runtime mode select is set to AUTO SP (or the desired mode, not HOLD).
    3. Check Rate limiter and Max output step values; very small limits can effectively freeze the output.
    4. Confirm that the Output entity accepts the commanded values (no validation in the target integration blocks changes).

Cannot change Manual SP / Manual OUT values

  • Symptom: Changing Manual SP or Manual OUT results in errors or values snapping back.
  • Description: Manual values can only be set when the controller is in the corresponding manual mode.
  • Resolution:
    1. Set Runtime mode to MANUAL SP before changing the Manual SP value, or to MANUAL OUT before changing the Manual OUT value.
    2. If you see a service error like “Cannot set Manual SP value: controller is in AUTO SP mode”, switch to the correct mode and retry.
    3. Verify that no automation is continuously overwriting the same entities.

Custom card not visible / “Custom element not found: pid-controller-mini”

  • Symptom: Lovelace shows Custom element not found: pid-controller-mini or the mini card does not load.
  • Description: The frontend resources for the custom card are not registered or not served.
  • Resolution:
    1. Ensure the integration is installed via HACS and Home Assistant has been restarted.
    2. If Lovelace is not in storage mode, manually add the resources:
      • Go to Settings → Dashboards → Resources.
      • Add the following URLs as JavaScript module resources:
        • /solar_energy_controller/frontend/pid-controller-mini.js
        • /solar_energy_controller/frontend/pid-controller-popup.js
    3. Clear your browser cache and reload the dashboard.

Known Limitations

The following are known limitations of the integration. These are design decisions and constraints, not bugs. For bug reports, please use the issue tracker.

Entity Domain Restrictions

  • Output entity: Must be number or input_number (cannot use sensor entities as output)
  • Setpoint entity: Must be number or input_number (cannot use sensor entities as setpoint)
  • Process Value entity: Can be sensor, number, or input_number
  • Grid Power entity: Can be sensor, number, or input_number

Control System Limitations

  • Polling-based updates: The integration uses polling, not push-based updates. Response time is limited by the update interval (minimum: 1 second)
  • Not real-time: Designed for energy systems with seconds-level dynamics, not millisecond-level real-time control
  • Update interval: Minimum polling interval is 1 second. Very fast updates (< 5 seconds) may increase system load
  • Single output entity: Each controller instance can only control one output entity at a time

Configuration Limitations

  • No YAML configuration: Configuration must be done through the Home Assistant UI (config flow and options flow)
  • No multiple instances with same entities: The integration prevents creating multiple controller instances with the same PV, SP, and Output entity combination (enforced by unique ID)

Data and Features

  • No historical data storage: The integration does not store historical PID calculations or state changes. Use Home Assistant's history feature to track entity states
  • No remote API: The integration only exposes Home Assistant entities. There is no separate API or remote control interface
  • No backup/restore of PID state: PID internal state (integral term, previous values) is not persisted across restarts

System Requirements

  • Entity availability: All configured entities (PV, SP, Output, Grid) must be available in Home Assistant. The controller will log warnings if entities become unavailable
  • Home Assistant version: Requires Home Assistant 2023.9.0 or later

Support

About

Solar Energy Flow Controller – Home Assistant integration

Resources

Stars

Watchers

Forks

Packages

No packages published