Battery Modeling¶
The Battery device composes multiple Battery model sections with PowerConnections through a central Node to provide energy storage with multi-section SOC tracking and cost-based operating preferences.
Model Elements Created¶
graph LR
subgraph "Device: battery_main"
BU["Battery Section<br/>undercharge<br/>(optional)"]
BN["Battery Section<br/>normal<br/>(always)"]
BO["Battery Section<br/>overcharge<br/>(optional)"]
Node["Node<br/>battery_main:node"]
BU -->|PowerConnection<br/>undercharge cost| Node
BU <-->|BalanceConnection| BN
BN -->|PowerConnection| Node
BN <-->|BalanceConnection| BO
BO -->|PowerConnection<br/>overcharge cost| Node
Conn["PowerConnection<br/>battery_main:connection<br/>(efficiency, power limits,<br/>early charge incentive)"]
end
Target[Connection Target]
Node --> Conn
Conn --> Target
The adapter creates 4-10 model elements depending on configuration:
| Model Element | Name | Parameters From Configuration |
|---|---|---|
| Battery | {name}:undercharge (optional) |
Capacity: (min% - undercharge%) * capacity, initial charge distributed |
| Battery | {name}:normal (always) |
Capacity: (max% - min%) * capacity, initial charge distributed |
| Battery | {name}:overcharge (optional) |
Capacity: (overcharge% - max%) * capacity, initial charge distributed |
| Node | {name}:node |
Pure junction (no power generation/consumption) |
| PowerConnection | {name}:undercharge:to_node |
Discharge price: undercharge cost penalty |
| PowerConnection | {name}:normal:to_node |
No pricing (neutral) |
| PowerConnection | {name}:overcharge:to_node |
Charge price: overcharge cost penalty |
| BatteryBalanceConnection | {name}:balance:undercharge:normal |
Enforces fill ordering between undercharge and normal sections |
| BatteryBalanceConnection | {name}:balance:normal:overcharge |
Enforces fill ordering between normal and overcharge sections |
| PowerConnection | {name}:connection |
Efficiency, power limits, early charge/discharge incentive |
Architecture Details¶
Section Capacity Calculation¶
For a 10 kWh battery with configuration [5%-10%-90%-95%]:
- Inaccessible energy: 0-5% = 0.5 kWh (below undercharge, cannot be accessed)
- Undercharge section: 5-10% = 0.5 kWh
- Normal section: 10-90% = 8.0 kWh
- Overcharge section: 90-95% = 0.5 kWh
Initial Charge Distribution¶
Initial charge is distributed bottom-up across sections:
- Calculate accessible energy:
(initial_soc% - undercharge%) * capacity - Fill undercharge section up to its capacity
- Fill normal section with remaining energy up to its capacity
- Fill overcharge section with any remaining energy
Example: 50% SOC in a [5%-10%-90%-95%] battery:
- Accessible: (50% - 5%) × 10 kWh = 4.5 kWh
- Undercharge gets: 0.5 kWh (full)
- Normal gets: 4.0 kWh (partial, 50% of its 8 kWh capacity)
- Overcharge gets: 0 kWh (empty)
Constraint-Based Section Ordering¶
BatteryBalanceConnection elements enforce fill ordering between adjacent battery sections via LP constraints:
Charging order (enforced by constraints):
- Undercharge section must fill before normal section
- Normal section must fill before overcharge section
Discharging order (enforced by constraints):
- Overcharge section empties before normal section
- Normal section empties before undercharge section
Key insight: These are hard constraints, not economic preferences. The optimizer cannot violate fill ordering regardless of price conditions.
Penalty Costs¶
Section-to-node connections apply penalty costs for operating in extended ranges:
- Undercharge section:
undercharge_costpenalty on discharge (discourages deep discharge) - Overcharge section:
overcharge_costpenalty on charge (discourages high SOC) - Normal section: No penalties (preferred operating range)
Early Charge/Discharge Incentives¶
The early_charge_incentive parameter (default 0.001 $/kWh) creates time-varying preferences on the main connection (node to target):
- Charge incentive: Negative cost (benefit) that decreases over time (-incentive → 0)
- Discharge incentive: Positive cost that increases over time (incentive → 2×incentive + discharge_cost)
These small values (tenths of cents) break ties when grid prices are equal, encouraging:
- Earlier charging when costs are equal
- Later discharge when revenues are equal
The incentives apply to the main connection only, not to section-to-node connections.
Devices Created¶
Battery creates 1-4 devices in Home Assistant depending on configuration:
| Device | Name | Created When | Purpose |
|---|---|---|---|
| Aggregate | {name} |
Always | Total power, energy, SOC across all sections |
| Undercharge | {name}:undercharge |
undercharge_percentage configured |
Undercharge section metrics and shadow prices |
| Normal | {name}:normal |
Multi-section operation active | Normal section metrics and shadow prices |
| Overcharge | {name}:overcharge |
overcharge_percentage configured |
Overcharge section metrics and shadow prices |
Parameter Mapping¶
The adapter transforms user configuration into model parameters:
| User Configuration | Model Element(s) | Model Parameter | Notes |
|---|---|---|---|
capacity |
Battery sections | Section capacities based on percentage ranges | Distributed across sections |
initial_charge_percentage |
Battery sections | initial_charge distributed bottom-up |
Fills sections sequentially |
min_charge_percentage |
Battery sections | Defines normal section lower bound | Inner bound (preferred min) |
max_charge_percentage |
Battery sections | Defines normal section upper bound | Inner bound (preferred max) |
undercharge_percentage |
Battery sections | Defines undercharge section lower bound | Outer bound (hard min) |
overcharge_percentage |
Battery sections | Defines overcharge section upper bound | Outer bound (hard max) |
early_charge_incentive |
Node-to-target connection | price_target_source (charge), price_source_target (discharge) |
Time-varying on main connection |
undercharge_cost |
Undercharge-to-node connection | price_source_target (discharge penalty) |
Penalty for undercharge discharge |
overcharge_cost |
Overcharge-to-node connection | price_target_source (charge penalty) |
Penalty for overcharge charging |
efficiency |
Node-to-target connection | efficiency_source_target, efficiency_target_source |
Applied to both directions |
max_charge_power |
Node-to-target connection | max_power_target_source |
Network to battery |
max_discharge_power |
Node-to-target connection | max_power_source_target |
Battery to network |
discharge_cost |
Node-to-target connection | Added to price_source_target |
Added to early discharge incentive |
| (automatic) | Balance connections | capacity_lower from section capacity |
Enforces section fill ordering |
Output Mapping¶
The adapter aggregates model outputs to user-friendly sensor names:
Aggregate device outputs:
| Model Output(s) | Sensor Name | Description |
|---|---|---|
Sum of section BATTERY_POWER_CHARGE |
power_charge |
Charge power |
Sum of section BATTERY_POWER_DISCHARGE |
power_discharge |
Discharge power |
Sum of section BATTERY_ENERGY_STORED |
energy_stored |
Energy stored |
| Calculated from total energy and capacity | state_of_charge |
State of charge |
Node NODE_POWER_BALANCE |
power_balance |
Power balance shadow price |
Section device outputs (undercharge, normal, overcharge):
| Model Output(s) | Sensor Name | Description |
|---|---|---|
Section BATTERY_ENERGY_STORED |
energy_stored |
Energy stored in this section |
Section BATTERY_POWER_CHARGE |
power_charge |
Charge power in this section |
Section BATTERY_POWER_DISCHARGE |
power_discharge |
Discharge power in this section |
Section BATTERY_ENERGY_IN_FLOW |
energy_in_flow |
Energy in flow shadow price |
Section BATTERY_ENERGY_OUT_FLOW |
energy_out_flow |
Energy out flow shadow price |
Section BATTERY_SOC_MAX |
soc_max |
SOC max shadow price |
Section BATTERY_SOC_MIN |
soc_min |
SOC min shadow price |
Balance connection BALANCE_POWER_DOWN |
balance_power_down |
Power flowing down into this section |
Balance connection BALANCE_POWER_UP |
balance_power_up |
Power flowing up out of this section |
The balance_power_down and balance_power_up sensors show power flowing through balance connections with adjacent sections.
Each section accumulates power from all adjacent balance connections (sections can have connections both above and below).
These sensors are useful for diagnosing section rebalancing when capacity changes occur.
See Battery Configuration for complete sensor documentation.
Configuration Impact¶
Section Configuration¶
- No extended sections (default): Single normal section with simple behavior
- Undercharge section: Allows conditional deep discharge when economically justified
- Overcharge section: Allows conditional high SOC when economically justified
- Both sections: Maximum flexibility with economic protection at extremes
Cost Configuration¶
Early charge incentive (early_charge_incentive):
- Default: 0.001 $/kWh (0.1 cents)
- Creates time-varying preferences within the optimization horizon on the main connection
- Applies to both charging (negative cost = incentive) and discharging (positive cost = disincentive)
- Should be small (< 0.01 $/kWh) to avoid dominating actual price signals
Undercharge cost (undercharge_cost):
- Penalty for discharging below
min_charge_percentage - Set relative to grid price range
- Typical range: \(0.50-\)2.00/kWh depending on battery degradation concerns
Overcharge cost (overcharge_cost):
- Penalty for charging above
max_charge_percentage - Set relative to value of excess solar or low grid prices
- Typical range: \(0.50-\)2.00/kWh depending on battery longevity concerns
Discharge cost (discharge_cost):
- Base cost applied to all discharge operations
- Models battery degradation from cycling
- Typical range: \(0.00-\)0.05/kWh
Next Steps¶
-
Battery configuration
Configure batteries in your Home Assistant setup.
-
Battery model
Mathematical formulation for single-section battery storage.
-
Connection model
How power limits, efficiency, and pricing are applied.
-
Balance connection
How section fill ordering is enforced.
-
Node model
How the central junction connects battery sections.